Compare commits

...

11 Commits

Author SHA1 Message Date
longguancheng
dc1f060aa2 Modifying the route algorithm parameters does indeed cause problems. 2026-01-28 14:56:00 +08:00
longguancheng
ed21719375 Modifying the route algorithm parameters does indeed cause problems. 2026-01-28 14:55:02 +08:00
Bingkun Li
dd3474d28b Change the output of job list query 2026-01-28 14:38:33 +08:00
wangxueshen
1d043819b4 feat:update 2026-01-28 14:32:29 +08:00
wangxueshen
aeaab62a09 feat:修改用户,设备保存问题,任务显示问题 2026-01-28 13:56:23 +08:00
Bingkun Li
b91d363b00 Update banner 2026-01-26 14:51:07 +08:00
Andy Yang
50ea6d790d change map default location 2026-01-26 14:33:52 +08:00
Bingkun Li
9651a62caa Update frontend code, add executing job list selecting 2026-01-26 14:19:53 +08:00
longguancheng
ed6b18574f 修改部分循环引用 2026-01-26 14:12:22 +08:00
longguancheng
dd67784d85 Merge remote-tracking branch 'origin/main' 2026-01-26 11:14:46 +08:00
Bingkun Li
dcb1ce1012 Change application name, and set debug level to info 2026-01-26 11:07:15 +08:00
48 changed files with 2002 additions and 1218 deletions

View File

@ -93,7 +93,15 @@ redis-server.exe --service-uninstall
# 启动前端
## 1. 在frontend目录中执行
```
#npm install
npm install
npm install --save-dev cross-env
npx update-browserslist-db@latest
在 package.json
"serve": "cross-env NODE_OPTIONS=--openssl-legacy-provider vue-cli-service serve",
```
## 2. 拷贝resource目录中的dt-sdk到node-modules目录
## 3. 编译前端代码

View File

@ -12,6 +12,11 @@
<artifactId>skyeye-service-manager</artifactId>
<dependencies>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.60</version>
</dependency>
<!-- 扩展工具包 -->
<dependency>
<groupId>com.zhangy</groupId>

View File

@ -8,8 +8,8 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling
@MapperScan("com.zhangy.skyeye.**.mapper")
@SpringBootApplication(scanBasePackages = "com.zhangy.**")
public class LdApplication {
public class SEApplication {
public static void main(String[] args) {
SpringApplication.run(LdApplication.class, args);
SpringApplication.run(SEApplication.class, args);
}
}

View File

@ -55,6 +55,11 @@ public class JmJobController {
return jobService.selectList(param);
}
@RequestMapping("/execJobs")
public Object selectExecJobs(@Valid @RequestBody JmJobQueryDTO param) {
return jobService.selectExecJobs(param);
}
/**
* 查询详情
*/

View File

@ -23,6 +23,11 @@ public interface JmJobMapper {
*/
List<JmJobDTO> selectList(JmJobQueryDTO param);
/**
* 查询执行中的job
*/
List<JmJobDTO> selectExecJobs(JmJobQueryDTO param);
/**
* 按主键查询
*/

View File

@ -1,15 +1,8 @@
package com.zhangy.skyeye.jm.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zhangy.skyeye.jm.consts.JmJobModeEnum;
import com.zhangy.skyeye.jm.dto.JmJobDTO;
import com.zhangy.skyeye.jm.dto.JmJobKtyDTO;
import com.zhangy.skyeye.jm.dto.JmJobPageDTO;
import com.zhangy.skyeye.jm.dto.JmJobQueryDTO;
import com.zhangy.skyeye.jm.entity.JmJob;
import com.zhangy.skyeye.jm.entity.JmJobExec;
import com.zhangy.skyeye.jm.entity.JmJobPayload;
import com.zhangy.skyeye.jm.entity.JmJobUav;
import java.util.List;

View File

@ -1,7 +1,6 @@
package com.zhangy.skyeye.jm.service;
import com.zhangy.skyeye.jm.entity.JmJobPayload;
import com.zhangy.skyeye.jm.entity.JmJobUav;
import java.util.List;
import java.util.Map;

View File

@ -22,6 +22,11 @@ public interface JmJobService {
*/
List<JmJobDTO> selectList(JmJobQueryDTO param);
/**
* 查找正在执行的job
*/
List<JmJobDTO> selectExecJobs(JmJobQueryDTO param);
/**
* 按主键查询
*/

View File

@ -2,13 +2,10 @@ package com.zhangy.skyeye.jm.service.impl;
import com.zhangy.skyeye.common.extend.exception.ServiceException;
import com.zhangy.skyeye.common.extend.util.ObjectUtil;
import com.zhangy.skyeye.jm.dto.JmJobDTO;
import com.zhangy.skyeye.jm.entity.JmAirline;
import com.zhangy.skyeye.jm.entity.JmAirlineExec;
import com.zhangy.skyeye.jm.mapper.JmAirlineExecMapper;
import com.zhangy.skyeye.jm.mapper.JmAirlineMapper;
import com.zhangy.skyeye.jm.service.JmAirlineExecService;
import com.zhangy.skyeye.jm.service.JmAirlineService;
import com.zhangy.skyeye.publics.consts.ExecStatusEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -22,8 +19,6 @@ public class JmAirlineExecServiceImpl implements JmAirlineExecService {
@Autowired
private JmAirlineExecMapper airlineExecMapper;
@Autowired
private JmAirlineMapper jmAirlineMapper;
@Override
public List<JmAirline> selectByJobExec(Long... jobId) {

View File

@ -1,6 +1,7 @@
package com.zhangy.skyeye.jm.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.zhangy.skyeye.common.extend.exception.ServiceException;
import com.zhangy.skyeye.common.extend.util.ObjectUtil;
import com.zhangy.skyeye.device.consts.PayloadTypeEnum;
@ -18,14 +19,17 @@ import com.zhangy.skyeye.py.service.IPyAirlineService;
import com.zhangy.skyeye.sar.consts.SarImageModeEnum;
import com.zhangy.skyeye.sar.dto.SarFlightPlanDTO;
import com.zhangy.skyeye.sar.util.SpotlightPlanner;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
/**
* 航线规划
*/
@Slf4j
@Service
public class JmAirlinePlanServiceImpl implements JmAirlinePlanService {
@ -38,6 +42,8 @@ public class JmAirlinePlanServiceImpl implements JmAirlinePlanService {
@Override
public Map<Long, List<JmAirline>> plan(JmJobModeEnum jobMode, SarImageModeEnum imageMode, Integer targetType,
List<JmJobUav> uavList, List<List<JmJobPoint>> pointList) {
log.info("航线规划参数:{}||{}||{}||{}|{}", jobMode, imageMode, targetType,
JSON.toJSONString(uavList), JSON.toJSONString(pointList));
checkParam(jobMode, imageMode, targetType);
// 非航线模式需要调算法生成航线需要从缓存取sar坐标
Map<Long, List<JmAirline>> airlineGroup = null;
@ -56,8 +62,6 @@ public class JmAirlinePlanServiceImpl implements JmAirlinePlanService {
*
* @param jobMode
* @param imageMode
* @param uavList
* @param pointList
*/
private void checkParam(JmJobModeEnum jobMode, SarImageModeEnum imageMode, Integer targetType) {
if (imageMode == SarImageModeEnum.JS) {
@ -90,7 +94,7 @@ public class JmAirlinePlanServiceImpl implements JmAirlinePlanService {
uav.setStartLon(startLon);
uav.setStartLat(startLat);
JmJobPoint home = new JmJobPoint(startLon, startLat);
for (List<JmJobPoint> targets: points) {
for (List<JmJobPoint> targets : points) {
JmJobPoint target = targets.get(0);
if (target == null) {
continue;
@ -109,7 +113,6 @@ public class JmAirlinePlanServiceImpl implements JmAirlinePlanService {
*
* @param uav 无人机
* @param home 起飞点
* @param point 目标点
* @return 航线
*/
public JmAirline planJs(JmJobUav uav, JmJobPoint home, JmJobPoint target) {
@ -119,7 +122,7 @@ public class JmAirlinePlanServiceImpl implements JmAirlinePlanService {
home.getLongitude(), home.getLatitude(),
uav.getHeight(), sar.getTheta(), sar.getDirection());
JmAirline airline = new JmAirline();
airline.setFlightType((byte)0);
airline.setFlightType((byte) 0);
double height = plan.getHeight();
airline.setFlightStartLon(plan.getPowerOnLon());
airline.setFlightStartLat(plan.getPowerOnLat());
@ -162,54 +165,79 @@ public class JmAirlinePlanServiceImpl implements JmAirlinePlanService {
* 转为航线算法参数
*/
private PyAirlineParamDTO toKtkxParam(List<List<JmJobPoint>> pointList, List<JmJobUav> uavList) {
List<PyAirlineTargetDTO> pyPointList = new ArrayList<>();
log.info("开始转换 PyAirlineParamDTOpointList 大小: {}, uavList 大小: {}",
pointList.size(), uavList.size());
// 所有无人机共享相同的目标点集扁平化所有区域的点
List<JmJobPoint> allPoints = pointList.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
// 转换为 Python 需要的 double[][] 坐标格式经度在前纬度在后
double[][] coords = allPoints.stream()
.map(p -> new double[]{p.getLongitude(), p.getLatitude()})
.toArray(double[][]::new);
log.info("提取到 {} 个目标点坐标", coords.length);
List<PyAirlineTargetDTO> pyTargets = new ArrayList<>();
List<PyAirlineUavDTO> pyUavList = new ArrayList<>();
for (int i = 0; i < uavList.size(); i++) {
JmJobUav u = uavList.get(i);
// 区域
List<JmJobPoint> points = pointList.get(i);
double[][] coords = points.stream()
.map(point -> new double[] { point.getLongitude(), point.getLatitude() })
.toArray(double[][]::new);
pyPointList.add(new PyAirlineTargetDTO(i, coords));
JmJobUav uav = uavList.get(i);
// 1. 为当前无人机创建目标共享坐标 target id 不同
pyTargets.add(new PyAirlineTargetDTO(i, coords));
// 2. 获取 SAR 载荷必须存在否则抛异常
JmJobPayload sarPayload = findSarPayload(uav);
String sarIp = sarPayload.getIp(); // 已在 findSarPayload 中设置
// 3. 获取载荷最新状态用于起始位置
JmSarStatusDTO status = payloadService.getLastStatus(sarIp);
if (status == null) {
throw ServiceException.errorLog("无法获取 SAR载荷的最新状态");
}
// 4. 如果起飞高度为空则使用载荷当前高度
if (uav.getStartAltitude() == null) {
uav.setStartAltitude((double) status.getAltitude());
log.info("无人机 {} 起飞高度为空,已使用载荷当前高度: {}", uav.getUavId(), uav.getStartAltitude());
}
// 5. 构建 Python UAV DTO
PyAirlineUavDTO pyUav = BeanUtil.copyProperties(uav, PyAirlineUavDTO.class);
pyUav.setId(uav.getUavId());
pyUav.setStartCoord(new double[]{status.getLongitude(), status.getLatitude()});
pyUav.setEndCoord(new double[]{status.getLongitude(), status.getLatitude()}); // 目前起终点相同
pyUav.setConstraint(uav.getHeight());
// 6. 构建 Payload DTO
PyAirlinePayloadDTO payloadDto = BeanUtil.copyProperties(sarPayload, PyAirlinePayloadDTO.class);
payloadDto.setType(PayloadTypeEnum.SAR.getCode());
pyUav.setPayload(payloadDto);
pyUavList.add(pyUav);
}
// 转换为数组Python 端需要数组格式
PyAirlineTargetDTO[] targetListArray = pyTargets.toArray(new PyAirlineTargetDTO[0]);
PyAirlineUavDTO[] uavListArray = pyUavList.toArray(new PyAirlineUavDTO[0]);
PyAirlineParamDTO param = new PyAirlineParamDTO();
param.setTargets(targetListArray);
param.setUavs(uavListArray);
log.info("转换完成,生成 PyAirlineParamDTO{} 个目标组,{} 架无人机",
targetListArray.length, uavListArray.length);
return param;
}
// 载荷
JmJobPayload sar = u.getPayloadList()
.stream()
.filter(jp -> {
Long payloadId = jp.getPayloadId();
SkyeyePayload p = payloadService.getOne(payloadId);
if (p != null && p.getType().equals(PayloadTypeEnum.SAR.getCode())) {
jp.setIp(p.getIp());
/**
* 从无人机载荷列表中查找 SAR 类型载荷并设置 IP
* @param uav 无人机对象
* @return SAR 载荷
* @throws ServiceException 如果没有找到 SAR 载荷
*/
private JmJobPayload findSarPayload(JmJobUav uav) {
return uav.getPayloadList().stream()
.filter(payload -> {
Long payloadId = payload.getPayloadId();
SkyeyePayload skyeyePayload = payloadService.getOne(payloadId);
if (skyeyePayload != null && PayloadTypeEnum.SAR.getCode().equals(skyeyePayload.getType())) {
payload.setIp(skyeyePayload.getIp());
return true;
}
return false;
})
.findFirst()
.orElseThrow( () -> ServiceException.errorLog("存在无人机缺少sar类型载荷"));
PyAirlineUavDTO uav = BeanUtil.copyProperties(u, PyAirlineUavDTO.class);
JmSarStatusDTO statusDTO = payloadService.getLastStatus(sar.getIp());
double startLon = statusDTO.getLongitude();
double startLat = statusDTO.getLatitude();
if (u.getStartAltitude() == null) {
u.setStartAltitude((double) statusDTO.getAltitude());
}
uav.setId(u.getUavId());
uav.setStartCoord(new double[] {startLon, startLat});
uav.setEndCoord(new double[] {startLon, startLat});
uav.setConstraint(u.getHeight());
PyAirlinePayloadDTO payload = BeanUtil.copyProperties(sar, PyAirlinePayloadDTO.class);
payload.setType(PayloadTypeEnum.SAR.getCode());
uav.setPayload(payload);
pyUavList.add(uav);
}
PyAirlineUavDTO[] uavs = pyUavList.toArray(new PyAirlineUavDTO[pyUavList.size()]);
PyAirlineTargetDTO[] targets = pyPointList.toArray(new PyAirlineTargetDTO[pyPointList.size()]);
PyAirlineParamDTO param = new PyAirlineParamDTO();
param.setTargets(targets);
param.setUavs(uavs);
return param;
.orElseThrow(() -> ServiceException.errorLog(
"存在无人机缺少sar类型载荷"));
}
}

View File

@ -13,6 +13,7 @@ import com.zhangy.skyeye.jm.entity.JmImage;
import com.zhangy.skyeye.jm.entity.JmImageItem;
import com.zhangy.skyeye.jm.entity.JmJobPayload;
import com.zhangy.skyeye.jm.mapper.JmImageMapper;
import com.zhangy.skyeye.jm.mapper.JmJobPayloadMapper;
import com.zhangy.skyeye.jm.service.*;
import com.zhangy.skyeye.publics.consts.FileStoreTypeEnum;
import com.zhangy.skyeye.publics.consts.FileTypeEnum;
@ -49,7 +50,7 @@ public class JmImageServiceImpl implements JmImageService {
private IPyImageService detectService;
@Autowired
private JmJobPayloadService jobPayloadService;
private JmJobPayloadMapper jobPayloadMapper;
@Autowired
private ISysFileService fileService;
@ -223,7 +224,7 @@ public class JmImageServiceImpl implements JmImageService {
jobExecId = jobExecDTO.getExecId();
fileType = FileTypeEnum.SAR_IMAGE_HIGH;
srcFileType = FileTypeEnum.SAR_IMAGE_HIGH_SRC;
JmJobPayload sar = jobPayloadService.selectSar(jobId, uavId);
JmJobPayload sar = jobPayloadMapper.selectSar(jobId, uavId);
if (sar == null) {
throw ServiceException.noLog("找不到该任务的SAR载荷");
}

View File

@ -2,9 +2,7 @@ package com.zhangy.skyeye.jm.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.zhangy.skyeye.common.extend.exception.ServiceException;
import com.zhangy.skyeye.common.extend.util.FileUtil;
import com.zhangy.skyeye.common.extend.util.ObjectUtil;
import com.zhangy.skyeye.device.service.IPayloadService;
import com.zhangy.skyeye.jm.dto.JmJobDTO;
import com.zhangy.skyeye.jm.dto.JmJobQueryDTO;
import com.zhangy.skyeye.jm.entity.JmAirlineExec;
@ -13,10 +11,11 @@ import com.zhangy.skyeye.jm.entity.JmJobPoint;
import com.zhangy.skyeye.jm.entity.JmJobUav;
import com.zhangy.skyeye.jm.event.JmJobStatusInitEvent;
import com.zhangy.skyeye.jm.mapper.JmJobExecMapper;
import com.zhangy.skyeye.jm.service.*;
import com.zhangy.skyeye.jm.service.JmAirlineExecService;
import com.zhangy.skyeye.jm.service.JmJobExecService;
import com.zhangy.skyeye.jm.service.JmJobPointService;
import com.zhangy.skyeye.jm.service.JmJobUavService;
import com.zhangy.skyeye.publics.consts.ExecStatusEnum;
import com.zhangy.skyeye.publics.consts.FileTypeEnum;
import com.zhangy.skyeye.publics.service.SysFileTypeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
@ -32,8 +31,6 @@ import java.util.stream.Collectors;
@Service
public class JmJobExecServiceImpl implements JmJobExecService {
@Autowired
private JmJobStatusService jobStatusService;
@Autowired
private JmJobExecMapper jobExecMapper;
@Autowired
@ -42,16 +39,9 @@ public class JmJobExecServiceImpl implements JmJobExecService {
private JmJobPointService jobPointService;
@Autowired
private JmJobUavService jobUavService;
@Autowired
private IPayloadService payloadService;
@Autowired
private ApplicationEventPublisher eventPublisher;
@Autowired
private SysFileTypeService fileTypeService;
@Override
public void initExecutingJobs() {
List<JmJobDTO> executingJobs = this.selectWorking();
@ -183,7 +173,6 @@ public class JmJobExecServiceImpl implements JmJobExecService {
@Transactional
@Override
public void deleteByJobConf(Long... jobConfId) {
Long[] jobExecIds = jobExecMapper.selectByConf(jobConfId).stream().map(e -> e.getId()).toArray(Long[]::new);
jmAirlineExecService.deleteByJob(jobConfId);
jobExecMapper.deleteByConf(jobConfId);
}

View File

@ -38,9 +38,9 @@ public class JmJobPayloadServiceImpl implements JmJobPayloadService {
if (ObjectUtil.isEmpty(jobExecList)) {
return list;
}
Long[] jobExecIds = jobExecList.stream().map(j -> j.getExecId()).distinct().toArray(Long[]::new);
Long[] jobExecIds = jobExecList.stream().map(JmJobDTO::getExecId).distinct().toArray(Long[]::new);
// jobExecList 按照时间倒序排列若有一个任务配置对应多个任务执行时取第一个元素为最新的执行数据
Map<Long, Long> jobConfExecIdMap = jobExecList.stream().collect(Collectors.toMap(j -> j.getConfId(), j -> j.getExecId(), (a, b) -> a));
Map<Long, Long> jobConfExecIdMap = jobExecList.stream().collect(Collectors.toMap(JmJobDTO::getConfId, JmJobDTO::getExecId, (a, b) -> a));
// 图片jobId不应该用confId
Map<Long, Map<Long, List<JmImage>>> imageGroup = sarImageService.selectByJob(FileTypeEnum.SAR_IMAGE_LOW, jobExecIds)
.stream()
@ -86,15 +86,16 @@ public class JmJobPayloadServiceImpl implements JmJobPayloadService {
@Override
public List<JmJobPayload> selectByUav(Long jobId, Long uavId) {
Map<Long, List<JmImage>> imageGroup = sarImageService.selectByUav(FileTypeEnum.SAR_IMAGE_LOW, jobId, uavId)
.stream()
.collect(Collectors.groupingBy(JmImage::getPayloadId));
List<JmJobPayload> list = jobPayloadMapper.selectByUav(jobId, uavId);
list.forEach(e -> {
Long payloadId = e.getPayloadId();
e.setImageList(imageGroup.containsKey(payloadId) ? imageGroup.get(payloadId) : Collections.EMPTY_LIST);
});
return list;
// 没用到
// Map<Long, List<JmImage>> imageGroup = sarImageService.selectByUav(FileTypeEnum.SAR_IMAGE_LOW, jobId, uavId)
// .stream()
// .collect(Collectors.groupingBy(JmImage::getPayloadId));
// List<JmJobPayload> list = jobPayloadMapper.selectByUav(jobId, uavId);
// list.forEach(e -> {
// Long payloadId = e.getPayloadId();
// e.setImageList(imageGroup.containsKey(payloadId) ? imageGroup.get(payloadId) : Collections.EMPTY_LIST);
// });
return jobPayloadMapper.selectByUav(jobId, uavId);
}
@Override

View File

@ -2,6 +2,7 @@ package com.zhangy.skyeye.jm.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhangy.skyeye.common.extend.enums.EnumUtil;
@ -36,10 +37,6 @@ import com.zhangy.skyeye.sar.enums.SarIMUStatusEnum;
import com.zhangy.skyeye.sar.service.ISarControlService;
import com.zhangy.skyeye.sar.service.ISarMtiPointService;
import com.zhangy.skyeye.sar.service.ISarMtiTrailService;
//import com.zhangy.skyeye.smp.dto.SmpSubscriptResDTO;
//import com.zhangy.skyeye.smp.dto.SmpWayPointDTO;
//import com.zhangy.skyeye.smp.service.ISmpSubscriptService;
//import com.zhangy.skyeye.smp.service.ISmpWayPointService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -69,33 +66,20 @@ public class JmJobServiceImpl implements JmJobService {
private JmJobStatusService jobStatusService;
@Autowired
private JmJobExecService jmJobExecService;
// @Autowired
// private ISmpWayPointService smpWayPointService;
// @Autowired
// private ISmpSubscriptService smpSubscriptService;
@Autowired
private ISarControlService sarControlService;
@Autowired
private ISarMtiPointService sarMtiPointService;
@Autowired
private ISarMtiTrailService sarMtiTrailService;
@Autowired
private IPayloadService payloadService;
@Autowired
private IUavService uavService;
@Autowired
private SysFileTypeService fileTypeService;
@Autowired
private IPyAirlineService ktkxService;
@Autowired
private QuartzService quartzService;
@Autowired
private JmAirlinePlanService jmAirlinePlanService;
@ -113,6 +97,13 @@ public class JmJobServiceImpl implements JmJobService {
return list;
}
@Override
public List<JmJobDTO> selectExecJobs(JmJobQueryDTO param) {
List<JmJobDTO> list = jobMapper.selectExecJobs(param);
loadDetail(param.getUavId(), list);
return list;
}
private void loadDetail(Long uavId, List<JmJobDTO> list) {
if (ObjectUtil.isEmpty(list)) {
return;
@ -157,6 +148,7 @@ public class JmJobServiceImpl implements JmJobService {
@Transactional
@Override
public JmJobDTO save(JmJobModeEnum jobMode, JmJobDTO e) {
log.info("保存任务参数:{}||{}", JSON.toJSONString(jobMode), JSON.toJSONString(e));
SarImageModeEnum imageMode = EnumUtil.parseEx(SarImageModeEnum.class, e.getImageMode());
// 非航线模式需要调算法生成航线需要从缓存取sar坐标
Map<Long, List<JmAirline>> airlineGroup = jmAirlinePlanService.plan(jobMode, imageMode, e.getTargetType(),
@ -202,7 +194,7 @@ public class JmJobServiceImpl implements JmJobService {
*/
private JmJobPayload checkAndSetPayload(List<JmJobPayload> payloadParamList) {
JmJobPayload sar = null;
for(JmJobPayload p : payloadParamList) {
for (JmJobPayload p : payloadParamList) {
Long payloadId = p.getPayloadId();
SkyeyePayload payload = payloadService.getOne(payloadId);
if (payload == null) {
@ -367,6 +359,7 @@ public class JmJobServiceImpl implements JmJobService {
/**
* 起飞 kmz
*
* @param job
*/
private void startKmz(JmJobDTO job) {

View File

@ -13,6 +13,7 @@ import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson2.*;
import java.io.IOException;
import java.net.ConnectException;
@ -37,6 +38,9 @@ public class PyAirlineServiceImpl implements IPyAirlineService {
@Value("${skyeye.py.ktkxUrl}")
private String url;
@Value("${skyeye.java.ktkxUrl}")
private String javaUrl;
// 判断是否为空并剔除无需执行任务的无人机
private boolean checkEmpty(Map<Long, PyAirlineDTO[]> uavMap) {
if (uavMap == null || uavMap.size() == 0) {
@ -72,7 +76,17 @@ public class PyAirlineServiceImpl implements IPyAirlineService {
@Override
public Map<Long, List<JmAirline>> getAirline(PyAirlineParamDTO param) {
HttpResponse<String> httpResponse = null;
log.info("请求航线规划算法服务参数:{}", JSON.toJSONString(param));
// HttpResponse<String> post;
// try {
// post = HttpUtil.post(javaUrl, null, param);
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// PyAirlineResponse pyAirlineResponse;
// pyAirlineResponse = JsonUtil.parse(post.body(), PyAirlineResponse.class);
// log.info("请求航线规划算法服务响应:{}",JSON.toJSONString(pyAirlineResponse));
HttpResponse<String> httpResponse;
try {
httpResponse = HttpUtil.post(url, null, param);
} catch (ConnectException ex) {
@ -82,18 +96,20 @@ public class PyAirlineServiceImpl implements IPyAirlineService {
}
PyAirlineResponse response;
response = JsonUtil.parse(httpResponse.body(), PyAirlineResponse.class);
log.info("请求航线规划算法服务响应:{}", JSON.toJSONString(response));
int responseCode = httpResponse.statusCode();
if (responseCode >= 400) {
log.warn("调用航线规划算法错误["+ responseCode + "]" + response.getMessage() + ",参数:" + JsonUtil.toString(param));
throw ServiceException.noLog("调用航线规划算法错误["+ responseCode + "]" + response.getMessage());
log.warn("调用航线规划算法错误[{}]{},参数:{}", responseCode, response.getMessage(), JsonUtil.toString(param));
throw ServiceException.noLog("调用航线规划算法错误[" + responseCode + "]" + response.getMessage());
}
Map<Long, PyAirlineDTO[]> uavMap = response.getData();
log.info("航线规划算法结果:{}", JSON.toJSONString(uavMap));
if (checkEmpty(uavMap)) {
if ("success".endsWith(response.getMessage())) {
throw ServiceException.noLog("无法生成航线可能飞行区域超过25平方公里");
}
log.warn("调用航线规划算法未返回数据["+ responseCode + "]" + response.getMessage() + ",参数:" + JsonUtil.toString(param));
throw ServiceException.noLog("调用航线规划算法未返回数据["+ responseCode + "]" + response.getMessage());
log.warn("调用航线规划算法未返回数据[{}]{},参数:{}", responseCode, response.getMessage(), JsonUtil.toString(param));
throw ServiceException.noLog("调用航线规划算法未返回数据[" + responseCode + "]" + response.getMessage());
}
Map<Long, List<JmAirline>> map = new HashMap<>();

View File

@ -0,0 +1,34 @@
package com.zhangy.skyeye.sar.context;
import com.zhangy.skyeye.jm.dto.JmAirlineStatusDTO;
import com.zhangy.skyeye.jm.dto.JmUavStatusDTO;
/**
* @PROJECT_NAME: skyeyesystem
* @DESCRIPTION: SAR 回传相关任务上下文提供者 用于打破 SarBackWsServiceImpl JmJobStatusService 的直接依赖
* @AUTHOR: GuanCheng Long
* @DATE: 2026/1/21 1:10
*/
public interface SarTaskContextProvider {
/**
* 根据载荷 IP 获取当前无人机状态
*/
JmUavStatusDTO getCurrentUav(String payloadIp);
/**
* 根据载荷 IP 获取当前航线状态
*/
JmAirlineStatusDTO getCurrentAirline(String payloadIp);
/**
* 获取当前任务执行 ID
*/
Long getCurrentJobExecId(String payloadIp);
/**
* 获取当前任务配置 ID
*/
Long getCurrentJobId(String payloadIp);
}

View File

@ -0,0 +1,104 @@
package com.zhangy.skyeye.sar.context;
import com.zhangy.skyeye.jm.dto.JmAirlineStatusDTO;
import com.zhangy.skyeye.jm.dto.JmUavStatusDTO;
import com.zhangy.skyeye.redis.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
*
*/
/**
* @PROJECT_NAME: skyeyesystem
* @DESCRIPTION: SAR 任务上下文提供者实现基于 Redis 缓存避免循环依赖
* - JmJobStatusServiceImpl 在更新状态时主动把 JmUavStatusDTO 推送到 Redis
* - 此类只从 Redis 读取不注入 JmJobStatusService
* @AUTHOR: GuanCheng Long
* @DATE: 2026/1/21 1:10
*/
@Slf4j
@Component
public class SarTaskContextProviderImpl implements SarTaskContextProvider {
@Autowired
private RedisUtil redisUtil;
// Redis 键前缀
private static final String UAV_STATUS_KEY_PREFIX = "sar:context:uav:";
// 缓存过期时间
private static final long CACHE_EXPIRE_SECONDS = 600; // 10 分钟
@Override
public JmUavStatusDTO getCurrentUav(String payloadIp) {
if (payloadIp == null || payloadIp.trim().isEmpty()) {
log.warn("获取 uav 状态失败payloadIp 为空");
return null;
}
String key = UAV_STATUS_KEY_PREFIX + payloadIp;
Object obj = redisUtil.get(key);
if (obj instanceof JmUavStatusDTO) {
return (JmUavStatusDTO) obj;
}
log.debug("Redis 中未找到 IP={} 的 uav 状态", payloadIp);
return null;
}
@Override
public JmAirlineStatusDTO getCurrentAirline(String payloadIp) {
JmUavStatusDTO uav = getCurrentUav(payloadIp);
if (uav == null) {
return null;
}
return uav.getCurrAirline();
}
@Override
public Long getCurrentJobExecId(String payloadIp) {
JmUavStatusDTO uav = getCurrentUav(payloadIp);
return uav != null ? uav.getJobExecId() : null;
}
@Override
public Long getCurrentJobId(String payloadIp) {
JmAirlineStatusDTO airline = getCurrentAirline(payloadIp);
return airline != null ? airline.getJobId() : null;
}
/**
* 更新/刷新缓存 JmJobStatusServiceImpl 调用
* 在状态更新成功后调用此方法
*/
public void updateUavStatus(String payloadIp, JmUavStatusDTO uavStatus) {
if (payloadIp == null || uavStatus == null) {
log.warn("更新 uav 状态失败参数为空ip={}, status={}", payloadIp, uavStatus);
return;
}
String key = UAV_STATUS_KEY_PREFIX + payloadIp;
try {
// 设置值 + 过期时间
redisUtil.set(key, uavStatus, CACHE_EXPIRE_SECONDS);
log.debug("已更新 Redis 缓存key={}, jobExecId={}", key, uavStatus.getJobExecId());
} catch (Exception e) {
log.error("更新 SAR uav 状态缓存失败ip={}", payloadIp, e);
}
}
/**
* 清理某个 IP 的缓存任务结束或异常时调用
*/
public void clearUavStatus(String payloadIp) {
if (payloadIp == null) {
return;
}
String key = UAV_STATUS_KEY_PREFIX + payloadIp;
redisUtil.del(key);
log.debug("SAR uav 缓存已标记清理(或自然过期):{}", key);
}
}

View File

@ -3,13 +3,11 @@ package com.zhangy.skyeye.sar.service.impl;
import com.zhangy.skyeye.jm.dto.JmAirlineStatusDTO;
import com.zhangy.skyeye.jm.dto.JmUavStatusDTO;
import com.zhangy.skyeye.jm.entity.JmImage;
import com.zhangy.skyeye.jm.service.JmJobStatusService;
import com.zhangy.skyeye.publics.consts.WebSocketKey;
import com.zhangy.skyeye.publics.service.SysFileTypeService;
import com.zhangy.skyeye.sar.context.SarTaskContextProvider;
import com.zhangy.skyeye.sar.dto.JmSarWaveWsDTO;
import com.zhangy.skyeye.sar.dto.SarBackWaveFrameDTO;
import com.zhangy.skyeye.sar.service.ISarBackWsService;
import com.zhangy.skyeye.sar.service.SarWsAsyncService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
@ -33,13 +31,7 @@ public class SarBackWsServiceImpl implements ISarBackWsService {
private SimpMessagingTemplate simpMessageingTemplate;
@Autowired
private SysFileTypeService sysFileTypeService;
@Autowired
private JmJobStatusService jobStatusService;
@Autowired
private SarWsAsyncService sarWsAsyncService;
private SarTaskContextProvider taskContextProvider;
@Override
public void sendWave(String payloadIp, SarBackWaveFrameDTO frame, byte[] frameData) {
@ -63,12 +55,14 @@ public class SarBackWsServiceImpl implements ISarBackWsService {
* @return
*/
private JmSarWaveWsDTO loadJobDetail(String payloadIp, JmSarWaveWsDTO ws, byte[] frameData) {
JmUavStatusDTO uav = jobStatusService.getCurrUav(payloadIp);
JmUavStatusDTO uav = taskContextProvider.getCurrentUav(payloadIp);
if (uav == null) { // 如果没有执行中的任务则忽略
log.debug("IP={} 无正在执行的任务,忽略波形推送", payloadIp);
return null;
}
JmAirlineStatusDTO airlineStatusVo = uav.getCurrAirline();
if (airlineStatusVo == null) {
log.debug("IP={} 无当前航线,忽略波形推送", payloadIp);
return null;
}
long jobConfId = airlineStatusVo.getJobId();

View File

@ -84,6 +84,8 @@ skyeye:
py:
ktkxUrl: http://127.0.0.1:18090/ktkx/UavPlanning/SAR
detectUrl: http://127.0.0.1:18091/ktkx/detect/cpu/SARCoord
java:
ktkxUrl: http://127.0.0.1:9117/ktkx/UavPlanning/SAR
weather:
cityCode: 101120201
@ -91,5 +93,5 @@ logging:
file:
name: "logs/"
level:
com.zhangy: debug
com.zhangy: info
org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler: OFF

View File

@ -35,7 +35,22 @@
<select id="selectList" resultType="com.zhangy.skyeye.jm.dto.JmJobDTO">
<include refid="selectSql"/>
where 1 = 1
where j.status != 1
<if test="type != null and type == 1">
and j.status in ('1', '3')
</if>
<if test="uavId != null">
and exists (select 1 from jm_job_uav ju where j.id = ju.job_id and ju.uav_id = #{uavId})
</if>
<if test="payloadId != null">
and exists (select 1 from jm_job_payload jp where j.id = jp.job_id and jp.payload_id = #{payloadId})
</if>
order by j.create_time desc
</select>
<select id="selectExecJobs" resultType="com.zhangy.skyeye.jm.dto.JmJobDTO">
<include refid="selectSql"/>
where j.status = '1'
<if test="type != null and type == 1">
and j.status in ('1', '3')
</if>

View File

@ -12,6 +12,6 @@ window.config = {
arcgisUrl: 'http://61.48.133.44:14001/map/arcgisMap',
minMapLevel: 1,
maxMapLevel: 16,
defaultLocation: [115.91531500114789, 40.35940233391189],
defaultLocation: [116.40531500114789, 39.86340233391189],
tdtToken: '316ac2812387c2cbff7a6f2f4e7f5bdc'
}

View File

@ -22,10 +22,12 @@ export const addTaskFast = params =>
req('post', '/sar/job/save', params)
// 预览任务
export const previewTaskFast = params =>
req('post', 'ktkx/UavPlanning/SAR', params)
req('post', '/jm/plan/airline', params)
// 编辑任务
export const editTaskFast = params =>
req('post', '/sar/job/save', params)
export const getExecJobs = params =>
req('post', '/sar/job/execJobs', params)
// 新增任务
export const addTaskAirline = params =>
req('post', '/sar/job/save2', params)
@ -41,6 +43,9 @@ export const deleteTaskItem = params =>
// 查询任务详情
export const getTaskItemDetail = params =>
req('get', '/sar/job/detail', params)
// 查询任务编辑详情
export const getTaskEditItemDetail = params =>
req('get', '/sar/job/info', params)
// 查询无人机列表
export const getUavListData = params =>
req('post', '/skyeye/uav/list', params)
@ -74,3 +79,7 @@ export const deletePictureItem = params =>
// ai识别
export const pictureAiCheck = params =>
req('post', '/sar/image/identify', params)
// 开机
export const changePayloadRadarOpenState = params =>
req('post', '/sar/control/send', params)

View File

@ -40,3 +40,18 @@ export const getWeatherInfo = params => req('get', '/weather/info', params)
// 获取字典接口
export const getAllDictType = params =>
req('get', '/dict/list', params)
// #region 新增user表接口
export const userList = params =>
req('post', '/user/list', params)
// 删除
export const userRemove = params =>
req('post', '/user/remove', params)
// 保存信息
export const userSave = params =>
req('post', '/user/save', params)
// 更新
export const userUpdate = params =>
req('post', '/user/update', params)
//#endregion

View File

@ -11,11 +11,12 @@
height: 100%;
position: absolute;
}
#cesium-split {
position: absolute;
left: 50%;
top: 0;
background-color: red;
background-color: #ffffff;
width: 4px;
height: 100%;
cursor: ew-resize;
@ -33,10 +34,12 @@
::v-deep .dt-card__content {
padding: 0;
}
.timeline-content {
display: flex;
justify-content: flex-start;
position: relative;
.timeline-contain {
flex: 1;
}

View File

@ -164,7 +164,7 @@ export default {
// console.log('刷新自己取', localStorage.getItem('userId'), localStorage.getItem('username'))
// }
if (this.username !== 'admin') {
// this.menus[3].show = false
this.menus[3].show = false
}
},
methods: {

View File

@ -52,5 +52,7 @@ const getters = {
jobModeOptions: state => state.dict.jobModeOptions,
polarization: state => state.dict.polarization,
polarizationOptions: state => state.dict.polarizationOptions,
sarImageMode: state => state.dict.sarImageMode,
sarImageModeOptions: state => state.dict.sarImageModeOptions,
}
export default getters

View File

@ -15,7 +15,7 @@ const state = {
duringPlay: false,
menuExpand: false, // 侧边工具栏是否展开
theme: 'light',
menusChose: '2'
menusChose: '1'
}
const mutations = {

View File

@ -13,9 +13,9 @@ const state = {
taskFlightModeOptions: [],
jobStatus: {},
jobStatusOptions: [],
sarResolution:{},
sarResolution: {},
sarResolutionOptions: [],
detectType:{},
detectType: {},
jobMode: {},
jobModeOptions: [
{
@ -29,6 +29,8 @@ const state = {
],
polarization: {},
polarizationOptions: {},
sarImageMode: {},
sarImageModeOptions: []
}
const mutations = {
@ -90,7 +92,12 @@ const mutations = {
SET_POLARIZATION_OPTIONS: (state, info) => {
state.polarizationOptions = info
},
SET_SAR_IMAGE_MODE: (state, info) => {
state.sarImageMode = info
},
SET_SAR_IMAGE_MODE_OPTIONS: (state, info) => {
state.sarImageModeOptions = info
},
}
const actions = {
getDict({ commit }) {
@ -103,66 +110,74 @@ const actions = {
let imuStatusOptions = []
let enableStatus = {}
let enableStatusOptions = []
let successStatus= {}
let successStatus = {}
let successStatusOptions = []
let sarWorkStatus= {}
let sarWorkStatus = {}
let sarWorkStatusOptions = []
let taskFlightMode= {}
let taskFlightMode = {}
let taskFlightModeOptions = []
let jobStatus= {}
let jobStatus = {}
let jobStatusOptions = []
let sarResolution= {}
let sarResolution = {}
let sarResolutionOptions = []
let detectType = {}
let jobMode = {}
let jobModeOptions = []
let polarization = {}
let polarizationOptions = []
let sarImageMode = {}
let sarImageModeOptions = []
res.data.data.forEach(item => {
switch (item.dictType) {
case 'imu_status':
imuStatus[item.dictValue] = item.dictLabel
imuStatusOptions.push({label: item.dictLabel, value: item.dictValue})
imuStatusOptions.push({ label: item.dictLabel, value: item.dictValue })
break
case 'enable_status':
enableStatus[item.dictValue] = item.dictLabel
enableStatusOptions.push({label: item.dictLabel, value: item.dictValue})
enableStatusOptions.push({ label: item.dictLabel, value: item.dictValue })
break
case 'success_status':
successStatus[item.dictValue] = item.dictLabel
successStatusOptions.push({label: item.dictLabel, value: item.dictValue})
successStatusOptions.push({ label: item.dictLabel, value: item.dictValue })
break
case 'sar_work_status':
sarWorkStatus[item.dictValue] = item.dictLabel
sarWorkStatusOptions.push({label: item.dictLabel, value: item.dictValue})
sarWorkStatusOptions.push({ label: item.dictLabel, value: item.dictValue })
break
case 'task_flight_mode':
taskFlightMode[item.dictValue] = item.dictLabel
taskFlightModeOptions.push({label: item.dictLabel, value: item.dictValue})
taskFlightModeOptions.push({ label: item.dictLabel, value: item.dictValue })
break
case 'job_status':
jobStatus[item.dictValue] = item.dictLabel
jobStatusOptions.push({label: item.dictLabel, value: item.dictValue})
jobStatusOptions.push({ label: item.dictLabel, value: item.dictValue })
break
case 'sar_resolution':
sarResolution[item.dictValue] = item.dictLabel
sarResolutionOptions.push({label: item.dictLabel, value: item.dictValue})
sarResolutionOptions.push({ label: item.dictLabel, value: item.dictValue })
break
case 'py_detect_type':
detectType[item.dictValue] = item.dictLabel
break
case 'job_mode':
jobMode[item.dictValue] = item.dictLabel
jobModeOptions.push({label: item.dictLabel, value: item.dictValue})
jobModeOptions.push({ label: item.dictLabel, value: item.dictValue })
break
case 'sar_polarization':
polarization[item.dictValue] = item.dictLabel
polarizationOptions.push({label: item.dictLabel, value: item.dictValue})
polarizationOptions.push({ label: item.dictLabel, value: item.dictValue })
break
case 'sar_image_mode':
sarImageMode[item.dictValue] = item.dictLabel
sarImageModeOptions.push({ label: item.dictLabel, value: item.dictValue })
break
}
})
commit('SET_SAR_IMAGE_MODE', sarImageMode)
commit('SET_SAR_IMAGE_MODE_OPTIONS', sarImageModeOptions)
// 适配机场类型
commit('SET_IMU_STATUS', imuStatus)
commit('SET_IMU_STATUS_OPTIONS', imuStatusOptions)
@ -192,6 +207,7 @@ const actions = {
// 极化方式
commit('SET_POLARIZATION', polarization)
commit('SET_POLARIZATION_OPTIONS', polarizationOptions)
commit('SET_POLARIZATION_OPTIONS', sarImageModeOptions)
resolve()
} else {
this.$message.error(res.data.message)

View File

@ -1506,6 +1506,7 @@ input[type="number"] {
}
}
.query-form {
.el-form-item {
margin-bottom: 0 !important;

View File

@ -35,11 +35,11 @@ export default {
return {
visibleLocale: false,
deviceData: [
{
name: '无人机1',
num: 'M3127',
location: '112.3423242,45.2312324'
}
// {
// name: '无人机1',
// num: 'M3127',
// location: '112.3423242,45.2312324'
// }
],
device: {
visible: false,
@ -148,6 +148,21 @@ export default {
addDevice() {
this.device.visible = true
this.device.title = `新增${this.deviceMap[this.queryForm.type]}`
if (this.queryForm.type === 'uav') {
this.device.form = {
id: '',
name1: '',
code: '',
ip1: ''
}
} else {
this.device.form = {
id: '',
name2: '',
type: '',
ip2: ''
}
}
},
editDevice(row) {
this.device.visible = true
@ -173,7 +188,7 @@ export default {
this.device.visible = false
},
async submitDevice() {
const valid = await this.$refs.form.validate(valid)
const valid = await this.$refs.form.validate()
if (!valid) return
const form = {}
if (this.queryForm.type === 'uav') {

View File

@ -305,3 +305,8 @@
top: $--icon-mode-larger-card-top;
transition: 0.2s ease-in-out;
}
::v-deep .el-icon-plus {
position: relative;
top: 2px;
}

View File

@ -25,10 +25,7 @@
></el-input>
</el-form-item> -->
<el-form-item label="">
<el-select
v-model="queryForm.type"
popper-class="select-light"
>
<el-select v-model="queryForm.type" popper-class="select-light">
<el-option
v-for="item in deviceTypes"
:key="item.value"
@ -78,7 +75,13 @@
></i>
</div>
</div> -->
<el-table v-if="isShowTable" :data="deviceData" stripe style="width: 100%">
<el-table
v-if="isShowTable"
:data="deviceData"
stripe
style="width: 100%"
height="100%"
>
<template v-if="queryForm.type === 'payload'">
<el-table-column prop="name" label="雷达名称"> </el-table-column>
<el-table-column prop="type" label="雷达类型"> </el-table-column>

View File

@ -29,16 +29,17 @@ export default {
uploadPictureInfo: {
visible: false
},
pictureData: [{
id: 1,
jobName: '任务1',
createTime: '2012-02-18 1200:00'
},
{
id: 2,
jobName: '任务2',
createTime: '2012-02-18 1200:00'
}
pictureData: [
// {
// id: 1,
// jobName: '任务1',
// createTime: '2012-02-18 1200:00'
// },
// {
// id: 2,
// jobName: '任务2',
// createTime: '2012-02-18 1200:00'
// }
],
page: {
size: 20,
@ -123,7 +124,7 @@ export default {
if (res.data.code === 200) {
console.log('图片分页', res.data.data)
let data = res.data.data.records
// this.pictureData = data
this.pictureData = data
this.page.total = res.data.data.total
} else {
this.$message.error(res.data.message)

View File

@ -44,13 +44,13 @@
<div class="pic-time">拍摄时间{{ item.createTime }}</div>
</div>
<div class="pic-command">
<el-tooltip effect="dark" content="修改名称" placement="left">
<el-tooltip effect="dark" content="修改名称" placement="top">
<i
class="el-icon-edit-outline"
@click.stop="editPictureName(item)"
></i>
</el-tooltip>
<el-tooltip effect="dark" content="删除" placement="right">
<el-tooltip effect="dark" content="删除" placement="top">
<i
class="el-icon-close delete-task"
@click.stop="deletePicture(item)"

View File

@ -125,7 +125,7 @@
.task-execute {
color: $--color-text-1;
font-size: 14px;
width: 90px;
width: 85px;
margin-left: 5px;
display: inline-block;
overflow: hidden;
@ -171,12 +171,12 @@
}
.right-part {
width: 40px;
width: 60px;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
justify-content: space-between;
align-items: center;
padding: 0 5px;
>i {
font-size: 14px;
@ -543,4 +543,12 @@
::v-deep .right-content {
display: flex;
}
::v-deep input {
background-color: #00000052;
}
::v-deep select {
background-color: #00000052;
}
}

View File

@ -10,12 +10,12 @@
title="任务列表"
:visible.sync="taskList.visible"
:scroll="false"
:showClose="true"
:showClose="false"
:showDivider="false"
>
<template v-slot:header>
<span class="remote-header">
<i class="ri-task-line"></i>
<i class="ri-function-add-line"></i>
任务列表
</span>
</template>
@ -25,7 +25,11 @@
</el-tooltip>
</template>
<div v-if="taskList.data.length" class="task-list__content">
<div v-for="item in taskList.data" :key="item.id" class="task-item">
<div
v-for="(item, index) in taskList.data"
:key="item.id"
class="task-item"
>
<div class="left-part">
<!-- <div class="task-progress-bar" :style="'width: ' + item.uavCompletion +'%;'"></div>-->
<div class="execute-info" @click="openTaskLineDetail(item)">
@ -36,7 +40,10 @@
></span>
<span class="task-execute">{{ item.name }}</span>
</div>
<div class="task-info" :style="{color:dealStatusColor(item.statusName)}">
<div
class="task-info"
:style="{ color: dealStatusColor(item.statusName) }"
>
{{ item.statusName }}
<!-- <i class="el-icon-camera"></i>-->
<!-- <span class="task-name">{{ item.name }}</span>-->
@ -47,27 +54,67 @@
<div class="task-time">{{ item.beginTime }}</div>
</div>
<div class="right-part">
<!-- <i class="el-icon-edit-outline edit-task" @click.stop="editTask(item)"></i>-->
<!-- <el-tooltip-->
<!-- effect="dark"-->
<!-- content="重新执行"-->
<!-- placement="right"-->
<!-- >-->
<!-- <i class="ri-repeat-line" @click.stop="reRunTask(item)"></i>-->
<!-- </el-tooltip>-->
<el-tooltip effect="dark" content="修改名称" placement="right">
<el-tooltip
effect="dark"
:content="item.check ? '隐藏' : '显示'"
placement="top"
>
<i
:class="item.check ? 'ri-eye-off-line' : 'ri-eye-line'"
@click.stop="toggleTaskSceneShow(item, index)"
></i>
</el-tooltip>
<el-tooltip
v-if="item.status === 0"
effect="dark"
content="执行"
placement="top"
>
<i
class="ri-arrow-up-circle-line"
@click.stop="makeTaskUavFly(item, index)"
></i>
</el-tooltip>
<el-tooltip
effect="dark"
content="重新执行"
placement="top"
v-if="item.status === 2"
>
<i
class="ri-restart-line"
@click.stop="reRunTask(item, index)"
></i>
</el-tooltip>
<el-dropdown
@command="handleCommand($event, item)"
placement="bottom"
size="small"
>
<span class="el-dropdown-link">
<i class="ri-more-fill"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="edit">修改名称</el-dropdown-item>
<el-dropdown-item command="copy">复制</el-dropdown-item>
<el-dropdown-item command="remove">删除</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<!-- <el-tooltip effect="dark" content="修改名称" placement="top">
<i
class="el-icon-edit-outline"
@click.stop="editTaskName(item)"
></i>
</el-tooltip>
<el-tooltip effect="dark" content="删除" placement="right">
<el-tooltip effect="dark" content="复制" placement="top">
<i class="ri-file-copy-2-line" @click.stop="copyTask(item)"></i>
</el-tooltip>
<el-tooltip effect="dark" content="删除" placement="top">
<i
class="el-icon-close delete-task"
@click.stop="deleteTask(item)"
></i>
</el-tooltip>
</el-tooltip> -->
</div>
</div>
</div>
@ -104,6 +151,7 @@
</el-form-item>
<el-form-item prop="mode" label="飞行模式">
<el-select
popper-class="form-light"
size="small"
:disabled="duringDraw || airlineCreateInfo.during"
@change="onModeChange"
@ -124,12 +172,14 @@
>
<div class="form-item-command">
<el-select
popper-class="form-light"
size="small"
:disabled="duringDraw"
v-model="form.targetChoose"
>
<el-option
v-for="item in drawOptions"
:disabled="getDrawTargetDisabled(item)"
:key="item.value"
:label="item.label"
:value="item.value"
@ -169,6 +219,7 @@
>
<span>{{ item.name }}</span>
<el-select
popper-class="form-light"
size="mini"
@change="
(value) => handleSelfDirectionChange(value, item, index)
@ -239,7 +290,11 @@
</div>-->
<el-form-item prop="uav" label="无人机">
<el-select size="small" v-model="form.uav">
<el-select
popper-class="form-light"
size="small"
v-model="form.uav"
>
<el-option
v-for="item in uavOptions"
:key="item.id"
@ -264,7 +319,11 @@
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item prop="loader" label="载荷">
<el-select size="small" v-model="form.loader">
<el-select
popper-class="form-light"
size="small"
v-model="form.loader"
>
<el-option
v-for="item in loaderOptions"
:key="item.id"
@ -305,12 +364,29 @@
</el-form-item>
<el-form-item prop="ratio" label="分辨率">
<el-select
popper-class="form-light"
size="small"
@change="calculateLimit"
v-model="form.ratio"
>
<el-option
v-for="item in sarResolutionOptions"
:disabled="getRatioDisabled(item)"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="成像模式" prop="imageMode">
<el-select
popper-class="form-light"
size="small"
v-model="form.imageMode"
@change="onImageModeChange"
>
<el-option
v-for="item in sarImageModeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
@ -360,7 +436,11 @@
></el-input-number>
</el-form-item>
<el-form-item label="自动聚焦">
<el-select size="small" v-model="form.autoFocus">
<el-select
popper-class="form-light"
size="small"
v-model="form.autoFocus"
>
<el-option
v-for="item in focusOptions"
:key="item.value"
@ -370,7 +450,11 @@
</el-select>
</el-form-item>
<el-form-item label="运动补偿">
<el-select size="small" v-model="form.moto">
<el-select
popper-class="form-light"
size="small"
v-model="form.moto"
>
<el-option
v-for="item in motoOptions"
:key="item.value"
@ -388,13 +472,18 @@
></el-input-number>
</el-form-item>
<el-form-item label="图像位数">
<el-select size="small" v-model="form.imageBit">
<el-select
popper-class="form-light"
size="small"
v-model="form.imageBit"
>
<el-option label="8bit" :value="0"></el-option>
<el-option label="16bit" :value="1"></el-option>
</el-select>
</el-form-item>
<el-form-item label="侧视方向" v-if="form.mode !== '3'">
<el-select
popper-class="form-light"
size="small"
@change="handleDirectionChange"
v-model="form.direction"
@ -408,7 +497,11 @@
</el-select>
</el-form-item>
<el-form-item label="极化方式">
<el-select size="small" v-model="form.polarization">
<el-select
popper-class="form-light"
size="small"
v-model="form.polarization"
>
<el-option
v-for="item in polarizationOptions"
:key="item.value"

View File

@ -107,11 +107,9 @@ export default class LineTarget {
DT.Cesium.Cartesian3.multiplyByScalar(endToStartDirection, distanceOne + distanceTwo, flyToStart)
DT.Cesium.Cartesian3.add(openToStart, this.positions[0], openToStart)
DT.Cesium.Cartesian3.add(flyToStart, this.positions[0], flyToStart)
// console.log('开机点', openToStart)
// let cat1 = DT.Cesium.Cartographic.fromCartesian(openToStart)
// let cat2 = DT.Cesium.Cartographic.fromCartesian(flyToStart)
// console.log('开机点高度', cat1.height , cat2.height)
// 求关机点
let startToEndDirection = new DT.Cesium.Cartesian3(1, 0, 0)
DT.Cesium.Cartesian3.subtract(this.positions[1], this.positions[0], startToEndDirection)
@ -122,7 +120,6 @@ export default class LineTarget {
DT.Cesium.Cartesian3.multiplyByScalar(startToEndDirection, distanceOne + distanceTwo, flyToEnd)
DT.Cesium.Cartesian3.add(openToEnd, this.positions[1], openToEnd)
DT.Cesium.Cartesian3.add(flyToEnd, this.positions[1], flyToEnd)
// console.log('关机点', openToEnd)
// 求成像区域中心经度,成像区域中心维度
let boundaryLonLat = []
@ -154,7 +151,6 @@ export default class LineTarget {
let center = [lon / 4, lat / 4] // 中心点坐标
let center2 = [(centerLonLat[0].longitude + centerLonLat[1].longitude) / 2, (centerLonLat[0].latitude + centerLonLat[1].latitude) / 2] // 中心点坐标
// console.log('中心区域', center)
let areaEndCenter = DT.Cesium.Cartesian3.fromDegrees(
(boundaryLonLat[0].longitude + boundaryLonLat[1].longitude) / 2,
@ -180,7 +176,6 @@ export default class LineTarget {
let groundOpenToStart2 = new DT.Cesium.Cartesian3() // 开机点
DT.Cesium.Cartesian3.multiplyByScalar(groundEndToStartDirection2, distanceTwo, groundOpenToStart2)
DT.Cesium.Cartesian3.add(groundOpenToStart2, areaStartCenter2, groundOpenToStart2)
// console.log('地面开机', groundOpenToStart)
// 求地面关机点
// let groundStartToEndDirection = new DT.Cesium.Cartesian3(1, 0, 0)
@ -189,20 +184,15 @@ export default class LineTarget {
// let groundOpenToEnd = new DT.Cesium.Cartesian3() // 开机点
// DT.Cesium.Cartesian3.multiplyByScalar(groundStartToEndDirection, distanceTwo, groundOpenToEnd)
// DT.Cesium.Cartesian3.add(groundOpenToEnd, areaEndCenter, groundOpenToEnd)
// console.log('地面关机', groundOpenToEnd)
// 成像区域幅宽和方位长度
let width = DT.Cesium.Cartesian3.distance(this.wave.crossPositions[0], this.wave.crossPositions[1])
let width2 = DT.Cesium.Cartesian3.distance(this.wave.crossPositions[0], this.wave.centerPositions[0]) * 2
let length = DT.Cesium.Cartesian3.distance(this.wave.crossPositions[1], this.wave.crossPositions[2])
// console.log('幅宽', width, length)
// 轴向角度
let point1 = turf.point([centerLonLat[0].longitude, centerLonLat[0].latitude]);
let point2 = turf.point([centerLonLat[1].longitude, centerLonLat[1].latitude]);
let bearing = turf.bearing(point1, point2) + 180
// console.log('角度12', bearing)
// console.log('高度123', this.viewer.cesiumViewer.terrainProvider)
// DT.Cesium.sampleTerrainMostDetailed(this.viewer.cesiumViewer.terrainProvider, [DT.Cesium.Cartographic.fromDegrees(center[0], center[1])]).then(res => {
// console.log('海拔', res)
// })
let startCat = DT.Cesium.Cartographic.fromCartesian(flyToStart)
let endCat = DT.Cesium.Cartographic.fromCartesian(flyToEnd)
@ -240,9 +230,6 @@ export default class LineTarget {
boundaryLonLat: boundaryLonLat,
direction: this.rotation > 0 ? 1 : -1,
}
console.log('下视角', this.rotation)
console.log('擦地角', 90 - Math.abs(this.rotation))
console.log('最后参数', info)
if (this.showTemp) {
this.tempCollection.forEach(temp => {
viewer.entities.remove(temp)
@ -485,6 +472,19 @@ export default class LineTarget {
}
restoreTarget(info) {
let startPosition = DT.Cesium.Cartesian3.fromDegrees(info.flightStartLon, info.flightStartLat, info.flightStartHeight)
let endPosition = DT.Cesium.Cartesian3.fromDegrees(info.flightEndLon, info.flightEndLat, info.flightEndHeight)
this.positions = [startPosition, endPosition]
this.createMark(startPosition, true)
this.createMark(endPosition, false)
this.createPolyline()
this.addUav()
this.addWave()
this.addMoveHandler()
}
createMark(position, start = true) {
let cat = DT.Cesium.Cartographic.fromCartesian(position)
let lon = Math.round(DT.Cesium.Math.toDegrees(cat.longitude) * 10000000000000) / 10000000000000
@ -573,7 +573,6 @@ export default class LineTarget {
shadows: DT.Cesium.ShadowMode.DISABLED
},
})
console.log('加载的无人机', this.uavEntity)
}
changeWaveAngle(value) {
this.angle = value
@ -633,9 +632,6 @@ export default class LineTarget {
if (this.rotation < 0) {
modifyAngle = 0 - modifyAngle
}
console.log('旋转角度和波束半角', this.rotation, this.angle)
console.log('距离', distanceOne, distanceTwo, distanceThree, angleOne)
console.log('修正角度', modifyAngle)
this.wave = new LineWave({color: DT.Cesium.Color.RED,viewer: this.viewer, startPosition: this.positions[0], endPosition: this.positions[1], angle: this.angle - Math.abs(modifyAngle/2), rotation: this.rotation- modifyAngle/2, offsetAngle: modifyAngle/2 })
this.viewer.primitives.add(this.wave.primitive)
this.viewer.entities.add(this.wave.crossLine)
@ -774,7 +770,6 @@ export default class LineTarget {
let result = new DT.Cesium.Cartesian3()
DT.Cesium.Cartesian3.lerp(cartesian, this.viewer.cesiumViewer.camera.positionWC, ratio, result)
// let cat = DT.Cesium.Cartographic.fromCartesian(result)
// console.log('拾取的位置相机', cat.height )
return result
}
@ -836,10 +831,6 @@ export class LineWave {
this.bottomHorizontalLength = Math.tan(halfAngleRadians) * this.length
this.bottomVerticalLength = this.lineLength
this.offsetAngle = options.offsetAngle ? options.offsetAngle : 0
console.log('角度是啥', this.angle)
console.log('旋转是啥', this.rotation)
console.log('修正是啥', this.offsetAngle)
console.log('旋转+修正是啥', this.offsetAngle + this.rotation)
this.createWave()
this.createEdge()
}
@ -894,9 +885,7 @@ export class LineWave {
let que = DT.Tool.calculateQuaternionFromV1ToV2(this.startPosition, this.endPosition)
console.log('角度', this.rotation)
let rotationQuaternion = DT.Cesium.Quaternion.fromAxisAngle(DT.Cesium.Cartesian3.UNIT_X, this.rotation * Math.PI / 180)
console.log('四元数', rotationQuaternion)
let combineQuaternion = new DT.Cesium.Quaternion()
DT.Cesium.Quaternion.multiply(que, rotationQuaternion, combineQuaternion)
let rotation = DT.Cesium.Matrix4.fromTranslationQuaternionRotationScale(this.middlePosition, combineQuaternion, DT.Cesium.Cartesian3.ONE)
@ -938,7 +927,6 @@ export class LineWave {
let que = DT.Tool.calculateQuaternionFromV1ToV2(this.startPosition, this.endPosition)
let rotationQuaternion = DT.Cesium.Quaternion.fromAxisAngle(DT.Cesium.Cartesian3.UNIT_X, this.rotation * Math.PI / 180)
let rotationQuaternionCenter = DT.Cesium.Quaternion.fromAxisAngle(DT.Cesium.Cartesian3.UNIT_X, (this.rotation + this.offsetAngle) * Math.PI / 180)
// console.log('四元数计算角度', this.rotation + this.offsetAngle)
let combineQuaternion = new DT.Cesium.Quaternion()
let combineQuaternionCenter = new DT.Cesium.Quaternion()
DT.Cesium.Quaternion.multiply(que, rotationQuaternion, combineQuaternion)
@ -1001,7 +989,6 @@ export class LineWave {
DT.Cesium.Cartesian3.clone(start, ray.origin);
DT.Cesium.Cartesian3.subtract(end, start, ray.direction);
let position = this.viewer.cesiumViewer.scene.globe.pick(ray, this.viewer.cesiumViewer.scene)
console.log('交点', position)
return position
}
findCrossPoint(start, end) {

View File

@ -21,7 +21,7 @@ import {
getTaskItemDetail,
getTaskListData,
getUavListData,
reRunTask, stopTaskFly
reRunTask, stopTaskFly, getExecJobs
} from '@/api/task'
import UavTarget from './uavTarget'
import PicturesUpload from '../pictures-upload/index.vue'
@ -73,15 +73,15 @@ export default {
visible: true,
activeTabId: 1,
data: [
{
signal: 50,
nickName: '无人机1',
battery: 80,
flyHeight: 80,
lon: 115.76,
lat: 40.38,
id: 2
}
// {
// signal: 50,
// nickName: '无人机1',
// battery: 80,
// flyHeight: 80,
// lon: 115.76,
// lat: 40.38,
// id: 2
// }
],
typeDict: {
1: '无人机',
@ -91,12 +91,14 @@ export default {
},
taskList: {
visible: true,
data: [{
status: 1,
name: '巡查任务',
statusName: '巡查中',
beginTime: '2026-01-23 12:14:45'
}]
data: [
// {
// status: 1,
// name: '巡查任务',
// statusName: '巡查中',
// beginTime: '2026-01-23 12:14:45'
// }
]
},
weatherInfo2: {
visible: true,
@ -531,6 +533,7 @@ export default {
socketInstance = null
stompClientInstance = null
}
viewer.entities.removeAll()
// if (broadcastChannel) {
// this.closeBroadcastChannel()
// }
@ -573,431 +576,431 @@ export default {
return '#336dff'
}
},
startTest() {
let testHeight = 1000
window.detectType = {
1: '车'
}
let task = [
{
id: 1,
name: '测试任务',
status: 1,
statusName: '执行中',
check: true,
beginTime: moment().format('YYYY-MM-DD HH:mm:ss'),
pointList: [
[
{
longitude: 115.915457,
latitude: 40.359459,
},
{
longitude: 115.915457,
latitude: 40.358999,
},
{
longitude: 115.915874,
latitude: 40.358999,
},
{
longitude: 115.915874,
latitude: 40.359459,
}
],
[
{
longitude: 115.915457,
latitude: 40.355459
},
]
],
uavList: [
{
jobId: 1,
uavId: 2,
uavName: '无人机1',
airlineList: [
{
startLon: 115.917609,
startLat: 40.359843,
startHeight: testHeight,
endLon: 115.917609,
endLat: 40.357843,
endHeight: testHeight,
id: 1
},
{
startLon: 115.919609,
startLat: 40.359843,
startHeight: testHeight,
endLon: 115.919609,
endLat: 40.357843,
endHeight: testHeight,
id: 2
}
],
trailList: [
{
longitude: 115.917609,
latitude: 40.359843,
height: testHeight
},
{
longitude: 115.918609,
latitude: 40.359843,
height: testHeight
},
{
longitude: 115.919609,
latitude: 40.357843,
height: testHeight
}
],
startLon: 115.917609,
startLat: 40.359843,
startHeight: testHeight,
payloadList: [
{
payloadId: 1,
payloadName: 'sar',
imageList: [
{
left1Lon: 115.917609,
left1Lat: 40.359843,
left2Lon: 115.917609,
left2Lat: 40.358843,
right2Lon: 115.918609,
right2Lat: 40.358843,
right1Lon: 115.918609,
right1Lat: 40.359843,
fileId: 1,
id: 1,
relativePath: '1.png',
itemList: [
{
id: 2,
left1Lon: 115.917609,
left1Lat: 40.359843,
left2Lon: 115.917609,
left2Lat: 40.358843,
right2Lon: 115.918609,
right2Lat: 40.358843,
right1Lon: 115.918609,
right1Lat: 40.359843,
type: 1,
},
{
id: 4,
left1Lon: 115.916609,
left1Lat: 40.359143,
left2Lon: 115.916609,
left2Lat: 40.358943,
right2Lon: 115.918509,
right2Lat: 40.358943,
right1Lon: 115.918509,
right1Lat: 40.359143,
type: 1,
}
]
},
{
left1Lon: 115.919609,
left1Lat: 40.359843,
left2Lon: 115.919609,
left2Lat: 40.358843,
right2Lon: 115.920609,
right2Lat: 40.358843,
right1Lon: 115.920609,
right1Lat: 40.359843,
fileId: 2,
relativePath: '1.png',
itemList: [
{
id: 5,
left1Lon: 115.919609,
left1Lat: 40.359843,
left2Lon: 115.919609,
left2Lat: 40.358843,
right2Lon: 115.920609,
right2Lat: 40.358843,
right1Lon: 115.920609,
right1Lat: 40.359843,
type: 1,
},
{
id: 6,
left1Lon: 115.918609,
left1Lat: 40.359143,
left2Lon: 115.918609,
left2Lat: 40.358943,
right2Lon: 115.920509,
right2Lat: 40.358943,
right1Lon: 115.920509,
right1Lat: 40.359143,
type: 1,
}
]
}
],
}
]
}
]
},
{
id: 2,
name: '测试任务2',
status: 2,
check: false,
statusName: '已完成',
beginTime: moment().format('YYYY-MM-DD HH:mm:ss'),
pointList: [
[
{
longitude: 115.905457,
latitude: 40.359459
},
{
longitude: 115.905457,
latitude: 40.358999
},
{
longitude: 115.905874,
latitude: 40.358999
},
{
longitude: 115.905874,
latitude: 40.359459
}
],
[
{
longitude: 115.905457,
latitude: 40.355459
},
]
],
uavList: [
{
jobId: 2,
uavId: 3,
// startTest() {
// let testHeight = 1000
// window.detectType = {
// 1: '车'
// }
// let task = [
// {
// id: 1,
// name: '测试任务',
// status: 1,
// statusName: '执行中',
// check: true,
// beginTime: moment().format('YYYY-MM-DD HH:mm:ss'),
// pointList: [
// [
// {
// longitude: 115.915457,
// latitude: 40.359459,
// },
// {
// longitude: 115.915457,
// latitude: 40.358999,
// },
// {
// longitude: 115.915874,
// latitude: 40.358999,
// },
// {
// longitude: 115.915874,
// latitude: 40.359459,
// }
// ],
// [
// {
// longitude: 115.915457,
// latitude: 40.355459
// },
// ]
// ],
// uavList: [
// {
// jobId: 1,
// uavId: 2,
// uavName: '无人机1',
// airlineList: [
// {
// startLon: 115.917609,
// startLat: 40.359843,
// startHeight: testHeight,
// endLon: 115.917609,
// endLat: 40.357843,
// endHeight: testHeight,
// id: 1
// },
// {
// startLon: 115.919609,
// startLat: 40.359843,
// startHeight: testHeight,
// endLon: 115.919609,
// endLat: 40.357843,
// endHeight: testHeight,
// id: 2
// }
// ],
// trailList: [
// {
// longitude: 115.917609,
// latitude: 40.359843,
// height: testHeight
// },
// {
// longitude: 115.918609,
// latitude: 40.359843,
// height: testHeight
// },
// {
// longitude: 115.919609,
// latitude: 40.357843,
// height: testHeight
// }
// ],
// startLon: 115.917609,
// startLat: 40.359843,
// startHeight: testHeight,
// payloadList: [
// {
// payloadId: 1,
// payloadName: 'sar',
// imageList: [
// {
// left1Lon: 115.917609,
// left1Lat: 40.359843,
// left2Lon: 115.917609,
// left2Lat: 40.358843,
// right2Lon: 115.918609,
// right2Lat: 40.358843,
// right1Lon: 115.918609,
// right1Lat: 40.359843,
// fileId: 1,
// id: 1,
// relativePath: '1.png',
// itemList: [
// {
// id: 2,
// left1Lon: 115.917609,
// left1Lat: 40.359843,
// left2Lon: 115.917609,
// left2Lat: 40.358843,
// right2Lon: 115.918609,
// right2Lat: 40.358843,
// right1Lon: 115.918609,
// right1Lat: 40.359843,
// type: 1,
// },
// {
// id: 4,
// left1Lon: 115.916609,
// left1Lat: 40.359143,
// left2Lon: 115.916609,
// left2Lat: 40.358943,
// right2Lon: 115.918509,
// right2Lat: 40.358943,
// right1Lon: 115.918509,
// right1Lat: 40.359143,
// type: 1,
// }
// ]
// },
// {
// left1Lon: 115.919609,
// left1Lat: 40.359843,
// left2Lon: 115.919609,
// left2Lat: 40.358843,
// right2Lon: 115.920609,
// right2Lat: 40.358843,
// right1Lon: 115.920609,
// right1Lat: 40.359843,
// fileId: 2,
// relativePath: '1.png',
// itemList: [
// {
// id: 5,
// left1Lon: 115.919609,
// left1Lat: 40.359843,
// left2Lon: 115.919609,
// left2Lat: 40.358843,
// right2Lon: 115.920609,
// right2Lat: 40.358843,
// right1Lon: 115.920609,
// right1Lat: 40.359843,
// type: 1,
// },
// {
// id: 6,
// left1Lon: 115.918609,
// left1Lat: 40.359143,
// left2Lon: 115.918609,
// left2Lat: 40.358943,
// right2Lon: 115.920509,
// right2Lat: 40.358943,
// right1Lon: 115.920509,
// right1Lat: 40.359143,
// type: 1,
// }
// ]
// }
// ],
// }
// ]
// }
// ]
// },
// {
// id: 2,
// name: '测试任务2',
// status: 2,
// check: false,
// statusName: '已完成',
// beginTime: moment().format('YYYY-MM-DD HH:mm:ss'),
// pointList: [
// [
// {
// longitude: 115.905457,
// latitude: 40.359459
// },
// {
// longitude: 115.905457,
// latitude: 40.358999
// },
// {
// longitude: 115.905874,
// latitude: 40.358999
// },
// {
// longitude: 115.905874,
// latitude: 40.359459
// }
// ],
// [
// {
// longitude: 115.905457,
// latitude: 40.355459
// },
// ]
// ],
// uavList: [
// {
// jobId: 2,
// uavId: 3,
uavName: '无人机1',
airlineList: [
{
startLon: 115.907609,
startLat: 40.359843,
startHeight: testHeight,
endLon: 115.917609,
endLat: 40.357843,
endHeight: testHeight,
id: 1
},
{
startLon: 115.909609,
startLat: 40.359843,
startHeight: testHeight,
endLon: 115.919609,
endLat: 40.357843,
endHeight: testHeight,
id: 2
}
],
trailList: [
{
longitude: 115.907609,
latitude: 40.359843,
height: testHeight
},
{
longitude: 115.906609,
latitude: 40.359843,
height: testHeight
},
{
longitude: 115.905609,
latitude: 40.357843,
height: testHeight
}
],
startLon: 115.907609,
startLat: 40.359843,
startHeight: testHeight,
payloadList: [
{
payloadId: 1,
payloadName: 'sar',
imageList: [
{
left1Lon: 115.907609,
left1Lat: 40.359843,
left2Lon: 115.907609,
left2Lat: 40.358843,
right2Lon: 115.908609,
right2Lat: 40.358843,
right1Lon: 115.908609,
right1Lat: 40.359843,
fileId: 1,
relativePath: '1.png',
itemList: [
{
id: 1,
left1Lon: 115.917609,
left1Lat: 40.359843,
left2Lon: 115.917609,
left2Lat: 40.358843,
right2Lon: 115.918609,
right2Lat: 40.358843,
right1Lon: 115.918609,
right1Lat: 40.359843,
type: 1,
},
{
id: 2,
left1Lon: 115.916609,
left1Lat: 40.359143,
left2Lon: 115.916609,
left2Lat: 40.358943,
right2Lon: 115.918509,
right2Lat: 40.358943,
right1Lon: 115.918509,
right1Lat: 40.359143,
type: 1,
}
]
},
{
left1Lon: 115.909609,
left1Lat: 40.359843,
left2Lon: 115.909609,
left2Lat: 40.358843,
right2Lon: 115.910609,
right2Lat: 40.358843,
right1Lon: 115.910609,
right1Lat: 40.359843,
fileId: 2,
relativePath: '1.png',
itemList: [
{
id: 1,
left1Lon: 115.909609,
left1Lat: 40.359843,
left2Lon: 115.909609,
left2Lat: 40.358843,
right2Lon: 115.910609,
right2Lat: 40.358843,
right1Lon: 115.910609,
right1Lat: 40.359843,
type: 1,
},
{
id: 2,
left1Lon: 115.908609,
left1Lat: 40.359143,
left2Lon: 115.908609,
left2Lat: 40.358943,
right2Lon: 115.910509,
right2Lat: 40.358943,
right1Lon: 115.910509,
right1Lat: 40.359143,
type: 1,
}
]
}
],
}
]
}
]
}
]
this.taskList.data = task
task.forEach(item => {
// 测试
if (item.status === 1) {
this.addUavToScene(item)
this.addTaskPlanArea(item.pointList, item.id)
}
})
// uavName: '无人机1',
// airlineList: [
// {
// startLon: 115.907609,
// startLat: 40.359843,
// startHeight: testHeight,
// endLon: 115.917609,
// endLat: 40.357843,
// endHeight: testHeight,
// id: 1
// },
// {
// startLon: 115.909609,
// startLat: 40.359843,
// startHeight: testHeight,
// endLon: 115.919609,
// endLat: 40.357843,
// endHeight: testHeight,
// id: 2
// }
// ],
// trailList: [
// {
// longitude: 115.907609,
// latitude: 40.359843,
// height: testHeight
// },
// {
// longitude: 115.906609,
// latitude: 40.359843,
// height: testHeight
// },
// {
// longitude: 115.905609,
// latitude: 40.357843,
// height: testHeight
// }
// ],
// startLon: 115.907609,
// startLat: 40.359843,
// startHeight: testHeight,
// payloadList: [
// {
// payloadId: 1,
// payloadName: 'sar',
// imageList: [
// {
// left1Lon: 115.907609,
// left1Lat: 40.359843,
// left2Lon: 115.907609,
// left2Lat: 40.358843,
// right2Lon: 115.908609,
// right2Lat: 40.358843,
// right1Lon: 115.908609,
// right1Lat: 40.359843,
// fileId: 1,
// relativePath: '1.png',
// itemList: [
// {
// id: 1,
// left1Lon: 115.917609,
// left1Lat: 40.359843,
// left2Lon: 115.917609,
// left2Lat: 40.358843,
// right2Lon: 115.918609,
// right2Lat: 40.358843,
// right1Lon: 115.918609,
// right1Lat: 40.359843,
// type: 1,
// },
// {
// id: 2,
// left1Lon: 115.916609,
// left1Lat: 40.359143,
// left2Lon: 115.916609,
// left2Lat: 40.358943,
// right2Lon: 115.918509,
// right2Lat: 40.358943,
// right1Lon: 115.918509,
// right1Lat: 40.359143,
// type: 1,
// }
// ]
// },
// {
// left1Lon: 115.909609,
// left1Lat: 40.359843,
// left2Lon: 115.909609,
// left2Lat: 40.358843,
// right2Lon: 115.910609,
// right2Lat: 40.358843,
// right1Lon: 115.910609,
// right1Lat: 40.359843,
// fileId: 2,
// relativePath: '1.png',
// itemList: [
// {
// id: 1,
// left1Lon: 115.909609,
// left1Lat: 40.359843,
// left2Lon: 115.909609,
// left2Lat: 40.358843,
// right2Lon: 115.910609,
// right2Lat: 40.358843,
// right1Lon: 115.910609,
// right1Lat: 40.359843,
// type: 1,
// },
// {
// id: 2,
// left1Lon: 115.908609,
// left1Lat: 40.359143,
// left2Lon: 115.908609,
// left2Lat: 40.358943,
// right2Lon: 115.910509,
// right2Lat: 40.358943,
// right1Lon: 115.910509,
// right1Lat: 40.359143,
// type: 1,
// }
// ]
// }
// ],
// }
// ]
// }
// ]
// }
// ]
// this.taskList.data = task
// task.forEach(item => {
// // 测试
// if (item.status === 1) {
// this.addUavToScene(item)
// this.addTaskPlanArea(item.pointList, item.id)
// }
// })
let initPosition = [115.919609, 40.357843, testHeight]
// 测试推送
setInterval(() => {
initPosition[0] += 0.001
initPosition[1] += 0.001
let body = [{
jobId: 1,
uavId: 2,
longitude: initPosition[0],
latitude: initPosition[1],
height: initPosition[2],
payloadList: [
{
longitude: initPosition[0],
latitude: initPosition[1],
altitude: initPosition[2],
}
]
}]
this.handleWebsocketStatus({ body: JSON.stringify(body) })
// let initPosition = [115.919609, 40.357843, testHeight]
// // 测试推送
// setInterval(() => {
// initPosition[0] += 0.001
// initPosition[1] += 0.001
// let body = [{
// jobId: 1,
// uavId: 2,
// longitude: initPosition[0],
// latitude: initPosition[1],
// height: initPosition[2],
// payloadList: [
// {
// longitude: initPosition[0],
// latitude: initPosition[1],
// altitude: initPosition[2],
// }
// ]
// }]
// this.handleWebsocketStatus({ body: JSON.stringify(body) })
}, 4000)
// }, 4000)
let initPic = {
left1Lon: 115.917609,
left1Lat: 40.359843,
left2Lon: 115.917609,
left2Lat: 40.358843,
right2Lon: 115.918609,
right2Lat: 40.358843,
right1Lon: 115.918609,
right1Lat: 40.359843,
fileId: 4,
id: 1,
jobId: 1,
payloadId: 1,
uavId: 2,
relativePath: '1.png',
itemList: [
{
id: 9,
left1Lon: 115.917609,
left1Lat: 40.359843,
left2Lon: 115.917609,
left2Lat: 40.358843,
right2Lon: 115.918609,
right2Lat: 40.358843,
right1Lon: 115.918609,
right1Lat: 40.359843,
type: 1,
},
]
}
setInterval(() => {
initPic.left1Lon += 0.001
initPic.left1Lat += 0.001
initPic.left2Lon += 0.001
initPic.left2Lat += 0.001
initPic.right2Lon += 0.001
initPic.right2Lat += 0.001
initPic.right1Lon += 0.001
initPic.right1Lat += 0.001
initPic.fileId += 1
initPic.itemList.forEach(item => {
item.left1Lon += 0.001
item.left1Lat += 0.001
item.left2Lon += 0.001
item.left2Lat += 0.001
item.right2Lon += 0.001
item.right2Lat += 0.001
item.right1Lon += 0.001
item.right1Lat += 0.001
item.id += 1
})
this.handleWebsocketImage({ body: JSON.stringify(initPic) })
}, 6000)
},
// let initPic = {
// left1Lon: 115.917609,
// left1Lat: 40.359843,
// left2Lon: 115.917609,
// left2Lat: 40.358843,
// right2Lon: 115.918609,
// right2Lat: 40.358843,
// right1Lon: 115.918609,
// right1Lat: 40.359843,
// fileId: 4,
// id: 1,
// jobId: 1,
// payloadId: 1,
// uavId: 2,
// relativePath: '1.png',
// itemList: [
// {
// id: 9,
// left1Lon: 115.917609,
// left1Lat: 40.359843,
// left2Lon: 115.917609,
// left2Lat: 40.358843,
// right2Lon: 115.918609,
// right2Lat: 40.358843,
// right1Lon: 115.918609,
// right1Lat: 40.359843,
// type: 1,
// },
// ]
// }
// setInterval(() => {
// initPic.left1Lon += 0.001
// initPic.left1Lat += 0.001
// initPic.left2Lon += 0.001
// initPic.left2Lat += 0.001
// initPic.right2Lon += 0.001
// initPic.right2Lat += 0.001
// initPic.right1Lon += 0.001
// initPic.right1Lat += 0.001
// initPic.fileId += 1
// initPic.itemList.forEach(item => {
// item.left1Lon += 0.001
// item.left1Lat += 0.001
// item.left2Lon += 0.001
// item.left2Lat += 0.001
// item.right2Lon += 0.001
// item.right2Lat += 0.001
// item.right1Lon += 0.001
// item.right1Lat += 0.001
// item.id += 1
// })
// this.handleWebsocketImage({ body: JSON.stringify(initPic) })
// }, 6000)
// },
// 工具栏操作
toggleTools(tool) {
tool.active = !tool.active
@ -1069,13 +1072,14 @@ export default {
},
getTaskList() {
getTaskListData({ type: 2, orders: [{ column: 'begin_time', asc: false }] }).then(res => {
getExecJobs({ type: 2, orders: [{ column: 'begin_time', asc: false }] }).then(res => {
if (res.data.code === 200) {
console.log('任务列表', res.data.data)
let data = res.data.data
let list = []
data.forEach(item => {
item.check = item.status === 1 || item.status === 3
// item.check = item.status === 1 || item.status === 3
item.check = false
item.statusName = this.jobStatus[item.status + '']
// TODO 临时设置
item.uavList.forEach(child => {
@ -1098,8 +1102,8 @@ export default {
// item.pointList = [item.pointList]
if (item.status === 1 || item.status === 3) {
// this.addJobLine(item, false)
this.addUavToScene(item)
this.addTaskPlanArea(item.pointList, item.id, item.name)
// this.addUavToScene(item)
// this.addTaskPlanArea(item.pointList, item.id, item.name)
}
// 测试
// this.addUavToScene(item)
@ -3041,6 +3045,8 @@ export default {
//#region 航线详情
openTaskLineDetail(info) {
this.taskLineDetail.visible = false
console.log(taskListResource, 555);
let find = taskListResource.find(item => item.id === info.id)
console.log('信息', find)

View File

@ -196,8 +196,8 @@
width: 40px;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
justify-content: space-between;
padding: 0 8px;
align-items: center;
>i {

View File

@ -84,37 +84,40 @@
></span>
<span class="task-execute">{{ item.name }}</span>
</div>
<div class="task-info" :style="{color:dealStatusColor(item.statusName)}">
<div
class="task-info"
:style="{ color: dealStatusColor(item.statusName) }"
>
{{ item.statusName }}
</div>
<div class="task-time">{{ item.beginTime }}</div>
</div>
<div class="right-part">
<div class="right-part" >
<el-tooltip
effect="dark"
:content="item.check ? '隐藏' : '显示'"
placement="right"
placement="top"
>
<i
:class="item.check ? 'ri-eye-off-line' : 'ri-eye-line'"
@click.stop="toggleTaskSceneShow(item, index)"
></i>
</el-tooltip>
<el-tooltip
<!-- <el-tooltip
v-if="item.status === 0"
effect="dark"
content="执行"
placement="right"
placement="top"
>
<i
class="ri-flight-takeoff-line"
class="ri-arrow-up-circle-line"
@click.stop="makeTaskUavFly(item, index)"
></i>
</el-tooltip>
</el-tooltip> -->
<el-tooltip
effect="dark"
content="结束任务"
placement="right"
placement="top"
v-if="item.status === 1"
>
<i
@ -122,19 +125,17 @@
@click.stop="stopTask(item, index)"
></i>
</el-tooltip>
<el-tooltip
<!-- <el-tooltip
effect="dark"
content="重新执行"
placement="right"
placement="top"
v-if="item.status === 2"
>
<i
class="ri-repeat-line"
class="ri-restart-line"
@click.stop="reRunTask(item, index)"
></i>
</el-tooltip>
<!-- <i class="el-icon-edit-outline edit-task" @click.stop="editTask(item)"></i>-->
<!-- <i class="el-icon-close delete-task" @click.stop="deleteTask(item)"></i>-->
</el-tooltip> -->
</div>
</div>
</template>

View File

@ -16,7 +16,10 @@ export default class UavTarget {
this.startAltitude = options.startAltitude
this.addPlanLine(options.airlineList)
console.log(options, '飞机数据');
if (options.startLon) {
this.addUav(options)
}
this.addUavLoader(options.payloadList)
}
addUav(info) {
@ -32,36 +35,37 @@ export default class UavTarget {
}
let currentPosition = this.positions[this.positions.length - 1].clone()
let id = `${this.jobId}~${this.uavId}-uav`
this.uavEntity = this.viewer.entities.add({
id,
position: currentPosition,
// label: {
// text: info.uavName,
// font: '14px sans-serif',
// fillColor: DT.Cesium.Color.WHITE,
// horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT,
// verticalOrigin: DT.Cesium.VerticalOrigin.CENTER,
// disableDepthTestDistance: 10000,
// pixelOffset: new DT.Cesium.Cartesian2(10, 0),
// showBackground: true,
// scaleByDistance: new DT.Cesium.NearFarScalar(0, 1, 1, 0.8),
// distanceDisplayCondition: new DT.Cesium.DistanceDisplayCondition(0, 20000),
// backgroundColor: DT.Cesium.Color.fromCssColorString('rgba(0,0,0,0.7)'),
// style: DT.Cesium.LabelStyle.FILL_AND_OUTLINE,
// },
// model: {
// uri: process.env.BASE_URL + 'model/uav.gltf',
// // scale: 1,
// minimumPixelSize: 32,
// maximumScale: 128,
// },
label: {
text: info.uavName,
font: '14px sans-serif',
fillColor: DT.Cesium.Color.WHITE,
horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT,
verticalOrigin: DT.Cesium.VerticalOrigin.CENTER,
disableDepthTestDistance: 10000,
pixelOffset: new DT.Cesium.Cartesian2(10, 0),
showBackground: true,
scaleByDistance: new DT.Cesium.NearFarScalar(0, 1, 1, 0.8),
distanceDisplayCondition: new DT.Cesium.DistanceDisplayCondition(0, 20000),
backgroundColor: DT.Cesium.Color.fromCssColorString('rgba(0,0,0,0.7)'),
style: DT.Cesium.LabelStyle.FILL_AND_OUTLINE,
},
model: {
uri: process.env.BASE_URL + 'model/uav.gltf',
// scale: 1,
minimumPixelSize: 32,
maximumScale: 128,
},
polyline: {
positions: new DT.Cesium.CallbackProperty(function () {
return that.positions
}, false),
width: 2,
zIndex: 6,
material: DT.Cesium.Color.CYAN,
width: 8,
zIndex: 600,
material: DT.Cesium.Color.BLACK,
depthFailMaterial: DT.Cesium.Color.CYAN,
arcType: DT.Cesium.ArcType.NONE
}
@ -125,7 +129,7 @@ export default class UavTarget {
addLayer.splitDirection = DT.Cesium.ImagerySplitDirection.LEFT
obj.picture = addLayer
if (image.itemList) {
image.itemList.forEach( (mark, markIndex) => {
image.itemList.forEach((mark, markIndex) => {
let markId = `${this.jobId}~${this.uavId}~${loader.payloadId}~${image.fileId}~${mark.id}-mark${imageIndex}${markIndex}`
let markPosition = DT.Cesium.Cartesian3.fromDegrees(mark.left1Lon, mark.left1Lat, 1)
let markArr = [
@ -216,7 +220,7 @@ export default class UavTarget {
// console.log('添加的图片', obj.picture)
if (image.itemList) {
image.itemList.forEach( (mark, markIndex) => {
image.itemList.forEach((mark, markIndex) => {
let markId = `${this.jobId}~${this.uavId}~${image.payloadId}~${image.fileId}~${mark.id}-mark${length}${markIndex}`
let markPosition = DT.Cesium.Cartesian3.fromDegrees(mark.left1Lon, mark.left1Lat, 1)
let markArr = [
@ -285,7 +289,7 @@ export default class UavTarget {
}
}
toggleLoaderPictureVisible(payloadId,fileId) {
toggleLoaderPictureVisible(payloadId, fileId) {
console.log('切换显隐', payloadId, fileId)
if (this.loaderPicture[payloadId]) {
let find = this.loaderPicture[payloadId].find(item => item.fileId + '' === fileId + '')
@ -300,7 +304,7 @@ export default class UavTarget {
}
}
}
toggleLoaderPictureActive(payloadId,fileId, active, visible = true) {
toggleLoaderPictureActive(payloadId, fileId, active, visible = true) {
if (this.loaderPicture[payloadId]) {
let find = this.loaderPicture[payloadId].find(item => item.fileId + '' === fileId + '')
if (find) {

View File

@ -5,7 +5,8 @@ import {
import PicturesUpload from '../pictures-upload/index.vue'
import RightSlide from '@/components/RightSlide.vue'
import LeftSlide from '@/components/LeftSlide.vue'
import { userRemove, userList, userUpdate, userSave } from '@/api/user'
import md5 from 'js-md5'
let taskListResource = []
export default {
name: 'TwinSituation',
@ -19,27 +20,42 @@ export default {
LeftSlide,
},
data() {
const cfPsdRule = (rule, value, callback) => {
if (value === '' || typeof value === 'undefined') {
callback(new Error('请再次输入密码'))
} else if (value !== this.user.form.password) {
callback(new Error('两次输入密码不一致!'))
} else {
callback()
}
}
return {
visibleLocale: false,
deviceData: [
{
name: '无人机1',
num: 'M3127',
location: '112.3423242,45.2312324'
}
userData: [
// {
// name: '无人机1',
// num: 'M3127',
// location: '112.3423242,45.2312324'
// }
],
device: {
user: {
visible: false,
form: {},
form: {
id: '',
account: '',
password: '',
confirmPassword: ''
},
rules: {
deviceName: [
{ required: true, message: '请输入设备名称', trigger: 'blur' }
account: [
{ required: true, message: '请输入用户名称', trigger: 'blur' }
],
num: [
{ required: true, message: '请输入设备编号', trigger: 'blur' }
password: [
{ required: true, message: '请输入用户密码', trigger: 'blur' }
],
location: [
{ required: true, message: '请输入设备位置', trigger: 'blur' }
confirmPassword: [
{ required: true, message: '请再次输入密码', trigger: 'blur' },
{ required: true, validator: cfPsdRule, trigger: 'blur' },
],
}
},
@ -64,41 +80,74 @@ export default {
},
},
created() {
this.userPage()
},
mounted() {
},
beforeDestroy() {
},
methods: {
addDevice() {
this.device.visible = true
userPage() {
userList().then(res => {
this.userData = res.data.data
})
},
editDevice(form) {
this.device.visible = true
this.device.form = form
addUser() {
this.user.form = {
id: '',
account: '',
password: '',
confirmPassword: ''
}
this.user.visible = true
},
detailDevice() {
this.device.visible = true
this.device.form = form
editUser(form) {
this.user.visible = true
this.user.form.account = form.account
this.user.form.id = form.id
},
close() {
this.$refs.form.resetFields()
this.device.visible = false
this.user.visible = false
this.user.form = {
id: '',
account: '',
password: '',
confirmPassword: ''
}
},
submitDevice() {
this.$refs.form.validate((valid) => {
console.log(valid, 3333333);
async submitUser() {
const valid = await this.$refs.form.validate()
if (!valid) return
delete this.user.form.confirmPassword
const form = { ...this.user.form }
form.password = md5(form.password)
if (form.id) {
userUpdate(this.user.form).then(res => {
this.$message.success('更新用户成功')
this.userPage()
this.close()
})
} else {
userSave(form).then(res => {
this.$message.success('新增用户成功')
this.userPage()
this.close()
})
}
},
async deleteDevice() {
const bool = await this.$confirm('确认要永久删除该设备吗?', '提示', {
async deleteUser(row) {
const bool = await this.$confirm('确认要永久删除该用户吗?', '提示', {
customClass: 'confirm-light',
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
console.log(bool, 333);
if (!bool) return
userRemove([row.id]).then(res => {
this.$message.success('删除用户成功')
this.userPage()
})
},
//#region 无人机详情代码

View File

@ -110,7 +110,7 @@
}
}
>.device-name {
>.user-name {
display: inline-block;
width: 110px;
height: 40px;
@ -175,7 +175,7 @@
}
}
.device-location {
.user-location {
color: $--color-text-1;
font-size: 14px;
display: flex;
@ -190,14 +190,14 @@
}
}
.device-lock {
.user-lock {
font-size: 18px;
color: #ffff00;
cursor: pointer;
}
}
.device-status {
.user-status {
width: 8px;
height: 8px;
display: inline-block;
@ -280,7 +280,7 @@
box-sizing: border-box;
}
.uav-item .device-name {
.uav-item .user-name {
width: 100px;
}
@ -305,3 +305,8 @@
top: $--icon-mode-larger-card-top;
transition: 0.2s ease-in-out;
}
::v-deep .el-icon-plus {
position: relative;
top: 2px;
}

View File

@ -2,15 +2,13 @@
<!-- 资源列表 -->
<dt-card
class="resource-list card-light"
icon="iconfont icon-left_icon_remote"
title="可用资源"
:visible.sync="visibleLocale"
:scroll="false"
:showClose="false"
:showDivider="false"
>
<template v-slot:header>
<el-form
<!-- <el-form
class="query-form"
:model="queryForm"
inline
@ -24,35 +22,21 @@
clearable
></el-input>
</el-form-item>
<!-- <el-form-item label="设备类型">
<el-select
v-model="queryForm.name"
placeholder="请输入设备类型"
popper-class="select-light"
clearable
>
<el-option
v-for="item in deviceTypes"
:key="item.value"
:value="item.value"
:label="item.label"
></el-option>
</el-select>
</el-form-item> -->
<el-form-item class="query-btn">
<el-button>查询</el-button>
</el-form-item>
</el-form>
</el-form> -->
</template>
<template v-slot:command>
<el-button size="mini" icon="el-icon-plus" @click="addDevice"
<el-button size="mini" icon="el-icon-plus" @click="addUser"
>新增用户</el-button
>
</template>
<el-table :data="deviceData" style="width: 100%">
<el-table-column prop="name" label="用户名称"> </el-table-column>
<el-table-column prop="num" label="手机号"> </el-table-column>
<el-table-column prop="location" label="邮箱"> </el-table-column>
<el-table :data="userData" style="width: 100%" height="100%">
<el-table-column prop="id" label="ID"> </el-table-column>
<el-table-column prop="account" label="用户名称"> </el-table-column>
<!-- <el-table-column prop="updateTime" label="更新时间"> </el-table-column> -->
<!-- <el-table-column prop="location" label="账号状态"> </el-table-column> -->
<el-table-column label="操作" width="200">
<template slot-scope="scope">
<el-button
@ -60,29 +44,22 @@
icon="el-icon-edit"
size="mini"
circle
@click="editDevice(scope.row)"
></el-button>
<el-button
type="info"
icon="ri-file-line"
size="mini"
circle
@click="detailDevice(scope.row)"
@click="editUser(scope.row)"
></el-button>
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
circle
@click="deleteDevice(scope.row)"
@click="deleteUser(scope.row)"
></el-button>
</template>
</el-table-column>
</el-table>
<dt-dialog
class="dialog-light"
:title="device.form.deviceId ? '编辑用户' : '新增用户'"
:visible.sync="device.visible"
:title="user.form.id ? '编辑用户' : '新增用户'"
:visible.sync="user.visible"
top="20vh"
width="22%"
append-to-body
@ -91,43 +68,48 @@
<div>
<el-form
ref="form"
:model="device.form"
:rules="device.rules"
:model="user.form"
:rules="user.rules"
label-position="right"
label-width="110px"
class="change-password-form"
>
<el-form-item label="用户名称" prop="deviceName">
<el-form-item label="用户名称" prop="account">
<el-input
v-model="device.form.deviceName"
name="account"
autocomplete="account"
v-model="user.form.account"
placeholder="请输入用户名称"
clearable
size="mini"
></el-input>
</el-form-item>
<el-form-item label="用户密码" prop="password">
<el-input
name="password"
autocomplete="new-password"
v-model="user.form.password"
placeholder="请输入用户密码"
clearable
size="mini"
show-password
></el-input>
</el-form-item>
<el-form-item label="手机号" prop="num">
<el-form-item label="确认密码" prop="confirmPassword">
<el-input
v-model="device.form.num"
placeholder="请输入用户手机号"
clearable
size="mini"
></el-input>
</el-form-item>
<el-form-item label="邮箱" prop="location">
<el-input
v-model="device.form.location"
placeholder="请输入用户邮箱"
v-model="user.form.confirmPassword"
placeholder="请再次输入密码"
clearable
size="mini"
show-password
></el-input>
</el-form-item>
</el-form>
</div>
<div class="btns" slot="footer">
<el-button @click="close" size="mini"> </el-button>
<el-button type="primary" size="mini" @click="submitDevice"
<el-button type="primary" size="mini" @click="submitUser"
> </el-button
>
</div>

View File

@ -477,7 +477,7 @@ export default {
watch: {
menusChose: {
handler: function (nv) {
console.log(nv, 33333333333);
window.localStorage.setItem('menusChose', nv)
switch (nv) {
case '1':
this.menus.situation.active = true
@ -516,7 +516,6 @@ export default {
break;
}
},
immediate: true
},
// viewMode(nv) {
// this.sendMessageByBroadcastChannel({ type: 'viewMode', form: 'home', value: nv })
@ -538,6 +537,8 @@ export default {
// },
},
created() {
const menusChose = window.localStorage.getItem('menusChose')
this.SET_MENUS_CHOSE(menusChose)
// this.init()
// this.getResourceData()
// 获取字典
@ -625,7 +626,7 @@ export default {
'SET_MAP_TYPE',
'SET_SPLIT_VISIBLE',
]),
...mapMutations('app', ['SET_THEME']),
...mapMutations('app', ['SET_THEME', 'SET_MENUS_CHOSE']),
...mapActions('dict', ['getDict']),
// 工具栏操作
toggleTools(tool) {
@ -681,7 +682,7 @@ export default {
this.sceneComplete = true
// this.addHandler()
// this.$refs.tools.handleMapChange('sat')
let position = DT.Cesium.Cartesian3.fromDegrees(window.config.defaultLocation[0], window.config.defaultLocation[1], 1000)
let position = DT.Cesium.Cartesian3.fromDegrees(window.config.defaultLocation[0], window.config.defaultLocation[1], 400000)
viewer.cesiumViewer.scene.camera.flyTo({
destination: position,
duration: 1

View File

@ -197,6 +197,7 @@ export default {
path: this.redirect || '/',
query: this.otherQuery,
})
window.localStorage.setItem('menusChose', '1')
console.log(this.$router, 'this.$router')
this.loading = false
})

View File

@ -1,9 +1,15 @@
${AnsiColor.BRIGHT_BLUE}
_____ _ _ ____ ____ _____
|_ _(_) / \ _ __ ___ ___ / ___| _ __ __ _ ___ ___ | _ \_ _|
| | | | / _ \ | '_ ` _ \ / _ \ \___ \| '_ \ / _` |/ __/ _ \_____| | | || |
| | | |/ ___ \| | | | | | (_) | ___) | |_) | (_| | (_| __/_____| |_| || |
|_| |_/_/ \_\_| |_| |_|\___/ |____/| .__/ \__,_|\___\___| |____/ |_|
______ _ __ __ _____
|___ /| | / / \ \ | ____|
/ / | |__ __ _ _ __ __ _| | _ | | _ _ | |__ ___
/ / | '_ \ / _` | '_ \ / _` | | | | | | | | | ||___ \/ __|
/ /__ | | | | (_| | | | | (_| | | | |__| | | |_| | ___) \__ \
/_____|_| |_|\__,_|_| |_|\__, |_| \____/ \__,_||____/|___/
| |
|_|
S K Y · E Y E R A D A R S Y S T E M
|_|
${AnsiColor.BRIGHT_GREEN}
Spring Boot Version: ${spring-boot.version}