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

View File

@ -0,0 +1,533 @@
// ==========================================================================
// GFast自动生成logic操作代码。
// 生成日期2023-12-12 17:56:19
// 生成路径: internal/app/system/logic/manage_task_record.go
// 生成人gfast
// desc:航线任务下发-记录
// company:云南奇讯科技有限公司
// ==========================================================================
package logic
import (
"context"
"encoding/json"
"errors"
"github.com/tiger1103/gfast/v3/api/webodm"
"github.com/tiger1103/gfast/v3/third/arithmetic/SpartaApi"
"os"
"path"
"path/filepath"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/util/gconv"
"github.com/tiger1103/gfast/v3/api/v1/common/coryCommon"
"github.com/tiger1103/gfast/v3/api/v1/system"
"github.com/tiger1103/gfast/v3/internal/app/system/consts"
"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/entity"
"github.com/tiger1103/gfast/v3/internal/app/system/service"
"github.com/tiger1103/gfast/v3/library/liberr"
"github.com/tiger1103/gfast/v3/third/plane/dj"
"github.com/tiger1103/gfast/v3/third/solaranalyzer"
tool "github.com/tiger1103/gfast/v3/utility/coryUtils"
)
func init() {
service.RegisterManageTaskRecord(New())
}
func New() *sManageTaskRecord {
return &sManageTaskRecord{}
}
type sManageTaskRecord struct{}
func (s *sManageTaskRecord) UpDataResource(ctx context.Context, req *system.UpDataResourceReq) (err error) {
err = g.Try(ctx, func(ctx context.Context) {
rpath1 := coryCommon.ResourcePublicToFunc(req.WImg, 0)
rpath2 := coryCommon.ResourcePublicToFunc(req.WTif, 0)
liberr.ErrIsNil(ctx, err)
_, err = dao.ManageTaskRecord.Ctx(ctx).Where("id", req.Id).Update(
g.Map{
"merge_project_id": req.MergeProjectId,
"merge_id": req.MergeId,
"w_img": rpath1,
"w_tif": rpath2,
})
liberr.ErrIsNil(ctx, err, "资源上传失败")
if req.Id == 753 {
// 将大图交给AI识别
recognizeRequest := SpartaApi.RecognizeReq{
CapUrl: coryCommon.GlobalPath + rpath1,
RecType: SpartaApi.UAV_MATRIX,
Async: "False",
CallBackUrl: "",
AreaHigh: "",
}
recognizeResult, _, recognizeErr := SpartaApi.CommonAlgorithmTwoUav(ctx, &recognizeRequest)
if recognizeErr != nil {
// 删除webdom资源
webodm.DelUuidFunc(req.MergeProjectId, req.MergeId)
// 删除tif、大图合并
img := coryCommon.GetCWD() + coryCommon.FileToFunc(req.WImg, 2)
os.Remove(img)
tif := coryCommon.GetCWD() + coryCommon.FileToFunc(req.WTif, 2)
os.Remove(tif)
// 获取飞机回传下载的资源的目录,进行数据删除(下载到本地的资源)
value, _ := dao.ManageTaskRecord.Ctx(ctx).Where("id", req.Id).Fields("flight_id").Value()
sql := `select
SUBSTRING_INDEX(object_key, '/', 3) as extracted_part
from
manage_task_record_resource
where
flight_id = ` + "'" + value.String() + "'" + `
limit 1`
if value, err := g.DB().GetValue(ctx, sql); err != nil {
os.RemoveAll(coryCommon.Uav + value.String())
}
// 清空数据
_, err = dao.ManageTaskRecord.Ctx(ctx).Where("id", req.Id).Update(
g.Map{
"is_resource_ready": 0,
"merge_project_id": nil,
"merge_id": nil,
"w_img": nil,
"w_tif": nil,
})
if err != nil {
liberr.ErrIsNil(ctx, err, "ai算法")
return
}
}
liberr.ErrIsNil(ctx, recognizeErr)
// 将结果转换为 JSON
recognizeResultJSON, jsonErr := json.Marshal(recognizeResult)
liberr.ErrIsNil(ctx, jsonErr)
// TIF 文件路径
tifFileName := filepath.Base(req.WTif)
tifFilePath := path.Join("resource/public/tif", tifFileName)
solaranalyzer.ParseAIResul2(string(recognizeResultJSON)).
ToGeoPoints(tifFilePath).Run(req.ProjectId, int(req.Id))
}
})
return
}
func (s *sManageTaskRecord) GetAiResult(ctx context.Context, req *system.GetAiResultReq) (*system.GetAiResultRes, error) {
listres := new(system.GetAiResultRes)
// SELECT pv.name, qf.name AS qf_name, sp.project_name AS sp_name
// FROM pv_module pv
// JOIN manage_task_result mtr ON pv.id = mtr.pv_id
// JOIN qianqi_fangzhen qf ON pv.fangzhen_id = qf.id
// JOIN sub_project sp ON pv.sub_projectid = sp.id
// WHERE mtr.task_id = 1 AND pv.type = 15
// ORDER BY qf_name;
// 1、根据任务ID获取AI识别结果
m := dao.ManageTaskResult.Ctx(ctx).As("mtr").
Fields("mtr.id, pv.name, qf.name AS qf_name, sp.project_name AS sp_name,pv.type").
LeftJoin("pv_module pv", "pv.id = mtr.pv_id").
LeftJoin("qianqi_fangzhen qf", "pv.fangzhen_id = qf.id").
LeftJoin("sub_project sp", "pv.sub_projectid = sp.id").
Where("mtr.task_id", req.Id).
Where("pv.type", req.Type).
Order("qf_name")
arr, err := m.Array()
liberr.ErrIsNil(ctx, err, "获取AI识别结果失败")
listres.Total = len(arr)
if req.PageNum == 0 {
req.PageNum = 1
}
listres.CurrentPage = req.PageNum
if req.PageSize == 0 {
req.PageSize = consts.PageSize
}
err = m.Page(req.PageNum, req.PageSize).Scan(&listres.List)
liberr.ErrIsNil(ctx, err, "获取AI识别结果失败")
return listres, nil
}
// ConfirmAiResult 提交 AI 识别结果
func (s *sManageTaskRecord) ConfirmAiResult(ctx context.Context, req *system.ConfirmAiResultReq) error {
taskID := req.TaskId
return solaranalyzer.UpdateTableData(taskID)
}
func getWorkStatusJSON(ctx context.Context, projectID string) (string, error) {
// 1、根据项目ID获取子项目
subProject := g.Model("sub_project").Fields("id").Where("project_id", projectID)
workStatusList := []entity.PvModule{}
if err := dao.PvModule.Ctx(ctx).WhereIn(dao.PvModule.Columns().SubProjectid, subProject).
WhereNot(dao.PvModule.Columns().Status, 2).
Where(dao.PvModule.Columns().Type, 15).Scan(&workStatusList); err != nil {
return "", err
}
workStatusJSON, err := json.Marshal(workStatusList)
if err != nil {
return "", err
}
return string(workStatusJSON), nil
}
func (s *sManageTaskRecord) FlighttaskResourceGetFunc(ctx context.Context, req *system.ManageTaskRecordDeleteReq) (err error) {
//err = g.Try(ctx, func(ctx context.Context) {
// for _, id := range req.Ids {
// var mtr *model.ManageTaskRecordInfoRes
// dao.ManageTaskRecord.Ctx(ctx).WherePri(id).Scan(&mtr)
// err, reply := mqtt.Flighttask_undo(mtr.MqClientId, strings.Split(mtr.FlightId, ","))
// liberr.ErrIsNil(ctx, err, "取消任务失败")
// if reply.Data.Result > 0 {
// err = mqtt.Geterror(reply.Data.Result)
// liberr.ErrIsNil(ctx, err)
// return
// }
// }
// _, err = dao.ManageTaskRecord.Ctx(ctx).Delete(dao.ManageTaskRecord.Columns().Id+" in (?)", req.Ids)
// liberr.ErrIsNil(ctx, err, "删除失败")
//})
return
}
func (s *sManageTaskRecord) List(ctx context.Context, req *system.ManageTaskRecordSearchReq) (listRes *system.ManageTaskRecordSearchRes, err error) {
listRes = new(system.ManageTaskRecordSearchRes)
err = g.Try(ctx, func(ctx context.Context) {
m := dao.ManageTaskRecord.Ctx(ctx).WithAll().As("a").
LeftJoin("manage_task", "b", "a.task_id = b.id").
Fields("a.*,b.air_line as airLine")
if req.ProjectId != "" {
m = m.Where("a."+dao.ManageTaskRecord.Columns().ProjectId+" = ?", req.ProjectId)
}
if req.IsVoluntarily != "" {
m = m.Where("a."+dao.ManageTaskRecord.Columns().IsVoluntarily+" = ?", req.IsVoluntarily)
}
if req.MqClientId != "" {
m = m.Where("a."+dao.ManageTaskRecord.Columns().MqClientId+" = ?", req.MqClientId)
}
if req.TaskType != "" {
m = m.Where("a."+dao.ManageTaskRecord.Columns().TaskType, req.TaskType)
}
// 创建时间模糊查询
if req.CreatedAt != "" {
date := tool.New().GetFormattedDate(gconv.Time(req.CreatedAt))
m = m.Where("a."+dao.ManageTaskRecord.Columns().CreatedAt+" like ?", "%"+date+"%")
}
if len(req.DateRange) != 0 {
m = m.Where("a."+dao.ManageTaskRecord.Columns().CreatedAt+" >=? AND "+"a."+dao.ManageTaskRecord.Columns().CreatedAt+" <=?", req.DateRange[0], req.DateRange[1])
}
arr, err := m.Array()
listRes.Total = len(arr)
liberr.ErrIsNil(ctx, err, "获取总行数失败")
if req.PageNum == 0 {
req.PageNum = 1
}
listRes.CurrentPage = req.PageNum
if req.PageSize == 0 {
req.PageSize = consts.PageSize
}
order := "id desc"
if req.OrderBy != "" {
order = req.OrderBy
}
var res []*model.ManageTaskRecordInfoRes
err = m.Page(req.PageNum, req.PageSize).Order("a." + order).Scan(&res)
liberr.ErrIsNil(ctx, err, "获取数据失败")
listRes.List = make([]*model.PcListOfRoutesRes, len(res))
for k, v := range res {
// 实际回传数量
count, countErr := dao.ManageTaskRecordResource.Ctx(ctx).Where("flight_id", v.FlightId).Count()
liberr.ErrIsNil(ctx, countErr)
/**
按钮显示与隐藏
*/
var a []int
// 1、执行任务时间为null那么只显示【执行任务1】【删除任务6】
if v.ExecuteTheTask == 0 {
a = []int{1, 6}
}
// 2、执行任务时间不为null那么显示【航线暂停2】【恢复航线3】【一键返航4】
if v.ExecuteTheTask != 0 {
if v.RouteId != 65535 {
a = []int{4}
}
if v.IsSuspend == "0" || v.IsSuspend == "" {
a = append(a, 2)
} else if v.IsSuspend == "1" {
a = append(a, 3)
}
}
// 3、航线完成那么显示【断点续飞5】【删除任务6】--------》如果断点没有中断原因就不显示断点续飞
if v.Accomplish > 0 {
a = []int{6}
if v.InterruptCause != 0 {
a = append(a, 5)
}
} else if v.RouteId == 65535 {
a = []int{6}
}
// 获取当前航线的航点,然后*当前飞机的
listRes.List[k] = &model.PcListOfRoutesRes{
Id: v.Id,
TaskId: v.TaskId,
FlightId: v.FlightId,
ExecuteTheTask: v.ExecuteTheTask,
Accomplish: v.Accomplish,
TaskName: v.TaskName,
AirLine: v.AirLine,
Remark: v.Remark,
IsResourceReady: v.IsResourceReady,
IsVoluntarily: v.IsVoluntarily,
EstimatedQuantity: v.Waypoint,
ActualReturn: count,
IsButton: a,
InterruptCause: v.InterruptCause,
// InterruptCauseCode: handleErrorCode(v.InterruptCause),
MergeProjectId: v.MergeProjectId,
MergeId: v.MergeId,
WImg: coryCommon.ResourcePublicToFunc(v.WImg, 0),
WTif: coryCommon.ResourcePublicToFunc(v.WTif, 0),
}
}
})
return
}
func (s *sManageTaskRecord) GetById(ctx context.Context, id int64) (res *model.ManageTaskRecordInfoRes, err error) {
err = g.Try(ctx, func(ctx context.Context) {
err = dao.ManageTaskRecord.Ctx(ctx).WithAll().Where(dao.ManageTaskRecord.Columns().Id, id).Scan(&res)
liberr.ErrIsNil(ctx, err, "获取信息失败")
})
return
}
// GetManageAirlineFile 获取航线文件及md5加密
func GetManageAirlineFile(flightId string) (res *dj.FileEntity, err error) {
dao.ManageTaskRecord.Ctx(gctx.New()).As("a").
LeftJoin("manage_task", "b", "b.id = a.task_id").
LeftJoin("manage_airline", "c", "c.id = b.air_line").
Where("a.flight_id", flightId).
Fields(" c.file_path as url,c.fingerprint").
Scan(&res)
res.Url = coryCommon.GlobalPath + res.Url
return
}
// GetTheTaskDataBasedOnTheTaskId 根据任务id得到任务数据然后根据任务数据得到航线信息和飞机摄像头信息
func GetTheTaskDataBasedOnTheTaskId(ctx context.Context, task int64) (number int, err error) {
err = g.Try(ctx, func(ctx context.Context) {
// 1、根据任务id得到任务数据
var entity *model.ManageTaskRecordInfoRes
dao.ManageTask.Ctx(gctx.New()).Ctx(ctx).WherePri(task).Fields(dao.ManageTask.Columns().MqClientId + "," + dao.ManageTask.Columns().AirLine).Scan(&entity)
if entity == nil {
return
}
// 2、获取航线的航点个数
var hd []model.PositionsEntity
value, err := dao.ManageAirline.Ctx(ctx).WherePri(entity.AirLine).Fields("positions").Value()
if err != nil {
err = errors.New("获取航点失败!")
liberr.ErrIsNil(ctx, err)
return
}
err = json.Unmarshal(value.Bytes(), &hd)
liberr.ErrIsNil(ctx, err)
// 3、获取到当前飞机的摄像头个数
count, _ := g.DB().Model("manage_device_video").Ctx(ctx).
Where("gateway_sn", entity.MqClientId).
Where("type = 1").Count()
// 4、计算预估摄像头数量
number = len(hd) * count
})
return
}
func handleErrorCode(code int) (str string) {
switch code {
case 0:
str = "无异常"
case 1:
str = "Mission ID 不存在,该航线任务未执行"
case 2:
str = "不常见错误,建议联系技术支持"
case 4:
str = "请求开始/恢复航线任务时,航线文件加载出错,请重新尝试上传文件开始或联系技术支持"
case 5:
str = "请求查询断点信息时,查询断点文件失败。请求恢复航线任务时,解析断点类型失败"
case 6:
str = "请求开始/结束航线任务时cmd 参数有误,协议请求的指令有误。请求恢复航线任务时,解析断点类型失败"
case 7:
str = "请求开始/恢复航线任务时,解析 wpmz 文件超时,请重试"
case 257:
str = "航线已经开始,不能再次开始"
case 258:
str = "此状态下无法中断航线,只允许在航线执行状态时暂停航线"
case 259:
str = "航线未开始,不能结束航线"
case 261:
str = "飞行任务冲突,无法获取飞行器控制权,不允许在降落和返航中开始航线"
case 262:
str = "该状态下无法恢复航线,只允许在航线暂停状态时恢复航线"
case 513:
str = "飞行器超过限高高度"
case 514:
str = "飞行器超过限远距离"
case 516:
str = "飞行器触发限低"
case 517:
str = "飞行器触发避障"
case 518:
str = "RTK 信号差"
case 519:
str = "接近禁飞区边界"
case 521:
str = "超过机场限飞区限高"
case 522:
str = "航线请求起飞失败"
case 523:
str = "起飞任务执行失败"
case 524:
str = "请求航线任务失败"
case 526:
str = "请求航线 RTK 收敛任务失败"
case 527:
str = "航线 RTK 收敛任务运行失败"
case 528:
str = "接近用户自定义飞行区边界"
case 769:
str = "GPS 信号弱"
case 770:
str = "遥控器档位不在 N 档,无法开始任务"
case 771:
str = "返航点未刷新"
case 772:
str = "当前电量过低无法开始任务"
case 773:
str = "低电量返航导致航线中断"
case 775:
str = "遥控器与飞行器失联"
case 778:
str = "飞行器在地面起桨,不允许开始航线"
case 779:
str = "实时仿地过程中,视觉状态异常(如过亮,过暗,两侧亮度不一致)"
case 780:
str = "实时仿地用户设置的仿地高度不合法(大于 200 m 或者小于 30 m"
case 781:
str = "实时仿地过程中全局地图计算出错"
case 784:
str = "大风返航导致航线中断"
case 1281:
str = "用户退出"
case 1282:
str = "用户中断"
case 1283:
str = "用户触发返航"
case 1539:
str = "开始信息(航点 index 或者 progress错误"
case 1540:
str = "使用不支持的坐标系"
case 1541:
str = "使用不支持的高度模式"
case 1542:
str = "使用不支持的过渡航线模式"
case 1543:
str = "使用不支持的 yaw 模式"
case 1544:
str = "使用不支持的 yaw 方向调转模式"
case 1545:
str = "使用不支持的航点类型"
case 1546:
str = "首尾点不能使用协调转弯类型"
case 1547:
str = "航线全局速度超过合理范围"
case 1548:
str = "航点数量异常"
case 1549:
str = "经纬度数据异常"
case 1550:
str = "转弯截距异常"
case 1551:
str = "航段最大速度超过合理范围"
case 1552:
str = "航段目标速度超过合理范围"
case 1553:
str = "航点 yaw 角度超过合理范围"
case 1555:
str = "断点续飞的 mission_id 输入错误"
case 1556:
str = "断点续飞的 progress 信息输入错误"
case 1557:
str = "断点续飞的任务状态异常"
case 1558:
str = "断点续飞的航点 index 信息输入错误"
case 1559:
str = "断点续飞的经纬度信息输入错误"
case 1560:
str = "断点续飞的航点 yaw 输入错误"
case 1561:
str = "断点续飞的标志位设置错误"
case 1563:
str = "航线生成失败"
case 1564:
str = "航线运行失败"
case 1565:
str = "航线避障紧急刹停"
case 1588:
str = "无法识别的动作类型"
case 1595:
str = "同一动作组内动作 ID 不能重复"
case 1598:
str = "动作 ID 值不能为 65535"
case 1602:
str = "动作组数量超过合理范围"
case 1603:
str = "动作组生效范围错误"
case 1606:
str = "断点续飞中动作 index 超过合理范围"
case 1608:
str = "断点信息中触发器运行结果异常"
case 1609:
str = "断点续飞中动作组 ID 信息不能重复"
case 1610:
str = "断点续飞中动作组位置不能重复"
case 1611:
str = "断点续飞中动作组位置超过合理范围"
case 1612:
str = "续飞中动作 ID 不在断点信息中"
case 1613:
str = "续飞中不能修改动作状态为中断"
case 1614:
str = "断点信息错误导致续飞失败"
case 1634:
str = "无法识别的动作类型"
case 1649:
str = "无法识别的触发器类型"
case 65534:
str = "未知错误"
case 65535:
str = "未知错误"
default:
str = "未定义的错误码"
}
return
}