From b2670c2a7f71fa80ebf1e5702bb23f33e4f2dcdc Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Sat, 31 Jan 2026 11:37:38 +0800
Subject: [PATCH] feat: 对等依赖
---
/dev/null | 14 -------
packages/constants/package.json | 8 +++
pnpm-lock.yaml | 60 ++++++++++++++++--------------
3 files changed, 39 insertions(+), 43 deletions(-)
diff --git a/applications/drone-command/src/utils/cesium/createRouteLine.js b/applications/drone-command/src/utils/cesium/createRouteLine.js
deleted file mode 100644
index 6ec1c1f..0000000
--- a/applications/drone-command/src/utils/cesium/createRouteLine.js
+++ /dev/null
@@ -1,1361 +0,0 @@
-import * as Cesium from 'cesium'
-import { Decimal } from 'decimal.js'
-import _, { cloneDeep, throttle } from 'lodash'
-import { v4 as uuidv4 } from 'uuid'
-import { render } from 'vue'
-import { analysisPointLineKmz, handlePointListForKmz } from '@/views/newRoutePlan/Waypoint/pointWayLineUtils'
-import HistoryDronePopup from '@/components/DeviceJobDetails/HistoryDronePopup.vue'
-
-import {
- getNewPolygonData,
-} from '@/views/newRoutePlan/routeUtils'
-
-import { analyzeKmzFile, removeTextKey, XMLToJSON } from '@/utils/cesium/kmz'
-import { ArrowLineMaterialProperty, LineTrailMaterial, PolylineGlowMaterial } from '@/utils/cesium/Material'
-import CreateFrustum from '@/utils/cesium/frustum/CreateFrustum'
-import { ElMessage } from 'element-plus'
-
-import rwqfdImg from '@/assets/images/signMachineNest/rwqfd.png'
-import endingOnlineImg from '@/assets/images/aiNowFly/ending-online.png'
-import newEndPointImg from '@/assets/images/newEndPointicon.png'
-import endPointImg from '@/assets/images/EndPointicon.png'
-import aircraftGltf from '@/assets/gltf/aircraft.gltf'
-import newNumPoint from '@/assets/images/newStartPoint.png'
-
-import { getPolyLine } from '@/views/newRoutePlan/Waypoint/pointWayLineUtils'
-import store from '@/store/index'
-import newStartPoint from '@/assets/images/newStartPoint.png'
-import newStartPointMore from '@/assets/images/newStartPointMore.png'
-import {
- arrowLineMaterialProperty, arrowLineMaterialPropertyGray, arrowLineMaterialPropertyGrayT,
- arrowLineMaterialPropertyGreen,
- arrowLineMaterialPropertyOrange,
-} from '@/hooks/useMorePointLine/useMorePointLine'
-
-
-let runningTextColor = Cesium.Color.fromCssColorString('#1FFF69')
-let runningTextOffset = new Cesium.Cartesian2(0, -32)
-let pendingTextColor = Cesium.Color.fromCssColorString('#FFB81D')
-let pendingTextOffset = new Cesium.Cartesian2(0, 32)
-let MapPopUpBox = HistoryDronePopup
-
-function getZoomFactor (camerasInfo, type) {
- let zoom_factor
- const irLevel = camerasInfo?.ir_zoom_factor
- const zoomLevel = camerasInfo?.zoom_factor
- if (type === 'wide') {
- zoom_factor = 1
- } else if (type === 'ir') {
- zoom_factor = irLevel
- } else {
- zoom_factor = zoomLevel
- }
- zoom_factor = _.round(zoom_factor, 1)
-
- return zoom_factor
-}
-// 记录index
-let indexLog = 0
-// 颜色
-function getPendingExecutionLineColor (lineNumber) {
- // 颜色顺序: 蓝(灰), 更灰
- const colors = [arrowLineMaterialPropertyGray, arrowLineMaterialPropertyGrayT]
- // 计算颜色索引 (从0开始)
- const colorIndex = (lineNumber - 1) % 2
- // 返回对应颜色
- return colors[colorIndex]
-}
-
-function getLineColor (lineNumber) {
- // 颜色顺序: 蓝(0), 黄(1), 绿(2)
- const colors = [arrowLineMaterialProperty, arrowLineMaterialPropertyOrange, arrowLineMaterialPropertyGreen]
- // 计算颜色索引 (从0开始)
- const colorIndex = (lineNumber - 1) % 3
- // 返回对应颜色
- return colors[colorIndex]
-}
-
-function getBase64Image (imgUrl) {
- const img = new Image()
- const canvas = document.createElement('canvas')
- const ctx = canvas.getContext('2d')
-
- return new Promise(resolve => {
- img.onload = function () {
- canvas.width = img.width
- canvas.height = img.height
- ctx.drawImage(img, 0, 0)
- const base64 = canvas.toDataURL('image/png')
- resolve(base64)
- }
- img.src = imgUrl
- })
-}
-async function createCombinedSVG (index, billboardImageUrl) {
- const base64Image = await getBase64Image(billboardImageUrl)
- const svg = `
- <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
- <image href="${base64Image}" x="10" y="10" width="80" height="80"/>
- <text x="50" y="54" font-size="26" fill="white" text-anchor="middle" dominant-baseline="middle">
- ${index + 1}
- </text>
- </svg>
- `
- return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`
-}
-
-function findHeightByCoordinates (data, targetLng, targetLat) {
- // 展平二维数组,然后查找第一个匹配的点
- const allPoints = data.flat()
- const point = allPoints.find(point =>
- point.longitude === targetLng && point.latitude === targetLat
- )
-
- return point ? point.height : null
-}
-
-function renderingMachineNest (options) {
- const { viewer, dockTransformPosition, dockPosition, data } = options
- viewer.entities.add({
- name: 'work-drone-route-point-dock',
- position: dockTransformPosition,
- billboard: {
- image: endingOnlineImg,
- width: 50,
- height: 50,
- disableDepthTestDistance: Number.POSITIVE_INFINITY,
- },
- customData: {
- data,
- },
- })
- viewer.entities.add({
- name: 'work-drone-route--point-polyline',
- position: dockTransformPosition,
- polyline: getPolyLine(viewer, { value: [dockPosition] }, 0),
- })
-}
-
-function renderingStartingPoint (options) {
- const { viewer, startPosition, data } = options
- viewer.entities.add({
- name: 'work-drone-route-point-start',
- position: startPosition,
- billboard: {
- image: rwqfdImg,
- width: 50,
- height: 50,
- disableDepthTestDistance: Number.POSITIVE_INFINITY,
- },
- customData: {
- data,
- },
- })
-}
-
-export default class CreateRouteLine {
- /**
- *
- * @param {*} options 参数
- */
- constructor(options) {
- this.type = options?.type || 'single'
- this.isShowVideoPlan = options?.isShowVideoPlan || false
-
- this.viewer = null
- this.currentWaypointIndex = null
- this.droneSpeedArr = []
-
- this.multiNestData = []
-
- this.detailsMapPopupData = []
-
- this.labelBoxRenderHandler = this.labelBoxRender.bind(this)
- this.removeLabelHandler = this.removeLabel.bind(this)
- }
-
- /**
- * 初始化viewer
- * @param {*} viewer
- */
- initCreateRoute (viewer) {
- this.viewer = viewer
- }
-
- /**
- * 设置当前所在点位
- * @param {*} data flighttaskProgressInfo 信息
- */
- setCurrentWaypointIndex (data) {
- const output = data?.output
- const sn = data?.sn
-
- if (output?.ext) {
- const currentWaypointIndex = output?.ext['current_waypoint_index']
-
- this.updataMultiNestData(sn, {
- currentWaypointIndex,
- })
- }
- }
-
- /**
- * 请求航线文件数据并绘制解析处理
- * @param {*} data 包含文件url等信息
- * @param {*} dockPosition 无人机位置
- * @returns
- */
- async parsingFiles (data, dockPosition = null, isShowDock = false, isShowPointBillboard = true) {
- console.log(data,'888')
- const { url, wayline_type, device_sn } = data
- indexLog = 0
- if (!url)
- return dockPosition != null
- ? {
- dronePosition: [{ lng: dockPosition.longitude, lat: dockPosition.latitude, alt: dockPosition.height }],
- }
- : {}
- this.updataMultiNestData(device_sn)
-
- const res = await analyzeKmzFile(`${url}?_t=${new Date().getTime()}`)
-
- const templateXML = await res.fileInfoObj['wpmz/template.kml']
- const waylinesXML = await res.fileInfoObj['wpmz/waylines.wpml']
-
- const templateXmlJson = XMLToJSON(templateXML)?.['Document']
- const waylinesXmlJson = XMLToJSON(waylinesXML)?.['Document']
-
- const templateXMLObj = removeTextKey(templateXmlJson.Folder)
- const { takeOffRefPoint } = removeTextKey(templateXmlJson.missionConfig)
-
- const [latitude, longitude, height] = takeOffRefPoint.split(',').map(item => _.round(item, 6))
-
- const startPoint = { latitude, longitude, height: Number.isNaN(height) ? 0 : height }
-
- const { templateType } = templateXMLObj
-
- const missionConfig = removeTextKey(waylinesXmlJson.missionConfig)
- const waylinesXMLObj = removeTextKey(waylinesXmlJson.Folder)
-
- if (templateType === 'mapping3d') {
- if (!waylinesXMLObj[0].Placemark.length) return ElMessage.error('没有航线点位')
- } else {
- if (!waylinesXMLObj.Placemark.length) return ElMessage.error('没有航线点位')
- }
-
- if ([2, 4, 5, 7, 10].includes(Number(wayline_type))) {
- if (templateType === 'mapping3d') {
- let morePolygonData = waylinesXMLObj.map(i => ({
- data: i.Placemark,
- }))
-
- let newPolygonData = getNewPolygonData(morePolygonData)
-
- let newPolygonDisposePositions = newPolygonData.map(i =>
- Cesium.Cartesian3.fromDegrees(Number(i[0]), Number(i[1]))
- )
-
- this.viewer.entities.add({
- name: 'work-drone-route-planar-outer-polygon',
-
- polygon: {
- hierarchy: new Cesium.CallbackProperty(() => {
- return new Cesium.PolygonHierarchy(newPolygonDisposePositions)
- }, false),
- material: Cesium.Color.fromBytes(255, 228, 22, 44),
- outline: false,
- outlineWidth: 2,
- heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
- },
- })
-
- return this.drawPlanarRoute(
- waylinesXMLObj[0],
- missionConfig,
- templateXmlJson,
- dockPosition,
- data,
- startPoint,
- isShowDock,
- isShowPointBillboard,
- wayline_type
- )
- }
-
- return this.drawPlanarRoute(
- waylinesXMLObj,
- missionConfig,
- templateXmlJson,
- dockPosition,
- data,
- startPoint,
- isShowDock,
- isShowPointBillboard,
- wayline_type
- )
- } else {
- return this.drawPointRoute(
- waylinesXMLObj,
- missionConfig,
- dockPosition,
- data,
- startPoint,
- isShowDock,
- isShowPointBillboard,
- wayline_type
- )
- }
- }
-
- // 拆分航线
- async splitWayLine (data, dronePosition = null, isShowDock = false, isShowPointBillboard = true) {
- const {
- pointPlacemark,
- polygonList,
- pointList,
- templateType,
- startPoint,
- execute_height_mode,
- auto_flight_speed,
- take_off_security_height,
- buffer_distance_meters,
- missionConfig,
- waylinesXMLObjR,
- } = await analysisPointLineKmz(`${data.domain_url}${data.object_key}`)
- const { positionArray, filePositions } = this.disposeData(
- waylinesXMLObjR,
- missionConfig,
- null,
- data,
- startPoint,
- 0
- )
- let bigPointList = handlePointListForKmz({
- placemark: pointPlacemark,
- startPoint: startPoint,
- execute_height_mode: execute_height_mode,
- auto_flight_speed: auto_flight_speed,
- })
- // 路径线
- let entityConfig
- bigPointList.shift()
- let flyPositions = bigPointList.map(i => [Number(i.longitude), Number(i.latitude), Number(i.height)])
- // 渲染多个点
- let firstTopPosition = null
- let resultPosotions = []
- await Promise.all(data.wayline_file_list.map(async (item, index) => {
- // 小航线渲染线
- const kmzUrl = import.meta.env.VITE_APP_AIRLINE_URL + item.object_key
- const { pointList } = await analysisPointLineKmz(kmzUrl)
- resultPosotions.push(pointList)
- })).then(res => {
- // 目的是区分大航线点属于哪条小航线
- bigPointList.forEach(bigObj => {
- let foundIndex = -1
- // 遍历 resultPositions 查找匹配项
- resultPosotions.some((subArray, subIndex) => {
- const found = subArray.some(obj =>
- obj.latitude === bigObj.latitude &&
- obj.longitude === bigObj.longitude
- )
- if (found) {
- foundIndex = subIndex
- return true // 找到就停止搜索
- }
- return false
- })
- // 如果找到了,给 bigPointList 的对象添加标记
- if (foundIndex !== -1) {
- bigObj.log = foundIndex // 或 bigObj.index = foundIndex
- }
- })
- console.log(bigPointList, '查看结果值') // 现在 bigPointList 会有 log 属性
- bigPointList.map(async (i, index) => {
- firstTopPosition = i
- const position = Cesium.Cartesian3.fromDegrees(Number(i.longitude), Number(i.latitude), Number(findHeightByCoordinates(resultPosotions, i.longitude, i.latitude)))
- const combinedImage = await createCombinedSVG(index, i.log % 2 ? newStartPoint : newStartPointMore)
-
- entityConfig = {
- name: 'work-drone-route-point-split',
- position: position,
- billboard: {
- disableDepthTestDistance: Number.POSITIVE_INFINITY,
- image: combinedImage,
- width: 50,
- height: 50,
- verticalOrigin: Cesium.VerticalOrigin.CENTER,
- horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
- }
- }
-
- // 只在第一个点添加 label
- if (index === 0) {
- entityConfig.label = {
- text: data.task_name || '',
- font: 'bold 16px sans-serif',
- fillColor: data.status === 2 ? runningTextColor : pendingTextColor,
- pixelOffset: data.status === 2 ? runningTextOffset : pendingTextOffset,
- style: Cesium.LabelStyle.FILL_AND_OUTLINE,
- outlineWidth: 2,
- outlineColor: Cesium.Color.BLACK,
- disableDepthTestDistance: Number.POSITIVE_INFINITY,
- }
- }
-
- this.viewer.entities.add(entityConfig)
- })
- })
-
- // 渲染航线
- data.wayline_file_list.map(async (item, index) => {
- // 小航线渲染线
- const kmzUrl = import.meta.env.VITE_APP_AIRLINE_URL + item.object_key
- const { pointList } = await analysisPointLineKmz(kmzUrl)
- // if (curRouteLineData.value.droneData && splitLines.length === 1) {
- // // 把pointList的第一个点替换为无人机位置
- // pointList[0] = curRouteLineData.value.droneData[0]
- // }
- if (take_off_security_height + pointList[0].height > firstTopPosition.height) {
- // 安全高度+机巢高度 > 第一个点高度
- const positionTest = {
- longitude: pointList[0].longitude,
- latitude: pointList[0].latitude,
- height: take_off_security_height + pointList[0].height,
- }
-
- const positionTest1 = {
- longitude: pointList[1].longitude,
- latitude: pointList[1].latitude,
- height: take_off_security_height + pointList[0].height,
- }
- pointList.splice(1, 0, positionTest)
- // 往数组中插入元素
- pointList.splice(2, 0, positionTest1)
- // console.log(pointList, 'pointList')
- } else if (take_off_security_height + pointList[0].height < firstTopPosition.height) {
- const positionTest = {
- longitude: pointList[0].longitude,
- latitude: pointList[0].latitude,
- height: firstTopPosition.height,
- }
- pointList.splice(1, 0, positionTest)
- }
- const routePositions = pointList.map(i =>
- Cesium.Cartesian3.fromDegrees(Number(i.longitude), Number(i.latitude), Number(i.height))
- )
-
- this.viewer.entities.add({
- name: 'work-drone-route-line-split',
- polyline: {
- width: 4,
- positions: routePositions,
- material: data.status === 1 ? arrowLineMaterialPropertyGray : getLineColor(index + 1),
- clampToGround: false,
- },
- })
- })
- // 落点线
- ; (bigPointList || [])?.forEach((item, index) => {
- const topPosition = Cesium.Cartesian3.fromDegrees(
- Number(item.longitude),
- Number(item.latitude),
- Number(item.height)
- )
- let setting = {
- name: 'work-drone-route--planar-polyline-split',
- position: topPosition,
- polyline: getPolyLine(this.viewer, { value: bigPointList }, index),
- }
- this.viewer.entities.add(setting)
- })
- return {
- entity: entityConfig,
- routeLinePositions: positionArray,
- filePositions:
- dronePosition != null
- ? [{ lng: dronePosition.longitude, lat: dronePosition.latitude, alt: dronePosition.height }, ...filePositions]
- : filePositions,
- }
- }
-
- /**
- * 绘制面状航线
- * @param {*} lineObj 航线文件中的
- * @param {*} missionConfig 航线文件中的
- * @param {*} templateXmlJson 航线文件中的
- * @param {*} dockPosition 无人机位置
- * @param {*} data
- * @param {*} startPoint
- * @returns
- */
- async drawPlanarRoute (
- lineObj,
- missionConfig,
- templateXmlJson,
- dockPosition,
- data,
- startPoint,
- isShowDock,
- isShowPointBillboard,
- wayline_type
- ) {
- const { positionArray, filePositions } = this.disposeData(
- lineObj,
- missionConfig,
- dockPosition,
- data,
- startPoint,
- wayline_type
- )
- const { device_sn } = data
-
- const dockTransformPosition = Cesium.Cartesian3.fromDegrees(
- Number(dockPosition.longitude),
- Number(dockPosition.latitude),
- Number(dockPosition.height)
- )
-
- let coordArr = null
-
- const placemark = templateXmlJson.Folder?.Placemark
- // 取出点位
- const coordinates = placemark.Polygon?.outerBoundaryIs.LinearRing.coordinates?.['#text']?.split('\n') || []
- // 数组转换
- coordArr = coordinates.map(coordinate =>
- coordinate
- .replace(/\s+/g, '')
- .split(',')
- .map(v => Number(v))
- )
-
- // 获取当前经纬度绝对高度
- let newCoordArr = coordArr.map(item => [item[0], item[1], 0])
- let planarRouteEntity = this.viewer.entities.add({
- name: 'work-drone-route-planar-polyline',
- polyline: {
- width: 3,
- positions: positionArray,
- material: Cesium.Color.CHARTREUSE,
- zIndex: 1,
- },
-
- customData: {
- data,
- },
- })
-
- let droppointPositions = (filePositions || [])?.map(i => ({
- longitude: Number(i.lng),
- latitude: Number(i.lat),
- height: Number(i.alt),
- }))
-
- // 落点线
- ; (droppointPositions || [])?.forEach((item, index) => {
- const topPosition = Cesium.Cartesian3.fromDegrees(
- Number(item.longitude),
- Number(item.latitude),
- Number(item.height)
- )
- let setting = {
- name: 'work-drone-route--planar-polyline',
- position: topPosition,
- polyline: getPolyLine(this.viewer, { value: droppointPositions }, index),
- }
- this.viewer.entities.add(setting)
- })
-
- // 面状航线第一个点突出展示
- isShowPointBillboard && this.startingIncreasePoint(positionArray)
-
- // 面状判断当前点位数量
- const cloneCoordArr = [...newCoordArr]
-
- if (cloneCoordArr.length >= 3) {
- cloneCoordArr.push(newCoordArr[0])
- }
-
- // 绘制面状边框线--------------------
- this.viewer.entities.add({
- name: 'work-drone-route-planar-border',
-
- polyline: {
- positions: Cesium.Cartesian3.fromDegreesArrayHeights(cloneCoordArr.flat()),
- width: 4,
- material: new Cesium.PolylineOutlineMaterialProperty({
- color: new Cesium.Color.fromBytes(74, 138, 233),
- outlineWidth: 2,
- outlineColor: Cesium.Color.WHITE,
- }),
- zIndex: -1,
- clampToGround: true,
- },
- })
-
- // 绘制面状地块--------------------
- this.viewer.entities.add({
- name: 'work-drone-route-planar-polygon',
- polygon: {
- hierarchy: Cesium.Cartesian3.fromDegreesArrayHeights(newCoordArr.flat()),
- material: new Cesium.Color.fromBytes(75, 159, 221, 100),
- outline: true,
- outlineColor: new Cesium.Color.fromBytes(35, 85, 216, 255),
- zIndex: -1,
- },
- })
-
- if (this.type === 'clusterScheduling') {
- this.viewer.entities.add({
- name: 'work-drone-route-point-start',
- position: Cesium.Cartesian3.fromDegrees(filePositions[0].lng, filePositions[0].lat, filePositions[0].alt),
-
- billboard: {
- image: rwqfdImg,
- outlineWidth: 0,
- width: 50,
- height: 50,
- disableDepthTestDistance: Number.POSITIVE_INFINITY,
- },
-
- label: {
- text: data.job_name || '',
- font: 'bold 16px sans-serif',
- fillColor: Cesium.Color.WHITE,
- pixelOffset: new Cesium.Cartesian2(0, -50),
- style: Cesium.LabelStyle.FILL_AND_OUTLINE,
- outlineWidth: 2,
- outlineColor: Cesium.Color.BLACK,
- disableDepthTestDistance: Number.POSITIVE_INFINITY,
- },
- })
- } else {
- // 显示机巢位置
- isShowDock && renderingMachineNest({
- viewer: this.viewer,
- dockTransformPosition,
- dockPosition,
- data
- })
- // 起点
- isShowPointBillboard && renderingStartingPoint({
- viewer: this.viewer,
- startPosition: Cesium.Cartesian3.fromDegrees(
- Number(filePositions[0].lng),
- Number(filePositions[0].lat),
- Number(filePositions[0].alt)
- ),
- data
- })
- }
-
- return {
- entity: planarRouteEntity,
- routeLinePositions: positionArray,
- filePositions:
- dockPosition != null
- ? [{ lng: dockPosition.longitude, lat: dockPosition.latitude, alt: dockPosition.height }, ...filePositions]
- : filePositions,
- }
- }
-
- planarBillboard (color) {
- const billboard = document.createElement('canvas')
- const ctx = billboard.getContext('2d')
- const radius = 4
- ctx.beginPath()
- ctx.arc(radius, radius, radius, 0, 2 * Math.PI, false)
- ctx.fillStyle = color // 设置填充颜色
- ctx.fill()
- return billboard
- }
-
- startingIncreasePoint (wayData) {
- let positions = wayData[3]
-
- let setting = {
- name: 'work-drone-route-planar-start',
- position: positions,
- billboard: {
- image: this.planarBillboard('#2D8CF0'),
- pixelOffset: new Cesium.Cartesian2(146, 72),
- zIndex: 2,
- },
- }
-
- this.viewer.entities.add(setting)
- }
-
- /**
- * 绘制点航线
- * @param {*} lineObj 航线文件中的
- * @param {*} missionConfig 航线文件中的
- * @param {*} dockPosition 无人机位置
- * @param {*} data 任务信息,航线地址等
- * @param {*} startPoint
- * @param {*} isShowDock 是否显示机巢位置
- * @returns
- */
- async drawPointRoute (
- lineObj,
- missionConfig,
- dockPosition,
- data,
- startPoint,
- isShowDock,
- isShowPointBillboard,
- wayline_type
- ) {
- const { positionArray, filePositions } = this.disposeData(
- lineObj,
- missionConfig,
- dockPosition,
- data,
- startPoint,
- wayline_type
- )
-
- const dockTransformPosition = Cesium.Cartesian3.fromDegrees(
- Number(dockPosition.longitude),
- Number(dockPosition.latitude),
- Number(dockPosition.height)
- )
- // 路径线
- let polyline
-
- indexLog = indexLog + 1
-
- if (this.type === 'clusterScheduling') {
- filePositions.forEach((item, index) => {
- let position = Cesium.Cartesian3.fromDegrees(item.lng, item.lat, item.alt)
- if (index === 0) {
- this.viewer.entities.add({
- name: 'work-drone-route-point-start',
- position,
- billboard: {
- image: rwqfdImg,
- outlineWidth: 0,
- width: 50,
- height: 50,
- disableDepthTestDistance: Number.POSITIVE_INFINITY,
- },
- label: {
- text: data.job_name || '',
- font: 'bold 16px sans-serif',
- fillColor: data.type === 2 ? runningTextColor : pendingTextColor,
- pixelOffset: data.type === 2 ? runningTextOffset : pendingTextOffset,
- style: Cesium.LabelStyle.FILL_AND_OUTLINE,
- outlineWidth: 2,
- outlineColor: Cesium.Color.BLACK,
- disableDepthTestDistance: Number.POSITIVE_INFINITY,
- },
- })
- } else if (index === filePositions.length - 1) {
- this.viewer.entities.add({
- name: 'work-drone-route-point-end',
- position,
- billboard: {
- image: newEndPointImg,
- outlineWidth: 0,
- width: 40,
- height: 40,
- scale: 1.0,
- verticalOrigin: Cesium.VerticalOrigin.TOP, // 添加这行确保图标正确显示
- pixelOffset: new Cesium.Cartesian2(0, -20), // 根据需要调整偏移量
- },
- })
- } else {
- this.viewer.entities.add({
- name: 'work-drone-route-point-approach',
- position,
- billboard: {
- image: newNumPoint,
- width: 50,
- height: 50,
- },
-
- label: {
- text: `${index}`,
- font: 'bold 14px serif',
- fillColor: Cesium.Color.WHITE,
- pixelOffset: new Cesium.Cartesian2(1, 0), // 根据需要调整偏移量
- eyeOffset: new Cesium.Cartesian3(0, 0, -10), // 使标签在点的上方
- },
-
- offset: new Cesium.Cartesian2(10, 30),
- })
- }
- })
- polyline = this.viewer.entities.add({
- name: 'work-drone-route-point-polyline',
- polyline: {
- width: 4,
- positions: positionArray,
- material: data.type === 2 ? getLineColor(indexLog) : arrowLineMaterialPropertyGray,
- clampToGround: false,
- },
- })
- } else {
- // 显示机巢位置
- isShowDock && renderingMachineNest({
- viewer: this.viewer,
- dockTransformPosition,
- dockPosition
- })
- // 起点
- isShowPointBillboard && renderingStartingPoint({
- viewer: this.viewer,
- startPosition: Cesium.Cartesian3.fromDegrees(
- Number(filePositions[0].lng),
- Number(filePositions[0].lat),
- Number(filePositions[0].alt)
- ),
- data
- })
- // 终点
- isShowPointBillboard &&
- this.viewer.entities.add({
- name: 'work-drone-route-point-end',
- position: positionArray[positionArray.length - 1],
- billboard: {
- image: new Cesium.ConstantProperty(endPointImg),
- width: 30,
- height: 30,
- verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 底部对齐
- },
- })
- console.log(data.status, '失败')
- polyline = this.viewer.entities.add({
- name: 'work-drone-route-point-polyline',
- polyline: {
- width: 4,
- positions: positionArray,
- material: data.status === 5 ? arrowLineMaterialPropertyGray : getLineColor(indexLog),
- clampToGround: false,
- },
- customData: {
- data,
- },
- })
- }
-
- let droppointPositions = (filePositions || [])?.map(i => ({
- longitude: Number(i.lng),
- latitude: Number(i.lat),
- height: Number(i.alt),
- }))
-
- // 落点线
- ; (droppointPositions || [])?.forEach((item, index) => {
- const topPosition = Cesium.Cartesian3.fromDegrees(
- Number(item.longitude),
- Number(item.latitude),
- Number(item.height)
- )
-
- let setting = {
- name: 'work-drone-route--point-polyline',
- position: topPosition,
- polyline: getPolyLine(this.viewer, { value: droppointPositions }, index),
- }
- this.viewer.entities.add(setting)
- })
-
- return {
- entity: polyline,
- routeLinePositions: positionArray,
- filePositions:
- dockPosition !== null
- ? [{ lng: dockPosition.longitude, lat: dockPosition.latitude, alt: dockPosition.height }, ...filePositions]
- : filePositions,
- }
- }
-
- /**
- * 通用处理数据
- * @param {*} lineObj
- * @param {*} missionConfig
- * @param {*} dronePosition
- * @param {*} startPoint
- * @returns {} {positionArray: 带拼接点位置, filePositions:光航线点位置}
- */
- disposeData (lineObj, missionConfig, dronePosition, data, startPoint, wayline_type) {
- const { device_sn } = data
- const executeHeightMode = lineObj.executeHeightMode === 'WGS84'
-
- let filePositions = lineObj.Placemark.map(item => {
- const [lng, lat] = item.Point.coordinates.split(',')
- const height = item.executeHeight
-
- return {
- lng: Number(lng),
- lat: Number(lat),
- alt: Number(height),
- }
- })
-
- let safetyHeight
-
- if (executeHeightMode) {
- let startHeight = new Decimal(missionConfig.takeOffSecurityHeight).plus(dronePosition?.height || 0).toNumber()
-
- safetyHeight = startHeight < filePositions[0].alt ? filePositions[0].alt : startHeight
- } else {
- safetyHeight =
- missionConfig.takeOffSecurityHeight < filePositions[0].alt
- ? filePositions[0].alt
- : missionConfig.takeOffSecurityHeight
- }
-
- let safetyPositions = []
-
- if (dronePosition != null) {
- safetyPositions = [
- {
- lng: Number(dronePosition.longitude),
- lat: Number(dronePosition.latitude),
- alt: Number(dronePosition.height),
- },
-
- {
- lng: Number(dronePosition.longitude),
- lat: Number(dronePosition.latitude),
- alt: Number(safetyHeight),
- },
-
- {
- lng: filePositions[0].lng,
- lat: filePositions[0].lat,
- alt: Number(safetyHeight),
- },
- ]
- }
-
- let pointAll = [...safetyPositions, ...filePositions]
-
- const currentRoutePositions = pointAll.map((item, index) => {
- let height = executeHeightMode ? item.alt : item.alt + (dronePosition != null ? dronePosition.height : 0)
-
- if (index == 0) height = item.alt
-
- return Cesium.Cartesian3.fromDegrees(item.lng, item.lat, height)
- })
-
- this.updataMultiNestData(device_sn, {
- currentRoutePositions,
- })
-
- if ([0].includes(wayline_type)) {
- let startHeight = executeHeightMode
- ? filePositions[0].alt
- : filePositions[0].alt + (dronePosition != null ? dronePosition.height : 0)
- let endHeight = executeHeightMode
- ? filePositions[1].alt
- : filePositions[1].alt + (dronePosition != null ? dronePosition.height : 0)
-
- this.updataMultiNestData(device_sn, {
- showPopupPosition: Cesium.Cartesian3.midpoint(
- Cesium.Cartesian3.fromDegrees(filePositions[0].lng, filePositions[0].lat, startHeight),
- Cesium.Cartesian3.fromDegrees(filePositions[1].lng, filePositions[1].lat, endHeight),
- new Cesium.Cartesian3()
- ),
- })
- } else {
- let startHeight = executeHeightMode
- ? safetyPositions[1].alt
- : safetyPositions[1].alt + (dronePosition != null ? dronePosition.height : 0)
- let endHeight = executeHeightMode
- ? safetyPositions[2].alt
- : safetyPositions[2].alt + (dronePosition != null ? dronePosition.height : 0)
-
- this.updataMultiNestData(device_sn, {
- showPopupPosition: Cesium.Cartesian3.midpoint(
- Cesium.Cartesian3.fromDegrees(safetyPositions[1].lng, safetyPositions[1].lat, startHeight),
- Cesium.Cartesian3.fromDegrees(safetyPositions[2].lng, safetyPositions[2].lat, endHeight),
- new Cesium.Cartesian3()
- ),
- })
- }
-
- return {
- positionArray: currentRoutePositions,
- filePositions: filePositions.map(item => {
- let height = executeHeightMode ? item.alt : item.alt + (dronePosition != null ? dronePosition.height : 0)
-
- return {
- ...item,
- alt: Number(height),
- }
- }),
- }
- }
-
- /**
- * 删除entity
- */
- removeAllRouteEntity () {
- const entities = this.viewer?.entities.values.filter(i => {
- return i?.name && i?.name.includes('work-drone-route-')
- })
-
- Array.isArray(entities) &&
- entities.forEach(item => {
- this.viewer?.entities.remove(item)
- })
- }
-
- // 当前无人机视椎体相关
- setCreateFrustum (host, zoomFactor = {}, cameraParams = {}) {
- if (!host) return
-
- const parent_sn = host?.parent_sn
-
- if (parent_sn) {
- const curDroneData = this.getCurDroneData(parent_sn)
-
- curDroneData.viewInfoFrustum?.destroyed()
-
- const attitude_head = 180 + host?.attitude_head
- const gimbal_pitch = 90 - Number(host?.payloads[0]?.gimbal_pitch) || 0
-
- let fov = 60
-
- if (
- zoomFactor?.value?.set === true &&
- cameraParams?.value?.set === true &&
- curDroneData?.camera_type &&
- ['wide', 'ir', 'zoom'].includes(curDroneData?.camera_type)
- ) {
- if (curDroneData.camera_type === 'wide') {
- fov = 65
- } else {
- const cameraMultiplier = getZoomFactor(host?.cameras?.[0], curDroneData.camera_type)
- switch (cameraMultiplier) {
- case 2: fov = 30; break
- case 3: fov = 19; break
- case 4: fov = 15; break
- case 5: fov = 13; break
- case 6: fov = 11; break
- case 7: fov = 9; break
- case 8: fov = 8.34; break
- case 9: fov = 7.68; break
- case 10: fov = 6.9; break
- case 14: fov = 5; break
- default: fov = 55.946 * Math.exp(-0.4504 * cameraMultiplier) + 6.323
- }
- }
- }
-
- this.updataMultiNestData(parent_sn, {
- viewInfoFrustum: new CreateFrustum(this.viewer, {
- position: {
- longitude: host?.longitude,
- latitude: host?.latitude,
- altitude: host?.height,
- },
- width: store.state.common.liveResolution.width || 960,
- height: store.state.common.liveResolution.height || 720,
- fov: fov,
- near: 0.01,
- far: 250,
- roll: gimbal_pitch,
- pitch: 0,
- heading: attitude_head,
-
- isShowVideoPlan: this.isShowVideoPlan,
- }),
- })
- }
- }
-
- setLiveStatusWs (data) {
- const { device_sn, live_status } = data
-
- if (device_sn && live_status) {
- this.updataMultiNestData(device_sn, {
- camera_type: live_status?.[0].video_type || 'wide',
- })
- }
- }
-
- removeCreateFrustum (host) {
- const parent_sn = host?.parent_sn
-
- if (parent_sn) {
- const curDroneData = this.getCurDroneData(parent_sn)
-
- curDroneData.viewInfoFrustum?.clear()
- }
- }
-
- // 设置当前无人机视椎体信息面板
- setFrustumInfoDetails (data) {
- const { dock_sn, distance_to_airport, distance_to_next_point, estimated_time_to_next_point, plane_mileage } = data
-
- if (dock_sn) {
- const aircraftEntity = this.viewer?.entities.values.find(i => {
- return i?.name && i?.name.includes(`aircraft-glf-${dock_sn}`)
- })
-
- if (aircraftEntity) {
- // 预计到达下一个航点时间
- let arrivalTime = estimated_time_to_next_point
-
- if (arrivalTime > 60) {
- const minute = Math.floor(arrivalTime / 60)
- const second = Math.round(arrivalTime % 60)
- arrivalTime = `${minute}m${second}s`
- } else {
- arrivalTime = Math.round(arrivalTime) + 's'
- }
-
- aircraftEntity.label = new Cesium.LabelGraphics({
- text: `离机场平面距离:${distance_to_airport}m\n离下个航点平面距离:${Math.round(
- distance_to_next_point
- )}m\n到达下个航点剩余时间:${arrivalTime}\n航线总平面里程:${Math.round(plane_mileage)}m`,
- font: '13px monospace',
- showBackground: true,
- horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
- verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
- disableDepthTestDistance: Number.POSITIVE_INFINITY,
- pixelOffset: new Cesium.Cartesian2(0, -40),
- show: true,
- })
-
- return
- }
- }
- }
-
- removeFrustumInfoDetails (host) {
- const parent_sn = host?.parent_sn
-
- if (parent_sn) {
- const aircraftEntity = this.viewer?.entities.values.find(i => {
- return i?.name && i?.name.includes(`aircraft-glf-${parent_sn}`)
- })
-
- if (aircraftEntity) {
- aircraftEntity.label.show = false
- }
- }
- }
-
- // 设置无人机模型
- setAircraftGltf (host) {
- const parent_sn = host?.parent_sn
- const attitude_head = Number(host?.payloads?.[0]?.gimbal_yaw) - 90 || 0
-
- if (parent_sn) {
- const aircraftEntity = this.viewer?.entities.values.find(i => {
- return i?.name && i?.name.includes(`aircraft-glf-${parent_sn}`)
- })
-
- const position = Cesium.Cartesian3.fromDegrees(host?.longitude, host?.latitude, host?.height)
- // ✅ 新增:Heading / Pitch / Roll(单位:度 -> 弧度)
- const heading = Cesium.Math.toRadians(attitude_head) // 航向角
- const pitch = Cesium.Math.toRadians(0) // 俯仰角
- const roll = Cesium.Math.toRadians(0) // 横滚角
-
- // ✅ 新增:构造 HeadingPitchRoll 和 四元数
- const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll)
- const orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr)
-
- if (aircraftEntity) {
- aircraftEntity.position = new Cesium.ConstantPositionProperty(position)
- aircraftEntity.orientation = new Cesium.ConstantProperty(orientation)
-
- return
- }
-
- if (parent_sn) {
- this.viewer?.entities.add({
- name: `aircraft-glf-${parent_sn}`,
- position,
- orientation,
- label: {},
- model: {
- uri: aircraftGltf, // 或 .glb
- scale: 64, // 缩放比例
- minimumPixelSize: 64, // 最小像素尺寸(保证模型远处可见)
- maximumScale: 64, // 最大缩放(可选)
- },
- })
- }
- }
- }
-
- // 移除无人机模型
- removeAircraftGltf (host) {
- const parent_sn = host?.parent_sn
-
- if (parent_sn) {
- const aircraftEntity = this.viewer?.entities.values.find(i => {
- return i?.name && i?.name.includes(`aircraft-glf-${parent_sn}`)
- })
-
- if (aircraftEntity) {
- this.viewer?.entities.remove(aircraftEntity)
- }
- }
- }
-
- // 移除所有无人机视椎体
- removeViewInfoFrustum () {
- this.multiNestData.forEach(item => {
- if ('viewInfoFrustum' in item && item.viewInfoFrustum) {
- item.viewInfoFrustum?.clear()
-
- delete item.viewInfoFrustum
- }
- })
- }
-
- mapEntityRemove (host) {
- const parent_sn = host?.parent_sn
-
- if (parent_sn) {
- const curDroneData = this.getCurDroneData(parent_sn)
-
- curDroneData.viewInfoFrustum?.clear()
-
- delete curDroneData.viewInfoFrustum
-
- const entities = this.viewer?.entities.values.filter(i => {
- return i?.name && i?.name.includes(`aircraft-glf-${parent_sn}`)
- })
-
- Array.isArray(entities) &&
- entities.forEach(item => {
- this.viewer?.entities.remove(item)
- })
- }
- }
-
- mapEntityRemoveAll () {
- const entities = this.viewer?.entities.values.filter(i => {
- return i?.name && i?.name.includes(`aircraft-glf-`)
- })
-
- Array.isArray(entities) &&
- entities.forEach(item => {
- this.viewer?.entities.remove(item)
- })
-
- this.multiNestData.length > 0 &&
- this.multiNestData.forEach(item => {
- item.viewInfoFrustum?.clear()
- })
- }
-
- /**
- * 更新多机场数据
- * @param {*} device_sn 机巢SN
- * @param {*} data 机巢对应需绑定数据
- */
- updataMultiNestData (device_sn, data) {
- const isHave = this.multiNestData.find(item => item.device_sn === device_sn)
- const isHaveInd = this.multiNestData.findIndex(item => item.device_sn === device_sn)
-
- if (isHave) {
- this.multiNestData[isHaveInd] = {
- ...this.multiNestData[isHaveInd],
-
- ...data,
- }
- } else {
- this.multiNestData.push({
- device_sn,
- ...data,
- })
- }
- }
-
- /**
- * 根据机巢sn获取当前机巢对应的相关信息
- * @param {*} device_sn
- */
- getCurDroneData (device_sn) {
- const isHave = this.multiNestData.find(item => item.device_sn === device_sn)
-
- if (isHave) return this.multiNestData.find(item => item.device_sn === device_sn)
-
- return false
- }
-
- showDetailMapPopup (data) {
- const that = this
- this.detailsMapPopupData = data.map(item => {
- return {
- ...item,
- show: true,
- uuid: uuidv4(),
- }
- })
- this.viewer.scene.postRender.addEventListener(that.labelBoxRenderHandler)
- }
-
- showSingleDetailMapPopup (data) {
- this.detailsMapPopupData.forEach(
- i => i?.job_id === data?.job_id && i?.device_sn === data?.device_sn && (i.show = true)
- )
- }
-
- getLabelDom (data) {
- const that = this
- const vNode = h(MapPopUpBox, { data, removeLabel: that.removeLabelHandler })
- const tooltipContainer = document.createElement('div')
-
- tooltipContainer.id = data.uuid
- tooltipContainer.style.position = 'absolute'
- tooltipContainer.style.transform = 'translate(-50%,10%)'
- tooltipContainer.style.pointerEvents = 'none'
- document.querySelector('.content-map-popups').append(tooltipContainer)
- render(vNode, tooltipContainer)
- return tooltipContainer
- }
-
- labelBoxRender () {
- this.detailsMapPopupData
- .filter(i => i.show === true)
- .forEach(item => {
- const { showPopupPosition } = this.getCurDroneData(item.device_sn)
-
- let dom = document.querySelector(`[id="${item.uuid}"]`)
-
- if (!dom) {
- dom = this.getLabelDom(item)
- }
-
- const screenPosition = this.viewer?.scene.cartesianToCanvasCoordinates(showPopupPosition)
- if (screenPosition) {
- dom.style.left = `${screenPosition.x}px`
- dom.style.top = `${screenPosition.y}px`
- dom.style.display = 'block'
- }
- })
- }
-
- // 移除弹框标签
- removeLabel (data) {
- const that = this
-
- that.removeDom(data)
- }
-
- removeDom (data) {
- const that = this
-
- const dom = document.querySelector(`[id="${data.uuid}"]`)
-
- if (dom && dom.parentNode) {
- that.detailsMapPopupData.forEach(i => i.uuid === data.uuid && (i.show = false))
-
- dom.parentNode.removeChild(dom)
- }
- }
-
- destroyedCustomDom () {
- const that = this
- that.viewer?.scene.postRender.removeEventListener(that.labelBoxRenderHandler)
- }
-}
diff --git a/applications/drone-command/src/views/job/components/CancelTaskDialog.vue b/applications/drone-command/src/views/job/components/CancelTaskDialog.vue
deleted file mode 100644
index 9f039c2..0000000
--- a/applications/drone-command/src/views/job/components/CancelTaskDialog.vue
+++ /dev/null
@@ -1,152 +0,0 @@
-<template>
- <el-dialog
- v-model="dialogVisible"
- :width="400"
- :close-on-click-modal="false"
- :destroy-on-close="true"
- class="cancel-task-dialogs"
- >
- <div class="dialog-headers">
- <img @click="closeClick" src="@/assets/images/task/close.png" alt="" />
- </div>
- <div class="dialog-contents">
- <div class="dialog-text">您确定取消任务?</div>
- <div class="dialog-btns">
- <img src="@/assets/images/task/cancel-one.png" @click="handleCancel" alt="" />
- <img src="@/assets/images/task/cancel-all.png" @click="handleCancelAll" alt="" />
- </div>
- </div>
- </el-dialog>
-</template>
-<script setup>
-import { cancelJobs } from '@/api/job/task'
-import { ElMessage } from 'element-plus'
-
-const props = defineProps({
- isShowCancelTask: {
- type: Boolean,
- default: false,
- },
- rowData: {
- type: Object,
- required: true,
- },
-})
-
-const emit = defineEmits(['update:isShowCancelTask', 'refresh'])
-
-const dialogVisible = computed({
- get: () => props.isShowCancelTask,
- set: val => emit('update:isShowCancelTask', val),
-})
-
-// 取消本次
-const handleCancel = () => {
- submitCancelTask(props.rowData, 1)
- dialogVisible.value = false
-}
-// 取消所有
-const handleCancelAll = () => {
- submitCancelTask(props.rowData, 0)
- dialogVisible.value = false
-}
-// 提交取消任务请求
-const submitCancelTask = (row, isSingle) => {
- if (!row.wayline_job_info_id) {
- ElMessage.warning('该任务无法取消,数据未兼容!')
- return
- }
- cancelJobs({
- jobInfoId: row.wayline_job_info_id,
- batchNo: row.batch_no,
- isSingle: isSingle,
- }).then(res => {
- if (res.data.code !== 0) return
- ElMessage.success('取消任务成功')
- emit('refresh')
- })
-}
-const closeClick = () => {
- dialogVisible.value = false
-}
-
-defineExpose({
- submitCancelTask,
-})
-</script>
-<style lang="scss">
-.cancel-task-dialogs {
- margin: 0;
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- padding: 0;
- // width: 398px;
- // height: 181px;
- background: #0f1d33;
- box-shadow: inset 0px -50px 50px 0px rgba(27, 148, 255, 0.13);
- border-radius: 50px 0px 0px 0px;
- border: 2px solid;
- border-image: linear-gradient(
- 180deg,
- rgba(81, 168, 255, 0),
- rgba(48, 111, 202, 1),
- rgba(255, 255, 255, 1),
- rgba(27, 148, 255, 1)
- )
- 2 2;
- .el-dialog__header {
- display: none;
- }
- .dialog-headers {
- width: 100%;
- height: 60px;
- background: url('@/assets/images/task/header.png') center no-repeat;
- background-size: 100% 100%;
- color: #fff;
- font-size: 16px;
- font-weight: bold;
- display: flex;
- align-items: center;
- justify-content: center;
- img {
- position: absolute;
- top: 24px;
- right: 20px;
- cursor: pointer;
- }
- }
-
- .dialog-contents {
- padding: 40px 20px 20px 20px;
- .dialog-text {
- color: #fff;
- font-size: 14px;
- margin-bottom: 60px;
- text-align: center;
- }
-
- .dialog-btns {
- display: flex;
- justify-content: center;
- gap: 46px;
- img {
- width: 96px;
- height: 32px;
- cursor: pointer;
- }
- // .el-button {
- // width: 120px;
- // height: 32px;
- // border-radius: 2px;
-
- // &.el-button--primary {
- // background: #026ad6;
- // border-color: #026ad6;
- // }
- // }
- }
- }
-}
-</style>
diff --git a/applications/drone-command/src/views/job/components/DeviceJobDetails.vue b/applications/drone-command/src/views/job/components/DeviceJobDetails.vue
deleted file mode 100644
index a7cfd66..0000000
--- a/applications/drone-command/src/views/job/components/DeviceJobDetails.vue
+++ /dev/null
@@ -1,806 +0,0 @@
-<!-- 历史任务详情 -->
-<template>
- <el-dialog class="command-dialog" append-to-body modal-class="detailsOfHistoricalTasks" v-model="isShow" title="巡检任务详情"
- :width="pxToRem(1800)" :close-on-click-modal="false" :destroy-on-close="true">
- <div class="content">
- <div class="contentLeft">
- <!-- 执行机巢详情-->
- <execute-nest-details :wayLineJobInfoId="wayLineJobInfoId" :batchNo="batchNo"></execute-nest-details>
- <!-- 详情-->
- <div class="detailsLine">
- <img src="/src/assets/images/task/sign.svg" alt="">
- <div class="title">
- 详情
- </div>
- <div class="btn" v-show="videoData.length > 0">
- <el-button
- class="playback-video-btn"
- v-show="videoData.length == 1"
- type="primary"
- @click="openPlaybackVideoDialog(videoData[0])"
- size="small"
- >
- 回放直播
- </el-button>
-
- <el-popover placement="bottom-start" popper-class="command-custom-popover bottom">
- <template #reference>
- <el-button class="playback-video-btn" v-show="videoData.length > 1" type="primary" size="small">
- 回放直播
- </el-button>
- </template>
-
- <div class="playback-video-list">
- <div v-for="(item, index) in videoData" :key="index">
- {{ formatTimestamp(item.execute_time) }}
-
- <div class="play-btn" @click="openPlaybackVideoDialog(item)">播放</div>
- </div>
- </div>
- </el-popover>
- </div>
- </div>
- <div class="infoBox">
- <div class="itemBoxLeft">
- <div v-for="(item, index) in infoList" :key="index" class="itemCon">
- <div class="itemBox">
- <div class="itemTitle">{{ item.name }}:</div>
- <div truncated class="itemValue" v-if="item.name !== '飞行事件' && item.name !== '任务执行次数'">
- {{ item.value ? item.value : '--' }}
- </div>
- <div class="itemValue" v-if="item.name === '任务执行次数'">{{ item.value ? item.value : '0' }}次</div>
- <!-- 飞行事件 -->
- <div class="flightEvents" v-if="item.name === '飞行事件'">
- <template v-if="flightEvents.length">
- <img
- v-for="(item, index) in flightEvents"
- alt=""
- :src="item.imgUrl"
- :title="item.label"
- :key="index"
- />
- </template>
- <div class="itemValue" v-else>--</div>
- </div>
- </div>
- </div>
- </div>
-
- </div>
- <JobRelatedEvents :jobTimes="jobTimes" :batchNo="batchNo" :waylineJobId="waylineJobId" :detailName="detailName" />
- <div class="devicetitle" v-if="isShow">
- <div>
- <img src="/src/assets/images/task/sign.svg" alt="">
- <p>
- 成果数据
- <span>{{ total }}</span>
- 个
- </p>
- </div>
- <div class="rightBox" v-if="total">
- <div class="downloadBtn" @click="htlsrwxq === 100 && downloadFun()">
- <el-progress v-if="htlsrwxq !== 100" :percentage="htlsrwxq" :show-text="false" striped striped-flow
- :duration="1" />
- <div class="downloadBtnText">
- <span v-if="htlsrwxq === 100">下载</span>
- <template v-else>
- 处理中<el-icon @click="cancelDownload">
- <CircleClose />
- </el-icon>
- </template>
- </div>
- </div>
- <div class="downloadBtn" @click="showAll = !showAll" v-if="total > 5">
- {{ showAll ? '收起' : '更多' }}
- </div>
- </div>
- </div>
-<!-- <div class="imgListBox">-->
-<!-- <!– 图片显示 –>-->
-<!-- <template v-for="(item, index) in achievementList.slice(0, visibleCount)" :key="index">-->
-<!-- <div class="result-item">-->
-<!-- <el-checkbox v-model="item.checked" />-->
-<!-- <div class="itemName">{{ item.createTime }}</div>-->
-<!-- <!– 正射 –>-->
-<!-- <el-image v-if="item.resultType === 4" :src="item.smallUrl" :preview-src-list="[item.showUrl]" fit="cover"-->
-<!-- preview-teleported />-->
-<!-- <!– 全景 –>-->
-<!-- <img v-else-if="item.resultType === 5" class="quanjing" @click="clickpanorama(item)" :src="item?.smallUrl"-->
-<!-- alt="" />-->
-<!-- <!– 视频 –>-->
-<!-- <div v-else-if="item.resultType === 1" class="videotime">-->
-<!-- <img class="videoDisplay" :src="convertVideoUrlToThumbnail(item.link)" alt=""-->
-<!-- @click="enterFullScreen(index)" />-->
-<!-- <img @click="enterFullScreen(index)" class="videobutton" src="@/assets/images/task/videoshow.png"-->
-<!-- alt="" />-->
-<!-- </div>-->
-<!-- <!– 图片 –>-->
-<!-- <el-image v-else :src="item.smallUrl" :preview-src-list="[item.showUrl]" preview-teleported-->
-<!-- :initial-index="index" fit="cover" />-->
-
-
-<!-- </div>-->
-
-<!-- </template>-->
-
-<!-- </div>-->
- <div class="imgListBox">
- <template v-for="(item, index) in achievementList.slice(0, visibleCount)" :key="index">
- <div class="result-item">
- <el-checkbox v-model="item.checked" />
- <div class="itemName">{{ item.createTime }}</div>
- <!-- 正射 -->
- <el-image v-if="item.resultType === 4" :src="item?.smallUrl" fit="cover" preview-teleported @click="clickPlay(index)"/>
- <!-- 全景 -->
- <img
- v-else-if="item.resultType === 5"
- class="quanjing"
- @click="clickPlay(index)"
- :src="item?.smallUrl"
- alt=""
- />
- <!-- 视频 -->
- <div v-else-if="item.resultType === 1" class="videotime">
- <img
- class="videoDisplay"
- :src="convertVideoUrlToThumbnail(item.link)"
- alt=""
- @click="clickPlay(index)"
- />
- <img
- @click="clickPlay(index)"
- class="videobutton"
- src="@/assets/images/signMachineNest/videoshow.png"
- alt=""
- />
- </div>
- <!-- 图片 -->
- <el-image v-else :src="item?.smallUrl" fit="cover" preview-teleported @click="clickPlay(index)"/>
- </div>
- </template>
- </div>
- <el-image-viewer
- v-if="showViewer"
- :url-list="previewUrls"
- :initial-index="activeIndex"
- @close="showViewer = false"
- />
- <div class="cg-empty" v-if="achievementList.length === 0">暂无数据</div>
- </div>
-
- <div class="content-right" v-if="isShow">
- <DeviceJobDetailsMap
- :detailsData="detailsData"
- :yuanImages="yuanImages"
- :taskData="taskData"
- @showImageeclick="showImageeclick"
- :jobId="props.jobId"
- />
- <div class="content-map-popups"></div>
- </div>
- </div>
- </el-dialog>
- <el-dialog class="command-dialog" append-to-body modal-class="detailsOfHistoricalTasks" v-model="VideoShow"
- :width="pxToRem(1600)" :close-on-click-modal="false" :destroy-on-close="true">
- <div class="fullscreen">
- <video ref="fullscreenVideo" class="fullscreen-video" :src="currentVideoUrl"
- :style="{ width: pxToRem(1567), height: '80vh' }" controls preload="auto" @play="handleVideoPlay"
- @ended="handleVideoEnded"></video>
- </div>
- </el-dialog>
- <!-- 全景360 -->
- <PanoramaPopup v-if="'全景'" v-model:panoramaParamsShow="panoramaParamsShow"
- v-model:panoramaParamsUrl="panoramaParamsUrl" />
-
- <PlaybackVideo v-model:show="playbackVideo" v-model:detailData="openVideoDetail" :detailsData="detailsData" />
- <FileTypePlay v-model:show="carouselShow" :list="achievementList" :cIndex="currentIndex"></FileTypePlay>
-</template>
-
-<script setup>
-import PanoramaPopup from '@/components/PanoramaPopup/PanoramaPopup.vue'
-import PlaybackVideo from '@/components/PlaybackVideo/PlaybackVideo.vue'
-import FileTypePlay from '@/views/job/components/FileTypePlay.vue';
-import ExecuteNestDetails from './executeNestDetails.vue'
-import { getWaylinejobLiveRecordPage } from '@/api/playback'
-import { getShowImg, getSmallImg, getzsSmallImg, getzsShowImg, aLinkDownloadUtil } from '@/utils/util'
-import { getaiImagesPageAPI, cancelDownloadApi, getDownloadStatusApi, attachDownload, aiImagesPage } from '@/api/dataCenter/dataCenter'
-import { getFindAction } from '@/views/RoutePlan/PointAirLine/pointWayLineUtils'
-import { pxToRem } from '@/utils/rem'
-import JobRelatedEvents from './JobRelatedEvents.vue'
-import { getEventMediaListApi, getJobDetails, getJobInfoFiles, getJobsAllFiles, NestDetailApi } from '@/api/job/task'
-import DeviceJobDetailsMap from './DeviceJobDetailsMap.vue'
-import { droneEventList } from '../const/drc'
-import { ElMessage, ElLoading } from 'element-plus'
-import { useStore } from 'vuex'
-import EventBus from '@/utils/eventBus'
-const store = useStore()
-const htlsrwxq = computed(() => store.state.common.downloadProgress?.htlsrwxq || 100)
-const isShow = defineModel('show')
-const VideoShow = ref(false)
-const showAll = ref(false) // 是否展示全部
-let loadingData
-const fullscreenVideo = ref(null)
-const playbackVideo = ref(false)
-const carouselShow = ref(false) // 是否轮播
-const currentIndex = ref(-1)
-// 视频播放事件处理
-const handleVideoPlay = (event) => {
- if (event.target.playbackRate !== 0.75) {
- event.target.playbackRate = 0.75
-
- }
-}
-const handleVideoEnded = index => {
- // 获取当前视频
- const video = fullscreenVideo.value
-
- // 重置视频播放时间为 0
- video.currentTime = 0
-
- // 重新加载视频
- video.load()
-}
-// 原图
-const yuanImages = ref([])
-function convertVideoUrlToThumbnail (videoUrl) {
- // 检查是否是有效的视频URL
- if (!videoUrl || typeof videoUrl !== 'string') {
- return videoUrl
- }
- // 替换文件扩展名
- return videoUrl.replace(/\.mp4$/, '_small.jpg')
-}
-const infoList = ref([
- { name: '任务编号', value: '', field: 'job_info_num' },
- { name: '任务名称', value: '', field: 'name' },
- { name: '任务类型', value: '', field: 'rep_rule_type' },
- { name: '飞行事件', value: '', field: 'event_number' },
- { name: '所属机巢', value: '', field: 'device_names' },
- { name: '创建人', value: '', field: 'creator_name' },
- { name: '所属部门', value: '', field: 'dept_name' },
- { name: '任务时间', value: '', field: 'cycle_time_value' },
- { name: '任务频次', value: '', field: 'rep_rule_type' },
- { name: '关联算法', value: '', field: 'ai_type_str' },
- { name: '自定义识别区', value: '', field: 'enable_custom_area' },
- { name: '任务描述', value: '', field: 'remark' },
- // { name: '任务执行次数', value: '', field: 'job_num' },
-])
-// 机巢状态
-const flystatus = ref('')
-const detailsData = ref({
- id: null,
- remark: null,
- is_monitoring: null,
- industry_type_str: null,
- area_code: null,
- ai_type_str: null,
- enable_custom_area: null,
- begin_time: null,
- end_time: null,
- device_names: null,
- create_time: null,
- name: null,
- event_number: null,
- creator_name: null,
- way_lines: [],
-})
-// 任务成果
-const total = ref(0)
-const achievementList = ref([])
-const props = defineProps(['wayLineJobInfoId', 'waylineJobId', 'batchNo', 'jobId'])
-const wayLineJobInfoId = computed(() => props.wayLineJobInfoId)
-const jobId = computed(() => props.jobId)
-provide('wayLineJobInfoId', wayLineJobInfoId)
-provide('jobId', jobId)
-
-// 可见数量
-const visibleCount = computed(() =>
- showAll.value ? achievementList.value.length : Math.min(5, achievementList.value.length)
-)
-
-const jumpMore = () => {
- ElMessage.warning('正在加急开发中...')
-}
-
-const flightEvents = ref([])
-const jobTimes = ref([])
-const historyTime = ref('')
-const jumpDataCenter = ref(null)
-const cycle_time = ref(null)
-const detailName = ref(null)
-
-const getDetails = () => {
- const params = {
- wayLineJobInfoId: props.wayLineJobInfoId,
- // waylineJobId: props.waylineJobId,
- batchNo: props.batchNo
- }
- getJobDetails(params).then(res => {
- detailsData.value = res.data.data
- jobTimes.value = res.data.data.job_times
- jumpDataCenter.value = res.data.data
- cycle_time.value = res.data.data.cycle_time_value
- detailName.value = detailsData.value.name
-
- infoList.value.forEach(item => {
- item.value = detailsData.value?.[item.field] || '--'
- if (item.name === '任务频次') {
- item.value = detailsData?.value.rep_rule_type ? detailsData?.value.final_cycle_frequency : '1次'
- }
- if (item.name === '任务类型') {
- const { rep_rule_type = '' } = detailsData?.value || {}
- item.value = rep_rule_type ? '周期任务' : '临时任务'
- }
- if (item.name === '飞行事件') {
- const { action_modes = [] } = detailsData?.value || {}
- flightEvents.value = action_modes.flatMap(getFindAction)
- }
- if (item.name === '自定义识别区' && infoList?.value[9].value !== '--') {
- item.value = res.data.data.enable_custom_area ? '是' : '否'
- }
- })
- getJobsAllFiles({
- wayLineJobId: detailsData.value.way_lines.map(item => item.job_id).join(','),
- resultTypes: [0, 1, 2, 4, 5,15],
- orderByCreateTime: true,
- }).then(result => {
- if (result.data.code !== 200) return
- achievementList.value = result.data.data.records.map(i => ({
- ...i,
- checked: false,
- smallUrl: i.resultType === 4 ? getzsSmallImg(i.link) : getSmallImg(i.link),
- showUrl: i.resultType === 4 ? getzsShowImg(i.link) : getShowImg(i.link),
- }))
- total.value = result.data.data.total
-
- yuanImages.value = result.data.data.records.filter(item => item.resultType !== 1)
- })
- })
-}
-// 播放
-const videoRef = ref(null)
-const currentVideoIndex = ref(-1)
-
-const enterFullScreen = (index) => {
- currentVideoIndex.value = index
- VideoShow.value = true
-}
-// 计算当前视频URL
-const currentVideoUrl = computed(() => {
- return achievementList.value[currentVideoIndex.value]?.link || ''
-})
-// 关闭弹窗处理
-const handleClose = () => {
- if (fullscreenVideo.value) {
- fullscreenVideo.value.pause()
- fullscreenVideo.value.currentTime = 0
- }
-}
-// 下载
-const downloadFun = async () => {
- const list = achievementList.value.filter(i => i.checked)
- console.log('list', list)
- if (!list?.length) return ElMessage.warning('请选择文件')
- if (list.length === 1) {
- list.forEach((item, index) => {
- const suffix = item.link.split('.').pop()
- aLinkDownloadUtil(item.link, item.nickName + '.' + suffix)
- })
- } else {
- loadingData = ElLoading.service({ background: 'rgba(0, 0, 0, 0.5)', text: '打包中,请稍等...' })
- const fileIds = list.map(i => i.id)
- const res = await getDownloadStatusApi({ type: 'htlsrwxq' })
- if (!['CANCELLED', 'COMPLETED'].includes(res.data.data?.status || 'COMPLETED')) {
- return ElMessage.warning('还有正在处理的')
- }
- attachDownload({ attachIds: fileIds, type: 'htlsrwxq' }).finally(() => {
- loadingData.close()
- })
- }
-}
-// 全景预览
-const panoramaParamsShow = ref(false)
-const panoramaParamsUrl = ref(null)
-const clickpanorama = val => {
- panoramaParamsShow.value = true
- panoramaParamsUrl.value = val.link
-}
-// 从地图点击图片预览
-const showViewer = ref(false)
-const activeIndex = ref(0)
-const previewUrls = ref([])
-const showImageeclick = (list, index, categoriestype) => {
- if (categoriestype === 5) {
- panoramaParamsShow.value = true
- panoramaParamsUrl.value = list[0]
- } else {
- previewUrls.value = list
- activeIndex.value = 0
- showViewer.value = true
- }
-}
-// 取消下载
-function cancelDownload () {
- cancelDownloadApi({ type: 'htlsrwxq' }).then(res => {
- ElMessage.success('取消成功')
- }).catch(e => {
- EventBus.emit('useGlobalWS-messageHandler', { biz_code: 'DOWNLOAD_PROGRESS', data: { status: 'CANCELLED', type: 'htlsrwxq' } })
- })
-}
-
-// 执行机巢详情
-const taskData = ref([])
-const getNestDetailApi = () => {
- const params = {
- jobInfoId: props.wayLineJobInfoId,
- batchNo: props.batchNo,
- }
- NestDetailApi(params).then(res => {
- taskData.value = res.data.data
- })
-}
-
-// 获取回放直播列表
-const videoData = ref([])
-const openVideoDetail = ref({})
-const getVideoList = () => {
- getWaylinejobLiveRecordPage({ job_info_id: props.wayLineJobInfoId }).then(videoDetails => {
- videoData.value = videoDetails.data.data.records
- })
-}
-
-const openPlaybackVideoDialog = data => {
- playbackVideo.value = true
- openVideoDetail.value = data
-}
-
-
-
-function clickPlay(index) {
- carouselShow.value = true
- currentIndex.value = index
-}
-
-onMounted(() => {
- getDetails()
- getNestDetailApi()
- getVideoList()
-})
-</script>
-
-<style lang="scss">
-.detailsOfHistoricalTasks {
- .el-dialog {
- --el-dialog-margin-top: 5vh;
- }
-
- .el-pagination {
- justify-content: center;
- padding: 20px;
- }
-
- .el-dialog__body {
- height: 80vh;
- }
-}
-</style>
-
-<style lang="scss" scoped>
-.content {
- display: flex;
- height: 100%;
-
- .contentLeft {
- margin-left: 35px;
- margin-right: 24px;
- width: 1150px;
- overflow: auto;
-
- .detailsLine {
- display: flex;
- align-items: center;
- border-bottom: 2px solid #e4e7ed;
- padding-bottom: 4px;
- img {
- width: 15px;
- height: 15px;
- }
- .title {
- margin-left: 10px;
- font-size: 16px;
- color: #303133;
- }
- .btn {
- margin-left: 16px;
- }
- }
-
- .devicetitle {
- margin-bottom: 16px;
- // background: url('/src/assets/images/task/detailtitle.png') no-repeat center;
- border-bottom: 2px solid #e4e7ed;
- background-size: 100% 100%;
- display: flex;
- justify-content: space-between;
- align-content: center;
-
- .rightBox {
- display: flex;
- align-items: center;
- padding-right: 10px;
- gap: 0 10px;
-
- .downloadBtn {
- position: relative;
- display: flex;
- align-items: center;
- justify-content: center;
- height: 28px;
- padding: 0 15px;
- background: rgba(28, 92, 255, 0.14);
- border-radius: 4px 4px 4px 4px;
- border: 1px solid #1c5cff;
- cursor: pointer;
- color: #1C5CFF;
-
- .downloadBtnText {
- display: flex;
- align-items: center;
- gap: 5px;
- z-index: 5;
- }
-
- .el-progress {
- position: absolute;
- left: 0;
- top: 0;
- width: 100%;
-
- :deep() {
- .el-progress-bar__outer {
- height: 28px !important;
- border-radius: 0 !important;
- background: transparent !important;
-
- .el-progress-bar__inner {
- border-radius: 0 !important;
- }
- }
- }
- }
-
- }
- }
-
- img {
- width: 15px;
- height: 15px;
- }
-
- p {
- display: inline-block;
- margin-left: 10px;
- font-size: 16px;
- color: #363636;
- line-height: 20px;
- text-align: left;
- margin-bottom: 8px;
-
- span {
- font-size: 26px;
- color: #0282ff;
- font-weight: bold;
- }
- }
-
- .more {
- color: #2f9dff;
- font-size: 14px;
- padding-top: 5px;
- cursor: pointer;
- }
- }
-
- .infoBox {
- display: flex;
- justify-content: space-between;
-
- .itemBoxLeft {
- flex: 1;
- display: grid;
- grid-template-columns: repeat(2, 1fr);
- column-gap: 10px;
- /* 只设置列间距 */
- row-gap: 0;
- /* 取消行间距 */
- padding: 10px;
- font-size: 14px;
-
- .itemBox {
- display: flex;
- align-items: center;
- background: #fff;
- height: 43px;
- border-top: 2px solid #EFEFEF;
-
- }
-
- }
-
- .itemCon:nth-last-child(-n+2) {
- border-bottom: 2px solid #EFEFEF;
- }
-
- .itemBox:nth-last-child(-n+2) .itemTitle {
- border-bottom: 1px solid #EFEFEF;
- }
-
- .itemTitle {
- color: #0B1D38;
- width: 26%;
- text-align: right;
- background: #F3F6FF;
- height: 43px;
- line-height: 43px;
- padding-right: 10px;
- border-top: 1px solid #EFEFEF;
- }
-
- .itemValue {
- font-size: 14px;
- color: #747e91;
- text-align: center;
- width: 74%;
-
- }
-
- .flightEvents {
- display: flex;
- flex-wrap: wrap;
- gap: 10px 10px;
- width: 74%;
- justify-content: center;
-
- img {
- width: 30px;
- height: 30px;
- }
- }
-
- }
-
- .imgListBox {
- display: grid;
- grid-template-columns: repeat(5, 1fr);
- gap: 10px;
- margin-bottom: 49px;
-
- >* {
- width: 100%;
- height: 200px;
- position: relative;
- border-radius: 0px 0px 4px 4px;
- overflow: hidden;
- }
-
- :deep(.el-checkbox__inner) {
- width: 17px !important;
- height: 17px !important;
- background: rgba(37, 36, 36, 0.63) !important;
- border-radius: 4px 4px 4px 4px;
- border: 1px solid #ffffff !important;
- }
-
- .el-checkbox {
- position: absolute;
- top: 0;
- left: 6px;
- }
-
- :deep(.el-checkbox__inner:after) {
- position: absolute;
- left: 50% !important;
- top: 40% !important;
- transform: translate(-50%, -50%) rotate(45deg) !important;
- }
-
- :deep(.el-checkbox.is-checked .el-checkbox__inner) {
- background-color: #09297b !important;
- border-color: #1c5cff !important;
- }
-
- .el-image {
- width: 100%;
- height: 100%;
- cursor: pointer;
- position: relative;
- }
-
- .quanjing {
- width: 100%;
- height: 100%;
- object-fit: cover;
- cursor: pointer;
- position: relative;
- }
-
- .videotime {
- width: 100%;
- height: 100%;
- position: relative;
-
- .videoDisplay {
- width: 100%;
- height: 100%;
- object-fit: cover;
- }
- }
-
- .itemName {
- position: absolute;
- bottom: 0;
- left: 0;
- height: 23px;
- width: 100%;
- background: rgba(22, 22, 22, 0.68);
- border-radius: 0px 0px 4px 4px;
- font-family: Source Han Sans CN, Source Han Sans CN;
- font-weight: 400;
- font-size: 14px;
- color: #ffffff;
- line-height: 23px;
- z-index: 9;
- padding: 0 6px;
- }
- }
-
- .videobutton {
- position: absolute;
- top: 40%;
- left: 50%;
- transform: translate(-50%);
- cursor: pointer;
- width: 40px;
- height: 40px;
- display: inline-block;
- background: #999;
- border-radius: 50%;
- }
-
- .videoDisplay {
- display: flex;
- flex-wrap: wrap;
- width: 200px;
- height: 200px;
-
- }
-
- .videotime {
- position: relative;
- }
-
- .cg-empty {
- text-align: center;
- color: #909399;
- }
-
- }
-
- .content-right {
- position: relative;
- width: 0;
- flex-grow: 1;
- background: #19ad8d;
- margin-right: 17px;
- overflow: hidden;
-
- .content-map-popups {
- pointer-events: none;
-
- >* {
- pointer-events: auto !important;
- }
- }
- }
-}
-</style>
diff --git a/applications/drone-command/src/views/job/components/DeviceJobDetailsMap.vue b/applications/drone-command/src/views/job/components/DeviceJobDetailsMap.vue
deleted file mode 100644
index c22b3c9..0000000
--- a/applications/drone-command/src/views/job/components/DeviceJobDetailsMap.vue
+++ /dev/null
@@ -1,353 +0,0 @@
-<template>
- <div id="deviceJobDetailsMap" class="command-cesium"></div>
-</template>
-<script setup>
-import { flyVisual } from '@ztzf/utils'
-import _ from 'lodash'
-
-import * as Cesium from 'cesium'
-import { PublicCesium } from '@/utils/cesium/publicCesium'
-import photoDirection from '@/assets/images/historyMapPopup/photoDirection-new.png'
-import { getEventImage } from '@/utils/stateToImageMap/event'
-import panoramaPoint from '@/assets/images/panorama/panorama-point.png' //全景图标
-import { getShowImg } from '@/utils/util'
-import { getPanoramaList } from '@/api/panorama'
-import CreateRouteLine from '@/utils/cesium/createRouteLine'
-import { useStore } from 'vuex'
-import { getOdmToken } from '@/api/model'
-
-const createRouteLineExample = new CreateRouteLine()
-const store = useStore()
-const emit = defineEmits(['showImageeclick'])
-const props = defineProps(['detailsData', 'yuanImages', 'jobId','taskData'])
-const userAreaCode = computed(() => store.state.user.userInfo.detail.areaCode)
-let viewer = null
-let publicCesiumInstance = null
-const viewInstance = shallowRef(null)
-import { cloneDeep } from 'lodash'
-import { useIdentificationArea } from '@ztzf/hooks'
-let handler = null
-let curMoveEntity = null
-const tokenStr = ref('')
-let tipsLabel = null
-
-const initMap = () => {
- publicCesiumInstance = new PublicCesium({
- dom: 'deviceJobDetailsMap',
- terrain: true,
- flatMode: false,
- layerMode: 4,
- })
-
- viewer = publicCesiumInstance.getViewer()
- viewInstance.value = publicCesiumInstance
- viewer.scene.globe.depthTestAgainstTerrain = true
-
- createRouteLineExample.initCreateRoute(viewer)
-
- handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
- handler.setInputAction(click => {
- const pickedObjects = viewer.scene.drillPick(click.position)
- LeftClickEvent(click, pickedObjects, viewer)
- }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
-
- handler.setInputAction(e => {
- let pick = viewer.scene.drillPick(e.endPosition)
- mouseMoveEvent(e, pick, viewer)
- }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
-}
-
-function mouseMoveEvent(click, pick, viewer) {
- let startEntity = pick?.find(
- i => i.id.name === 'work-drone-route-planar-polyline' || i.id.name === 'work-drone-route-point-polyline'
- )?.id
- const position = viewer.scene.pickPosition(click.endPosition)
- const device_sn = startEntity?.customData?.data?.device_sn
- const lineBoxShow = createRouteLineExample.detailsMapPopupData?.find(i => i.device_sn === device_sn)?.show
- if (startEntity && !lineBoxShow) {
- if (!tipsLabel){
- tipsLabel = viewer.entities.add({
- position: position,
- label: {
- text: `点击显示详情`,
- font: '14px sans-serif',
- showBackground: true,
- backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.8),
- pixelOffset: new Cesium.Cartesian2(0, -20),
- eyeOffset: new Cesium.Cartesian3(0, 0, -10), // 使标签在点的上方
- disableDepthTestDistance: Number.POSITIVE_INFINITY, // 避免被遮挡
- }
- })
- return
- }
- tipsLabel.position = position
- }else{
- tipsLabel && viewer.entities.remove(tipsLabel)
- tipsLabel = null
- }
-}
-
-// 绘制线和飞行
-const drawLine = async () => {
- Promise.all(
- props.detailsData.way_lines.map(
- async item =>
- await createRouteLineExample.parsingFiles(
- {
- ...item,
- url: `${item.url}?_t=${new Date().getTime()}`,
- status: props.taskData.length > 1 ? props.taskData.filter(i => i.dock_sn === item.device_sn)[0].status : ''
- },
- {
- longitude: item.longitude,
- latitude: item.latitude,
- height: item.height,
- },
- true,
- false
- )
- )
- ).then(res => {
- createRouteLineExample.showDetailMapPopup(props.detailsData.way_lines)
-
- let arr = res.map(i => i.filePositions)
-
- let newArr = _.flatten(arr)
-
- flyVisual({
- positionsData: newArr.map(i => [i.lng, i.lat, i.alt]),
- viewer,
- pitch: -60,
- })
- })
-}
-
-const lastSelectedId = ref(null)
-// 鼠标左键点击事件
-const LeftClickEvent = (click, pick, viewer) => {
- // pick是一个数组
- if (pick && pick.length > 0) {
- let startEntity = pick.find(
- i => i.id.name === 'work-drone-route-planar-polyline' || i.id.name === 'work-drone-route-point-polyline'
- )?.id
-
- if (startEntity) {
- createRouteLineExample.showSingleDetailMapPopup(startEntity?.customData?.data)
- tipsLabel && viewer.entities.remove(tipsLabel)
- tipsLabel = null
- return
- }
- let imagePath = []
- let categories = ''
- let panoramic = ''
- pick.forEach(item => {
- const index = item.id.index
- if (item.id.customType == 'spotImages') {
- imagePath.push(item.id.customInfo.link)
- } else if (item.id.customType == 'aggregationSplashed') {
- imagePath.push(item.id.customInfo.link)
- } else if (item.id.customType == 'panorama') {
- //全景
- imagePath.push(item.id.customInfo.link)
- categories = item.id.customInfo.resultType
- }
- })
- if (imagePath.length === 0) return
- const finalImagePaths = categories === 5 ? imagePath : imagePath.map(i => getShowImg(i))
- emit('showImageeclick', finalImagePaths, 0, categories)
- }
-}
-
-const removeMap = () => {
- viewer.entities.removeAll()
- publicCesiumInstance?.viewerDestroy()
- publicCesiumInstance = null
- viewer = null
-}
-const {setArea,removeArea } = useIdentificationArea()
-watch(
- () => props.detailsData,
- async (newValue, oldValue) => {
- if (newValue) {
- await drawLine()
- }
- if (newValue?.ai_types && newValue.enable_custom_area){
- setArea(newValue.ai_types.split(','),viewer)
- }
- }
-)
-const zsList = ref([])
-// 获取odmtoken
-function getOdmTokenStr() {
- getOdmToken().then(res => {
- if (res.data.code !== 200) return
- tokenStr.value = res.data.data
- })
-}
-// 获取正射列表
-function getZSList(newVal) {
- let list = []
- newVal.map((item, index) => {
- item.childrens.map(zschilditem => {
- if (zschilditem?.data) {
- zschilditem?.data.map(dataitem => {
- list.push(dataitem)
- })
- }
- })
- })
- return list
-}
-// 获取正射请求地图聚合数据
-const zsMapList = ref([])
-function getZSMapList(valSn) {
- const params = {
- areaCode: userAreaCode.value,
- deviceSn: valSn,
- resultType: 4,
- wayLineJobId: props.jobId,
- }
- getPanoramaList(params).then(res => {
- const resData = res?.data?.data
- zsMapList.value = resData?.childrens || []
- zsList.value = getZSList(zsMapList.value)
-
- renderOrthophoto()
- })
-}
-
-// 渲染正射
-function renderOrthophoto() {
- zsList.value.forEach((item, index) => {
- const cur = viewInstance.value.addCustomImageryProviderDataSource(
- new Cesium.UrlTemplateImageryProvider({
- url: `${import.meta.env.VITE_APP_AREA_NAME}/webodm${item.url}?jwt=${tokenStr.value.split(' ')[1]}`,
- })
- )
- })
-}
-
-watch(
- () => props.yuanImages,
- (newValue, oldValue) => {
- // 增加箭头
- if (newValue.length === 0) return
- let eventArr = newValue.filter(i => i.resultType === 2)
- let originalArr = newValue.filter(i => i.resultType === 0)
- let panoramicArr = newValue.filter(i => i.resultType === 5)
- let orthographicArr = newValue.filter(i => i.resultType === 4)
- if (orthographicArr) {
- getZSMapList(orthographicArr[0]?.deviceSn)
- }
- originalArr.forEach((item_in, index) => {
- // 根据偏航角度展示图片拍摄的方向
- let yawAngleDegrees =
- item_in.metadata.gimbalYawDegree < 0
- ? 360 + Number(item_in.metadata.gimbalYawDegree)
- : Number(item_in.metadata.gimbalYawDegree)
-
- viewer.entities.add({
- position: Cesium.Cartesian3.fromDegrees(
- +item_in.metadata.shootPosition.lng,
- +item_in.metadata.shootPosition.lat,
- +item_in.metadata.absoluteAltitude
- ),
- id: 'spotImages' + item_in.id,
- customType: 'spotImages',
- customInfo: {
- ...item_in,
- },
- index: index,
- billboard: {
- image: photoDirection,
- outlineWidth: 0,
- width: 14,
- height: 21,
- disableDepthTestDistance: Number.POSITIVE_INFINITY,
- verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
- },
- })
- })
-
- eventArr.forEach((item, index) => {
- viewer.entities.add({
- id: `aggregationSplashed${item.id}`,
- customType: 'aggregationSplashed',
- customInfo: {
- ...item,
- },
- position: Cesium.Cartesian3.fromDegrees(
- +item.metadata.shootPosition.lng,
- +item.metadata.shootPosition.lat,
- +item.metadata.absoluteAltitude
- ),
- billboard: {
- image: getEventImage(item.status),
- width: 30,
- height: 30,
- disableDepthTestDistance: Number.POSITIVE_INFINITY,
- },
- index: index,
- properties: {
- customData: {
- data: item,
- },
- },
- })
- })
- // 全景
- panoramicArr.forEach((item, index) => {
- viewer.entities.add({
- id: `panorama${item.id}`,
- customType: 'panorama',
- customInfo: {
- ...item,
- },
- position: Cesium.Cartesian3.fromDegrees(
- +item.metadata.shootPosition.lng,
- +item.metadata.shootPosition.lat,
- +item.metadata.absoluteAltitude
- ),
- billboard: {
- image: panoramaPoint,
- width: 30,
- height: 30,
- disableDepthTestDistance: Number.POSITIVE_INFINITY,
- },
- index: index,
- properties: {
- customData: {
- data: item,
- },
- },
- })
- })
- },
- { immediate: true, deep: true }
-)
-
-onBeforeUnmount(() => {
- // 移除事件监听
- handler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
- handler?.destroy()
- handler = null
-
- createRouteLineExample.destroyedCustomDom()
-
- removeMap()
-})
-
-onMounted(() => {
- getOdmTokenStr()
- nextTick(() => {
- initMap()
- })
-
-})
-</script>
-<style scoped lang="scss">
-#deviceJobDetailsMap {
- position: relative;
- height: 100%;
-}
-</style>
diff --git a/applications/drone-command/src/views/job/components/FileTypePlay.vue b/applications/drone-command/src/views/job/components/FileTypePlay.vue
deleted file mode 100644
index 517ac37..0000000
--- a/applications/drone-command/src/views/job/components/FileTypePlay.vue
+++ /dev/null
@@ -1,158 +0,0 @@
-<template>
- <!-- <div class="file-type-play">-->
- <el-image-viewer
- v-if="isShow"
- ref="preview"
- :url-list="playList"
- :initial-index="currentActiveIndex"
- @close="closeImageViewer"
- @switch="onViewerSwitch"
- teleported>
- </el-image-viewer>
-</template>
-
-<script setup>
-import { getShowImg } from '@/utils/util'
-
-const currentActiveIndex = ref(0)
-
-const isShow = defineModel('show', {
- type: Boolean,
- default: true,
-})
-
-const props = defineProps(['list','cIndex'])
-
-const playList = ref([])
-
-function getQJUrl(url) {
- return `https://wrj.shuixiongit.com/dronePanorama/html/simple-index.html?path=${getShowImg(url)}`
-}
-
-function closeImageViewer() {
- isShow.value = false
-}
-
-function onViewerSwitch (index) {
- currentActiveIndex.value = index
- videoImageSwitch()
-}
-
-const videoImageSwitch = () => {
- nextTick(() => {
- const viewerCanvas = document.querySelector('.el-image-viewer__canvas');
- const viewerActions = document.querySelector('.el-image-viewer__actions');
- const parentDOM = document.querySelector('.el-image-viewer__wrapper');
-
- // const maskLayer = document.querySelector('.el-image-viewer__mask'); // 获取遮罩层
-
- // 清理之前可能存在的视频或全景图元素
- const existingVideo = parentDOM?.querySelector('.preview-video');
- const existingIframe = parentDOM?.querySelector('.preview-panorama');
-
- if (existingVideo) existingVideo.remove();
- if (existingIframe) existingIframe.remove();
-
- const item = props.list[currentActiveIndex.value];
-
- if (item?.resultType === 1) {
- // ========== 处理视频 ==========
- // 隐藏图片查看器的UI
- if (viewerActions) viewerActions.style.display = 'none';
- if (viewerCanvas) viewerCanvas.style.display = 'none';
-
- // 创建并添加视频元素
- const videoDom = document.createElement('video');
- videoDom.className = 'preview-video';
- // videoDom.autoplay = true;
- videoDom.muted = true;
- videoDom.playsInline = true;
- videoDom.loop = true;
- videoDom.controls = true;
- videoDom.preload = 'auto';
- videoDom.src = item.object_key || item.showUrl;
-
- videoDom.style.position = 'relative';
- // 添加视频样式
- videoDom.style.width = '100%';
- videoDom.style.height = '100%';
- videoDom.style.objectFit = 'contain';
-
- // 添加事件监听器
- videoDom.addEventListener('play', (event) => {
- // 设置播放速度为 0.75
- if (event.target.playbackRate !== 0.75) {
- event.target.playbackRate = 0.75;
- }
- });
-
- videoDom.addEventListener('ended', () => {
- // 重置视频播放时间为 0 并重新加载
- videoDom.currentTime = 0;
- videoDom.load();
- });
-
- if (parentDOM) {
- parentDOM.appendChild(videoDom);
- }
- } else if (item?.resultType === 5) {
- // ========== 处理全景图 ==========
- // 隐藏图片查看器的UI(如果全景图不需要查看器UI)
- // if (maskLayer) maskLayer.style.display = 'none';
- if (viewerActions) viewerActions.style.display = 'none';
- if (viewerCanvas) viewerCanvas.style.display = 'none';
-
- // 创建并添加iframe元素
- const iframeDom = document.createElement('iframe');
- iframeDom.className = 'preview-panorama';
- iframeDom.src = getQJUrl(item?.link); // 使用你的全景图URL生成函数
- iframeDom.frameBorder = '0'; // 注意:frameBorder 是 camelCase
- iframeDom.allow = 'fullscreen'; // 允许全屏,如果需要
- iframeDom.title = '全景图浏览';
-
- // 添加iframe样式
- // iframeDom.style.zIndex = '2000'; // 比遮罩层的 2000 高
- iframeDom.style.position = 'relative';
- iframeDom.style.width = '100%';
- iframeDom.style.height = '100%';
- iframeDom.style.border = 'none';
-
- // 如果需要,可以设置iframe的加载策略
- iframeDom.loading = 'eager';
-
- if (parentDOM) {
- parentDOM.appendChild(iframeDom);
- }
- } else {
- // ========== 处理图片(或其他类型) ==========
- // 显示图片查看器的UI
- if (viewerCanvas) viewerCanvas.style.display = 'flex';
- if (viewerActions) viewerActions.style.display = 'flex';
- }
- });
-};
-
-watch(isShow, async newVal => {
- if (newVal) {
- playList.value = props.list.map((item) => item.showUrl)
- currentActiveIndex.value = props.cIndex
- videoImageSwitch()
-
- }
-})
-</script>
-<style lang="scss">
-.el-image-viewer__wrapper {
- .el-image-viewer__canvas {
- img {
- height: 90%;
- top: 5%;
- }
- }
-
- .preview-video {
- max-height: 96%;
- }
-}
-
-</style>
\ No newline at end of file
diff --git a/applications/drone-command/src/views/job/components/JobRelatedEvents.vue b/applications/drone-command/src/views/job/components/JobRelatedEvents.vue
deleted file mode 100644
index 7296230..0000000
--- a/applications/drone-command/src/views/job/components/JobRelatedEvents.vue
+++ /dev/null
@@ -1,392 +0,0 @@
-<template>
- <div class="JobRelatedEvents">
- <div class="machineTableDetailsTitle">
- <img src="/src/assets/images/task/sign.svg" alt="">
- <div class="title">
- 关联事件<span>{{ total }}</span>件
- </div>
- <div class="exportBtn" v-if="total > 0 ">
- <el-button
- :loading="isShowExportTextLoading"
- :disabled="isShowExportTextLoading"
- class="playback-video-btn" type="primary" @click="exportTheTask" size="small">
- {{ isShowExportTextLoading ? '导出中' : '导出报告' }}
- </el-button>
- </div>
- </div>
- <div class="search">
- <div class="searchBox">
- <div class="item">
- <div class="itemchild">模糊查询:</div>
- <el-input v-model="params.event_name" placeholder="请输入事件名称" clearable></el-input>
- </div>
- <!-- <div class="item">
- <div class="itemchild">任务执行日期:</div>
- <el-date-picker
- popper-class="custom-date-picker"
- class="tasktimer"
- v-model="taskData"
- type="date"
- placeholder="请选择日期"
- value-format="YYYY-MM-DD"
- :disabled-date="disabledDate"
- @change="changeselect"
- />
- </div> -->
- <div class="item">
- <div class="itemchild">关联算法:</div>
- <TaskAlgorithmBusiness ref="algorithmRef" :setWidth="186" :showAlgorithm="true" @algorithmChange="algorithmChange" />
- </div>
- </div>
- <div class="search-btn">
- <el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>
- <el-button icon="el-icon-refresh" @click="handleReset">重置</el-button>
- </div>
- </div>
-
- <div class="command-table">
- <el-table
- v-loading="loading"
- :row-class-name="tableRowClassName"
- :data="list"
- style="width: 100%"
- :row-style="{ height: pxToRem(48), fontSize: pxToRem(14), 'text-align': 'center' }"
- :header-cell-style="{ 'text-align': 'center', height: pxToRem(36), fontSize: pxToRem(14) }"
- >
- <el-table-column label="序号" type="index" :width="pxToRemNum(60)">
- <template #default="{ $index }">
- {{ ($index + 1 + (sizeParams.current - 1) * sizeParams.size).toString().padStart(2, '0') }}
- </template>
- </el-table-column>
- <el-table-column show-overflow-tooltip prop="event_num" label="事件编号" :width="pxToRemNum(160)">
- <template #default="scope">
- <el-tooltip-copy :content="scope.row.event_num" :showCopyText="true">
- {{ scope.row.event_num }}
- </el-tooltip-copy>
- </template>
- </el-table-column>
- <el-table-column show-overflow-tooltip prop="event_name" label="事件名称" align="center"/>
- <el-table-column show-overflow-tooltip prop="remark" label="事件地址" align="center"/>
- <el-table-column show-overflow-tooltip prop="ai_types" label="关联算法" align="center"/>
- <el-table-column show-overflow-tooltip prop="work_type" label="事件来源" align="center">
- <template #default="scope">
- {{scope.row.work_type === '0' ? '巡检任务' :
- scope.row.work_type === '1' ? '人工上报' :
- scope.row.work_type === '2' ? '识别分析' : '' }}
- </template>
- </el-table-column>
- <el-table-column show-overflow-tooltip prop="create_time" label="事件时间" align="center"/>
- <el-table-column prop="status" label="事件状态" align="center">
- <template #default="scope">
- <div class="pending" v-if="scope.row.status === 0">待处理</div>
- <div class="reviewed" v-if="scope.row.status === 2">待审核</div>
- <div class="processing" v-if="scope.row.status === 3">处理中</div>
- <div class="done" v-if="scope.row.status === 4">已完成</div>
- <div class="ended" v-if="scope.row.status === 5">已完结</div>
- </template>
- </el-table-column>
- <el-table-column label="操作" :width="pxToRemNum(150)">
- <template #default="scope">
- <div class="btnGroups">
- <el-popover
- v-if="scope.row.status === 3 || scope.row.status === 0"
- popper-class="command-custom-qrcode-popover"
- :width="pxToRem(119)"
- :visible="scope.row.showQR"
- placement="top"
- title=""
- trigger="click"
- >
- <template #reference>
- <el-button type="text" @click="QRCode(scope.row)">事件导航</el-button>
- </template>
- <div class="qrcode-content">
- <div class="close-btn" @click.stop="scope.row.showQR = false">×</div>
- <CreateQRcode v-if="scope.row.showQR" :latAndLon="latAndLon"></CreateQRcode>
- </div>
- </el-popover>
- <el-button icon="el-icon-view" type="text" @click="examine(scope.row)">查看</el-button>
- </div>
- </template>
- </el-table-column>
- </el-table>
- </div>
- <el-pagination v-if="list.length > 0"
- class="command-pagination"
- popper-class="custom-pagination-dropdown"
- background
- :page-sizes="[10, 20, 30, 50]"
- v-model:current-page="sizeParams.current"
- v-model:page-size="sizeParams.size"
- layout=" prev, pager, next,sizes, jumper"
- :total="total"
- @change="pageChange"
- />
- </div>
-</template>
-<script setup>
-import { useStore } from 'vuex'
-import { wgs84ToGcj02 } from '@/utils/coordinateTransformation'
-import CreateQRcode from '@/components/CreateQRcode/CreateQRcode.vue'
-import { getDeviceEventList } from '@/api/job/task'
-import { dayjs, ElMessage } from 'element-plus'
-import { useRouter } from 'vue-router';
-import { NestDetailApi, exportTaskReports } from '@/api/home'
-import { pxToRem, pxToRemNum } from '@/utils/rem'
-import TaskAlgorithmBusiness from './TaskAlgorithmBusiness.vue'
-const router = useRouter();
-const emit = defineEmits(['refresh'])
-const props = defineProps(['jobTimes', 'batchNo', 'waylineJobId','detailName'])
-const taskData = ref('')
-const algorithmRef = ref()
-
-const algorithmChange = val => {
- params.value.ai_types = val
- handleSearch()
-}
-const loading = ref(true)
-const list = ref()
-const params = ref({
- way_line_job_info_id: null,
- event_name: '',
- ai_types: [], // 算法类型
- start_date: null,
- end_date: null,
-})
-const sizeParams = ref({
- current: 1,
- size: 5,
-})
-// 日期选择
-const changeselect = () => {
- params.value.start_date = taskData.value.length ? `${taskData.value} 00:00:00` : null
- params.value.end_date = taskData.value.length ? `${taskData.value} 23:59:59` : null
-}
-const store = useStore()
-const child_sn = computed(() => store.state.home.singleUavHome.child_sn)
-const total = ref(0)
-const examine = row => {
- const orderNumber = row.event_num
- router.push({
- path: `/tickets/ticket`,
- query: {
- orderNumber,
- },
- });
-}
-const wayLineJobInfoId = inject('wayLineJobInfoId')
-
-const getList = () => {
- if (!wayLineJobInfoId.value) return
- params.value.way_line_job_info_id = wayLineJobInfoId.value
- params.value.batch_no = props.batchNo
- loading.value = true
- getDeviceEventList(
- {
- ...params.value,
- }, sizeParams.value
- ).then(res => {
- const resData = res?.data?.data || {}
- list.value = resData.records.map(item => ({
- ...item,
- showQR: false, // 为每条数据添加showQR状态
- }))
- total.value = resData.total
- loading.value = false
- // store.commit('setJobEventList', list.value)
- })
-}
-
-const pageChange = val => {
- sizeParams.value.current = val
- getList()
-}
-// 表格隔行变色
-const tableRowClassName = ({ row, rowIndex }) => {
- if (rowIndex % 2 === 1) {
- return 'warning-row'
- } else {
- return 'success-row'
- }
-}
-// 禁用当天之前的日期
-const disabledDate = time => {
- const curTime = dayjs(time).format('YYYY-MM-DD')
- // console.log(curTime)
- return !(props.jobTimes || []).includes(curTime)
-}
-const handleReset = () => {
- params.value.ai_types = []
- params.value.event_name = ''
- params.value.end_date = null
- params.value.start_date = null
- taskData.value = ''
- algorithmRef.value?.handleClear()
- algorithmChange([])
- getList()
-}
-const handleSearch = () => {
- getList()
-}
-// 二维码
-const latAndLon = ref(null)
-const QRCode = item => {
- const [gcjLng, gcjLat] = wgs84ToGcj02(Number(item.longitude), Number(item.latitude))
- latAndLon.value = `${gcjLng},${gcjLat}`
- list.value.forEach(i => {
- i.showQR = i.id === item.id ? !i.showQR : false
- })
-}
-// 导出任务报表
-const isShowExportTextLoading = ref(false)
-const exportTheTask = () => {
- isShowExportTextLoading.value = true
- const params = {
- wayLineJobInfoId: wayLineJobInfoId.value,
- waylineJobId: props.waylineJobId,
- batchNo: props.batchNo,
- }
- exportTaskReports(params).then(res => {
- const elink = document.createElement('a')
- elink.download = props.detailName + '.docx'
- elink.style.display = 'none'
- const blob = new Blob([res.data])
- elink.href = URL.createObjectURL(blob)
- document.body.appendChild(elink)
- elink.click()
- document.body.removeChild(elink)
- isShowExportTextLoading.value = false
- })
-}
-onMounted(() => {
- getList()
-})
-</script>
-<style scoped lang="scss">
-.JobRelatedEvents {
- .machineTableDetailsTitle {
- display: flex;
- border-bottom: 2px solid #e4e7ed;
- margin-bottom: 16px;
- align-content: center;
- .exportBtn {
- margin-left: 16px;
- }
- img {
- width: 15px;
- height: 15px;
- }
- .title {
- margin-left: 10px;
- font-size: 16px;
- color: #363636;
-
- span {
- font-size: 26px;
- color: #0282ff;
- font-weight: bold;
- margin: 0 4px
- }
- }
- }
-
-// 待处理
-.pending {
- color: #ff7411;
-}
-// 待审核
-.reviewed {
- color: #ff472f;
-}
-// 处理中
-.processing {
- color: #FFC300;
-}
-// 已完成
-.done {
- color: #06d957;
-}
-// 已完结
-.ended {
- color: #06d957;
-}
-.search {
- display: flex;
- justify-content: space-between;
- margin-bottom: 19px; // 添加底部间距
- .item {
- position: relative;
- display: flex;
- align-items: center;
- font-size: 14px;
- color: #363636;
- margin-right: 20px;
- .itemchild {
- white-space: nowrap;
- margin-right: 5px;
- }
- :deep(.el-date-editor.el-input__wrapper) {
- width: 200px; // 调整日期选择器宽度
- }
- }
- .item:nth-last-child {
- margin-right: 113px;
- }
-}
-.searchBox {
- display: flex;
-}
-
-.search-btn {
- display: flex;
- justify-content: space-between;
- font-size: 14px;
-
- .btn {
- width: 80px;
- height: 32px;
- border-radius: 4px 4px 4px 4px;
- line-height: 32px;
- display: flex;
- justify-content: center;
- align-items: center;
-
- img {
- width: 14px;
- height: 14px;
- }
- }
- .search {
- background: #409EFF;
- color: #fff;
- margin-right: 10px;
- cursor: pointer;
- }
- .clear {
- border: 1px solid #D2D1D1;
- color: #676767;
- margin-right: 10px;
- cursor: pointer;
- }
- .add {
- background: #FF9243;
- color: #fff;
- }
- }
- .btnItem {
- height: 27px;
- line-height: 27px;
- border-radius: 0px 0px 0px 0px;
- border: 1px solid #51a8ff;
- font-family: Segoe UI, Segoe UI;
- font-weight: 400;
- font-size: 14px;
- color: #1C5CFF;
- padding: 0 10px;
- display: inline-block;
- margin-right: 10px;
- cursor: pointer;
- }
-}
-
-</style>
diff --git a/applications/drone-command/src/views/job/components/SearchBox.vue b/applications/drone-command/src/views/job/components/SearchBox.vue
deleted file mode 100644
index e3bf99c..0000000
--- a/applications/drone-command/src/views/job/components/SearchBox.vue
+++ /dev/null
@@ -1,590 +0,0 @@
-<template>
- <div class="search-box-test" :class="{ 'is-expand': isExpand }">
- <el-form :model="searchForm" inline>
- <div class="search-first">
- <el-form-item>
- <el-input v-model="searchForm.key_word" placeholder="请输入任务编号/名称" clearable />
- </el-form-item>
- <el-form-item label="行政区划:">
- <el-tree-select
- popper-class="custom-tree-select"
- v-model="searchForm.area_code"
- :data="deptTreeData"
- :default-expanded-keys="[searchForm.area_code]"
- check-strictly
- node-key="id"
- :props="treeProps"
- clearable
- @change="handleNodeClick"
- />
- </el-form-item>
- <el-form-item label="所属机巢:">
- <el-select
- :teleported="false"
- v-model="searchForm.device_sn"
- placeholder="请选择"
- clearable
- @change="handleSearch"
- >
- <el-option
- v-for="item in machineData"
- :key="item.device_sn"
- :label="item.nickname"
- :value="item.device_sn"
- />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-date-picker
- popper-class="custom-date-picker"
- v-model="dateRange"
- type="daterange"
- range-separator="至"
- start-placeholder="开始日期"
- end-placeholder="结束日期"
- :value-format="timeFormat"
- @change="handleDateChange"
- />
- </el-form-item>
- <el-form-item>
- <div class="time-card">
- <div
- class="card-item"
- :class="item === checked ? 'active' : ''"
- v-for="(item, index) in timeList"
- :key="index"
- @click="timeClick(item, index)"
- >
- {{ timeListStr[index] }}
- </div>
- </div>
- </el-form-item>
- <div class="more" v-if="isExpand" @click="toggleExpand">收起</div>
- <div class="more" v-else @click="toggleExpand">更多</div>
- <div class="search-btn" :style="{ bottom: isExpand ? '5px' : '-3px' }">
-
- <el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>
- <el-button icon="el-icon-refresh" @click="handleReset">重置</el-button>
- </div>
- <el-form-item label="任务算法:" v-if="isExpand" class="taskAlgorithm">
- <!-- <TaskAlgorithmBusiness
- ref="algorithmRef"
- :setWidth="160"
- :showAlgorithm="true"
- @algorithmChange="algorithmChange"
- /> -->
- <el-tree-select
- style="z-index: 1000"
- :teleported="false"
- class="custom-tree-select"
- :style="{ width: pxToRem(186) }"
- v-model="dictKey"
- :data="dataList"
- :default-expanded-keys="[dictKey]"
- :props="treePropsSF"
- :render-after-expand="false"
- :default-checked-keys="checkedKeys"
- node-key="id"
- multiple
- show-checkbox
- collapse-tags
- collapse-tags-tooltip
- clearable
- @check="handleCheck"
- @clear="handleClear"
- />
- </el-form-item>
- <el-form-item label="所属部门:" v-if="isExpand">
- <el-tree-select
- popper-class="custom-tree-select"
- v-model="searchForm.create_dept"
- :data="deptData"
- :default-expanded-keys="[searchForm.create_dept]"
- check-strictly
- node-key="id"
- :props="treeDeptProps"
- clearable
- @change="(id) => handleDeptNodeClick({id})"
- />
- </el-form-item>
- <el-form-item label="任务状态:" v-if="isExpand">
- <el-select
- style="z-index: 1000"
- :teleported="false"
- v-model="searchForm.status"
- placeholder="请选择"
- clearable
- multiple
- collapse-tags
- collapse-tags-tooltip
- @change="handleSearch"
- >
- <el-option
- v-for="item in statusOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="任务类型:" v-if="isExpand">
- <el-select
- :teleported="false"
- v-model="searchForm.is_circle_job"
- placeholder="请选择"
- clearable
- @change="handleSearch"
- >
- <el-option label="周期任务" :value="1" />
- <el-option label="临时任务" :value="0" />
- </el-select>
- </el-form-item>
- </div>
- </el-form>
- </div>
-</template>
-<script setup>
-import { pxToRem } from '@/utils/rem';
-import { ElMessage } from 'element-plus';
-import { deptsByAreaCode, getSFDictionaryTree } from '@/api/job/task';
-import { getDeptLazyTree } from '@/api/system/dept'
-// import TaskAlgorithmBusiness from './TaskAlgorithmBusiness.vue';
-import dayjs from 'dayjs';
-import { useStore } from 'vuex';
-import { getRegionTreeAll } from '@/api/job/task';
-import { getDeviceRegion } from '@/api/job/task';
-const route = useRoute();
-const store = useStore();
-const userAreaCode = computed(() => store.getters.userInfo.detail.areaCode);
-const selectedAreaCode = computed(() => store.state.user.selectedAreaCode);
-
-const algorithmRef = ref(null)
-const isExpand = ref(false);
-const toggleExpand = () => {
- isExpand.value = !isExpand.value;
-};
-const timeFormat = 'YYYY-MM-DD HH:mm:ss';
-
-const dateRange = ref([]);
-
-const treeProps = {
- label: 'name',
- value: 'id',
- children: 'childrens',
-};
-const searchForm = reactive({
- ai_types: [], // 算法类型
- area_code: userAreaCode.value, // 区域code
- create_dept: '', // 创建部门
- date_enum: 'CURRENT_MONTH', // 日期枚举,可用值:TODAY,CURRENT_WEEK,CURRENT_MONTH,CURRENT_YEAR
- device_sn: '', // 设备编号
- end_date: null, // 结束时间
- industry_type: '', // 行业key
- key_word: '', // 模糊搜索关键词(匹配名称/昵称/设备sn)
- start_date: null, // 开始时间
- status: [], // 作业状态
- is_circle_job: null, // 任务类型
-});
-
-// 从单机巢任务传参值
-const signDevice_sn = ref('');
-
-const statusOptions = [
- { label: '待执行', value: 1 },
- { label: '执行中', value: 2 },
- { label: '已执行', value: 3 },
- // { label: '已取消', value: 4 },
- { label: '执行失败', value: 5 },
- { label: '取消执行', value: 7 },
-];
-
-const emit = defineEmits(['search', 'addTask']);
-
-const algorithmChange = val => {
- searchForm.ai_types = val;
- handleSearch()
-};
-
-const businessChange = val => {
- searchForm.industry_type = val;
-};
-
-let deptData = ref([]);
-// 所属部门信息
-const getDeptsByAreaCode = () => {
- getDeptLazyTree({ parentId: 0, level: 0 }).then(res => {
- deptData.value = res.data.data;
- });
-};
-
-// 部门
-let deptTreeData = ref([]);
-// 机巢
-let machineData = ref([]);
-
-// 记录选中行政区划值
-let area_code_log = ref('')
-// 记录选中部门
-let dept_id_log = ref('')
-
-// 部门下得机巢
-const requestDockInfo = () => {
- getRegionTreeAll({ parentCode: userAreaCode.value }).then(res => {
- deptTreeData.value = res.data.data ? [res.data.data] : [];
-
- area_code_log.value = userAreaCode.value
- roadDroneList()
- });
-};
-
-function handleNodeClick(data) {
- area_code_log.value = data?.id
- roadDroneList()
-}
-
-// 筛选部门管理
-function handleDeptNodeClick(data) {
- dept_id_log.value = data.id
- roadDroneList()
-}
-
-// 算法
-const treePropsSF = {
- label: 'dictValue',
- value: 'id',
- children: 'children',
-}
-// 部门
-const treeDeptProps = {
- label: 'title',
- value: 'id',
- children: 'children',
-}
-const dictKey = ref('')
-const dataList = ref([])
-function getAlgorithmList() {
- getSFDictionaryTree({code:'SF'}).then((res) => {
- if (res.data.code === 200) {
- const result = res.data.data[0].children
- // 过滤第一层数据
- const filteredData = result.map(item => {
- // 过滤第二层数据
- const children = item.children?.map(child => ({
- ...child,
- children: [] // 清空第三层数据
- }))
- return {
- ...item,
- children: children || []
- }
- })
- dataList.value = filteredData
- }
- })
-}
-
-function handleSFNodeClick(data) {
- if (data.children && data.children.length) {
- // 获取子节点dictKey
- const childDictKeys = data.children.map(child => child.dictKey)
- searchForm.ai_types = childDictKeys
- } else {
- searchForm.ai_types = [data.dictKey]
- }
- // 更新列表
- handleSearch()
-}
-function handleClear() {
- dictKey.value = ''
- searchForm.ai_types = []
- handleSearch()
-}
-
-async function roadDroneList() {
- // 处理机巢数据
- searchForm.device_sn = ''
- machineData.value = ''
- const droneList = await getDeviceRegion({ area_code: area_code_log.value, dept_id: dept_id_log.value })
-
- machineData.value = droneList?.data?.data
- // 默认选中值
- if (signDevice_sn.value) {
- searchForm.device_sn = signDevice_sn.value
- }
- handleSearch()
-}
-
-// 日期 和周期
-let timeList = ['today', 'week', 'month', 'year'];
-let timeListStr = ['今日', '本周', '本月', '本年'];
-let timeListEnum = ['TODAY', 'CURRENT_WEEK', 'CURRENT_MONTH', 'CURRENT_YEAR'];
-let checked = ref('');
-
-// 根据 周期 获取时间段
-function getDateRange(date_enum) {
- // 设置对应的日期范围
- switch (date_enum) {
- case 'today':
- dateRange.value = [dayjs().startOf('day').format(timeFormat), dayjs().endOf('day').format(timeFormat)]
- break
- case 'week':
- dateRange.value = [dayjs().startOf('week').format(timeFormat), dayjs().format(timeFormat)]
- break
- case 'month':
- dateRange.value = [dayjs().startOf('month').format(timeFormat), dayjs().format(timeFormat)]
- break
- case 'year':
- dateRange.value = [dayjs().startOf('year').format(timeFormat), dayjs().format(timeFormat)]
- break
- }
-}
-
-let timeClick = (item, index) => {
- if (checked.value === item) {
- checked.value = null
- searchForm.date_enum = undefined
- dateRange.value = []
- } else {
- checked.value = item
- searchForm.date_enum = timeListEnum[index]
- getDateRange(item)
- }
- handleSearch()
-}
-// 搜索
-const handleSearch = () => {
- if (!dateRange.value) {
- dateRange.value = [];
- }
- // if (dateRange.value && dateRange.value.length) {
- // // 有值时 清除 日 本周 本月 本年状态
- // checked.value = '';
- // searchForm.date_enum = '';
- // }
- // 提交至store
- let params = {
- ...searchForm,
- start_date: dateRange.value.length
- ? dayjs(dateRange?.value[0]).startOf('day').format(timeFormat)
- : null,
- end_date: dateRange.value.length
- ? dayjs(dateRange?.value[1]).endOf('day').format(timeFormat)
- : null,
- };
- store.commit('setTaskSearchParams', params);
- emit('search', params);
-};
-const handleDateChange = val => {
- checked.value = null
- searchForm.date_enum = undefined
- handleSearch()
-};
-
-// 重置
-const handleReset = () => {
- dateRange.value = [];
- Object.keys(searchForm).forEach(key => {
- searchForm[key] = '';
- });
- searchForm.ai_types = [];
- searchForm.date_enum = 'CURRENT_MONTH';
- searchForm.area_code = userAreaCode.value;
- checked.value = 'month';
- signDevice_sn.value = ''
- // 清除算法
- dictKey.value = '';
- // algorithmRef.value?.clear()
- area_code_log.value = userAreaCode.value
- dept_id_log.value = ''
- roadDroneList()
- // handleSearch();
-};
-
-// 新增任务
-const addTask = () => {
- emit('addTask');
-};
-
-// 监听从巡检任务概况提交的数据
-// watch(
-// () => store.state.task.jumpTask,
-// newVal => {
-
-// if (newVal && Object.keys(newVal).length) {
-// // 兼容当日任务 计划任务 历史任务传参
-// if (newVal.clickValue) {
-// checked.value = newVal.clickValue;
-// searchForm.date_enum = newVal.date_enum;
-// }
-// if (newVal.date_value) {
-// dateRange.value = newVal.date_value;
-// }
-// if (newVal.status) {
-// searchForm.status = newVal.status;
-// }
-// if (newVal.device_sn) {
-// searchForm.device_sn = newVal.device_sn;
-// // 不直接赋值的原因: 回选会被清空值
-// signDevice_sn.value = newVal.device_sn;
-// }
-// } else {
-// checked.value = 'today';
-// searchForm.date_enum = 'TODAY';
-// }
-// handleSearch();
-// },
-// { immediate: true, deep: true }
-// );
-
-const checkedKeys = ref([])
-
-const handleCheck = (data, { checkedKeys, checkedNodes }) => {
- dictKey.value = checkedKeys
- // 获取所有选中节点的 dictKey
- const selectedDictKeys = checkedNodes.map(node => node.dictKey).filter(Boolean)
- searchForm.ai_types = selectedDictKeys
- handleSearch()
-}
-
-onBeforeUnmount(() => {
- checked.value = 'today';
- searchForm.date_enum = 'TODAY';
-});
-
-onMounted(() => {
- requestDockInfo();
- getDeptsByAreaCode()
- getAlgorithmList();
- // 日历传值
- const calendarday = ref(route.query.day);
-
- if (calendarday.value) {
- const date = dayjs(calendarday.value).format(timeFormat);
-
- const dateArray = [date, date];
-
- dateRange.value = dateArray;
- searchForm.date_enum = ''
- const find = store.state.tags.bsTagList.find(i => i.path === '/job/jobstatistics')
- find && (find.query = {})
- } else {
- checked.value = 'month'
- getDateRange('month')
- }
- // 查询一次
- // handleSearch()
-});
-</script>
-<style lang="scss"></style>
-<style lang="scss" scoped>
-// .taskAlgorithm {
-// :deep() {
-// .task-algorithm > div {
-// width: 233px !important;
-// }
-// }
-// }
-.search-box-test {
- transition: all 0.3s;
-
- .search-first {
- position: relative;
- display: flex;
- flex-wrap: wrap;
- align-items: center;
- gap: 20px 15px; // 设置行间距和列间距
-
- .more {
- cursor: pointer;
- width: 32px;
- height: 32px;
- color: #1c5cff;
- line-height: 32px;
- font-size: 16px;
- margin: 0 28px;
- }
-
- .search-btn {
- // position: absolute;
- // right: 0;
- display: flex;
- justify-content: space-between;
- cursor: pointer;
- font-size: 14px;
-
- .btn {
- width: 80px;
- height: 32px;
- border-radius: 4px 4px 4px 4px;
- line-height: 32px;
- display: flex;
- justify-content: center;
- align-items: center;
- // margin-left: px;
- img {
- width: 14px;
- height: 14px;
- }
- }
- .search {
- background: #409eff;
- color: #fff;
- margin-right: 10px;
- }
- .clear {
- border: 1px solid #d2d1d1;
- color: #676767;
- margin-right: 10px;
- }
- .add {
- background: #ff9243;
- color: #fff;
- }
- }
-
- .time-card {
- text-align: center;
- background: #ffffff;
- border-radius: 4px 0px 0px 4px;
- border: 1px solid #e5e5e5;
- font-family: Source Han Sans CN, Source Han Sans CN;
- font-weight: 400;
- font-size: 14px;
- color: #7c8091;
- display: flex;
- height: 32px;
-
- .card-item {
- width: 60px;
- height: 100%;
- line-height: 32px;
- cursor: pointer;
- }
-
- .active {
- background: #ffffff;
- border-radius: 0px 0px 0px 0px;
- border: 1px solid #1c5cff;
- color: #1441ff;
- }
- }
- }
-
- :deep(.el-form) {
- :deep(.el-input__wrapper.is-disabled) {
- box-shadow: 0 0 0 1px #026ad6;
- }
-
- .el-form-item {
- margin-bottom: 0;
- width: 233px;
- margin-right: 20px;
-
- .el-form-item__label {
- color: #363636;
- line-height: 32px;
- }
- }
- }
-}
-</style>
diff --git a/applications/drone-command/src/views/job/components/TaskAlgorithmBusiness.vue b/applications/drone-command/src/views/job/components/TaskAlgorithmBusiness.vue
deleted file mode 100644
index 231de4a..0000000
--- a/applications/drone-command/src/views/job/components/TaskAlgorithmBusiness.vue
+++ /dev/null
@@ -1,131 +0,0 @@
-<!-- 关联算法和综合业务 -->
-<template>
- <div class="task-algorithm" v-if="showAlgorithm">
- <el-select
- class="command-select"
- :teleported="false"
- :style="{ width: pxToRem(setWidth) }"
- v-model="ai_types"
- multiple
- collapse-tags
- collapse-tags-tooltip
- placeholder="支持多项选择"
- clearable
- @clear="handleClear"
- @change="handleAlgorithmChange"
- >
- <el-option v-for="item in taskAlgorithm" :key="item.id" :label="item.dictValue" :value="item.dictKey" />
- </el-select>
- </div>
- <div class="task-business" v-if="showBusiness">
- <el-select class="command-select"
- :teleported="false"
- :style="{ width: pxToRem(setWidth) }"
- v-model="industry_type"
- placeholder="请选择类型"
- clearable
- @change="handleBusinessChange"
- >
- <el-option v-for="item in taskBusiness" :key="item.id" :label="item.dictValue" :value="item.dictKey" />
- </el-select>
- </div>
-</template>
-
-<script setup>
-import { getMultipleDictionary } from '@/api/job/task'
-import { pxToRem } from '@/utils/rem';
-
-// 接收父组件传参
-const props = defineProps({
- showAlgorithm: {
- type: Boolean,
- default: false,
- },
- showBusiness: {
- type: Boolean,
- default: false,
- },
- setWidth: {
- type: String,
- default: '100%',
- },
-})
-
-// 算法
-let ai_types = ref('')
-let taskAlgorithm = ref([])
-// 综合业务
-let industry_type = ref('')
-let taskBusiness = ref([])
-
-// 请求字典字段
-const requestDictionary = () => {
- getMultipleDictionary('SF,HYLB').then(res => {
- if (res.code !== 0) {
- // 处理数据
- taskAlgorithm.value = res.data.data['SF']
- taskBusiness.value = res.data.data['HYLB']
- }
- })
-}
-const emit = defineEmits(['algorithmChange', 'businessChange'])
-// 算法选择事件
-const handleAlgorithmChange = value => {
- emit('algorithmChange', value)
-}
-// 业务选择事件
-const handleBusinessChange = value => {
- emit('businessChange', value)
-}
-
-function handleClear() {
- ai_types.value = []
- emit('algorithmChange', [])
-}
-
-defineExpose({
- handleClear,
-})
-
-onMounted(() => {
- requestDictionary()
-})
-</script>
-<style scoped lang="scss">
-// :deep(.el-tag, .el-tag.el-tag--primary),
-// :deep(.el-tag.el-tag--info) {
-// --el-tag-bg-color: none !important;
-// --el-tag-border-color: none !important;
-// --el-tag-hover-color: none !important;
-// color: #fff !important;
-// }
-::v-deep(.command-select) {
- .el-select__wrapper {
- z-index: 1111;
-
- /* 修改 Tooltip 面板样式 */
- .el-popper.is-light {
- background: #fff !important;
- // box-shadow: none !important;
- // border: none !important;
- border-radius: 4px !important;
-
- .el-select__selection {
- max-width: 240px !important;
-
- .el-select__selected-item {
- .el-tag {
- // background: #fff !important;
- // color: #000;
- }
- }
- }
-
- .el-popper__arrow::before {
- // background: #fff !important;
- // border: 1px solid #8d8b8b !important;
- }
- }
- }
-}
-</style>
diff --git a/applications/drone-command/src/views/job/components/TaskIntermediateContent/AddTask.vue b/applications/drone-command/src/views/job/components/TaskIntermediateContent/AddTask.vue
deleted file mode 100644
index 9fa7ff3..0000000
--- a/applications/drone-command/src/views/job/components/TaskIntermediateContent/AddTask.vue
+++ /dev/null
@@ -1,414 +0,0 @@
-<!-- 新建任务 -->
-<template>
- <el-dialog
- class="command-dialog"
- modal-class="add-task"
- v-model="isShowAddTask"
- title="新建任务"
- :width="1500"
- :close-on-click-modal="false"
- :destroy-on-close="true"
- @close="cancel"
- >
- <!-- <el-divider content-position="left">新建任务</el-divider> -->
- <div class="task-contain">
- <div class="left">
- <div class="search">
- <div class="item">
- <div class="itemchild">任务名称:</div>
- <el-input class="command-input" v-model="searchForm.name" placeholder="请输入"></el-input>
- </div>
- <div class="item">
- <div class="itemchild">日期选择:</div>
- <el-date-picker
- popper-class="custom-date-picker"
- class="command-date-picker tasktimer"
- v-model="taskData"
- type="date"
- placeholder="请选择日期"
- value-format="YYYY-MM-DD"
- :disabled-date="disabledDate"
- />
- </div>
- <div class="item">
- <div class="itemchild">任务时间:</div>
- <el-time-picker
- style="flex: 1"
- popper-class="custom-time-picker"
- class="command-date-picker tasktimer"
- v-model="timeSlot"
- placeholder="请选择"
- format="HH:mm"
- value-format="HH:mm"
- />
- </div>
- <div class="item">
- <div class="itemchild">选择航线:</div>
-
- <el-select
- :teleported="false"
- class="command-select"
- v-model="searchForm.file_id"
- @change="getWayLineFile"
- placeholder="请选择"
- clearable
- >
- <el-option
- v-for="item in routeOptions"
- :key="item.wayline_id"
- :label="item.name"
- :value="item.wayline_id"
- />
- </el-select>
- </div>
- <div class="item">
- <div class="itemchild">关联算法:</div>
- <!-- <TaskAlgorithmBusiness :setWidth="220" :showAlgorithm="true" @algorithmChange="algorithmChange" /> -->
- </div>
- <div class="item">
- <div class="itemchild">任务描述:</div>
- <el-input class="command-input" v-model="searchForm.remark" placeholder="请输入"></el-input>
- </div>
- </div>
- <div class="lines">
- <div class="wayline-type">
- <el-radio-group v-model="waylineType" @change="radioChange">
- <el-radio :value="1" label="单点航线"></el-radio>
- <el-radio :value="2" label="智能规划选区"></el-radio>
- </el-radio-group>
- </div>
- <!-- <TaskMap
- class="wayline-map"
- :wayLineFile="wayLineFile"
- :waylineModel="waylineModel"
- :checkedTableData="checkedTableData"
- :waylineTypeTest="waylineType"
- @clickPosition="clickSignPosition"
- @saveWayline="savePlanerWayline"
- /> -->
- </div>
- </div>
- <div class="right">
- <TaskTable
- ref="taskTableRef"
- :waylineId="waylineId"
- :waylineModel="waylineModel"
- :waylineType="waylineType"
- :singlePoint="singlePoint"
- :planarPoints="planarPoints"
- @update:selected="handleSelected"
- />
- <div class="btn">
- <!-- <img @click="cancel" src="@/assets/images/task/cancel.png" alt="" /> -->
- <img
- @click="!loading && submitClick()"
- :style="{ opacity: loading ? 0.5 : 1, cursor: loading ? 'not-allowed' : 'pointer' }"
- src="@/assets/images/task/publish.png"
- alt=""
- />
- </div>
- </div>
- </div>
- </el-dialog>
-</template>
-
-<script setup>
-import { ElMessage } from 'element-plus'
-import { pxToRem } from '@/utils/rem'
-import { getWaylineList, createTask } from '@/api/job/task'
-// import TaskAlgorithmBusiness from '../components/TaskAlgorithmBusiness.vue'
-// import TaskMap from './TaskMap.vue'
-import TaskTable from './TaskTable.vue'
-import { useRouter } from 'vue-router'
-const router = useRouter()
-
-const emit = defineEmits(['refresh'])
-
-const rangDate = ref([])
-// 航线ID
-const waylineId = ref('')
-// 航线文件
-const wayLineFile = ref('')
-// 航线类型
-const waylineType = ref(3)
-// 添加子组件引用
-const taskTableRef = ref(null)
-const taskData = ref('')
-const timeSlot = ref('')
-const searchForm = reactive({
- name: '',
- ai_types: [],
- file_id: '',
- begin_time: '',
- end_time: '',
- execute_time_arr: '',
- remark: '',
- type: waylineType.value,
- dock_sns: [],
- longitude: '',
- latitude: '',
- polygon: [],
-})
-const isShowAddTask = defineModel('show')
-
-const loading = ref(true)
-
-// 禁用当天之前的日期
-const disabledDate = time => {
- return time.getTime() < Date.now() - 8.64e7 // 86400000 = 24 * 60 * 60 * 1000
-}
-
-// 获取航线列表数据
-const routeOptions = ref([])
-const getRouteList = async () => {
- const res = await getWaylineList()
- if (res.data.code === 0) {
- routeOptions.value = res.data.data
- }
-}
-// 关联算法
-const algorithmChange = val => {
- searchForm.ai_types = val
-}
-
-// 切换航线类型
-const radioChange = val => {
- // 清空选中航线值
- searchForm.file_id = ''
- // 航线ID也清空
- waylineId.value = ''
- wayLineFile.value = ''
- waylineType.value = val
- searchForm.type = val
- // 清空列表数据
- nextTick(() => {
- if (taskTableRef.value) {
- taskTableRef.value.clearTableData()
- }
- })
-}
-// 航线类型
-const waylineModel = ref('')
-// 航线类型
-const judgeWaylineMode = route => {
- if (route.wayline_type == '2' || route.wayline_type == '4') {
- waylineModel.value = 'planar'
- } else {
- waylineModel.value = 'point'
- }
-}
-
-// 获取航线文件
-const getWayLineFile = async val => {
- searchForm.type = 0
- waylineType.value = 0
- waylineId.value = val
- const currentRoute = routeOptions.value.find(item => item.wayline_id === val)
- wayLineFile.value = currentRoute?.object_key || ''
- judgeWaylineMode(currentRoute)
-}
-
-// 获取选中机场列表数据,并且发布
-let checkedTableData = ref([])
-const handleSelected = val => {
- searchForm.dock_sns = val.map(item => item.device_sn)
- checkedTableData.value = val
-}
-
-// 地图点击事件 表格重新刷新数据
-let singlePoint = ref({})
-const clickSignPosition = val => {
- singlePoint.value = val
- searchForm.longitude = val.longitude
- searchForm.latitude = val.latitude
-}
-
-// 保存面状航线
-let planarPoints = ref([])
-const savePlanerWayline = val => {
- planarPoints.value = val
- const polygonArray = val.map(point => [point.longitude, point.latitude])
- searchForm.polygon = polygonArray
-}
-
-// 提交
-const submitClick = () => {
- if (loading.value) return
- if (!taskData.value) {
- ElMessage({
- message: '请选择任务日期',
- type: 'warning',
- })
- return
- }
- if (!searchForm.name) {
- ElMessage({
- message: '请输入任务名称',
- type: 'warning',
- })
- return
- }
- // 检查任务时间
- if (timeSlot.value) {
- const now = new Date()
- const today = now.toDateString()
- const selectedDate = new Date(taskData.value).toDateString()
-
- if (today === selectedDate) {
- const [hours, minutes] = timeSlot.value.split(':')
- const selectedTime = new Date()
- selectedTime.setHours(parseInt(hours), parseInt(minutes))
-
- if (selectedTime < now) {
- ElMessage({
- message: '任务时间不能小于当前时间',
- type: 'warning',
- })
- return
- }
- }
- }
- if (searchForm.dock_sns.length === 0) {
- ElMessage({
- message: '请选择机场',
- type: 'warning',
- })
- return
- }
- loading.value = true
- searchForm.begin_time = `${taskData.value} 00:00:00`
- searchForm.end_time = `${taskData.value} 23:59:59`
- searchForm.execute_time_arr = timeSlot.value ? [timeSlot.value] : []
- createTask(searchForm)
- .then(res => {
- if (res.data.code === 0) {
- ElMessage.success('任务创建成功')
- // 关闭当前窗口,刷新任务管理列表
- isShowAddTask.value = false
- if (searchForm.dock_sns.length === 1) {
- // 清除数据
- cancel()
- emit('refresh')
- } else {
- // 超过两个机场 跳转至集群调度
- store.commit('setSaveTaskId', res?.data.data.id)
- router.push({ path: '/clusterScheduling' })
- }
- }
- })
- .catch(err => {
- loading.value = false
- console.log(err)
- })
- .finally(() => {
- loading.value = false
- })
-}
-const cancel = () => {
- isShowAddTask.value = false
- // 清除搜索数据
- searchForm.name = ''
- searchForm.ai_types = []
- searchForm.file_id = ''
- searchForm.begin_time = ''
- searchForm.end_time = ''
- timeSlot.value = ''
- searchForm.remark = ''
- searchForm.dock_sns = []
- rangDate.value = []
- waylineId.value = ''
- wayLineFile.value = ''
- taskData.value = ''
-}
-
-onMounted(() => {
- getRouteList()
-})
-</script>
-
-<style lang="scss">
-.add-task {
- .el-pagination {
- text-align: left;
- padding: 20px;
- }
-}
-/* 修改日期单元格背景色 */
-// .custom-date-picker .el-picker-panel__body {
-// background: #012350 !important;
-// color: #fff !important;
-// }
-</style>
-
-<style lang="scss" scoped>
-.task-contain {
- display: flex;
- padding: 20px 32px 32px 27px;
- .left {
- width: 1330px;
- margin-right: 34px;
- .search {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- grid-template-rows: repeat(2, 1fr);
- gap: 30px; // 增加间距使布局更合理
- margin-bottom: 8px; // 添加底部间距
- .item {
- position: relative;
- display: flex;
- align-items: center;
- font-size: 16px;
- color: #ffffff;
- .itemchild {
- width: 68px;
- white-space: nowrap;
- margin-right: 5px;
- }
- // :deep(.el-date-editor.el-input__wrapper) {
- // width: 200px; // 调整日期选择器宽度
- // }
- }
- }
- }
- .right {
- width: 366px;
- display: flex;
- flex-direction: column;
- justify-content: space-between;
-
- .btn {
- display: flex;
- justify-content: center;
- align-items: center;
- img {
- width: 137px;
- height: 32px;
- cursor: pointer;
- }
- }
- }
- :deep(.tasktimer .el-input__wrapper) {
- background: none !important;
- color: #8ac3fd !important;
- }
- :deep(.el-input .el-input__icon) {
- color: #fff !important;
- }
- :deep(.el-input__inner) {
- color: #8ac3fd !important;
- &::placeholder {
- color: #8ac3fd !important;
- }
- }
- :deep(.el-radio__inner) {
- background: none !important;
- border: 1px solid #1b5d9a !important;
- }
- :deep(.el-radio__label) {
- color: #fff !important;
- }
- :deep(.el-radio__inner:after) {
- background: #65b5ff !important;
- }
-}
-</style>
diff --git a/applications/drone-command/src/views/job/components/TaskIntermediateContent/TaskIntermediateContent.vue b/applications/drone-command/src/views/job/components/TaskIntermediateContent/TaskIntermediateContent.vue
deleted file mode 100644
index 56b1402..0000000
--- a/applications/drone-command/src/views/job/components/TaskIntermediateContent/TaskIntermediateContent.vue
+++ /dev/null
@@ -1,382 +0,0 @@
-<!-- 任务统计表格 -->
-<template>
- <div class="task-intermediate-content">
- <SearchBox @search="searchClick" @addTask="handleAddTask"></SearchBox>
- <div class="task-table">
- <el-table border :data="jobListData" class="custom-header">
- <el-table-column label="序号" type="index" width="60">
- <template #default="{ $index }">
- {{ ($index + 1 + (jobListParams.current - 1) * jobListParams.size).toString().padStart(2,
- '0') }}
- </template>
- </el-table-column>
- <el-table-column prop="job_info_num" label="任务编号" width="160">
- <template #default="scope">
- <el-tooltip-copy :content="scope.row.job_info_num" :showCopyText="true">
- {{scope.row.job_info_num}}
- </el-tooltip-copy>
- </template>
- </el-table-column>
- <el-table-column prop="name" label="任务名称" width="160">
- <template #default="scope">
- <el-tooltip-copy :content="scope.row.name" :showCopyText="true">
- {{scope.row.name}}
- </el-tooltip-copy>
- </template>
- </el-table-column>
- <el-table-column prop="device_names" label="所属机巢" show-overflow-tooltip/>
- <el-table-column prop="ai_type_str" label="关联算法" show-overflow-tooltip align="center" />
- <el-table-column label="任务状态" align="center">
- <template #default="scope">
- <div class="base_f_c_c">
- <span :style="{
- color:
- scope.row.status === 1
- ? '#00CDC2'
- : scope.row.status === 2
- ? '#FF720F'
- : scope.row.status === 3
- ? '#00AA2D'
- : scope.row.status === 5
- ? '#FF4848'
- : scope.row.status === 7
- ? '#A6A6A6'
- : '',
- }">
- {{ scope.row.status ? getStatusText(scope.row.status) : '' }}
- </span>
- <el-tooltip
- class="item"
- effect="dark"
- :content="scope.row.reason"
- placement="top"
- popper-class="reasonNotFly command-tooltip-box1"
- >
- <el-icon v-if="scope.row.status === 5 && scope.row.reason" color="#FF4848"><QuestionFilled /></el-icon>
- </el-tooltip>
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="is_circle_job" label="任务类型" align="center">
- <template #default="scope">
- <span>{{ scope.row.rep_rule_type ? '周期任务' : '临时任务' }}</span>
- </template>
- </el-table-column>
- <!-- <el-table-column prop="job_num" label="执行次数" /> -->
- <el-table-column prop="event_number" label="关联事件" align="center">
- <template #default="scope">
- <span>{{ scope.row.event_number ? scope.row.event_number : '/' }}</span>
- </template>
- </el-table-column>
- <el-table-column prop="cycle_time_value" label="任务时间" show-overflow-tooltip />
- <el-table-column prop="dept_name" label="创建部门" width="200" align="center" />
- <el-table-column prop="creator_name" label="创建人" align="center" show-overflow-tooltip />
- <el-table-column label="操作" :width="pxToRemNum(200)" align="center">
- <template #default="scope">
- <!-- <el-button type="text" @click="rejectDetail(row.id)">驳回原因</el-button> -->
- <el-button icon="el-icon-back" v-if="scope.row.status === 2" type="text"
- @click="turnBack(scope.row)">
- 返航
- </el-button>
- <el-button icon="el-icon-close" v-if="scope.row.status === 1" type="text"
- @click="cancelTask(scope.row)">
- 取消任务
- </el-button>
- <el-button icon="el-icon-view" type="text" @click="handleDetail(scope.row)">查看</el-button>
- </template>
- </el-table-column>
- <template #empty>
- <el-empty
- class="custom-empty"
- :image-size="100"
- >
- <template #description>
- <span class="custom-text">暂无数据</span>
- </template>
- </el-empty>
- </template>
- </el-table>
- </div>
- <div class="pagination" v-if="jobListData.length > 0">
- <el-pagination class="command-pagination" popper-class="custom-pagination-dropdown" background
- :page-sizes="[10, 20, 30, 40, 50, 100]" :size="size" v-model:current-page="jobListParams.current"
- v-model:page-size="jobListParams.size" layout="total, sizes, prev, pager, next, jumper" :total="total"
- @size-change="handleSizeChange" @current-change="handleCurrentChange" />
- </div>
- </div>
- <!-- 添加任务 -->
- <AddTask v-model:show="isShowAddTask" @refresh="refreshGetJobList" />
- <!-- 当前任务详情 -->
- <!-- <CurrentTaskDetails
- v-if="isShowCurrentTaskDetails"
- v-model:show="isShowCurrentTaskDetails"
- :wayLineJobInfoId="rowData.id"
- /> -->
- <!-- 历史任务详情 -->
- <DeviceJobDetails v-if="isShowDeviceJobDetails" v-model:show="isShowDeviceJobDetails" :wayLineJobInfoId="rowData.id"
- :batchNo="rowData.batch_no" :jobId="jobId" :waylineJobId="rowData.wayline_job_id"/>
- <CancelTaskDialog ref="cancelTaskDialogRef" v-model:isShowCancelTask="isShowCancelTask" :row-data="rowData"
- @refresh="getJobList" />
-</template>
-
-<script setup>
-import SearchBox from '../SearchBox.vue'
-import AddTask from './AddTask.vue'
-import { pxToRem, pxToRemNum } from '@/utils/rem'
-// import CurrentTaskDetails from '@/components/CurrentTaskDetails/CurrentTaskDetails.vue'
-import { jobList, cancelJobs, taskReturnLines, returnHomeCluster, statusChangedApi } from '@/api/job/task';
-import { ElMessage } from 'element-plus'
-import DeviceJobDetails from '../DeviceJobDetails.vue'
-import CancelTaskDialog from '../CancelTaskDialog.vue'
-import { useStore } from 'vuex'
-import { cloneDeep } from 'lodash'
-import { inject, onBeforeUnmount } from 'vue';
-import ElTooltipCopy from '@/components/ElTooltipCopy.vue';
-const store = useStore()
-const singleUavHome = computed(() => store.state.home.singleUavHome)
-const jobListParams = reactive({
- current: 1,
- size: 10,
- searchParams: {},
-})
-const jobListData = ref([])
-const total = ref(0)
-let isShowDeviceJobDetails = ref(false)
-let isShowCurrentTaskDetails = ref(false)
-let isShowCancelTask = ref(false)
-const cancelTaskDialogRef = ref(null)
-
-// 获取任务列表
-const getJobList = () => {
- const apiParams = {
- ...cloneDeep(jobListParams),
- searchParams: {
- ...cloneDeep(jobListParams.searchParams),
- status_list: jobListParams.searchParams.status || undefined,
- status: undefined,
- },
- }
- jobList(apiParams).then(res => {
- if (res.data.code !== 0) return
- jobListData.value = res.data.data.records
- total.value = res.data.data.total
- })
-}
-// 状态文字
-const getStatusText = status => {
- const statusMap = {
- 1: '待执行',
- 2: '执行中',
- 3: '已执行',
- 4: '已取消',
- 5: '执行失败',
- 7: '取消执行',
- }
- return statusMap[status] || '-'
-}
-
-// 查看当前任务详情 如果是一台机则显示详情 如果是多台机则进入集群调度(暂未开发)
-let rowData = ref({})
-const jobId = ref('')
-const handleDetail = row => {
- if (!row.device_sns.length) return ElMessage.warning('没有device_sns')
- rowData.value = row ? row : {}
- if (row.device_sns.length > 1 && (row.status === 2 || row.status === 1)) {
- const adminUrl = `${import.meta.env.VITE_APP_AREA_NAME}/command-center-dashboard/#/clusterScheduling`
- const targetPath = `taskNo=${encodeURIComponent(rowData.value.job_info_num)}`
- window.open(`${adminUrl}?${targetPath}`, '_blank')
- return
- }
- jobId.value = rowData.value?.job_id
- if (row.status === 2 || row.status === 1) {
- // isShowCurrentTaskDetails.value = true
- // 跳转大屏当前任务详情
- const adminUrl = `${import.meta.env.VITE_APP_AREA_NAME}/command-center-dashboard/#/taskManage`
- const targetPath = `id=${encodeURIComponent(rowData.value.id)}&batchNo=${encodeURIComponent(rowData.value.batch_no)}&dockSn=${encodeURIComponent(rowData.value.device_sns[0])}`
- window.open(`${adminUrl}?${targetPath}`, '_blank')
- } else {
- isShowDeviceJobDetails.value = true
- }
-}
-
-// 分页大小改变
-const handleSizeChange = val => {
- jobListParams.size = val
- getJobList()
-}
-
-// 页码改变
-const handleCurrentChange = val => {
- jobListParams.current = val
- getJobList()
-}
-
-// 传参查询条件
-const searchClick = params => {
- jobListParams.current = 1
- jobListParams.size = 10
- jobListParams.searchParams = params
- getJobList()
-}
-
-const refreshGetJobList = () => {
- jobListParams.current = 1
- jobListParams.size = 10
- getJobList()
-}
-
-// 新建任务
-const isShowAddTask = ref(false)
-const handleAddTask = () => {
- isShowAddTask.value = true
-}
-
-const tableRowClassName = ({ row, rowIndex }) => {
- if (rowIndex % 2 === 1) {
- return 'warning-row'
- } else {
- return 'success-row'
- }
-}
-// 取消任务 0 取消全部 1取消单条
-const cancelTask = row => {
- if (row.execute_time_arr?.length && row.execute_time_arr?.length > 0) {
- rowData.value = row
- isShowCancelTask.value = true
- } else {
- cancelTaskDialogRef.value.submitCancelTask(row, 1)
- }
-}
-// 返航
-const turnBack = row => {
- if (row.returnStatus === '待机') return
-
- if (row.returnStatus === '自动返航') return ElMessage.success('无人机返航中')
-
- if (row.returnStatus === '自动降落') return ElMessage.success('无人机降落中')
- returnHomeCluster(row.device_sns).then(res => {
- if (res.data.code !== 0) return
- ElMessage.success('返航操作成功')
- getJobList()
- })
-}
-
-function handleCellClick(row, column) {
- if (column.no === 1) {
- navigator.clipboard.writeText(row.job_info_num).then(() => {
- ElMessage.success('复制任务编号成功')
- })
- } else if (column.no === 2) {
- navigator.clipboard.writeText(row.name).then(() => {
- ElMessage.success('复制任务名称成功')
- })
- }
-}
-
-
-const changeKey = inject('changeKey')
-const jobUpdateKey = computed(() => store.state.common.jobUpdateKey)
-const deviceUpdateKey = computed(() => store.state.common.deviceUpdateKey)
-
-watch([jobUpdateKey,deviceUpdateKey],()=>{
- getJobList()
- changeKey.value++
-})
-
-onBeforeUnmount(() => {
- // clearInterval(polling)
-})
-
-onMounted(() => {
- // getJobList()
-})
-</script>
-
-<style lang="scss" scoped>
-.task-intermediate-content {
- height: 0;
- flex: 1;
- margin: 0 10px 10px 10px;
- background-color: #ffffff;
- padding: 10px 20px;
- border-radius: 5px;
- display: flex;
- flex-direction: column;
-
- // 表格
- .task-table {
- height: 0;
- flex: 1;
- margin-top: 18px;
- overflow: auto;
- :deep(.el-scrollbar__view) {
- height: 100%;
- }
- :deep(.el-table--fit,.el-scrollbar__view) {
- height: 100%;
- }
- }
-
- .custom-empty {
- //font-family: Source Han Sans CN, Source Han Sans CN;
- //margin-top: 15%;
- //.custom-text {
- // color: #fff;
- // font-size: 16px;
- //}
- }
-
- .btnItem {
- height: 27px;
- line-height: 27px;
- border-radius: 0px 0px 0px 0px;
- border: 1px solid #51a8ff;
- font-family: Segoe UI, Segoe UI;
- font-weight: 400;
- font-size: 14px;
- color: #1C5CFF;
- padding: 0 10px;
- display: inline-block;
- margin-right: 10px;
- cursor: pointer;
-
- &.turnBack {
- border: 1px solid #ffa500;
- color: #ffa500;
- }
-
- &.cancelTask {
- border: 1px solid #00AA2D;
- color: #00AA2D;
- }
- }
-
- // :deep(.el-table) {
- // --el-table-tr-bg-color: #ffffff;
- // --el-table-striped-bg-color: #EFEFEF;
-
- // .el-table__body tr.el-table__row--striped td {
- // background-color: var(--el-table-striped-bg-color);
- // }
- // }
- // 分页
- :deep(.custom-header th.el-table__cell) {
- color: rgba(0, 0, 0, 0.85);
- }
-
- :deep(.el-table td.el-table__cell) {
- color: #606266;
- }
-
- :deep(.el-pagination) {
- display: flex;
- padding: 20px 0;
- justify-content: right;
- }
-
- :deep(.el-pagination button) {
- background: center center no-repeat none !important;
- color: #8eb8ea !important;
- }
-}
-</style>
diff --git a/applications/drone-command/src/views/job/components/TaskIntermediateContent/TaskTable.vue b/applications/drone-command/src/views/job/components/TaskIntermediateContent/TaskTable.vue
deleted file mode 100644
index 2416daf..0000000
--- a/applications/drone-command/src/views/job/components/TaskIntermediateContent/TaskTable.vue
+++ /dev/null
@@ -1,252 +0,0 @@
-<template>
- <div class="table-container command-table">
- <div class="taskTableTitle"><span>可飞行机巢列表</span></div>
- <el-table
- :data="tableData"
- :row-style="{ height: '38px', fontSize: '14px', 'text-align': 'center' }"
- :header-cell-style="{ 'text-align': 'center', height: '36px', fontSize: '14px' }"
- @selection-change="handleSelectionChange"
- >
- <el-table-column type="selection" :selectable="checkSelectable" />
- <el-table-column type="index" label="序号">
- <template #default="{ $index }">
- {{ ($index + 1).toString().padStart(2, '0') }}
- </template>
- </el-table-column>
- <el-table-column prop="nickname" label="机巢名称" />
- <el-table-column prop="estimated_arrival_time" label="预计到达时间(min)" />
- <el-table-column prop="flight_range" label="执行里程(km)" />
- </el-table>
- <div class="pagination">
- <el-pagination
- class="command-pagination"
- v-model:current-page="pagingParams.page"
- v-model:page-size="pagingParams.size"
- layout=" prev, pager, next"
- :total="total"
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- />
- </div>
- </div>
-</template>
-
-<script setup>
-import { getFlyingNestBy } from '@/api/job/task'
-import _ from 'lodash'
-
-const props = defineProps({
- waylineId: {
- type: String,
- default: '',
- },
- waylineType: {
- type: Number,
- default: 3,
- },
- singlePoint: {
- type: Object,
- default: () => ({}),
- },
- waylineModel: {
- type: String,
- default: '',
- },
- planarPoints: {
- type: Array,
- default: () => [],
- },
-})
-
-// 选中的数据
-const selectedRows = ref([])
-// 分页参数
-let pageParams = ref({
- wayline_id: props.waylineId,
- type: props.waylineType,
- longitude: props.singlePoint.longitude,
- latitude: props.singlePoint.latitude,
- polygon: [],
-})
-let pagingParams = ref({
- current: 1,
- size: 10,
-})
-// 获取可用机巢列表数据
-const total = ref(0)
-const tableData = ref([])
-const getNestList = async () => {
- tableData.value = []
- const res = await getFlyingNestBy(pageParams.value, pagingParams.value)
- if (res.data.code === 0) {
- tableData.value = (res.data?.data || []).map((item, index) => ({
- ...item,
- estimated_arrival_time: item.estimated_arrival_time > 0 ? _.round(item.estimated_arrival_time / 60, 0) : 0,
- flight_range: item.flight_range > 0 ? _.round(item.flight_range / 1000, 0) : 0,
- }))
- }
-}
-// 分页大小改变
-const handleSizeChange = val => {
- pagingParams.value.size = val
- getNestList()
-}
-
-// 页码改变
-const handleCurrentChange = val => {
- pagingParams.value.current = val
- getNestList()
-}
-
-// 刷新数据
-const refreshData = () => {
- tableData.value = []
- pagingParams.value.current = 1
- getNestList()
-}
-
-const emit = defineEmits(['update:selected'])
-const handleSelectionChange = val => {
- // 如果不是智能规划选区模式,才更新所有选中数据
- if (props.waylineType !== 2) {
- selectedRows.value = val
- emit('update:selected', val)
- } else {
- // 如果是智能规划选区模式,更新选中数据
- if (val.length > 1) {
- const lastSelected = selection[selection.length - 1]
- selectedRows.value = [lastSelected]
- emit('update:selected', selectedRows.value)
- } else {
- emit('update:selected', val)
- }
- }
-}
-
-// 控制表格行是否可选
-const checkSelectable = row => {
- if (props.waylineType === 2) {
- // 如果已经有选中的行,且当前行未被选中,则不允许选择
- return selectedRows.value.length === 0 || selectedRows.value.some(selected => selected.device_sn === row.device_sn)
- }
- return true
-}
-
-// 处理单行选择
-// const handleSelect = (selection, row) => {
-// console.log(55555, selection)
-// if (props.waylineType === 2) {
-// // 如果是智能规划选区模式,确保只能选中一行
-// if (selection.length === 0) {
-// }
-// if (selection.length > 1 || selection.length === 1) {
-// // 保留最后选中的那一行
-// const lastSelected = selection[selection.length - 1]
-// selectedRows.value = [lastSelected]
-// // 触发更新事件
-// console.log('99999', selectedRows.value)
-// emit('update:selected', selectedRows.value)
-// }
-// }
-// }
-
-// 监听航线ID变化
-watch(
- () => props.waylineId,
- newVal => {
- pageParams.value.type = 0
- if (newVal && props.waylineModel === 'point') {
- pageParams.value.wayline_id = newVal
- refreshData()
- } else {
- // 数据为空时,清除列表数据
- tableData.value = []
- }
- },
- { deep: true }
-)
-
-// 监听单点返回的数据
-watch(
- () => props.singlePoint,
- newVal => {
- pageParams.value.wayline_id = ''
- pageParams.value.type = 1
- if (newVal && newVal.latitude && newVal.longitude) {
- pageParams.value.latitude = newVal.latitude
- pageParams.value.longitude = newVal.longitude
- refreshData()
- }
- },
- { deep: true }
-)
-
-// 监听面状航线返回的数据
-watch(
- () => props.planarPoints,
- newVal => {
- pageParams.value.wayline_id = ''
- pageParams.value.type = 2
- if (newVal && newVal.length > 0) {
- const polygonArray = newVal.map(point => [point.longitude, point.latitude])
- pageParams.value.polygon = polygonArray
- refreshData()
- }
- },
- { deep: true }
-)
-
-// 暴露给父组件的方法
-const clearTableData = () => {
- tableData.value = []
-}
-defineExpose({
- clearTableData,
-})
-// 表格隔行变色
-const tableRowClassName = ({ row, rowIndex }) => {
- if (rowIndex % 2 === 1) {
- return 'warning-row'
- } else {
- return 'success-row'
- }
-}
-onMounted(() => {})
-</script>
-
-<style lang="scss" scoped>
-.table-container {
- .pagination {
- margin-top: 10px;
- }
- :deep(.cell) {
- padding: 0;
- margin: 0;
- // border: 1px solid red;
- // width: 20px;
- }
- // 分页
- :deep(.el-pagination) {
- display: flex;
- justify-content: center;
- }
- .taskTableTitle {
- margin-bottom: 16px;
- background: url('/src/assets/images/signMachineNest/machineRight/detailtitle.png') no-repeat center;
- background-size: 100% 100%;
- span {
- display: inline-block;
- margin-left: 10px;
- font-size: 16px;
- color: #ddf0ff;
- line-height: 20px;
- text-align: left;
- margin-bottom: 8px;
- }
- }
- :deep(.el-checkbox__inner) {
- background: none !important;
- border: 1px solid #3194ef !important;
- }
-}
-</style>
diff --git a/applications/drone-command/src/views/job/components/TaskTop/TaskEvent.vue b/applications/drone-command/src/views/job/components/TaskTop/TaskEvent.vue
deleted file mode 100644
index 9f39ef2..0000000
--- a/applications/drone-command/src/views/job/components/TaskTop/TaskEvent.vue
+++ /dev/null
@@ -1,155 +0,0 @@
-<!-- 任务事件数量比统计 -->
-<template>
- <div class="task-event">
- <div class="title">任务事件数量比统计</div>
- <div class="chart" ref="chartRef"></div>
- </div>
-</template>
-
-<script setup>
-import * as echarts from 'echarts'
-import { jobEventBar } from '@/api/job/task'
-import dayjs from 'dayjs'
-import useEchartsResize from '@/hooks/useEchartsResize'
-import { useStore } from 'vuex'
-
-const store = useStore()
-
-// const setTaskSearchParams = computed(() => store.state.task.setTaskSearchParams);
-
-// 日期
-const currenDate = dayjs().format('YYYY-MM-DD')
-const newTime = ref([currenDate, currenDate])
-// 图表
-const chartRef = ref(null)
-let { chart } = useEchartsResize(chartRef)
-
-const option = {
- tooltip: {
- trigger: 'axis',
- axisPointer: {
- type: 'shadow',
- },
- },
- legend: {
- itemWidth: 8,
- itemHeight: 12,
- data: ['任务', '事件'],
- top: '2%',
- textStyle: {
- color: '#6B90B5',
- fontSize: 12,
- },
- },
- grid: {
- top: '15%',
- left: '3%',
- right: '4%',
- bottom: '2%',
- containLabel: true,
- },
- xAxis: {
- type: 'category',
- // data: ['1月', '2月', '3月', '4月', '5月', '6月'],
- axisLine: {
- show: true, // 隐藏轴线
- },
- axisLabel: {
- color: '#5B5B5D',
- },
- },
- yAxis: {
- type: 'value',
- axisLine: {
- lineStyle: {
- color: '#363636',
- },
- },
- splitLine: {
- lineStyle: {
- color: 'rgba(255, 255, 255, 0.1)',
- },
- },
- axisLabel: {
- color: '#5B5B5D',
- },
- },
- series: [
- {
- name: '任务',
- type: 'bar',
- barWidth: 6,
- itemStyle: {
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- { offset: 0, color: '#FF8902' },
- { offset: 1, color: '#FF8902' },
- ]),
- },
- },
- {
- name: '事件',
- type: 'bar',
- barWidth: 6,
- itemStyle: {
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- { offset: 0, color: '#4363FF' },
- { offset: 1, color: '#4363FF' },
- ]),
- },
- },
- ],
-}
-
-// 获取行业统计数据
-const getJobEventBar = value => {
- const params = {
- ...value,
- status_list:value.status,
- status:undefined
- }
- jobEventBar(params).then(res => {
- if (res.data.code !== 0) return
- option.xAxis.data = res.data.data.map(item => item.name)
- option.series[0].data = res.data?.data.map(item => item.data[0].value)
- option.series[1].data = res.data?.data.map(item => item.data[1].value)
- chart.value.setOption(option)
- })
-}
-
-const changeKey = inject('changeKey')
-// 添加监听
-watch(
- () => [store.state.task.taskSearchParams, changeKey.value],
- () => getJobEventBar(store.state.task.taskSearchParams),
- { deep: true }
-)
-</script>
-
-<style lang="scss" scoped>
-.task-event {
- width: 0;
- flex: 1;
- height: 100%;
- margin-left: 10px;
- background: #FFFFFF;
- border-radius: 8px 8px 8px 8px;
-
- .title {
- padding: 10px 0 10px 16px;
- width: 144px;
- height: 18px;
- font-family: Segoe UI, Segoe UI;
- font-weight: bold;
- font-size: 16px;
- color: #363636;
- line-height: 18px;
- }
-
- .chart {
- padding: 6px 0px;
- width: 100%;
- height: 166px;
-
- }
-}
-</style>
diff --git a/applications/drone-command/src/views/job/components/TaskTop/TaskIndustry.vue b/applications/drone-command/src/views/job/components/TaskTop/TaskIndustry.vue
deleted file mode 100644
index 58c3ed8..0000000
--- a/applications/drone-command/src/views/job/components/TaskTop/TaskIndustry.vue
+++ /dev/null
@@ -1,117 +0,0 @@
-<!-- 任务算法统计 -->
-<template>
- <div class="task-industry">
- <div class="title">机巢事件数量占比</div>
- <div class="chart" ref="chartRef"></div>
- </div>
-</template>
-
-<script setup>
-import * as echarts from 'echarts'
-import { industryJobNumPieChart } from '@/api/job/task'
-import useEchartsResize from '@/hooks/useEchartsResize'
-import { useStore } from 'vuex'
-
-const store = useStore()
-const chartRef = ref(null)
-let { chart } = useEchartsResize(chartRef)
-
-const option = {
- tooltip: {
- trigger: 'item',
- formatter: '{b}: {c} ({d}%)',
- },
- legend: {
- orient: 'vertical',
- top: 'center',
- right: '20',
- textStyle: {
- color: '#363636',
- fontSize: 12,
- },
- itemWidth: 8, // 减小图例标记的宽度
- itemHeight: 8, // 减小图例标记的高度
- itemGap: 8, // 减小图例项之间的间距
- formatter: '{name}', // 简化图例文本
- },
- series: [
- {
- name: '机巢事件统计',
- type: 'pie',
- // roseType: 'radius',
- radius: ['20%', '70%'],
- center: ['30%', '50%'],
- data: [],
- label: {
- show: false,
- position: 'outside',
- formatter: '{c}',
- fontSize: 12,
- color: '#000',
- },
- labelLine: {
- show: false,
- length: 10,
- length2: 10,
- lineStyle: {
- color: '#000',
- },
- },
- },
- ],
-}
-
-// 获取机巢事件数据
-const getIndustryJobNumPieChart = value => {
- industryJobNumPieChart(value).then(res => {
- if (res.data.code !== 0) return
- option.series[0].data = res.data.data
- // forEach(item => {
- // const matchData = res.data.data.find(d => d.name === item.name);
- // if (matchData) {
- // item.value = matchData.value;
- // }
- // });
- chart.value.setOption(option)
- })
-}
-
-const changeKey = inject('changeKey')
-// 添加监听
-watch(
- () => [store.state.task.taskSearchParams,changeKey.value],
- () => getIndustryJobNumPieChart(store.state.task.taskSearchParams),
- { deep: true }
-)
-
-
-onMounted(() => {
- getIndustryJobNumPieChart({ date_enum: 'TODAY' })
-})
-</script>
-
-<style lang="scss" scoped>
-.task-industry {
- width: 300px;
- height: 100%;
- background: #FFFFFF;
- border-radius: 8px 8px 8px 8px;
- margin-left: 10px;
-
- .title {
- font-family: Segoe UI, Segoe UI;
- padding: 10px 0 10px 16px;
- width: 160px;
- height: 18px;
- font-weight: bold;
- font-size: 16px;
- color: #363636;
- line-height: 18px;
- }
-
- .chart {
- width: 100%;
- height: 180px;
- }
-}
-</style>
diff --git a/applications/drone-command/src/views/job/components/TaskTop/TaskTime.vue b/applications/drone-command/src/views/job/components/TaskTop/TaskTime.vue
deleted file mode 100644
index fdacf62..0000000
--- a/applications/drone-command/src/views/job/components/TaskTop/TaskTime.vue
+++ /dev/null
@@ -1,161 +0,0 @@
-<!-- 任务数量统计 -->
-<template>
- <div class="task-time">
- <div class="title">任务数量统计</div>
- <div class="chart" ref="chartRef"></div>
- </div>
-</template>
-
-<script setup>
-import * as echarts from 'echarts'
-import { jobNumBar } from '@/api/job/task'
-import dayjs from 'dayjs'
-import useEchartsResize from '@/hooks/useEchartsResize'
-import { useStore } from 'vuex'
-
-const store = useStore()
-
-// 日期
-const currenDate = dayjs().format('YYYY-MM-DD')
-const newTime = ref([currenDate, currenDate])
-
-const chartRef = ref(null)
-let { chart } = useEchartsResize(chartRef)
-
-const option = {
- tooltip: {
- trigger: 'axis',
- axisPointer: {
- type: 'shadow',
- },
- formatter: '{b}: {c} 件',
- },
- legend: {
- itemWidth: 8,
- itemHeight: 12,
- top: '2%',
- textStyle: {
- color: '#6B90B5',
- fontSize: 12,
- },
- },
- grid: {
- top: '15%',
- left: '3%',
- right: '4%',
- bottom: '2%',
- containLabel: true,
- },
- // xAxis: {
- // type: 'category',
- // axisLine: {
- // lineStyle: {
- // color: '#fff'
- // }
- // },
- // axisLabel: {
- // color: '#fff',
- // interval: 0,
- // rotate: 30
- // }
- // },
- xAxis: {
- type: 'category',
- data: ['1'],
- axisLine: {
- show: true, // 隐藏轴线
- },
- // axisTick: {
- // show: true,
- // length: 2,
- // lineStyle: {
- // color: 'red',
- // },
- // },
- axisLabel: {
- color: '#363636',
- margin: 8,
- },
- },
- yAxis: {
- type: 'value',
- nameTextStyle: {
- color: '#E6F7FF',
- fontSize: 12,
- padding: [0, 0, 0, 0], // 调整单位文字位置
- },
- axisLine: {
- lineStyle: {
- color: '#fff',
- },
- },
- splitLine: {
- lineStyle: {
- color: 'rgba(255, 255, 255, 0.1)',
- },
- },
- axisLabel: {
- color: '#5B5B5D',
- },
- },
- series: [
- {
- name: '任务数量',
- type: 'bar',
- barWidth: 8,
- itemStyle: {
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- { offset: 0, color: '#1C5CFF ' },
- { offset: 1, color: '#1C5CFF ' },
- ]),
- },
- },
- ],
-}
-
-// 获取任务时间统计数据
-const getJobNumBar = value => {
- jobNumBar(value).then(res => {
- if (res.data.code !== 0) return
- option.xAxis.data = res.data.data.map(item => item.name)
- option.series[0].data = res.data.data.map(item => item.value)
- chart.value.setOption(option)
- })
-}
-
-const changeKey = inject('changeKey')
-// 添加监听
-watch(
- () => [store.state.task.taskSearchParams,changeKey.value],
- () => getJobNumBar(store.state.task.taskSearchParams),
- { deep: true }
-)
-</script>
-
-<style lang="scss" scoped>
-.task-time {
- width: 529px;
- height: 100%;
- margin-left: 10px;
- background: #FFFFFF;
- border-radius: 8px 8px 8px 8px;
-
- .title {
- padding: 10px 0 10px 16px;
- width: 96px;
- height: 18px;
- font-family: Segoe UI, Segoe UI;
- font-weight: bold;
- font-size: 16px;
- color: #363636;
- line-height: 18px;
- }
-
- .chart {
- padding: 6px 0px;
- width: 100%;
- height: 166px;
- color: #000;
- }
-}
-</style>
diff --git a/applications/drone-command/src/views/job/components/TaskTop/TaskTop.vue b/applications/drone-command/src/views/job/components/TaskTop/TaskTop.vue
deleted file mode 100644
index 68b8a6b..0000000
--- a/applications/drone-command/src/views/job/components/TaskTop/TaskTop.vue
+++ /dev/null
@@ -1,47 +0,0 @@
-<!--
- * @Author : yuan
- * @Date : 2025-06-14 15:19:16
- * @LastEditors : yuan
- * @LastEditTime : 2025-06-26 11:46:38
- * @FilePath : \src\views\job\components\TaskTop\TaskTop.vue
- * @Description :
- * Copyright 2025 OBKoro1, All Rights Reserved.
- * 2025-06-14 15:19:16
--->
-<template>
- <div class="task-top">
- <!--时间 天气-->
- <div class="statistical-chart">
- <TaskTotal />
- <TaskIndustry />
- <TaskTime />
- <TaskEvent />
- </div>
- </div>
-</template>
-
-<script setup>
-import { pxToRem } from '@/utils/rem'
-import TaskTotal from './TaskTotal.vue'
-import TaskIndustry from './TaskIndustry.vue'
-import TaskTime from './TaskTime.vue'
-import TaskEvent from './TaskEvent.vue'
-</script>
-
-<style lang="scss" scoped>
-.task-top {
- position: relative;
- display: flex;
-
- .statistical-chart {
- margin-left: 10px;
- margin-right: 10px;
- display: flex;
- width: 0;
- flex: 1;
- height: 216px;
- box-sizing: border-box;
- margin-bottom: 10px;
- }
-}
-</style>
diff --git a/applications/drone-command/src/views/job/components/TaskTop/TaskTotal.vue b/applications/drone-command/src/views/job/components/TaskTop/TaskTotal.vue
deleted file mode 100644
index b3bd734..0000000
--- a/applications/drone-command/src/views/job/components/TaskTop/TaskTotal.vue
+++ /dev/null
@@ -1,157 +0,0 @@
-<!-- 任务统计 -->
-<template>
- <div class="task-total">
- <div class="title">任务数据概览</div>
- <div class="contain">
- <div class="left">
- <div class="total-num">
- <img src="@/assets/images/task/total-number.png" alt="" />
- <div class="txt">总执行次数</div>
- <div class="num">{{ numTotal }}</div>
- </div>
- </div>
- <div class="other-total">
- <div class="total" v-for="(item, index) in list" :key="index">
- <div class="total-item">
- <div class="name"><img :src="item.img" alt="" />{{ item.name }}</div>
- <div class="value" :style="{ color: item.color }">{{ item.value }}</div>
- </div>
- </div>
- </div>
- </div>
- </div>
-</template>
-
-<script setup>
-import { pxToRem } from '@/utils/rem'
-import { totalJobNum, jobStatistics } from '@/api/job/task'
-import { useStore } from 'vuex'
-import jhzxpng from '@/assets/images/task/jhzx.png'
-import yzxpng from '@/assets/images/task/yzx.png'
-import zxzpng from '@/assets/images/task/zxz.png'
-import zxsbpng from '@/assets/images/task/zxsb.png'
-import dzxpng from '@/assets/images/task/dzx.png'
-import qxzxpng from '@/assets/images/task/qxzx.png'
-
-const store = useStore()
-
-const total = ref(0)
-const numTotal = ref(0)
-const list = ref([
- { name: '计划执行', value: '0', color: '#1C5CFF', img: jhzxpng },
- { name: '已执行', value: '0', color: '#00AA2D', img: yzxpng },
- { name: '执行中', value: '0', color: '#FF720F', img: zxzpng},
- { name: '执行失败', value: '0', color: '#FF4848', img: zxsbpng },
- { name: '待执行', value: '0', color: '#00CDC2', img: dzxpng },
- { name: '取消执行', value: '0', color: '#373333', img: qxzxpng },
-])
-
-
-// 获取其他任务统计
-const getJobStatistics = value => {
- jobStatistics(value).then(res => {
- if (res.data.code !== 0) returen
- const {executed = 0,failed_executions = 0,go_home_executions = 0} = res.data?.data || {}
- numTotal.value = executed + failed_executions + go_home_executions
- list.value[0].value = res.data.data.planned_executions || 0
- list.value[1].value = res.data.data.executed || 0
- list.value[2].value = res.data.data.running_num || 0
- list.value[3].value = res.data.data.failed_executions || 0
- list.value[4].value = res.data.data.pending_executions || 0
- list.value[5].value = res.data.data.go_home_executions || 0
- })
-}
-
-const changeKey = inject('changeKey')
-// 添加监听
-watch(
- () => [store.state.task.taskSearchParams,changeKey.value],
- () => getJobStatistics(store.state.task.taskSearchParams),
- { deep: true }
-)
-
-</script>
-
-<style scoped lang="scss">
-.task-total {
- width: 300px;
- font-family: Source Han Sans CN, Source Han Sans CN;
- background: #FFFFFF;
- border-radius: 8px 8px 8px 8px;
- .title {
- padding: 10px 0 10px 16px;
- width: 96px;
- height: 18px;
- font-family: Segoe UI, Segoe UI;
- font-weight: bold;
- font-size: 16px;
- color: #363636;
- line-height: 18px;
- text-align: left;
- font-style: normal;
- text-transform: none;
- }
- .contain {
- display: flex;
- }
- .total-num {
- width: 100px;
-
- img {
- width: 84px;
- height: 84px;
- }
- .txt {
- font-weight: 400;
- font-size: 14px;
- color: #363636;
- line-height: 18px;
- text-align: center;
- }
- .num {
- font-weight: bold;
- font-size: 20px;
- color: #363636;
- line-height: 18px;
- text-align: center;
- margin-top: 6px;
- }
- }
- .other-total {
- position: relative;
- top: -10px;
- width: 200px;
- height: 160px;
- display: flex;
- gap: 10px;
-
- flex-wrap: wrap;
- align-content: space-evenly;
- .total {
- display: flex;
- align-items: center;
- margin-bottom: -18px;
- text-align: center;
-
- .name {
- display: flex;
- align-items: center;
- width: 90px;
- font-weight: 400;
- font-size: 14px;
- color: #363636;
- line-height: 18px;
- img {
- width: 18px;
- height: 18px;
- }
- }
- .value {
- font-weight: bold;
- font-size: 16px;
- text-align: center;
- }
- }
- }
-}
-</style>
diff --git a/applications/drone-command/src/views/job/components/executeNestDetails.vue b/applications/drone-command/src/views/job/components/executeNestDetails.vue
deleted file mode 100644
index 6fe3e25..0000000
--- a/applications/drone-command/src/views/job/components/executeNestDetails.vue
+++ /dev/null
@@ -1,225 +0,0 @@
-<template>
- <div class="executeNestDetails">
- <img src="/src/assets/images/task/sign.svg" alt="">
- <div class="title">
- 任务执行详情
- </div>
- </div>
- <div class="command-table">
- <el-table
- v-loading="loading"
- element-loading-background="rgba(22, 43, 74, 0.79)"
- :row-class-name="tableRowClassName"
- :data="taskData"
- style="width: 100%"
- :row-style="{ height: pxToRem(48), fontSize: pxToRem(14), 'text-align': 'center' }"
- :header-cell-style="{ 'text-align': 'center', height: pxToRem(36), fontSize: pxToRem(14) }"
- >
- <el-table-column type="index" label="序号" :width="pxToRemNum(100)" align="center">
- <template #default="{ $index }">
- {{ ($index + 1).toString().padStart(2, '0') }}
- </template>
- </el-table-column>
- <el-table-column show-overflow-tooltip prop="nick_name" label="机巢名称" align="center">
- <template #default="scope">
- <el-tooltip-copy :content="scope.row.nick_name" :showCopyText="true">
- {{ scope.row.nick_name }}
- </el-tooltip-copy>
- </template>
- </el-table-column>
-
- <el-table-column prop="status" label="执行状态" align="center">
- <template #default="scope">
- <div class="base_f_c_c">
- <span
- :style="{
- color:
- scope.row.status === 1
- ? '#ffe17e'
- : scope.row.status === 2
- ? '#ffa768'
- : scope.row.status === 3
- ? 'rgb(6, 217, 87)'
- : scope.row.status === 5
- ? '#FF4848'
- : scope.row.status === 7
- ? '#A6A6A6'
- : '',
- }"
- >
- {{ scope.row.status ? getStatusText(scope.row.status) : '' }}
- </span>
-
- <el-tooltip
- class="item"
- effect="dark"
- :content="scope.row.reason"
- placement="top"
- popper-class="reasonNotFly command-tooltip-box1"
- >
- <el-icon v-if="scope.row.status === 5 && scope.row.reason" color="#FF4848"><QuestionFilled /></el-icon>
- </el-tooltip>
- </div>
- </template>
- </el-table-column>
- </el-table>
- </div>
-</template>
-<script setup>
-import { NestDetailApi } from '@/api/home'
-import { dayjs, ElMessage, ElMessageBox } from 'element-plus'
-import { pxToRem, pxToRemNum } from '@/utils/rem'
-import { QuestionFilled } from '@element-plus/icons-vue'
-import { ContinuingToFly } from '@/const/device'
-const props = defineProps(['wayLineJobInfoId', 'batchNo'])
-const taskData = ref('')
-// 是否展示再次执行弹框
-let isShowDetails = ref(false)
-const singledevice_sns = ref([])
-const deviseName = ref(null)
-const devisejobInfoId = ref('')
-const devisebatchNo = ref(null)
-const loading = ref(true)
-const isShowContinuingToFly = code => {
- return ContinuingToFly.find(i => i.code === code)
-}
-// 状态文字
-const getStatusText = status => {
- const statusMap = {
- 1: '待执行',
- 2: '执行中',
- 3: '已执行',
- 4: '已取消',
- 5: '执行失败',
- 7: '取消执行',
- }
- return statusMap[status] || '-'
-}
-// 表格隔行变色
-const tableRowClassName = ({ row, rowIndex }) => {
- if (rowIndex % 2 === 1) {
- return 'warning-row'
- } else {
- return 'success-row'
- }
-}
-
-const handleSearch = () => {}
-// 执行机巢详情
-const getNestDetailApi = () => {
- const params = {
- jobInfoId: props.wayLineJobInfoId,
- batchNo: props.batchNo,
- }
- NestDetailApi(params).then(res => {
- taskData.value = res.data.data
- })
-}
-onMounted(() => {
- getNestDetailApi()
-})
-</script>
-
-<style scoped lang="scss">
-.executeNestDetails {
- display: flex;
- align-items: center;
- border-bottom: 2px solid #e4e7ed;
- img {
- width: 15px;
- height: 15px;
- }
- margin-bottom: 8px;
-
- .title {
- margin-left: 10px;
- font-size: 16px;
- color: #303133;
- }
-}
-
-.command-table {
- margin-bottom: 16px;
-}
-
-// 待处理
-.pending {
- color: #ff7411;
-}
-// 待审核
-.reviewed {
- color: #ff472f;
-}
-// 处理中
-.processing {
- color: #ffff61;
-}
-// 已完成
-.done {
- color: #06d957;
-}
-// 已完结
-.ended {
- color: #06d957;
-}
-
-.searchBox {
- display: flex;
-}
-.search-btn {
- display: flex;
- img {
- cursor: pointer;
- margin-right: 8px;
- width: 82px;
- height: 32px;
- }
-}
-.btnGroups {
- display: flex;
- align-items: center;
- justify-content: space-around;
- div {
- height: 27px;
- line-height: 27px;
- background: #001f4e !important;
- border-radius: 0px 0px 0px 0px;
- border: 1px solid #51a8ff !important;
- font-size: 14px;
- color: #ffffff;
- text-align: center;
- cursor: pointer;
- padding: 0 8px;
- }
-}
-</style>
-<style lang="scss">
-.machineTableDetailsTitle {
- display: flex;
- border-bottom: 2px solid #e4e7ed;
- background-size: 100% 100%;
-
- img {
- width: 15px;
- height: 15px;
- margin-top: 6px;
- }
-
- .title {
- display: inline-block;
- margin-left: 10px;
- font-size: 16px;
- // color: #0282ff;
- color: #303133;
- line-height: 20px;
- text-align: left;
- margin-bottom: 8px;
- }
-
- .btn {
- margin-left: 16px;
- margin-bottom: 8px;
- line-height: 20px;
- }
-}
-</style>
diff --git a/applications/drone-command/src/views/job/const/drc.js b/applications/drone-command/src/views/job/const/drc.js
deleted file mode 100644
index e15b981..0000000
--- a/applications/drone-command/src/views/job/const/drc.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import startRecordImg from '@/assets/images/task/startRecord.png'
-import hoverImg from '@/assets/images/task/hover.png'
-import takePhotoImg from '@/assets/images/task/takePhoto.png'
-
-export const droneEventList = [
- {name:'开始录像',value:'startRecord',img:startRecordImg},
- {name:'悬停',value:'hover',img:hoverImg},
- {name:'拍照',value:'takePhoto',img:takePhotoImg},
-]
\ No newline at end of file
diff --git a/applications/drone-command/src/views/job/jobinfo.vue b/applications/drone-command/src/views/job/jobinfo.vue
deleted file mode 100644
index 240c22f..0000000
--- a/applications/drone-command/src/views/job/jobinfo.vue
+++ /dev/null
@@ -1,277 +0,0 @@
-<template>
- <basic-container>
- <avue-crud :option="option" v-model:search="search" v-model:page="page" v-model="form" :table-loading="loading"
- :data="data" :permission="permissionList" :before-open="beforeOpen" ref="crud" @row-update="rowUpdate"
- @row-save="rowSave" @row-del="rowDel" @search-change="searchChange" @search-reset="searchReset"
- @selection-change="selectionChange" @current-change="currentChange" @size-change="sizeChange"
- @refresh-change="refreshChange" @on-load="onLoad">
- <template #menu-left>
- <el-button type="danger" icon="el-icon-delete" plain v-if="permission.jobinfo_delete" @click="handleDelete">删 除
- </el-button>
- <el-button type="info" plain icon="el-icon-sort" @click="handleSync">数 据 同 步
- </el-button>
- </template>
- <template #menu="scope">
- <el-button type="primary" text icon="el-icon-video-play" @click="handleRun(scope.row)">运 行
- </el-button>
- </template>
- <template #enable="{ row }">
- <el-switch v-model="row.enable" inline-prompt @change="slotChange(row)" active-text="启用" inactive-text="暂停"
- :active-value="1" :inactive-value="0" />
- </template>
- </avue-crud>
- </basic-container>
-</template>
-
-<script>
-import { getList, getDetail, add, update, remove, change, run, sync } from '@/api/job/jobinfo'
-import option from '@/option/job/jobinfo'
-import { mapGetters } from 'vuex'
-import 'nprogress/nprogress.css'
-import func from '@/utils/func'
-
-export default {
- data () {
- return {
- form: {},
- query: {},
- search: {},
- loading: true,
- page: {
- pageSize: 10,
- currentPage: 1,
- total: 0,
- },
- selectionList: [],
- option: option,
- data: [],
- searchChangeHandler: null,
- }
- },
- created() {
- this.searchChangeHandler = (params) => {
- this.searchChange(params, () => {});
- };
- this.$bus?.on('triggerSearchChange', this.searchChangeHandler);
- },
- beforeDestroy() {
- if (this.searchChangeHandler) {
- this.$bus?.off('triggerSearchChange', this.searchChangeHandler);
- this.searchChangeHandler = null;
- }
- },
- computed: {
- ...mapGetters(['permission']),
- permissionList () {
- return {
- addBtn: this.validData(this.permission.jobinfo_add, false),
- viewBtn: this.validData(this.permission.jobinfo_view, false),
- delBtn: this.validData(this.permission.jobinfo_delete, false),
- editBtn: this.validData(this.permission.jobinfo_edit, false),
- }
- },
- ids () {
- let ids = []
- this.selectionList.forEach(ele => {
- ids.push(ele.id)
- })
- return ids.join(',')
- },
- },
- methods: {
- rowSave (row, done, loading) {
- if (func.isArrayAndNotEmpty(row.lifecycle)) {
- const lifecycleStart = row.lifecycle[0]
- const lifecycleEnd = row.lifecycle[1]
- if (!func.isUndefined(lifecycleStart) && !func.isUndefined(lifecycleEnd)) {
- row.lifecycle = lifecycleStart + ',' + lifecycleEnd
- }
- } else {
- row.lifecycle = ''
- }
- add(row).then(
- () => {
- this.onLoad(this.page)
- this.$message({
- type: 'success',
- message: '操作成功!',
- })
- done()
- },
- error => {
- loading()
- window.console.log(error)
- }
- )
- },
- rowUpdate (row, index, done, loading) {
- if (func.isArrayAndNotEmpty(row.lifecycle)) {
- const lifecycleStart = row.lifecycle[0]
- const lifecycleEnd = row.lifecycle[1]
- if (!func.isUndefined(lifecycleStart) && !func.isUndefined(lifecycleEnd)) {
- row.lifecycle = lifecycleStart + ',' + lifecycleEnd
- }
- } else {
- row.lifecycle = ""
- }
- update(row).then(
- () => {
- this.onLoad(this.page)
- this.$message({
- type: 'success',
- message: '操作成功!',
- })
- done()
- },
- error => {
- loading()
- console.log(error)
- }
- )
- },
- rowDel (row) {
- this.$confirm('确定将选择数据删除?', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- })
- .then(() => {
- return remove(row.id)
- })
- .then(() => {
- this.onLoad(this.page)
- this.$message({
- type: 'success',
- message: '操作成功!',
- })
- })
- },
- handleDelete () {
- if (this.selectionList.length === 0) {
- this.$message.warning('请选择至少一条数据')
- return
- }
- this.$confirm('确定将选择数据删除?', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- })
- .then(() => {
- return remove(this.ids)
- })
- .then(() => {
- this.onLoad(this.page)
- this.$message({
- type: 'success',
- message: '操作成功!',
- })
- this.$refs.crud.toggleSelection()
- })
- },
- handleSync () {
- this.$confirm('确定进行数据双向同步?', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- })
- .then(() => {
- return sync()
- })
- .then(() => {
- this.onLoad(this.page)
- this.$message({
- type: 'success',
- message: '操作成功!',
- })
- })
- },
- handleRun (row) {
- this.$confirm('运行后将创建一个实例执行,是否继续?', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- })
- .then(() => {
- return run(row)
- })
- .then(() => {
- this.$message({
- type: 'success',
- message: '运行成功!',
- })
- })
- },
- slotChange (row) {
- if (!row.id) {
- return
- }
- change(row).then(
- () => {
- this.onLoad(this.page)
- this.$message({
- type: 'success',
- message: '操作成功!',
- })
- },
- error => {
- window.console.log(error)
- }
- )
- },
- beforeOpen (done, type) {
- if (['edit', 'view'].includes(type)) {
- getDetail(this.form.id).then(res => {
- this.form = res.data.data
- })
- }
- done()
- },
- searchReset () {
- this.query = {}
- this.onLoad(this.page)
- },
- searchChange (params, done) {
- this.query = params
- this.page.currentPage = 1
- this.onLoad(this.page, params)
- done()
- },
- selectionChange (list) {
- this.selectionList = list
- },
- selectionClear () {
- this.selectionList = []
- this.$refs.crud.toggleSelection()
- },
- currentChange (currentPage) {
- this.page.currentPage = currentPage
- },
- sizeChange (pageSize) {
- this.page.pageSize = pageSize
- },
- refreshChange () {
- this.onLoad(this.page, this.query)
- },
- onLoad (page) {
- this.loading = true
-
- const { jobServerId, jobName } = this.query
-
- let values = {
- jobServerId_like: jobServerId,
- jobName_like: jobName,
- }
-
- getList(page.currentPage, page.pageSize, values).then(res => {
- const data = res.data.data
- this.page.total = data.total
- this.data = data.records
- this.loading = false
- this.selectionClear()
- })
- },
- },
-}
-</script>
-
-<style scoped lang="scss"></style>
diff --git a/applications/drone-command/src/views/job/jobserver.vue b/applications/drone-command/src/views/job/jobserver.vue
deleted file mode 100644
index 29567a9..0000000
--- a/applications/drone-command/src/views/job/jobserver.vue
+++ /dev/null
@@ -1,213 +0,0 @@
-<template>
- <basic-container>
- <avue-crud :option="option" v-model:search="search" v-model:page="page" v-model="form" :table-loading="loading"
- :data="data" :permission="permissionList" :before-open="beforeOpen" ref="crud" @row-update="rowUpdate"
- @row-save="rowSave" @row-del="rowDel" @search-change="searchChange" @search-reset="searchReset"
- @selection-change="selectionChange" @current-change="currentChange" @size-change="sizeChange"
- @refresh-change="refreshChange" @on-load="onLoad">
- <template #menu-left>
- <el-button type="danger" icon="el-icon-delete" plain v-if="permission.jobserver_delete" @click="handleDelete">删
- 除
- </el-button>
- <el-button type="info" plain icon="el-icon-sort" @click="handleSync">数 据 同 步
- </el-button>
- </template>
- <template #menu="scope">
- <el-button type="primary" text icon="el-icon-video-play" @click="handleLink(scope.row)">服务跳转
- </el-button>
- </template>
- </avue-crud>
- </basic-container>
-</template>
-
-<script>
-import { getList, getDetail, add, update, remove, sync } from '@/api/job/jobserver'
-import option from '@/option/job/jobserver'
-import { mapGetters } from 'vuex'
-import 'nprogress/nprogress.css'
-import func from '@/utils/func'
-
-export default {
- data () {
- return {
- form: {},
- query: {},
- search: {},
- loading: true,
- page: {
- pageSize: 10,
- currentPage: 1,
- total: 0,
- },
- selectionList: [],
- option: option,
- data: [],
- }
- },
- computed: {
- ...mapGetters(['permission']),
- permissionList () {
- return {
- addBtn: this.validData(this.permission.jobserver_add, false),
- viewBtn: this.validData(this.permission.jobserver_view, false),
- delBtn: this.validData(this.permission.jobserver_delete, false),
- editBtn: this.validData(this.permission.jobserver_edit, false),
- }
- },
- ids () {
- let ids = []
- this.selectionList.forEach(ele => {
- ids.push(ele.id)
- })
- return ids.join(',')
- },
- },
- methods: {
- rowSave (row, done, loading) {
- add(row).then(
- () => {
- this.onLoad(this.page)
- this.$message({
- type: 'success',
- message: '操作成功!',
- })
- done()
- },
- error => {
- loading()
- window.console.log(error)
- }
- )
- },
- rowUpdate (row, index, done, loading) {
- update(row).then(
- () => {
- this.onLoad(this.page)
- this.$message({
- type: 'success',
- message: '操作成功!',
- })
- done()
- },
- error => {
- loading()
- console.log(error)
- }
- )
- },
- rowDel (row) {
- this.$confirm('确定将选择数据删除?', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- })
- .then(() => {
- return remove(row.id)
- })
- .then(() => {
- this.onLoad(this.page)
- this.$message({
- type: 'success',
- message: '操作成功!',
- })
- })
- },
- handleDelete () {
- if (this.selectionList.length === 0) {
- this.$message.warning('请选择至少一条数据')
- return
- }
- this.$confirm('确定将选择数据删除?', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- })
- .then(() => {
- return remove(this.ids)
- })
- .then(() => {
- this.onLoad(this.page)
- this.$message({
- type: 'success',
- message: '操作成功!',
- })
- this.$refs.crud.toggleSelection()
- })
- },
- handleLink (row) {
- window.open(func.formatUrl(row.jobServerUrl))
- },
- handleSync () {
- this.$confirm('确定进行数据双向同步?', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- })
- .then(() => {
- return sync()
- })
- .then(() => {
- this.onLoad(this.page)
- this.$message({
- type: 'success',
- message: '操作成功!',
- })
- })
- },
- beforeOpen (done, type) {
- if (['edit', 'view'].includes(type)) {
- getDetail(this.form.id).then(res => {
- this.form = res.data.data
- })
- }
- done()
- },
- searchReset () {
- this.query = {}
- this.onLoad(this.page)
- },
- searchChange (params, done) {
- this.query = params
- this.page.currentPage = 1
- this.onLoad(this.page, params)
- done()
- },
- selectionChange (list) {
- this.selectionList = list
- },
- selectionClear () {
- this.selectionList = []
- this.$refs.crud.toggleSelection()
- },
- currentChange (currentPage) {
- this.page.currentPage = currentPage
- },
- sizeChange (pageSize) {
- this.page.pageSize = pageSize
- },
- refreshChange () {
- this.onLoad(this.page, this.query)
- },
- onLoad (page) {
- this.loading = true
-
- const { jobServerName, jobAppName } = this.query
-
- let values = {
- jobServerName_like: jobServerName,
- jobAppName_like: jobAppName,
- }
-
- getList(page.currentPage, page.pageSize, values).then(res => {
- const data = res.data.data
- this.page.total = data.total
- this.data = data.records
- this.loading = false
- this.selectionClear()
- })
- },
- },
-}
-</script>
-
-<style scoped lang="scss"></style>
diff --git a/applications/drone-command/src/views/job/jobstatistics.vue b/applications/drone-command/src/views/job/jobstatistics.vue
deleted file mode 100644
index 3689297..0000000
--- a/applications/drone-command/src/views/job/jobstatistics.vue
+++ /dev/null
@@ -1,14 +0,0 @@
-
-<template>
- <TaskTop />
- <TaskIntermediateContent />
-</template>
-<script setup>
-import TaskTop from "@/views/job/components/TaskTop/TaskTop.vue"
-import TaskIntermediateContent from "@/views/job/components/TaskIntermediateContent/TaskIntermediateContent.vue"
-import { ref } from 'vue';
-const changeKey = ref(0)
-provide('changeKey', changeKey)
-</script>
-
-<style scoped lang="scss"></style>
diff --git a/packages/constants/package.json b/packages/constants/package.json
index 72630ba..82b4ef2 100644
--- a/packages/constants/package.json
+++ b/packages/constants/package.json
@@ -4,5 +4,11 @@
"private": true,
"description": "常量",
"main": "index.js",
- "license": "ISC"
+ "license": "ISC",
+ "peerDependencies": {
+ "cesium": "catalog:"
+ },
+ "devDependencies": {
+ "cesium": "catalog:"
+ }
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e24baf1..1189736 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -854,7 +854,11 @@
packages/components: {}
- packages/constants: {}
+ packages/constants:
+ devDependencies:
+ cesium:
+ specifier: 'catalog:'
+ version: 1.126.0
packages/hooks:
dependencies:
@@ -13590,30 +13594,30 @@
- '@vue/composition-api'
- vue
- '@wangeditor-next/basic-modules@1.5.47(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)':
+ '@wangeditor-next/basic-modules@1.5.47(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.throttle@4.1.1)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)':
dependencies:
- '@wangeditor-next/core': 1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
- dom7: 3.0.0
+ '@wangeditor-next/core': 1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)
+ dom7: 4.0.6
is-url: 1.2.4
lodash.throttle: 4.1.1
- nanoid: 3.3.11
- slate: 0.72.8
+ nanoid: 5.1.6
+ slate: 0.82.1
snabbdom: 3.6.3
- '@wangeditor-next/code-highlight@1.3.43(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(dom7@4.0.6)(slate@0.82.1)(snabbdom@3.6.3)':
+ '@wangeditor-next/code-highlight@1.3.43(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(slate@0.82.1)(snabbdom@3.6.3)':
dependencies:
- '@wangeditor-next/core': 1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
+ '@wangeditor-next/core': 1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)
dom7: 4.0.6
prismjs: 1.30.0
slate: 0.82.1
snabbdom: 3.6.3
- '@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)':
+ '@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)':
dependencies:
'@types/event-emitter': 0.3.5
'@uppy/core': 2.3.4
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
- dom7: 3.0.0
+ dom7: 4.0.6
event-emitter: 0.3.5
html-void-elements: 3.0.0
i18next: 23.16.8
@@ -13624,9 +13628,9 @@
lodash.foreach: 4.5.0
lodash.throttle: 4.1.1
lodash.toarray: 4.4.0
- nanoid: 3.3.11
+ nanoid: 5.1.6
scroll-into-view-if-needed: 3.1.0
- slate: 0.72.8
+ slate: 0.82.1
slate-history: 0.109.0(slate@0.82.1)
snabbdom: 3.6.3
@@ -13634,13 +13638,13 @@
dependencies:
'@uppy/core': 2.3.4
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
- '@wangeditor-next/basic-modules': 1.5.47(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
- '@wangeditor-next/code-highlight': 1.3.43(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(dom7@4.0.6)(slate@0.82.1)(snabbdom@3.6.3)
- '@wangeditor-next/core': 1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
- '@wangeditor-next/list-module': 1.1.52(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(dom7@4.0.6)(slate@0.82.1)(snabbdom@3.6.3)
- '@wangeditor-next/table-module': 1.6.60(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.debounce@4.0.8)(lodash.throttle@4.1.1)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)
- '@wangeditor-next/upload-image-module': 1.1.50(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor-next/basic-modules@1.5.47(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.throttle@4.1.1)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.foreach@4.5.0)(slate@0.82.1)(snabbdom@3.6.3)
- '@wangeditor-next/video-module': 1.3.51(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(dom7@4.0.6)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)
+ '@wangeditor-next/basic-modules': 1.5.47(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.throttle@4.1.1)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)
+ '@wangeditor-next/code-highlight': 1.3.43(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(slate@0.82.1)(snabbdom@3.6.3)
+ '@wangeditor-next/core': 1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)
+ '@wangeditor-next/list-module': 1.1.52(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(slate@0.82.1)(snabbdom@3.6.3)
+ '@wangeditor-next/table-module': 1.6.60(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.debounce@4.0.8)(lodash.throttle@4.1.1)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)
+ '@wangeditor-next/upload-image-module': 1.1.50(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor-next/basic-modules@1.5.47(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.throttle@4.1.1)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.foreach@4.5.0)(slate@0.82.1)(snabbdom@3.6.3)
+ '@wangeditor-next/video-module': 1.3.51(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)
dom7: 4.0.6
is-hotkey: 0.2.0
lodash.camelcase: 4.3.0
@@ -13653,16 +13657,16 @@
slate: 0.82.1
snabbdom: 3.6.3
- '@wangeditor-next/list-module@1.1.52(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(dom7@4.0.6)(slate@0.82.1)(snabbdom@3.6.3)':
+ '@wangeditor-next/list-module@1.1.52(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(slate@0.82.1)(snabbdom@3.6.3)':
dependencies:
- '@wangeditor-next/core': 1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
+ '@wangeditor-next/core': 1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)
dom7: 4.0.6
slate: 0.82.1
snabbdom: 3.6.3
- '@wangeditor-next/table-module@1.6.60(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.debounce@4.0.8)(lodash.throttle@4.1.1)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)':
+ '@wangeditor-next/table-module@1.6.60(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.debounce@4.0.8)(lodash.throttle@4.1.1)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)':
dependencies:
- '@wangeditor-next/core': 1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
+ '@wangeditor-next/core': 1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)
dom7: 4.0.6
lodash.debounce: 4.0.8
lodash.throttle: 4.1.1
@@ -13670,22 +13674,22 @@
slate: 0.82.1
snabbdom: 3.6.3
- '@wangeditor-next/upload-image-module@1.1.50(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor-next/basic-modules@1.5.47(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.throttle@4.1.1)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.foreach@4.5.0)(slate@0.82.1)(snabbdom@3.6.3)':
+ '@wangeditor-next/upload-image-module@1.1.50(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor-next/basic-modules@1.5.47(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.throttle@4.1.1)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.foreach@4.5.0)(slate@0.82.1)(snabbdom@3.6.3)':
dependencies:
'@uppy/core': 2.3.4
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
- '@wangeditor-next/basic-modules': 1.5.47(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
- '@wangeditor-next/core': 1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
+ '@wangeditor-next/basic-modules': 1.5.47(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.throttle@4.1.1)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)
+ '@wangeditor-next/core': 1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)
dom7: 4.0.6
lodash.foreach: 4.5.0
slate: 0.82.1
snabbdom: 3.6.3
- '@wangeditor-next/video-module@1.3.51(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3))(dom7@4.0.6)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)':
+ '@wangeditor-next/video-module@1.3.51(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor-next/core@1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)':
dependencies:
'@uppy/core': 2.3.4
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
- '@wangeditor-next/core': 1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
+ '@wangeditor-next/core': 1.7.45(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.6)(slate@0.82.1)(snabbdom@3.6.3)
dom7: 4.0.6
nanoid: 5.1.6
slate: 0.82.1
--
Gitblit v1.9.3