吉安感知网项目-前端
张含笑
2026-01-23 9197799574b4e1cb918771f424b93c11c7da8317
Merge remote-tracking branch 'origin/master'
9 files modified
784 ■■■■ changed files
uniapps/work-wx/src/pages/equipmentManagement/index.vue 9 ●●●●● patch | view | raw | blame | history
uniapps/work-wx/src/pages/legalPolicy/index.vue 11 ●●●● patch | view | raw | blame | history
uniapps/work-wx/src/pages/page/index.vue 98 ●●●●● patch | view | raw | blame | history
uniapps/work-wx/src/store/modules/app/index.js 52 ●●●●● patch | view | raw | blame | history
uniapps/work-wx/src/subPackages/deviceRegistration/add.vue 96 ●●●●● patch | view | raw | blame | history
uniapps/work-wx/src/subPackages/flightApplication/add.vue 109 ●●●●● patch | view | raw | blame | history
uniapps/work-wx/src/subPackages/flightApplication/details.vue 157 ●●●●● patch | view | raw | blame | history
uniapps/work-wx/src/subPackages/flightApplication/index.vue 87 ●●●● patch | view | raw | blame | history
uniapps/work-wx/src/subPackages/regulationsDetail/details.vue 165 ●●●● patch | view | raw | blame | history
uniapps/work-wx/src/pages/equipmentManagement/index.vue
@@ -29,6 +29,11 @@
import addSvg from '@/static/images/add.png'
import droneSvg from '@/static/images/drone.png'
import { aircraftInfoPageInfoOfMyApi } from '@/api/index.js'
// 获取store中的数据 字典
import { useAppStore, useUserStore } from "@/store";
const appStore = useAppStore()
const equipmentList = ref([])
const noticeTitle = ref('')
const formParams = ref({
@@ -50,6 +55,10 @@
  try {
    const res = await aircraftInfoPageInfoOfMyApi(formParams.value)
    const newData = res.data.data.records || []
    // 处理type 字典
    newData.forEach(item => {
      item.type = appStore.getProType.find(type => type.value === item.type)?.label || '暂无'
    })
    // 如果是第一页,直接替换数据;否则追加数据
    if (formParams.value.current === 1) {
      equipmentList.value = newData
uniapps/work-wx/src/pages/legalPolicy/index.vue
@@ -13,7 +13,7 @@
          </view>
          <view class="right">
            <view class="r-top">{{ item.title }}</view>
            <view class="r-middle">{{ item.description || '暂无描述' }}</view>
            <view class="r-middle">{{ item.noticeDesc || '暂无描述' }}</view>
            <view class="r-bottom">{{ item.time || '暂无' }}</view>
          </view>
        </view>
@@ -43,6 +43,7 @@
  size: 10,
  noticeType: 2,
  noticeTitle: noticeTitle.value,
  isAsc: true
})
const tabClick = (val) => {
@@ -50,7 +51,7 @@
     formParams.value.noticeType = 2
  } else {
    formParams.value.noticeType = 1
  }
  }
  formParams.value.current = 1
  announcementList.value = []
  getSysNoticeList()
@@ -122,7 +123,7 @@
  height: 100%;
  display: flex;
  flex-direction: column;
   :deep(.u-search) {
    padding: 10px 20px;
    height: 68rpx;
@@ -141,7 +142,7 @@
  .tabs-container >>> .u-tabs__nav {
    width: auto !important;
  }
  }
  .content {
    width: 100%;
    height: 0;
@@ -180,7 +181,7 @@
      .r-bottom {
        font-weight: 400;
        font-size: 13px;
        color: #86909C;
        color: #86909C;
        margin-top: 10rpx;
      }
    }
uniapps/work-wx/src/pages/page/index.vue
@@ -86,6 +86,11 @@
  import docSvg from '@/static/images/doc.png'
  import lbBottomPng from '@/static/images/lb_bottom.png'
  import { sysNoticePageInfoApi, droneFlightTaskApi } from '@/api/index'
  import { flightTaskApi,flightRulesApi,flightModeApi,flightPlanApi,flyActivityStatusApi,proTypeApi} from '@/api/index'
import { useAppStore } from "@/store";
const appStore = useAppStore()
const lbList = reactive([]);
// lbPng 轮播图 5次
for (let i = 0; i < 5; i++) {
@@ -150,7 +155,7 @@
    announcementList.value = res.data.data.records.map(item => ({
      ...item,
      title: item.taskName,
      description: item.remark,
      description: item.noticeDesc,
      time: item.createTime,
      num: item.num,
      like: item.like,
@@ -173,6 +178,7 @@
        current: 1,
        size: 3,
        noticeType: val,
        isAsc: true
      })
      // 只需要取前3条 公告
      if (val === 1) {
@@ -221,10 +227,98 @@
    })
  }
  // 获取任务类型
const actionsFlightTaskType = ref([])
function getTaskType() {
    flightTaskApi().then(res => {
        actionsFlightTaskType.value = res.data.data.map(item => ({
            ...item,
            label: item.dictLabel || '暂无',
            value: item.dictValue || '暂无',
        }))
        // 存储到store
        appStore.setTaskType(actionsFlightTaskType.value)
    })
}
// 获取飞行模式
const actionsFlightMode = ref([])
function getFlightMode() {
    flightModeApi().then(res => {
        actionsFlightMode.value = res.data.data.map(item => ({
            ...item,
            label: item.dictLabel || '暂无',
            value: item.dictValue || '暂无',
        }))
        // 存储到store
        appStore.setFlightMode(actionsFlightMode.value)
    })
}
// 获取飞行规则
const actionsFlightRule = ref([])
function getFlightRules() {
    flightRulesApi().then(res => {
        actionsFlightRule.value = res.data.data.map(item => ({
            ...item,
            label: item.dictLabel || '暂无',
            value: item.dictValue || '暂无',
        }))
        // 存储到store
        appStore.setFlightRules(actionsFlightRule.value)
    })
}
// 获取飞行计划
const actionsPlanType = ref([])
function getFlightPlan() {
    flightPlanApi().then(res => {
        actionsPlanType.value = res.data.data.map(item => ({
            ...item,
            label: item.dictLabel || '暂无',
            value: item.dictValue || '暂无',
        }))
        // 存储到store
        appStore.setFlightPlan(actionsPlanType.value)
    })
}
// 获取审批状态
const flyActivityStatus = ref([])
function getFlyActivityStatus() {
    flyActivityStatusApi().then(res => {
        flyActivityStatus.value = res.data.data.map(item => ({
            ...item,
            label: item.dictLabel || '暂无',
            value: item.dictValue || '暂无',
        }))
        // 存储到store
        appStore.setFlyActivityStatus(flyActivityStatus.value)
    })
}
// 获取飞行器类型
const typeList = ref([])
function getProTypeApi() {
    proTypeApi().then(res => {
        typeList.value = res.data.data.map(item => ({
            ...item,
            label: item.dictLabel || '暂无',
            value: item.dictValue || '暂无',
        }))
        // 存储到store
        appStore.setProType(typeList.value)
    })
}
onMounted(() => {
  getFlightAirspaceList()
  getSysNoticeList(2)
  getSysNoticeList(1)
  // 获取字典
  getTaskType()
  getFlightMode()
  getFlightRules()
  getFlightPlan()
  getFlyActivityStatus()
  getProTypeApi()
})
</script>
@@ -320,7 +414,7 @@
        justify-content: space-between;
        font-weight: 400;
        font-size: 13px;
        color: #86909C;
        color: #86909C;
        margin-top: 10rpx;
      }
    }
uniapps/work-wx/src/store/modules/app/index.js
@@ -10,7 +10,13 @@
    theme: storage.get(THEME_KEY) || 'light',
    deviceUpdateKey: 0, //设备刷新key
    jobUpdateKey: 0, //任务刷新key
    // 字典
    taskType: [], // 任务类型
    flightMode: [], // 飞行模式
    flightRules: [], // 飞行规则
    flightPlan: [], // 飞行计划
    flyActivityStatus: [], // 飞行活动状态
    proType: [], // 飞行器类型
  }),
  getters: {
    getSystemInfo (state) {
@@ -18,14 +24,53 @@
    },
    getTheme (state) {
      return state.theme
    }
    },
    // 字典
    getTaskType (state) {
      return state.taskType
    },
    getFlightMode (state) {
      return state.flightMode
    },
    getFlightRules (state) {
      return state.flightRules
    },
    getFlightPlan (state) {
      return state.flightPlan
    },
    getFlyActivityStatus (state) {
      return state.flyActivityStatus
    },
    getProType (state) {
      return state.proType
    },
  },
  actions: {
    // 设置字典
    setTaskType (data) {
      this.taskType = data
    },
    setFlightMode (data) {
      this.flightMode = data
    },
    setFlightRules (data) {
      this.flightRules = data
    },
    setFlightPlan (data) {
      this.flightPlan = data
    },
    setFlyActivityStatus (data) {
      this.flyActivityStatus = data
    },
    setProType (data) {
      this.proType = data
    },
    setSystemInfo (info) {
      this.systemInfo = info
    },
    setDeviceUpdateKeyAdd () {
      console.log(111, this.deviceUpdateKey + 1)
      this.deviceUpdateKey = this.deviceUpdateKey + 1
    },
    setJobUpdateKeyAdd (state, data) {
@@ -76,6 +121,7 @@
        })
      })
    }
  }
})
uniapps/work-wx/src/subPackages/deviceRegistration/add.vue
@@ -260,7 +260,7 @@
        @cancel="showPurchaseDate = false"
        />
        <!-- 所属区域 -->
        <u-cascader
        <u-cascader
            v-model:show="isShowRegion"
            v-model="formParams.regionCode"
            :data="areaData"
@@ -282,6 +282,10 @@
import { aircraftInfoSaveApi,uploadFileApi, areaDataApi, proTypeApi, manufacturerInfoApi } from '@/api/index'
import { ref, computed, onMounted } from 'vue'
import dayjs from 'dayjs'
// 获取store中的数据 字典
import { useAppStore, useUserStore } from "@/store";
const appStore = useAppStore()
const formRef = ref(null);
const formParams = ref({
@@ -326,6 +330,10 @@
    isModifiedText: [
        { required: true, message: '请选择是否改装', trigger: 'change' }
    ],
    type: [
        { required: true, message: '请选择飞行器类型', trigger: 'change' }
    ],
})
// 是否改装
const actionsModified = ref([
@@ -356,31 +364,29 @@
const findRegionNamesByCodes = (codes, areaData) => {
  const result = []
  let currentData = areaData
  for (const code of codes) {
    // 转换为字符串比较(因为code可能是字符串类型)
    const codeStr = code.toString()
    const item = currentData.find(item => item.code === codeStr)
    if (!item) {
      console.warn(`未找到code为 ${codeStr} 的行政区划`)
      break
    }
    result.push(item.name)
    currentData = item.children || []
  }
  return result
}
// 所属区域确认
const onRegionConfirm = (e) => {
    console.log(e,'888')
    formParams.value.region = e[2] || '' // 用逗号分隔的区域码
    // 通过arrRegion的数组值为[36,3608,360824] 从areaData里面反查出名称
    const regionNames = findRegionNamesByCodes(e, areaData.value)
    console.log(regionNames, '77777')
    formParams.value.regionText = regionNames.join('-') || '' // 用连字符连接的区域名称
    isShowRegion.value = false
}
@@ -412,13 +418,14 @@
  formParams.value.manufacturerText = selected.label
  showManufacturer.value = false
}
// 飞行器型号
// 飞行器类型
const showType = ref(false);
const typeList = ref([])
// 选择飞行器型号
const typeList = ref(appStore.getProType)
// 选择飞行器类型
const onPickerConfirmType = (e) => {
  const selected = e.value[0]
  formParams.value.type = selected.value
  console.log(formParams.value.type,'6666')
  formParams.value.typeText = selected.label
  showType.value = false
}
@@ -427,36 +434,36 @@
    // 获取上传的文件对象
    const file = event.file;
    console.log('上传的文件:', file);
    // 显示加载提示
    uni.showLoading({
        title: '上传中...'
    });
    // 准备上传参数
    const uploadParams = {
        name: 'file', // 服务器端接收文件的字段名
        file: file, // 传入文件对象
        filePath: file.path || file.url, // 文件路径
    };
    // 调用上传文件接口
    uploadFileApi(uploadParams).then(res => {
        uni.hideLoading();
        console.log('上传成功结果:', res);
        // 根据接口返回的数据结构处理结果
        if (res.data && res.data.code === 200) {
            // 假设接口返回的数据结构是 { url, fileName } 等
            const uploadResult = res.data.data;
            // 更新表单数据,将上传结果展示在input内
            formParams.value.caacRegistrationCodeText = uploadResult.fileName || uploadResult.url || '文件上传成功';
            // 可以将完整的上传信息保存到表单中,以便提交时使用
            formParams.value.caacRegistrationCode= uploadResult.fileUrl || '文件上传成功';
            uni.showToast({
                title: '上传成功',
                icon: 'success'
@@ -491,36 +498,36 @@
    // 获取上传的文件对象
    const file = event.file;
    console.log('上传的文件:', file);
    // 显示加载提示
    uni.showLoading({
        title: '上传中...'
    });
    // 准备上传参数
    const uploadParams = {
        name: 'file', // 服务器端接收文件的字段名
        file: file, // 传入文件对象
        filePath: file.path || file.url, // 文件路径
    };
    // 调用上传文件接口
    uploadFileApi(uploadParams).then(res => {
        uni.hideLoading();
        console.log('上传成功结果:', res);
        // 根据接口返回的数据结构处理结果
        if (res.data && res.data.code === 200) {
            // 假设接口返回的数据结构是 { url, fileName } 等
            const uploadResult = res.data.data;
            // 更新表单数据,将上传结果展示在input内
            formParams.value.deviceImageText = uploadResult.fileName || uploadResult.url || '文件上传成功';
            // 可以将完整的上传信息保存到表单中,以便提交时使用
            formParams.value.deviceImage= uploadResult.fileUrl || '文件上传成功';
            uni.showToast({
                title: '上传成功',
                icon: 'success'
@@ -571,15 +578,15 @@
    }
}
// 获取飞行器类型
function getProTypeApi() {
    proTypeApi().then(res => {
        typeList.value = res.data.data.map(item => ({
            ...item,
            label: item.dictLabel,
            value: item.dictValue
        }))
    })
}
// function getProTypeApi() {
//     proTypeApi().then(res => {
//         typeList.value = res.data.data.map(item => ({
//             ...item,
//             label: item.dictLabel,
//             value: item.dictValue
//         }))
//     })
// }
// 获取无人机厂商
function getManufacturerInfoApi() {
    manufacturerInfoApi({
@@ -594,7 +601,6 @@
    })
}
onMounted(async () => {
    getProTypeApi()
    getManufacturerInfoApi()
    // 动态从外部URL导入xzqhData,确保在使用前已初始化
    // 注意:直接动态导入外部URL可能会有跨域或构建问题,建议检查服务器CORS设置
@@ -610,11 +616,11 @@
    display: flex;
    flex-direction: column;
    // padding: 24rpx;
    .select-wrapper {
        position: relative;
        width: 100%;
        .select-icon {
            position: absolute;
            right: 20rpx;
@@ -624,6 +630,10 @@
            font-size: 24rpx;
            pointer-events: none;
        }
    }
    :deep(.u-toolbar__wrapper__confirm) {
        color: #1D6FE9;
    }
    .upload {
@@ -656,7 +666,7 @@
        border-radius: 8rpx 8rpx 8rpx 8rpx;
        margin-bottom: 20rpx;
    }
    :deep(.u-form-item) {
        margin-bottom: 20rpx;
        padding: 16rpx 24rpx 18rpx 24rpx;
@@ -671,7 +681,7 @@
            border-radius: 8rpx;
            padding: 0 20rpx;
            background-color: #f5f5f5;
            &::placeholder {
                font-family: Source Han Sans CN, Source Han Sans CN;
                font-weight: 400;
@@ -679,12 +689,12 @@
                color: #D2D2D2;
            }
        }
        .clickable-input {
            width: 100%;
            cursor: pointer;
        }
        :deep(.u-form-item__label) {
            margin-bottom: 20rpx;
            // font-weight: bold;
@@ -694,7 +704,7 @@
            font-size: 30rpx;
            color: #222324;
        }
        :deep(.u-form-item__required) {
            color: #FF2600;
            margin-right: 8rpx;
uniapps/work-wx/src/subPackages/flightApplication/add.vue
@@ -1,6 +1,6 @@
<template>
<view class="flightApplication-add">
    <u-form labelPosition="top" :model="formParams" :rules="rules" ref="formRef">
         <view class="title form-title">基本信息</view>
        <u-form-item
@@ -101,7 +101,7 @@
        >
            <u-input v-model="formParams.flightEndTime" border="none" placeholder="请选择日期" suffixIcon="calendar"></u-input>
        </u-form-item>
        <u-form-item
                label="计划类型"
                labelWidth="200rpx"
@@ -386,16 +386,20 @@
</view>
</template>
<script setup>
import { flightPlanSaveApi,
    flightRoutePageInfoApi,
    aircraftInfoPageInfoOfMyApi,
    pilotInfoPageInfoOfMyApi,
    droneFlightTaskApi,
    uploadFileApi,
    flightTaskApi,flightRulesApi,flightModeApi,flightPlanApi
import {
    flightPlanSaveApi,
    flightRoutePageInfoApi,
    aircraftInfoPageInfoOfMyApi,
    pilotInfoPageInfoOfMyApi,
    droneFlightTaskApi,
    uploadFileApi
 } from '@/api/index'
import { ref, computed, onMounted } from 'vue'
import dayjs from 'dayjs'
// 获取store中的数据 字典
import { useAppStore, useUserStore } from "@/store";
const appStore = useAppStore()
const formRef = ref(null);
const formParams = ref({
@@ -498,7 +502,7 @@
})
// 任务类型
const isShowFlightTaskType = ref(false)
const actionsFlightTaskType = ref([])
const actionsFlightTaskType = ref(appStore.getTaskType)
const onPickerFlightTaskType = (e) => {
  const selected = e.value[0]
  formParams.value.flightTaskType = selected.value
@@ -508,7 +512,7 @@
// 飞行规则
const isShowFlightRule = ref(false)
const actionsFlightRule = ref([])
const actionsFlightRule = ref(appStore.getFlightRules)
const onPickerFlightRule = (e) => {
  const selected = e.value[0]
  formParams.value.flightRule = selected.value
@@ -517,7 +521,7 @@
}
// 飞行方式
const isShowFlightMode = ref(false)
const actionsFlightMode = ref([])
const actionsFlightMode = ref(appStore.getFlightMode)
const onPickerFlightMode = (e) => {
  const selected = e.value[0]
  formParams.value.flightMode = selected.value
@@ -526,7 +530,7 @@
}
// 计划类型
const isShowPlanType = ref(false)
const actionsPlanType = ref([])
const actionsPlanType = ref(appStore.getFlightPlan)
const onPickerPlanType = (e) => {
  const selected = e.value[0]
  formParams.value.planType = selected.value
@@ -637,36 +641,36 @@
    // 获取上传的文件对象
    const file = event.file;
    console.log('上传的文件:', file);
    // 显示加载提示
    uni.showLoading({
        title: '上传中...'
    });
    // 准备上传参数
    const uploadParams = {
        name: 'file', // 服务器端接收文件的字段名
        file: file, // 传入文件对象
        filePath: file.path || file.url, // 文件路径
    };
    // 调用上传文件接口
    uploadFileApi(uploadParams).then(res => {
        uni.hideLoading();
        console.log('上传成功结果:', res);
        // 根据接口返回的数据结构处理结果
        if (res.data && res.data.code === 200) {
            // 假设接口返回的数据结构是 { url, fileName } 等
            const uploadResult = res.data.data;
            // 更新表单数据,将上传结果展示在input内
            formParams.value.tempAirspaceApprovalText = uploadResult.fileName || uploadResult.url || '文件上传成功';
            // 可以将完整的上传信息保存到表单中,以便提交时使用
            formParams.value.tempAirspaceApproval = uploadResult.fileUrl || '文件上传成功';
            uni.showToast({
                title: '上传成功',
                icon: 'success'
@@ -712,52 +716,12 @@
    }
  })
}
// 获取任务类型
function getTaskType() {
    flightTaskApi().then(res => {
        actionsFlightTaskType.value = res.data.data.map(item => ({
            ...item,
            label: item.dictLabel || '暂无',
            value: item.dictValue || '暂无',
        }))
    })
}
// 获取飞行模式
function getFlightMode() {
    flightModeApi().then(res => {
        actionsFlightMode.value = res.data.data.map(item => ({
            ...item,
            label: item.dictLabel || '暂无',
            value: item.dictValue || '暂无',
        }))
    })
}
// 获取飞行规则
function getFlightRules() {
    flightRulesApi().then(res => {
        actionsFlightRule.value = res.data.data.map(item => ({
            ...item,
            label: item.dictLabel || '暂无',
            value: item.dictValue || '暂无',
        }))
    })
}
// 获取飞行计划
function getFlightPlan() {
    flightPlanApi().then(res => {
        actionsPlanType.value = res.data.data.map(item => ({
            ...item,
            label: item.dictLabel || '暂无',
            value: item.dictValue || '暂无',
        }))
    })
}
onMounted(() => {
    // getProTypeApi()
    getTaskType()
    getFlightMode()
    getFlightRules()
    getFlightPlan()
    // getTaskType()
    // getFlightMode()
    // getFlightRules()
    // getFlightPlan()
    getAircraftInfo()
    getPilotInfo()
    getAirspaceInfo()
@@ -787,6 +751,9 @@
        border-radius: 8rpx 8rpx 8rpx 8rpx;
        // margin-bottom: 20rpx;
    }
    :deep(.u-toolbar__wrapper__confirm) {
        color: #1D6FE9;
    }
    .custom-label {
        .label-tip {
            font-family: Source Han Sans CN, Source Han Sans CN;
@@ -795,7 +762,7 @@
            color: #3A3A3A;
        }
    }
    .attention {
        font-family: Source Han Sans CN, Source Han Sans CN;
        font-weight: 400;
@@ -807,7 +774,7 @@
    .select-wrapper {
        position: relative;
        width: 100%;
        .select-icon {
            position: absolute;
            right: 20rpx;
@@ -853,7 +820,7 @@
            border-radius: 8rpx;
            padding: 0 20rpx;
            background-color: #f5f5f5;
            &::placeholder {
                font-family: Source Han Sans CN, Source Han Sans CN;
                font-weight: 400;
@@ -861,12 +828,12 @@
                color: #D2D2D2;
            }
        }
        .clickable-input {
            width: 100%;
            cursor: pointer;
        }
        :deep(.u-form-item__label) {
            margin-bottom: 20rpx;
            // font-weight: bold;
@@ -876,7 +843,7 @@
            font-size: 30rpx;
            color: #222324;
        }
        :deep(.u-form-item__required) {
            color: #FF2600;
            margin-right: 8rpx;
uniapps/work-wx/src/subPackages/flightApplication/details.vue
@@ -1,10 +1,8 @@
<!-- 飞行活动申请 -->
<template>
<view class="flightApplication-add">
    <view class="title">
        基本信息
    </view>
    <u-form labelPosition="top" :model="formParams" :rules="rules" ref="formRef">
        <view class="title form-title">基本信息</view>
        <u-form-item
                label="飞行计划"
                labelWidth="200rpx"
@@ -74,7 +72,7 @@
        >
            <u-input v-model="formParams.flightEndTime" border="none" suffixIcon="calendar"></u-input>
        </u-form-item>
        <u-form-item
                label="计划类型"
                labelWidth="200rpx"
@@ -208,57 +206,55 @@
</view>
</template>
<script setup>
import { flightPlanSaveApi,
    flightRoutePageInfoApi,
    aircraftInfoPageInfoOfMyApi,
    pilotInfoPageInfoOfMyApi,
    flightAirspacePageInfoApi,
    uploadFileApi,
    flightTaskApi,flightRulesApi,flightModeApi,flightPlanApi,flightPlanDetailsApi
import {
    flightPlanDetailsApi,
    flightRoutePageInfoApi,
    aircraftInfoPageInfoOfMyApi,
    pilotInfoPageInfoOfMyApi,
    flightAirspacePageInfoApi,
 } from '@/api/index'
import { ref, computed, onMounted } from 'vue'
import dayjs from 'dayjs'
// 获取store中的数据 字典
import { useAppStore, useUserStore } from "@/store";
const appStore = useAppStore()
const formRef = ref(null);
const formParams = ref({})
const rules = ref({})
// 任务类型
const isShowFlightTaskType = ref(false)
const actionsFlightTaskType = ref([])
const actionsFlightTaskType = ref(appStore.getTaskType)
// 飞行规则
const isShowFlightRule = ref(false)
const actionsFlightRule = ref([])
const actionsFlightRule = ref(appStore.getFlightRules)
// 飞行方式
const isShowFlightMode = ref(false)
const actionsFlightMode = ref([])
const actionsFlightMode = ref(appStore.getFlightMode)
// 计划类型
const isShowPlanType = ref(false)
const actionsPlanType = ref([])
const actionsPlanType = ref(appStore.getFlightPlan)
// 是否显示开始时间选择器
const isShowStartTime = ref(false)
// 是否显示结束时间选择器
const isShowEndTime = ref(false)
const startTime = ref(Date.now()); // 设置默认值为当前时间戳
const endTime = ref(Date.now()); // 设置默认值为当前时间戳
// const startTime = ref(Date.now()); // 设置默认值为当前时间戳
// const endTime = ref(Date.now()); // 设置默认值为当前时间戳
const onConfirmStartTime = (e) => {
    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:ss')
    isShowEndTime.value = false
}
// const onConfirmStartTime = (e) => {
//     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:ss')
//     isShowEndTime.value = false
// }
// 获取飞行器信息
const isShowAircraftInfo = ref(false)
// const isShowAircraftInfo = ref(false)
const aircraftInfoList = ref([])
function getAircraftInfo() {
    aircraftInfoPageInfoOfMyApi({
@@ -271,14 +267,13 @@
        }))
    })
}
const onPickerAircraftInfo = (e) => {
  const selected = e.value[0]
  formParams.value.aircraftId = selected.value
  formParams.value.aircraftText = selected.label
  isShowAircraftInfo.value = false
}
// const onPickerAircraftInfo = (e) => {
//   const selected = e.value[0]
//   formParams.value.aircraftId = selected.value
//   formParams.value.aircraftText = selected.label
//   isShowAircraftInfo.value = false
// }
// 获取飞手信息
const isShowPilotInfo = ref(false)
const pilotInfoList = ref([])
function getPilotInfo() {
    pilotInfoPageInfoOfMyApi({
@@ -292,7 +287,6 @@
    })
}
// 获取空域信息
const isShowAirspaceInfo = ref(false)
const airspaceInfoList = ref([])
function getAirspaceInfo() {
    flightAirspacePageInfoApi({
@@ -306,7 +300,6 @@
    })
}
// 获取航线信息
const isShowFlightRouteInfo = ref(false)
const flightRouteInfoList = ref([])
function getFlightRouteInfo() {
    flightRoutePageInfoApi({
@@ -320,71 +313,27 @@
    })
}
// 获取任务类型
function getTaskType() {
    flightTaskApi().then(res => {
        actionsFlightTaskType.value = res.data.data.map(item => ({
            ...item,
            label: item.dictLabel || '暂无',
            value: item.dictCode || '暂无',
        }))
    })
}
// 获取飞行模式
function getFlightMode() {
    flightModeApi().then(res => {
        actionsFlightMode.value = res.data.data.map(item => ({
            ...item,
            label: item.dictLabel || '暂无',
            value: item.dictCode || '暂无',
        }))
    })
}
// 获取飞行规则
function getFlightRules() {
    flightRulesApi().then(res => {
        actionsFlightRule.value = res.data.data.map(item => ({
            ...item,
            label: item.dictLabel || '暂无',
            value: item.dictCode || '暂无',
        }))
    })
}
// 获取飞行计划
function getFlightPlan() {
    flightPlanApi().then(res => {
        actionsPlanType.value = res.data.data.map(item => ({
            ...item,
            label: item.dictLabel || '暂无',
            value: item.dictCode || '暂无',
        }))
    })
}
onLoad((options) => {
     flightPlanDetailsApi(options.id).then(res => {
        console.log(res.data.data, '789')
        // return
        formParams.value = res.data.data
        formParams.value.routeId = res.data.data.routeInfo.name
        formParams.value.airspaceId = res.data.data.airspaceInfo.taskName
        formParams.value.aircraftId = res.data.data.airspaceInfo.aircraftInfoList.map(item => item.name).join(',')
        formParams.value.pilotId = res.data.data.operatorInfoList.map(item => item.name).join(',')
        formParams.value.flightRule = actionsFlightRule.value.find(item => item.dictValue === res.data.data.flightRule)?.dictLabel || ''
        formParams.value.flightMode = actionsFlightMode.value.find(item => item.dictValue === res.data.data.flightMode)?.dictLabel || ''
        formParams.value.planType = actionsPlanType.value.find(item => item.dictValue === res.data.data.planType)?.dictLabel || ''
        formParams.value.flightTaskType = actionsFlightTaskType.value.find(item => item.dictValue === res.data.data.flightTaskType)?.dictLabel || ''
        const result = res.data.data
        formParams.value = result
        formParams.value.routeId = result.routeInfo.name
        formParams.value.airspaceId = result.airspaceInfo.taskName || '无'
        formParams.value.aircraftId = result.airspaceInfo.aircraftInfoList.map(item => item.name).join(',') || '无'
        formParams.value.pilotId = result.operatorInfoList.map(item => item.name).join(',') || '无'
        // 字典
        formParams.value.flightRule = actionsFlightRule.value.find(item => item.dictValue === result.flightRule)?.dictLabel || '无'
        formParams.value.flightMode = actionsFlightMode.value.find(item => item.dictValue === result.flightMode)?.dictLabel || '无'
        formParams.value.planType = actionsPlanType.value.find(item => item.dictValue === result.planType)?.dictLabel || '无'
        formParams.value.flightTaskType = actionsFlightTaskType.value.find(item => item.dictValue === result.flightTaskType)?.dictLabel || '无'
    })
})
onMounted(() => {
    getTaskType()
    getFlightMode()
    getFlightRules()
    getFlightPlan()
    // getAircraftInfo()
    // getPilotInfo()
    // getAirspaceInfo()
    // getFlightRouteInfo()
    getAircraftInfo()
    getPilotInfo()
    getAirspaceInfo()
    getFlightRouteInfo()
})
</script>
<style scoped lang="scss">
@@ -421,7 +370,7 @@
    .select-wrapper {
        position: relative;
        width: 100%;
        .select-icon {
            position: absolute;
            right: 20rpx;
@@ -467,7 +416,7 @@
            border-radius: 8rpx;
            padding: 0 20rpx;
            background-color: #f5f5f5;
            &::placeholder {
                font-family: Source Han Sans CN, Source Han Sans CN;
                font-weight: 400;
@@ -475,12 +424,12 @@
                color: #D2D2D2;
            }
        }
        .clickable-input {
            width: 100%;
            cursor: pointer;
        }
        :deep(.u-form-item__label) {
            margin-bottom: 20rpx;
            // font-weight: bold;
@@ -490,7 +439,7 @@
            font-size: 30rpx;
            color: #222324;
        }
        :deep(.u-form-item__required) {
            color: #FF2600;
            margin-right: 8rpx;
uniapps/work-wx/src/subPackages/flightApplication/index.vue
@@ -25,10 +25,12 @@
                            <u-image :src="spSvg" class="icon" width="16" height="16"></u-image>
                            <view class="name">{{approvalRecord.flightPlanName}}</view>
                        </view>
                        <view class="status">{{approvalRecord.planApprovalStatus || ''}}</view>
                        <view class="status" :class="getStatusClass(approvalRecord.planApprovalStatus)">
                            {{ approvalRecord.planApprovalStatusLabel || ''}}
                        </view>
                    </view>
                    <view class="txt">飞行器:{{approvalRecord.device || ''}}</view>
                    <view class="txt">飞行任务:{{approvalRecord.flightTaskType || ''}}</view>
                    <view class="txt">飞行器:{{approvalRecord.spacecraftLabel || '无'}}</view>
                    <view class="txt">飞行任务:{{approvalRecord.flightTaskTypeLabel || ''}}</view>
                    <view class="txt">飞行起飞时间:{{approvalRecord.actualTakeoffTime || ''}}</view>
                    <view class="txt">飞行降落时间:{{approvalRecord.actualLandingTime || ''}}</view>
                </view>
@@ -42,7 +44,12 @@
    import { flightPlanPageInfoApi } from '@/api/index.js'
    import fxsqSvg from '@/static/images/fly-apply.png'
    import mysbSvg from '@/static/images/my-sb.png'
import { ref } from 'vue'
    import { ref } from 'vue'
    import { aircraftInfoPageInfoOfMyApi } from '@/api/index'
    // 获取store中的数据 字典
    import { useAppStore, useUserStore } from "@/store";
    const appStore = useAppStore()
function gridClick(index) {
@@ -58,6 +65,40 @@
    }
}
const getStatusClass = (status) => {
    switch (status) {
        case '0':
            return 'Sorange'
        case '99':
            return 'Sgreen'
        case '-1':
            return 'Sred'
        case '1':
            return 'Sblue'
        default:
            return ''
    }
}
// 获取飞行器信息
const aircraftInfoList = ref([])
async function getAircraftInfo() {
    try {
        const res = await aircraftInfoPageInfoOfMyApi({
            current: 1,
            size: 1000,
        })
        aircraftInfoList.value = res.data.data.records.map(item => ({
            label: item.name,
            value: item.id,
        }))
    } catch (error) {
        console.error('获取飞行器信息失败:', error)
    }
}
// 审批记录是很多条
const approvalRecords = ref([])
const formParams = ref({
@@ -70,6 +111,12 @@
    try {
        const res = await flightPlanPageInfoApi(formParams.value)
        const newData = res.data.data.records || []
        // 处理字典数据
        newData.forEach(item => {
            item.spacecraftLabel = aircraftInfoList.value.find(info => info.value === item.spacecraftId)?.label || '无'
            item.planApprovalStatusLabel = appStore.flyActivityStatus.find(status => status.dictValue === item.planApprovalStatus)?.dictLabel || '无'
            item.flightTaskTypeLabel = appStore.taskType.find(type => type.dictValue === item.flightTaskType)?.dictLabel || '无'
        })
        // 如果是第一页,直接替换数据;否则追加数据
        if (formParams.value.current === 1) {
            approvalRecords.value = newData
@@ -106,7 +153,10 @@
        url: '/subPackages/flightApplication/details?id=' + item.id,
    })
}
onMounted(() => {
onMounted(async () => {
    await getAircraftInfo()
    getApprovalRecords()
})
</script>
@@ -192,12 +242,11 @@
    }
    .name-status {
        display: flex;
        justify-content: space-between;
        align-items: center;
        // justify-content: space-between;
        margin-bottom: 20rpx;
        .name-image {
            width: calc(100% - 120rpx);
            display: flex;
            justify-content: center;
            align-items: center;
            .u-image {
                width: 32rpx;
@@ -208,18 +257,36 @@
                font-size: 32rpx;
                color: #1D2129;
                margin-left: 6rpx;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
            }
        }
        .status {
            width: 100rpx;
            text-align: center;
            line-height: 40rpx;
            background: #FF9604;
            line-height: 44rpx;
            height: 44rpx;
            border-radius: 2px 2px 2px 2px;
            font-weight: 500;
            font-size: 24rpx;
            color: #FFFFFF;
            padding: 0 6rpx;
            &.Sorange {
                background: #FF9604;
            }
            &.Sred {
                background: #F8422A;
            }
            &.Sgreen {
                background: #17A836;
            }
            &.Sblue {
                background: #1D6FE9;
            }
        }
    }
    .txt {
        font-weight: 400;
uniapps/work-wx/src/subPackages/regulationsDetail/details.vue
@@ -18,7 +18,7 @@
        </view>
    </view>
    </scroll-view>
    <u-pdf-reader v-if="pdfUrl" :src="pdfUrl"></u-pdf-reader>
    <!-- <u-pdf-reader v-if="pdfUrl" :src="pdfUrl"></u-pdf-reader> -->
</view>
</template>
<script setup>
@@ -40,136 +40,55 @@
    td: 'border: 1px solid #ddd; padding: 8rpx;'
};
const pdfUrl = ref('')
const pdfUrl = ref('https://wrj.shuixiongit.com/minio/cloud-bucket/78611c83-8fb3-47c9-a18c-0349137bb30c/DJI_202601171733_001_78611c83-8fb3-47c9-a18c-0349137bb30c/DJI_20260117173534_0004_V.jpeg')
const fileObject = ref(null)
function downloadFile(item) {
    console.log(item,'999')
    // aLinkDownloadUtil(item.fileUrl, item.fileName)
    // downloadAndPreview(item.fileUrl, item.fileName)
    pdfUrl.value = item.fileUrl
    // downloadAndSavePDF(item.fileUrl, item.fileName)
}
// 下载并打开文件(支持PDF、图片、Word等)
const downloadAndPreview = async (fileUrl, fileName) => {
    uni.showLoading({
        title: '下载中...',
        mask: true
    })
    try {
        // 1. 下载文件到临时目录
        const downloadRes = await uni.downloadFile({
            url: fileUrl,
            timeout: 60000
        })
        if (downloadRes.statusCode !== 200) {
            throw new Error(`下载失败: ${downloadRes.statusCode}`)
        }
        // 2. 打开文件(小程序会调用系统能力)
        uni.openDocument({
            filePath: downloadRes.tempFilePath,
            fileType: getFileType(fileName),
            showMenu: true, // 显示右上角菜单
            success: () => {
                console.log('打开文档成功')
                uni.showToast({
                    title: '已打开文件',
                    icon: 'success'
                })
            },
            fail: (error) => {
                console.error('打开失败:', error)
                // 如果打开失败,尝试其他方式
                handleOpenFail(downloadRes.tempFilePath, fileName)
            }
        })
    } catch (error) {
        console.error('下载失败:', error)
        uni.showToast({
            title: '下载失败,请重试',
            icon: 'none'
        })
    } finally {
        uni.hideLoading()
    }
  console.log(item,'8888')
    pdfUrl.value = item.filePreviewUrl
    // fileObject.value = {
    //   url: item.fileUrl,
    //   name: item.fileName,
    //   extname: 'pdf'
    // }
    previewPdf(pdfUrl.value)
}
// 下载并保存PDF到手机(iOS需要特殊处理)
const downloadAndSavePDF = (pdfUrl, fileName = 'document.pdf') => {
const previewPdf = (url) => {
  uni.showLoading({
    title: '下载中...',
    mask: true
    title: '加载中...'
  })
  // 检查权限(主要针对iOS)
  const checkAndDownload = () => {
    uni.downloadFile({
      url: pdfUrl,
      success: (downloadRes) => {
        uni.hideLoading()
        if (downloadRes.statusCode === 200) {
          const tempFilePath = downloadRes.tempFilePath
          // 保存到本地
          uni.saveFile({
            tempFilePath: tempFilePath,
            success: (saveRes) => {
              const savedFilePath = saveRes.savedFilePath
              uni.showModal({
                title: '下载成功',
                content: `文件已保存到: ${savedFilePath}`,
                showCancel: false,
                success: () => {
                  // 可以引导用户去文件管理查看
                }
              })
            },
            fail: (saveErr) => {
              console.error('保存失败:', saveErr)
              uni.showToast({
                title: '保存失败111',
                icon: 'error'
              })
            }
          })
        }
      },
      fail: (err) => {
        uni.hideLoading()
        uni.showToast({
          title: '下载失败1111',
          icon: 'error'
        })
      }
    })
  }
  // 检查文件访问权限
  uni.authorize({
    scope: 'scope.writePhotosAlbum',
    success: () => {
      checkAndDownload()
    },
    fail: () => {
      uni.showModal({
        title: '权限提示',
        content: '需要文件存储权限才能下载文件',
        success: (modalRes) => {
          if (modalRes.confirm) {
            uni.openSetting({
              success: (settingRes) => {
                if (settingRes.authSetting['scope.writePhotosAlbum']) {
                  checkAndDownload()
                }
              }
  // 1. 先下载文件到本地
  uni.downloadFile({
    url: url,
    success: (res) => {
      if (res.statusCode === 200) {
        // 2. 打开文档
        uni.openDocument({
          filePath: res.tempFilePath,
          fileType: 'pdf',
          success: () => {
            console.log('打开文档成功')
            uni.hideLoading()
          },
          fail: (err) => {
            console.error('打开文档失败:', err)
            uni.hideLoading()
            uni.showToast({
              title: '打开文件失败',
              icon: 'none'
            })
          }
        }
        })
      }
    },
    fail: (err) => {
      console.error('下载文件失败:', err)
      uni.hideLoading()
      uni.showToast({
        title: '下载文件失败',
        icon: 'none'
      })
    }
  })
@@ -205,7 +124,7 @@
    const id = options.id || '1';
    regulationsDetailApi(id).then(res => {
        htmlContent.value = res.data.data.noticeContent;
        title.value = res.data.data.noticeTitle;
        title.value = res.data.data.noticeDesc;
        fileList.value = res.data.data.fileList || []
    })
    .catch(err => {