feiyu02
2025-09-17 b330e57051e54789eb83d10dc58c4d9d10c608e1
src/views/fysp/task/MonitorObjEdit.vue
@@ -1,13 +1,17 @@
<template>
  <el-affix :offset="60">
  <!-- <el-affix :offset="60" target=".el-main"> -->
    <div class="page-header">
      <el-page-header @back="$router.back()">
      <el-page-header @back="goBack">
        <template #content>
          <span> 总任务编辑 </span>
        </template>
        <template #extra>
          <div>
            <el-button type="primary" :disabled="!isEdit" :loading="saveLoading" @click="saveEdit"
            <el-button
              type="primary"
              :disabled="!isEdit"
              :loading="saveLoading"
              @click="handleSaveClick"
              >保存修改</el-button
            >
          </div>
@@ -15,319 +19,55 @@
      </el-page-header>
      <el-divider />
    </div>
  </el-affix>
  <el-row gutter="20">
    <el-col :span="16">
      <div>
        <el-text>已选场景</el-text>
      </div>
      <el-divider />
      <CompMonitorObj
        :data="curMonitorObjList"
        show-delete
        v-model:tabName="curSceneType"
        v-model:showData="showMonitorObjList"
        @delete-item="deleteMov"
      >
      </CompMonitorObj>
    </el-col>
    <el-col :span="8">
      <el-affix :offset="140">
        <div>
          <el-text>可选场景</el-text>
        </div>
        <el-divider />
        <div>
          <el-segmented v-model="curSceneType" :options="sceneTypeOptions" />
        </div>
        <FYInfoSearch
          label=""
          placeholder="请输入场景名称关键字"
          :data="showSceneList"
          :on-search="searchScene"
          :total="total"
          scroll-height="70vh"
          :page-show="false"
        >
          <template #default="{ row }">
            <ItemScene :item="row">
              <el-button-group>
                <el-button size="small" type="primary" @click="openInsertDialog(row)"
                  >插入</el-button
                >
                <el-button size="small" type="primary" @click="openAddDialog(row)">新增</el-button>
              </el-button-group>
            </ItemScene>
          </template>
        </FYInfoSearch>
      </el-affix>
    </el-col>
  </el-row>
  <el-dialog v-model="insertDialog" title="插入场景至空余编号" width="500">
    <div>以下为可选的空余编号</div>
    <el-radio-group v-model="selectedIndex" size="default">
      <el-radio-button v-for="item in valibleIndex" :key="item" :label="item" :value="item" />
    </el-radio-group>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="insertDialog = false">取消</el-button>
        <el-button :disabled="!selectedIndex" type="primary" @click="insertMov"> 确认 </el-button>
      </div>
    </template>
  </el-dialog>
  <el-dialog v-model="addDialog" title="新增场景编号顺延" width="500">
    <div>顺延编号为:{{ lastIndex }}</div>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="addDialog = false">取消</el-button>
        <el-button type="primary" @click="addMov"> 确认 </el-button>
      </div>
    </template>
  </el-dialog>
  <!-- </el-affix> -->
  <CompMonitorObjEdit
    ref="objEditRef"
    :task="task"
    :objList="curMonitorObjList"
    @upload-success="goBack"
  ></CompMonitorObjEdit>
</template>
<script>
import CompMonitorObj from './components/CompMonitorObj.vue';
import svUserApi from '@/api/fysp/userApi';
import taskApi from '@/api/fysp/taskApi';
import sceneApi from '@/api/fysp/sceneApi';
import { ElMessage, ElNotification } from 'element-plus';
<script setup>
import { ref, computed, onMounted } from 'vue';
import CompMonitorObjEdit from './components/CompMonitorObjEdit.vue';
import { useRoute, useRouter } from 'vue-router';
export default {
  components: { CompMonitorObj },
  props: {},
  data() {
    return {
      // 监管场景
      curMonitorObjList: [],
      // 当前筛选的场景类型
      curSceneType: undefined,
      showMonitorObjList: [],
const route = useRoute();
const router = useRouter();
const objEditRef = ref(null);
const curMonitorObjList = ref([]);
const task = ref({});
      // 行政区划
      area: {},
      // 所有场景
      sceneList: [],
      total: 0,
const isEdit = computed(() => {
  return objEditRef.value ? objEditRef.value.isEdit : false;
});
      // 插入弹出框
      insertDialog: false,
      // 插入或新增的编号
      selectedIndex: undefined,
      // 插入或新增的场景
      selectedScene: undefined,
      // 监管次数
      monitorTimes: 1,
      // 新增弹出框
      addDialog: false,
      // 新增的监管场景
      insertObj: [],
      // 更新的监管场景
      updateObj: [],
      // 删除的监管场景
      deleteObj: []
    };
  },
  computed: {
    // 当前场景类型下的展示场景
    showSceneList() {
      return this.sceneList.filter((v) => {
        const index = this.curMonitorObjList.findIndex((o) => {
          return o.sguid == v.guid;
        });
        return index == -1 && v.type == this.curSceneType;
      });
    },
    sceneTypeOptions(){
      const list = [];
      this.sceneList.forEach((d) => {
        if (list.indexOf(d.type) == -1) list.push(d.type);
      });
      return list;
    },
    // 当前场景类型下的可插入编号
    valibleIndex() {
      // 原列表已经按照编号顺序排列
      let index = 1;
      const indexList = [];
      this.showMonitorObjList.forEach((l) => {
        while (l.displayid > index) {
          indexList.push(index);
          index++;
        }
        index++;
      });
      if (indexList.length == 0) {
        indexList.push(1);
      }
      return indexList;
    },
    lastIndex() {
      const len = this.showMonitorObjList.length;
      if (len > 0) {
        return this.showMonitorObjList[len - 1].displayid + 1;
      } else {
        return 1;
      }
    },
    isEdit() {
      return this.insertObj.length > 0 || this.deleteObj.length > 0 || this.updateObj.length > 0;
    }
  },
  methods: {
    // 查询
    searchScene({ text, page, pageSize }) {
      this.area.sceneName = text;
      return sceneApi.searchScene(this.area, 1, 10000).then((res) => {
        if (res.success) {
          // 查询结果
          this.sceneList = res.data;
          // 总数据量
          this.total = res.head.totalCount;
        }
      });
    },
    deleteMov(item) {
      if (item.extension1) {
        ElMessage({
          message: '已监管场景无法移除',
          type: 'error'
        });
        return;
      }
      const i = this.curMonitorObjList.indexOf(item);
      this.curMonitorObjList.splice(i, 1);
      const i1 = this.insertObj.indexOf(item);
      this.insertObj.splice(i1, 1);
      const i2 = this.updateObj.indexOf(item);
      this.updateObj.splice(i2, 1);
function handleSaveClick() {
  objEditRef.value.saveEdit();
}
      this.deleteObj.push(item);
    },
    openInsertDialog(item) {
      this.insertDialog = true;
      this.selectedScene = item;
      this.monitorTimes = 1;
    },
    openAddDialog(item) {
      this.addDialog = true;
      this.selectedScene = item;
      this.monitorTimes = 1;
    },
    insertMov() {
      // 1. 创建新场景
      let mov = this.createMov(this.selectedIndex, this.selectedScene);
      // 2. 查找第一个编号大于插入编号的值,将新监管对象插入其之前
      const insertAtIndex = this.curMonitorObjList.findIndex((v) => {
        return v.displayid > this.selectedIndex;
      });
      this.curMonitorObjList.splice(insertAtIndex, 0, mov);
      this.selectedIndex = undefined;
      this.insertDialog = false;
    },
    addMov() {
      // 1. 创建新场景
      let mov = this.createMov(this.lastIndex, this.selectedScene);
      // 2. 添加至末尾
      this.curMonitorObjList.push(mov);
      this.addDialog = false;
    },
    // 创建一个新的监管对象
    createMov(displayid, scene) {
      // 1. 查找该场景是否之前已被删除
      const index = this.deleteObj.findIndex((v) => {
        return v.sguid == scene.guid;
      });
      let mov;
      // 2. 若是全新的场景,则新生成一个监管对象,否则只更新编号
      if (index == -1) {
        mov = {
          tid: this.task.tguid,
          sguid: scene.guid,
          sensename: scene.name,
          tasktypeid: 1,
          tasktype: '巡查',
          monitornum: this.monitorTimes,
          displayid: displayid,
          sceneTypeId: scene.typeid,
          sceneType: scene.type
        };
        this.insertObj.push(mov);
      } else {
        mov = this.deleteObj[index];
        mov.displayid = displayid;
        this.updateObj.push(mov);
        this.deleteObj.splice(index, 1);
      }
      return mov;
    },
    // 保存修改
    saveEdit() {
      // this.saveLoading = true;
      if (this.insertObj.length > 0) {
        const p1 = taskApi.addMonitorObject(this.insertObj).then((res) => {
          ElNotification({
            title: `巡查任务修改成功`,
            message: `新增场景${res}个`,
            type: 'success',
            position: 'bottom-left'
          });
          this.insertObj = [];
        });
      }
      if (this.updateObj.length > 0) {
        const p2 = taskApi.updateMonitorObject(this.updateObj).then((res) => {
          ElNotification({
            title: `巡查任务修改成功`,
            message: `更新场景${res}个`,
            type: 'success',
            position: 'bottom-left'
          });
          this.updateObj = [];
        });
      }
      if (this.deleteObj.length > 0) {
        const p3 = taskApi.deleteMonitorObject(this.deleteObj).then((res) => {
          ElNotification({
            title: `巡查任务修改成功`,
            message: `删除场景${res}个`,
            type: 'success',
            position: 'bottom-left'
          });
          this.deleteObj = [];
        });
      }
      // return Promise.all([p1, p2, p3]).finally(() => {
      //   this.saveLoading = false;
      // });
    }
  },
  mounted() {
    // 监管场景信息
    this.curMonitorObjList = JSON.parse(decodeURIComponent(this.$route.query.data));
    // 根据总任务获取行政区划信息
    const task = JSON.parse(decodeURIComponent(this.$route.query.task));
    this.task = task;
    this.area = {
      provincecode: task.provincecode,
      provincename: task.provincename,
      citycode: task.citycode,
      cityname: task.cityname,
      districtcode: task.districtcode,
      districtname: task.districtname,
      towncode: task.towncode,
      townname: task.townname,
      online: true
    };
    this.searchScene({ text: '' });
  }
};
function goBack() {
  router.back();
}
onMounted(() => {
  // 监管场景信息
  // curMonitorObjList.value = JSON.parse(decodeURIComponent(route.query.data));
  // 总任务
  task.value = JSON.parse(decodeURIComponent(route.query.task));
  // 监管场景信息
  curMonitorObjList.value = JSON.parse(
    decodeURIComponent(route.query.data)
  );
});
</script>
<style scoped>
.page-header {
  background-color: #fff;
  background-color: white;
  padding: 10px 0;
  /* border-bottom: 1px solid var(--el-color-info-light-7); */
}
</style>