This commit is contained in:
2025-07-07 20:11:59 +08:00
parent ab0fdbc447
commit 06e3aa2eb3
2009 changed files with 193082 additions and 0 deletions

305
task/bind_function.go Normal file
View File

@ -0,0 +1,305 @@
/*
* @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() {
}

81
task/demo.go Normal file
View File

@ -0,0 +1,81 @@
/*
* @desc:测试定时任务
* @company:云南省奇讯科技有限公司
* @Author: yixiaohu
* @Date: 2021/7/16 15:52
*/
package task
import (
"context"
"fmt"
"github.com/gogf/gf/v2/os/gtime"
"github.com/tiger1103/gfast/v3/internal/app/system/dao"
"github.com/tiger1103/gfast/v3/internal/app/system/model"
"github.com/tiger1103/gfast/v3/internal/app/system/model/do"
"github.com/tiger1103/gfast/v3/internal/app/system/service"
wxDao "github.com/tiger1103/gfast/v3/internal/app/wxApplet/dao"
"github.com/tiger1103/gfast/v3/third/thirdParty"
)
func Test1(ctx context.Context) {
fmt.Println("无参测试")
service.SysJobLog().Add(ctx, &do.SysJobLog{
TargetName: "test1",
CreatedAt: gtime.Now(),
Result: "无参测试运行成功",
})
}
func Test2(ctx context.Context) {
//1、获取到app用户表中项目id为60的且没有删除的所有用户
columns := dao.BusConstructionUser.Columns()
var listData []*model.DiSanFang
dao.BusConstructionUser.Ctx(ctx).As("a").
LeftJoin(wxDao.SysProjectTeamMember.Table()+" as b", "b.team_id = a.team_id and b.openid=a.openid").
Where("a."+columns.ProjectId, 60).
WhereNotNull("a." + columns.SfzNumber).
Fields("a.*,b.post_id").Scan(&listData)
//2、调用第三方接口
if listData != nil && len(listData) > 0 {
//处理得到数据
var rr []*thirdParty.RealUser
for _, datum := range listData {
//判断是否是班长
classManagerFlag := "0"
if datum.PostId == "10" {
classManagerFlag = "1"
}
rr = append(rr, &thirdParty.RealUser{
UserName: datum.UserName,
ClassManagerFlag: classManagerFlag,
Phone: datum.Phone,
Sex: datum.Sex,
CardType: "0",
CardNumber: datum.SfzNumber,
UserType: "0",
Nation: datum.SfzNation,
Birthday: datum.SfzBirth,
Address: datum.SfzSite,
CardStartTime: datum.SfzStart,
CardEndTime: datum.SfzEnd,
Pic: "http://xny.yj-3d.com:7363" + datum.PacePhoto,
})
}
//调用
batchSize := 10
total := len(rr)
for start := 0; start < total; start += batchSize {
end := start + batchSize
if end > total {
end = total
}
batch := rr[start:end]
err := thirdParty.SendRy(ctx, batch)
if err != nil {
fmt.Println("发送田东人员信息失败", err)
}
}
}
}

124
task/uav_cron.go Normal file
View File

@ -0,0 +1,124 @@
package task
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"github.com/robfig/cron/v3"
"github.com/tiger1103/gfast/v3/api/v1/system"
"github.com/tiger1103/gfast/v3/internal/app/system/controller"
"github.com/tiger1103/gfast/v3/internal/app/system/dao"
"github.com/tiger1103/gfast/v3/internal/app/system/model"
"golang.org/x/net/context"
"strconv"
"time"
)
var c = cron.New(cron.WithSeconds())
// UavRun 启动任务
func UavRun(ctx context.Context) {
//1、获取到所有无人机的任务
var taskEntity []*model.ManageTaskCronInfoRes
err := dao.ManageTaskCron.Ctx(ctx).Scan(&taskEntity)
if err != nil {
g.Log().Error(ctx, err)
return
}
if len(taskEntity) == 0 {
return
}
//2、添加任务到cron中
for _, data := range taskEntity {
// 创建一个包装函数
wrapFunc := func() {
id := data.TaskId
clientId := data.MqClientId
TakeOffFunc(id, clientId)
}
oneId, err := c.AddFunc(data.Cron, wrapFunc)
if err != nil {
g.Log().Error(ctx, err)
return
}
//3、将启动任务得到的任务ID转存到数据库中
_, err = dao.ManageTaskCron.Ctx(ctx).Where(dao.ManageTaskCron.Columns().Id, data.Id).Update(g.Map{"cron_id": oneId})
if err != nil {
g.Log().Error(ctx, err)
return
}
}
//4、启动任务
c.Start()
}
// MidMissionFunc 中途追加或修改任务
func MidMissionFunc() {
time.Sleep(time.Second * 1) //防止sql语句还未插入进数据库
//1、关闭所有任务
c.Stop()
//2、移除所有任务
for _, entry := range c.Entries() {
c.Remove(entry.ID)
}
//3、重新启动任务
ctx := gctx.New()
UavRun(ctx)
}
// OffTimerAllFunc 关闭所有定时器
func OffTimerAllFunc(id int) {
//1、关闭所有任务
c.Stop()
//2、移除所有任务
for _, entry := range c.Entries() {
c.Remove(entry.ID)
}
}
// OffTimerFunc 关闭指定的定时器
func OffTimerFunc(id int) {
c.Remove(cron.EntryID(id))
}
// TakeOffFunc 飞机从下发任务到执行任务一系列操作
func TakeOffFunc(taskId int64, gatewaySn string) {
ctx := context.Background()
//1、获取当前时间毫秒时间戳然后组织数据下发任务
idStr := strconv.FormatInt(taskId, 10)
req := system.FlighttaskPrepareReq{
Id: idStr,
GatewaySn: gatewaySn,
TaskType: "0",
ExecuteTime: time.Now().UnixNano() / int64(time.Millisecond),
Remark: "定时执行飞行任务",
TimedFlight: "ok",
}
recordId, err := controller.FlighttaskPrepareFunc(ctx, &req)
if err != nil {
g.Log("uav").Error(ctx, err)
return
}
//2、等待10秒钟(确保上一个指令执行完毕),然后执行任务
time.Sleep(10 * time.Second)
taskReq := system.PerformATaskReq{
Id: recordId,
GatewaySn: gatewaySn,
}
_, err = controller.ManageTaskRecord.PerformATaskFunc(ctx, &taskReq)
if err != nil {
g.Log("uav").Error(ctx, err)
return
}
}
// ValidateCronExprWithSeconds 用于验证 6 字段的 Cron 表达式
func ValidateCronExprWithSeconds(expr string) error {
// 创建一个支持秒级字段的解析器
parser := cron.NewParser(cron.Second | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor)
_, err := parser.Parse(expr)
return err
}