无人机管理后台前端(已迁走)
chenyao
2025-09-27 179aad3c34772d5c813110a0d238518bf839dba5
feat:复制文件
5 files modified
365 ■■■■■ changed files
src/api/resource/wayline.js 8 ●●●● patch | view | raw | blame | history
src/hooks/useRouteLine/useRouteLine.js 23 ●●●●● patch | view | raw | blame | history
src/store/modules/common.js 6 ●●●● patch | view | raw | blame | history
src/views/monitor/log/flightLog.vue 101 ●●●● patch | view | raw | blame | history
src/views/tickets/orderLog.vue 227 ●●●●● patch | view | raw | blame | history
src/api/resource/wayline.js
@@ -17,7 +17,13 @@
  });
};
export const newGetWorkspacesPage = params => {
  return request({
    url: `/drone-device-core/wayline/api/v1/wayline-groups/page`,
    method: 'get',
    params,
  })
}
export const getWaylineFileListByArea = (areaCode) => {
  return request({
src/hooks/useRouteLine/useRouteLine.js
@@ -13,6 +13,8 @@
import { ArrowLineMaterialProperty } from '@/utils/cesium/Material'
import { flyVisual } from '@/utils/cesium/mapUtil'
import { useStore } from 'vuex'
let arrowLineMaterialProperty = new ArrowLineMaterialProperty({
    color: new Cesium.Color(128 / 255, 215 / 255, 255 / 255, 1),
    directionColor: new Cesium.Color(1, 1, 1, 1),
@@ -22,6 +24,7 @@
})
export function useRouteLine () {
    const store = useStore()
    let viewer = null
    let previewDataSource = null
@@ -162,15 +165,15 @@
            },
        })
            // 落点线
            ; (pointList || [])?.forEach((item, index) => {
                const topPosition = Cesium.Cartesian3.fromDegrees(Number(item.longitude), Number(item.latitude), Number(item.height))
                let setting = {
                    position: topPosition,
                    polyline: getPolyLine(viewer, { value: pointList }, index),
                }
                previewDataSource.entities.add(setting)
            })
        // 落点线
        ; (pointList || [])?.forEach((item, index) => {
            const topPosition = Cesium.Cartesian3.fromDegrees(Number(item.longitude), Number(item.latitude), Number(item.height))
            let setting = {
                position: topPosition,
                polyline: getPolyLine(viewer, { value: pointList }, index),
            }
            previewDataSource.entities.add(setting)
        })
        // 终点
        previewDataSource.entities.add({
@@ -191,6 +194,8 @@
                height: 50,
            },
        })
        // 获取最后一点高度
        store.commit('setLastHeight', Number(pointList[pointList.length - 1].height))
        flyVisual({
            positionsData:pointList.map(i => [Number(i.longitude), Number(i.latitude), Number(i.height)]),
            viewer,
src/store/modules/common.js
@@ -18,9 +18,13 @@
    downloadProgress:{
      htsjzx: 100, //数据中心
      htlsrwxq: 100, //历史任务详情
    }
    },
    lastHeight: 0, // 获取最后一点高度
  },
  mutations: {
    setLastHeight(state, data) {
      state.lastHeight = data
    },
    setDownloadProgress(state, data) {
      state.downloadProgress = data
    },
src/views/monitor/log/flightLog.vue
@@ -4,38 +4,38 @@
    <div class="ztzf-search-mange">
      <el-form :model="params" inline>
        <div class="search-contain">
          <div>
            <el-form-item label="任务名称:">
              <el-input v-model="params.jobName" placeholder="请输入任务名称" clearable />
            </el-form-item>
            <el-form-item label="任务编号:">
              <el-input v-model="params.jobInfoNum" placeholder="请输入任务编号" clearable />
            </el-form-item>
            <el-form-item label="日期:">
              <el-date-picker
                v-model="rangTime"
                type="daterange"
                range-separator="至"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                clearable
                @change="changeselect"
              />
            </el-form-item>
          </div>
          <div class="btns">
            <el-button type="primary" @click="getList" :icon="Search">搜索</el-button>
            <el-button @click="cancelSearch" :icon="Delete">清空</el-button>
          </div>
          <!--          <div>-->
          <el-form-item label="任务名称:">
            <el-input v-model="params.jobName" placeholder="请输入任务名称" clearable />
          </el-form-item>
          <el-form-item label="任务编号:">
            <el-input v-model="params.jobInfoNum" placeholder="请输入任务编号" clearable />
          </el-form-item>
          <el-form-item label="日期:">
            <el-date-picker
              v-model="rangTime"
              type="daterange"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              clearable
              @change="changeselect"
            />
          </el-form-item>
          <!--          </div>-->
          <!--          <div class="btns">-->
          <el-button type="primary" @click="getList" :icon="Search">搜索</el-button>
          <el-button @click="cancelSearch" :icon="Delete">清空</el-button>
          <!--          </div>-->
        </div>
      </el-form>
    </div>
    <div class="mange-table">
<!--      <el-tabs v-model="tabType" class="demo-tabs" @tab-click="handleTabClick">-->
<!--        <el-tab-pane label="全部" name="全部"></el-tab-pane>-->
<!--        <el-tab-pane label="我的收藏" name="收藏"></el-tab-pane>-->
<!--        -->
<!--      </el-tabs>-->
      <!--      <el-tabs v-model="tabType" class="demo-tabs" @tab-click="handleTabClick">-->
      <!--        <el-tab-pane label="全部" name="全部"></el-tab-pane>-->
      <!--        <el-tab-pane label="我的收藏" name="收藏"></el-tab-pane>-->
      <!--        -->
      <!--      </el-tabs>-->
      <el-table border :data="tableList" class="custom-header">
        <el-table-column label="序号" type="index" width="60"></el-table-column>
        <el-table-column prop="job_name" label="任务名称" align="center" show-overflow-tooltip></el-table-column>
@@ -52,26 +52,26 @@
            {{ timeFormatConvert(scope.row.end_time) }}
          </template>
        </el-table-column>
<!--        <el-table-column prop="end_time" label="标签" align="center">-->
<!--          <template #default="scope">-->
<!--            <el-select v-model="scope.row.label_id" @change="handleUpdateLabel(scope.row)" clearable>-->
<!--              <el-option-->
<!--                v-for="item in tagList"-->
<!--                :key="item.id"-->
<!--                :label="item.label_name"-->
<!--                :value="item.id"-->
<!--              ></el-option>-->
<!--            </el-select>-->
<!--          </template>-->
<!--        </el-table-column>-->
        <!--        <el-table-column prop="end_time" label="标签" align="center">-->
        <!--          <template #default="scope">-->
        <!--            <el-select v-model="scope.row.label_id" @change="handleUpdateLabel(scope.row)" clearable>-->
        <!--              <el-option-->
        <!--                v-for="item in tagList"-->
        <!--                :key="item.id"-->
        <!--                :label="item.label_name"-->
        <!--                :value="item.id"-->
        <!--              ></el-option>-->
        <!--            </el-select>-->
        <!--          </template>-->
        <!--        </el-table-column>-->
        <el-table-column label="操作" width="300" align="center">
          <template #default="scope">
            <el-button icon="el-icon-view" type="text" @click="handleDetail(scope.row)">查看</el-button>
            <el-button icon="el-icon-view" type="text" @click="handleLineTrajectory(scope.row)">轨迹</el-button>
            <el-button icon="el-icon-delete" type="text" @click="handleDelete(scope.row)">删除</el-button>
<!--            <el-button type="text" @click="handleStar(scope.row)">-->
<!--              <el-icon><Star /></el-icon>-->
<!--              {{ scope.row.is_favorite ? '取消收藏':'收藏' }}</el-button>-->
            <!--            <el-button type="text" @click="handleStar(scope.row)">-->
            <!--              <el-icon><Star /></el-icon>-->
            <!--              {{ scope.row.is_favorite ? '取消收藏':'收藏' }}</el-button>-->
            <el-button type="text" @click="handleExport(scope.row)"><el-icon><Download /></el-icon>导出</el-button>
          </template>
        </el-table-column>
@@ -95,12 +95,12 @@
      <el-table-column prop="elevation" label="实时真高" align="center"></el-table-column>
    </el-table>
    <template #footer>
    <div class="pagination dialog-footer" style="display: flex;justify-content: end;margin-top: 10px;">
      <el-pagination class="ztzf-pagination" popper-class="custom-pagination-dropdown" background
                     :page-sizes="[10, 20, 30, 40, 50, 100]" :size="size" v-model:current-page="detailParams.current"
                     v-model:page-size="detailParams.size" layout="total, sizes, prev, pager, next, jumper" :total="detailTotal"
                     @size-change="handleSizeChangeDetails" @current-change="handleCurrentChangeDetails" />
    </div>
      <div class="pagination dialog-footer" style="display: flex;justify-content: end;margin-top: 10px;">
        <el-pagination class="ztzf-pagination" popper-class="custom-pagination-dropdown" background
                       :page-sizes="[10, 20, 30, 40, 50, 100]" :size="size" v-model:current-page="detailParams.current"
                       v-model:page-size="detailParams.size" layout="total, sizes, prev, pager, next, jumper" :total="detailTotal"
                       @size-change="handleSizeChangeDetails" @current-change="handleCurrentChangeDetails" />
      </div>
    </template>
  </el-dialog>
  <el-dialog class="ztzf-dialog-mange" append-to-body v-model="isShowFlyMapView" title="查看" :width="pxToRem(1000)" :close-on-click-modal="false" :destroy-on-close="true">
@@ -307,7 +307,8 @@
        Number(i.height)
      ]),
      viewer,
      multiple: 10
      multiple: 4.6,
      pitch: -60
    });
  } else {
    console.warn('No valid positions data');
src/views/tickets/orderLog.vue
@@ -138,7 +138,7 @@
              <div class="search-bar-box-item search-btn">
                <el-button type="primary" icon="el-icon-search" @click="handleSearch"
                  >搜索</el-button
                >搜索</el-button
                >
                <el-button icon="el-icon-refresh" @click="handleReset">清空</el-button>
              </div>
@@ -178,10 +178,10 @@
                type="primary"
                icon="el-icon-plus"
                @click="handleAdd"
                >新建工单</el-button
              >新建工单</el-button
              >
              <el-button type="success" plain icon="el-icon-download" @click="exportData"
                >导出</el-button
              >导出</el-button
              >
            </template>
@@ -193,7 +193,7 @@
                    type="text"
                    icon="el-icon-view"
                    @click="handleCheckDetail(row)"
                    >审核</el-button
                  >审核</el-button
                  >
                </template>
                <!-- v-if="
@@ -207,42 +207,42 @@
                    icon="el-icon-warning"
                    v-if="hasRecallPaddingBtnPermission()"
                    @click="orderLogRecall(row.id)"
                    >撤回</el-button
                  >撤回</el-button
                  >
                  <!-- <el-button type="text" icon="el-icon-view" @click="handleViewDetail(row)">详情</el-button> -->
                </template>
                <!--已驳回-->
                <template v-if="row.status == 2">
                  <el-button type="text" icon="el-icon-warning" @click="rejectDetail(row.id)"
                    >驳回原因</el-button
                  >驳回原因</el-button
                  >
                  <el-button
                    v-if="userInfo.user_id == row.create_user"
                    type="text"
                    icon="el-icon-view"
                    @click="handleViewDetail(row)"
                    >编辑</el-button
                  >编辑</el-button
                  >
                  <el-button v-else type="text" icon="el-icon-view" @click="handleViewDetail(row)"
                    >详情</el-button
                  >详情</el-button
                  >
                </template>
                <!-- 已通过 -->
                <template v-if="row.status == 3">
                  <el-button type="text" icon="el-icon-view" @click="handleViewDetail(row)"
                    >详情</el-button
                  >详情</el-button
                  >
                </template>
                <!--草稿-->
                <template v-if="row.status == 0">
                  <el-button type="text" icon="el-icon-edit" @click="handleViewDetail(row)"
                    >编辑</el-button
                  >编辑</el-button
                  >
                  <el-button type="text" icon="el-icon-position" @click="userPublishPush(row.id)"
                    >发布</el-button
                  >发布</el-button
                  >
                  <el-button type="text" icon="el-icon-delete" @click="deleteOrderLog(row.id)"
                    >删除</el-button
                  >删除</el-button
                  >
                </template>
              </div>
@@ -281,7 +281,7 @@
              ></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
          <el-col :span="6">
            <el-form-item label="关联航线" prop="file_id">
              <el-select
                v-model="form.file_id"
@@ -298,15 +298,15 @@
              </el-select>
            </el-form-item>
          </el-col>
<!--          <el-col :span="6">-->
<!--            <el-form-item label="安全返航真高" prop="rth_altitude">-->
<!--              <el-input-number-->
<!--                v-model="form.rth_altitude"-->
<!--                :min="30"-->
<!--                :max="300"-->
<!--              ></el-input-number>-->
<!--            </el-form-item>-->
<!--          </el-col>-->
          <el-col :span="6">
            <el-form-item label="安全返航真高" prop="rth_altitude">
              <el-input-number
                v-model="form.rth_altitude"
                :min="50"
                :max="300"
              ></el-input-number>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
@@ -394,13 +394,13 @@
          </el-col>
        </el-row>
<!--        <el-row>-->
<!--          <div class="add-box-btns">-->
<!--            <el-button type="danger" @click="submitForm(1)">发起</el-button>-->
<!--            <el-button type="primary" @click="submitForm(0)">存草稿</el-button>-->
<!--            <el-button @click="dialogVisible = false">取消</el-button>-->
<!--          </div>-->
<!--        </el-row>-->
        <!--        <el-row>-->
        <!--          <div class="add-box-btns">-->
        <!--            <el-button type="danger" @click="submitForm(1)">发起</el-button>-->
        <!--            <el-button type="primary" @click="submitForm(0)">存草稿</el-button>-->
        <!--            <el-button @click="dialogVisible = false">取消</el-button>-->
        <!--          </div>-->
        <!--        </el-row>-->
      </el-form>
      <template #footer>
        <div class="dialog-footer">
@@ -624,7 +624,7 @@
          >驳回</el-button
          >
        </div>
        </template>
      </template>
    </el-dialog>
    <!-- 工单详情 -->
@@ -800,34 +800,34 @@
      </el-form>
      <template #footer>
      <div class="dialog-footer">
        <el-button
          type="danger"
          v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)"
          @click="submitForm(1)"
          icon="el-icon-position"
        >发布</el-button
        >
        <!-- <el-button type="primary" v-if="form.status == 0 || userInfo.user_id == form.create_user"
                        @click="submitForm(0)">保存</el-button> -->
        <div class="dialog-footer">
          <el-button
            type="danger"
            v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)"
            @click="submitForm(1)"
            icon="el-icon-position"
          >发布</el-button
          >
          <!-- <el-button type="primary" v-if="form.status == 0 || userInfo.user_id == form.create_user"
                          @click="submitForm(0)">保存</el-button> -->
        <el-button
          type="primary"
          v-if="form.status == 1 && hasPaddingBtnPermission()"
          @click="orderLogPass(form.id)"
          icon="el-icon-check"
        >通过</el-button
        >
        <el-button
          type="danger"
          v-if="form.status == 1 && hasRejectionBtnPermission()"
          @click="orderLogReject(form.id)"
          icon="el-icon-close"
        >驳回</el-button
        >
        <el-button @click="detailVisibleCopy = false" icon="el-icon-circle-close">取消</el-button>
      </div>
        </template>
          <el-button
            type="primary"
            v-if="form.status == 1 && hasPaddingBtnPermission()"
            @click="orderLogPass(form.id)"
            icon="el-icon-check"
          >通过</el-button
          >
          <el-button
            type="danger"
            v-if="form.status == 1 && hasRejectionBtnPermission()"
            @click="orderLogReject(form.id)"
            icon="el-icon-close"
          >驳回</el-button
          >
          <el-button @click="detailVisibleCopy = false" icon="el-icon-circle-close">取消</el-button>
        </div>
      </template>
    </el-dialog>
  </basic-container>
</template>
@@ -848,7 +848,7 @@
} from '@/api/tickets/orderLog';
import { getTicketInfo } from '@/api/tickets/ticket';
import { getDictionaryByCode } from '@/api/system/dictbiz';
import { getWaylineFileListByArea } from '@/api/resource/wayline';
import { getWaylineFileListByArea, newGetWorkspacesPage } from '@/api/resource/wayline';
import { export_json_to_excel } from '@/utils/exportExcel';
import { getFlyingNestBy } from '@/api/device/device';
import { mapGetters } from 'vuex';
@@ -861,9 +861,13 @@
import weekday from 'dayjs/plugin/weekday';
import elTooltipCopy from '@/components/ElTooltipCopy.vue';
import { CircleClose, Promotion, Select } from '@element-plus/icons-vue';
import { useStore } from 'vuex';
import _ from 'lodash'
// const store = useStore()
dayjs.extend(weekday);
dayjs.locale('zh-cn');
// const lastHeight = computed(() => store.state.common.lastHeight)
export default {
  components: { elTooltipCopy },
@@ -871,7 +875,7 @@
  data() {
    return {
      activeTab: 'all',
      getlastHeight: 0,
      tabs: [
        { label: '全部工单', name: 'all', value: null, count: 0 },
        { label: '待审核', name: 'WAIT_AUDIT', value: 1, count: 0 },
@@ -913,7 +917,7 @@
        indexLabel: '序号',
        indexFixed: true,
        align: 'center',
        align: 'left',
        border: true,
        stripe: false,
        searchShow: true,
@@ -1095,6 +1099,10 @@
      return CircleClose
    },
    ...mapGetters(['userInfo', 'permission']),
    lastHeight() {
      const height = this.$store.state.common.lastHeight;
      return Number(height) || 0; // 确保是数字类型
    },
    filteredTabs() {
      // rejection_and_draft 权限控制“已驳回”和“草稿”tab
      // console.log(this.permission, '权限信息')
@@ -1269,43 +1277,53 @@
              return this.$message.warning('任务时间不能小于当前时间');
            }
          }
          const maxItem = this.device_sns.reduce((max, item) => {
            return item.drone_height > max.drone_height ? item : max;
          });
          console.log(maxItem, '高度')
          let result = _.round((maxItem.drone_height + this.form.rth_altitude), 2)
          const submitData = {
            ...this.form,
            status: status,
            ai_types: this.form.ai_types?.length ? this.form.ai_types : [],
          };
          // 判断该值this.form.date_range[0] 周几 和rep_fre_type 是不是相等
          // if (this.form.deal_time) {
          //    const weekday = dayjs(this.form.date_range[0]).format('dddd');
          //    console.log('444', weekday)
          //   //  form.rep_fre_type
          //   const now = new Date()
          //   const today = now.toDateString()
          //   const selectedDate = new Date(this.form.date_range[0]).toDateString()
          if (this.lastHeight > result) {
            this.$confirm(`安全返航真高${result}米低于航线返航点高度${this.lastHeight}米,为确保返航路径安全,建议您进行调整后再发布`, '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            }).then(async () => {
              const submitData = {
                ...this.form,
                status: status,
                ai_types: this.form.ai_types?.length ? this.form.ai_types : [],
              };
              await saveUpdateOrderLog(submitData);
              let id = this.form.id;
              if (id) {
                this.$message.success('工单发布成功');
              } else {
                this.$message.success('工单创建成功');
              }
              this.dialogVisible = false;
              this.detailVisible = false;
              (this.device_sns = []), (this.wayLineList = []), this.fetchTableData();
            }).catch(() => {
          //   if (today === selectedDate) {
          //     const [hours, minutes] = this.form.deal_time.split(':')
          //     const selectedTime = new Date()
          //     selectedTime.setHours(parseInt(hours), parseInt(minutes))
          //     if (selectedTime < now) {
          //       return this.$message.warning('任务时间不能小于当前时间')
          //     }
          //   }
          // }
          await saveUpdateOrderLog(submitData);
          let id = this.form.id;
          if (id) {
            this.$message.success('工单发布成功');
            });
          } else {
            this.$message.success('工单创建成功');
            const submitData = {
              ...this.form,
              status: status,
              ai_types: this.form.ai_types?.length ? this.form.ai_types : [],
            };
            await saveUpdateOrderLog(submitData);
            let id = this.form.id;
            if (id) {
              this.$message.success('工单发布成功');
            } else {
              this.$message.success('工单创建成功');
            }
            this.dialogVisible = false;
            this.detailVisible = false;
            (this.device_sns = []), (this.wayLineList = []), this.fetchTableData();
          }
          this.dialogVisible = false;
          this.detailVisible = false;
          (this.device_sns = []), (this.wayLineList = []), this.fetchTableData();
        }
      });
    },
@@ -1411,6 +1429,7 @@
    handleAdd() {
      this.form = {};
      this.form.rth_altitude = 120;
      this.dialogVisible = true;
      this.$nextTick(() => {
@@ -1573,8 +1592,15 @@
    },
    //获取航线列表
    async asyncgetWaylineFileListByArea(name) {
      var wayLineListResponse = await getWaylineFileListByArea(this.userInfo.detail.areaCode);
      this.wayLineList = wayLineListResponse.data.data;
      const formData = {
        name: '',
        waylineType: undefined,
        current: 1,
        size: 99999999,
        descs: 'update_time',
      }
      var wayLineListResponse = await newGetWorkspacesPage(formData);
      this.wayLineList =  wayLineListResponse.data.data.records
      this.initMapLine();
    },
@@ -1608,10 +1634,10 @@
      this.initMapLine({}, async polygon => {
        const currentLine = that.wayLineList.find(item => item.wayline_id === waylineId);
        console.log(currentLine.wayline_type, '5555')
        //按照航线来
        const params = {
          type: [2, 4, 5].includes(currentLine.wayline_type) ? 2 : 0,
          type: ['2', '4', '5'].includes(currentLine.wayline_type) ? 2 : 0,
          wayline_id: waylineId,
          polygon,
        };
@@ -1670,8 +1696,11 @@
      });
    },
  },
  watch: {
    // lastHeight(newVal, oldVal) {
    //   console.log('lastHeight', newVal, oldVal);
    //   this.getlastHeight = newVal;
    // },
    tableData: {
      handler() {
        // this.updateTabCounts()