无人机管理后台前端(已迁走)
张含笑
2025-08-15 e52521dc7a3e52cf53e2ab2b4e1c71cfe0b4a10d
src/views/tickets/ticket.vue
@@ -36,6 +36,7 @@
              placeholder="请选择工单类型"
              class="filter-item"
              clearable
              @change="handleSearch"
            >
              <el-option
                v-for="item in types"
@@ -59,6 +60,7 @@
              placeholder="请选择状态"
              class="filter-item"
              clearable
              @change="handleSearch"
            >
              <el-option
                v-for="item in statuses"
@@ -72,6 +74,7 @@
              placeholder="请选择关联算法"
              class="filter-item"
              clearable
              @change="handleSearch"
            >
              <el-option
                v-for="item in algorithms"
@@ -85,6 +88,7 @@
              placeholder="请选择复核状态"
              class="filter-item"
              clearable
              @change="handleSearch"
            >
              <el-option
                v-for="item in reviewStatuses"
@@ -361,7 +365,7 @@
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="danger" :loading="submitLoading" @click="submitForm">发布</el-button>
          <el-button type="infoprimary" plain :loading="draftLoading" @click="saveDraft"
            >存草稿</el-button
@@ -374,7 +378,7 @@
    </el-dialog>
    <!-- 工单详情对话框 -->
    <el-dialog   align-center v-model="detailVisible" title="工单详情" width="80%" append-to-body>
    <el-dialog   class="custom-dialog" align-center v-model="detailVisible" title="工单详情" width="80%"  append-to-body>
      <div class="detail-container">
        <div class="detail-top-title">
          <div class="event-title-center event-orderNumber">
@@ -417,7 +421,8 @@
          </el-steps>
        </div>
        <!-- 基本信息表格 -->
      <div class="PopUpTableScrolls">
          <!-- 基本信息表格 -->
        <el-table :show-header="false" :data="formattedDetailFields" border class="tableCss">
          <el-table-column prop="label1" label="基本信息" width="150">
            <template #default="{ row }">
@@ -472,7 +477,7 @@
          <el-table-column prop="label2" label="基本信息" width="150">
            <template #default="{ row }">
              <!-- 添加必填星号的标签 -->
              <span
                v-if="
                  currentDetail.status === 0 &&
@@ -488,8 +493,8 @@
          <el-table-column>
            <template #default="{ row }">
              <!-- 修改工单类型和工单内容的显示 -->
              <template
                v-if="
                  currentDetail.status === 0 &&
@@ -574,7 +579,7 @@
        <!-- 图片和地图部分 -->
        <div class="media-section">
          <el-row :gutter="20">
            <el-col :span="12">
              <div class="media-box">
                <div class="media-title">事件图片</div>
@@ -633,28 +638,46 @@
                  </div>
                </template>
                <template v-else>
                  <div class="media-title">地图标记事件点</div>
                  <div class="media-title">地图标记事件点
                    <el-popover   v-if="currentDetail.status === 3 || currentDetail.status === 0"
                        popper-class="custom-qrcode-popover"
                        :width="120"
                        :visible="currentDetail.showQR && detailVisible"
                        placement="top"
                        title=""
                        trigger="click"
                     >
                        <template #reference>
                           <img @click.stop="handleQRCode(currentDetail)"  class="QRCodeImg" src="@/assets/images/dataCenter/qrCode.svg" alt="" title="事件导航" />
                        </template>
                        <div class="qrcode-content">
                           <CreateQRcode v-if="currentDetail.showQR && detailVisible" :latAndLon="currentDetail.location"></CreateQRcode>
                        </div>
                     </el-popover>
                  </div>
                  <div class="media-content">
                    <map-container v-if="detailVisible" ref="MapContainer"></map-container>
                  </div>
                </template>
              </div>
            </el-col>
          </el-row>
        </div>
      </div>
        <!-- 操作按钮 -->
        <div class="dialog-footer">
        <div class="dialog-footer1">
            <div
                class="leftBtn"
                :class="currentIndex === 0 ? 'disableds' : ''"
                @click="leftClick"
              >
               <el-icon><ArrowLeft /></el-icon>
               上一页
              </div>
       <div>
       <div class="btngroups">
           <template v-if="currentDetail.status === 2">
            <!-- 待审核 -->
            <el-button
@@ -713,7 +736,7 @@
                class="leftBtn"
                @click="rightClick"
              >
               <el-icon><ArrowRight /></el-icon>
              下一页
              </div>
        </div>
      </div>
@@ -729,6 +752,7 @@
      <el-form :model="dispatchForm" :rules="dispatchRules" ref="dispatchForm" label-width="100px">
        <el-form-item label="选择部门" prop="department">
          <el-select
            v-model="dispatchForm.department"
            placeholder="请选择部门"
            @change="handleDispatchDepartmentChange"
@@ -743,6 +767,7 @@
        </el-form-item>
        <el-form-item label="选择处理人" prop="handler">
          <el-select
          filterable
            v-model="dispatchForm.handler"
            placeholder="请选择处理人"
            :disabled="!dispatchForm.department"
@@ -880,6 +905,7 @@
import { getAdcodeObj } from '@/utils/disposeData'
import elTooltipCopy from '@/components/ElTooltipCopy.vue'
import getBaseConfig from '@/buildConfig/config'
import CreateQRcode from '@/components/CreateQRcode/CreateQRcode.vue'
const { envName } = getBaseConfig()
function regExp (label, name) {
  var reg = new RegExp(label + '=([^&]*)(&|$)', 'g')
@@ -887,7 +913,7 @@
}
export default {
  components: { elTooltipCopy },
  components: { elTooltipCopy,CreateQRcode },
  name: 'TicketPage',
  data() {
    return {
@@ -963,9 +989,9 @@
          // { label: "序号", prop: "id", width: 70 },
          { label: '工单编号', prop: 'orderNumber', width: 170 },
          { label: '工单名称', prop: 'orderName', width: 150, overHidden: true, tooltip: true },
          { label: '所属单位', prop: 'department',width: 150, overHidden: true, tooltip: true },
          { label: '所属单位', prop: 'department', overHidden: true, tooltip: true },
          { label: '发起时间', prop: 'startTime', width: 160 },
          { label: '关联算法', prop: 'aiType', width: 150, overHidden: true, tooltip: true },
          { label: '关联算法', prop: 'aiType', overHidden: true, tooltip: true },
          {
            label: '工单类型',
            prop: 'type',
@@ -1096,7 +1122,7 @@
  },
  mounted() {
    const href = this.$route.href;
    if (this.$route?.query?.status !== undefined && this.$route?.query?.status !== null) {
      this.filters.status = this.$route?.query?.status + '';
@@ -1268,7 +1294,6 @@
        { label: '当前状态', value: this.mapStatus(this.currentDetail.status) },
        { label: '事件地址', value: this.currentDetail.address || this.currentDetail.latAndLon }, // 包含经纬度信息
        { label: '关联算法',
        //  value: this.currentDetail.aiType
         value:
            this.algorithms.find(t => t.value === this.currentDetail.aiType)?.label ||
            this.currentDetail.aiType ||
@@ -1292,7 +1317,9 @@
          value2: filteredFields[i + 1]?.value || (filteredFields[i + 1]?.label ? '暂无数据' : ''),
        });
      }
      return formattedFields;
    },
    dynamicFixedStatuses() {
      // 直接使用接口返回的 stepInfos
@@ -1400,12 +1427,16 @@
      this.currentDetail.processingDetail = this.currentDetail.content;
      this.handleViewDetail(this.currentDetail);
      // 如果使用地图组件,需要更新地图标记
      this.$nextTick(() => {
        if (this.$refs.MapContainer && this.currentDetail.location) {
          this.$refs.MapContainer.initAddEntity('point', this.currentDetail.location);
        }
      });
    },
    async handleQRCode (val){
    val.showQR = !val.showQR
    },
    async loadAMapScripts() {
      try {
@@ -1553,7 +1584,7 @@
      }
      const matchedCategory = this.allAlgorithms.find(
        category => category.dict_key === typeValue
        category => category.dict_key === typeValue
      );
      if (!matchedCategory || !matchedCategory.algorithms || matchedCategory.algorithms.length === 0) {
@@ -1565,7 +1596,7 @@
// console.log('matchedCategory',matchedCategory);
      this.algorithms = matchedCategory.algorithms.map(algo => ({
        label: algo.dict_value,
        label: algo.dict_value,
        value: algo.dict_key,
        dict_key: algo.dict_key,
        dict_value: algo.dict_value
@@ -2047,12 +2078,15 @@
      this.currentDetail = {
        ...detailData,
        // address: null,
        showQR: false,
        latAndLon: _.round(detailData.location[0], 6) + ',' + _.round(detailData.location[1], 6),
      };
      console.log('this.currentDetail', this.currentDetail);
      this.detailVisible = true;
      this.handleTypeChange(this.currentDetail.type)
      console.log('this.currentDetail.location',this.currentDetail.location);
      this.$nextTick(() => {
        if (this.$refs.MapContainer && this.$refs.MapContainer.initAddEntity) {
          this.$refs.MapContainer.initAddEntity('point', this.currentDetail.location);
@@ -2344,8 +2378,8 @@
        this.$message.warning('请填写工单名称');
        return;
      }
      if (!this.currentDetail.type) {
        this.$message.warning('请选择工单类型');
      if (!this.currentDetail.aiType) {
        this.$message.warning('请选择关联算法');
        return;
      }
      if (!this.currentDetail.content || !this.currentDetail.content.trim()) {
@@ -2355,6 +2389,9 @@
      // 通过验证后,打开派发对话框
      this.dispatchDialogVisible = true;
      console.log('受理',this.currentDetail);
    },
    hasProcessingBtnPermission() {
      // undefined 或 false 都返回 false,只有 true 返回 true
@@ -2394,6 +2431,8 @@
        return;
      }
      this.dispatchLoading = true;
      console.log('派发成功',this.currentDetail);
      this.$refs.dispatchForm.validate(async valid => {
        if (valid) {
          try {
@@ -2407,7 +2446,9 @@
              content: this.currentDetail.content, // 使用 content 替代原来的 remark
              createDept: this.dispatchForm.department, // 派发部门 ID
              updateUser: this.dispatchForm.handler, // 处理人 ID
              aiType:this.currentDetail.aiType
            };
           console.log('派发',data);
            const file = this.currentDetail.file || null; // 如果没有文件,则为 null
@@ -2950,7 +2991,12 @@
};
</script>
<style lang="scss">
.custom-dialog {  max-height: 96vh; }
.custom-qrcode-popover {
min-width: 120px !important;
}
</style>
<style lang="scss" scoped>
::v-deep(.el-tabs) {
@@ -3157,10 +3203,7 @@
}
.dialog-footer {
display: flex;
  text-align: center;
  align-items: center;
  justify-content: space-between;
  padding-top: 16px;
  border-top: 1px solid #ebeef5;
@@ -3176,7 +3219,33 @@
    }
  }
}
.dialog-footer1 {
  position: sticky;
    bottom: 28px;
    left: 0;
    right: 0;
    background: white;
    z-index: 10;
    padding: 16px 20px;
    border-top: 1px solid #ebeef5;
    display: flex;
    justify-content: space-between;
    align-items: center;
  .el-button + .el-button {
    margin-left: 12px;
  }
.btngroups {
margin-left: 12px;
}
  .el-button {
    padding: 9px 20px;
    &:last-child {
      margin-left: 12px;
      margin-right: 12px;
    }
  }
}
.map-container {
  width: 100%;
  height: 400px;
@@ -3338,18 +3407,16 @@
}
.leftBtn {
  width: 36px;
  height: 36px;
  width: 70px;
  height: 32px;
  background-color: #999;
  border-radius: 50%;
  border-radius: 5px;
  text-align: center;
  line-height: 36px;
line-height: 32px;
  color: #fff;
  cursor: pointer;
  opacity: 0.8;
display: flex;
align-items: center;
justify-content: center;
}
.disableds {
@@ -3358,7 +3425,11 @@
  pointer-events: none;
  opacity: 0.3 !important;
}
.PopUpTableScrolls{
height: 600px;
overflow-y: scroll;
overflow-x: hidden;
}
.media-box {
  width: 100%;
  border: 1px solid #dcdfe6;
@@ -3370,11 +3441,19 @@
  .media-title {
    font-weight: bold;
    margin-bottom: 5px;
    display: flex;
    align-items: center;
    .QRCodeImg{
    width: 18px;
    height: 18px;
    cursor: pointer;
    padding-bottom: 1px;
    }
  }
  .media-content {
    position: relative;
    height: 250px;
    height: 500px;
    :deep(.el-image) {
      width: 100% !important;