applications/drone-command/env/.env.development
@@ -2,7 +2,7 @@ # @Author : yuan # @Date : 2026-01-31 14:34:31 # @LastEditors : yuan # @LastEditTime : 2026-01-31 15:18:17 # @LastEditTime : 2026-02-02 11:01:46 # @FilePath : \applications\drone-command\env\.env.development # @Description : # Copyright 2026 OBKoro1, All Rights Reserved. @@ -16,7 +16,7 @@ #开发环境代理地址(推荐本地新建文件 .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.168 #新大屏地址 VITE_APP_DASHBOARD_URL='https://wrj.shuixiongit.com/command-center-dashboard/' applications/drone-command/src/views/api.txt
@@ -1,22 +1,34 @@ ## 列表 ## 根据多边形区域查询派出所 **接口地址**:`/area/fwDefenseSceneManage/list` **接口地址**:`/area/fwPoliceStation/queryByPolygons` **请求方式**:`GET` **请求方式**:`POST` **请求数据类型**:`application/x-www-form-urlencoded` **请求数据类型**:`application/json` **响应数据类型**:`*/*` **接口描述**:<p>传入time</p> **接口描述**:<p>传入多边形WKT字符串集合</p> **请求示例**: ```javascript { "polygons": [ "POLYGON((114.96898636473107 27.11156483383477,114.97972069576815 27.111564833834766,114.97972069576815 27.120473921808035,114.96898636473107 27.120473921808035,114.96898636473107 27.11156483383477))" ] } ``` **请求参数**: @@ -27,7 +39,8 @@ | 参数名称 | 参数说明 | 请求类型 | 是否必须 | 数据类型 | schema | | -------- | -------- | ----- | -------- | -------- | ------ | |time|时间筛选(yyyy-MM-dd HH:mm:ss)|query|false|string(date-time)|| |dto|派出所多边形区域查询入参|body|true|FwPoliceStationPolygonQueryDTO对象|FwPoliceStationPolygonQueryDTO对象| |  polygons|多边形WKT字符串集合||true|array|string| **响应状态**: @@ -35,7 +48,8 @@ | 状态码 | 说明 | schema | | -------- | -------- | ----- | |200|OK|R«List«FwDefenseSceneManageVO»»| |200|OK|R«List«FwPoliceStationVO»»| |201|Created|| |401|Unauthorized|| |403|Forbidden|| |404|Not Found|| @@ -47,18 +61,21 @@ | 参数名称 | 参数说明 | 类型 | schema | | -------- | -------- | ----- |----- | |code|状态码|integer(int32)|integer(int32)| |data|承载数据|array|FwDefenseSceneManageVO| |data|承载数据|array|FwPoliceStationVO| |  address|派出所地址|string|| |  areaCode|区域编码|string|| |  defenseLeader|防控负责人|string|| |  defenseSceneId|关联场景配置ID|integer(int64)|| |  defenseSceneName|场景配置名称|string|| |  effectiveDateEnd|有效时间-结束|string(date-time)|| |  effectiveDateStart|有效时间-开始|string(date-time)|| |  id||integer(int64)|| |  latitude|指挥点纬度|number(double)|| |  leaderPhone|防控负责人电话|string|| |  longitude|指挥点经度|number(double)|| |  sceneName|场景名称|string|| |  contactPerson|联系人|string|| |  contactPhone|联系方式|string|| |  createDept|创建部门|integer(int64)|| |  createTime|创建时间|string(date-time)|| |  createUser|创建人|integer(int64)|| |  id|主键id|integer(int64)|| |  latitude|纬度|number(double)|| |  longitude|经度|number(double)|| |  stationName|派出所名称|string|| |  status|状态(0正常 1停用)|integer(int32)|| |  updateTime|更新时间|string(date-time)|| |  updateUser|更新人|integer(int64)|| |msg|返回消息|string|| |success|是否成功|boolean|| @@ -69,17 +86,20 @@ "code": 0, "data": [ { "address": "", "areaCode": "", "defenseLeader": "", "defenseSceneId": 0, "defenseSceneName": "", "effectiveDateEnd": "", "effectiveDateStart": "", "contactPerson": "", "contactPhone": "", "createDept": 0, "createTime": "", "createUser": 0, "id": 0, "latitude": 0, "leaderPhone": "", "longitude": 0, "sceneName": "" "stationName": "", "status": 0, "updateTime": "", "updateUser": 0 } ], "msg": "", applications/drone-command/src/views/areaManage/partition/1.json
applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
@@ -226,7 +226,7 @@ <script setup> import { Close } from '@element-plus/icons-vue' import { computed, inject, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue' import { computed, inject, nextTick, onBeforeUnmount, ref, watch } from 'vue' import { ElMessage } from 'element-plus' import { fwAreaDivideDetailApi, fwAreaDivideSubmitApi } from './partitionApi' import { saveOperationLog } from '@ztzf/apis' @@ -248,8 +248,8 @@ } from '@/utils/cesium/deviceRange' import * as Cesium from 'cesium' import { AREA_TYPE_STYLE_MAP, BUFFER_LEVEL_STYLES, DEFAULT_AREA_STYLE } from '@ztzf/constants' import { fwPoliceStationListApi } from '@/views/areaManage/precinctInfo/precinctInfoApi' import { fwDeviceListApi } from '@/views/basicManage/deviceStock/fwDevice' import { fwPoliceStationQueryByPolygonsApi } from '@/views/areaManage/precinctInfo/precinctInfoApi' import { fwDeviceListByPolygonsApi } from '@/views/basicManage/deviceStock/fwDevice' import polygonIcon from '@/assets/images/areaMap/polygon.png' import rectIcon from '@/assets/images/areaMap/rect.png' import ellipseIcon from '@/assets/images/areaMap/ellipse.png' @@ -307,8 +307,13 @@ const deviceRangePrimitiveMap = new Map() const activeToolMode = ref('') const suppressDeviceFly = ref(false) const isDialogInitializing = ref(false) let lastSelectedDeviceIds = [] let deviceRangeRenderToken = 0 let deviceListTimer = null let deviceListRequestToken = 0 let policeStationListTimer = null let policeStationRequestToken = 0 const rules = { areaName: fieldRules(true, 50), @@ -411,6 +416,14 @@ () => visible.value, val => { if (!val) { if (deviceListTimer) { clearTimeout(deviceListTimer) deviceListTimer = null } if (policeStationListTimer) { clearTimeout(policeStationListTimer) policeStationListTimer = null } viewEntity && viewer?.entities?.remove(viewEntity) viewEntity = null clearActiveTool() @@ -425,6 +438,15 @@ val => { updateActiveShapeAreaType(val) } ) watch( () => shapeList.value, () => { if (isDialogInitializing.value) return queueDeviceListRefresh() queuePoliceStationRefresh() }, { deep: true } ) // 加载详情 @@ -474,6 +496,103 @@ viewer.scene.primitives.remove(primitive) } deviceRangePrimitiveMap.clear() } function clearDeviceListState () { deviceOptions.value = [] selectedDeviceRows.value = [] formData.value.deviceIds = '' if (deviceTableRef.value) { deviceTableRef.value.clearSelection() } } function clearPoliceStationState () { policeStationOptions.value = [] formData.value.policeStationId = '' } function formatWktNumber (value) { if (!Number.isFinite(Number(value))) return null return Number(value).toFixed(6) } function isSameWktPoint (left, right) { if (!left || !right) return false return Math.abs(left.lat - right.lat) < 0.000001 && Math.abs(left.lng - right.lng) < 0.000001 } function buildPolygonWktFromPoints (points) { if (!Array.isArray(points) || points.length < 3) return null const ring = points .map(resolveLngLatPoint) .filter(Boolean) .map(point => ({ lng: point.lng, lat: point.lat })) if (ring.length < 3) return null const first = ring[0] const last = ring[ring.length - 1] if (!isSameWktPoint(first, last)) { ring.push({ ...first }) } const coordText = ring .map(point => { const lng = formatWktNumber(point.lng) const lat = formatWktNumber(point.lat) if (lat === null || lng === null) return null return `${lng} ${lat}` }) .filter(Boolean) .join(', ') if (!coordText) return null return `POLYGON((${coordText}))` } function buildEllipseWktFromMeta (center, semiMajor, semiMinor) { if (!viewer) return null const resolvedCenter = resolveLngLatPoint(center) if (!resolvedCenter) return null if (!Number.isFinite(Number(semiMajor)) || !Number.isFinite(Number(semiMinor))) return null const centerCartesian = Cesium.Cartesian3.fromDegrees( resolvedCenter.lng, resolvedCenter.lat, resolvedCenter.height || 0 ) const positions = buildEllipsePositions(centerCartesian, Number(semiMajor), Number(semiMinor)) if (!positions.length) return null const points = positions .map(item => { const converted = cartesian3Convert(item, viewer) return { lng: converted.longitude, lat: converted.latitude } }) .filter(Boolean) return buildPolygonWktFromPoints(points) } function resolveShapePolygonsWkt () { const polygons = [] shapeList.value.forEach(shape => { if (!shape) return if (shape.drawType === 'buffer') { const radii = Array.isArray(shape?.meta?.bufferRadii) ? shape.meta.bufferRadii.filter(item => Number.isFinite(item) && item > 0) : [] const maxRadius = radii.length ? Math.max(...radii) : null const wkt = buildEllipseWktFromMeta(shape?.meta?.center, maxRadius, maxRadius) if (wkt) polygons.push(wkt) return } if (shape.drawType === 'ellipse') { const wkt = buildEllipseWktFromMeta(shape?.meta?.center, shape?.meta?.semiMajor, shape?.meta?.semiMinor) if (wkt) { polygons.push(wkt) return } } const points = getShapeDisplayPoints(shape) const wkt = buildPolygonWktFromPoints(points) if (wkt) polygons.push(wkt) }) return polygons } async function renderDeviceRangeSingle (device) { @@ -1069,18 +1188,77 @@ } // 获取派出所列表 async function getPoliceStationList () { const res = await fwPoliceStationListApi() function queuePoliceStationRefresh () { if (!visible.value) return if (policeStationListTimer) { clearTimeout(policeStationListTimer) } policeStationListTimer = setTimeout(() => { policeStationListTimer = null void getPoliceStationListByPolygons() }, 200) } async function getPoliceStationListByPolygons () { if (!visible.value) return const polygons = resolveShapePolygonsWkt() if (!polygons.length) { clearPoliceStationState() return } policeStationRequestToken += 1 const requestToken = policeStationRequestToken const res = await fwPoliceStationQueryByPolygonsApi({ polygons }) if (requestToken !== policeStationRequestToken) return policeStationOptions.value = res?.data?.data ?? [] await nextTick() const matched = policeStationOptions.value.find( item => String(item.id) === String(formData.value.policeStationId) ) if (!matched) { formData.value.policeStationId = '' } } // 获取设备列表 async function getDeviceList () { if (deviceOptions.value.length) return const res = await fwDeviceListApi({ isAreaSelect: 1, areaId: formData.value.id, isTrack: 1 }) function queueDeviceListRefresh () { if (!visible.value) return if (deviceListTimer) { clearTimeout(deviceListTimer) } deviceListTimer = setTimeout(() => { deviceListTimer = null void getDeviceListByPolygons() }, 200) } async function getDeviceListByPolygons () { if (!visible.value) return const polygons = resolveShapePolygonsWkt() if (!polygons.length) { clearDeviceListState() return } deviceListRequestToken += 1 const requestToken = deviceListRequestToken const res = await fwDeviceListByPolygonsApi({ isAreaSelect: 1, isTrack: 1, polygons, }) if (requestToken !== deviceListRequestToken) return deviceOptions.value = res?.data?.data ?? [] if (dialogMode.value === 'view') { deviceOptions.value = deviceOptions.value.filter(item => formData.value.deviceIds.includes(item.id)) if (dialogMode.value === 'view' && formData.value.deviceIds) { const targetIds = formData.value.deviceIds.split(',') deviceOptions.value = deviceOptions.value.filter(item => targetIds.includes(String(item.id))) } await nextTick() const prevSuppressDeviceFly = suppressDeviceFly.value suppressDeviceFly.value = true syncDeviceSelection() suppressDeviceFly.value = prevSuppressDeviceFly if (!readonly.value) { renderDeviceRanges(selectedDeviceRows.value) } } @@ -1114,14 +1292,16 @@ // 同步选择状态 function syncDeviceSelection () { if (isDialogInitializing.value && !deviceOptions.value.length) return const rows = [] const arr = formData.value.deviceIds.split(',') const arr = formData.value.deviceIds ? formData.value.deviceIds.split(',') : [] deviceOptions.value.forEach(row => { if (arr.includes(row.id)) { if (arr.includes(String(row.id))) { rows.push(row) } }) selectedDeviceRows.value = rows formData.value.deviceIds = rows.map(item => item.id).join(',') if (readonly.value) { renderDeviceRanges(selectedDeviceRows.value) return @@ -1135,9 +1315,12 @@ // 打开弹框 async function open ({ mode, row } = {}) { isDialogInitializing.value = true dialogMode.value = mode || 'add' formData.value = dialogMode.value === 'add' ? initForm() : row selectedDeviceRows.value = [] deviceOptions.value = [] policeStationOptions.value = [] shapeList.value = [] activeShapeId.value = null activeAreaType.value = '' @@ -1149,7 +1332,6 @@ viewEntity && viewer?.entities?.remove(viewEntity) viewEntity = null clearActiveTool() await getDeviceList() if (dialogMode.value === 'add') { mapRef.value?.zoomToAdminBoundary?.() // default no draw mode @@ -1169,13 +1351,20 @@ if (!readonly.value) { renderDeviceRanges(selectedDeviceRows.value) } isDialogInitializing.value = false queueDeviceListRefresh() queuePoliceStationRefresh() } onMounted(() => { getPoliceStationList() }) onBeforeUnmount(() => { if (deviceListTimer) { clearTimeout(deviceListTimer) deviceListTimer = null } if (policeStationListTimer) { clearTimeout(policeStationListTimer) policeStationListTimer = null } hideTypePanel() }) @@ -1260,10 +1449,10 @@ cursor: pointer; transition: all 0.2s ease; overflow: hidden; box-sizing: border-box; } .tool-btn:hover { background: rgba(255, 255, 255, 0.16); border-color: rgba(255, 255, 255, 0.35); transform: translateY(-1px); } applications/drone-command/src/views/areaManage/precinctInfo/precinctInfoApi.js
@@ -18,6 +18,15 @@ }) } // 多边形区域查询派出所 export const fwPoliceStationQueryByPolygonsApi = data => { return request({ url: `/drone-fw/area/fwPoliceStation/queryByPolygons`, method: 'post', data, }) } // 增加或更新 export const fwPoliceStationSubmitApi = data => { return request({ applications/drone-command/src/views/basicManage/deviceStock/fwDevice.js
@@ -18,6 +18,15 @@ }) } // 多边形过滤设备列表 export const fwDeviceListByPolygonsApi = data => { return request({ url: `/drone-fw/device/fwDevice/listByPolygons`, method: 'post', data, }) } // 增加或更新 export const fwDeviceSubmitApi = data => { return request({ applications/task-work-order/src/styles/common/cockpit.scss
@@ -31,6 +31,7 @@ &::placeholder { color: var(--tips); } color: #383874; } @@ -123,6 +124,7 @@ &::placeholder { color: var(--tips); } color: #383874; } @@ -1209,5 +1211,21 @@ // .el-form-item:nth-last-child(1) { // margin-bottom: 0; // } .el-input, .el-input-number { width: 0; flex: 1; .el-input__wrapper { padding: 0 8px; } .el-input__inner { text-align: left; &::placeholder { text-align: left; } } } } applications/task-work-order/src/views/orderView/appConfiguration/materials/FormDiaLog.vue
@@ -24,10 +24,10 @@ <div class="label">是否适用全部情形</div> <div class="val">{{ getDictLabel(String(formData.isAllScenario), dictObj.isAllScenario) }}</div> </el-col> <el-col :span="12"> <!-- <el-col :span="12"> <div class="label">所属区域</div> <div class="val">{{ formData.areaName }}</div> </el-col> </el-col> --> </el-row> <el-form @@ -86,7 +86,7 @@ </el-select> </el-form-item> </el-col> <el-col :span="12"> <!-- <el-col :span="12"> <el-form-item label="所属区域" prop="areaCode"> <el-tree-select class="gd-select" @@ -104,7 +104,7 @@ :render-after-expand="false" /> </el-form-item> </el-col> </el-col> --> </el-row> </el-form> <template #footer v-if="!dialogReadonly"> applications/task-work-order/src/views/orderView/appConfiguration/materials/index.vue
@@ -11,7 +11,7 @@ /> </el-form-item> <el-form-item label="所属区划" prop="areaCode"> <!-- <el-form-item label="所属区划" prop="areaCode"> <el-tree-select class="gd-select gray" popper-class="gd-tree-select-popper" @@ -27,7 +27,7 @@ :load="loadRegionNode" :render-after-expand="false" /> </el-form-item> </el-form-item> --> <el-form-item class="gd-search-actions"> <el-button :icon="RefreshRight" @click="resetForm"></el-button> @@ -59,7 +59,7 @@ {{ getDictLabel(String(row.isAllScenario), dictObj.isAllScenario) }} </template> </el-table-column> <el-table-column prop="areaName" show-overflow-tooltip label="所属区域" /> <!-- <el-table-column prop="areaName" show-overflow-tooltip label="所属区域" /> --> <el-table-column label="操作" class-name="operation-btns" width="200"> <template v-slot="{ row }"> <el-link type="primary" @click="openForm('view', row)">查看</el-link> applications/task-work-order/src/views/orderView/orderDataManage/evaluate/index.vue
@@ -80,7 +80,6 @@ </template> <script setup> import { Search, RefreshRight, Plus, Delete } from '@element-plus/icons-vue' import { onMounted, ref } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' import { getDeptTree } from '@/api/system/dept' import FormDiaLog from './FormDiaLog.vue' @@ -91,12 +90,15 @@ import { useStore } from 'vuex' const store = useStore() const userDepartment = store.state.user.userInfo?.dept_id const permission = computed(() => store.state.user.permission); console.log('ppppppp', permission.value.sjyy_shtg) // 初始化查询参数 const initSearchParams = () => ({ title: '', // 标题 isResolved: '', // 是否解决 current: 1, // 当前页 size: 10, // 每页大小 isQueryAll:''//是否查询所有 }) const searchParams = ref(initSearchParams()) // 查询参数 const total = ref(0) // 总条数 @@ -122,7 +124,16 @@ async function getList() { loading.value = true try { const res = await gdDataEvaluationPageApi(searchParams.value) // 根据权限设置查询参数 const params = { ...searchParams.value } if (permission.value.sjyy_shtg) { params.isQueryAll = true params.isResolved = '0' } else { params.isQueryAll = false delete params.isResolved } const res = await gdDataEvaluationPageApi(params) res?.data?.data?.records.forEach(item => { item.isTheSameDepartment = String(item.createDept) === String(userDepartment) }) applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue
@@ -538,7 +538,7 @@ .item-content { position: relative; .flowName { width: 80px; width: 72px; position: absolute; left: -120px; top: 0px; uniapps/work-wx/src/api/index.js
@@ -61,6 +61,22 @@ method: 'get' }) } export const takeoffOperationApi = data => { return request({ url: `/webservice/flightPlan/takeoffOperation`, method: 'post', data, }) } export const flightApprovalApi = data => { return request({ url: `/webservice/flightPlan/flightApproval`, method: 'post', data, }) } // 航空器注册 export const aircraftInfoSaveApi = data => { uniapps/work-wx/src/subPackages/deviceRegistration/add.vue
@@ -199,7 +199,6 @@ <template #right> <u-upload @afterRead="afterReadImage" @delete="deletePic" name="6" multiple :maxCount="1" @@ -231,13 +230,50 @@ @cancel="showType = false" /> <!-- 飞行器厂商 --> <u-picker <!-- <u-picker :show="showManufacturer" :columns="[manufacturerList]" keyName="label" @confirm="onPickerConfirmManufacturer" @cancel="showManufacturer = false" /> /> --> <u-popup :show="showManufacturer" mode="bottom" round="20" @close="showManufacturer = false" > <scroll-view scroll-y> <view class="select-header"> <u-search v-model="searchFacturerName" placeholder="请输入飞行器厂商名称关键字" @custom="getManufacturerInfoApi" ></u-search> </view> <view class="select-content"> <!-- 加载状态 --> <view v-if="loadingManufacturer" class="loading-container"> <u-loading-icon></u-loading-icon> </view> <u-radio-group v-if="!loadingManufacturer" v-model="formParams.spacecraftId" placement="column" @change="radioChange" > <u-radio :customStyle="{marginBottom: '8px'}" v-for="(item, index) in manufacturerList" :key="item.id" :label="item.label" :name="item.value" > </u-radio> </u-radio-group> </view> </scroll-view> </u-popup> <u-picker :show="showIsModified" :columns="[actionsModified]" @@ -335,6 +371,10 @@ ], }) // 搜索飞行器厂商 const searchFacturerName = ref('') // 是否改装 const actionsModified = ref([ { @@ -411,12 +451,17 @@ // 飞行器厂商 const showManufacturer = ref(false); const manufacturerList = ref([]) const loadingManufacturer = ref(false) // 选择飞行器厂商 const onPickerConfirmManufacturer = (e) => { const selected = e.value[0] formParams.value.manufacturer = selected.value formParams.value.manufacturerText = selected.label showManufacturer.value = false } function radioChange(value) { formParams.value.manufacturer = value formParams.value.manufacturerText = manufacturerList.value.find(item => item.value === value)?.label || '' } // 飞行器类型 const showType = ref(false); @@ -589,10 +634,20 @@ // } // 获取无人机厂商 function getManufacturerInfoApi() { if (searchFacturerName.value === '') { uni.showToast({ title: '请输入搜索内容', icon: 'none' }) return } loadingManufacturer.value = true manufacturerInfoApi({ unitName: searchFacturerName.value, current: 1, size: 1000, }).then(res => { loadingManufacturer.value = false manufacturerList.value = res.data.data.records.map(item => ({ ...item, label: item.unitName, @@ -601,7 +656,7 @@ }) } onMounted(async () => { getManufacturerInfoApi() // getManufacturerInfoApi() // 动态从外部URL导入xzqhData,确保在使用前已初始化 // 注意:直接动态导入外部URL可能会有跨域或构建问题,建议检查服务器CORS设置 const response = await fetch('https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ja-app-wx/xzqh/index.json') @@ -711,5 +766,38 @@ margin-right: 8rpx; } } .uni-scroll-view { display: flex; flex-direction: column; } .select-header { display: flex; justify-content: space-between; padding: 20rpx 20rpx; font-size: 32rpx; color: #222324; .select-header-btn { display: flex; font-size: 28rpx; color: #1D6FE9; .cancel-btn { color: #86909C; margin-right: 20rpx; } } } .select-content { height: 400rpx; text-align: center; padding: 20rpx 20rpx; .loading-container { height: 400rpx; display: flex; align-items: center; justify-content: center; } } } </style> uniapps/work-wx/src/subPackages/flightApplication/add.vue
@@ -209,14 +209,14 @@ <u-form-item label="飞行器" labelWidth="230rpx" prop="aircraftId" prop="spacecraftText" :borderBottom="true" required ref="item2" @click="isShowAircraftInfo = true" > <u-input v-model="formParams.aircraftText" v-model="formParams.spacecraftText" disabled disabledColor="#ffffff" placeholder="请选择" @@ -231,7 +231,7 @@ <u-form-item label="飞手" labelWidth="230rpx" prop="pilotId" prop="pilotText" :borderBottom="true" ref="item2" required @@ -276,7 +276,7 @@ <u-form-item label="航线" labelWidth="230rpx" prop="routeId" prop="selectedRouteId" :borderBottom="true" ref="item2" required @@ -350,21 +350,85 @@ <!-- <u-calendar :show="isShowTimeRange" mode="date" @confirm="onConfirmTimeRange" @close="isShowTimeRange = false" :close-on-click-overlay="true"></u-calendar> --> <!-- <u-calendar :show="isShowTimeRange" mode="range" @confirm="onConfirmTimeRange" @close="isShowTimeRange = false" :close-on-click-overlay="true" :allow-same-day="true" :show-time="true" time-format="HH:mm:ss"></u-calendar> --> <!-- 飞行器 --> <u-picker <!-- <u-picker :show="isShowAircraftInfo" :columns="[aircraftInfoList]" keyName="label" @confirm="onPickerAircraftInfo" @cancel="isShowAircraftInfo = false" /> /> --> <u-popup :show="isShowAircraftInfo" mode="bottom" round="20" @close="isShowAircraftInfo = false" > <scroll-view scroll-y> <view class="select-header"> <view>请选择飞行器</view> <view class="select-header-btn"> <view class="cancel-btn" @click="isShowAircraftInfo = false">取消</view> <view @click="onPickerAircraftInfo">确定</view> </view> </view> <view class="select-content"> <up-checkbox-group v-model="formParams.spacecraftId" placement="column" @change="checkboxChange" > <up-checkbox :customStyle="{marginBottom: '8px'}" v-for="(item, index) in aircraftInfoList" :key="item.id" :label="item.label" :name="item.value" > </up-checkbox> </up-checkbox-group> </view> </scroll-view> </u-popup> <!-- 飞手 --> <u-picker <!-- <u-picker :show="isShowPilotInfo" :columns="[pilotInfoList]" keyName="label" @confirm="onPickerPilotInfo" @cancel="isShowPilotInfo = false" /> /> --> <u-popup :show="isShowPilotInfo" mode="bottom" round="20" @close="isShowPilotInfo = false" > <scroll-view scroll-y> <view class="select-header"> <view>请选择飞手</view> <view class="select-header-btn"> <view class="cancel-btn" @click="isShowPilotInfo = false">取消</view> <view @click="onPickerPilotInfo">确定</view> </view> </view> <view class="select-content"> <up-checkbox-group v-model="formParams.pilotId" placement="column" @change="checkboxPilotChange" > <up-checkbox :customStyle="{marginBottom: '8px'}" v-for="(item, index) in pilotInfoList" :key="item.id" :label="item.label" :name="item.value" > </up-checkbox> </up-checkbox-group> </view> </scroll-view> </u-popup> <!-- 空域 --> <u-picker :show="isShowAirspaceInfo" @@ -427,13 +491,13 @@ flightStartTime: '', // 飞行活动开始时间 flightEndTime: '', // 飞行活动结束时间 weatherCondition: '', // 气象条件 spacecraftId: '', // 航天器id spacecraftId: [], // 航天器id spacecraftText: '', // 航天器文本 pilotId: '', // 飞手id pilotId: [], // 飞手id pilotText: '', // 飞手文本 airspaceId: '', // 空域id airspaceText: '', // 空域文本 routeId: '', // 航线id selectedRouteId: '', // 航线id routeText: '', // 航线文本 }) const rules = ref({ @@ -491,16 +555,16 @@ endTime: [ { required: true, message: '请选择飞行活动结束时间', trigger: 'change' } ], spacecraftId: [ spacecraftText: [ { required: true, message: '请选择飞行器', trigger: 'change' } ], pilotId: [ pilotText: [ { required: true, message: '请选择飞手', trigger: 'change' } ], airspaceId: [ { required: true, message: '请选择空域', trigger: 'change' } ], routeId: [ selectedRouteId: [ { required: true, message: '请选择航线', trigger: 'change' } ], }) @@ -550,11 +614,11 @@ const endTime = ref(Date.now()); // 设置默认值为当前时间戳 const onConfirmStartTime = (e) => { formParams.value.flightStartTime = dayjs(e.value).format('YYYY-MM-DD HH:mm') formParams.value.flightStartTime = dayjs(e.value).format('YYYY-MM-DD HH:mm:ss') isShowStartTime.value = false } const onConfirmEndTime = (e) => { formParams.value.flightEndTime = dayjs(e.value).format('YYYY-MM-DD HH:mm') formParams.value.flightEndTime = dayjs(e.value).format('YYYY-MM-DD HH:mm:ss') isShowEndTime.value = false } @@ -574,10 +638,17 @@ })) }) } const onPickerAircraftInfo = (e) => { const selected = e.value[0] formParams.value.aircraftId = selected.value formParams.value.aircraftText = selected.label // const onPickerAircraftInfo = (e) => { // const selected = e.value[0] // formParams.value.spacecraftId = selected.value // formParams.value.aircraftText = selected.label // isShowAircraftInfo.value = false // } function checkboxChange(val) { formParams.value.spacecraftId = val.join(',') formParams.value.spacecraftText = aircraftInfoList.value.filter(item => val.includes(item.value)).map(item => item.label).join(',') } const onPickerAircraftInfo = () => { isShowAircraftInfo.value = false } // 获取飞手信息 @@ -594,10 +665,14 @@ })) }) } function checkboxPilotChange(val) { formParams.value.pilotId = val.join(',') formParams.value.pilotText = pilotInfoList.value.filter(item => val.includes(item.value)).map(item => item.label).join(',') } const onPickerPilotInfo = (e) => { const selected = e.value[0] formParams.value.pilotId = selected.value formParams.value.pilotText = selected.label // const selected = e.value[0] // formParams.value.pilotId = selected.value // formParams.value.pilotText = selected.label isShowPilotInfo.value = false } // 获取空域信息 @@ -636,7 +711,7 @@ } const onPickerFlightRouteInfo = (e) => { const selected = e.value[0] formParams.value.routeId = selected.value formParams.value.selectedRouteId = selected.value formParams.value.routeText = selected.label isShowFlightRouteInfo.value = false } @@ -866,5 +941,33 @@ margin-right: 8rpx; } } .uni-scroll-view { display: flex; flex-direction: column; } .select-header { display: flex; justify-content: space-between; padding: 20rpx 20rpx; font-size: 32rpx; color: #222324; .select-header-btn { display: flex; font-size: 28rpx; color: #1D6FE9; .cancel-btn { color: #86909C; margin-right: 20rpx; } } } .select-content { height: 400rpx; text-align: center; padding: 20rpx 20rpx; } } </style> uniapps/work-wx/src/subPackages/flightApplication/details.vue
@@ -136,7 +136,7 @@ ref="item1" > <u-input v-model="formParams.weatherCondition" v-model="formParams.weatherCondition" readonly border="none" ></u-input> @@ -185,39 +185,39 @@ <u-form-item label="航线" labelWidth="230rpx" prop="routeId" prop="selectedRouteId" :borderBottom="true" ref="item2" > <u-input v-model="formParams.routeId" v-model="formParams.selectedRouteId" readonly border="none" ></u-input> </u-form-item> <u-popup :show="applyShow" :round="10" mode="center" @close="close" :closeable="true" :mask-close-able="true"> <u-form labelPosition="top" :model="formParams" :rules="rules" ref="formRef"> <u-form labelPosition="top" :model="formParamsTime" :rules="rulesTime" ref="formTimeRef"> <u-form-item label="计划申请起飞时间" labelWidth="260rpx" prop="actualTakeoffTime" prop="takeOffStartTime" :borderBottom="true" ref="item1" @click="isShowStartTime = true" required > <u-input v-model="formParams.actualTakeoffTime" border="none" placeholder="请选择" suffixIcon="calendar"></u-input> <u-input v-model="formParamsTime.takeOffStartTime" border="none" placeholder="请选择" suffixIcon="calendar"></u-input> </u-form-item> <u-form-item label="计划申请结束时间" labelWidth="260rpx" prop="actualLandingTime" prop="takeOffEndTime" :borderBottom="true" ref="item1" @click="isShowEndTime = true" required > <u-input v-model="formParams.actualLandingTime" border="none" placeholder="请选择" suffixIcon="calendar"></u-input> <u-input v-model="formParamsTime.takeOffEndTime" border="none" placeholder="请选择" suffixIcon="calendar"></u-input> </u-form-item> <u-datetime-picker @@ -239,10 +239,10 @@ @cancel="isShowEndTime = false"> </u-datetime-picker> </u-form> <u-button @click="submitApply" color="#1D6FE9">确定</u-button> <u-button @click="submitSure" color="#1D6FE9">确定</u-button> </u-popup> </u-form> <u-button v-if="formParams.planApprovalStatus === '99'" @click="submitApply" color="#1D6FE9">申请</u-button> <u-button v-if="formParams.planApprovalStatus === '99' && (formParams.planStatus === '0')" @click="submitApply" color="#1D6FE9">申请</u-button> </view> </template> <script setup> @@ -252,6 +252,7 @@ aircraftInfoPageInfoOfMyApi, pilotInfoPageInfoOfMyApi, flightAirspacePageInfoApi, flightApprovalApi } from '@/api/index' import { ref, computed, onMounted } from 'vue' import dayjs from 'dayjs' @@ -261,8 +262,20 @@ const appStore = useAppStore() const formRef = ref(null); const formTimeRef = ref(null); const formParams = ref({}) const rules = ref({}) const formParamsTime = ref({ id: '', takeOffStartTime: '', takeOffEndTime: '', planStatus: '1', }) const rulesTime = ref({ takeOffStartTime: [{ required: true, message: '请选择计划申请起飞时间', trigger: ['blur'] }], takeOffEndTime: [{ required: true, message: '请选择计划申请结束时间', trigger: ['blur'] }], }) // 任务类型 const actionsFlightTaskType = ref(appStore.getTaskType) @@ -284,11 +297,11 @@ const endTime = ref(Date.now()); // 设置默认值为当前时间戳 const onConfirmStartTime = (e) => { formParams.value.actualTakeoffTime = dayjs(e.value).format('YYYY-MM-DD HH:mm') formParamsTime.value.takeOffStartTime = dayjs(e.value).format('YYYY-MM-DD HH:mm:ss') isShowStartTime.value = false } const onConfirmEndTime = (e) => { formParams.value.actualLandingTime = dayjs(e.value).format('YYYY-MM-DD HH:mm') formParamsTime.value.takeOffEndTime = dayjs(e.value).format('YYYY-MM-DD HH:mm:ss') isShowEndTime.value = false } @@ -370,10 +383,28 @@ applyShow.value = true } async function submitSure() { // 校验时间 await formTimeRef.value.validate() formParamsTime.value.id = formParams.value.id flightApprovalApi(formParamsTime.value).then(res => { if (res.data.code === 200) { uni.showToast({ title: '操作成功', icon: 'success', }) // 跳转申请列表页 uni.navigateTo({ url: '/subPackages/flightApplication/index', }) } }) } function close() { // 清空时间 formParams.value.actualTakeoffTime = '' formParams.value.actualLandingTime = '' formParamsTime.value.takeOffStartTime = '' formParamsTime.value.takeOffEndTime = '' applyShow.value = false } @@ -381,7 +412,6 @@ flightPlanDetailsApi(options.id).then(res => { // return const result = res.data.data console.log(result, '7777') formParams.value = result // 字典 formParams.value.flightRule = actionsFlightRule.value.find(item => item.dictValue === result.flightRule)?.dictLabel || '无' @@ -389,11 +419,19 @@ formParams.value.planType = actionsPlanType.value.find(item => item.dictValue === result.planType)?.dictLabel || '无' formParams.value.flightTaskType = actionsFlightTaskType.value.find(item => item.dictValue === result.flightTaskType)?.dictLabel || '无' // 数据 formParams.value.routeId = result?.routeInfo?.name || '无' // 航线 formParams.value.selectedRouteId = result?.routeInfo?.name || '无' // 空域 formParams.value.airspaceId = result?.airspaceInfo?.taskName || '无' formParams.value.aircraftId = result?.airspaceInfo?.aircraftInfoList?.map(item => item.name).join(',') || '无' // 飞行器 formParams.value.aircraftId = result?.aircraftInfoList?.map(item => item.name).join(',') || '无' // 飞手 formParams.value.pilotId = result?.operatorInfoList?.map(item => item.name).join(',') || '无' // 日期赋值 formParamsTime.value.takeOffStartTime = dayjs(result.flightStartTime).format('YYYY-MM-DD HH:mm:ss') formParamsTime.value.takeOffEndTime = dayjs(result.flightEndTime).format('YYYY-MM-DD HH:mm:ss') }) }) onMounted(() => { uniapps/work-wx/src/subPackages/flightApplication/index.vue
@@ -25,11 +25,9 @@ <u-image :src="spSvg" class="icon" width="16" height="16"></u-image> <view class="name">{{approvalRecord.flightPlanName}}</view> </view> <view class="status" :class="getStatusClass(approvalRecord.planApprovalStatus)"> {{ approvalRecord.planApprovalStatusLabel || ''}} </view> </view> <view class="txt">计划起飞状态:{{approvalRecord.fly_activity_takeoff_status || ''}}</view> <view class="txt">审批状态: <span :class="getStatusClass(approvalRecord.planApprovalStatus)">{{approvalRecord.planApprovalStatusLabel || ''}}</span></view> <view class="txt">计划起飞状态:<span :class="getPlanStatusClass(approvalRecord.planStatus)">{{approvalRecord.flyActivityTakeoffStatusLabel || ''}}</span></view> <view class="txt">飞行器:{{approvalRecord.spacecraftLabel || '无'}}</view> <view class="txt">飞行任务:{{approvalRecord.flightTaskTypeLabel || ''}}</view> <view class="txt">飞行起飞时间:{{approvalRecord.flightStartTime || ''}}</view> @@ -81,6 +79,27 @@ } } const getPlanStatusClass = (status) => { switch (status) { case '0': return 'Sred' case '1': return 'Ssqz' case '2': return 'Sjz' case '3': return 'SOrange' case '99': return 'Syzz' case '-1': return 'Ssqbh' case '-2': return 'Sysx' default: return '' } } // 获取飞行器信息 const aircraftInfoList = ref([]) async function getAircraftInfo() { @@ -114,9 +133,12 @@ const newData = res.data.data.records || [] // 处理字典数据 newData.forEach(item => { item.spacecraftLabel = aircraftInfoList.value.find(info => info.value === item.spacecraftId)?.label || '无' item.spacecraftLabel = aircraftInfoList?.value.filter(info => item.spacecraftId?.split(',').includes(info.value)).map(info => info.label).join('、') || '无' // 审批状态 item.planApprovalStatusLabel = appStore.flyActivityStatus.find(status => status.dictValue === item.planApprovalStatus)?.dictLabel || '无' // 计划起飞状态 item.flyActivityTakeoffStatusLabel = appStore.flyActivityTakeoffStatus.find(status => status.dictValue === item.planStatus)?.dictLabel || '无' // 飞行任务 item.flightTaskTypeLabel = appStore.taskType.find(type => type.dictValue === item.flightTaskType)?.dictLabel || '无' }) // 如果是第一页,直接替换数据;否则追加数据 @@ -275,18 +297,7 @@ color: #FFFFFF; padding: 0 6rpx; &.Sorange { background: #FF9604; } &.Sred { background: #F8422A; } &.Sgreen { background: #17A836; } &.Sblue { background: #1D6FE9; } } } @@ -295,6 +306,38 @@ font-size: 12px; color: #86909C; margin-bottom: 14rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .Sorange { color: #FF9604; } .Sred { color: #F8422A; } .Sgreen { color: #17A836; } .Sblue { color: #1D6FE9; } .Sjz { color: #0088FF; } .Syzz { color: #002BFF; } .Ssqbh { color: #FF383C; } .Sysx { color:#414141; } .Ssqz { color: #FF9500; } } </style>