Merge remote-tracking branch 'origin/master'
# Conflicts:
# applications/task-work-order/src/views/orderView/flyingHand/index.vue
54 files modified
16 files added
| | |
| | | # @Author : yuan |
| | | # @Date : 2026-01-07 14:58:30 |
| | | # @LastEditors : yuan |
| | | # @LastEditTime : 2026-01-23 17:51:43 |
| | | # @LastEditTime : 2026-01-26 17:29:11 |
| | | # @FilePath : \applications\drone-command\env\.env.development |
| | | # @Description : |
| | | # Copyright 2026 OBKoro1, All Rights Reserved. |
| | |
| | | |
| | | #开发环境代理地址(推荐本地新建文件 .env.development.local 来进行覆盖) |
| | | # VITE_APP_URL = https://wrj.shuixiongit.com/api |
| | | VITE_APP_URL= http://192.168.1.33 |
| | | VITE_APP_URL= http://192.168.1.204 |
| | | |
| | | #新大屏地址 |
| | | VITE_APP_DASHBOARD_URL = 'https://wrj.shuixiongit.com/command-center-dashboard/' |
| | |
| | | * @Author : yuan |
| | | * @Date : 2026-01-09 11:14:04 |
| | | * @LastEditors : yuan |
| | | * @LastEditTime : 2026-01-09 11:35:14 |
| | | * @LastEditTime : 2026-01-26 19:02:07 |
| | | * @FilePath : \applications\drone-command\src\api\dataCockpit\index.js |
| | | * @Description : |
| | | * Copyright 2026 OBKoro1, All Rights Reserved. |
| | |
| | | }) |
| | | } |
| | | |
| | | // ???? |
| | | export const alarmFavoriteSaveApi = (data) => { |
| | | return request({ |
| | | url: '/drone-fw/record/fwAlarmFavorite/save', |
| | | method: 'post', |
| | | data |
| | | }) |
| | | } |
| | | |
| | | // ?????? |
| | | export const alarmFavoriteRemoveApi = (ids) => { |
| | | const formattedIds = Array.isArray(ids) ? ids.join(',') : ids |
| | | return request({ |
| | | url: '/drone-fw/record/fwAlarmFavorite/cancelFavorite', |
| | | method: 'post', |
| | | params: { |
| | | ids: formattedIds |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // 数据驾驶舱地图聚合 |
| | | export const cockpitAggregationApi = () => { |
| | | export const cockpitAggregationApi = (params) => { |
| | | return request({ |
| | | url: '/drone-fw/device/fwDevice/statisticalDeviceOut', |
| | | method: 'get' |
| | | method: 'get', |
| | | params |
| | | }) |
| | | } |
| | | |
| | |
| | | <div class="map-shell"> |
| | | <CommonCesiumMap ref="mapRef" class="command-cesium map-container" :dom-id="props.containerId" :active="true" |
| | | :flat-mode="false" :terrain="true" :layer-mode="4" :contour="false" :boundary="false" |
| | | :show-admin-boundary="true" :zoom-to-boundary="true" :enable-stage-emit="true" :cluster-height="100000" |
| | | @ready="handleMapReady" @stage-change="handleStageChange" /> |
| | | :show-admin-boundary="true" :zoom-to-boundary="true" :enable-stage-emit="true" |
| | | :cluster-height="CLUSTER_HEIGHT" :detail-height="DETAIL_HEIGHT" @ready="handleMapReady" |
| | | @stage-change="handleStageChange" /> |
| | | <div v-if="props.showLayerControl" class="layer-control-root" :class="{ collapsed: props.leftCollapsed }"> |
| | | <div class="layer-control-wrap" ref="layerWrapRef"> |
| | | <div class="layer-control" @click="toggleLayerPanel"> |
| | |
| | | createRadialGradientMaterial, |
| | | getTexturedVertexFormat, |
| | | } from './device-map-materials' |
| | | |
| | | const CLUSTER_HEIGHT = 100000 |
| | | const DETAIL_HEIGHT = 10000 |
| | | |
| | | const props = defineProps({ |
| | | onlineDevices: { |
| | |
| | | const latitude = Number(latitudeRaw) |
| | | if (!Number.isFinite(longitude) || !Number.isFinite(latitude)) return null |
| | | return { longitude, latitude } |
| | | } |
| | | |
| | | const getDeviceRange = item => { |
| | | if (!item) return null |
| | | const rawRange = item.effectiveRangeKm ?? item.range ?? item.coverRadiusM |
| | | const range = Number(rawRange) |
| | | if (!Number.isFinite(range) || range <= 0) return null |
| | | return range |
| | | } |
| | | |
| | | const ensureCockpitPrimitiveLayer = () => { |
| | |
| | | if (aggregationSource) aggregationSource.show = visible |
| | | } |
| | | |
| | | const setDroneVisibility = visible => { |
| | | if (droneTrackBillboardCollection) droneTrackBillboardCollection.show = visible |
| | | if (droneTrackPolylineCollection) droneTrackPolylineCollection.show = visible |
| | | if (!visible && selectedTargetType.value === 'drone') { |
| | | closePopup() |
| | | } |
| | | } |
| | | const getStageByHeight = height => { |
| | | if (height == null) return 'detail' |
| | | if (height >= CLUSTER_HEIGHT) return 'cluster' |
| | | if (height <= DETAIL_HEIGHT) return 'detail' |
| | | return 'mid' |
| | | } |
| | | |
| | | const ensureCountyCenterMap = () => { |
| | | if (countyCenterMap.size) return |
| | | const geojson = JSON.parse(jaGeojsonRaw) |
| | |
| | | }) |
| | | } |
| | | |
| | | const buildSimulatedTrackPoints = base => { |
| | | ensureCountyCenterMap() |
| | | const anchor = base || { longitude: 116.397, latitude: 39.908 } |
| | | const offsets = [ |
| | | [0, 0, 120], |
| | | [0.02, 0.012, 150], |
| | | [0.04, 0.006, 180], |
| | | [0.06, -0.008, 200], |
| | | [0.03, -0.02, 160], |
| | | [0.0, -0.015, 140], |
| | | [-0.02, -0.005, 120], |
| | | [-0.01, 0.01, 130], |
| | | const buildSimulatedTrackPoints = () => { |
| | | return [ |
| | | { |
| | | longitude: 114.963191, |
| | | latitude: 27.136716, |
| | | height: 120 |
| | | }, |
| | | { |
| | | longitude:114.957308, |
| | | latitude: 27.138452, |
| | | height: 120 |
| | | }, |
| | | { |
| | | longitude:114.952, |
| | | latitude: 27.136317, |
| | | height: 120 |
| | | }, |
| | | { |
| | | longitude:114.949293, |
| | | latitude: 27.133864, |
| | | height: 120 |
| | | }, |
| | | { |
| | | longitude:114.944666, |
| | | latitude: 27.130526, |
| | | height: 120 |
| | | }, |
| | | { |
| | | longitude:114.945909, |
| | | latitude:27.127845, |
| | | height: 120 |
| | | }, |
| | | { |
| | | longitude:114.962974, |
| | | latitude:27.136242, |
| | | height: 120 |
| | | }, |
| | | ] |
| | | return offsets.map(item => ({ |
| | | longitude: anchor.longitude + item[0], |
| | | latitude: anchor.latitude + item[1], |
| | | height: item[2], |
| | | })) |
| | | } |
| | | |
| | | |
| | |
| | | const renderSimulatedDroneTrack = () => { |
| | | if (!viewer) return |
| | | clearDroneTrackEntities() |
| | | ensureCountyCenterMap() |
| | | ensureDroneTrackCollections() |
| | | droneTrackBillboardCollection.show = detailVisible.value |
| | | droneTrackPolylineCollection.show = detailVisible.value |
| | | droneTrackRuntime = [] |
| | | const centers = Array.from(countyCenterMap.entries()) |
| | | const baseCenters = centers.length |
| | | ? centers.slice(0, 4) |
| | | : [['默认区域', { longitude: 116.397, latitude: 39.908 }]] |
| | | const baseCenters = [['默认区域', { longitude:114.958541, latitude: 27.121917 }]] |
| | | const segmentDuration = 6 |
| | | const baseTrackColor = Cesium.Color.fromCssColorString('red') |
| | | baseCenters.forEach(([centerName, center], trackIndex) => { |
| | |
| | | }) |
| | | const droneId = `drone-track-${trackIndex}` |
| | | const billboard = droneTrackBillboardCollection.add({ |
| | | position: positions[0], |
| | | position: positions[positions.length - 1], |
| | | image: droneIcon, |
| | | width: 36, |
| | | height: 36, |
| | |
| | | const position = getDevicePosition(item) |
| | | if (!position) return |
| | | const entityId = `online-device-${item.id ?? index}-${index}` |
| | | addDeviceRings(position, ringFillInstancesByStyle, ringOutlineInstancesByStyle) |
| | | const rangeMeters = getDeviceRange(item) |
| | | addDeviceRings(position, ringFillInstancesByStyle, ringOutlineInstancesByStyle, rangeMeters) |
| | | const billboard = deviceBillboardCollection.add({ |
| | | position: Cesium.Cartesian3.fromDegrees(position.longitude, position.latitude, 0), |
| | | image: equipmentIcon, |
| | |
| | | ringFillInstancesByStyle.forEach((instances, index) => { |
| | | if (!instances.length) return |
| | | const ring = RING_STYLES[index] |
| | | const alpha = ring.alpha ?? 0.64 |
| | | const innerRatio = |
| | | typeof ring.innerRatio === 'number' |
| | | ? ring.innerRatio |
| | | : ring.inner && ring.outer |
| | | ? Math.min(Math.max(ring.inner / ring.outer, 0), 0.9) |
| | | : 0 |
| | | const material = createRadialGradientMaterial( |
| | | Cesium.Color.fromCssColorString(ring.gradient[0]).withAlpha(0.64), |
| | | Cesium.Color.fromCssColorString(ring.gradient[1]).withAlpha(0.64) |
| | | Cesium.Color.fromCssColorString(ring.gradient[0]).withAlpha(alpha), |
| | | Cesium.Color.fromCssColorString(ring.gradient[1]).withAlpha(alpha), |
| | | { |
| | | gamma: 1.7, |
| | | innerCutoff: innerRatio, |
| | | } |
| | | ) |
| | | const primitive = new Cesium.GroundPrimitive({ |
| | | geometryInstances: instances, |
| | |
| | | const renderDefenseZones = zones => { |
| | | if (!viewer) return |
| | | clearDefenseZoneEntities() |
| | | const result = buildZonePrimitives(zones, '#19D266', '#2AEDBF', '#012B11') |
| | | const result = buildZonePrimitives(zones, '#72F3FF', '#72F3FF', '#0A7C88') |
| | | defenseZonePrimitive = result.primitive |
| | | defenseZoneOutlinePrimitive = result.outlinePrimitive |
| | | if (defenseZonePrimitive) defenseZonePrimitive.show = detailVisible.value |
| | |
| | | const renderPartitions = zones => { |
| | | if (!viewer) return |
| | | clearPartitionEntities() |
| | | const result = buildZonePrimitives(zones, '#FFCD2A', '#FFC609', '#583300') |
| | | const result = buildZonePrimitives(zones, '#FFD772', '#FFD772', '#A86B00') |
| | | partitionPrimitive = result.primitive |
| | | partitionOutlinePrimitive = result.outlinePrimitive |
| | | if (partitionPrimitive) partitionPrimitive.show = detailVisible.value |
| | |
| | | width: 66.73, |
| | | height: 43, |
| | | verticalOrigin: Cesium.VerticalOrigin.BOTTOM, |
| | | heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, |
| | | // disableDepthTestDistance: Number.POSITIVE_INFINITY, |
| | | }, |
| | | label: { |
| | | text: `${count}`, |
| | |
| | | |
| | | pixelOffset: new Cesium.Cartesian2(0, -35), |
| | | disableDepthTestDistance: Number.POSITIVE_INFINITY, |
| | | heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, |
| | | }, |
| | | }) |
| | | }) |
| | |
| | | |
| | | const loadAggregation = async () => { |
| | | try { |
| | | const res = await cockpitAggregationApi() |
| | | const res = await cockpitAggregationApi({ |
| | | effectiveRangeKmIsNotNull: 1 |
| | | }) |
| | | renderAggregation(res?.data?.data ?? []) |
| | | } catch (error) { |
| | | renderAggregation([]) |
| | |
| | | const showCluster = stage === 'cluster' |
| | | setClusterVisibility(showCluster) |
| | | setDetailVisibility(!showCluster) |
| | | setDroneVisibility(!showCluster) |
| | | } |
| | | |
| | | const handleMapReady = ({ viewer: mapViewer }) => { |
| | | viewer = mapViewer |
| | | ensureCockpitPrimitiveLayer() |
| | | const height = viewer?.camera?.positionCartographic?.height |
| | | const stage = height != null && height >= 100000 ? 'cluster' : 'detail' |
| | | const stage = getStageByHeight(height) |
| | | updateStageDisplay(stage) |
| | | renderDeviceEntities(props.onlineDevices) |
| | | loadDefenseZones() |
| | |
| | | import * as Cesium from 'cesium' |
| | | |
| | | export const RING_STYLES = [{ inner: 0, outer: 2000, gradient: ['#FF361C', '#360B00'] }] |
| | | export const RING_STYLES = [ |
| | | { |
| | | inner: 0, |
| | | outer: 2000, |
| | | gradient: ['#FF6A57', '#A11806'], |
| | | alpha: 0.42, |
| | | outlineAlpha: 0.85, |
| | | innerRatio: 0.12, |
| | | }, |
| | | ] |
| | | |
| | | export const MATERIAL_TYPE = 'RadialGradientMaterial' |
| | | export const DRONE_TRACK_MATERIAL_TYPE = 'DroneTrackFlowMaterial' |
| | |
| | | uniforms: { |
| | | color1: new Cesium.Color(1.0, 1.0, 1.0, 1.0), |
| | | color2: new Cesium.Color(0.0, 0.0, 0.0, 1.0), |
| | | gamma: 1.7, |
| | | innerCutoff: 0.0, |
| | | }, |
| | | source: ` |
| | | uniform vec4 color1; |
| | | uniform vec4 color2; |
| | | uniform float gamma; |
| | | uniform float innerCutoff; |
| | | |
| | | czm_material czm_getMaterial(czm_materialInput materialInput) { |
| | | czm_material material = czm_getDefaultMaterial(materialInput); |
| | | vec2 st = materialInput.st - vec2(0.5); |
| | | float t = clamp(length(st) * 2.0, 0.0, 1.0); |
| | | vec4 color = mix(color1, color2, t); |
| | | float ramp = smoothstep(innerCutoff, 1.0, t); |
| | | float shaped = pow(t, gamma); |
| | | float alpha = color.a * ramp * shaped; |
| | | material.diffuse = color.rgb; |
| | | material.alpha = color.a; |
| | | material.alpha = alpha; |
| | | return material; |
| | | } |
| | | `, |
| | |
| | | }) |
| | | } |
| | | |
| | | export const createRadialGradientMaterial = (color1, color2) => { |
| | | export const createRadialGradientMaterial = (color1, color2, options = {}) => { |
| | | registerRadialGradientMaterial() |
| | | return Cesium.Material.fromType(MATERIAL_TYPE, { color1, color2 }) |
| | | return Cesium.Material.fromType(MATERIAL_TYPE, { color1, color2, ...(options || {}) }) |
| | | } |
| | | |
| | | export const createDroneTrackMaterial = options => { |
| | |
| | | return positions |
| | | } |
| | | |
| | | export const addDeviceRings = (center, ringFillInstancesByStyle, ringOutlineInstancesByStyle) => { |
| | | export const addDeviceRings = (center, ringFillInstancesByStyle, ringOutlineInstancesByStyle, rangeMeters) => { |
| | | if (!ringFillInstancesByStyle) return |
| | | const centerPosition = Cesium.Cartesian3.fromDegrees(center.longitude, center.latitude, 0) |
| | | const vertexFormat = getTexturedVertexFormat() |
| | | RING_STYLES.forEach((ring, index) => { |
| | | if (!ringFillInstancesByStyle[index]) return |
| | | const outer = Number.isFinite(rangeMeters) && rangeMeters > 0 ? rangeMeters : ring.outer |
| | | ringFillInstancesByStyle[index].push( |
| | | new Cesium.GeometryInstance({ |
| | | geometry: new Cesium.EllipseGeometry({ |
| | | center: centerPosition, |
| | | semiMajorAxis: ring.outer, |
| | | semiMinorAxis: ring.outer, |
| | | semiMajorAxis: outer, |
| | | semiMinorAxis: outer, |
| | | vertexFormat, |
| | | }), |
| | | }) |
| | |
| | | if (!ringOutlineInstancesByStyle) return |
| | | RING_STYLES.forEach((ring, index) => { |
| | | if (!ringOutlineInstancesByStyle[index]) return |
| | | const positions = buildCirclePositions(center, ring.outer) |
| | | const outer = Number.isFinite(rangeMeters) && rangeMeters > 0 ? rangeMeters : ring.outer |
| | | const positions = buildCirclePositions(center, outer) |
| | | const outlineAlpha = typeof ring.outlineAlpha === 'number' ? ring.outlineAlpha : 0.8 |
| | | ringOutlineInstancesByStyle[index].push( |
| | | new Cesium.GeometryInstance({ |
| | | geometry: new Cesium.GroundPolylineGeometry({ |
| | |
| | | }), |
| | | attributes: { |
| | | color: Cesium.ColorGeometryInstanceAttribute.fromColor( |
| | | Cesium.Color.fromCssColorString(ring.gradient[0]).withAlpha(0.8) |
| | | Cesium.Color.fromCssColorString(ring.gradient[0]).withAlpha(outlineAlpha) |
| | | ), |
| | | }, |
| | | }) |
| | |
| | | 'iconfont icon-msnui-360', |
| | | 'iconfont icon-iframe', |
| | | 'iconfont icon-huanyingye', |
| | | 'iconfont_com icon-a-1', |
| | | 'iconfont_com icon-a-4', |
| | | 'iconfont_com icon-a-3', |
| | | 'iconfont_com icon-a-2', |
| | | 'iconfont_com icon-a-6', |
| | | 'iconfont_com icon-a-5', |
| | | 'iconfont_com icon-Frame', |
| | | ], |
| | | }, |
| | | ]; |
| | |
| | | @import './mapEdit.scss'; |
| | | |
| | | @import './common/cockpit.scss'; |
| | | @import './customFont.scss'; |
| | | |
| | | a { |
| | | text-decoration: none; |
| New file |
| | |
| | | @font-face { |
| | | font-family: "iconfont_com"; |
| | | /* Project id 5099981 */ |
| | | src: url('//at.alicdn.com/t/c/font_5099981_ysrl5v42ycd.woff2?t=1769414361186') format('woff2'), |
| | | url('//at.alicdn.com/t/c/font_5099981_ysrl5v42ycd.woff?t=1769414361186') format('woff'), |
| | | url('//at.alicdn.com/t/c/font_5099981_ysrl5v42ycd.ttf?t=1769414361186') format('truetype'), |
| | | url('//at.alicdn.com/t/c/font_5099981_ysrl5v42ycd.svg?t=1769414361186#iconfont') format('svg'); |
| | | } |
| | | |
| | | .iconfont_com { |
| | | font-family: "iconfont_com" !important; |
| | | font-size: 16px; |
| | | font-style: normal; |
| | | -webkit-font-smoothing: antialiased; |
| | | -moz-osx-font-smoothing: grayscale; |
| | | } |
| | | |
| | | .icon-a-1:before { |
| | | content: "\e609"; |
| | | } |
| | | |
| | | .icon-a-4:before { |
| | | content: "\e604"; |
| | | } |
| | | |
| | | .icon-a-3:before { |
| | | content: "\e605"; |
| | | } |
| | | |
| | | .icon-a-2:before { |
| | | content: "\e606"; |
| | | } |
| | | |
| | | .icon-a-6:before { |
| | | content: "\e607"; |
| | | } |
| | | |
| | | .icon-a-5:before { |
| | | content: "\e608"; |
| | | } |
| | | |
| | | .icon-Frame:before { |
| | | content: "\e602"; |
| | | } |
| | | |
| | | .icon-a-:before { |
| | | content: "\e601"; |
| | | } |
| | | |
| | | .icon-MenuIcon-biaozhunshujutuisong-heise:before { |
| | | content: "\e611"; |
| | | } |
| | | |
| | | .icon-MenuIcon-xuncharenwujiankong-heise:before { |
| | | content: "\e614"; |
| | | } |
| | | |
| | | .icon-MenuIcon-shebeirizhi-heise:before { |
| | | content: "\e615"; |
| | | } |
| | |
| | | |
| | | |
| | | ## 分页 |
| | | ## 重点关注 |
| | | |
| | | |
| | | **接口地址**:`/blade-log/log/operationLog/page` |
| | | **接口地址**:`/drone-fw/record/fwAlarmFavorite/save` |
| | | |
| | | |
| | | **请求方式**:`GET` |
| | | **请求方式**:`POST` |
| | | |
| | | |
| | | **请求数据类型**:`application/x-www-form-urlencoded` |
| | | **请求数据类型**:`application/json` |
| | | |
| | | |
| | | **响应数据类型**:`*/*` |
| | | |
| | | |
| | | **接口描述**:<p>分页</p> |
| | | **接口描述**:<p>传入fwAlarmFavorite</p> |
| | | |
| | | |
| | | |
| | | **请求示例**: |
| | | |
| | | |
| | | ```javascript |
| | | { |
| | | "alarmRecordId": 0 |
| | | } |
| | | ``` |
| | | |
| | | |
| | | **请求参数**: |
| | |
| | | |
| | | | 参数名称 | 参数说明 | 请求类型 | 是否必须 | 数据类型 | schema | |
| | | | -------- | -------- | ----- | -------- | -------- | ------ | |
| | | |createBy|操作人|query|false|string|| |
| | | |current|当前页|query|false|integer(int32)|| |
| | | |endTime|结束时间|query|false|string|| |
| | | |size|每页的数量|query|false|integer(int32)|| |
| | | |startTime|开始时间|query|false|string|| |
| | | |title|日志类型(0菜单/1按钮)|query|false|string|| |
| | | |fwAlarmFavorite|告警记录关注表|body|true|FwAlarmFavorite对象|FwAlarmFavorite对象| |
| | | |  alarmRecordId|告警记录id||false|integer(int64)|| |
| | | |
| | | |
| | | **响应状态**: |
| | |
| | | |
| | | | 状态码 | 说明 | schema | |
| | | | -------- | -------- | ----- | |
| | | |200|OK|R«IPage«OperationLogVO»»| |
| | | |200|OK|R| |
| | | |201|Created|| |
| | | |401|Unauthorized|| |
| | | |403|Forbidden|| |
| | | |404|Not Found|| |
| | |
| | | | 参数名称 | 参数说明 | 类型 | schema | |
| | | | -------- | -------- | ----- |----- | |
| | | |code|状态码|integer(int32)|integer(int32)| |
| | | |data|承载数据|IPage«OperationLogVO»|IPage«OperationLogVO»| |
| | | |  current||integer(int64)|| |
| | | |  pages||integer(int64)|| |
| | | |  records||array|OperationLogVO| |
| | | |    createBy|操作人|string|| |
| | | |    remoteIp|客户端IP|string|| |
| | | |    requestUri|请求地址|string|| |
| | | |    title|日志标题|string|| |
| | | |    type|日志类型(0菜单/1按钮)|string|| |
| | | |    userAgent|客户端|string|| |
| | | |  size||integer(int64)|| |
| | | |  total||integer(int64)|| |
| | | |data|承载数据|object|| |
| | | |msg|返回消息|string|| |
| | | |success|是否成功|boolean|| |
| | | |
| | |
| | | ```javascript |
| | | { |
| | | "code": 0, |
| | | "data": { |
| | | "current": 0, |
| | | "pages": 0, |
| | | "records": [ |
| | | { |
| | | "createBy": "", |
| | | "remoteIp": "", |
| | | "requestUri": "", |
| | | "title": "", |
| | | "type": "", |
| | | "userAgent": "" |
| | | } |
| | | ], |
| | | "size": 0, |
| | | "total": 0 |
| | | }, |
| | | "data": {}, |
| | | "msg": "", |
| | | "success": true |
| | | } |
| | | ``` |
| | | |
| | | |
| | | |
| | | |
| | | ## 取消关注 |
| | | |
| | | |
| | | **接口地址**:`/drone-fw/record/fwAlarmFavorite/remove` |
| | | |
| | | |
| | | **请求方式**:`POST` |
| | | |
| | | |
| | | **请求数据类型**:`application/json` |
| | | |
| | | |
| | | **响应数据类型**:`*/*` |
| | | |
| | | |
| | | **接口描述**:<p>传入ids</p> |
| | | |
| | | |
| | | |
| | | **请求参数**: |
| | | |
| | | |
| | | **请求参数**: |
| | | |
| | | |
| | | | 参数名称 | 参数说明 | 请求类型 | 是否必须 | 数据类型 | schema | |
| | | | -------- | -------- | ----- | -------- | -------- | ------ | |
| | | |ids|主键集合|query|true|string|| |
| | | |
| | | |
| | | **响应状态**: |
| | | |
| | | |
| | | | 状态码 | 说明 | schema | |
| | | | -------- | -------- | ----- | |
| | | |200|OK|R| |
| | | |201|Created|| |
| | | |401|Unauthorized|| |
| | | |403|Forbidden|| |
| | | |404|Not Found|| |
| | | |
| | | |
| | | **响应参数**: |
| | | |
| | | |
| | | | 参数名称 | 参数说明 | 类型 | schema | |
| | | | -------- | -------- | ----- |----- | |
| | | |code|状态码|integer(int32)|integer(int32)| |
| | | |data|承载数据|object|| |
| | | |msg|返回消息|string|| |
| | | |success|是否成功|boolean|| |
| | | |
| | | |
| | | **响应示例**: |
| | | ```javascript |
| | | { |
| | | "code": 0, |
| | | "data": {}, |
| | | "msg": "", |
| | | "success": true |
| | | } |
| | |
| | | <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)"> |
| | | <div class="command-table-content command-table-content-bg"> |
| | | <el-table class="command-table" :data="list" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="46" /> |
| | | <el-table-column type="index" show-overflow-tooltip width="64" label="序号" /> |
| | | <el-table-column prop="deviceName" show-overflow-tooltip width="130" label="设备名称" /> |
| | | <el-table-column prop="deviceType" show-overflow-tooltip width="130" label="设备类型"> |
| | |
| | | </el-table-column> |
| | | <el-table-column prop="source" show-overflow-tooltip width="112" label="来源" /> |
| | | <el-table-column prop="purpose" show-overflow-tooltip width="206" label="用途" /> |
| | | <el-table-column prop="belongDeptName" show-overflow-tooltip width="124" label="所属部门" /> |
| | | <el-table-column prop="belongDeptName" show-overflow-tooltip label="所属部门" /> |
| | | <el-table-column prop="charger" show-overflow-tooltip width="100" label="负责人" /> |
| | | <el-table-column prop="yxzt" show-overflow-tooltip width="116" label="运行状态"> |
| | | <template v-slot="{ row }"> |
| | |
| | | } |
| | | |
| | | .legend-color.defense { |
| | | background: radial-gradient(50% 50% at 50% 50%, #2aedbf 0%, #012b11 100%); |
| | | border: 1px solid #19d266; |
| | | background: radial-gradient(50% 50% at 50% 50%, rgba(114, 243, 255, 0.45) 0%, rgba(10, 124, 136, 0.55) 100%); |
| | | border: 1px solid rgba(114, 243, 255, 0.85); |
| | | } |
| | | |
| | | .legend-color.partition { |
| | | background: radial-gradient(50% 50% at 50% 50%, #ffc609 0%, #583300 100%); |
| | | border: 1px solid #ffcd2a; |
| | | background: radial-gradient(50% 50% at 50% 50%, rgba(255, 215, 114, 0.5) 0%, rgba(168, 107, 0, 0.6) 100%); |
| | | border: 1px solid rgba(255, 215, 114, 0.9); |
| | | } |
| | | |
| | | .legend-icon { |
| | |
| | | * @Author : yuan |
| | | * @Date : 2026-01-08 09:29:07 |
| | | * @LastEditors : yuan |
| | | * @LastEditTime : 2026-01-19 11:31:09 |
| | | * @LastEditTime : 2026-01-26 09:59:52 |
| | | * @FilePath : \applications\drone-command\src\views\dataCockpit\components\RealWarning.vue |
| | | * @Description : |
| | | * Copyright 2026 OBKoro1, All Rights Reserved. |
| | |
| | | :data="item" |
| | | @signal="() => handleAction('signal', item)" |
| | | @counter="() => handleAction('counter', item)" |
| | | @favorite="() => console.log('收藏', item.id)" |
| | | @favorite="() => handleFavorite(item)" |
| | | /> |
| | | </div> |
| | | </div> |
| | |
| | | |
| | | <script setup> |
| | | import RealTemplate from './templateComponents/RealTemplate.vue' |
| | | import { alarmLogApi, interferenceAndExpulsionApi } from '@/api/dataCockpit' |
| | | import { |
| | | alarmLogApi, |
| | | alarmFavoriteRemoveApi, |
| | | alarmFavoriteSaveApi, |
| | | interferenceAndExpulsionApi |
| | | } from '@/api/dataCockpit' |
| | | import { onMounted, ref } from 'vue' |
| | | import EmptyState from './EmptyState.vue' |
| | | import { ElMessage } from 'element-plus' |
| | |
| | | counter: '诱导驱离' |
| | | } |
| | | |
| | | |
| | | const getAlarmRecordId = (item) => item?.alarmRecordId ?? item?.id |
| | | const getFavoriteId = (item) => |
| | | item?.favoriteId ?? |
| | | item?.alarmFavoriteId ?? |
| | | item?.fwAlarmFavoriteId ?? |
| | | item?.favoriteRecordId ?? |
| | | getAlarmRecordId(item) |
| | | |
| | | const isFavorited = (item) => { |
| | | const value = item?.favorited ?? item?.isFavorite |
| | | return value === 1 || value === '1' || value === true |
| | | } |
| | | |
| | | const buildPayload = (type, item) => ({ |
| | | counterWay: type === 'signal' ? 1 : type === 'counter' ? 2 : '', |
| | | alarmRecordId: item?.alarmRecordId ?? item?.id |
| | | alarmRecordId: getAlarmRecordId(item) |
| | | }) |
| | | |
| | | const handleAction = async (type, item) => { |
| | |
| | | try { |
| | | const res = await interferenceAndExpulsionApi(buildPayload(type, item)) |
| | | if (res?.data?.success) { |
| | | ElMessage({ type: 'success', message: `${actionText}成功` }) |
| | | ElMessage({ type: 'success', message: actionText + '成功' }) |
| | | await fetchRealWarning() |
| | | } else { |
| | | ElMessage({ type: 'error', message: res?.data?.msg || `${actionText}失败` }) |
| | | ElMessage({ type: 'error', message: res?.data?.msg || actionText + '失败' }) |
| | | } |
| | | } catch (error) { |
| | | ElMessage({ type: 'error', message: `${actionText}失败` }) |
| | | ElMessage({ type: 'error', message: actionText + '失败' }) |
| | | } |
| | | } |
| | | |
| | | const handleFavorite = async (item) => { |
| | | const alarmRecordId = getAlarmRecordId(item) |
| | | if (!alarmRecordId) { |
| | | ElMessage({ type: 'warning', message: '缺少告警记录ID' }) |
| | | return |
| | | } |
| | | const isFavorite = isFavorited(item) |
| | | const actionText = isFavorite ? '取消关注' : '关注' |
| | | try { |
| | | const res = isFavorite |
| | | ? await alarmFavoriteRemoveApi(getFavoriteId(item)) |
| | | : await alarmFavoriteSaveApi({ alarmRecordId }) |
| | | if (res?.data?.success) { |
| | | ElMessage({ type: 'success', message: actionText + '成功' }) |
| | | await fetchRealWarning() |
| | | } else { |
| | | ElMessage({ type: 'error', message: res?.data?.msg || actionText + '失败' }) |
| | | } |
| | | } catch (error) { |
| | | ElMessage({ type: 'error', message: actionText + '失败' }) |
| | | } |
| | | } |
| | | |
| | |
| | | const params = { current: 1, size: 20, alarmType: '1' } |
| | | const res = await alarmLogApi(params) |
| | | const records = res?.data?.data?.records ?? [] |
| | | realWarningData.value = records |
| | | realWarningData.value = records.map((record) => ({ |
| | | ...record, |
| | | isFavorite: |
| | | record?.isFavorite ?? |
| | | (record?.favorited === 1 || record?.favorited === '1') |
| | | })) |
| | | } finally { |
| | | const elapsed = Date.now() - startAt |
| | | if (elapsed < minLoadingMs) { |
| | |
| | | </div> |
| | | <div class="col"> |
| | | <span class="label">有效范围</span> |
| | | {{ data.effectiveRangeKm }}KM |
| | | {{ Number(data.effectiveRangeKm).toFixed(0) }}m |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | class="command-input" |
| | | v-model="formData.effectiveRangeKm" |
| | | :min="0" |
| | | :precision="2" |
| | | :precision="0" |
| | | :step="1" |
| | | :controls="false" |
| | | placeholder="请输入" |
| | | /> |
| | |
| | | |
| | | function formatRange(value) { |
| | | if (value == null || value === '') return '-' |
| | | return `${value}` |
| | | const normalized = normalizeRange(value) |
| | | return normalized == null ? '-' : `${normalized}` |
| | | } |
| | | |
| | | function normalizeRange(value) { |
| | | const numeric = Number(value) |
| | | if (!Number.isFinite(numeric)) return null |
| | | return Math.trunc(numeric) |
| | | } |
| | | |
| | | // 关闭弹框 |
| | |
| | | submitting.value = true |
| | | try { |
| | | const {longitude, latitude} = parseDeployLocation(formData.value.deployLocation) |
| | | const normalizedRange = normalizeRange(formData.value.effectiveRangeKm) |
| | | |
| | | const payload = { |
| | | id: formData.value.id || formData.value.deviceId || undefined, |
| | | effectiveRangeKmIsNotNull: formData.value.effectiveRangeKm ? 1 : 2, |
| | | effectiveRangeKm: formData.value.effectiveRangeKm, |
| | | effectiveRangeKmIsNotNull: normalizedRange != null ? 1 : 2, |
| | | effectiveRangeKm: normalizedRange, |
| | | longitude, |
| | | latitude |
| | | } |
| | | formData.value.effectiveRangeKm = normalizedRange |
| | | delete payload.deviceId |
| | | await detectionRangeSubmitApi(payload) |
| | | |
| | |
| | | current: 1, |
| | | size: 200, |
| | | effectiveRangeKmIsNotNull: 2, |
| | | isTrack: 1 |
| | | }) |
| | | const records = res?.data?.data?.records ?? [] |
| | | deviceOptions.value = records.map(item => ({ |
| | |
| | | watch( |
| | | () => formData.value.effectiveRangeKm, |
| | | value => { |
| | | const normalized = normalizeRange(value) |
| | | if (value != null && normalized == null) { |
| | | formData.value.effectiveRangeKm = null |
| | | return |
| | | } |
| | | if (value != null && normalized !== value) { |
| | | formData.value.effectiveRangeKm = normalized |
| | | return |
| | | } |
| | | const parsed = parseDeployLocation(formData.value.deployLocation) |
| | | if (!parsed) return |
| | | updateRangeCircle(parsed.longitude, parsed.latitude, value) |
| | | updateRangeCircle(parsed.longitude, parsed.latitude, normalized) |
| | | } |
| | | ) |
| | | </script> |
| | |
| | | |
| | | function formatRange(row) { |
| | | if (!row) return '-' |
| | | const value = row.effectiveRangeKm ?? row.range |
| | | return value === null || value === undefined || value === '' ? '-' : value |
| | | |
| | | let value = row.effectiveRangeKm ?? row.range |
| | | |
| | | return value === null || value === undefined || value === '' ? '-' : Number(value).toFixed(0) |
| | | } |
| | | |
| | | function formatDeviceCode(row) { |
| | |
| | | async function getList() { |
| | | loading.value = true |
| | | try { |
| | | const res = await fwDevicePageApi(searchParams.value) |
| | | const res = await fwDevicePageApi({ |
| | | ...searchParams.value, |
| | | deviceStatusList: '0,1,2' |
| | | }) |
| | | list.value = res?.data?.data?.records ?? [] |
| | | total.value = res?.data?.data?.total ?? 0 |
| | | } finally { |
| | |
| | | function getDictList() { |
| | | getDictionaryByCode('deviceType,deviceStatus,deviceAtt').then(res => { |
| | | dictObj.value = res.data.data |
| | | dictObj.value.deviceStatus = dictObj.value.deviceStatus.filter(item => item.dictKey != 3) |
| | | }) |
| | | } |
| | | |
| | |
| | | watch( |
| | | () => mapCurrentDetail, |
| | | newVal => { |
| | | const newDataMap=JSON.parse(newVal) |
| | | const newDataMap=newVal |
| | | // 只有 workNavigationShow 为 true 且有经纬度时才添加标记 |
| | | if (workNavigationShow && newDataMap?.longitude && newDataMap?.latitude) { |
| | | addIncidentMarker(newDataMap) |
| | |
| | | :workNavigationShow="true" |
| | | :mapCurrentDetail="mapCurrentDetail" |
| | | > |
| | | <!-- <template #eventNav>--> |
| | | <!-- <EventNavigation :mapCurrentDetail="mapCurrentDetail"></EventNavigation>--> |
| | | <!-- </template>--> |
| | | </WorkMap> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { getDeviceRegion } from '@/api/home/aggregation' |
| | | import WorkMap from '@/appComponents/workMap/index.vue' |
| | | import EventNavigation from '@/appPages/work/workDetail/mapWork/eventNavigation.vue' |
| | | import { useRoute } from 'vue-router' |
| | | import { showToast } from 'vant' |
| | | import { getList } from '/src/api/work/index.js' |
| | | import { useStore } from 'vuex' |
| | | const store = useStore() |
| | | const userInfo = computed(() => store?.state?.user?.userInfo) |
| | | const route = useRoute() |
| | | const mapCurrentDetail = ref({}) |
| | | const eventNum = ref('') |
| | | |
| | | |
| | | onMounted(async () => { |
| | | eventNum.value = route.query.currentItem |
| | | mapCurrentDetail.value = eventNum.value |
| | | mapCurrentDetail.value = JSON.parse(decodeURIComponent(route.query.currentItem)) |
| | | |
| | | }) |
| | | </script> |
| | |
| | | |
| | | # 是否在打包时开启压缩,支持 gzip 和 brotli |
| | | VITE_BUILD_COMPRESS=gzip |
| | | |
| | | # xt接口地址 |
| | | VITE_APP_URL_XT=http://218.202.104.82:8200 |
| | |
| | | # VITE_APP_URL = https://wrj.shuixiongit.com/api |
| | | VITE_APP_URL= http://192.168.1.204 |
| | | |
| | | VITE_APP_URL_XT=http://218.202.104.82:8200 |
| | | |
| | | |
| | | #新大屏地址 |
| | | VITE_APP_DASHBOARD_URL = 'https://wrj.shuixiongit.com/command-center-dashboard/' |
| | |
| | | }) |
| | | } |
| | | |
| | | // 获取航线列表 |
| | | export const airlineListApi = (data) => { |
| | | return request({ |
| | | url: `/webservice/webservice/airline/queryList`, |
| | | method: 'post', |
| | | data: data, |
| | | }) |
| | | } |
| | | |
| | | // 获取航线详情 |
| | | export const queryAirById = (id) => { |
| | | return request({ |
| | | url: `/webservice/webservice/airline/queryById/${id}`, |
| | | method: 'get', |
| | | }) |
| | | } |
| | | |
| | | |
| | |
| | | let initialized = false |
| | | let removeCameraListener = null |
| | | |
| | | |
| | | const preventDefault = event => { |
| | | event.preventDefault() |
| | | return |
| | | } |
| | | |
| | | const cesiumContextMenu = (isAdd = true) => { |
| | | let cesium = document.getElementById(mapId) |
| | | if (!cesium) return |
| | | if (isAdd) { |
| | | cesium.addEventListener('contextmenu', preventDefault) |
| | | } else { |
| | | cesium.removeEventListener('contextmenu', preventDefault) |
| | | } |
| | | } |
| | | |
| | | const initMap = async () => { |
| | | if (initialized) return |
| | | initialized = true |
| | |
| | | boundary: props.boundary, |
| | | contour: props.contour, |
| | | }) |
| | | cesiumContextMenu(true) |
| | | viewer.value = viewInstance.value.getViewer() |
| | | if (props.showAdminBoundary) { |
| | | adminBoundarySources = await loadJaAdminBoundary(viewer.value, { |
| | |
| | | if (removeCameraListener) removeCameraListener() |
| | | removeJaAdminBoundary(viewer.value, adminBoundarySources) |
| | | viewInstance.value?.viewerDestroy?.() |
| | | cesiumContextMenu(false) |
| | | }) |
| | | |
| | | const getMap = () => ({ viewer: viewer.value, publicCesium: viewInstance.value }) |
| | |
| | | 'iconfont icon-msnui-360', |
| | | 'iconfont icon-iframe', |
| | | 'iconfont icon-huanyingye', |
| | | 'iconfont_com icon-a-1', |
| | | 'iconfont_com icon-a-4', |
| | | 'iconfont_com icon-a-3', |
| | | 'iconfont_com icon-a-2', |
| | | 'iconfont_com icon-a-6', |
| | | 'iconfont_com icon-a-5', |
| | | 'iconfont_com icon-Frame', |
| | | ], |
| | | }, |
| | | ]; |
| | |
| | | @import './mapEdit.scss'; |
| | | |
| | | @import './common/cockpit.scss'; |
| | | @import './customFont.scss'; |
| | | |
| | | a { |
| | | text-decoration: none; |
| | |
| | | |
| | | * { |
| | | outline: none; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .avue-sidebar, |
| | |
| | | height: 100%; |
| | | box-sizing: border-box; |
| | | background: url('@/assets/images/layoutBg.png') repeat; |
| | | background-position: 0 -20px; |
| | | |
| | | .layer-content-bottom { |
| | | width: 100%; |
| | |
| | | } |
| | | |
| | | .gd-cesium { |
| | | position: relative; |
| | | .cesium-viewer { |
| | | height: 100%; |
| | | overflow: hidden; |
| | |
| | | $form-bg-gray: #DDE2ED; |
| | | $form-tips-gray: #A1A3D4; |
| | | |
| | | $search-item-icon-color: #383874; |
| | | $search-item-symbol-color: #383874; |
| | | |
| | | $search-item-symbol-bg: #fff; |
| | | $search-item-symbol-txt: #4E5969; |
| | | |
| | | .gd-input { |
| | | --bg: #{$form-bg}; |
| | | --tips: #{$form-tips}; |
| | |
| | | --tips: #{$form-tips-gray}; |
| | | } |
| | | |
| | | .el-input__wrapper, .el-textarea__inner { |
| | | .el-input__wrapper, |
| | | .el-textarea__inner { |
| | | box-shadow: none !important; |
| | | background: var(--bg); |
| | | border: none; |
| | | } |
| | | .el-input__inner, .el-textarea__inner { |
| | | |
| | | .el-input__inner, |
| | | .el-textarea__inner { |
| | | &::placeholder { |
| | | color: var(--tips); |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | .gd-select, { |
| | | .gd-button-main { |
| | | --el-button-bg-color: #4C34FF; |
| | | --el-button-text-color: #ffffff; |
| | | --el-button-border-color: #4C34FF; |
| | | --el-button-hover-bg-color: rgb(130, 113, 255); |
| | | --el-button-hover-text-color: #ffffff; |
| | | --el-button-hover-border-color: rgb(130, 113, 255); |
| | | --el-button-active-bg-color: rgb(65, 46, 208); |
| | | --el-button-active-border-color: rgb(65, 46, 208); |
| | | color: #ffffff; |
| | | } |
| | | |
| | | .gd-select { |
| | | --bg: #{$form-bg}; |
| | | --tips: #{$form-tips}; |
| | | |
| | |
| | | background: var(--bg); |
| | | box-shadow: none !important; |
| | | border: none; |
| | | |
| | | |
| | | .el-select__suffix { |
| | | .el-icon { |
| | | color: $search-item-icon-color; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-select__placeholder { |
| | |
| | | &.gray { |
| | | --bg: #{$form-bg-gray}; |
| | | --tips: #{$form-tips-gray}; |
| | | } |
| | | |
| | | .el-icon { |
| | | color: $search-item-icon-color; |
| | | } |
| | | |
| | | .el-range-separator { |
| | | color: $search-item-symbol-color !important; |
| | | } |
| | | |
| | | box-shadow: none !important; |
| | |
| | | background: none !important; |
| | | } |
| | | |
| | | .el-tree-node.is-current > .el-tree-node__content { |
| | | .el-tree-node.is-current>.el-tree-node__content { |
| | | color: #479dff !important; |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | .gd-date-picker-popper { |
| | | background: #DDE2ED !important; |
| | | background: #fff !important; |
| | | border: none !important; |
| | | border-radius: 0px 0px 8px 8px; |
| | | |
| | | .el-date-picker__prev-btn, |
| | | .el-date-picker__next-btn { |
| | | .el-icon { |
| | | color: #fff !important; |
| | | color: #4E5969 !important; |
| | | } |
| | | } |
| | | |
| | | .el-date-picker__header-label { |
| | | color: #fff !important; |
| | | color: #4E5969 !important; |
| | | } |
| | | |
| | | .el-picker-panel { |
| | | .el-picker-panel__body-wrapper { |
| | | .el-picker-panel__body { |
| | | background: #DDE2ED !important; |
| | | color: #fff !important; |
| | | background: #fff !important; |
| | | color: #4E5969 !important; |
| | | |
| | | .el-date-range-picker__time-header { |
| | | .el-input__wrapper { |
| | |
| | | .el-picker-panel__content { |
| | | .el-date-range-picker__header { |
| | | .el-picker-panel__icon-btn { |
| | | color: #fff !important; |
| | | color: #4E5969 !important; |
| | | |
| | | &:hover { |
| | | color: var(--el-color-primary) !important; |
| | |
| | | } |
| | | } |
| | | |
| | | & > div { |
| | | &>div { |
| | | span { |
| | | color: #fff !important; |
| | | color: #4E5969 !important; |
| | | } |
| | | } |
| | | } |
| | |
| | | td.start-date span, |
| | | td.start-date span, |
| | | td.end-date span { |
| | | background-color: #DDE2ED !important; |
| | | color: #fff !important; |
| | | background-color: #354DFF !important; |
| | | } |
| | | |
| | | td.in-range div, |
| | | td.in-range div:hover, |
| | | &.is-week-mode .el-date-table__row.current div, |
| | | &.is-week-mode .el-date-table__row:hover div { |
| | | background-color: rgba(60, 121, 202) !important; |
| | | background-color: rgba(71, 126, 255, .1) !important; |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | .el-overlay-dialog { |
| | | display: flex; |
| | | justify-content: center; /* 水平居中 */ |
| | | align-items: center; /* 垂直居中 */ |
| | | justify-content: center; |
| | | /* 水平居中 */ |
| | | align-items: center; |
| | | /* 垂直居中 */ |
| | | } |
| | | |
| | | .gd-dialog { |
| | | padding: 30px; |
| | | padding: 20px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | background: #FFFFFF; |
| | |
| | | max-height: 90vh; |
| | | |
| | | .el-dialog__header { |
| | | padding-bottom: 20px; |
| | | position: relative; |
| | | |
| | | span { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: bold; |
| | |
| | | text-align: left; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | | |
| | | &>button { |
| | | width: auto; |
| | | height: auto; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .el-icon { |
| | |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | color: #161B2C; |
| | | } |
| | | |
| | | |
| | | .detail-container { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | |
| | | .detail-left { |
| | | margin-right: 20px; |
| | | width: 312px; |
| | | padding: 24px; |
| | | border: 1px solid #E4E4E4; |
| | | } |
| | | |
| | | .detail-right { |
| | | &>div { |
| | | .detail-title { |
| | | margin: 10px 0; |
| | | } |
| | | |
| | | &:first-child { |
| | | .detail-title { |
| | | margin-top: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 查看 |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-upload { |
| | | button { |
| | | background: #4C34FF; |
| | | border: none; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-dialog__footer { |
| | |
| | | margin-left: 16px; |
| | | width: 96px; |
| | | height: 36px; |
| | | color: #161B2C; |
| | | |
| | | &:first-child { |
| | | margin-left: 0; |
| | | } |
| | | } |
| | | |
| | | .save-btn { |
| | | color: #FFFFFF; |
| | | } |
| | | } |
| | | } |
| | |
| | | flex: 1; |
| | | background: transparent !important; |
| | | |
| | | .el-table--border .el-table__inner-wrapper:after, |
| | | .el-table--border:after, |
| | | .el-table--border:before, |
| | | .el-table__inner-wrapper:before { |
| | | height: 0; |
| | | } |
| | | |
| | | tr { |
| | | background: transparent !important; |
| | | } |
| | | |
| | | tr.el-table__row { |
| | | &:hover { |
| | | background: #F7F8FC !important; |
| | | } |
| | | } |
| | | |
| | | th.el-table__cell { |
| | |
| | | td.operation-btns .cell { |
| | | display: flex; |
| | | flex-wrap: nowrap; |
| | | gap: 12px; |
| | | /* 按钮间距(推荐) */ |
| | | white-space: nowrap; |
| | | /* 双保险 */ |
| | | |
| | | a { |
| | | display: flex; |
| | | align-items: center; |
| | | position: relative; |
| | | margin: 0 10px; |
| | | min-width: 28px; |
| | | color: #0075FF; |
| | | |
| | | span { |
| | | color: #0075FF; |
| | | } |
| | | |
| | | &:first-child { |
| | | margin-left: 0; |
| | | } |
| | | |
| | | &::before { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 50%; |
| | | right: -10px; |
| | | width: 1px; |
| | | height: 12px; |
| | | background: #BCC8E3; |
| | | transform: translateY(calc(-50% - 1px)); |
| | | } |
| | | |
| | | &:last-child { |
| | | margin-right: 0; |
| | | |
| | | &::before { |
| | | display: none; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | background: transparent !important; |
| | | } |
| | | |
| | | .el-checkbox { |
| | | width: 16px; |
| | | height: 16px; |
| | | |
| | | .el-checkbox__input { |
| | | width: 16px; |
| | | height: 16px; |
| | | |
| | | .el-checkbox__inner { |
| | | width: 16px; |
| | | height: 16px; |
| | | |
| | | border: none; |
| | | background: url("@/assets/images/common/n-checkbox.png") no-repeat center / 100% 100% !important; |
| | | } |
| | | } |
| | | |
| | | &.is-checked { |
| | | .el-checkbox__input { |
| | | .el-checkbox__inner { |
| | | border: none; |
| | | background: url("@/assets/images/common/checkbox.png") no-repeat center / 100% 100% !important; |
| | | |
| | | &::after { |
| | | content: none; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .fixed-column { |
| | | background-color: #1A1A2A !important; |
| | | } |
| | | } |
| | | |
| | | .el-table { |
| | | |
| | | .el-table--border .el-table__inner-wrapper:after, |
| | | .el-table--border:after, |
| | | .el-table--border:before, |
| | | .el-table__inner-wrapper:before { |
| | | height: 0; |
| | | } |
| | | |
| | | td.el-table__cell { |
| | | border: none !important; |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | .gd-confirm-custom { |
| | | background: #1A1A2A; |
| | | background: #fff; |
| | | border-radius: 6px; |
| | | border: 1px solid #2E2E46; |
| | | border: none; |
| | | |
| | | .el-message-box__header { |
| | | .el-message-box__title { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #FFFFFF; |
| | | color: #383874; |
| | | line-height: 22px; |
| | | text-align: left; |
| | | font-style: normal; |
| | |
| | | } |
| | | |
| | | .el-message-box__content { |
| | | color: #D4D5D7; |
| | | color: #4E5969; |
| | | } |
| | | |
| | | .el-message-box__btns { |
| | |
| | | } |
| | | |
| | | .gd-confirm-button { |
| | | background: #284FE3 !important; |
| | | border-color: #284FE3 !important; |
| | | background: #4C34FF !important; |
| | | border: none !important; |
| | | color: #fff !important; |
| | | } |
| | | |
| | | .gd-confirm-cancel-button { |
| | | background: #2B2B4C !important; |
| | | border-color: #2B2B4C !important; |
| | | color: #FFFFFF !important; |
| | | background: #F2F3F5 !important; |
| | | border: none !important; |
| | | color: #161B2C !important; |
| | | } |
| | | |
| | | .gd-search-form { |
| | |
| | | |
| | | .gd-select-popper { |
| | | border: none; |
| | | background: $form-bg !important; |
| | | background: $search-item-symbol-bg !important; |
| | | |
| | | .el-select-dropdown { |
| | | .el-scrollbar { |
| | | .el-select-dropdown__wrap { |
| | | .el-select-dropdown__list { |
| | | .el-select-dropdown__item { |
| | | color: #4E5969; |
| | | color: $search-item-symbol-txt; |
| | | |
| | | &.hover { |
| | | background-color: rgba(0, 120, 233, 0.63) !important; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .gd-tabs { |
| | | .el-tabs__header { |
| | | .el-tabs__item.is-active { |
| | | color: #3247E5; |
| | | } |
| | | |
| | | .el-tabs__active-bar { |
| | | background: #3247E5; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .gd-dialog-table { |
| | | background: transparent !important; |
| | | |
| | | tr { |
| | | background: transparent !important; |
| | | } |
| | | |
| | | tr.el-table__row { |
| | | &:hover { |
| | | background: #F7F8FC !important; |
| | | } |
| | | } |
| | | |
| | | th.el-table__cell { |
| | | height: 40px; |
| | | border-bottom: 1px solid #DBDFF1 !important; |
| | | |
| | | .cell { |
| | | padding: 0 0 0 16px; |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | color: #9292C1; |
| | | text-align: left; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | | } |
| | | |
| | | td.el-table__cell { |
| | | padding: 9px 0; |
| | | height: 56px; |
| | | |
| | | .cell { |
| | | padding: 0 0 0 16px; |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | color: #383874; |
| | | text-align: left; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | | } |
| | | |
| | | td.operation-btns .cell { |
| | | display: flex; |
| | | flex-wrap: nowrap; |
| | | /* 按钮间距(推荐) */ |
| | | white-space: nowrap; |
| | | /* 双保险 */ |
| | | |
| | | a { |
| | | display: flex; |
| | | align-items: center; |
| | | position: relative; |
| | | margin: 0 10px; |
| | | min-width: 28px; |
| | | |
| | | span { |
| | | color: #0075FF; |
| | | } |
| | | |
| | | &:first-child { |
| | | margin-left: 0; |
| | | } |
| | | |
| | | &::before { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 50%; |
| | | right: -10px; |
| | | width: 1px; |
| | | height: 12px; |
| | | background: #BCC8E3; |
| | | transform: translateY(calc(-50% - 1px)); |
| | | } |
| | | |
| | | &:last-child { |
| | | margin-right: 0; |
| | | |
| | | &::before { |
| | | display: none; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | th.el-table__cell:not(.fixed-column), |
| | | td.el-table__cell:not(.fixed-column) { |
| | | background: transparent !important; |
| | | } |
| | | |
| | | .el-checkbox { |
| | | width: 16px; |
| | | height: 16px; |
| | | |
| | | .el-checkbox__input { |
| | | width: 16px; |
| | | height: 16px; |
| | | |
| | | .el-checkbox__inner { |
| | | width: 16px; |
| | | height: 16px; |
| | | |
| | | border: none; |
| | | background: url("@/assets/images/common/n-checkbox.png") no-repeat center / 100% 100% !important; |
| | | } |
| | | } |
| | | |
| | | &.is-checked { |
| | | .el-checkbox__input { |
| | | .el-checkbox__inner { |
| | | border: none; |
| | | background: url("@/assets/images/common/checkbox.png") no-repeat center / 100% 100% !important; |
| | | |
| | | &::after { |
| | | content: none; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .fixed-column { |
| | | background-color: #1A1A2A !important; |
| | | } |
| | | } |
| | | |
| | | .el-popper { |
| | | .el-menu--popup-container { |
| | | .el-menu { |
| | | .el-menu-item.is-active { |
| | | &::before { |
| | | display: none; |
| | | } |
| | | |
| | | background: #4C34FF; |
| | | |
| | | span { |
| | | color: #fff; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | @font-face { |
| | | font-family: "iconfont_com"; |
| | | /* Project id 5099981 */ |
| | | src: url('//at.alicdn.com/t/c/font_5099981_ysrl5v42ycd.woff2?t=1769414361186') format('woff2'), |
| | | url('//at.alicdn.com/t/c/font_5099981_ysrl5v42ycd.woff?t=1769414361186') format('woff'), |
| | | url('//at.alicdn.com/t/c/font_5099981_ysrl5v42ycd.ttf?t=1769414361186') format('truetype'), |
| | | url('//at.alicdn.com/t/c/font_5099981_ysrl5v42ycd.svg?t=1769414361186#iconfont') format('svg'); |
| | | } |
| | | |
| | | .iconfont_com { |
| | | font-family: "iconfont_com" !important; |
| | | font-size: 16px; |
| | | font-style: normal; |
| | | -webkit-font-smoothing: antialiased; |
| | | -moz-osx-font-smoothing: grayscale; |
| | | } |
| | | |
| | | .icon-a-1:before { |
| | | content: "\e609"; |
| | | } |
| | | |
| | | .icon-a-4:before { |
| | | content: "\e604"; |
| | | } |
| | | |
| | | .icon-a-3:before { |
| | | content: "\e605"; |
| | | } |
| | | |
| | | .icon-a-2:before { |
| | | content: "\e606"; |
| | | } |
| | | |
| | | .icon-a-6:before { |
| | | content: "\e607"; |
| | | } |
| | | |
| | | .icon-a-5:before { |
| | | content: "\e608"; |
| | | } |
| | | |
| | | .icon-Frame:before { |
| | | content: "\e602"; |
| | | } |
| | | |
| | | .icon-a-:before { |
| | | content: "\e601"; |
| | | } |
| | | |
| | | .icon-MenuIcon-biaozhunshujutuisong-heise:before { |
| | | content: "\e611"; |
| | | } |
| | | |
| | | .icon-MenuIcon-xuncharenwujiankong-heise:before { |
| | | content: "\e614"; |
| | | } |
| | | |
| | | .icon-MenuIcon-shebeirizhi-heise:before { |
| | | content: "\e615"; |
| | | } |
| | |
| | | |
| | | border-radius: 3px 3px 3px 3px; |
| | | |
| | | &:active { |
| | | color: #FFFFFF !important; |
| | | background: #5B6BFF !important; |
| | | |
| | | span { |
| | | color: #fff !important; |
| | | } |
| | | } |
| | | |
| | | &.is-active { |
| | | //padding: 0 !important; |
| | | //padding-left: 20px !important; |
| | | color: #FFFFFF; |
| | | background: #5B6BFF; |
| | | color: #FFFFFF !important; |
| | | background: #5B6BFF !important; |
| | | |
| | | .is-icon-close { |
| | | //margin: 0 10px; |
| | |
| | | <template v-if="!dialogReadonly"> |
| | | <el-button color="#F2F3F5" @click="visible = false">取消</el-button> |
| | | <el-button |
| | | class="save-btn" |
| | | class="" |
| | | color="#4C34FF" |
| | | |
| | | :loading="submitting" |
| | |
| | | <template v-if="dialogReadonly && innovationDetailsStatus ==='0'"> |
| | | <el-button color="#F2F3F5" @click="handleReject">不通过</el-button> |
| | | <el-button |
| | | class="save-btn" |
| | | class="" |
| | | color="#4C34FF" |
| | | :loading="submitting" |
| | | :disabled="submitting" |
| | |
| | | <div class="gd-table-container" v-loading="loading"> |
| | | <div class="gd-table-content gd-table-content-bg"> |
| | | <el-table class="gd-table" :data="list" @selection-change="handleSelectionChange"> |
| | | <el-table-column label="序号" width="60" align="center"> |
| | | <el-table-column label="序号" width="70" align="center"> |
| | | <template #default="{ $index }"> |
| | | {{ formatNumber((searchParams.current - 1) * searchParams.size + $index + 1) }} |
| | | </template> |
| | |
| | | <el-table-column prop="resourceName" show-overflow-tooltip label="资源名称" /> |
| | | <el-table-column prop="resourceCode" show-overflow-tooltip label="资源编码" /> |
| | | <el-table-column prop="caseDesc" show-overflow-tooltip label="案例描述" /> |
| | | <el-table-column label="操作" class-name="operation-btns" width="180"> |
| | | <el-table-column label="操作" class-name="operation-btns" width="240"> |
| | | <template v-slot="{ row }"> |
| | | <el-link @click="openForm('view', row)">查看</el-link> |
| | | <!-- <el-link @click="openForm('edit', row)">编辑</el-link>--> |
| | | <el-link @click="handleDelete(row)" v-if="!['1', '2'].includes(row.innovationStatus)">删除</el-link> |
| | | <el-link type="primary" @click="openForm('view', row)">查看</el-link> |
| | | <!-- <el-link type="primary" @click="openForm('edit', row)">编辑</el-link>--> |
| | | <el-link type="primary" @click="handleDelete(row)" v-if="!['1', '2'].includes(row.innovationStatus)">删除</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | > |
| | | 保存 |
| | | </el-button> |
| | | <el-button class="save-btn" color="#4C34FF" :loading="submitting" :disabled="submitting" @click="handleApply">申请</el-button> |
| | | <el-button class="" color="#4C34FF" :loading="submitting" :disabled="submitting" @click="handleApply">申请</el-button> |
| | | </template> |
| | | <template v-if="dialogReadonly && detailObjectionStatus === '1'"> |
| | | <el-button color="#F2F3F5" :loading="submitting" :disabled="submitting" @click="visible = false">取消</el-button> |
| | | |
| | | <el-button |
| | | class="save-btn" |
| | | class="" |
| | | color="#4C34FF" |
| | | |
| | | :loading="submitting" |
| | |
| | | 反馈 |
| | | </el-button> |
| | | <el-button |
| | | class="save-btn" |
| | | class="" |
| | | color="#4C34FF" |
| | | |
| | | :loading="submitting" |
| | |
| | | ElMessage.warning('没有可下载的附件') |
| | | return |
| | | } |
| | | |
| | | |
| | | // 遍历所有附件并下载 |
| | | attachmentDetailsList.value.forEach(attach => { |
| | | if (attach.link) { |
| | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .detail-container { |
| | | padding: 20px; |
| | | } |
| | | .upload-container { |
| | | width: 100%; |
| | | } |
| | |
| | | <div class="gd-table-container" v-loading="loading"> |
| | | <div class="gd-table-content gd-table-content-bg"> |
| | | <el-table class="gd-table" :data="list"> |
| | | <el-table-column label="序号" width="60"> |
| | | <el-table-column label="序号" width="70"> |
| | | <template v-slot="{ $index }"> |
| | | {{ String($index + 1).padStart(2, '0') }} |
| | | </template> |
| | |
| | | {{ getDictLabel(row.objectionStatus, dictObj.objectionStatus) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="catalogResourceName" width="170" show-overflow-tooltip label="目录/申请资源名称" /> |
| | | <el-table-column prop="catalogResourceName" width="130" show-overflow-tooltip label="目录/申请资源名称" /> |
| | | <el-table-column prop="otherObjectionDetail" show-overflow-tooltip label="其他异议详情" /> |
| | | <el-table-column prop="submitter" show-overflow-tooltip label="问题提交人" /> |
| | | <el-table-column prop="submitterContact" show-overflow-tooltip width="145" label="提交人联系方式" /> |
| | | <el-table-column prop="submitterContact" show-overflow-tooltip width="120" label="提交人联系方式" /> |
| | | <el-table-column prop="submitUnitName" show-overflow-tooltip label="提交单位" /> |
| | | <el-table-column prop="handleUnit" show-overflow-tooltip label="处理单位" /> |
| | | <el-table-column prop="objectionDesc" show-overflow-tooltip label="异议描述" /> |
| | | <el-table-column prop="objectionBasis" show-overflow-tooltip label="异议依据" /> |
| | | <el-table-column prop="attachName" show-overflow-tooltip label="附件名称" /> |
| | | <el-table-column prop="reviewOpinion" show-overflow-tooltip label="审核意见" /> |
| | | <el-table-column label="操作" class-name="operation-btns" width="180"> |
| | | <el-table-column label="操作" class-name="operation-btns" width="240"> |
| | | <template v-slot="{ row }"> |
| | | <el-link @click="openForm('view', row)">查看</el-link> |
| | | <el-link @click="openForm('edit', row)" v-if="!['1', '2'].includes(row.objectionStatus)">编辑</el-link> |
| | | <el-link @click="handleDelete(row)" v-if="!['1', '2'].includes(row.objectionStatus)">删除</el-link> |
| | | <el-link type="primary" @click="openForm('view', row)">查看</el-link> |
| | | <el-link type="primary" @click="openForm('edit', row)" v-if="!['1', '2'].includes(row.objectionStatus)">编辑</el-link> |
| | | <el-link type="primary" @click="handleDelete(row)" v-if="!['1', '2'].includes(row.objectionStatus)">删除</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | <template #footer v-if="!dialogReadonly"> |
| | | <el-button color="#F2F3F5" @click="visible = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button> |
| | | <el-button |
| | | class="save-btn" |
| | | class="" |
| | | color="#4C34FF" |
| | | |
| | | :loading="submitting" |
| | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="evaluationContent" show-overflow-tooltip label="评价内容" /> |
| | | <el-table-column label="操作" class-name="operation-btns" width="180"> |
| | | <el-table-column label="操作" class-name="operation-btns" width="240"> |
| | | <template v-slot="{ row }"> |
| | | <el-link @click="openForm('view', row)">查看</el-link> |
| | | <el-link @click="openForm('edit', row)">编辑</el-link> |
| | | <el-link @click="handleDelete(row)">删除</el-link> |
| | | <el-link type="primary" @click="openForm('view', row)">查看</el-link> |
| | | <el-link type="primary" @click="openForm('edit', row)">编辑</el-link> |
| | | <el-link type="primary" @click="handleDelete(row)">删除</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | <template #footer> |
| | | <template v-if="detailDemandStatus === '1' && !requesterProvider"> |
| | | <el-button color="#F2F3F5" @click="rejectTheApplication">拒绝申请</el-button> |
| | | <el-button class="save-btn" color="#4C34FF" @click="approvedByTheReview">审核通过</el-button> |
| | | <el-button class="" color="#4C34FF" @click="approvedByTheReview">审核通过</el-button> |
| | | </template> |
| | | <template v-if="detailDemandStatus === '2'"> |
| | | <el-button class="save-btn" color="#4C34FF" @click="downloadAllFiles">全部下载</el-button> |
| | | <el-button class="" color="#4C34FF" @click="downloadAllFiles">全部下载</el-button> |
| | | </template> |
| | | <template v-if="detailDemandStatus === '3'"> |
| | | <el-button class="save-btn" color="#4C34FF" @click="visible =false">关闭</el-button> |
| | | <el-button class="" color="#4C34FF" @click="visible =false">关闭</el-button> |
| | | </template> |
| | | </template> |
| | | </el-dialog> |
| | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .detail-container { |
| | | padding: 20px; |
| | | display: flex; |
| | | gap: 30px; |
| | | align-items: stretch; |
| | | } |
| | | |
| | | /* 左侧步骤条 */ |
| | | .detail-left { |
| | | width: 25%; |
| | | width: 35%; |
| | | padding-right: 20px; |
| | | border-right: 1px solid #e8e8e8; |
| | | } |
| | | |
| | | /* 右侧表单 */ |
| | | .detail-right { |
| | | width: 75%; |
| | | width: 65%; |
| | | .reject-reason { |
| | | margin-bottom: 20px; |
| | | background: #f2f3f5; |
| | |
| | | > |
| | | 保存 |
| | | </el-button> |
| | | <el-button class="save-btn" color="#4C34FF" :loading="submitting" :disabled="submitting" @click="handleApply">申请</el-button> |
| | | <el-button color="#4C34FF" :loading="submitting" :disabled="submitting" @click="handleApply">申请</el-button> |
| | | |
| | | </template> |
| | | </el-dialog> |
| | |
| | | <template> |
| | | <div class="audit-record-container"> |
| | | <div class="label">审批记录</div> |
| | | <el-steps direction="vertical" :active="displayedSteps.length"> |
| | | <el-step v-for="step in displayedSteps" :key="step.status" :title="step.title" :description="`${step.person || ''}\n${step.time || ''}`" /> |
| | | </el-steps> |
| | | <el-timeline class="gd-timeline"> |
| | | <el-timeline-item |
| | | v-for="(step, index) in displayedSteps" |
| | | :key="step.status" |
| | | :icon="Check" |
| | | :type="index === displayedSteps.length - 1 ? 'success' : 'info'" |
| | | :timestamp="step.time" |
| | | > |
| | | <div class="item-content"> |
| | | <div class="flowName">{{ step.title }}</div> |
| | | <div >{{ step.person }}</div> |
| | | </div> |
| | | </el-timeline-item> |
| | | </el-timeline> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, watch } from 'vue' |
| | | import { Check } from '@element-plus/icons-vue' |
| | | import { gdSupplyDemandAuditListApi } from '@/views/orderView/orderDataManage/supplyAdd/supplyAddApi' |
| | | |
| | | const props = defineProps({ |
| | |
| | | |
| | | <style scoped lang="scss"> |
| | | .audit-record-container { |
| | | height: 95%; |
| | | .label { |
| | | font-weight: 500; |
| | | margin-bottom: 8px; |
| | | color: #333; |
| | | width:100%; |
| | | // height: 95%; |
| | | |
| | | } |
| | | |
| | | /* 时间线样式 */ |
| | | :deep(.gd-timeline) { |
| | | padding-left: 90px; |
| | | } |
| | | |
| | | :deep(.el-timeline-item) { |
| | | padding-bottom: 20px; |
| | | .item-content { |
| | | position: relative; |
| | | .flowName { |
| | | width: 80px; |
| | | position: absolute; |
| | | left: -120px; |
| | | top: 0px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* 步骤条样式 */ |
| | | :deep(.el-steps) { |
| | | align-items: flex-start; |
| | | } |
| | | |
| | | :deep(.el-step) { |
| | | // margin-bottom: 20px; |
| | | } |
| | | |
| | | :deep(.el-step__title) { |
| | | font-size: 14px; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | :deep(.el-step__description) { |
| | | font-size: 13px; |
| | | color: #666; |
| | | white-space: pre-wrap; |
| | | line-height: 1.4; |
| | | :deep(.el-timeline-item__timestamp) { |
| | | font-size: 12px; |
| | | color: #999; |
| | | margin-top: 2px; |
| | | } |
| | | </style> |
| | |
| | | <div class="gd-table-container" v-loading="loading"> |
| | | <div class="gd-table-content gd-table-content-bg"> |
| | | <el-table class="gd-table" :data="list"> |
| | | <el-table-column label="序号" width="60" align="center"> |
| | | <el-table-column label="序号" width="70" align="center"> |
| | | <template #default="scope"> |
| | | {{ ((searchParams.current - 1) * searchParams.size + scope.$index + 1).toString().padStart(2, '0') }} |
| | | </template> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="contactPerson" show-overflow-tooltip label="需求联系人" /> |
| | | <el-table-column prop="contactPhone" show-overflow-tooltip width="150" label="需求联系人电话" /> |
| | | <el-table-column prop="contactPhone" show-overflow-tooltip width="180" label="需求联系人电话" /> |
| | | <el-table-column prop="contactEmail" show-overflow-tooltip label="需求邮箱" /> |
| | | <el-table-column prop="demandStatus" show-overflow-tooltip label="需求状态"> |
| | | <template v-slot="{ row }"> |
| | |
| | | <el-table-column prop="responsibleDeptName" show-overflow-tooltip label="责任部门" /> |
| | | <el-table-column prop="dataSource" show-overflow-tooltip label="数据来源依据" /> |
| | | <el-table-column prop="demandInfo" show-overflow-tooltip label="需求信息项" /> |
| | | <el-table-column label="操作" class-name="operation-btns" width="180"> |
| | | <el-table-column label="操作" class-name="operation-btns" width="240"> |
| | | <template v-slot="{ row }"> |
| | | <el-link @click="openForm('view', row)">查看</el-link> |
| | | <el-link type="primary" @click="openForm('view', row)">查看</el-link> |
| | | <!-- 只对非审批状态显示编辑和删除按钮 --> |
| | | <el-link @click="openForm('edit', row)" v-if="!['1', '2', '3'].includes(row.demandStatus)">编辑</el-link> |
| | | <el-link @click="handleDelete(row)" v-if="!['1', '2', '3'].includes(row.demandStatus)">删除</el-link> |
| | | <el-link type="primary" @click="openForm('edit', row)" v-if="!['1', '2', '3'].includes(row.demandStatus)">编辑</el-link> |
| | | <el-link type="primary" @click="handleDelete(row)" v-if="!['1', '2', '3'].includes(row.demandStatus)">删除</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | </div> |
| | | </div> |
| | | <template #footer> |
| | | <el-button class="save-btn" color="#4C34FF" @click="handleConfirm">确认</el-button> |
| | | <el-button class="" color="#4C34FF" @click="handleConfirm">确认</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .detail-container { |
| | | padding: 20px; |
| | | display: flex; |
| | | align-items: flex-start; |
| | | gap: 30px; |
| | | .detail-cell { |
| | | display: flex; |
| | | justify-content: center; |
| | | .cell-label { |
| | | min-width: 80px; |
| | | flex-shrink: 0; |
| | | } |
| | | :deep(.el-textarea__inner) { |
| | | height: 100px !important; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button color="#F2F3F5" @click="visible = false">取消</el-button> |
| | | <el-button class="save-btn" color="#4C34FF" :loading="submitting" :disabled="submitting" @click="handleSubmit"> |
| | | <el-button class="" color="#4C34FF" :loading="submitting" :disabled="submitting" @click="handleSubmit"> |
| | | 保存 |
| | | </el-button> |
| | | </template> |
| | |
| | | <template> |
| | | <el-dialog class="gd-dialog" v-model="visible" title="查看" @closed="visible = false" width="1000px" destroy-on-close> |
| | | <div class="gd-table-container" v-loading="loading" style="height: 600px"> |
| | | <div class="gd-table-content gd-table-content-bg"> |
| | | <el-table class="gd-table" :data="list"> |
| | | <el-table-column label="线索缩略图" width="120"> |
| | | <template v-slot="{ row }"> |
| | | <el-image |
| | | v-if="row.resultUrl" |
| | | :src="row.resultUrl" |
| | | :preview-src-list="[row.resultUrl]" |
| | | fit="cover" |
| | | style="width: 80px; height: 60px" |
| | | preview-teleported |
| | | /> |
| | | <span v-else>-</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="resultCode" show-overflow-tooltip label="线索编号" /> |
| | | <el-table-column prop="shootTime" show-overflow-tooltip label="拍摄时间" /> |
| | | <el-table-column label="线索位置" show-overflow-tooltip> |
| | | <template v-slot="{ row }"> |
| | | {{ formatLocation(row) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="distributeStatus" show-overflow-tooltip label="线索状态"> |
| | | <template v-slot="{ row }"> |
| | | {{ getDistributeStatusLabel(row.distributeStatus) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="distributeDeptName" show-overflow-tooltip label="分发部门" /> |
| | | <el-table-column prop="distributeUserName" show-overflow-tooltip label="分发人员" /> |
| | | <el-table-column label="操作" class-name="operation-btns" width="140"> |
| | | <template v-slot="{ row }"> |
| | | <el-link v-if="row.distributeStatus === 0" @click="openDistributeDialog(row)" :disabled="row.distributeStatus === 1"> |
| | | 转为事件并分发 |
| | | </el-link> |
| | | <div class="disabled-text" v-else>转为事件并分发</div> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | <div v-loading="loading"> |
| | | <el-table :data="list"> |
| | | <el-table-column label="线索缩略图" width="120"> |
| | | <template v-slot="{ row }"> |
| | | <el-image |
| | | v-if="row.resultUrl" |
| | | :src="row.resultUrl" |
| | | :preview-src-list="[row.resultUrl]" |
| | | fit="cover" |
| | | style="width: 80px; height: 60px" |
| | | preview-teleported |
| | | /> |
| | | <span v-else>-</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="resultCode" show-overflow-tooltip label="线索编号" /> |
| | | <el-table-column prop="shootTime" show-overflow-tooltip label="拍摄时间" /> |
| | | <el-table-column label="线索位置" show-overflow-tooltip> |
| | | <template v-slot="{ row }"> |
| | | {{ formatLocation(row) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="distributeStatus" show-overflow-tooltip label="线索状态"> |
| | | <template v-slot="{ row }"> |
| | | {{ getDistributeStatusLabel(row.distributeStatus) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="distributeDeptName" show-overflow-tooltip label="分发部门" /> |
| | | <el-table-column prop="distributeUserName" show-overflow-tooltip label="分发人员" /> |
| | | <el-table-column label="操作" class-name="operation-btns" width="140"> |
| | | <template v-slot="{ row }"> |
| | | <el-link type="primary" |
| | | @click="openDistributeDialog(row)" |
| | | :disabled="row.distributeStatus === 1 || currentRow.taskStatus !== '8'" |
| | | > |
| | | 转为事件并分发 |
| | | </el-link> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | |
| | | <template #footer> |
| | |
| | | <el-table-column prop="taskDesc" show-overflow-tooltip label="巡查任务描述" /> |
| | | <el-table-column label="操作" class-name="operation-btns"> |
| | | <template v-slot="{ row }"> |
| | | <el-link @click="viewDiaLogView(row)">查看线索</el-link> |
| | | <el-link type="primary" @click="viewDiaLogView(row)">查看线索</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | const range = dateRangeFormat(dateRange.value) |
| | | loading.value = true |
| | | try { |
| | | const res = await gdPatrolTaskPageApi({ ...searchParams.value, startTime: range[0], endTime: range[1] }) |
| | | const res = await gdPatrolTaskPageApi({ |
| | | ...searchParams.value, |
| | | startTime: range[0], |
| | | endTime: range[1], |
| | | taskStatus: 8 |
| | | }) |
| | | list.value = res?.data?.data?.records ?? [] |
| | | total.value = res?.data?.data?.total ?? 0 |
| | | } finally { |
| | |
| | | </el-table-column> |
| | | <el-table-column label="操作" class-name="operation-btns"> |
| | | <template v-slot="{ row }"> |
| | | <el-link @click="seeOnlineWord(row)">查看</el-link> |
| | | <el-link @click="openForm(row)">在线编辑</el-link> |
| | | <el-link @click="handleDelete(row)">删除</el-link> |
| | | <el-link type="primary" @click="seeOnlineWord(row)">查看</el-link> |
| | | <el-link type="primary" @click="openForm(row)">在线编辑</el-link> |
| | | <el-link type="primary" @click="handleDelete(row)">删除</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | <template #footer> |
| | | <el-button color="#F2F3F5" @click="isShowEditView = false">取消</el-button> |
| | | <el-button |
| | | class="save-btn" |
| | | class="" |
| | | color="#4C34FF" |
| | | :loading="submitting" |
| | | :disabled="submitting" |
| | |
| | | <template #footer> |
| | | <el-button color="#F2F3F5" @click="visible = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button> |
| | | <el-button |
| | | class="save-btn" |
| | | class="" |
| | | color="#4C34FF" |
| | | v-if="!dialogReadonly" |
| | | :loading="submitting" |
| | |
| | | import { gdWorkOrderPageApi } from '../orderManage/orderManageApi' |
| | | import { gdManageDeviceListApi } from '../orderManage/gdManageDeviceApi' |
| | | import { pxToRem } from '@/utils/rem' |
| | | import { airlineListApi } from '@/api/zkxt' |
| | | |
| | | // 初始化任务行 |
| | | const initTaskRow = () => ({ |
| | |
| | | const dialogMode = ref('add') // 弹框模式 |
| | | const submitting = ref(false) // 提交中 |
| | | const dialogReadonly = computed(() => dialogMode.value === 'view') |
| | | const titleEnum = ref({ edit: '编辑', view: '查看', add: '新增' }) |
| | | const titleEnum = ref({ edit: '新增', view: '查看', add: '新增' }) |
| | | |
| | | // 工单相关 |
| | | const workOrderList = ref([]) // 工单列表 |
| | |
| | | // 下拉选项 |
| | | const flyerListMap = ref({}) // 飞手列表,按行索引存储 |
| | | const deviceList = ref([]) // 设备列表 |
| | | const routeOptions = ref([ |
| | | { name: '航线1', id: '1' }, |
| | | { name: '航线2', id: '2' }, |
| | | { name: '航线3', id: '3' }, |
| | | ]) // 航线假数据 |
| | | const routeOptions = inject('routeOptions') |
| | | |
| | | // 子任务列表 |
| | | const taskList = ref([initTaskRow()]) |
| | |
| | | |
| | | // 获取工单列表 |
| | | async function getWorkOrderList() { |
| | | const res = await gdWorkOrderPageApi({ size: 999, workOrderStatus: '20' }) |
| | | const res = await gdWorkOrderPageApi({ size: 999, workOrderStatus: dialogMode.value ==='add' ? '20' : '' }) |
| | | workOrderList.value = res?.data?.data?.records ?? [] |
| | | } |
| | | |
| | |
| | | // 获取设备列表 |
| | | async function getDeviceList() { |
| | | const res = await gdManageDeviceListApi({ |
| | | deviceIds: selectedWorkOrder.value.recommendDeviceIds, |
| | | deviceIds: selectedWorkOrder.value?.recommendDeviceIds, |
| | | }) |
| | | deviceList.value = res?.data?.data ?? [] |
| | | } |
| | |
| | | watch( |
| | | () => selectedWorkOrderId.value, |
| | | () => { |
| | | handleWorkOrderChange(selectedWorkOrderId.value) |
| | | getDeviceList() |
| | | } |
| | | ) |
| | |
| | | |
| | | // 打开弹框 |
| | | async function open({ mode = 'add', row } = {}) { |
| | | console.log(row, 'rowrow') |
| | | dialogMode.value = mode |
| | | if (mode === 'add') { |
| | | await getWorkOrderList() |
| | | if (dialogMode.value === 'add') { |
| | | selectedWorkOrderId.value = null |
| | | selectedWorkOrder.value = null |
| | | taskList.value = [initTaskRow()] |
| | |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getWorkOrderList() |
| | | |
| | | }) |
| | | |
| | | defineExpose({ open }) |
| | |
| | | <template #footer> |
| | | <el-button color="#F2F3F5" @click="visible = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button> |
| | | <el-button |
| | | class="save-btn" |
| | | class="" |
| | | color="#4C34FF" |
| | | v-if="!dialogReadonly" |
| | | :loading="submitting" |
| | |
| | | :title="titleEnum[dialogMode]" |
| | | @closed="visible = false" |
| | | destroy-on-close |
| | | width="auto" |
| | | :close-on-click-modal="false" |
| | | > |
| | | <div class="content" style="display: flex"> |
| | |
| | | :type="index === processList.length - 1 ? 'success' : 'info'" |
| | | :color="activity.color" |
| | | :hollow="activity.hollow" |
| | | :timestamp="activity.flowDesc.split(' ')[1]" |
| | | :timestamp="activity.createTime" |
| | | > |
| | | <div class="item-content"> |
| | | <div>{{ activity.flowDesc.split(' ')[0] }}</div> |
| | | <div>{{ activity.operator }}</div> |
| | | <div class="flowName">{{ activity.flowName }}</div> |
| | | </div> |
| | | </el-timeline-item> |
| | |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="label">巡查任务航线</div> |
| | | <div class="val">{{ getRouteName(formData.patrolRouteUrl) }}</div> |
| | | <div class="val">{{ getAirName(formData.patrolRouteUrl) }}</div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="label">推荐飞手</div> |
| | |
| | | <div class="label">关联工单</div> |
| | | <div class="val">{{ getWorkOrderName(formData.workOrderId) }}</div> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-col :span="12"> |
| | | <div class="label">巡查任务描述</div> |
| | | <div class="val">{{ formData.taskDesc }}</div> |
| | | </el-col> |
| | | </el-row> |
| | | <template v-if="['6', '7', '8'].includes(taskStatus)"> |
| | | <div class="detail-title" :style="{ marginTop: pxToRem(10) }">任务成功({{ list.length || 0 }}条)</div> |
| | | <div class="detail-title" :style="{ marginTop: pxToRem(10) }"> |
| | | 任务成果({{ taskResultList.length || 0 }}条) |
| | | </div> |
| | | <div class="imgBox"> |
| | | <div v-for="item in list"> |
| | | <div v-for="item in taskResultList"> |
| | | <el-image |
| | | v-if="item.resultUrl" |
| | | :src="item.resultUrl" |
| | |
| | | </el-row> |
| | | </el-form> |
| | | |
| | | <div class="detail-title" :style="{ marginTop: pxToRem(10) }">任务航线</div> |
| | | <!-- 地图组件 --> |
| | | <CommonCesiumMap |
| | | ref="mapRef" |
| | |
| | | :layer-mode="4" |
| | | :boundary="false" |
| | | :zoomToBoundary="false" |
| | | @ready="() => mapRef.flyBoundary()" |
| | | @ready="readyMap" |
| | | /> |
| | | </div> |
| | | </div> |
| | | |
| | | <template #footer> |
| | | <template v-if="requester"> |
| | | <el-button v-if="['1', '4'].includes(taskStatus)" @click="viewDescription" color="#F2F3F5"> |
| | | {{ gdStatusObj[taskStatus].reason }} |
| | | </el-button> |
| | | <el-button @click="statusChange(3)" v-if="taskStatus === '3'" color="#4C34FF">撤回任务</el-button> |
| | | <el-button @click="refusalToAccept" v-if="taskStatus === '6'" color="#F2F3F5">拒绝验收</el-button> |
| | | <el-button @click="statusChange(6)" v-if="taskStatus === '6'" color="#4C34FF">验收通过</el-button> |
| | | <el-button |
| | | v-if="!dialogReadonly || ['1', '4'].includes(taskStatus)" |
| | | :loading="submitting" |
| | | :disabled="submitting" |
| | | color="#4C34FF" |
| | | @click="handleSubmit" |
| | | > |
| | | 提交 |
| | | </el-button> |
| | | <el-button v-if="['1', '4'].includes(taskStatus)" @click="viewDescription"> |
| | | {{ gdStatusObj[taskStatus].reason }} |
| | | </el-button> |
| | | <el-button @click="statusChange(3)" v-if="taskStatus === '3'">撤回任务</el-button> |
| | | <el-button @click="refusalToAccept" v-if="taskStatus === '6'">拒绝验收</el-button> |
| | | <el-button @click="statusChange(6)" v-if="taskStatus === '6'">验收通过</el-button> |
| | | </template> |
| | | <template v-else> |
| | | <el-button v-if="['7'].includes(taskStatus)" @click="viewDescription"> |
| | | <el-button v-if="['7'].includes(taskStatus)" @click="viewDescription" color="#F2F3F5"> |
| | | {{ gdStatusObj[taskStatus].reason }} |
| | | </el-button> |
| | | <el-button v-if="taskStatus === '0'" @click="addDescription">拒绝签收</el-button> |
| | | <el-button v-if="taskStatus === '0'" @click="statusChange(1)">签收</el-button> |
| | | <el-button v-if="taskStatus === '3'" @click="addDescription">驳回</el-button> |
| | | <el-button v-if="taskStatus === '3'" @click="statusChange(4)">同意</el-button> |
| | | <el-button v-if="taskStatus === '0'" @click="addDescription" color="#F2F3F5">拒绝签收</el-button> |
| | | <el-button v-if="taskStatus === '0'" @click="statusChange(1)" color="#4C34FF">签收</el-button> |
| | | <el-button v-if="taskStatus === '3'" @click="addDescription" color="#F2F3F5">驳回</el-button> |
| | | <el-button v-if="taskStatus === '3'" @click="statusChange(4)" color="#4C34FF">同意</el-button> |
| | | </template> |
| | | </template> |
| | | |
| | |
| | | <script setup> |
| | | import { computed, ref, onMounted } from 'vue' |
| | | import { ElMessage } from 'element-plus' |
| | | import { fieldRules, getDictLabel } from '@ztzf/utils' |
| | | import { fieldRules, flyVisual, getDictLabel } from '@ztzf/utils' |
| | | import { gdPatrolTaskRepublish, gdFlyerPageApi, gdPatrolTaskAuditApi } from './inspectionRequestApi' |
| | | import { gdWorkOrderFlowListApi, gdWorkOrderPageApi } from '../orderManage/orderManageApi' |
| | | import { gdManageDeviceListApi } from '../orderManage/gdManageDeviceApi' |
| | |
| | | import RefuseOrderDialog from '@/views/orderView/orderManage/orderManage/RefuseOrderDialog.vue' |
| | | import RefuseOrderDialog1 from '@/views/orderView/orderManage/inspectionRequest/RefuseOrderDialog1.vue' |
| | | import { Check } from '@element-plus/icons-vue' |
| | | import { queryAirById } from '@/api/zkxt' |
| | | import * as Cesium from 'cesium' |
| | | |
| | | // 初始化表单数据 |
| | | const initForm = () => ({ |
| | |
| | | const flyerList = ref([]) |
| | | const deviceList = ref([]) |
| | | const workOrderList = ref([]) |
| | | const routeOptions = ref([ |
| | | { name: '航线1', id: '1' }, |
| | | { name: '航线2', id: '2' }, |
| | | { name: '航线3', id: '3' }, |
| | | ]) |
| | | const routeOptions = inject('routeOptions') |
| | | const getAirName = inject('getAirName') |
| | | |
| | | const gdStatusObj = { |
| | | '0': { reason: '拒绝原因', operationType: '2' }, |
| | |
| | | const processList = ref([]) |
| | | // 加载时间线list |
| | | function loadList() { |
| | | gdWorkOrderFlowListApi({ workOrderId: formData.value.id,type: '1' }).then(res => { |
| | | gdWorkOrderFlowListApi({ workOrderId: formData.value.id, type: '1' }).then(res => { |
| | | processList.value = res.data.data |
| | | }) |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | let list = ref([]) |
| | | let taskResultList = ref([]) |
| | | // 获取成果列表 |
| | | async function getList() { |
| | | async function getTaskResultList() { |
| | | if (!formData.value?.id) return |
| | | try { |
| | | const res = await gdTaskResultListApi({ patrolTaskId: formData.value.id }) |
| | | list.value = res?.data?.data ?? [] |
| | | taskResultList.value = res?.data?.data ?? [] |
| | | } finally { |
| | | } |
| | | } |
| | | |
| | | // 获取航线详情 |
| | | function getAirDetails() { |
| | | queryAirById(formData.value.patrolRouteUrl).then(res => { |
| | | const list = res.data.data.airlineWaypoints |
| | | if (!list.length) return mapRef.value?.flyBoundary() |
| | | const result = list.map(item => [Number(item.longitude), Number(item.latitude)]).flat() |
| | | viewer.entities.add({ |
| | | polyline: { |
| | | positions: Cesium.Cartesian3.fromDegreesArray(result), |
| | | clampToGround: true, |
| | | width: 3, |
| | | material: Cesium.Color.RED, |
| | | }, |
| | | }) |
| | | // 渲染起点(蓝色) |
| | | const startPoint = list[0] |
| | | viewer.entities.add({ |
| | | position: Cesium.Cartesian3.fromDegrees( |
| | | Number(startPoint.longitude), |
| | | Number(startPoint.latitude), |
| | | startPoint.height || 0 |
| | | ), |
| | | point: { |
| | | pixelSize: 12, |
| | | color: Cesium.Color.BLUE, |
| | | outlineColor: Cesium.Color.WHITE, |
| | | outlineWidth: 2, |
| | | heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, |
| | | }, |
| | | }) |
| | | // 渲染终点(红色) |
| | | const endPoint = list[list.length - 1] |
| | | viewer.entities.add({ |
| | | position: Cesium.Cartesian3.fromDegrees( |
| | | Number(endPoint.longitude), |
| | | Number(endPoint.latitude), |
| | | endPoint.height || 0 |
| | | ), |
| | | point: { |
| | | pixelSize: 12, |
| | | color: Cesium.Color.RED, |
| | | outlineColor: Cesium.Color.WHITE, |
| | | outlineWidth: 2, |
| | | heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, |
| | | }, |
| | | }) |
| | | flyVisual({ |
| | | positionsData: list.map(i => [Number(i.longitude), Number(i.latitude), i.height || 0]), |
| | | viewer, |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | // 打开弹框 |
| | | async function open({ mode = 'view', row } = {}) { |
| | | dialogMode.value = mode |
| | | formData.value = { ...initForm(), ...row } |
| | | console.log(row) |
| | | ;['6', '7', '8'].includes(row.taskStatus) && getList() |
| | | ;['6', '7', '8'].includes(row.taskStatus) && getTaskResultList() |
| | | loadList() |
| | | initMap() |
| | | } |
| | | |
| | | const readyMap = () => { |
| | | // mapRef.value?.flyBoundary() |
| | | getAirDetails() |
| | | } |
| | | |
| | | // 初始化地图实例 |
| | |
| | | .content { |
| | | display: flex; |
| | | gap: 0 20px; |
| | | height: 680px; |
| | | |
| | | .leftBox { |
| | | width: 920px; |
| | | flex: 1; |
| | | overflow: auto; |
| | | display: flex; |
| | | flex-direction: column; |
| | | .gd-cesium { |
| | | padding-top: 10px; |
| | | width: 100%; |
| | | height: 423px; |
| | | min-height: 380px; |
| | | flex: 1; |
| | | } |
| | | |
| | | } |
| | | .processBox { |
| | | width: 312px; |
| | | padding: 24px 0; |
| | | border: 1px solid #e4e4e4; |
| | | overflow: auto; |
| | | |
| | | .item-content { |
| | | position: relative; |
| | | .flowName { |
| | |
| | | <el-table-column prop="taskDesc" show-overflow-tooltip label="巡查任务描述" /> |
| | | <el-table-column label="操作" class-name="operation-btns"> |
| | | <template v-slot="{ row }"> |
| | | <el-link @click="viewDiaLogView(row)">查看</el-link> |
| | | <!-- <el-link @click="openForm('edit', row)">编辑</el-link>--> |
| | | <el-link type="primary" @click="viewDiaLogView(row)">查看</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | import { gdPatrolTaskPageApi, gdPatrolTaskRemoveApi } from './inspectionRequestApi' |
| | | import ViewDiaLog from '@/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue' |
| | | import { useStore } from 'vuex' |
| | | import { airlineListApi } from '@/api/zkxt' |
| | | |
| | | const store = useStore() |
| | | const requester = computed(() => store.state.user.userInfo?.role_id === '2014158512610869250') |
| | |
| | | selectedIds.value = rows.map(item => item.id) |
| | | } |
| | | |
| | | const routeOptions = ref([]) |
| | | const getAirName = id => { |
| | | const item = routeOptions.value.find(item => item.id === id) |
| | | return item ? item.name : id |
| | | } |
| | | provide('routeOptions', routeOptions) |
| | | provide('getAirName', getAirName) |
| | | function getAirList() { |
| | | airlineListApi({}).then(res => { |
| | | routeOptions.value = res.data.data || [] |
| | | }) |
| | | } |
| | | |
| | | // 获取字典 |
| | | function getDictList() { |
| | | getDictionaryByCode('patrolTaskType,workOrderType,deviceLoadDemand,taskStatus').then(res => { |
| | |
| | | onMounted(() => { |
| | | getList() |
| | | getDictList() |
| | | getAirList() |
| | | }) |
| | | </script> |
| | | <style scoped lang="scss"></style> |
| | |
| | | <!-- 运营收益 --> |
| | | <template> |
| | | <basic-container> |
| | | <div class="gd-table-toolbar"> |
| | | <el-button :icon="Plus" color="#4C34FF" type="primary" @click="handleAdd">新增</el-button> |
| | | <div class="gd-table-toolbar"> |
| | | <el-button :icon="Plus" color="#4C34FF" type="primary" @click="handleAdd">新增</el-button> |
| | | <el-button :icon="Delete" color="#4C34FF" :disabled="!selectedIds.length" @click="handleDelete()">删除</el-button> |
| | | </div> |
| | | <div class="gd-table-container" v-loading="loading"> |
| | | <div class="gd-table-content gd-table-content-bg"> |
| | | <el-table class="gd-table" :data="tableList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="46" /> |
| | | <el-table-column label="序号" type="index" width="60"></el-table-column> |
| | | <el-table-column prop="operatingIncome" label="营业收入" align="center"></el-table-column> |
| | | <el-table-column prop="totalCost" label="综合总成本费用" align="center"></el-table-column> |
| | | <el-table-column prop="netProfit" label="净利润" align="center"></el-table-column> |
| | | <el-table-column prop="financialIrr" label="财务内部收益率" align="center"></el-table-column> |
| | | <el-table-column prop="marketSpace" label="市场空间" align="center" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="createTime" label="创建时间" align="center"></el-table-column> |
| | | <el-table-column prop="nickName" label="创建人" align="center"></el-table-column> |
| | | <el-table-column label="操作" width="180" align="center"> |
| | | <template #default="scope"> |
| | | <!-- <el-button icon="el-icon-view" type="text" @click="handleDetail(scope.row)">查看</el-button> --> |
| | | <el-button type="text" @click="handleEdit(scope.row)">编辑</el-button> |
| | | <el-button type="text" @click="handleDelete(scope.row)">删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | <div class="gd-pagination-parent"> |
| | | <el-pagination |
| | | popper-class="gd-select-popper" |
| | | v-model:current-page="params.current" |
| | | v-model:page-size="params.size" |
| | | layout="total, prev, pager, next, sizes" |
| | | :total="total" |
| | | @change="getList" |
| | | /> |
| | | </div> |
| | | </div> |
| | | <el-dialog class="gd-dialog" append-to-body v-model="isShowEditView" :title="titleTxt" |
| | | :width="pxToRem(800)" :close-on-click-modal="false" :destroy-on-close="true" @close="handleClose"> |
| | | <div class="gd-table-container" v-loading="loading"> |
| | | <div class="gd-table-content gd-table-content-bg"> |
| | | <el-table class="gd-table" :data="tableList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="46" /> |
| | | <el-table-column label="序号" type="index" width="60"></el-table-column> |
| | | <el-table-column prop="operatingIncome" label="营业收入" align="center"></el-table-column> |
| | | <el-table-column prop="totalCost" label="综合总成本费用" align="center"></el-table-column> |
| | | <el-table-column prop="netProfit" label="净利润" align="center"></el-table-column> |
| | | <el-table-column prop="financialIrr" label="财务内部收益率" align="center"></el-table-column> |
| | | <el-table-column prop="marketSpace" label="市场空间" align="center" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="createTime" label="创建时间" align="center"></el-table-column> |
| | | <el-table-column prop="nickName" label="创建人" align="center"></el-table-column> |
| | | <el-table-column label="操作" width="180" align="center" class-name="operation-btns"> |
| | | <template #default="scope"> |
| | | <!-- <el-button icon="el-icon-view" type="text" @click="handleDetail(scope.row)">查看</el-button> --> |
| | | <el-link type="primary" @click="handleEdit(scope.row)">编辑</el-link> |
| | | <el-link type="primary" @click="handleDelete(scope.row)">删除</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | <div class="gd-pagination-parent"> |
| | | <el-pagination popper-class="gd-select-popper" v-model:current-page="params.current" |
| | | v-model:page-size="params.size" layout="total, prev, pager, next, sizes" :total="total" @change="getList" /> |
| | | </div> |
| | | </div> |
| | | <el-dialog class="gd-dialog" append-to-body v-model="isShowEditView" :title="titleTxt" :width="pxToRem(800)" |
| | | :close-on-click-modal="false" :destroy-on-close="true" @close="handleClose"> |
| | | <el-form class="gd-dialog-form" ref="ruleFormRef" :model="editParams" :rules="rules" label-width="140px"> |
| | | <el-form-item label="营业收入" prop="operatingIncome"> |
| | | <el-input class="gd-input" v-model="editParams.operatingIncome" /> |
| | | </el-form-item> |
| | | <el-form-item label="综合总成本费用" prop="totalCost"> |
| | | <el-input class="gd-input" v-model="editParams.totalCost" /> |
| | | </el-form-item> |
| | | <el-form-item label="净利润" prop="netProfit"> |
| | | <el-input class="gd-input" v-model="editParams.netProfit" /> |
| | | </el-form-item> |
| | | <el-form-item label="财务内部收益率" prop="financialIrr"> |
| | | <el-input class="gd-input" v-model="editParams.financialIrr" /> |
| | | </el-form-item> |
| | | <el-form-item label="市场空间" prop="marketSpace"> |
| | | <el-input class="gd-input" v-model="editParams.marketSpace" /> |
| | | </el-form-item> |
| | | <el-row> |
| | | <el-col span="12"> |
| | | <el-form-item label="营业收入" prop="operatingIncome"> |
| | | <el-input class="gd-input" v-model="editParams.operatingIncome" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col span="12"> |
| | | <el-form-item label="综合总成本费用" prop="totalCost"> |
| | | <el-input class="gd-input" v-model="editParams.totalCost" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row> |
| | | <el-col span="12"> |
| | | <el-form-item label="净利润" prop="netProfit"> |
| | | <el-input class="gd-input" v-model="editParams.netProfit" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col span="12"> |
| | | <el-form-item label="财务内部收益率" prop="financialIrr"> |
| | | <el-input class="gd-input" v-model="editParams.financialIrr" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row> |
| | | <el-col span="12"> |
| | | <el-form-item label="市场空间" prop="marketSpace"> |
| | | <el-input class="gd-input" v-model="editParams.marketSpace" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <!-- </div> --> |
| | | <template #footer> |
| | | <el-button color="#F2F3F5" @click="isShowEditView = false">取消</el-button> |
| | | <el-button class="save-btn" color="#4C34FF" :loading="submitting" :disabled="submitting" @click="submit(ruleFormRef)"> |
| | | 保存 |
| | | </el-button> |
| | | </template> |
| | | </el-dialog> |
| | | <!-- </div> --> |
| | | <template #footer> |
| | | <el-button color="#F2F3F5" @click="isShowEditView = false">取消</el-button> |
| | | <el-button class="" color="#4C34FF" :loading="submitting" :disabled="submitting" @click="submit(ruleFormRef)"> |
| | | 保存 |
| | | </el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </basic-container> |
| | | </template> |
| | | <script setup> |
| | | import { ElMessage, ElMessageBox, ElLoading } from 'element-plus'; |
| | | import { operatingIncomePage, operatingIncomeUpdate, operatingIncomeAdd, operatingIncomeBatchDelete } from './operatingIncomeApi'; |
| | | import { ElMessage, ElMessageBox, ElLoading } from 'element-plus' |
| | | import { operatingIncomePage, operatingIncomeUpdate, operatingIncomeAdd, operatingIncomeBatchDelete } from './operatingIncomeApi' |
| | | |
| | | let titleTxt = ref('新增') |
| | | const total = ref(0) |
| | | const params = ref({ |
| | | current: 1, |
| | | size: 10, |
| | | }); |
| | | }) |
| | | const submitting = ref(false) |
| | | const loading = ref(true) // 列表加载中 |
| | | const selectedIds = ref([]) // 勾选的ID列表 |
| | |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (!/^\d+(\.\d+)?$/.test(value)) { |
| | | callback(new Error('请输入有效的数字(整数或小数)')); |
| | | callback(new Error('请输入有效的数字(整数或小数)')) |
| | | } else { |
| | | callback(); |
| | | callback() |
| | | } |
| | | }, |
| | | trigger: 'blur' |
| | |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (!/^\d+(\.\d+)?$/.test(value)) { |
| | | callback(new Error('请输入有效的数字(整数或小数)')); |
| | | callback(new Error('请输入有效的数字(整数或小数)')) |
| | | } else { |
| | | callback(); |
| | | callback() |
| | | } |
| | | }, |
| | | trigger: 'blur' |
| | |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (!/^\d+(\.\d+)?$/.test(value)) { |
| | | callback(new Error('请输入有效的数字(整数或小数)')); |
| | | callback(new Error('请输入有效的数字(整数或小数)')) |
| | | } else { |
| | | callback(); |
| | | callback() |
| | | } |
| | | }, |
| | | trigger: 'blur' |
| | |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (!/^\d+(\.\d+)?$/.test(value)) { |
| | | callback(new Error('请输入有效的数字(整数或小数)')); |
| | | callback(new Error('请输入有效的数字(整数或小数)')) |
| | | } else { |
| | | callback(); |
| | | callback() |
| | | } |
| | | }, |
| | | trigger: 'blur' |
| | |
| | | }) |
| | | |
| | | // 勾选值设置 |
| | | function handleSelectionChange(rows) { |
| | | selectedIds.value = rows.map(item => item.id) |
| | | function handleSelectionChange (rows) { |
| | | selectedIds.value = rows.map(item => item.id) |
| | | } |
| | | |
| | | function getList() { |
| | | function getList () { |
| | | loading.value = true |
| | | operatingIncomePage(params.value).then(res => { |
| | | tableList.value = res.data.data.records || [] |
| | |
| | | loading.value = false |
| | | }) |
| | | } |
| | | function handleEdit(row) { |
| | | function handleEdit (row) { |
| | | titleTxt.value = '编辑' |
| | | isShowEditView.value = true |
| | | editParams.value = { ...row } |
| | | } |
| | | |
| | | // 删除 |
| | | async function handleDelete(row) { |
| | | const tips = row ? '该条' : '选中的项' |
| | | await ElMessageBox.confirm(`确认删除${tips}吗?`, '提示', { |
| | | type: 'warning', |
| | | customClass: 'gd-confirm-custom', |
| | | confirmButtonClass: 'gd-confirm-button', |
| | | cancelButtonClass: 'gd-confirm-cancel-button', |
| | | }) |
| | | const ids = row ? row.id : selectedIds.value |
| | | await operatingIncomeBatchDelete(ids) |
| | | ElMessage.success('删除成功') |
| | | selectedIds.value = [] |
| | | getList() |
| | | async function handleDelete (row) { |
| | | const tips = row ? '该条' : '选中的项' |
| | | await ElMessageBox.confirm(`确认删除${tips}吗?`, '提示', { |
| | | type: 'warning', |
| | | customClass: 'gd-confirm-custom', |
| | | confirmButtonClass: 'gd-confirm-button', |
| | | cancelButtonClass: 'gd-confirm-cancel-button', |
| | | }) |
| | | const ids = row ? row.id : selectedIds.value |
| | | await operatingIncomeBatchDelete(ids) |
| | | ElMessage.success('删除成功') |
| | | selectedIds.value = [] |
| | | getList() |
| | | } |
| | | |
| | | function handleAdd() { |
| | | function handleAdd () { |
| | | titleTxt.value = '新增' |
| | | isShowEditView.value = true |
| | | } |
| | | |
| | | async function submit(formValidate) { |
| | | async function submit (formValidate) { |
| | | if (!formValidate) return |
| | | await formValidate.validate((valid, fields) => { |
| | | if (valid) { |
| | |
| | | }) |
| | | } |
| | | |
| | | function handleClose() { |
| | | function handleClose () { |
| | | // 清除表单内容 |
| | | editParams.value = { |
| | | id: '', |
| | |
| | | }) |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | .operatingIncome { |
| | | height: 0; |
| | | flex: 1; |
| | | margin: 0 10px 10px 10px; |
| | | background-color: #ffffff; |
| | | padding: 10px 20px; |
| | | border-radius: 5px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | .search-box { |
| | | margin-top: 20px; |
| | | height: 40px; |
| | | } |
| | | .operatingIncome { |
| | | height: 0; |
| | | flex: 1; |
| | | margin: 0 10px 10px 10px; |
| | | background-color: #ffffff; |
| | | padding: 10px 20px; |
| | | border-radius: 5px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | :deep(.el-input) { |
| | | .el-input__wrapper { |
| | | width: 200px; |
| | | } |
| | | } |
| | | .search-box { |
| | | margin-top: 20px; |
| | | height: 40px; |
| | | } |
| | | |
| | | // 表格 |
| | | .mange-table { |
| | | height: 0; |
| | | flex: 1; |
| | | margin-top: 18px; |
| | | overflow: auto; |
| | | } |
| | | :deep(.el-pagination) { |
| | | display: flex; |
| | | justify-content: right; |
| | | } |
| | | |
| | | :deep(.el-pagination button) { |
| | | background: center center no-repeat none !important; |
| | | color: #8eb8ea !important; |
| | | } |
| | | :deep(.ztzf-select){ |
| | | .el-select__selection { |
| | | width: 200px; |
| | | } |
| | | :deep(.el-input) { |
| | | .el-input__wrapper { |
| | | width: 200px; |
| | | } |
| | | } |
| | | |
| | | .content { |
| | | |
| | | // 表格 |
| | | .mange-table { |
| | | height: 0; |
| | | flex: 1; |
| | | margin-top: 18px; |
| | | overflow: auto; |
| | | } |
| | | |
| | | :deep(.el-pagination) { |
| | | display: flex; |
| | | justify-content: right; |
| | | } |
| | | |
| | | :deep(.el-pagination button) { |
| | | background: center center no-repeat none !important; |
| | | color: #8eb8ea !important; |
| | | } |
| | | |
| | | :deep(.ztzf-select) { |
| | | .el-select__selection { |
| | | width: 200px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .content { |
| | | padding: 20px; |
| | | |
| | | |
| | | .view-table { |
| | | width: 100%; |
| | | border-collapse: collapse; |
| | | border: 1px solid #EBEEF5; |
| | | |
| | | |
| | | tr { |
| | | &:not(:last-child) { |
| | | border-bottom: 1px solid #EBEEF5; |
| | | } |
| | | |
| | | |
| | | td { |
| | | padding: 12px 10px; |
| | | |
| | | |
| | | &.label { |
| | | width: 140px; |
| | | text-align: right; |
| | |
| | | // background-color: #F5F7FA; |
| | | border-right: 1px solid #EBEEF5; |
| | | } |
| | | |
| | | |
| | | &.value { |
| | | width: 180px; |
| | | // color: #303133; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .content-edit { |
| | | .el-form { |
| | | .el-form-item { |
| | | width: 320px; |
| | | |
| | | :deep(.el-form-item__label) { |
| | | width: 140px; |
| | | } |
| | | } |
| | | |
| | | // .el-form-item:last-child { |
| | | // width: 640px; |
| | | // } |
| | | .btns { |
| | | display: flex; |
| | | justify-content: center |
| | | } |
| | | display: flex; |
| | | justify-content: center |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | :type="index === processList.length - 1 ? 'success' : 'info'" |
| | | :color="activity.color" |
| | | :hollow="activity.hollow" |
| | | :timestamp="activity.flowDesc.split(' ')[1]" |
| | | :timestamp="activity.createTime" |
| | | > |
| | | <div class="item-content"> |
| | | <div>{{ activity.flowDesc.split(' ')[0] }}</div> |
| | | <div>{{ activity.operator }}</div> |
| | | <div class="flowName">{{ activity.flowName }}</div> |
| | | </div> |
| | | </el-timeline-item> |
| | |
| | | </el-col> |
| | | </el-row> |
| | | <div class="detail-title" :style="{ marginTop: pxToRem(20) }">已选设备</div> |
| | | <el-table class="setHeight" ref="deviceTableRef" :data="deviceList" row-key="id"> |
| | | <el-table class="setHeight gd-dialog-table" ref="deviceTableRef" :data="deviceList" row-key="id"> |
| | | <el-table-column prop="nickname" label="设备名称" /> |
| | | <el-table-column prop="deviceName" label="设备型号" /> |
| | | <el-table-column prop="devicePayload" label="设备负载" /> |
| | |
| | | <div class="detail-title" :style="{ marginTop: pxToRem(20) }">工单执行范围</div> |
| | | <CommonCesiumMap |
| | | ref="mapRef" |
| | | class="leftMap gd-cesium" |
| | | class="gd-cesium" |
| | | :active="visible" |
| | | :flat-mode="false" |
| | | :terrain="true" |
| | |
| | | |
| | | <template #footer> |
| | | <template v-if="requester"> |
| | | <template v-if="!suddenlyEdit"> |
| | | <el-button |
| | | v-if="['11', '21', '23', '24', '25', '31', '60'].includes(gdStatus)" |
| | | @click="viewDescription" |
| | | color="#F2F3F5" |
| | | > |
| | | {{ gdStatusObj[gdStatus].reason }} |
| | | </el-button> |
| | | <el-button @click="addDescription" v-if="['20', '24', '25', '50'].includes(gdStatus)" color="#F2F3F5"> |
| | | {{ gdStatus === '50' ? '结算' : '申请取消' }} |
| | | </el-button> |
| | | <el-button color="#4C34FF" @click="requestModification" v-if="['20', '25'].includes(gdStatus)"> |
| | | 申请修改 |
| | | </el-button> |
| | | </template> |
| | | <el-button |
| | | v-if="['11'].includes(gdStatus) || suddenlyEdit || (!dialogReadonly && !formData.id)" |
| | | :loading="submitting" |
| | | :disabled="submitting" |
| | | color="#4C34FF" |
| | | @click="handleSubmit" |
| | | > |
| | | {{ gdStatus === '11' || !gdStatus ? '发布' : '提交修改' }} |
| | | </el-button> |
| | | <el-button v-if="['11', '21', '23', '24', '25', '31', '60'].includes(gdStatus)" @click="viewDescription"> |
| | | {{ gdStatusObj[gdStatus].reason }} |
| | | </el-button> |
| | | <el-button @click="addDescription" v-if="['20', '24', '25', '50'].includes(gdStatus)"> |
| | | {{ gdStatus === '50' ? '结算' : '申请取消' }} |
| | | </el-button> |
| | | <el-button @click="requestModification" v-if="['20', '25'].includes(gdStatus)">申请修改</el-button> |
| | | </template> |
| | | <template v-else> |
| | | <el-button v-if="['21', '23'].includes(gdStatus)" @click="viewDescription"> |
| | | <el-button v-if="['21', '23'].includes(gdStatus)" @click="viewDescription" color="#F2F3F5"> |
| | | {{ gdStatusObj[gdStatus].reason }} |
| | | </el-button> |
| | | <el-button v-if="gdStatus === '10'" @click="addDescription">拒绝接单</el-button> |
| | | <el-button v-if="gdStatus === '10'" @click="statusChange(1)">接单</el-button> |
| | | <el-button v-if="gdStatus === '22'" @click="statusChange(8)">不同意修改</el-button> |
| | | <el-button v-if="gdStatus === '22'" @click="statusChange(7)">同意修改</el-button> |
| | | <el-button v-if="gdStatus === '21'" @click="addDescription">不同意取消</el-button> |
| | | <el-button v-if="gdStatus === '21'" @click="statusChange(5)">同意取消</el-button> |
| | | <el-button v-if="gdStatus === '30'" @click="addDescription">协商修改</el-button> |
| | | <el-button v-if="gdStatus === '31'" @click="statusChange(10)">同意</el-button> |
| | | <el-button v-if="gdStatus === '10'" @click="addDescription" color="#F2F3F5">拒绝接单</el-button> |
| | | <el-button v-if="gdStatus === '10'" @click="statusChange(1)" color="#4C34FF">接单</el-button> |
| | | <el-button v-if="gdStatus === '22'" @click="addDescription" color="#F2F3F5">不同意修改</el-button> |
| | | <el-button v-if="gdStatus === '22'" @click="statusChange(7)" color="#4C34FF">同意修改</el-button> |
| | | <el-button v-if="gdStatus === '21'" @click="addDescription" color="#F2F3F5">不同意取消</el-button> |
| | | <el-button v-if="gdStatus === '21'" @click="statusChange(5)" color="#4C34FF">同意取消</el-button> |
| | | <el-button v-if="gdStatus === '30'" @click="addDescription" color="#4C34FF">协商修改</el-button> |
| | | <el-button v-if="gdStatus === '31'" @click="statusChange(10)" color="#4C34FF">同意</el-button> |
| | | </template> |
| | | </template> |
| | | |
| | |
| | | const processList = ref([]) |
| | | let viewPlane |
| | | const hasPatrolTaskList = computed(() => ['30', '40', '50', '60'].includes(String(formData.value.workOrderStatus))) |
| | | import droneIcon from '@/assets/images/orderView/orderManage/drone.png' |
| | | |
| | | const gdStatusObj = { |
| | | '10': { reason: '拒绝原因', operationType: '2' }, |
| | | '11': { reason: '拒绝原因' }, |
| | | '20': { reason: '取消原因', operationType: '3' }, |
| | | '21': { reason: '原因', operationType: '6' }, |
| | | '22': { reason: '驳回原因' }, |
| | | '22': { reason: '驳回原因', operationType: '8' }, |
| | | '23': { reason: '取消原因' }, |
| | | '24': { reason: '驳回原因', operationType: '3' }, |
| | | '25': { reason: '驳回原因', operationType: '3' }, |
| | |
| | | }) |
| | | } |
| | | |
| | | function requestModification() { |
| | | // 申请修改按钮 |
| | | async function requestModification() { |
| | | suddenlyEdit.value = true |
| | | dialogMode.value = 'edit' |
| | | await getDeviceList() |
| | | nextTick(() => { |
| | | syncSelection() |
| | | viewPlane && viewer.entities.remove(viewPlane) |
| | |
| | | }) |
| | | } |
| | | |
| | | // 填写说明弹框回调 |
| | | function rejectSuccess() { |
| | | visible.value = false |
| | | emit('success') |
| | |
| | | const str = [...pointList.value, pointList.value[0]].map(item => `${item.longitude} ${item.latitude}`).join(',') |
| | | let geom = `POLYGON((${str}))` |
| | | const res = await gdManageDeviceListApi({ |
| | | deviceIds: formData.value.recommendDeviceIds, |
| | | devicePayload: dialogMode.value === 'add' ? formData.value.deviceLoadDemand : '', |
| | | geom: dialogMode.value === 'add' ? geom : '', |
| | | deviceIds: dialogMode.value === 'add' ? '' : formData.value.recommendDeviceIds, |
| | | devicePayload: formData.value?.deviceLoadDemand, |
| | | geom: geom, |
| | | }) |
| | | deviceList.value = res?.data?.data ?? [] |
| | | } catch (error) { |
| | |
| | | } |
| | | |
| | | // 设备需求变化 |
| | | function loadDemandChange() { |
| | | async function loadDemandChange() { |
| | | formData.value.recommendDeviceIds = '' |
| | | selectedDevices.value = [] |
| | | getDeviceList() |
| | | await getDeviceList() |
| | | syncSelection() |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | watch( |
| | | () => dateRange.value, |
| | | newVal => { |
| | | const range = dateRangeFormat(dateRange.value) |
| | | formData.value.executeStartTime = range[0] |
| | | formData.value.executeEndTime = range[1] |
| | | } |
| | | ) |
| | | |
| | | // 加载时间线list |
| | | function loadList() { |
| | | gdWorkOrderFlowListApi({ workOrderId: formData.value.id,type: '0' }).then(res => { |
| | | gdWorkOrderFlowListApi({ workOrderId: formData.value.id, type: '0' }).then(res => { |
| | | processList.value = res.data.data |
| | | }) |
| | | } |
| | |
| | | }) |
| | | } |
| | | |
| | | // 同步关联场景 |
| | | // 回显选中设备 |
| | | function syncSelection() { |
| | | if (!deviceTableRef.value) return |
| | | deviceTableRef.value.clearSelection() |
| | |
| | | }) |
| | | } |
| | | |
| | | function setMapDevice() { |
| | | gdManageDeviceListApi().then(res => { |
| | | renderingDevice(res?.data?.data || []) |
| | | }) |
| | | } |
| | | |
| | | import droneIcon from '@/assets/images/orderView/orderManage/drone.png' |
| | | |
| | | function renderingDevice(list) { |
| | | // 渲染红点 |
| | | // 渲染 |
| | | function renderingAllDevice(list) { |
| | | list.forEach(item => { |
| | | const position = Cesium.Cartesian3.fromDegrees(item.longitude || 115.0, item.latitude || 27.11) |
| | | viewer.entities.add({ |
| | | position: position, |
| | | billboard: { |
| | | image: droneIcon, |
| | | width: 40, |
| | | height: 40, |
| | | width: 30, |
| | | height: 30, |
| | | verticalOrigin: Cesium.VerticalOrigin.CENTER, |
| | | }, |
| | | label: { |
| | | text: item.nickname, |
| | | font: '12px/1.5 Microsoft YaHei', |
| | | style: Cesium.LabelStyle.FILL_AND_OUTLINE, |
| | | outlineWidth: 2, |
| | | outlineColor: Cesium.Color.WHITE, |
| | | horizontalOrigin: Cesium.HorizontalOrigin.CENTER, |
| | | verticalOrigin: Cesium.VerticalOrigin.BOTTOM, |
| | | pixelOffset: new Cesium.Cartesian2(0, -20), |
| | | }, |
| | | }) |
| | | }) |
| | |
| | | // 打开弹框 |
| | | async function open({ mode = 'add', row } = {}) { |
| | | dialogMode.value = mode |
| | | formData.value = dialogMode.value === 'add' ? initForm() : row |
| | | initMap() |
| | | const allDeviceRes = await gdManageDeviceListApi() |
| | | formData.value = dialogMode.value === 'add' ? initForm() : row |
| | | renderingAllDevice(allDeviceRes?.data?.data || []) |
| | | if (dialogMode.value === 'add') { |
| | | addPolygon() |
| | | } else { |
| | |
| | | hasPatrolTaskList.value && gdPatrolTaskPage() |
| | | dialogMode.value === 'edit' ? editPolygon() : viewPolygon() |
| | | } |
| | | // setMapDevice() |
| | | |
| | | await nextTick() |
| | | await getDeviceList() |
| | | syncSelection() |
| | | getDeviceList() |
| | | highlightSelectedDevices() |
| | | } |
| | | |
| | | // 初始化地图实例 |
| | |
| | | viewer = map?.viewer || null |
| | | } |
| | | |
| | | // 高亮选中的设备 |
| | | function highlightSelectedDevices() { |
| | | const selectedIds = (formData.value.recommendDeviceIds || '').split(',').filter(Boolean) |
| | | if (!viewer?.entities) return |
| | | viewer.entities.values.forEach(entity => { |
| | | if (entity.billboard?.image?._value === droneIcon && entity.label) { |
| | | const device = deviceList.value.find(d => d.nickname === entity.label.text._value) |
| | | if (device && selectedIds.includes(String(device.id))) { |
| | | entity.label.fillColor = Cesium.Color.YELLOW |
| | | } else { |
| | | entity.label.fillColor = Cesium.Color.WHITE |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | watch(() => formData.value.recommendDeviceIds, highlightSelectedDevices) |
| | | |
| | | watch( |
| | | () => dateRange.value, |
| | | newVal => { |
| | | const range = dateRangeFormat(dateRange.value) |
| | | formData.value.executeStartTime = range[0] |
| | | formData.value.executeEndTime = range[1] |
| | | } |
| | | ) |
| | | |
| | | // 地图加载完毕 |
| | | function mapReady() { |
| | | dialogMode.value === 'add' && mapRef.value.flyBoundary() |
| | | } |
| | |
| | | .content { |
| | | display: flex; |
| | | gap: 0 20px; |
| | | height: 680px; |
| | | |
| | | .leftBox { |
| | | width: 0; |
| | | flex: 1; |
| | | display: flex; |
| | | overflow: auto; |
| | | flex-direction: column; |
| | | |
| | | .gd-cesium { |
| | | width: 100%; |
| | | height: 423px; |
| | | min-height: 380px; |
| | | flex: 1; |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | .processBox { |
| | | padding: 24px 0; |
| | | width: 312px; |
| | | border: 1px solid #e4e4e4; |
| | | overflow: auto; |
| | | |
| | | .item-content { |
| | | position: relative; |
| | | .flowName { |
| | |
| | | <template #footer> |
| | | <el-button color="#F2F3F5" @click="visible = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button> |
| | | <el-button |
| | | class="save-btn" |
| | | class="" |
| | | color="#4C34FF" |
| | | v-if="!dialogReadonly" |
| | | :loading="submitting" |
| | |
| | | <el-table-column prop="createTime" show-overflow-tooltip label="工单创建时间" /> |
| | | <el-table-column label="操作" class-name="operation-btns"> |
| | | <template v-slot="{ row }"> |
| | | <el-link @click="openFormChange(row)">查看</el-link> |
| | | <!--<el-link @click="openForm('edit', row)">编辑</el-link>--> |
| | | <el-link @click="handleDelete(row)" v-if="requester">删除</el-link> |
| | | <el-link type="primary" @click="openFormChange(row)">查看</el-link> |
| | | <!--<el-link type="primary" @click="openForm('edit', row)">编辑</el-link>--> |
| | | <el-link type="primary" @click="handleDelete(row)" v-if="requester">删除</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | function openFormChange(row) { |
| | | dialogVisible.value = true |
| | | nextTick(() => { |
| | | const mode = ['11','25'].includes(row.workOrderStatus) && requester.value ? 'edit' : 'view' |
| | | const mode = ['11'].includes(row.workOrderStatus) && requester.value ? 'edit' : 'view' |
| | | dialogRef.value?.open({ mode, row }) |
| | | }) |
| | | } |
| | |
| | | return request({ |
| | | url: `/drone-gd/workOrder/gdWorkOrderFlow/list`, |
| | | method: 'get', |
| | | params, |
| | | params:{ descs: 'create_time', ...params }, |
| | | }) |
| | | } |
| New file |
| | |
| | | <template> |
| | | <el-dialog |
| | | class="gd-dialog" |
| | | v-model="visible" |
| | | :title="titleEnum[dialogMode]" |
| | | @closed="visible = false" |
| | | destroy-on-close |
| | | :close-on-click-modal="false" |
| | | > |
| | | <el-row class="detail-row-view" v-if="dialogReadonly"> |
| | | <el-col :span="12"> |
| | | <div class="label">机构名称</div> |
| | | <div class="val">{{ formData.deptName }}</div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="label">所属区划</div> |
| | | <div class="val">{{ formData.areaName }}</div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="label">机构状态</div> |
| | | <div class="val"> {{ getDictLabel(formData.status, dictObj.institutionStatus) }}</div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="label">机构描述</div> |
| | | <div class="val">{{ formData.remark }}</div> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-form |
| | | class="gd-dialog-form" |
| | | v-else |
| | | ref="formRef" |
| | | :model="formData" |
| | | :rules="rules" |
| | | :disabled="dialogReadonly" |
| | | label-width="140px" |
| | | > |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="机构名称" prop="deptName"> |
| | | <el-input class="gd-input" v-model="formData.deptName" placeholder="请输入" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="所属区划" prop="areaCode"> |
| | | <el-select |
| | | class="gd-select" |
| | | popper-class="gd-select-popper" |
| | | v-model="formData.areaCode" |
| | | placeholder="请选择" |
| | | clearable |
| | | > |
| | | <el-option v-for="item in regionOptions" :key="item.value" :label="item.title" :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="机构状态" prop="status"> |
| | | <el-select |
| | | class="gd-select" |
| | | popper-class="gd-select-popper" |
| | | v-model="formData.status" |
| | | placeholder="请选择" |
| | | clearable |
| | | > |
| | | <el-option v-for="item in dictObj.institutionStatus" :key="item.dictKey" |
| | | :label="item.dictValue" |
| | | :value="item.dictKey" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="机构描述" prop="remark"> |
| | | <el-input |
| | | class="gd-input" |
| | | v-model="formData.remark" |
| | | placeholder="请输入" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer v-if="!dialogReadonly"> |
| | | <el-button color="#F2F3F5" @click="visible = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button> |
| | | <el-button |
| | | class="save-btn" |
| | | color="#4C34FF" |
| | | :loading="submitting" |
| | | :disabled="submitting" |
| | | @click="handleSubmit" |
| | | > |
| | | 保存 |
| | | </el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { getDictLabel } from '@ztzf/utils' |
| | | import { computed, ref, inject, nextTick } from 'vue' |
| | | import { ElMessage } from 'element-plus' |
| | | import { fieldRules } from '@ztzf/utils' |
| | | import { |
| | | agenciesSubmitApi, |
| | | agenciesDetailApi, |
| | | } from './agenciesApi' |
| | | |
| | | // 初始化表单数据 |
| | | const initForm = () => ({ |
| | | deptName: '', |
| | | areaCode: '', |
| | | status: '', |
| | | remark: '', |
| | | id: null, |
| | | }) |
| | | |
| | | const dictObj = inject('dictObj') |
| | | const regionOptions = inject('regionOptions') |
| | | |
| | | const emit = defineEmits(['success']) |
| | | const formRef = ref(null) // 表单实例 |
| | | const formData = ref(initForm()) // 表单数据 |
| | | const visible = defineModel() // 弹框显隐 |
| | | const dialogMode = ref('add') // 弹框模式 |
| | | const submitting = ref(false) // 提交中 |
| | | const dialogReadonly = computed(() => dialogMode.value === 'view') |
| | | const titleEnum = ref({ edit: '编辑', view: '查看', add: '新增' }) |
| | | |
| | | const rules = { |
| | | deptName: fieldRules(true), |
| | | areaCode: fieldRules(true), |
| | | status: fieldRules(true), |
| | | remark: fieldRules(true), |
| | | } |
| | | |
| | | // 提交新增/编辑 |
| | | async function handleSubmit() { |
| | | const isValid = await formRef.value?.validate().catch(() => false) |
| | | if (!isValid) return |
| | | submitting.value = true |
| | | try { |
| | | await agenciesSubmitApi(formData.value) |
| | | ElMessage.success(dialogMode.value === 'add' ? '新增成功' : '更新成功') |
| | | visible.value = false |
| | | emit('success') |
| | | } finally { |
| | | submitting.value = false |
| | | } |
| | | } |
| | | |
| | | // 加载详情 |
| | | async function loadDetail() { |
| | | if (!formData.value.id) return |
| | | const res = await agenciesDetailApi({ id: formData.value.id }) |
| | | const data = res?.data?.data ?? {} |
| | | // 将 status 转换为字符串类型,与字典中的 dictKey 类型保持一致 |
| | | if (data.status !== undefined) { |
| | | data.status = String(data.status) |
| | | } |
| | | // 将 areaCode 转换为字符串类型,与 regionOptions 中的 value 类型保持一致 |
| | | if (data.areaCode !== undefined) { |
| | | data.areaCode = String(data.areaCode) |
| | | } |
| | | formData.value = data |
| | | } |
| | | |
| | | // 打开弹框 |
| | | async function open({ mode = 'add', row } = {}) { |
| | | dialogMode.value = mode |
| | | formData.value = dialogMode.value === 'add' ? initForm() : row |
| | | if (dialogMode.value !== 'add') { |
| | | await loadDetail() |
| | | } |
| | | } |
| | | |
| | | defineExpose({ open }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | </style> |
| New file |
| | |
| | | import request from '@/axios' |
| | | |
| | | // 列表 |
| | | export const agenciesPageApi = params => { |
| | | return request({ |
| | | url: `/blade-system/dept/page`, |
| | | method: 'get', |
| | | params: { ...params }, |
| | | }) |
| | | } |
| | | |
| | | // 新增或编辑 |
| | | export const agenciesSubmitApi = data => { |
| | | return request({ |
| | | url: `/blade-system/dept/submit`, |
| | | method: 'post', |
| | | data, |
| | | }) |
| | | } |
| | | |
| | | // 删除 |
| | | export const agenciesRemoveApi = params => { |
| | | return request({ |
| | | url: `/blade-system/dept/remove`, |
| | | method: 'post', |
| | | params, |
| | | }) |
| | | } |
| | | |
| | | // 详情 |
| | | export const agenciesDetailApi = params => { |
| | | return request({ |
| | | url: `/blade-system/dept/detail`, |
| | | method: 'get', |
| | | params, |
| | | }) |
| | | } |
| | | |
| | | // 导入机构 |
| | | export const agenciesImportApi = (data,params) => { |
| | | return request({ |
| | | url: `/blade-system/dept/import-region`, |
| | | method: 'post', |
| | | data, |
| | | params |
| | | }) |
| | | } |
| | | |
| | | // 导出机构 |
| | | export const agenciesExportApi = params => { |
| | | return request({ |
| | | url: `/blade-system/dept/export-region`, |
| | | method: 'get', |
| | | params, |
| | | responseType: 'blob', |
| | | }) |
| | | } |
| | | |
| | | // 懒加载列表 |
| | | export const regionLazyTreeApi = params => { |
| | | return request({ |
| | | url: `/blade-system/region/lazy-tree`, |
| | | method: 'get', |
| | | params, |
| | | }) |
| | | } |
| New file |
| | |
| | | <template> |
| | | <basic-container> |
| | | <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form"> |
| | | <el-form-item label="机构名称" prop="deptName"> |
| | | <el-input |
| | | class="gd-input gray" |
| | | v-model="searchParams.deptName" |
| | | placeholder="请输入" |
| | | clearable |
| | | @clear="handleSearch" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="机构编码" prop="bindCode"> |
| | | <el-input |
| | | class="gd-input gray" |
| | | v-model="searchParams.bindCode" |
| | | placeholder="请输入" |
| | | clearable |
| | | @clear="handleSearch" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="所属区划" prop="areaCode"> |
| | | <el-select |
| | | class="gd-select gray" |
| | | popper-class="gd-select-popper" |
| | | v-model="searchParams.areaCode" |
| | | placeholder="请选择" |
| | | clearable |
| | | @change="handleSearch" |
| | | > |
| | | <el-option v-for="item in regionOptions" :key="item.value" :label="item.title" :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item class="gd-search-actions"> |
| | | <el-button :icon="RefreshRight" @click="resetForm"></el-button> |
| | | <el-button class="search-btn" :icon="Search" @click="handleSearch"></el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <div class="gd-table-toolbar"> |
| | | <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">新增机构</el-button> |
| | | <el-button :icon="Upload" @click="handleImport">导入机构</el-button> |
| | | <el-button :icon="Download" @click="handleExport">导出机构</el-button> |
| | | </div> |
| | | |
| | | <div class="gd-table-container" v-loading="loading"> |
| | | <div class="gd-table-content gd-table-content-bg"> |
| | | <el-table class="gd-table" :data="list"> |
| | | <el-table-column label="序号" width="80"> |
| | | <template v-slot="{ $index }"> |
| | | {{ ((searchParams.current - 1) * searchParams.size + $index + 1).toString().padStart(2, '0') }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="bindCode" show-overflow-tooltip label="机构编码" /> |
| | | <el-table-column prop="deptName" show-overflow-tooltip label="机构名称" /> |
| | | <el-table-column prop="areaName" show-overflow-tooltip label="所属区划" /> |
| | | <el-table-column prop="remark" show-overflow-tooltip label="机构描述" /> |
| | | <el-table-column prop="status" show-overflow-tooltip label="机构状态"> |
| | | <template v-slot="{ row }"> |
| | | {{ getDictLabel(row.status, dictObj.institutionStatus) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" class-name="operation-btns" width="310"> |
| | | <template v-slot="{ row }"> |
| | | <el-link type="primary" @click="openForm('view', row)">查看</el-link> |
| | | <el-link type="primary" @click="openForm('edit', row)">编辑</el-link> |
| | | <el-link type="primary" @click="handleDelete(row)">删除</el-link> |
| | | <el-link type="primary" @click="toggleStatus(row)">{{row.status === 1 ? '禁用' : '启用'}}</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | |
| | | <div class="gd-pagination-parent"> |
| | | <el-pagination |
| | | popper-class="gd-select-popper" |
| | | v-model:current-page="searchParams.current" |
| | | v-model:page-size="searchParams.size" |
| | | layout="total, prev, pager, next, sizes" |
| | | :total="total" |
| | | @change="getList" |
| | | /> |
| | | </div> |
| | | </div> |
| | | |
| | | <FormDiaLog ref="dialogRef" @success="getList" v-if="dialogVisible" v-model="dialogVisible" /> |
| | | |
| | | <!-- 导入机构弹框 --> |
| | | <el-dialog |
| | | class="gd-dialog" |
| | | append-to-body |
| | | v-model="isShowImportView" |
| | | title="导入机构" |
| | | :width="pxToRem(600)" |
| | | :close-on-click-modal="false" |
| | | :destroy-on-close="true" |
| | | @close="handleImportClose" |
| | | > |
| | | <el-form class="gd-dialog-form" ref="importFormRef" :model="importParams" :rules="importRules" label-width="140px"> |
| | | |
| | | <el-form-item label="上传文件" prop="file"> |
| | | {{ importFileName }} |
| | | <el-upload class="avatar-uploader" action="" :show-file-list="false" :before-upload="onImportFileBefore"> |
| | | <el-button size="small" type="primary">点击上传</el-button> |
| | | </el-upload> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button color="#F2F3F5" @click="isShowImportView = false">取消</el-button> |
| | | <el-button |
| | | class="" |
| | | color="#4C34FF" |
| | | :loading="importSubmitting" |
| | | :disabled="importSubmitting" |
| | | @click="submitImport(importFormRef)" |
| | | > |
| | | 导入 |
| | | </el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </basic-container> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { Search, RefreshRight, Plus, Delete, Upload, Download } from '@element-plus/icons-vue' |
| | | import { onMounted, ref, provide, nextTick } from 'vue' |
| | | import { ElMessage, ElMessageBox, ElUpload } from 'element-plus' |
| | | import FormDiaLog from './FormDiaLog.vue' |
| | | import { |
| | | agenciesPageApi, |
| | | agenciesRemoveApi, |
| | | agenciesImportApi, |
| | | agenciesExportApi, |
| | | regionLazyTreeApi, |
| | | agenciesSubmitApi |
| | | } from './agenciesApi' |
| | | import { getDictionaryByCode } from '@/api/system/dictbiz' |
| | | import { getDictLabel } from '@ztzf/utils' |
| | | import { pxToRem } from '@/utils/rem' |
| | | // 初始化查询参数 |
| | | const initSearchParams = () => ({ |
| | | deptName: '', // 机构名称 |
| | | bindCode: '', // 机构编码 |
| | | areaCode: '', // 所属区划 |
| | | current: 1, // 当前页 |
| | | size: 10, // 每页大小 |
| | | }) |
| | | const searchParams = ref(initSearchParams()) // 查询参数 |
| | | const total = ref(0) // 总条数 |
| | | const loading = ref(true) // 列表加载中 |
| | | const list = ref([]) // 列表数据 |
| | | const queryParamsRef = ref(null) // 查询表单实例 |
| | | const dialogRef = ref(null) // 弹框实例 |
| | | const dialogVisible = ref(false) |
| | | const regionOptions = ref([]) // 区域选项 |
| | | const dictObj = ref({}) // 字典对象 |
| | | |
| | | // 导入机构相关 |
| | | const isShowImportView = ref(false) |
| | | const importFileName = ref('') |
| | | const importParams = ref({ |
| | | isCovered: '0', |
| | | file: '', |
| | | }) |
| | | const importFormRef = ref() |
| | | const importSubmitting = ref(false) |
| | | const importRules = ref({ |
| | | file: [{ required: true, message: '请上传文件', trigger: ['change'] }], |
| | | }) |
| | | |
| | | provide('regionOptions', regionOptions) |
| | | provide('dictObj', dictObj) |
| | | |
| | | // 获取字典列表 |
| | | function getDictList() { |
| | | getDictionaryByCode('institutionStatus').then(res => { |
| | | dictObj.value = res.data.data |
| | | }) |
| | | } |
| | | |
| | | // 获取区域列表 |
| | | function getRegionList() { |
| | | regionLazyTreeApi({parentCode: '360800000000'}).then(res => { |
| | | console.log('区域列表', res.data.data); |
| | | |
| | | regionOptions.value = res.data.data || [] |
| | | }) |
| | | } |
| | | |
| | | // 获取列表 |
| | | async function getList() { |
| | | loading.value = true |
| | | try { |
| | | const res = await agenciesPageApi(searchParams.value) |
| | | list.value = res?.data?.data?.records ?? [] |
| | | total.value = res?.data?.data?.total ?? 0 |
| | | } finally { |
| | | loading.value = false |
| | | } |
| | | } |
| | | |
| | | // 查询 |
| | | function handleSearch() { |
| | | searchParams.value.current = 1 |
| | | getList() |
| | | } |
| | | |
| | | // 重置查询 |
| | | function resetForm() { |
| | | queryParamsRef.value?.resetFields() |
| | | searchParams.value.current = 1 |
| | | getList() |
| | | } |
| | | |
| | | // 新增/编辑/查看 弹框 |
| | | function openForm(mode, row) { |
| | | dialogVisible.value = true |
| | | nextTick(() => { |
| | | dialogRef.value?.open({ mode, row }) |
| | | }) |
| | | } |
| | | |
| | | // 删除 |
| | | async function handleDelete(row) { |
| | | await ElMessageBox.confirm('确认删除该条记录吗?', '提示', { |
| | | type: 'warning', |
| | | customClass: 'gd-confirm-custom', |
| | | confirmButtonClass: 'gd-confirm-button', |
| | | cancelButtonClass: 'gd-confirm-cancel-button', |
| | | }) |
| | | await agenciesRemoveApi({ ids: row.id }) |
| | | ElMessage.success('删除成功') |
| | | getList() |
| | | } |
| | | |
| | | // 切换机构状态 |
| | | async function toggleStatus(row) { |
| | | // 计算目标状态:当前为1则切换为0,当前为0则切换为1 |
| | | const targetStatus = row.status === 1 ? 0 : 1 |
| | | const actionText = targetStatus === 0 ? '禁用' : '启用' |
| | | |
| | | await ElMessageBox.confirm(`确认${actionText}该机构吗?`, '提示', { |
| | | type: 'warning', |
| | | customClass: 'gd-confirm-custom', |
| | | confirmButtonClass: 'gd-confirm-button', |
| | | cancelButtonClass: 'gd-confirm-cancel-button', |
| | | }) |
| | | |
| | | try { |
| | | await agenciesSubmitApi({ ...row, status: targetStatus }) |
| | | ElMessage.success(`${actionText}成功`) |
| | | getList() |
| | | } catch (error) { |
| | | ElMessage.error(`${actionText}失败`) |
| | | } |
| | | } |
| | | |
| | | // 导入机构 |
| | | function handleImport() { |
| | | isShowImportView.value = true |
| | | } |
| | | |
| | | // 导入机构弹框关闭 |
| | | function handleImportClose() { |
| | | importFileName.value = '' |
| | | importParams.value = { |
| | | isCovered: '0', |
| | | file: '', |
| | | } |
| | | } |
| | | |
| | | // 上传文件前处理 |
| | | function onImportFileBefore(file) { |
| | | // 执行文件上传 |
| | | let data = new FormData() |
| | | data.append('file', file) |
| | | |
| | | agenciesImportApi(data, { isCovered: importParams.value.isCovered }).then(res => { |
| | | if (res.data.code === 200) { |
| | | ElMessage.success('导入成功') |
| | | // 保存文件名 |
| | | importFileName.value = file.name |
| | | importParams.value.file = file |
| | | isShowImportView.value = false |
| | | getList() |
| | | } else { |
| | | ElMessage.error(res.msg || '导入失败') |
| | | } |
| | | }) |
| | | |
| | | return false // 阻止组件的默认上传行为 |
| | | } |
| | | |
| | | // 提交导入 |
| | | async function submitImport(formValidate) { |
| | | if (!formValidate) return |
| | | await formValidate.validate(async (valid, fields) => { |
| | | if (valid) { |
| | | importSubmitting.value = true |
| | | try { |
| | | // 这里实际上传文件的逻辑已经在onImportFileBefore中处理了 |
| | | // 这里可以添加额外的验证或逻辑 |
| | | } finally { |
| | | importSubmitting.value = false |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // 导出机构 |
| | | function handleExport() { |
| | | agenciesExportApi(searchParams.value).then(res => { |
| | | const blob = new Blob([res.data]) |
| | | const url = URL.createObjectURL(blob) |
| | | const a = document.createElement('a') |
| | | a.href = url |
| | | a.download = `机构列表${new Date().getTime()}.xlsx` |
| | | document.body.appendChild(a) |
| | | a.click() |
| | | document.body.removeChild(a) |
| | | URL.revokeObjectURL(url) |
| | | }) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getDictList() |
| | | getRegionList() |
| | | getList() |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <div> |
| | | 区划管理 |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup > |
| | | /** |
| | | * @description index |
| | | * @date 2026-01-26 (周一) 10:50:43 |
| | | */ |
| | | defineOptions({ |
| | | name: 'index' |
| | | }) |
| | | |
| | | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | </style> |
| New file |
| | |
| | | import request from '@/axios' |
| | | |
| | | // 列表 |
| | | export const agenciesPageApi = params => { |
| | | return request({ |
| | | url: `/blade-system/dept/page`, |
| | | method: 'get', |
| | | params: { ...params }, |
| | | }) |
| | | } |
| | | |
| | | // 新增或编辑 |
| | | export const agenciesSubmitApi = data => { |
| | | return request({ |
| | | url: `/blade-system/dept/submit`, |
| | | method: 'post', |
| | | data, |
| | | }) |
| | | } |
| | | |
| | | // 删除 |
| | | export const agenciesRemoveApi = params => { |
| | | return request({ |
| | | url: `/blade-system/dept/remove`, |
| | | method: 'post', |
| | | params, |
| | | }) |
| | | } |
| | | |
| | | // 详情 |
| | | export const agenciesDetailApi = params => { |
| | | return request({ |
| | | url: `/blade-system/dept/detail`, |
| | | method: 'get', |
| | | params, |
| | | }) |
| | | } |
| | | |
| | | // 导入机构 |
| | | export const agenciesImportApi = (data,params) => { |
| | | return request({ |
| | | url: `/blade-system/dept/import-region`, |
| | | method: 'post', |
| | | data, |
| | | params |
| | | }) |
| | | } |
| | | |
| | | // 导出机构 |
| | | export const agenciesExportApi = params => { |
| | | return request({ |
| | | url: `/blade-system/dept/export-region`, |
| | | method: 'get', |
| | | params, |
| | | responseType: 'blob', |
| | | }) |
| | | } |
| | | |
| | | // 懒加载列表 |
| | | export const regionLazyTreeApi = params => { |
| | | return request({ |
| | | url: `/blade-system/region/lazy-tree`, |
| | | method: 'get', |
| | | params, |
| | | }) |
| | | } |
| | |
| | | specifier: ^1.4.4 |
| | | version: 1.6.3 |
| | | '@smallwei/avue': |
| | | specifier: ^3.6.2 |
| | | version: 3.8.0 |
| | | specifier: 3.6.2 |
| | | version: 3.6.2 |
| | | '@turf/turf': |
| | | specifier: ^6.5.0 |
| | | version: 6.5.0 |
| | |
| | | specifier: ^4.1.1 |
| | | version: 4.1.1 |
| | | avue-plugin-ueditor: |
| | | specifier: ^1.0.4 |
| | | specifier: 1.0.4 |
| | | version: 1.0.4 |
| | | axios: |
| | | specifier: ^1.8.3 |
| | |
| | | version: 1.6.3 |
| | | '@smallwei/avue': |
| | | specifier: 'catalog:' |
| | | version: 3.8.0(element-plus@2.9.11(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) |
| | | version: 3.6.2(element-plus@2.9.11(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) |
| | | '@turf/turf': |
| | | specifier: 'catalog:' |
| | | version: 6.5.0 |
| | |
| | | version: 1.6.3 |
| | | '@smallwei/avue': |
| | | specifier: 'catalog:' |
| | | version: 3.8.0(element-plus@2.9.11(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) |
| | | version: 3.6.2(element-plus@2.9.11(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) |
| | | '@turf/turf': |
| | | specifier: 'catalog:' |
| | | version: 6.5.0 |
| | |
| | | version: 1.6.3 |
| | | '@smallwei/avue': |
| | | specifier: 'catalog:' |
| | | version: 3.8.0(element-plus@2.9.11(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) |
| | | version: 3.6.2(element-plus@2.9.11(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) |
| | | '@turf/turf': |
| | | specifier: 'catalog:' |
| | | version: 6.5.0 |
| | |
| | | '@sinonjs/fake-timers@8.1.0': |
| | | resolution: {integrity: sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==} |
| | | |
| | | '@smallwei/avue@3.8.0': |
| | | resolution: {integrity: sha512-htgZsATcTtBVfoHhU7i6fBNnHT222hKGVelGX7IBldNUVPdJHsdnC4gL+FMs6w83Z6GhIeXuWgleoYxllbfAnQ==} |
| | | '@smallwei/avue@3.6.2': |
| | | resolution: {integrity: sha512-Ifkt0o7KLsAMptfoNMG7qYS86OL2pEet761wWZyZGu8e48wuNNPOfqx5jnibGjx2oIoKtYUFh7tFdllOCth2EQ==} |
| | | peerDependencies: |
| | | element-plus: '>=2.2.0' |
| | | vue: '>=3.2.0' |
| | |
| | | dependencies: |
| | | '@sinonjs/commons': 1.8.6 |
| | | |
| | | '@smallwei/avue@3.8.0(element-plus@2.9.11(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3))': |
| | | '@smallwei/avue@3.6.2(element-plus@2.9.11(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3))': |
| | | dependencies: |
| | | '@element-plus/icons-vue': 2.3.2(vue@3.5.27(typescript@5.9.3)) |
| | | countup.js: 1.9.3 |
| | |
| | | - '@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@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/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)': |
| | | dependencies: |
| | | '@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 |
| | | '@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 |
| | | is-url: 1.2.4 |
| | | lodash.throttle: 4.1.1 |
| | | nanoid: 5.1.6 |
| | | slate: 0.82.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@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/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)': |
| | | dependencies: |
| | | '@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/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 |
| | | 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@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/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)': |
| | | dependencies: |
| | | '@types/event-emitter': 0.3.5 |
| | | '@uppy/core': 2.3.4 |
| | | '@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4) |
| | | dom7: 4.0.6 |
| | | dom7: 3.0.0 |
| | | event-emitter: 0.3.5 |
| | | html-void-elements: 3.0.0 |
| | | i18next: 23.16.8 |
| | |
| | | lodash.foreach: 4.5.0 |
| | | lodash.throttle: 4.1.1 |
| | | lodash.toarray: 4.4.0 |
| | | nanoid: 5.1.6 |
| | | nanoid: 3.3.11 |
| | | scroll-into-view-if-needed: 3.1.0 |
| | | slate: 0.82.1 |
| | | slate: 0.72.8 |
| | | slate-history: 0.109.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@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) |
| | | '@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) |
| | | dom7: 4.0.6 |
| | | is-hotkey: 0.2.0 |
| | | lodash.camelcase: 4.3.0 |
| | |
| | | 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/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)': |
| | | dependencies: |
| | | '@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/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/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)': |
| | | dependencies: |
| | | '@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/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 |
| | |
| | | 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/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)': |
| | | 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@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) |
| | | '@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) |
| | | 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)': |
| | | '@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)': |
| | | 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@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/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 |
| | |
| | | "@saber/nf-design-base-elp": "^1.3.0" |
| | | "@saber/nf-form-design-elp": "^1.4.1" |
| | | "@saber/nf-form-elp": "^1.4.4" |
| | | "@smallwei/avue": "^3.6.2" |
| | | "@smallwei/avue": "3.6.2" |
| | | "@turf/turf": "^6.5.0" |
| | | "animate.css": "^4.1.1" |
| | | "avue-plugin-ueditor": "^1.0.4" |
| | | "avue-plugin-ueditor": "1.0.4" |
| | | "axios": "^1.8.3" |
| | | "cesium": "1.126.0" |
| | | "codemirror": "^5.65.16" |
| | |
| | | data: { hidden_flag: 0, ...data }, |
| | | }) |
| | | } |
| | | // 位置上报 |
| | | export const reportLocationApi = data => { |
| | | return request({ |
| | | url: '/webservice/jaUserTrajectory/reportLocation', |
| | | method: 'post', |
| | | data, |
| | | }) |
| | | } |
| | |
| | | <!-- |
| | | * @Author : yuan |
| | | * @Date : 2025-12-03 14:20:57 |
| | | * @LastEditors : yuan |
| | | * @LastEditTime : 2025-12-20 16:49:02 |
| | | * @FilePath : \src\pages\map\index.vue |
| | | * @Description : |
| | | * Copyright 2025 OBKoro1, All Rights Reserved. |
| | | * 2025-12-03 14:20:57 |
| | | --> |
| | | <template> |
| | | <view class="page-wrap"> |
| | | <WebViewPlus :src="`${viewUrl}`" @webMessage="onPostMessage" /> |
| | |
| | | <div class="eventTickets" :style="{ paddingTop: topMargin + 'px' }"> |
| | | |
| | | <div class="searchTop"> |
| | | <up-search placeholder="请输入关键字搜索" :animation="true" v-model="listParams.keyword" :show-action="false" @search="handleSearch"></up-search> |
| | | <up-search placeholder="请输入关键字搜索" :animation="true" v-model="listParams.keyword" :show-action="false" @search="handleSearch" @clear="handleClear"></up-search> |
| | | </div> |
| | | <div class="listBox"> |
| | | <div class="tabs-container"> |
| | |
| | | <div class="itemContent">{{formatDate(item.createTime) }}</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 暂无数据提示 --> |
| | | <div class="noData" v-if="!loading && dataList.length === 0"> |
| | | <text>暂无数据</text> |
| | | </div> |
| | | |
| | | <!-- 加载提示 --> |
| | |
| | | |
| | | // 搜索功能 |
| | | const handleSearch = () => { |
| | | listParams.value.current = 1 |
| | | hasMore.value = true |
| | | dataList.value = [] |
| | | getDataList() |
| | | getstatusCountData() |
| | | } |
| | | // 清除搜索 |
| | | const handleClear = () => { |
| | | listParams.value.keyword = '' |
| | | listParams.value.current = 1 |
| | | hasMore.value = true |
| | | dataList.value = [] |
| | |
| | | color: #999; |
| | | width: 100%; |
| | | } |
| | | |
| | | .noData { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | height: 300rpx; |
| | | font-size: 28rpx; |
| | | color: #999; |
| | | width: 100%; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | import { defineStore } from 'pinia' |
| | | import locationUtil from '@/utils/location.js' |
| | | import { reportLocationApi } from '@/api/map.js' |
| | | |
| | | const useLocationStore = defineStore('location', { |
| | | state: () => ({ |
| | |
| | | // 位置更新间隔(毫秒) |
| | | updateInterval: 5000, |
| | | // 位置监听器ID |
| | | watcherId: null |
| | | watcherId: null, |
| | | // 上次位置上报时间 |
| | | lastReportTime: 0 |
| | | }), |
| | | |
| | | getters: { |
| | |
| | | }, |
| | | |
| | | /** |
| | | * 位置信息上报(可根据实际需求实现) |
| | | * 位置信息上报 |
| | | * @param {Object} location 位置信息 |
| | | */ |
| | | reportLocation(location) { |
| | | // 这里可以添加位置信息上报到服务器的逻辑 |
| | | // 例如:api.uploadLocation(location) |
| | | // console.log('位置上报:', location); |
| | | async reportLocation(location) { |
| | | |
| | | try { |
| | | const now = Date.now(); |
| | | // 检查是否达到上报时间间隔(1分钟) |
| | | if (now - this.lastReportTime >= 60000) { |
| | | // 构造请求参数 |
| | | const params = { |
| | | longitude: location.longitude, |
| | | latitude: location.latitude, |
| | | // reportTime: new Date().toISOString() |
| | | }; |
| | | |
| | | // 调用位置上报接口 |
| | | const result = await reportLocationApi(params); |
| | | console.log('位置上报成功:', result); |
| | | |
| | | // 更新上次上报时间 |
| | | this.lastReportTime = now; |
| | | } |
| | | } catch (error) { |
| | | console.error('位置上报失败:', error); |
| | | } |
| | | }, |
| | | |
| | | /** |