|
@@ -21,7 +21,7 @@
|
|
|
<!-- 未上传状态内容 -->
|
|
<!-- 未上传状态内容 -->
|
|
|
<div class="uploaded-content" v-show="item.questionStatus === 3 || item.expanded">
|
|
<div class="uploaded-content" v-show="item.questionStatus === 3 || item.expanded">
|
|
|
<div class="content-wrapper">
|
|
<div class="content-wrapper">
|
|
|
- <text-ellipsis class="item-desc" rows="2" :content="item.reason" expand-text="展开"
|
|
|
|
|
|
|
+ <text-ellipsis class="item-desc" rows="2" :content="item.remark + item.reason" expand-text="展开"
|
|
|
collapse-text="收起" />
|
|
collapse-text="收起" />
|
|
|
<div class="tip-box">如果不确定是否发生,直接上传照片即可</div>
|
|
<div class="tip-box">如果不确定是否发生,直接上传照片即可</div>
|
|
|
<div class="example-wrapper">
|
|
<div class="example-wrapper">
|
|
@@ -32,14 +32,14 @@
|
|
|
</div>
|
|
</div>
|
|
|
<div class="example-list" v-if="item.exampleImagesJson.length > 0">
|
|
<div class="example-list" v-if="item.exampleImagesJson.length > 0">
|
|
|
<div class="image-item-wrapper" v-for="(example, exIndex) in item.exampleImagesJson"
|
|
<div class="image-item-wrapper" v-for="(example, exIndex) in item.exampleImagesJson"
|
|
|
- :key="example" @click="showExample(item.exampleImagesJson, exIndex)">
|
|
|
|
|
|
|
+ :key="example" @click="showExample(item,item.exampleImagesJson, exIndex)">
|
|
|
<img class="image-item" :src="example" alt="" />
|
|
<img class="image-item" :src="example" alt="" />
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<text-ellipsis class="patrol-suggestion" rows="2" :content="'巡园建议:' + item.patrolSuggestion">
|
|
<text-ellipsis class="patrol-suggestion" rows="2" :content="'巡园建议:' + item.patrolSuggestion">
|
|
|
<template #action="{ expanded }"><span class="action-text">{{ expanded ? '收起' : '展开'
|
|
<template #action="{ expanded }"><span class="action-text">{{ expanded ? '收起' : '展开'
|
|
|
- }}</span></template>
|
|
|
|
|
|
|
+ }}</span></template>
|
|
|
</text-ellipsis>
|
|
</text-ellipsis>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -50,7 +50,7 @@
|
|
|
<!-- 图片展示 -->
|
|
<!-- 图片展示 -->
|
|
|
<div class="uploaded-images">
|
|
<div class="uploaded-images">
|
|
|
<div class="uploaded-img-wrap" v-for="(image, imgIndex) in item.imagePaths" :key="image"
|
|
<div class="uploaded-img-wrap" v-for="(image, imgIndex) in item.imagePaths" :key="image"
|
|
|
- @click="showExample(item.imagePaths.map(p => base_img_url2 + p), imgIndex, { hideLabel: true })">
|
|
|
|
|
|
|
+ @click="showExample(item,item.imagePaths.map(p => base_img_url2 + p), imgIndex, { hideLabel: true })">
|
|
|
<img class="uploaded-img" :src="base_img_url2 + image" alt="" />
|
|
<img class="uploaded-img" :src="base_img_url2 + image" alt="" />
|
|
|
<span v-show="item.questionStatus === 3" class="uploaded-img-remove"
|
|
<span v-show="item.questionStatus === 3" class="uploaded-img-remove"
|
|
|
@click.stop="removeUploadedImage(item, imgIndex)">×</span>
|
|
@click.stop="removeUploadedImage(item, imgIndex)">×</span>
|
|
@@ -80,14 +80,18 @@
|
|
|
</uploader>
|
|
</uploader>
|
|
|
|
|
|
|
|
<div class="question-wrapper" v-if="item.imagePaths.length">
|
|
<div class="question-wrapper" v-if="item.imagePaths.length">
|
|
|
- <div class="question-text">
|
|
|
|
|
- <span class="text-title">{{ item.question }}</span>
|
|
|
|
|
- <el-input v-model="item.answerValues[0]" :disabled="item.questionStatus !== 3" type="number"
|
|
|
|
|
- style="width: 70px">
|
|
|
|
|
- <template #suffix>
|
|
|
|
|
- <span class="text-unit">{{ item.indicators[0]?.unit || '%' }}</span>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-input>
|
|
|
|
|
|
|
+ <div class="question-cont">
|
|
|
|
|
+ <div class="question-text"
|
|
|
|
|
+ v-for="(q, qIdx) in (item.questionList || [item.question].filter(Boolean))" :key="qIdx">
|
|
|
|
|
+ <span class="text-title">{{ q }}</span>
|
|
|
|
|
+ <el-input v-model="item.answerValues[qIdx]" :disabled="item.questionStatus !== 3"
|
|
|
|
|
+ type="number" style="width: 70px">
|
|
|
|
|
+ <template #suffix>
|
|
|
|
|
+ <span class="text-unit">{{ item.indicators[qIdx]?.unit ?? item.indicators[0]?.unit
|
|
|
|
|
+ ?? '%' }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-input>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="draw-region-btn" v-if="item.interactionTypeId != 1 && item.questionStatus === 3"
|
|
<div class="draw-region-btn" v-if="item.interactionTypeId != 1 && item.questionStatus === 3"
|
|
|
@click="handleDrawRegion(item)">
|
|
@click="handleDrawRegion(item)">
|
|
@@ -114,9 +118,10 @@
|
|
|
<div class="proportion-info" v-show="item.questionStatus !== 3"
|
|
<div class="proportion-info" v-show="item.questionStatus !== 3"
|
|
|
:style="{ justifyContent: item.expanded ? 'center' : 'space-between' }">
|
|
:style="{ justifyContent: item.expanded ? 'center' : 'space-between' }">
|
|
|
<template v-if="!item.expanded">
|
|
<template v-if="!item.expanded">
|
|
|
- <span class="proportion-text">{{ item.question }}{{
|
|
|
|
|
- item.answerValues[0] || 0
|
|
|
|
|
- }}{{ item.indicators[0]?.unit || '%' }}</span>
|
|
|
|
|
|
|
+ <span class="proportion-text">{{(item.questionList && item.questionList.length
|
|
|
|
|
+ ? item.questionList.map((q, i) => q + (item.answerValues[i] ?? '') + (item.indicators[i]?.unit
|
|
|
|
|
+ ?? item.indicators[0]?.unit ?? '%')).join('')
|
|
|
|
|
+ : item.question + (item.answerValues[0] ?? '') + (item.indicators[0]?.unit ?? '%')) }}</span>
|
|
|
</template>
|
|
</template>
|
|
|
<div class="toggle-btn" @click="toggleExpand(item)">
|
|
<div class="toggle-btn" @click="toggleExpand(item)">
|
|
|
<span>{{ item.expanded ? "收起" : "展开" }}</span>
|
|
<span>{{ item.expanded ? "收起" : "展开" }}</span>
|
|
@@ -141,8 +146,8 @@
|
|
|
<drone-consult-popup v-model:show="showDroneConsultPopup" @copy="onCopyWechatId" />
|
|
<drone-consult-popup v-model:show="showDroneConsultPopup" @copy="onCopyWechatId" />
|
|
|
|
|
|
|
|
<!-- 示例照片轮播组件 -->
|
|
<!-- 示例照片轮播组件 -->
|
|
|
- <example-popup v-model:show="showExamplePopup" :images="exampleList" :start-index="exampleStartIndex"
|
|
|
|
|
- title="蒂蛀虫示例图" :show-title-and-tips="exampleShowTitleAndTips" />
|
|
|
|
|
|
|
+ <example-popup v-model:show="showExamplePopup" :images="exampleList" :tips="exampleTips" :start-index="exampleStartIndex" :title="exampleTitle"
|
|
|
|
|
+ :show-title-and-tips="exampleShowTitleAndTips" />
|
|
|
<!-- 照片上传进度 -->
|
|
<!-- 照片上传进度 -->
|
|
|
<popup v-model:show="showUploadProgressPopup" round class="upload-progress-popup">
|
|
<popup v-model:show="showUploadProgressPopup" round class="upload-progress-popup">
|
|
|
<div class="upload-progress-title">
|
|
<div class="upload-progress-title">
|
|
@@ -155,11 +160,14 @@
|
|
|
</upload>
|
|
</upload>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="input-box">
|
|
<div class="input-box">
|
|
|
- <div class="input-item">
|
|
|
|
|
- <span class="label-text">{{ currentItem.question }}</span>
|
|
|
|
|
- <el-input class="label-input" v-model="answerValue" placeholder="请输入" type="number">
|
|
|
|
|
|
|
+ <div class="input-item"
|
|
|
|
|
+ v-for="(q, qIdx) in (currentItem?.questionList?.length ? currentItem.questionList : (currentItem?.question ? [currentItem.question] : []))"
|
|
|
|
|
+ :key="qIdx">
|
|
|
|
|
+ <span class="label-text">{{ q }}</span>
|
|
|
|
|
+ <el-input class="label-input" v-model="currentItem.answerValues[qIdx]" placeholder="请输入" type="number">
|
|
|
<template #suffix>
|
|
<template #suffix>
|
|
|
- <span class="unit">{{ currentItem.indicators[0]?.unit || '%' }}</span>
|
|
|
|
|
|
|
+ <span class="unit">{{ currentItem.indicators[qIdx]?.unit ?? currentItem.indicators[0]?.unit ??
|
|
|
|
|
+ '%' }}</span>
|
|
|
</template>
|
|
</template>
|
|
|
</el-input>
|
|
</el-input>
|
|
|
</div>
|
|
</div>
|
|
@@ -167,7 +175,7 @@
|
|
|
</div>
|
|
</div>
|
|
|
<template v-if="currentItem.interactionTypeId != 1">
|
|
<template v-if="currentItem.interactionTypeId != 1">
|
|
|
<div class="region-tips">勾画新发生区域,精准匹配专属农事方案</div>
|
|
<div class="region-tips">勾画新发生区域,精准匹配专属农事方案</div>
|
|
|
- <div class="region-map" ref="mapContainer" @click="handleDrawRegion">
|
|
|
|
|
|
|
+ <div class="region-map" ref="mapContainer" @click="handleDrawRegion(currentItem)">
|
|
|
<div class="region-map-text">点击勾画新发生区域</div>
|
|
<div class="region-map-text">点击勾画新发生区域</div>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
@@ -181,7 +189,7 @@
|
|
|
请点击查看" buttonText="查看报告" @confirm="handleBtn" :zIndex="9999" />
|
|
请点击查看" buttonText="查看报告" @confirm="handleBtn" :zIndex="9999" />
|
|
|
</template>
|
|
</template>
|
|
|
<script setup>
|
|
<script setup>
|
|
|
-import { ref, onMounted, onActivated, computed, onDeactivated } from "vue";
|
|
|
|
|
|
|
+import { ref, onMounted, onActivated, computed, onUnmounted } from "vue";
|
|
|
import { ElMessage } from "element-plus";
|
|
import { ElMessage } from "element-plus";
|
|
|
import { Uploader, Popup, TextEllipsis } from "vant";
|
|
import { Uploader, Popup, TextEllipsis } from "vant";
|
|
|
import customHeader from "@/components/customHeader.vue";
|
|
import customHeader from "@/components/customHeader.vue";
|
|
@@ -220,7 +228,6 @@ const query = ref(useRoute().query);
|
|
|
const morePopupRef = ref(null);
|
|
const morePopupRef = ref(null);
|
|
|
//照片上传进度
|
|
//照片上传进度
|
|
|
const showUploadProgressPopup = ref(false);
|
|
const showUploadProgressPopup = ref(false);
|
|
|
-const answerValue = ref('');
|
|
|
|
|
// 上传进度统计
|
|
// 上传进度统计
|
|
|
const totalUploadCount = ref(0); // 本次选择的总文件数(固定不随上传成功变化)
|
|
const totalUploadCount = ref(0); // 本次选择的总文件数(固定不随上传成功变化)
|
|
|
const uploadedSuccessCount = ref(0); // 已上传成功的文件数
|
|
const uploadedSuccessCount = ref(0); // 已上传成功的文件数
|
|
@@ -236,29 +243,93 @@ const format = () => {
|
|
|
const drawRegionMap = new DrawRegionMap();
|
|
const drawRegionMap = new DrawRegionMap();
|
|
|
const mapContainer = ref(null);
|
|
const mapContainer = ref(null);
|
|
|
|
|
|
|
|
-// 从 sessionStorage 中回显已勾画的区域
|
|
|
|
|
const renderRegionFromSession = () => {
|
|
const renderRegionFromSession = () => {
|
|
|
|
|
+ if (!drawRegionMap.kmap) return;
|
|
|
|
|
+
|
|
|
|
|
+ // 先清空图层
|
|
|
|
|
+ drawRegionMap.clearLayer && drawRegionMap.clearLayer();
|
|
|
|
|
+
|
|
|
|
|
+ // 1)通过保存的互动项 ID,在 listData 中找到对应项,用接口 rangeWkt 回显只读区域
|
|
|
|
|
+ const savedId = sessionStorage.getItem("drawRegionInteractionId");
|
|
|
|
|
+ if (savedId && Array.isArray(listData.value) && listData.value.length > 0) {
|
|
|
|
|
+ const targetItem = listData.value.find(
|
|
|
|
|
+ (it) =>
|
|
|
|
|
+ it &&
|
|
|
|
|
+ it.id != null &&
|
|
|
|
|
+ (String(it.id) === savedId || Number(it.id) === Number(savedId))
|
|
|
|
|
+ );
|
|
|
|
|
+ if (targetItem && targetItem.rangeWkt && targetItem.rangeWkt.length > 10) {
|
|
|
|
|
+ // 使用 setStatusRegions 显示接口返回的区域
|
|
|
|
|
+ renderRegionFromItemWkt(targetItem);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 2)再回显本地勾画的多边形到可编辑图层(两者可共存)
|
|
|
const polygonStr = sessionStorage.getItem("drawRegionPolygonData");
|
|
const polygonStr = sessionStorage.getItem("drawRegionPolygonData");
|
|
|
- if (!polygonStr) return;
|
|
|
|
|
- try {
|
|
|
|
|
- const polygonData = JSON.parse(polygonStr);
|
|
|
|
|
- if (polygonData && Array.isArray(polygonData.geometryArr) && polygonData.geometryArr.length > 0) {
|
|
|
|
|
- // 先清空原有图层,再回显
|
|
|
|
|
- drawRegionMap.clearLayer && drawRegionMap.clearLayer();
|
|
|
|
|
- // needFitView 设为 true,让视图适配当前地块;同时传入面积用于只读模式展示“XX亩”
|
|
|
|
|
- drawRegionMap.setAreaGeometry(polygonData.geometryArr, true, polygonData.mianji);
|
|
|
|
|
|
|
+ if (polygonStr) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const polygonData = JSON.parse(polygonStr);
|
|
|
|
|
+ if (
|
|
|
|
|
+ polygonData &&
|
|
|
|
|
+ Array.isArray(polygonData.geometryArr) &&
|
|
|
|
|
+ polygonData.geometryArr.length > 0 &&
|
|
|
|
|
+ drawRegionMap.kmap &&
|
|
|
|
|
+ drawRegionMap.kmap.polygonLayer
|
|
|
|
|
+ ) {
|
|
|
|
|
+ // 注意这里不再调用 clearLayer,避免清掉上一步 setStatusRegions 的只读区域
|
|
|
|
|
+ // 此处也不单独做 fit,由下方统一调用 fitAllRegions 适配所有图层
|
|
|
|
|
+ drawRegionMap.setAreaGeometry(polygonData.geometryArr, false, polygonData.mianji);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ console.error("解析 drawRegionPolygonData 失败:", e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 3)统一根据只读图层 + 可编辑图层的范围自适应视图,保证所有区域都在视野内
|
|
|
|
|
+ if (drawRegionMap.fitAllRegions) {
|
|
|
|
|
+ drawRegionMap.fitAllRegions();
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 用当前项的 rangeWkt(接口返回的已保存区域)回显到地图;使用 setStatusRegions 方法显示
|
|
|
|
|
+const renderRegionFromItemWkt = (item) => {
|
|
|
|
|
+ const raw = item?.rangeWkt;
|
|
|
|
|
+ if (!raw || typeof raw !== 'string' || raw.length <= 10) return;
|
|
|
|
|
+ if (!drawRegionMap.kmap || !drawRegionMap.staticRegionLayer) return;
|
|
|
|
|
+ let geometryArr = [];
|
|
|
|
|
+ const trimmed = raw.trim();
|
|
|
|
|
+ if (trimmed.startsWith('{')) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const parsed = JSON.parse(raw);
|
|
|
|
|
+ if (parsed && Array.isArray(parsed.geometryArr) && parsed.geometryArr.length > 0) {
|
|
|
|
|
+ geometryArr = parsed.geometryArr;
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ console.error("解析 rangeWkt JSON 失败:", e);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ geometryArr = [raw];
|
|
|
|
|
+ }
|
|
|
|
|
+ if (geometryArr.length > 0) {
|
|
|
|
|
+ // 转换为 setStatusRegions 需要的格式:[{ geometry: wkt, status?: 'resolved' | 'unresolved' }]
|
|
|
|
|
+ const regions = geometryArr
|
|
|
|
|
+ .filter(wkt => wkt && typeof wkt === 'string' && wkt.trim().length > 10)
|
|
|
|
|
+ .map(wkt => ({
|
|
|
|
|
+ geometry: wkt.trim(),
|
|
|
|
|
+ status: 'resolved' // 接口返回的区域默认显示为未解决状态
|
|
|
|
|
+ }));
|
|
|
|
|
+ if (regions.length > 0) {
|
|
|
|
|
+ drawRegionMap.setStatusRegions(regions);
|
|
|
}
|
|
}
|
|
|
- } catch (e) {
|
|
|
|
|
- console.error("解析 drawRegionPolygonData 失败:", e);
|
|
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
//
|
|
//
|
|
|
const urgentType = {
|
|
const urgentType = {
|
|
|
- "0": "普通",
|
|
|
|
|
|
|
+ "0": "一般紧急",
|
|
|
"1": "紧急",
|
|
"1": "紧急",
|
|
|
"2": "非常紧急",
|
|
"2": "非常紧急",
|
|
|
- null: "未设置",
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const uploadFileObj = new UploadFile();
|
|
const uploadFileObj = new UploadFile();
|
|
@@ -276,8 +347,14 @@ const afterReadUpload = async (data) => {
|
|
|
}
|
|
}
|
|
|
totalUploadCount.value = data.length;
|
|
totalUploadCount.value = data.length;
|
|
|
uploadedSuccessCount.value = 0;
|
|
uploadedSuccessCount.value = 0;
|
|
|
- drawRegionMap.clearLayer && drawRegionMap.clearLayer();
|
|
|
|
|
- sessionStorage.removeItem("drawRegionPolygonData");
|
|
|
|
|
|
|
+ // 仅当「编辑发生区域」和本次上传是同一项时保留勾画数据并回显;否则清除,避免数据串
|
|
|
|
|
+ const savedInteractionId = sessionStorage.getItem("drawRegionInteractionId");
|
|
|
|
|
+ const isSameItem = savedInteractionId != null && String(currentItem.value?.id) === savedInteractionId;
|
|
|
|
|
+ if (!isSameItem) {
|
|
|
|
|
+ drawRegionMap.clearLayer && drawRegionMap.clearLayer();
|
|
|
|
|
+ sessionStorage.removeItem("drawRegionPolygonData");
|
|
|
|
|
+ sessionStorage.removeItem("drawRegionInteractionId");
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
for (let file of data) {
|
|
for (let file of data) {
|
|
|
// 将文件上传至服务器
|
|
// 将文件上传至服务器
|
|
@@ -303,7 +380,7 @@ const afterReadUpload = async (data) => {
|
|
|
showUploadProgressPopup.value = true;
|
|
showUploadProgressPopup.value = true;
|
|
|
|
|
|
|
|
// 所有文件上传结束后再打开进度弹窗,此时 imgArr 已包含全部图片
|
|
// 所有文件上传结束后再打开进度弹窗,此时 imgArr 已包含全部图片
|
|
|
- if (initImgArr.value.length > 0 && currentItem.value.interactionTypeId != 1) {
|
|
|
|
|
|
|
+ if (initImgArr.value.length > 0 && currentItem.value.interactionTypeId != 1 && currentItem.value.questionStatus === 3) {
|
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
|
// 只在第一次时初始化地图,后续复用已有实例
|
|
// 只在第一次时初始化地图,后续复用已有实例
|
|
|
if (!drawRegionMap.kmap) {
|
|
if (!drawRegionMap.kmap) {
|
|
@@ -315,8 +392,50 @@ const afterReadUpload = async (data) => {
|
|
|
false
|
|
false
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
- // 每次打开弹窗都尝试根据 sessionStorage 回显最新地块
|
|
|
|
|
- renderRegionFromSession();
|
|
|
|
|
|
|
+ // 先清空所有图层,再按规则分别回显:接口 rangeWkt 用 setStatusRegions,本地 session 用 setAreaGeometry,可共存
|
|
|
|
|
+ drawRegionMap.clearLayer && drawRegionMap.clearLayer();
|
|
|
|
|
+ const savedId = sessionStorage.getItem("drawRegionInteractionId");
|
|
|
|
|
+ const currentId = currentItem.value?.id;
|
|
|
|
|
+ const isSameItem =
|
|
|
|
|
+ savedId != null &&
|
|
|
|
|
+ currentId != null &&
|
|
|
|
|
+ (String(currentId) === savedId || Number(currentId) === Number(savedId));
|
|
|
|
|
+ const hasSessionPolygon = !!sessionStorage.getItem("drawRegionPolygonData");
|
|
|
|
|
+
|
|
|
|
|
+ // 1)接口返回的 rangeWkt:始终用 setStatusRegions 渲染到只读图层
|
|
|
|
|
+ if (currentItem.value?.rangeWkt?.length > 10) {
|
|
|
|
|
+ renderRegionFromItemWkt(currentItem.value);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 2)本地刚编辑的多边形(同一项且有 session 数据):用 setAreaGeometry 渲染到可编辑图层
|
|
|
|
|
+ if (isSameItem && hasSessionPolygon) {
|
|
|
|
|
+ const polygonStr = sessionStorage.getItem("drawRegionPolygonData");
|
|
|
|
|
+ if (polygonStr) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const polygonData = JSON.parse(polygonStr);
|
|
|
|
|
+ if (
|
|
|
|
|
+ polygonData &&
|
|
|
|
|
+ Array.isArray(polygonData.geometryArr) &&
|
|
|
|
|
+ polygonData.geometryArr.length > 0 &&
|
|
|
|
|
+ drawRegionMap.kmap &&
|
|
|
|
|
+ drawRegionMap.kmap.polygonLayer
|
|
|
|
|
+ ) {
|
|
|
|
|
+ // 此处不再调用 clearLayer,避免清掉上一步 setStatusRegions 的只读区域
|
|
|
|
|
+ drawRegionMap.setAreaGeometry(
|
|
|
|
|
+ polygonData.geometryArr,
|
|
|
|
|
+ true,
|
|
|
|
|
+ polygonData.mianji
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ console.error("解析 drawRegionPolygonData 失败:", e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (drawRegionMap.fitAllRegions) {
|
|
|
|
|
+ drawRegionMap.fitAllRegions();
|
|
|
|
|
+ }
|
|
|
|
|
+ // 3)其它情况:保持清空后的空地图
|
|
|
}, 100);
|
|
}, 100);
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
@@ -324,16 +443,21 @@ const afterReadUpload = async (data) => {
|
|
|
const currentItem = ref(null);
|
|
const currentItem = ref(null);
|
|
|
const handleUploadClick = (item) => {
|
|
const handleUploadClick = (item) => {
|
|
|
currentItem.value = item;
|
|
currentItem.value = item;
|
|
|
- answerValue.value = item.answerValues[0] || '';
|
|
|
|
|
};
|
|
};
|
|
|
|
|
+
|
|
|
// 示例照片轮播
|
|
// 示例照片轮播
|
|
|
const showExamplePopup = ref(false);
|
|
const showExamplePopup = ref(false);
|
|
|
const exampleList = ref([]);
|
|
const exampleList = ref([]);
|
|
|
const exampleStartIndex = ref(0);
|
|
const exampleStartIndex = ref(0);
|
|
|
const exampleShowTitleAndTips = ref(true);
|
|
const exampleShowTitleAndTips = ref(true);
|
|
|
-const showExample = (list, index, options = {}) => {
|
|
|
|
|
|
|
+const exampleTitle = ref('')
|
|
|
|
|
+const exampleTips = ref('')
|
|
|
|
|
+const showExample = (item, list, index, options = {}) => {
|
|
|
|
|
+ console.log("list", item);
|
|
|
|
|
+ exampleTitle.value = item.exampleImageAnnotation;
|
|
|
exampleList.value = list || [];
|
|
exampleList.value = list || [];
|
|
|
exampleStartIndex.value = index || 0;
|
|
exampleStartIndex.value = index || 0;
|
|
|
|
|
+ exampleTips.value = item.shootingMethod;
|
|
|
exampleShowTitleAndTips.value = options.hideLabel !== true;
|
|
exampleShowTitleAndTips.value = options.hideLabel !== true;
|
|
|
showExamplePopup.value = true;
|
|
showExamplePopup.value = true;
|
|
|
};
|
|
};
|
|
@@ -361,6 +485,21 @@ const loadData = async () => {
|
|
|
} else {
|
|
} else {
|
|
|
item.exampleImagesJson = [];
|
|
item.exampleImagesJson = [];
|
|
|
}
|
|
}
|
|
|
|
|
+ // question 按 || 切割成数组,用于循环渲染
|
|
|
|
|
+ const questionStr = item.question != null ? String(item.question) : '';
|
|
|
|
|
+ item.questionList = questionStr
|
|
|
|
|
+ ? questionStr.split('||').map(s => s.trim()).filter(Boolean)
|
|
|
|
|
+ : [];
|
|
|
|
|
+ if (!item.questionList.length && questionStr !== '') {
|
|
|
|
|
+ item.questionList = [questionStr];
|
|
|
|
|
+ }
|
|
|
|
|
+ // 保证 answerValues 与 questionList 长度一致,便于每项对应一个输入框
|
|
|
|
|
+ if (!Array.isArray(item.answerValues)) {
|
|
|
|
|
+ item.answerValues = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ while (item.answerValues.length < item.questionList.length) {
|
|
|
|
|
+ item.answerValues.push('');
|
|
|
|
|
+ }
|
|
|
return {
|
|
return {
|
|
|
...item
|
|
...item
|
|
|
};
|
|
};
|
|
@@ -386,8 +525,13 @@ const removeUploadedImage = (item, imgIndex) => {
|
|
|
// 确认上传 / 暂未到达进程
|
|
// 确认上传 / 暂未到达进程
|
|
|
const handleConfirm = async (item, isConfirm) => {
|
|
const handleConfirm = async (item, isConfirm) => {
|
|
|
if (isConfirm) {
|
|
if (isConfirm) {
|
|
|
- if (item.answerValues[0] === '' || item.answerValues[0] === null || item.answerValues[0] === undefined) {
|
|
|
|
|
- ElMessage.warning("请输入当前果园比例");
|
|
|
|
|
|
|
+ const list = item.questionList || [];
|
|
|
|
|
+ const needFill = list.length || 1;
|
|
|
|
|
+ const hasEmpty = Array.from({ length: needFill }, (_, i) => i).some(
|
|
|
|
|
+ (i) => item.answerValues[i] === '' || item.answerValues[i] === null || item.answerValues[i] === undefined
|
|
|
|
|
+ );
|
|
|
|
|
+ if (hasEmpty) {
|
|
|
|
|
+ ElMessage.warning("请填写当前果园比例");
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
if (item.imagePaths.length === 0 && uploadData.value.length === 0) {
|
|
if (item.imagePaths.length === 0 && uploadData.value.length === 0) {
|
|
@@ -422,25 +566,31 @@ const handleConfirmUpload = async () => {
|
|
|
ElMessage.warning("请先上传照片");
|
|
ElMessage.warning("请先上传照片");
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
- // 校验是否填写了输入框内容(百分比)
|
|
|
|
|
- if (answerValue.value === '' || answerValue.value === null || answerValue.value === undefined) {
|
|
|
|
|
- ElMessage.warning("请输入占比数值");
|
|
|
|
|
|
|
+ const item = currentItem.value;
|
|
|
|
|
+ const len = item?.questionList?.length || 1;
|
|
|
|
|
+ const hasEmpty = Array.from({ length: len }, (_, i) => i).some(
|
|
|
|
|
+ (i) => item.answerValues[i] === '' || item.answerValues[i] === null || item.answerValues[i] === undefined
|
|
|
|
|
+ );
|
|
|
|
|
+ if (hasEmpty) {
|
|
|
|
|
+ ElMessage.warning("请填写占比数值");
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
+ const answerVals = (item.answerValues || []).slice(0, len);
|
|
|
const parmas = {
|
|
const parmas = {
|
|
|
- interactionId: currentItem.value.id,
|
|
|
|
|
|
|
+ interactionId: item.id,
|
|
|
farmId: localStorage.getItem("selectedFarmId"),
|
|
farmId: localStorage.getItem("selectedFarmId"),
|
|
|
imagePaths: uploadData.value,
|
|
imagePaths: uploadData.value,
|
|
|
rangeWkt: sessionStorage.getItem("drawRegionPolygonData") || '',
|
|
rangeWkt: sessionStorage.getItem("drawRegionPolygonData") || '',
|
|
|
- replyText: currentItem.value.replyText,
|
|
|
|
|
- answerValues: [answerValue.value],
|
|
|
|
|
|
|
+ replyText: item.replyText,
|
|
|
|
|
+ answerValues: answerVals,
|
|
|
}
|
|
}
|
|
|
const { code, msg } = await VE_API.home.uploadAnswerData(parmas);
|
|
const { code, msg } = await VE_API.home.uploadAnswerData(parmas);
|
|
|
if (code === 0) {
|
|
if (code === 0) {
|
|
|
ElMessage.success("确认成功");
|
|
ElMessage.success("确认成功");
|
|
|
- // 清空上传数据
|
|
|
|
|
|
|
+ // 清空上传数据及勾画关联
|
|
|
uploadData.value = [];
|
|
uploadData.value = [];
|
|
|
sessionStorage.removeItem("drawRegionPolygonData");
|
|
sessionStorage.removeItem("drawRegionPolygonData");
|
|
|
|
|
+ sessionStorage.removeItem("drawRegionInteractionId");
|
|
|
showUploadProgressPopup.value = false;
|
|
showUploadProgressPopup.value = false;
|
|
|
// 刷新列表
|
|
// 刷新列表
|
|
|
await refreshList();
|
|
await refreshList();
|
|
@@ -455,13 +605,16 @@ const toggleExpand = (item) => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const handleDrawRegion = (item) => {
|
|
const handleDrawRegion = (item) => {
|
|
|
|
|
+ if (sessionStorage.getItem("drawRegionInteractionId") != item.id) {
|
|
|
|
|
+ sessionStorage.removeItem("drawRegionPolygonData");
|
|
|
|
|
+ sessionStorage.removeItem("drawRegionInteractionId");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 记录本次勾画对应的互动项 id,上传时若是同一项则保留回显,否则清除避免数据串
|
|
|
|
|
+ sessionStorage.setItem("drawRegionInteractionId", String(item.id));
|
|
|
const polygonData = sessionStorage.getItem("drawRegionPolygonData");
|
|
const polygonData = sessionStorage.getItem("drawRegionPolygonData");
|
|
|
|
|
+
|
|
|
if (item.rangeWkt && item.rangeWkt.length > 10) {
|
|
if (item.rangeWkt && item.rangeWkt.length > 10) {
|
|
|
- if (polygonData) {
|
|
|
|
|
- router.push(`/draw_region?polygonData=${polygonData}`);
|
|
|
|
|
- } else {
|
|
|
|
|
- router.push(`/draw_region?polygonData=${item.rangeWkt}`);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ router.push(`/draw_region?polygonData=${polygonData}&rangeWkt=${item.rangeWkt}&updatedTime=${item.updatedTime.slice(0,10)}`);
|
|
|
} else {
|
|
} else {
|
|
|
if (polygonData) {
|
|
if (polygonData) {
|
|
|
router.push(`/draw_region?polygonData=${polygonData}`);
|
|
router.push(`/draw_region?polygonData=${polygonData}`);
|
|
@@ -472,8 +625,9 @@ const handleDrawRegion = (item) => {
|
|
|
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-onDeactivated(() => {
|
|
|
|
|
|
|
+onUnmounted(() => {
|
|
|
sessionStorage.removeItem("drawRegionPolygonData");
|
|
sessionStorage.removeItem("drawRegionPolygonData");
|
|
|
|
|
+ sessionStorage.removeItem("drawRegionInteractionId");
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const uploadData = ref([]);
|
|
const uploadData = ref([]);
|
|
@@ -844,13 +998,12 @@ const handleSubmitAll = () => {
|
|
|
|
|
|
|
|
.question-wrapper {
|
|
.question-wrapper {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
- align-items: center;
|
|
|
|
|
|
|
+ align-items: flex-start;
|
|
|
justify-content: space-between;
|
|
justify-content: space-between;
|
|
|
gap: 10px;
|
|
gap: 10px;
|
|
|
margin: 12px 0 6px;
|
|
margin: 12px 0 6px;
|
|
|
box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
|
width: 100%;
|
|
width: 100%;
|
|
|
-
|
|
|
|
|
.question-text {
|
|
.question-text {
|
|
|
background: #ffffff;
|
|
background: #ffffff;
|
|
|
color: #6f6f6f;
|
|
color: #6f6f6f;
|
|
@@ -866,6 +1019,10 @@ const handleSubmitAll = () => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ .question-text + .question-text {
|
|
|
|
|
+ margin-top: 6px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
.draw-region-btn {
|
|
.draw-region-btn {
|
|
|
background: rgba(33, 153, 248, 0.1);
|
|
background: rgba(33, 153, 248, 0.1);
|
|
|
border-radius: 4px;
|
|
border-radius: 4px;
|