306 lines
10 KiB
Go
306 lines
10 KiB
Go
/*
|
||
* @desc:定时任务配置
|
||
* @company:云南省奇讯科技有限公司
|
||
* @Author: yixiaohu
|
||
* @Date: 2021/7/16 15:45
|
||
*/
|
||
|
||
package task
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"github.com/robfig/cron/v3"
|
||
"github.com/tiger1103/gfast/v3/internal/app/system/controller"
|
||
"github.com/tiger1103/gfast/v3/third/arithmetic/SpartaApi"
|
||
"github.com/tiger1103/gfast/v3/third/jiguang"
|
||
"github.com/tiger1103/gfast/v3/third/reminders"
|
||
"log"
|
||
"os"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/gogf/gf/v2/database/gdb"
|
||
"github.com/gogf/gf/v2/frame/g"
|
||
"github.com/gogf/gf/v2/os/gctx"
|
||
"github.com/tiger1103/gfast/v3/api/v1/common/coryCommon"
|
||
"github.com/tiger1103/gfast/v3/internal/app/system/dao"
|
||
logicDocumentData "github.com/tiger1103/gfast/v3/internal/app/system/logic/documentData"
|
||
"github.com/tiger1103/gfast/v3/internal/app/system/model"
|
||
"github.com/tiger1103/gfast/v3/internal/app/system/model/entity"
|
||
"github.com/tiger1103/gfast/v3/internal/app/system/service"
|
||
wxModel "github.com/tiger1103/gfast/v3/internal/app/wxApplet/model"
|
||
wxService "github.com/tiger1103/gfast/v3/internal/app/wxApplet/service"
|
||
"github.com/tiger1103/gfast/v3/library/liberr"
|
||
)
|
||
|
||
func Run() {
|
||
task1 := &model.TimeTask{
|
||
FuncName: "test1",
|
||
//Run: Test1,
|
||
Run: SpartaApi.CORYAInit,
|
||
}
|
||
task2 := &model.TimeTask{
|
||
FuncName: "test2",
|
||
Run: Test2,
|
||
}
|
||
checkUserOnlineTask := &model.TimeTask{
|
||
FuncName: "checkUserOnline",
|
||
Run: service.SysUserOnline().CheckUserOnline,
|
||
}
|
||
// ys7快照
|
||
periodicCameraSnapshotTask := &model.TimeTask{
|
||
FuncName: "periodicCameraSnapshot",
|
||
Run: controller.PeriodicSnapshotFunc,
|
||
}
|
||
theNewsAgencyIsActivatedA1amEveryDay := &model.TimeTask{
|
||
FuncName: "theNewsAgencyIsActivatedA1amEveryDay",
|
||
Run: StartNewsAgencyTicker,
|
||
}
|
||
DailyAbsenteeism := &model.TimeTask{
|
||
FuncName: "dailyAbsenteeism",
|
||
Run: wxService.BusAttendance().DailyAbsenteeismFunc,
|
||
}
|
||
deleteTemporaryFilesPeriodicallyTask := &model.TimeTask{
|
||
FuncName: "deleteTemporaryFilesPeriodically",
|
||
Run: DeleteTemporaryFilesPeriodicallyFunc,
|
||
}
|
||
theRecycleBinIsEmptyTask := &model.TimeTask{
|
||
FuncName: "theRecycleBinIsEmpty",
|
||
Run: TheRecycleBinIsEmptyFunc,
|
||
}
|
||
updateProjectStatusTask := &model.TimeTask{
|
||
FuncName: "updateProjectStatus",
|
||
Run: UpdateProjectStatus,
|
||
}
|
||
|
||
service.TaskList().AddTask(task1)
|
||
service.TaskList().AddTask(task2)
|
||
service.TaskList().AddTask(checkUserOnlineTask)
|
||
service.TaskList().AddTask(periodicCameraSnapshotTask)
|
||
service.TaskList().AddTask(theNewsAgencyIsActivatedA1amEveryDay)
|
||
service.TaskList().AddTask(DailyAbsenteeism)
|
||
service.TaskList().AddTask(deleteTemporaryFilesPeriodicallyTask) // 清空临时文件夹
|
||
service.TaskList().AddTask(theRecycleBinIsEmptyTask)
|
||
service.TaskList().AddTask(updateProjectStatusTask)
|
||
ctx := gctx.New()
|
||
// 自动执行已开启的任务
|
||
jobs, err := service.SysJob().GetJobs(ctx)
|
||
if err != nil {
|
||
g.Log().Error(ctx, err)
|
||
return
|
||
}
|
||
for _, job := range jobs {
|
||
service.SysJob().JobStart(ctx, job)
|
||
}
|
||
}
|
||
|
||
func DeleteTemporaryFilesPeriodicallyFunc(ctx context.Context) {
|
||
directoryPath := coryCommon.GetCWD() + coryCommon.Temporary
|
||
// 调用删除函数
|
||
if err := coryCommon.RemoveAllFilesInDirectory(directoryPath); err != nil {
|
||
fmt.Println("Error:", err)
|
||
return
|
||
}
|
||
//删除摄像头记录表(这里的记录关联了临时文件的资源)
|
||
// 计算 30 天前的时间
|
||
//thirtyDaysAgo := gtime.Now().AddDate(0, 0, -30).Format("Y-m-d H:i:s")
|
||
//dao.Ys7DevicesImg.Ctx(ctx).Where("created_at < ?", thirtyDaysAgo).Delete()
|
||
dao.Ys7DevicesImg.Ctx(ctx).WhereNotNull(dao.Ys7DevicesImg.Columns().Name).Delete()
|
||
}
|
||
|
||
// TheRecycleBinIsEmptyFunc 先查询出所有删除数据(删除时间+30天) 小于当前时间,那么就删除
|
||
func TheRecycleBinIsEmptyFunc(ctx context.Context) {
|
||
tableNames := []string{
|
||
dao.Document.Table(), // 模板
|
||
dao.DocumentData.Table(), // 资料
|
||
dao.DocumentCompletion.Table(), // 竣工
|
||
dao.DocumentProductionDrawing.Table(), // 施工
|
||
dao.DocumentReport.Table(), // 可研
|
||
dao.DocumentQualityMeeting.Table(), // 质量会议
|
||
dao.DocumentSafetyMeeting.Table(), // 安全会议
|
||
}
|
||
for i := range tableNames {
|
||
DelDocumentFunc(ctx, tableNames[i])
|
||
}
|
||
}
|
||
|
||
func DelDocumentFunc(ctx context.Context, table string) (err error) {
|
||
err = g.Try(ctx, func(ctx context.Context) {
|
||
var ddlr []*model.DocumentListRes
|
||
g.DB().Model(table).Ctx(ctx).Unscoped().Where(gdb.Raw("DATE_ADD(deleted_at, INTERVAL 30 DAY) < now()")).WhereNotNull("deleted_at").Fields("id,filen_path").Scan(&ddlr)
|
||
if len(ddlr) > 0 {
|
||
var idArrDdlr []int64
|
||
// 1、删除路径对应的文件
|
||
for _, data := range ddlr {
|
||
os.RemoveAll(coryCommon.FileToFunc(data.FilenPath, 2))
|
||
idList := logicDocumentData.RecursiveDeletion(ctx, data.Id)
|
||
if idList != nil {
|
||
idArrDdlr = append(idArrDdlr, idList...)
|
||
}
|
||
idArrDdlr = append(idArrDdlr, data.Id)
|
||
}
|
||
// 2、删除对应文档
|
||
_, err = g.DB().Model(table).Ctx(ctx).Unscoped().Delete(dao.Document.Columns().Id+" in (?)", idArrDdlr)
|
||
liberr.ErrIsNil(ctx, err)
|
||
// 3、删除对应文档的操作记录.
|
||
_, err = g.DB().Model("bus_design_document_record").Ctx(ctx).
|
||
Where("table_name", table).
|
||
Where("table_id in (?)", idArrDdlr).Delete()
|
||
liberr.ErrIsNil(ctx, err)
|
||
}
|
||
})
|
||
return err
|
||
}
|
||
|
||
// 获取所有的子项目后,如果子项目的总量和完成量相等,则将其子项目添加完成日期
|
||
func UpdateProjectStatus(ctx context.Context) {
|
||
// 获取所有的子项目
|
||
var projectList []entity.SubProject
|
||
if err := dao.SubProject.Ctx(ctx).Scan(&projectList); err != nil {
|
||
return
|
||
}
|
||
|
||
// 遍历每个项目
|
||
for _, project := range projectList {
|
||
result, err := dao.WorkStatus.Ctx(ctx).Where(dao.WorkStatus.Columns().SubProjectid, project.Id).Fields("sum(total) as total ,sum(finished) as finished").All()
|
||
if err != nil {
|
||
continue
|
||
}
|
||
|
||
total := result[0]["total"].Int()
|
||
finished := result[0]["finished"].Int()
|
||
|
||
if total == 0 || finished == 0 {
|
||
continue
|
||
}
|
||
|
||
// 如果总量和完成量相等,则将其子项目添加完成日期
|
||
if total == finished {
|
||
// 更新项目状态
|
||
dao.SubProject.Ctx(ctx).Where(dao.SubProject.Columns().Id, project.Id).
|
||
WhereNull(dao.SubProject.Columns().DoneTime).
|
||
Update(g.Map{
|
||
dao.SubProject.Columns().DoneTime: time.Now().Format("2006-01-02"),
|
||
})
|
||
}
|
||
}
|
||
}
|
||
|
||
//===========================================上下班打卡提醒业务===========================================
|
||
//===========================================上下班打卡提醒业务===========================================
|
||
//===========================================上下班打卡提醒业务===========================================
|
||
|
||
var onAndOffDuty = cron.New(cron.WithSeconds())
|
||
|
||
func StartNewsAgencyTicker(ctx context.Context) {
|
||
|
||
//停止onAndOffDuty所有的cron
|
||
entries := onAndOffDuty.Entries()
|
||
for i := range entries {
|
||
onAndOffDuty.Remove(entries[i].ID)
|
||
}
|
||
|
||
//获取所有项目的打卡范围
|
||
var projectEntity []model.SysProjectListRes
|
||
if err := dao.SysProject.Ctx(ctx).
|
||
Where("status", 0).
|
||
//Where("show_hidden", 1).
|
||
Fields("id,project_name,punch_range").
|
||
Scan(&projectEntity); err != nil {
|
||
log.Printf("获取项目失败:%v", err)
|
||
if err != nil {
|
||
return
|
||
}
|
||
}
|
||
// 遍历项目列表
|
||
for _, pData := range projectEntity {
|
||
fmt.Println(pData.ProjectName, "--", pData.Id, "--", pData.PunchRange)
|
||
|
||
punchRange := pData.PunchRange
|
||
split := strings.Split(punchRange, ",")
|
||
// 解析上班时间并设置上班前 60 分钟的定时任务
|
||
workStartTime, err := time.Parse("15:04", split[0])
|
||
if err != nil {
|
||
log.Printf("解析上班时间字符串失败:%v", err)
|
||
continue
|
||
}
|
||
a := pData
|
||
|
||
workStartTime = workStartTime.Add(-60 * time.Minute)
|
||
_, err = onAndOffDuty.AddFunc(fmt.Sprintf("1 %d %d * * *", workStartTime.Minute(), workStartTime.Hour()), func() {
|
||
go sendReminder(ctx, a, 0)
|
||
})
|
||
// 解析下班时间并设置下班前 10 分钟的定时任务
|
||
workEndTime, err := time.Parse("15:04", split[1])
|
||
if err != nil {
|
||
log.Printf("解析下班时间字符串失败:%v", err)
|
||
continue
|
||
}
|
||
//workEndTime = workEndTime.Add(-2 * time.Minute)
|
||
_, err = onAndOffDuty.AddFunc(fmt.Sprintf("1 %d %d * * *", workEndTime.Minute(), workEndTime.Hour()), func() {
|
||
go sendReminder(ctx, a, 1)
|
||
})
|
||
}
|
||
onAndOffDuty.Start()
|
||
}
|
||
|
||
// 发送提醒
|
||
func sendReminder(ctx context.Context, pData model.SysProjectListRes, ii int) {
|
||
// 获取当前项目下面的所有成员
|
||
var openidList []*wxModel.BusConstructionUserListRes
|
||
if err := dao.BusConstructionUser.Ctx(ctx).
|
||
Fields("project_id,openid").
|
||
Where("status = 0").
|
||
Where("entry_date is not null and entry_date!='' and (leave_date is null or leave_date = '')").
|
||
Where("project_id", pData.Id).
|
||
Scan(&openidList); err != nil {
|
||
log.Printf("获取项目成员失败:%v", err)
|
||
return
|
||
}
|
||
commuter := ""
|
||
typeInt := 0
|
||
if ii == 0 {
|
||
typeInt = reminders.CheckIn
|
||
commuter = "上班"
|
||
} else {
|
||
typeInt = reminders.CheckOut
|
||
commuter = "下班"
|
||
}
|
||
// 记录当前openid对应最后一次登录的设备id,然后推送app通知信息
|
||
openids := []string{}
|
||
now := time.Now()
|
||
currentDate := now.Format("2006-01-02")
|
||
for _, oi := range openidList {
|
||
openids = append(openids, oi.Openid)
|
||
message := reminders.Reminder{
|
||
Type: typeInt,
|
||
Status: reminders.Remind,
|
||
Title: "中煤" + currentDate + commuter + "打卡提醒",
|
||
Content: "即将进入打卡时间,请前往打卡(如若休息请忽略!)",
|
||
ProjectID: int(oi.ProjectId),
|
||
ReceiverID: oi.Openid,
|
||
}
|
||
// 发布提醒
|
||
reminders.PublishReminder(message, false)
|
||
}
|
||
deviceId := []string{}
|
||
array, err := g.DB().Model("user_registration").Ctx(ctx).WhereIn("open_id", openids).Fields("registration_id").Array()
|
||
for _, value := range array {
|
||
deviceId = append(deviceId, value.String())
|
||
}
|
||
if err == nil && len(deviceId) > 0 {
|
||
//推送app通知
|
||
go jiguang.SendAppClockingNotice(ctx, deviceId, currentDate, commuter)
|
||
}
|
||
}
|
||
|
||
// @Title 函数名称 2024/8/19 11:16:00
|
||
// @Description 存储摄像头拍到的所有图片(这些数据每月月初会删掉)
|
||
// @Auth Cory
|
||
// @param 输入参数名 ---> "参数解释"
|
||
// @Return error ---> "错误信息"
|
||
func aaaaaa() {
|
||
|
||
}
|