浏览代码

fix:调整每日指标数据提醒的逻辑,不再每分钟查询一次,而是在凌晨的时候写入定时任务中,直接到点提醒

Roc 3 年之前
父节点
当前提交
221482ee69
共有 7 个文件被更改,包括 680 次插入20 次删除
  1. 9 0
      models/data_entry.go
  2. 1 0
      models/db.go
  3. 22 0
      models/edbdata.go
  4. 7 0
      models/users.go
  5. 416 2
      services/task.go
  6. 224 17
      utils/common.go
  7. 1 1
      utils/config.go

+ 9 - 0
models/data_entry.go

@@ -37,3 +37,12 @@ func GetEdbdataCount(tradeCode, nowDate string) (count int, err error) {
 	err = o.Raw(sql, tradeCode, nowDate).QueryRow(&count)
 	return
 }
+
+// GetEdbInfoByFrequencyNotDay 获取频度非日度 且 提醒时间不为空 的指标数据
+func GetEdbInfoByFrequencyNotDay() (items []*EdbInfo, err error) {
+	sql := `SELECT * FROM edbinfo WHERE frequency!="日度" AND notice_time<>''  `
+	o := orm.NewOrm()
+	o.Using("edb")
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}

+ 1 - 0
models/db.go

@@ -76,5 +76,6 @@ func init() {
 		new(ReportSendThsDetail),
 		new(Report),
 		new(CompanyEndDate),
+		new(Edbdata),
 	)
 }

+ 22 - 0
models/edbdata.go

@@ -0,0 +1,22 @@
+package models
+
+import (
+	"rdluck_tools/orm"
+	"time"
+)
+
+type Edbdata struct {
+	TradeCode  string    `orm:"column(TRADE_CODE);pk" description:"指标编码"`
+	Dt         string    `orm:"column(DT)" description:"日期"`
+	Close      string    `orm:"column(CLOSE)" description:"值"`
+	ModifyTime time.Time `orm:"column(modify_time)" description:"修改时间"`
+}
+
+// GetLastEdbdataInfo 根据指标编号获取指标最近的一条数据
+func GetLastEdbdataInfo(tradeCode string) (item *Edbdata, err error) {
+	sql := `SELECT * FROM edbdata WHERE TRADE_CODE=? order by DT desc `
+	o := orm.NewOrm()
+	o.Using("edb")
+	err = o.Raw(sql, tradeCode).QueryRow(&item)
+	return
+}

+ 7 - 0
models/users.go

@@ -74,3 +74,10 @@ func ModifyUserLastViewTime(uid int, lastViewTime string) (err error) {
 	_, err = o.Raw(sql, lastViewTime, uid).Exec()
 	return
 }
+
+// GetUserOpenidListByUserId 根据用户id来获取他的openid列表集合
+func GetUserOpenidListByUserId(userId int) (list []*OpenIdList, err error) {
+	sql := `SELECT open_id FROM user_record WHERE user_id = ? and create_platform = 1`
+	_, err = orm.NewOrm().Raw(sql, userId).QueryRows(&list)
+	return
+}

+ 416 - 2
services/task.go

@@ -2,11 +2,15 @@ package services
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"github.com/beego/beego/v2/task"
+	"hongze/hongze_task/models"
 	"hongze/hongze_task/services/company_contract"
 	"hongze/hongze_task/services/data"
 	"hongze/hongze_task/utils"
+	"strconv"
+	"strings"
 	"sync"
 	"time"
 )
@@ -56,6 +60,10 @@ func Task() {
 	//LzExportExcel()
 	//GetLzProductList()GetLzProductDetail
 
+	// 定时新增手工指标数据提醒
+	addEdbTask := task.NewTask("sendWaitReport", "0 * * * * * ", AddEdbTask)
+	task.AddTask("定时新增手工指标数据提醒", addEdbTask)
+
 	fmt.Println("task end")
 }
 
@@ -87,8 +95,8 @@ func releaseTask() {
 	sendEmail := task.NewTask("sendEmail", "0 0 12 * * 0 ", SendEmail)
 	task.AddTask("sendEmail", sendEmail)
 
-	oneMinute := task.NewTask("oneMinute", "0 */1 7-23 * * * ", OneMinute)
-	task.AddTask("oneMinute", oneMinute)
+	//oneMinute := task.NewTask("oneMinute", "0 */1 7-23 * * * ", OneMinute)
+	//task.AddTask("oneMinute", oneMinute)
 
 	// 正式/试用 用户到期提醒
 	companyRemind := task.NewTask("companyRemind", "0 30 08 * * *", CompanyRemind)
@@ -193,3 +201,409 @@ endData:=time.Now().UnixNano()/1e6
 	dateTime:=time.Unix(endData/1000,0)
 	fmt.Println(dateTime)
 */
+
+func AddEdbTask(cont context.Context) (err error) {
+	//每次先清除掉昨天的定时任务,再次开启今天的定时任务
+	for taskName := range TaskNameMap {
+		task.DeleteTask(taskName)
+		delete(TaskNameMap, taskName)
+	}
+	edbTaskAddTask()
+	return
+}
+
+// TaskNameMap 定时任务名称map集合
+var TaskNameMap map[string]bool
+
+func edbTaskAddTask() {
+	list, err := models.GetEdbInfoByFrequencyNotDay()
+	if err != nil {
+		fmt.Println("查询获取频度非日度 且 提醒时间不为空 的指标数据失败,Err:", err.Error())
+	}
+	TaskNameMap = make(map[string]bool)
+
+	// 今天的日期字符串(格式:2021-10-25)
+	todayStr := time.Now().Format(utils.FormatDate)
+
+	//当前周的周一与周日
+	nowWeekFirstDay := utils.GetNowWeekMonday()
+	nowWeekLastDay := utils.GetNowWeekLastDay()
+
+	//当前月的一号与最后一天
+	nowMonthFirstDay := utils.GetNowMonthFirstDay()
+	nowMonthLastDay := utils.GetNowMonthLastDay()
+
+	//当前季度的第一天与最后一天
+	nowQuarterFirstDay := utils.GetNowQuarterFirstDay()
+	nowQuarterLastDay := utils.GetNowQuarterLastDay()
+
+	//当前半年的第一天与最后一天
+	nowHalfYearFirstDay := utils.GetNowHalfYearFirstDay()
+	nowHalfYearLastDay := utils.GetNowHalfYearLastDay()
+
+	// 当前年的第一天与最后一天
+	nowYearFirstDay := utils.GetNowYearFirstDay()
+	nowYearLastDay := utils.GetNowYearLastDay()
+
+	//失败列表
+	failList := make([]string, 0)
+
+	//定时任务
+	edbTaskNameChannel := make(chan string)
+	//定时任务数量
+	taskNum := 0
+
+	//task.globalTaskManager.adminTaskList
+	for _, edb := range list {
+		tmpEdb := edb            //指标信息
+		isNotice := false        //是否需要提醒
+		noticeTime := "12:00:00" //提醒时间
+
+		var dataDtTime time.Time
+		edbData, tmpErr := models.GetLastEdbdataInfo(edb.TradeCode)
+		if tmpErr != nil {
+			if tmpErr.Error() != utils.ErrNoRow() {
+				failList = append(failList, fmt.Sprint(edb.TradeCode, "失败,Err:", tmpErr.Error()))
+				continue
+			}
+		}
+
+		//如果确实是有数据的
+		if edbData != nil {
+			tmpDataDtTime, _ := time.ParseInLocation(utils.FormatDate, edbData.Dt, time.Now().Location())
+			dataDtTime = tmpDataDtTime
+		}
+
+		switch edb.Frequency {
+		case "周度":
+			modifyDate := nowWeekLastDay //下次更新日期
+			if edb.NoticeTime != "" {
+				addDay := 7
+				noticeArr := strings.Split(edb.NoticeTime, " ")
+				if len(noticeArr) >= 2 {
+					noticeTime = noticeArr[1]
+				}
+				noticeWeek := noticeArr[0]
+				switch noticeWeek {
+				case "周一":
+					addDay = 1
+				case "周二":
+					addDay = 2
+				case "周三":
+					addDay = 3
+				case "周四":
+					addDay = 4
+				case "周五":
+					addDay = 5
+				case "周六":
+					addDay = 6
+				case "周日":
+					addDay = 7
+				}
+				modifyDate = modifyDate.AddDate(0, 0, addDay-7)
+			}
+
+			//如果正好是提醒日,同时本周没有过记录,那么需要提醒
+			if todayStr == modifyDate.Format(utils.FormatDate) && !nowWeekFirstDay.Before(dataDtTime) {
+				isNotice = true
+			}
+		case "月度":
+			addDay := 0
+			modifyDate := nowMonthLastDay //下次更新日期
+			if edb.NoticeTime != "" {
+				strArr := strings.Split(edb.NoticeTime, "日")
+				if len(strArr) >= 2 {
+					noticeTime = strArr[1]
+				}
+				tmpAddDay, tmpErr := strconv.Atoi(strArr[0])
+				if tmpErr != nil {
+					continue
+				}
+				addDay = tmpAddDay - 1
+				modifyDate = nowMonthFirstDay.AddDate(0, 0, addDay)
+			}
+
+			//如果正好是提醒日,同时本月没有过记录,那么需要提醒
+			if todayStr == modifyDate.Format(utils.FormatDate) && !nowMonthFirstDay.Before(dataDtTime) {
+				isNotice = true
+			}
+		case "季度":
+			//提醒时间
+			if edb.NoticeTime != "" {
+				noticeArr := strings.Split(edb.NoticeTime, " ")
+				if len(noticeArr) >= 2 {
+					noticeTime = noticeArr[1]
+				}
+			}
+			//每季度更新数据时间
+			//如果正好是提醒日(每季度最后一天),同时本季度没有过记录,那么需要提醒
+			if todayStr == nowQuarterLastDay.Format(utils.FormatDate) && !nowQuarterFirstDay.Before(dataDtTime) {
+				isNotice = true
+			}
+		case "半年度":
+			//提醒时间
+			if edb.NoticeTime != "" {
+				noticeArr := strings.Split(edb.NoticeTime, " ")
+				if len(noticeArr) >= 2 {
+					noticeTime = noticeArr[1]
+				}
+			}
+			//每半年度更新数据时间
+			//如果正好是提醒日(每半年度最后一天),同时本半年度没有过记录,那么需要提醒
+			if todayStr == nowHalfYearLastDay.Format(utils.FormatDate) && !nowHalfYearFirstDay.Before(dataDtTime) {
+				isNotice = true
+			}
+		case "年度":
+			//提醒时间
+			if edb.NoticeTime != "" {
+				noticeArr := strings.Split(edb.NoticeTime, " ")
+				if len(noticeArr) >= 2 {
+					noticeTime = noticeArr[1]
+				}
+			}
+			//每年度更新数据时间
+			//如果正好是提醒日(每年度最后一天),同时半年度没有过记录,那么需要提醒
+			if todayStr == nowYearLastDay.Format(utils.FormatDate) && !nowYearFirstDay.Before(dataDtTime) {
+				isNotice = true
+			}
+		}
+
+		if isNotice {
+			taskName := "edb_task_" + fmt.Sprint(edb.TradeCode)
+			fmt.Println(taskName, ";", edb.SecName)
+
+			//定时任务
+			tmpTaskFunc := func(ctx context.Context) (funcErr error) {
+				//方法执行结束后,移除定时任务
+				defer func() {
+					edbTaskNameChannel <- taskName
+				}()
+				// 匿名方法内判断是否发送提醒,因为可能时间到的时候,发现
+				funcIsNotice := false
+				// 再次获取指标数据详情
+				edbData, tmpErr := models.GetLastEdbdataInfo(tmpEdb.TradeCode)
+				if tmpErr != nil {
+					if tmpErr.Error() != utils.ErrNoRow() {
+						funcErr = tmpErr
+						return
+					}
+				}
+				if utils.RunMode == "debug" {
+					//tmpEdb.UserId = 44078 //测试环境的话,发送邮箱给颜鹏
+					tmpEdb.UserId = 29775 //测试环境的话,发送邮箱给嘉豪
+
+				}
+
+				//数据过期时间
+				var funcDataDtTime time.Time
+				//如果确实是有数据的
+				if edbData != nil {
+					tmpDataDtTime, _ := time.ParseInLocation(utils.FormatDate, edbData.Dt, time.Now().Location())
+					funcDataDtTime = tmpDataDtTime
+				}
+
+				switch tmpEdb.Frequency {
+				case "周度":
+					modifyDate := nowWeekLastDay //下次更新日期
+					if tmpEdb.NoticeTime != "" {
+						addDay := 7
+						noticeArr := strings.Split(tmpEdb.NoticeTime, " ")
+						if len(noticeArr) >= 2 {
+							noticeTime = noticeArr[1]
+						}
+						noticeWeek := noticeArr[0]
+						switch noticeWeek {
+						case "周一":
+							addDay = 1
+						case "周二":
+							addDay = 2
+						case "周三":
+							addDay = 3
+						case "周四":
+							addDay = 4
+						case "周五":
+							addDay = 5
+						case "周六":
+							addDay = 6
+						case "周日":
+							addDay = 7
+						}
+						modifyDate = modifyDate.AddDate(0, 0, addDay-7)
+					}
+
+					//如果正好是提醒日,同时本周没有过记录,那么需要提醒
+					if todayStr == modifyDate.Format(utils.FormatDate) && !nowWeekFirstDay.Before(funcDataDtTime) {
+						funcIsNotice = true
+					}
+				case "月度":
+					addDay := 0
+					modifyDate := nowMonthLastDay //下次更新日期
+					if tmpEdb.NoticeTime != "" {
+						strArr := strings.Split(tmpEdb.NoticeTime, "日")
+						if len(strArr) >= 2 {
+							noticeTime = strArr[1]
+						}
+						tmpAddDay, tmpErr := strconv.Atoi(strArr[0])
+						if tmpErr != nil {
+							funcErr = tmpErr
+						}
+						addDay = tmpAddDay - 1
+						modifyDate = nowMonthFirstDay.AddDate(0, 0, addDay)
+					}
+
+					//如果正好是提醒日,同时本月没有过记录,那么需要提醒
+					if todayStr == modifyDate.Format(utils.FormatDate) && !nowMonthFirstDay.Before(funcDataDtTime) {
+						funcIsNotice = true
+					}
+				case "季度":
+					//提醒时间
+					if tmpEdb.NoticeTime != "" {
+						noticeArr := strings.Split(tmpEdb.NoticeTime, " ")
+						if len(noticeArr) >= 2 {
+							noticeTime = noticeArr[1]
+						}
+					}
+					//每季度更新数据时间
+					//如果正好是提醒日(每季度最后一天),同时本季度没有过记录,那么需要提醒
+					if todayStr == nowQuarterLastDay.Format(utils.FormatDate) && !nowQuarterFirstDay.Before(funcDataDtTime) {
+						funcIsNotice = true
+					}
+				case "半年度":
+					//提醒时间
+					if tmpEdb.NoticeTime != "" {
+						noticeArr := strings.Split(tmpEdb.NoticeTime, " ")
+						if len(noticeArr) >= 2 {
+							noticeTime = noticeArr[1]
+						}
+					}
+					//每半年度更新数据时间
+					//如果正好是提醒日(每半年度最后一天),同时本半年度没有过记录,那么需要提醒
+					if todayStr == nowHalfYearLastDay.Format(utils.FormatDate) && !nowHalfYearFirstDay.Before(funcDataDtTime) {
+						funcIsNotice = true
+					}
+				case "年度":
+					//提醒时间
+					if tmpEdb.NoticeTime != "" {
+						noticeArr := strings.Split(tmpEdb.NoticeTime, " ")
+						if len(noticeArr) >= 2 {
+							noticeTime = noticeArr[1]
+						}
+					}
+					//每年度更新数据时间
+					//如果正好是提醒日(每年度最后一天),同时半年度没有过记录,那么需要提醒
+					if todayStr == nowYearLastDay.Format(utils.FormatDate) && !nowYearFirstDay.Before(funcDataDtTime) {
+						funcIsNotice = true
+					}
+				}
+
+				fmt.Println(tmpEdb.TradeCode, " funcIsNotice:", funcIsNotice)
+				//如果还是要提醒
+				if funcIsNotice {
+					//用户微信openid列表数据
+					openIdList := make([]*models.OpenIdList, 0)
+
+					//获取用户信息
+					isAdmin := true
+					admin, err := models.GetAdminByAdminId(tmpEdb.UserId)
+					if err != nil {
+						if err.Error() == utils.ErrNoRow() {
+							isAdmin = false
+						} else {
+							return err
+						}
+					}
+					if admin == nil {
+						isAdmin = false
+					}
+					if isAdmin {
+						if admin.Mobile == "" {
+
+						} else {
+							wxUser, err := models.GetWxUserByMobile(admin.Mobile)
+							if err != nil {
+								return err
+							}
+							if wxUser == nil {
+								funcErr = errors.New("用户信息不存在:mobile:" + admin.Mobile)
+								return err
+							}
+							tmpOpenidList, err := models.GetUserOpenidListByUserId(int(wxUser.UserId))
+							if err != nil {
+								return err
+							}
+							openIdList = tmpOpenidList
+						}
+					} else {
+						tmpOpenidList, err := models.GetUserOpenidListByUserId(tmpEdb.UserId)
+						if err != nil {
+							return err
+						}
+						openIdList = tmpOpenidList
+					}
+					//发送消息
+					if len(openIdList) <= 0 {
+						funcErr = errors.New("openId 列表为空" + strconv.Itoa(tmpEdb.UserId))
+						return
+					}
+
+					first := "数据录入提醒"
+					keyword1 := tmpEdb.SecName
+					keyword2 := "每周 " + edb.NoticeTime
+					remark := tmpEdb.SecName + "该更新了"
+					fmt.Println("开始发送模板消息了")
+					for _, openid := range openIdList {
+						fmt.Println(openid)
+					}
+
+					err = SendWxMsgWithFrequency(first, keyword1, keyword2, remark, openIdList)
+					if err != nil {
+						return err
+					}
+					//发送成功,记录发送日志
+					{
+						sendRecord := new(models.EdbinfoSendMsgRecord)
+						sendRecord.UserId = tmpEdb.UserId
+						sendRecord.TradeCode = tmpEdb.TradeCode
+						sendRecord.CreateTime = time.Now()
+						err = models.AddEdbinfoSendMsgRecord(sendRecord)
+						if err != nil {
+							return err
+						}
+					}
+				}
+				return
+			}
+
+			//添加定时任务
+			spec := ``
+			if noticeTime != "" {
+				noticeArr := strings.Split(noticeTime, ":")
+				if len(noticeArr) == 3 {
+					//spec = ` */20 * * * * * `
+					spec = fmt.Sprintf(` %s %s %s * * * `, noticeArr[2], noticeArr[1], noticeArr[0])
+				}
+			}
+			//定时任务开始的时间
+			tmpTask := task.NewTask(taskName, spec, tmpTaskFunc)
+
+			task.AddTask(taskName, tmpTask)
+			TaskNameMap[taskName] = true
+			taskNum++
+		}
+	}
+
+	//清除定时任务
+	go deleteTask(edbTaskNameChannel, taskNum)
+
+	for _, v := range failList {
+		fmt.Println(v)
+	}
+	//fmt.Println(task.NewMapSorter())
+}
+func deleteTask(keyChannel chan string, lenI int) {
+	for i := 0; i < lenI; i++ {
+		taskName := <-keyChannel
+		task.DeleteTask(taskName)
+		delete(TaskNameMap, taskName)
+	}
+}

+ 224 - 17
utils/common.go

@@ -1,4 +1,3 @@
-
 package utils
 
 import (
@@ -7,6 +6,7 @@ import (
 	"encoding/base64"
 	"encoding/hex"
 	"encoding/json"
+	"errors"
 	"fmt"
 	"image"
 	"image/png"
@@ -291,22 +291,22 @@ func SaveBase64ToFile(content, path string) error {
 
 func SaveBase64ToFileBySeek(content, path string) (err error) {
 	data, err := base64.StdEncoding.DecodeString(content)
-	exist,err:=PathExists(path)
-	if err!=nil {
+	exist, err := PathExists(path)
+	if err != nil {
 		return
 	}
 	if !exist {
 		f, err := os.Create(path)
-		if err!=nil {
+		if err != nil {
 			return err
 		}
 		n, _ := f.Seek(0, 2)
 		// 从末尾的偏移量开始写入内容
 		_, err = f.WriteAt([]byte(data), n)
 		defer f.Close()
-	}else{
+	} else {
 		f, err := os.OpenFile(path, os.O_WRONLY, 0644)
-		if err!=nil {
+		if err != nil {
 			return err
 		}
 		n, _ := f.Seek(0, 2)
@@ -318,7 +318,7 @@ func SaveBase64ToFileBySeek(content, path string) (err error) {
 	return nil
 }
 
-func PathExists(path string) (bool,error) {
+func PathExists(path string) (bool, error) {
 	_, err := os.Stat(path)
 	if err == nil {
 		return true, nil
@@ -488,33 +488,240 @@ func Sha1(data string) string {
 	return hex.EncodeToString(sha1.Sum([]byte("")))
 }
 
-func GetWeekDay() (weekStr string){
+func GetWeekDay() (weekStr string) {
 	nowWeek := time.Now().Weekday().String()
 	switch nowWeek {
 	case "Monday":
-		weekStr="周一"
+		weekStr = "周一"
 		break
 	case "Tuesday":
-		weekStr="周二"
+		weekStr = "周二"
 		break
 	case "Wednesday":
-		weekStr="周三"
+		weekStr = "周三"
 		break
 	case "Thursday":
-		weekStr="周四"
+		weekStr = "周四"
 		break
 	case "Friday":
-		weekStr="周五"
+		weekStr = "周五"
 		break
 	case "Saturday":
-		weekStr="周六"
+		weekStr = "周六"
 		break
 	case "Sunday":
-		weekStr="周日"
+		weekStr = "周日"
 		break
 	default:
-		weekStr=""
+		weekStr = ""
 		break
 	}
 	return
-}
+}
+
+// GetNowWeekMonday 获取本周周一的时间
+func GetNowWeekMonday() time.Time {
+	offset := int(time.Monday - time.Now().Weekday())
+	if offset == 1 { //正好是周日,但是按照中国人的理解,周日是一周最后一天,而不是一周开始的第一天
+		offset = -6
+	}
+	mondayTime := time.Now().AddDate(0, 0, offset)
+	mondayTime = time.Date(mondayTime.Year(), mondayTime.Month(), mondayTime.Day(), 0, 0, 0, 0, mondayTime.Location())
+	return mondayTime
+}
+
+// GetNowWeekLastDay 获取本周最后一天的时间
+func GetNowWeekLastDay() time.Time {
+	offset := int(time.Monday - time.Now().Weekday())
+	if offset == 1 { //正好是周日,但是按照中国人的理解,周日是一周最后一天,而不是一周开始的第一天
+		offset = -6
+	}
+	firstDayTime := time.Now().AddDate(0, 0, offset)
+	firstDayTime = time.Date(firstDayTime.Year(), firstDayTime.Month(), firstDayTime.Day(), 0, 0, 0, 0, firstDayTime.Location()).AddDate(0, 0, 6)
+	lastDayTime := time.Date(firstDayTime.Year(), firstDayTime.Month(), firstDayTime.Day(), 23, 59, 59, 0, firstDayTime.Location())
+
+	return lastDayTime
+}
+
+// GetNowMonthFirstDay 获取本月第一天的时间
+func GetNowMonthFirstDay() time.Time {
+	nowMonthFirstDay := time.Date(time.Now().Year(), time.Now().Month(), 1, 0, 0, 0, 0, time.Now().Location())
+	return nowMonthFirstDay
+}
+
+// GetNowMonthLastDay 获取本月最后一天的时间
+func GetNowMonthLastDay() time.Time {
+	nowMonthLastDay := time.Date(time.Now().Year(), time.Now().Month(), 1, 0, 0, 0, 0, time.Now().Location()).AddDate(0, 1, -1)
+	nowMonthLastDay = time.Date(nowMonthLastDay.Year(), nowMonthLastDay.Month(), nowMonthLastDay.Day(), 23, 59, 59, 0, nowMonthLastDay.Location())
+	return nowMonthLastDay
+}
+
+// GetNowQuarterFirstDay 获取本季度第一天的时间
+func GetNowQuarterFirstDay() time.Time {
+	month := int(time.Now().Month())
+	var nowQuarterFirstDay time.Time
+	if month >= 1 && month <= 3 {
+		//1月1号
+		nowQuarterFirstDay = time.Date(time.Now().Year(), 1, 1, 0, 0, 0, 0, time.Now().Location())
+	} else if month >= 4 && month <= 6 {
+		//4月1号
+		nowQuarterFirstDay = time.Date(time.Now().Year(), 4, 1, 0, 0, 0, 0, time.Now().Location())
+	} else if month >= 7 && month <= 9 {
+		nowQuarterFirstDay = time.Date(time.Now().Year(), 7, 1, 0, 0, 0, 0, time.Now().Location())
+	} else {
+		nowQuarterFirstDay = time.Date(time.Now().Year(), 10, 1, 0, 0, 0, 0, time.Now().Location())
+	}
+	return nowQuarterFirstDay
+}
+
+// GetNowQuarterLastDay 获取本季度最后一天的时间
+func GetNowQuarterLastDay() time.Time {
+	month := int(time.Now().Month())
+	var nowQuarterLastDay time.Time
+	if month >= 1 && month <= 3 {
+		//03-31 23:59:59
+		nowQuarterLastDay = time.Date(time.Now().Year(), 3, 31, 23, 59, 59, 0, time.Now().Location())
+	} else if month >= 4 && month <= 6 {
+		//06-30 23:59:59
+		nowQuarterLastDay = time.Date(time.Now().Year(), 6, 30, 23, 59, 59, 0, time.Now().Location())
+	} else if month >= 7 && month <= 9 {
+		//09-30 23:59:59
+		nowQuarterLastDay = time.Date(time.Now().Year(), 9, 30, 23, 59, 59, 0, time.Now().Location())
+	} else {
+		//12-31 23:59:59
+		nowQuarterLastDay = time.Date(time.Now().Year(), 12, 31, 23, 59, 59, 0, time.Now().Location())
+	}
+	return nowQuarterLastDay
+}
+
+// GetNowHalfYearFirstDay 获取当前半年的第一天的时间
+func GetNowHalfYearFirstDay() time.Time {
+	month := int(time.Now().Month())
+	var nowHalfYearLastDay time.Time
+	if month >= 1 && month <= 6 {
+		//03-31 23:59:59
+		nowHalfYearLastDay = time.Date(time.Now().Year(), 1, 1, 0, 0, 0, 0, time.Now().Location())
+	} else {
+		//12-31 23:59:59
+		nowHalfYearLastDay = time.Date(time.Now().Year(), 7, 1, 0, 0, 0, 0, time.Now().Location())
+	}
+	return nowHalfYearLastDay
+}
+
+// GetNowHalfYearLastDay 获取当前半年的最后一天的时间
+func GetNowHalfYearLastDay() time.Time {
+	month := int(time.Now().Month())
+	var nowHalfYearLastDay time.Time
+	if month >= 1 && month <= 6 {
+		//03-31 23:59:59
+		nowHalfYearLastDay = time.Date(time.Now().Year(), 6, 30, 23, 59, 59, 0, time.Now().Location())
+	} else {
+		//12-31 23:59:59
+		nowHalfYearLastDay = time.Date(time.Now().Year(), 12, 31, 23, 59, 59, 0, time.Now().Location())
+	}
+	return nowHalfYearLastDay
+}
+
+// GetNowYearFirstDay 获取当前年的最后一天的时间
+func GetNowYearFirstDay() time.Time {
+	//12-31 23:59:59
+	nowYearFirstDay := time.Date(time.Now().Year(), 1, 1, 0, 0, 0, 0, time.Now().Location())
+	return nowYearFirstDay
+}
+
+// GetNowYearLastDay 获取当前年的最后一天的时间
+func GetNowYearLastDay() time.Time {
+	//12-31 23:59:59
+	nowYearLastDay := time.Date(time.Now().Year(), 12, 31, 23, 59, 59, 0, time.Now().Location())
+	return nowYearLastDay
+}
+
+// CalculationDate 计算两个日期之间相差n年m月y天
+func CalculationDate(startDate, endDate time.Time) (beetweenDay string, err error) {
+	//startDate := time.Date(2021, 3, 28, 0, 0, 0, 0, time.Now().Location())
+	//endDate := time.Date(2022, 3, 31, 0, 0, 0, 0, time.Now().Location())
+	numYear := endDate.Year() - startDate.Year()
+
+	numMonth := int(endDate.Month()) - int(startDate.Month())
+
+	numDay := 0
+	//获取截止月的总天数
+	endDateDays := getMonthDay(endDate.Year(), int(endDate.Month()))
+
+	//获取截止月的前一个月
+	endDatePrevMonthDate := endDate.AddDate(0, -1, 0)
+	//获取截止日期的上一个月的总天数
+	endDatePrevMonthDays := getMonthDay(endDatePrevMonthDate.Year(), int(endDatePrevMonthDate.Month()))
+	//获取开始日期的的月份总天数
+	startDateMonthDays := getMonthDay(startDate.Year(), int(startDate.Month()))
+
+	//判断,截止月是否完全被选中,如果相等,那么代表截止月份全部天数被选择
+	if endDate.Day() == endDateDays {
+		numDay = startDateMonthDays - startDate.Day() + 1
+
+		//如果剩余天数正好与开始日期的天数是一致的,那么月份加1
+		if numDay == startDateMonthDays {
+			numMonth++
+			numDay = 0
+			//超过月份了,那么年份加1
+			if numMonth == 12 {
+				numYear++
+				numMonth = 0
+			}
+		}
+	} else {
+		numDay = endDate.Day() - startDate.Day() + 1
+	}
+
+	//天数小于0,那么向月份借一位
+	if numDay < 0 {
+		//向上一个月借一个月的天数
+		numDay += endDatePrevMonthDays
+
+		//总月份减去一个月
+		numMonth = numMonth - 1
+	}
+
+	//月份小于0,那么向年份借一位
+	if numMonth < 0 {
+		//向上一个年借12个月
+		numMonth += 12
+
+		//总年份减去一年
+		numYear = numYear - 1
+	}
+	if numYear < 0 {
+		err = errors.New("日期异常")
+		return
+	}
+
+	if numYear > 0 {
+		beetweenDay += fmt.Sprint(numYear, "年")
+	}
+	if numMonth > 0 {
+		beetweenDay += fmt.Sprint(numMonth, "个月")
+	}
+	if numDay > 0 {
+		beetweenDay += fmt.Sprint(numDay, "天")
+	}
+	return
+}
+
+// getMonthDay 获取某年某月有多少天
+func getMonthDay(year, month int) (days int) {
+	if month != 2 {
+		if month == 4 || month == 6 || month == 9 || month == 11 {
+			days = 30
+
+		} else {
+			days = 31
+		}
+	} else {
+		if ((year%4) == 0 && (year%100) != 0) || (year%400) == 0 {
+			days = 29
+		} else {
+			days = 28
+		}
+	}
+	return
+}

+ 1 - 1
utils/config.go

@@ -86,7 +86,7 @@ ZwIDAQAB
 		AdminId = 11
 		WxAppId = "wx9b5d7291e581233a"
 		WxAppSecret = "f4d52e34021eee262dce9682b31f8861"
-		TemplateId = "P0klzaZjEI2UYth-z-WnmtOQgyxcF8klPoA_MlsA8Eo"
+		TemplateId = "pDk4o924gSZWj80ZdNnHodnLMIXjPSlKZU0ciQMOhec"
 		RemindTemplateId = "9JYV6sHMJlu2EHRBIj_8ift6wkrrTb9_UO-M_-YXKBw"
 		//同花顺测试地址
 		THS_SendUrl = `https://mtest.10jqka.com.cn/gateway/ps/syncNews`