列表进度处理

<script setup lang="ts">
import { Modal, message } from 'ant-design-vue';
import { ref } from 'vue';
import doubleSelect from './doubleSelect.vue';
import MapDialog from './mapDialog.vue';
import morejc from './morejc.vue';
import photolist from './photolist.vue';
import morenum from './morenum.vue';
import mxend from './mxend.vue';
import photomodal from './photomodal.vue';
import nameModal from './nameModal.vue';
import { getFullModelFileURL } from '@/utils/common';
// const props = withDefaults(defineProps<{
//   searchobj: any
// }>(), {
//   searchobj: () => { },
// });
const name = ref();
const confirmData = ref([]);
const treeData: any = ref([
]);
// 航线信息
const doubleSelectList = ref([
  {
    label: '三维建模测试航线A',
    children: [
      {
        label: '三维建模测试航线A-航线1',
        value: '1',
      },
      {
        label: '三维建模测试航线A-航线2',
        value: '2',
      },
      {
        label: '三维建模测试航线A-航线3',
        value: '3',
      },
      {
        label: '三维建模测试航线A-航线4',
        value: '4',
      },
      {
        label: '三维建模测试航线A-航线5',
        value: '5',
      },
    ],
    value: '12',
  },
  {
    label: '三维建模测试航线B',
    children: [
      {
        label: '三维建模测试航线B-航线1',
        value: '11',
      },
      {
        label: '三维建模测试航线B-航线2',
        value: '22',
      },
      {
        label: '三维建模测试航线B-航线3',
        value: '33',
      },
      {
        label: '三维建模测试航线B-航线4',
        value: '44',
      },
      {
        label: '三维建模测试航线B-航线5',
        value: '55',
      },
    ],
    value: '21',
  },
]);
// const  0-未开始, 1-未完成, 2-正常
const STATE = {
  '0': '未开始',
  '1': '未完成',
  '2': '已完成',
  '-1': '建模失败',
};
const mapDialogRef = ref();
// 左侧模型列表
let currentPage = 1;
const leftItem = ref();
const total = ref<number>(0);
const photolistqsRef = ref(); // 期数图片组件
const makeTypeshow = ref(1);// 模型样式
const numObj = ref();// 期数对象
const timer = ref<any>(); // 定时器

function _getApiModelMakePageQuery(isNew?: boolean, paramsObj?: any) {
  if (isNew) {
    currentPage = 1;
  }
  else {
    currentPage++;
  }
  const params: any = {
    currentPage,
    pageSize: 10,
    name: name.value,
  };
  if (paramsObj && paramsObj !== null) {
    params.createStartTime = paramsObj.createStartTime;
    params.createEndTime = paramsObj.createEndTime;
    params.finishStartTime = paramsObj.finishStartTime;
    params.finishEndTime = paramsObj.finishEndTime;
    params.state = paramsObj.state;
  }
  getApiModelMakePageQuery(params).then((res) => {
    if (res.success) {
      if (res.data && res.data !== null) {
        const _list: any = res.data?.records;
        total.value = res?.data?.total ?? 0;
        if (_list && _list.length) {
          if (isNew) {
            treeData.value = _list;
          }
          else {
            treeData.value = [...treeData.value, ..._list];
          }
          listClick(0, treeData.value[0]);
          leftItem.value = treeData.value[0]; // 默认第一条
          timer.value = setInterval(() => {
            // 获取进度
            treeData.value.forEach((element: any, index: any) => {
              // 0-未开始, 1-未完成, 2-正常 -1建模失败 */
              if (element.state === 1) {
                _getApiMediaModelLibraryGetOdmTaskInfoByModelMakePeriodId(element.latestModelMakePeriodId, index);
              }
              else if (element.state === 2) {
                treeData.value[index].modelState = 99;
                treeData.value[index].progress = 100;
              }
              else if (element.state === -1) {
                treeData.value[index].modelState = -2;
                treeData.value[index].progress = 0;
              }
              else {
                treeData.value[index].modelState = -1;
                treeData.value[index].progress = 0;
              }
            });
          }, 1000);
        }
      }
      else {
        treeData.value = [];
      }
    }
  });
}
// 停止定时请求
function stop() {
  if (timer.value) {
    clearInterval(timer.value);
    timer.value = null;
  }
}
/**
 * 筛选确认事件
 * @param val
 */
function onConfirm(val: any) {
  confirmData.value = val;
  const d = val.map((item: any) => {
    return {
      flyRecordId: item.id,
      taskName: item.taskName,
    };
  });
  // 追加架次
  _postApiModelMakePeriodAppend(d);
}

/**
 * 删除已选数据事件
 * @param val
 */
function onDelete(val: any) {
  Modal.confirm({
    title: '提示',
    content: '是否确认删除?',
    okText: '确认',
    cancelText: '取消',
    async onOk() {
      _postApiModelMakePeriodClear(val.modelMakePeriodId, [val]);
    },
  });
}
// 已选任务删除
function _postApiModelMakePeriodClear(id: any, list: any) {
  postApiModelMakePeriodClear({
    id,
    flyRecordList: list,
  }).then((res) => {
    if (res.success) {
      message.success(res.msg);
      _getApiModelMakePeriodFlyRecordList(numObj.value.id);// 已选任务
      photolistqsRef.value?._getApiModelMakePeriodImagePageQuery(); // 更新图片
    }
    else {
      message.error(res.msg);
    }
  });
}
function search() {
  _getApiModelMakePageQuery(true);
}
function add() {
  mapDialogRef.value.open();
}
const listIndex = ref(0);
const numList: any = ref([

]);
const titIndex = ref(0);
// 左侧点击
function listClick(index: any, item: any) {
  leftItem.value = item;
  listIndex.value = index;
  // 获取期数
  numObj.value = null;
  titIndex.value = 0;
  confirmData.value = [];
  makeTypeshow.value = 1;
  numList.value = [];
  _getApiModelMakePeriodList();
}
function _getApiModelMakePeriodList() {
  getApiModelMakePeriodList({
    modelMakeId: leftItem.value.id,
  }).then((res) => {
    if (res.success) {
      if (res.data && res.data !== null) {
        numList.value = res?.data;
        if (numList.value && numList.value.length) {
          numObj.value = numList.value[0]; // 默认第一期
          // 当前期数下已选任务
          _getApiModelMakePeriodFlyRecordList(numObj.value.id);
          // 如若是已完成 显示模型
          showModal(numObj.value);
        }
      }
    }
  });
}
// 更新期数列表
function getNumList() {
  _getApiModelMakePeriodList();
  _getApiModelMakePageQuery(true);// 左侧列表也更新
}
// 期数点击
const newNumIndex = ref();
const newNumItem = ref();
function titClick(index: any, item: any) {
  titIndex.value = index;
  numObj.value = item; // 当前期数
  newNumIndex.value = index;
  newNumItem.value = item;
  // console.log(item, 22222222222);
  // 已选任务
  _getApiModelMakePeriodFlyRecordList(item.id);
  // 如若是已完成 显示模型
  showModal(item);
}
// 追加架次
const morejcRef = ref();
function addmorejc() {
  if (!numObj.value) {
    message.warning('请先新建期数');
    return;
  }
  morejcRef.value.open();
}
// 重新添加
function addreset() {
  Modal.confirm({
    title: '提示',
    content: '重新添加架次将清空所有已选数据,是否确定重新添加?',
    okText: '确认',
    cancelText: '取消',
    async onOk() {
      _postApiModelMakePeriodClear(numObj.value.id, []);
    },
  });
}
// 三维制作
function doing() {
  Modal.confirm({
    title: '三维建模',
    content: '确认是否开始建模?',
    okText: '确认',
    cancelText: '取消',
    async onOk() {
      postApiModelMakePeriodStart({
        id: numObj.value.id,
      }).then((res) => {
        if (res.success) {
          message.success(res.msg);
          _getApiModelMakePageQuery(true);// 左侧列表刷新
        }
        else {
          message.error(res.msg);
        }
      });
    },
  });
}
// 新增期数
const morenumRef = ref();
function addnum() {
  // 左侧点击的值传过去
  morenumRef.value.open(leftItem.value);
}
const switchv = ref(1);
// 右侧是否点击
const rightIsclick = ref(0);
function makeClick() {
  rightIsclick.value++;
}
// 获取追加架次
function getjiaciconfirm(data: any) {
  const dd = data.map((item: any) => {
    return {
      flyRecordId: item.value,
      taskName: item.label,
    };
  });
  _postApiModelMakePeriodAppend(dd);
}
// 追加架次
function _postApiModelMakePeriodAppend(dataArr: any) {
  postApiModelMakePeriodAppend({
    id: numObj.value.id, // 期数id
    flyRecordList: dataArr,
  }).then((res) => {
    if (res.success) {
      message.success(res.msg);
      _getApiModelMakePeriodFlyRecordList(numObj.value.id);// 已选任务
      photolistqsRef.value?._getApiModelMakePeriodImagePageQuery();// 期数图片
    }
    else {
      message.error(res.msg);
    }
  });
}
// 查看原始数据
const photomodalRef = ref();
function lookPhoto() {
  photomodalRef.value.open();
}
// 若是已完成,显示模型
function showModal(item: any) {
  if (item.state === 2) {
    makeTypeshow.value = 2;
    nextTick(() => {
      (window as any).viewer.tifModel.addModel(getFullModelFileURL(item.geoJsonPath), true, leftItem.value.altitude, 16);
    });
  }
  else {
    makeTypeshow.value = 1;
  }
}
// 获取任务列表
function _getApiModelMakePeriodFlyRecordList(id: any) {
  getApiModelMakePeriodFlyRecordList({
    id,
  }).then((res) => {
    if (res.success) {
      if (res.data && res.data.length) {
        confirmData.value = res.data;
      }
      else {
        confirmData.value = [];
      }
      // console.log('confirmData.value ', confirmData.value);
    }
  });
}
// 名称修改
const nameModalRef = ref();
function edit() {
  nameModalRef.value?.open(leftItem.value);
}
function getname(data: any) {
  // postApiModelMakeUpdate
  // postApiModelMakePeriodUpdate
  postApiModelMakeUpdate({
    id: leftItem.value.id,
    name: data.name,
  }).then((res) => {
    if (res.success) {
      message.success(res.msg);
      _getApiModelMakePageQuery(true);
      // nextTick(()=>{
      //   listClick(listIndex.value, leftItem.value);
      // setTimeout(() => {
      //   titClick(newNumIndex.value, newNumItem.value);
      // }, 1000);
      // })
    }
    else {
      message.error(res.msg);
    }
  });
}
// 期数模型进度
function _getApiMediaModelLibraryGetOdmTaskInfoByModelMakePeriodId(modelMakePeriodIdv: any, index: any) {
  if (modelMakePeriodIdv && modelMakePeriodIdv !== null) {
    getApiMediaModelLibraryGetOdmTaskInfoByModelMakePeriodId({
      modelMakePeriodId: modelMakePeriodIdv,
    }).then((res) => {
      if (res.success) {
        if (res.data && res.data !== null) {
          treeData.value[index].modelState = res.data.state;
          treeData.value[index].progress = (res.data.progress)?.toFixed(2);
          // console.log('treeData.value111', treeData.value);
          // 如果有正常的重新刷新列表
          if (res.data.state === 99) {
            stop();
            _getApiModelMakePageQuery(true);
          }
        }
      }
    });
  }
}
function switchChange() {
  (window as any).viewer.tifModel.showModel(switchv.value);
}
// watch(
//   () => props.searchobj,
//   () => {
//     console.log('props.searchobj1111',props.searchobj)
//   },
//   {
//     deep: true,
//     immediate: true,
//   },
// );
_getApiModelMakePageQuery(true);
onUnmounted(() => {
  rightIsclick.value = 0;
  stop();
});
defineExpose({
  _getApiModelMakePageQuery,
});
</script>

<template>
  <div class="h-full flex  wrap-box" @click="makeClick">
    <div class="flex-none w-350px py-4 px-3 left-box">
      <div class="flex justify-between">
        <a-input v-model:value="name" placeholder="请输入" class="flex-none w-70%" allow-clear @change="search">
          <template #prefix>
            <SearchOutlined />
          </template>
        </a-input>
        <a-button v-auth="'board.achievement.add'" type="primary" @click="add">
          新建模型
        </a-button>
      </div>
      <ScrollLoad
        v-if="treeData?.length" class="list-box flex-auto overflow-auto min-h-0 pb-10"
        @load-more="_getApiModelMakePageQuery(false)"
      >
        <div
          v-for="(item, index) in treeData" :key="index" class="list-box-sub"
          :class="listIndex === index ? 'active' : ''" @click="listClick(index, item)"
        >
          <div>
            <span>
              {{ item.name }}
            </span> <span :class="`state-${item.state}`">{{ STATE[item.state] }}</span>
          </div>
          <div>
            {{ item.address }}
          </div>
          <!-- 进度新增 -->
          <div class="external-wrap">
            <div class="chart-rising-external">
              <div
                :style="{ width: `${item.progress}%` }" class="chart-rising-inside"
                :class="`state${item.modelState}`"
              />
            </div>
            <div class="chart-rising-text">
              {{ item.progress ? item.progress : 0 }}%
            </div>
          </div>
        </div>
      </ScrollLoad>
      <div v-else class="no-data pt-4 pl-2">
        暂无数据
      </div>
    </div>
    <div class="flex-auto make_box">
      <div class="right-top">
        三维照片:
        <div v-if="numList?.length" class="top-tit">
          <span
            v-for="(item, index) in numList" :key="index" :class="titIndex === index ? 'active' : ''"
            @click="titClick(index, item)"
          >第
            {{ item.periods }}
            期</span>
        </div>
        <div v-else class="no-data">
          暂无期数
        </div>
        <a-button
          v-if="treeData?.length" v-auth="'board.achievement.numadd'" type="primary" class="ml-2"
          @click="addnum"
        >
          新增
        </a-button>
      </div>
      <!-- 展示内容-制作添加 -->
      <div v-if="makeTypeshow === 1" class="cont-box">
        <div class="flex items-center">
          <doubleSelect
            title="选择飞行数据:" :tree-data="doubleSelectList" :right-isclick="rightIsclick" :num-obj="numObj"
            @confirm="onConfirm"
          />
          <div class="flex justify-between" style="flex-grow: 1;">
            <div>
              <a-button v-auth="'board.achievement.addzj'" type="primary" class="mr-3" @click="addmorejc">
                追加架次
              </a-button>
              <a-button
                v-if="confirmData && confirmData.length" v-auth="'board.achievement.resetadd'"
                @click="addreset"
              >
                重新添加
              </a-button>
            </div>
            <div>
              <span class="mr-3">创建时间:{{ numObj ? numObj.createTime ? numObj.createTime : '--' : '--' }}</span>
              <!-- 未完成才可以制作 -->
              <a-button
                v-if="numObj && numObj.state === 0 && confirmData.length" v-auth="'board.achievement.adddoing'"
                type="primary" class="mr-3" @click="doing"
              >
                三维制作
              </a-button>
            </div>
          </div>
        </div>
        <div v-if="confirmData && confirmData.length" class="flex yixuan-box">
          <div class="tit">
            已选数据:
          </div>
          <div class="flex w-full flex-wrap">
            <div v-for="item, index in confirmData" :key="index" class="select-item">
              <a-tooltip placement="top" :title="item?.taskName">
                <div class="select-item-text">
                  {{ item?.taskName }}
                </div>
              </a-tooltip>
              <div v-auth="'board.achievement.numdel'" class="img" @click="onDelete(item)">
                <img src="@/assets/images/delete.png" alt="">
              </div>
            </div>
          </div>
        </div>
        <div v-else class="no-data yixuan-box">
          已选数据:请先选择
        </div>
        <!-- 图片墙 -->
        <photolist ref="photolistqsRef" :model-make-period-id="numObj ? numObj.id : ''" />
      </div>
      <!-- 展示内容-制作完成显示 -->
      <div v-if="makeTypeshow === 2" class="cont-box cont-box2">
        <div class="tit-box flex">
          <div class="tit-box-left">
            <img src="@/assets/images/achieveDisplay/cont-right-icon.png" alt="" class="img1">
            <span>
              {{ leftItem ? leftItem.name ? leftItem.name : '' : '' }}
            </span>
            <img
              v-auth="'board.achievement.edit'" src="@/assets/images/achieveDisplay/cont-right-edit.png" alt=""
              class="img2" @click="edit"
            >
            <span class="mr-4">|</span>
            <span class="detail-cls" @click="lookPhoto">
              查看原始建模数据
            </span>
            <img src="@/assets/images/achieveDisplay/cont-right-arrow.png" alt="" class="img3">
          </div>
          <div class="tit-box-right">
            <span class="mr-8">
              制作完成时间:{{ numObj.finishTime ? numObj.finishTime : '--' }}
            </span>
            <span class="mr-8">
              在地图上显示
              <a-switch v-model:checked="switchv" :checked-value="1" :un-checked-value="0" class="ml-2" @change="switchChange" />
            </span>
            <span>
              默认展示
              <a-switch v-model:checked="switchv" :checked-value="1" :un-checked-value="0" class="ml-2" @change="switchChange" />
            </span>
          </div>
        </div>
        <!-- 完整模型 -->
        <mxend />
      </div>
    </div>
    <MapDialog ref="mapDialogRef" @confirm="_getApiModelMakePageQuery(true)" />
    <!-- 追加架次 -->
    <morejc ref="morejcRef" @confirm="getjiaciconfirm" />
    <!-- 期数添加 -->
    <morenum ref="morenumRef" @confirm="getNumList" />
    <!-- 原始建模数据 -->
    <photomodal ref="photomodalRef" :model-make-period-id="numObj ? numObj.id : ''" :rewn-list="confirmData" />
    <!-- 修改名称 -->
    <nameModal ref="nameModalRef" @confirmname="getname" />
  </div>
</template>

<style lang="less" scoped>
.wrap-box {
  border: 1px solid #456b9f;

  .left-box {
    border-right: 1px solid #456b9f;

    .list-box {
      // overflow-y: auto;
      // height: calc(100% - 50px);
      height: 670px;
      margin-top: 12px;

      .list-box-sub {
        padding: 8px;
        margin-bottom: 10px;
        font-family: PingFangSC-Regular;
        font-size: 15px;
        font-weight: 400;
        color: #f7f7f7;
        cursor: pointer;

        &:hover {
          background: #0c2e52;
        }

        &.active {
          background: #0c2e52;
        }

        div:nth-of-type(1) {
          display: flex;
          line-height: 21px;

          span:nth-of-type(1) {
            display: inline-block;
            width: 260px;
          }

          span:nth-of-type(2) {
            display: inline-block;
            width: 55px;
            // height: 16px;
            margin-top: 2px;
            margin-left: 8px;
            font-size: 12px;
            line-height: 16px;
            color: #ffffff;
            text-align: center;
            text-align: center;
            // background: #007f4f59;
            border-radius: 3px;
            // box-shadow: inset -3px -3px 12px 0 #03865cc7;
          }
          .state--1 {
            background: red;
            box-shadow: inset -3px -3px 12px 0 red;
          }
          .state-0 {
            background: #d86605;
            box-shadow: inset -3px -3px 12px 0 #d86605;
          }

          .state-1 {
            background: #fff70459;
            box-shadow: inset -3px -3px 12px 0 #f1e90659;
          }

          .state-2 {
            background: #007f4f59;
            box-shadow: inset -3px -3px 12px 0 #007f4f59;
          }
        }

        div:nth-of-type(2) {
          margin-top: 5px;
          font-size: 13px;
          color: #ffffffb3;
        }

        // .chart-rising-title {
        //   width: 62px;
        //   text-align: right;
        // }

        // .chart-rising-title,
        // .chart-rising-text {
        //   margin: 0 5px;
        //   font-size: 8px;
        //   font-weight: 400;
        //   color: rgba(255, 255, 255, 0.7);
        // }
        .external-wrap {
          display: flex;
          align-items: center;
          margin-top: 5px;

          .chart-rising-external {
            display: flex;
            align-items: center;

            width: 272px;
            height: 4px;
            background: #096fff4d;
            border-radius: 11px;

            .chart-rising-inside {
              height: 4px;
              background: #1790ff;
              border-radius: 11px;

              &.state99 {
                background: #59c06c;
              }

              &.state-1 {
                background: red;
              }

              &.state-2 {
                background: red;
              }

              &.state-3 {
                background: red;
              }
            }
          }

          .chart-rising-text {
            margin-top: 0;
            margin-left: 8px;
            font-family: PingFangSC-Regular;
            font-size: 12px;
            font-weight: 400;
            color: #ffffff80;
            text-align: right;
          }
        }
      }
    }
  }

  .make_box {
    .right-top {
      display: flex;
      align-items: center;
      height: 48px;
      padding: 0 16px;
      font-family: PingFangSC-Medium;
      font-size: 15px;
      font-weight: 500;
      color: #ffffff;
      border-bottom: 1px solid #456b9f;

      .top-tit {
        display: flex;
        align-items: center;
        height: 100%;
        margin-left: 26px;

        span {
          display: flex;
          align-items: center;
          height: 100%;
          margin-right: 43px;
          font-family: PingFangSC-Regular;
          font-size: 15px;
          font-weight: 400;
          color: #ffffffb3;
          text-align: center;
          cursor: pointer;

          // &:hover {
          //   color: #fff;
          //   border-bottom: 2px solid #2f6bff;
          // }

          &.active {
            color: #fff;
            border-bottom: 2px solid #2f6bff;
          }
        }
      }
    }

    .cont-box {
      .yixuan-box {
        display: flex;
        // flex-wrap: wrap;
        // align-items: center;
        // height: 32px;
        padding: 0 16px;

        .tit {
          width: 80px;
        }

        .select-item {
          display: flex;
          align-items: center;
          width: 218px;
          height: 28px;
          margin-right: 12px;
          margin-bottom: 10px;
          line-height: 32px;
          cursor: pointer;
          background: #173d66;
          border: 1px solid #446d9e00;
          border-radius: 4px;

          .select-item-text {
            width: 185px;
            padding: 3px 8px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            cursor: pointer;
          }

          .img {
            //  padding-left: 15px;
            padding: 0 6px;
            margin-top: 4px;
            cursor: pointer;

            img {
              width: 15px;
              height: 15px;
            }
          }
        }
      }

      &.cont-box2 {
        align-items: center;
        padding: 16px;

        .tit-box {
          display: flex;
          align-items: center;
          justify-content: space-between;
          height: 32px;
          line-height: 32px;

          .tit-box-left {
            display: flex;
            align-items: center;

            .img1 {
              width: 33px;
              height: 33px;
              margin-right: 8px;
            }

            .img2 {
              width: 16px;
              height: 16px;
              margin-right: 16px;
              margin-left: 4px;
              cursor: pointer;
            }

            .img3 {
              width: 16px;
              height: 16px;
              margin-left: 4px;
            }

            .detail-cls {
              font-family: PingFangSC-Regular;
              font-size: 15px;
              font-weight: 400;
              color: #1790ff;
              cursor: pointer;
            }
          }

          .tit-box-right {
            display: flex;
            align-items: center;

            span {
              display: flex;
              align-items: center;
            }
          }
        }
      }
    }
  }
}
</style>

 

posted @ 2025-07-31 16:32  abcByme  阅读(11)  评论(0)    收藏  举报