src/views/fysp/data-product/ProdSceneReport.vue
@@ -1,3 +1,420 @@
<template>
  场景报告管理
</template>
  <BaseContentLayout>
    <template #header>
      <SearchBar @on-submit="search"> </SearchBar>
    </template>
    <template #aside>
      <SideList
        :items="subtasks"
        :loading="sideLoading"
        @item-click="chooseSubtask"
      ></SideList>
    </template>
    <template #main>
      <el-scrollbar class="el-scrollbar" v-loading="mainLoading">
        <CompSceneConstructionInfo
          title="A、基本信息"
          :scene="formScene"
          :form-info="formSubScene"
        />
        <div><el-text type="">附图片:</el-text></div>
        <CompImgInfo
          v-model:title="imgTitle"
          :img-src="sceneImg.url"
          @change="anyPhotoDialog = true"
        ></CompImgInfo>
        <el-divider />
        <el-text tag="h1">B、主要污染防治设施</el-text>
        <el-space wrap>
          <CompImgInfo
            v-for="(item, i) in deviceList"
            :key="i"
            down-title
            v-model:title="item._deviceTypeName"
            :img-src="item._showStatusPic"
            @change="showDevicePhotoDialog(item, i)"
          ></CompImgInfo>
        </el-space>
        <el-divider />
        <el-text tag="h1">C、现场污染问题与整改情况</el-text>
        <el-space wrap>
          <CompProblemTable
            v-for="(item, i) in curProList"
            :key="i"
            :problem="item"
            @change="(value) => handleProPicSelect(value, i)"
          ></CompProblemTable>
        </el-space>
        <el-divider />
        <el-text tag="h1">D、扬尘污染防治建议</el-text>
        <div class="p-b-8">
          针对该工地本期巡查发现的问题,评估为扬尘污染防治
          <el-radio-group v-model="radioStandard" size="default">
            <el-radio value="规范" border>规范</el-radio>
            <el-radio value="基本规范" border>基本规范</el-radio>
            <el-radio value="不规范" border>不规范</el-radio>
            <el-radio value="严重不规范" border>严重不规范</el-radio>
          </el-radio-group>
          工地,建议该工地严格按照《扬尘防治方案》、《扬尘防治承诺书》、《文明施工管理规范》、《精细化管理指标》等相关文件落实整改。
        </div>
        <el-row justify="center" style="height: 200px">
          <el-button
            icon="Download"
            type="primary"
            :loading="docLoading"
            :disabled="!sceneImg.url"
            @click="genWord()"
          >
            生成报告
          </el-button>
        </el-row>
      </el-scrollbar>
    </template>
  </BaseContentLayout>
  <el-dialog
    v-model="anyPhotoDialog"
    width="66%"
    title="任意图片"
    destroy-on-close
  >
    <ArbitraryPhoto
      :max-select="1"
      :readonly="false"
      :subtask="curSubtask.data"
      @selectByAnyPhonoEvent="handleSelectAnyPhoto"
      :defaultFile="[sceneImg]"
    >
    </ArbitraryPhoto>
  </el-dialog>
  <el-dialog
    title="设备图片"
    width="66%"
    v-model="deiveceImgDialog"
    destroy-on-close
  >
    <CompDevicePhono
      @selectPhonoEvent="handleSelectDevicePhoto"
      :imgPathsDataSource="showDeviceImgList"
    >
    </CompDevicePhono>
  </el-dialog>
</template>
<script setup>
import { ref, computed } from 'vue';
import { $fysp } from '@/api/index';
import taskApi from '@/api/fysp/taskApi';
import sceneApi from '@/api/fysp/sceneApi';
import deviceApi from '@/api/fysp/deviceApi';
import evaluateApi from '@/api/fysp/evaluateApi';
import { formatDeviceList } from '@/model/fysp/device';
import { enumDevice, toLabel } from '@/enum/device/device';
import { exportDocx } from '@/utils/doc';
import right_triangle from '@/assets/image/right_triangle.png';
import CompSceneConstructionInfo from '@/views/fysp/scene/CompSceneConstructionInfo.vue';
import ArbitraryPhoto from '@/views/fysp/check/components/ArbitraryPhoto.vue';
import CompDevicePhono from '@/views/fysp/check/components/CompDevicePhono.vue';
import CompImgInfo from '@/views/fysp/data-product/components/CompImgInfo.vue';
import CompProblemTable from './components/CompProblemTable.vue';
import dayjs from 'dayjs';
/************************* 左侧巡查任务选单 **********************************/
const curSubtask = ref({});
const subtasks = ref([]);
const sideLoading = ref(false);
const mainLoading = ref(false);
//获取任务问题的审核情况
function getSubtaskType(s) {
  let type = 0;
  if (s.proNum == 0) {
    type = 2;
  } else if (s.proCheckedNum == 0) {
    type = 0;
  } else if (s.proCheckedNum < s.proNum) {
    type = 1;
  } else {
    type = 2;
  }
  return type;
}
//查询子任务统计信息
function search(formSearch) {
  // this.topTask = formSearch.topTask;
  sideLoading.value = true;
  mainLoading.value = true;
  // this.curProList = [];
  curSubtask.value = {};
  const param = {
    topTaskId: formSearch.topTask.tguid,
    sceneTypeId: formSearch.sceneTypeId
  };
  taskApi.getSubtaskSummary(param).then((res) => {
    const list = [];
    res.forEach((s) => {
      const t = getSubtaskType(s);
      list.push({
        type: t,
        title: s.stName,
        categoly: s.stPlanTime.split('T')[0],
        data: s
      });
    });
    subtasks.value = list;
    if (list.length == 0) {
      sideLoading.value = false;
      mainLoading.value = false;
    }
  });
}
//点击左侧菜单任务事件
function chooseSubtask(s) {
  sideLoading.value = false;
  mainLoading.value = true;
  curSubtask.value = s;
  fetchSceneInfo(s.data.sceneId).finally(() => {
    mainLoading.value = false;
  });
  fetchDeviceList(s);
  fetchProblems(s);
  fetchEvaluation(s);
}
/************************* 场景基本信息 **********************************/
const imgTitle = ref('施工铭牌');
const formScene = ref({});
const formSubScene = ref({});
function fetchSceneInfo(sceneId) {
  formSubScene.value = {};
  sceneImg.value = {};
  return sceneApi.getSceneDetail(sceneId).then((res) => {
    //场景
    if (res.data.scense) formScene.value = res.data.scense;
    formSubScene.value = res.data.subScene ? res.data.subScene : {};
    // if (res.data.sceneDevice) {
    //   formSceneDevice = res.data.sceneDevice;
    // } else {
    //   formSceneDevice = {
    //     sGuid: formScene.guid,
    //   };
    // }
  });
}
// 任意拍图片选择对话框
const anyPhotoDialog = ref(false);
const sceneImg = ref({});
function handleSelectAnyPhoto(data) {
  anyPhotoDialog.value = false;
  if (data.length > 0) {
    sceneImg.value = data[0];
  }
}
/************************* 场景设备信息 **********************************/
// 设备图片选择对话框
const deiveceImgDialog = ref(false);
const showDeviceIndex = ref(0);
const showDeviceImgList = ref([]);
// 设备图片列表
const deviceList = ref([]);
function showDevicePhotoDialog(device, index) {
  showDeviceIndex.value = index;
  deiveceImgDialog.value = true;
  showDeviceImgList.value = [];
  let imgList = [];
  device._status
    .map((s) => s._picUrls)
    .forEach((pics) => {
      imgList = imgList.concat(
        pics.map((p) => {
          return {
            topTypeId: device.topTypeId,
            _picUrl: p
          };
        })
      );
    });
  // console.log(imgList);
  showDeviceImgList.value = imgList;
}
function handleSelectDevicePhoto(data) {
  deiveceImgDialog.value = false;
  if (data.length > 0) {
    deviceList.value[showDeviceIndex.value]._showStatusPic = data[0]._picUrl;
  }
}
const deviceTopTypes = [
  { id: 0, label: '监控设备' },
  { id: 1, label: '治理设备' }
  // { id: 2, label: '生产设备' }
];
function fetchDeviceList(s) {
  deviceList.value = [];
  for (const deviceTopTypeElement of deviceTopTypes) {
    const topTypeId = deviceTopTypeElement.id;
    deviceApi
      .fetchDevices(s.data.sceneId, topTypeId)
      .then((res) => {
        return formatDeviceList(res.data);
      })
      .then((result) => {
        result.forEach((r) => {
          const param = {
            deviceId: r.id,
            sceneId: r.sceneGuid,
            deviceTypeId: topTypeId
          };
          deviceApi
            .fetchDeviceStatus(param)
            .then((res) => {
              res.data.forEach((e) => {
                if (e.dlPicUrl && e.dlPicUrl.trim() != '') {
                  e._picUrls = e.dlPicUrl
                    .split(';')
                    .map((v) => $fysp.imgUrl + v);
                } else {
                  e._picUrls = [];
                }
              });
              return res;
            })
            .then((res) => {
              if (res.data.length > 0 && res.data[0]._picUrls.length > 0) {
                r._showStatusPic = res.data[0]._picUrls[0];
              }
              r._status = res.data;
              r.topTypeId = topTypeId;
              r._deviceTypeName = toLabel(r.sceneTypeId, topTypeId, [
                r.typeId,
                r.subtypeId
              ]).join('-');
              deviceList.value.push(r);
            });
        });
      });
  }
}
/************************* 现场巡查情况(问题与整改) **********************************/
const problemDesc = ref('');
//当前任务的问题列表
const curProList = ref([]);
const month = ref('');
const selectedProList = ref([]);
function fetchProblems(s) {
  curProList.value = [];
  taskApi.getProBySubtask(s.data.stGuid).then((res) => {
    curProList.value = res;
    // 生成巡查描述文本
    month.value = dayjs(s.data.stPlanTime).month() + 1;
    const proCount = curProList.value.length;
    problemDesc.value = `${month.value}月巡查共计发现${proCount}个问题`;
    if (proCount > 0) {
      problemDesc.value += ':';
      curProList.value.forEach((p, i) => {
        problemDesc.value += `${i + 1}、${p.problemname};`;
      });
      problemDesc.value += '如下图所示:';
    } else {
      problemDesc.value += '。';
    }
    // 生成选中的问题和整改图片描述
    selectedProList.value = curProList.value.map((v) => {
      return {};
    });
  });
}
function handleProPicSelect(value, index) {
  selectedProList.value[index] = value;
}
/************************* 扬尘防治建议 **********************************/
const radioStandard = ref('规范');
function fetchEvaluation(s) {
  evaluateApi.fetchItemEvaluation(s.data.stGuid).then((res) => {
    radioStandard.value = res.data.grade;
  });
}
/************************* 生成报告 **********************************/
const docLoading = ref(false);
// 生成word报告
function genWord() {
  const _deviceList = [];
  for (let i = 0; i < deviceList.value.length; i += 2) {
    const d1 = deviceList.value[i];
    const d2 =
      i + 1 < deviceList.value.length ? deviceList.value[i + 1] : undefined;
    _deviceList.push({
      _showStatusPic_1: d1._showStatusPic,
      _deviceTypeName_1: d1._deviceTypeName,
      // hasPic2: d2 ? true : false,
      _showStatusPic_2: d2 ? d2._showStatusPic : right_triangle,
      _deviceTypeName_2: d2 ? d2._deviceTypeName : ''
    });
  }
  const param = {
    index: formScene.value.index,
    sceneName: formScene.value.name,
    projectType: formSubScene.value.csProjectType,
    stage: formSubScene.value.siExtension1,
    startTime: formSubScene.value.csStartTime,
    endTime: formSubScene.value.csEndTime,
    leftTime: formSubScene.value.csLeftTime,
    location: formScene.value.location,
    floorSpace: formSubScene.value.csFloorSpace,
    constructionArea: formSubScene.value.csConstructionArea,
    constructionAreaPerMonth: formSubScene.value.csConstructionAreaPerMonth,
    contacts: formScene.value.contacts,
    contactst: formScene.value.contactst,
    securityOfficer: formSubScene.value.csSecurityOfficer,
    securityOfficerTel: formSubScene.value.csSecurityOfficerTel,
    constructionUnit: formSubScene.value.csConstructionUnit,
    employerUnit: formSubScene.value.csEmployerUnit,
    sceneType: formScene.value.type,
    imgTitle: imgTitle.value,
    imgTitle_url: sceneImg.value.url,
    deviceList: _deviceList,
    problemDesc: problemDesc.value,
    problemList: selectedProList.value.map((v) => {
      return {
        month: month.value,
        ...v
      };
    }),
    standard_1: radioStandard.value == '规范',
    standard_2: radioStandard.value == '基本规范',
    standard_3: radioStandard.value == '不规范',
    standard_4: radioStandard.value == '严重规范'
  };
  for (const key in param) {
    if (param[key] == undefined) {
      param[key] = '';
    }
  }
  const date = dayjs(curSubtask.value.data.stPlanTime).format('MM月DD日');
  console.log(param);
  docLoading.value = true;
  exportDocx(
    '/单体模版.docx',
    param,
    `${param.sceneName}单体(${date}).docx`,
    {
      horizontalHeight: 368,
      verticalWidth: 266
    }
  ).finally(() => (docLoading.value = false));
}
</script>