Prechádzať zdrojové kódy

feat:添加显示更清楚UI

wangsisi 4 dní pred
rodič
commit
2676f77d2b

+ 91 - 3
src/App.vue

@@ -150,19 +150,35 @@
 
     <!-- 开启底部安全区适配 -->
     <number-keyboard safe-area-inset-bottom />
+
+    <!-- 异常巡检识别中:右上角固定 loading + 文案 -->
+    <div v-if="showInspectLoading" class="inspect-loading-fixed">
+        <loading type="spinner" color="#fff" size="18px" />
+        <span class="inspect-loading-fixed__text">识别中</span>
+    </div>
+
+    <!-- 异常巡检成功:全局弹窗,任意页面可显示 -->
+    <tip-popup
+        v-model:show="showInspectSuccessPopup"
+        type="executeSuccess"
+        text="您已上传成功"
+        text2="诊断报告已生成"
+        buttonText="完成"
+    />
     </el-config-provider>
 </template>
 
 <script setup>
-import { NumberKeyboard } from "vant";
-import { Tabbar, TabbarItem } from "vant";
-import { nextTick, watch, onMounted, ref, computed } from "vue";
+import { NumberKeyboard, Tabbar, TabbarItem, Loading } from "vant";
+import { nextTick, watch, onMounted, onBeforeUnmount, ref, computed } from "vue";
 import { useRoute, useRouter } from "vue-router";
 import { useStore } from "vuex";
 import { NH, NZ, EXPERT } from "@/common/user_role";
 import zhCn from "element-plus/es/locale/lang/zh-cn";
 import en from "element-plus/es/locale/lang/en";
 import { useI18n } from "@/i18n";
+import eventBus from "@/api/eventBus";
+import tipPopup from "@/components/popup/tipPopup.vue";
 
 const { t, locale } = useI18n();
 const store = useStore();
@@ -170,6 +186,40 @@ const elementLocale = computed(() => (locale.value === "en" ? en : zhCn));
 const route = useRoute();
 const router = useRouter();
 
+/** 与 growthTrack 异常巡检约定:识别中全局悬浮 loading / 成功全局弹窗 */
+const INSPECT_PENDING_KEY = "AGRI_INSPECT_PENDING";
+const INSPECT_PENDING_EVENT = "inspect-upload-pending";
+const INSPECT_DONE_EVENT = "inspect-upload-done";
+const INSPECT_SUCCESS_KEY = "AGRI_INSPECT_UPLOAD_SUCCESS";
+const INSPECT_SUCCESS_EVENT = "inspect-upload-success";
+const showInspectLoading = ref(false);
+const showInspectSuccessPopup = ref(false);
+
+function openInspectLoading() {
+    showInspectLoading.value = true;
+}
+
+function closeInspectLoading() {
+    sessionStorage.removeItem(INSPECT_PENDING_KEY);
+    showInspectLoading.value = false;
+}
+
+function tryShowInspectLoading() {
+    if (sessionStorage.getItem(INSPECT_PENDING_KEY) !== "1") return;
+    openInspectLoading();
+}
+
+function openInspectSuccessPopup() {
+    closeInspectLoading();
+    sessionStorage.removeItem(INSPECT_SUCCESS_KEY);
+    showInspectSuccessPopup.value = true;
+}
+
+function tryShowInspectSuccessPopup() {
+    if (sessionStorage.getItem(INSPECT_SUCCESS_KEY) !== "1") return;
+    openInspectSuccessPopup();
+}
+
 // 首页loading加载完才显示底部导航栏
 const showTab = ref(false);
 // 0: 农户, 1: 专家, 2:农资农服
@@ -221,6 +271,12 @@ watch(
 );
 
 onMounted(() => {
+    tryShowInspectLoading();
+    tryShowInspectSuccessPopup();
+    eventBus.on(INSPECT_PENDING_EVENT, openInspectLoading);
+    eventBus.on(INSPECT_DONE_EVENT, closeInspectLoading);
+    eventBus.on(INSPECT_SUCCESS_EVENT, openInspectSuccessPopup);
+
     setTimeout(() => {
         curRole.value = store.state.app.curRole;
         if (route.meta.showTabbar) {
@@ -237,6 +293,12 @@ onMounted(() => {
     }, 500);
 });
 
+onBeforeUnmount(() => {
+    eventBus.off(INSPECT_PENDING_EVENT, openInspectLoading);
+    eventBus.off(INSPECT_DONE_EVENT, closeInspectLoading);
+    eventBus.off(INSPECT_SUCCESS_EVENT, openInspectSuccessPopup);
+});
+
 watch(
     () => route.name,
     (newName, oldName) => {
@@ -264,4 +326,30 @@ watch(
     pointer-events: all;
     z-index: 9999;
 }
+
+.inspect-loading-fixed {
+    position: fixed;
+    top: 10px;
+    right: 12px;
+    z-index: 10000;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    gap: 2px;
+    width: 56px;
+    height: 56px;
+    border-radius: 50%;
+    background: #1989fa;
+    box-shadow: 0 4px 12px rgba(25, 137, 250, 0.35);
+    pointer-events: none;
+
+    &__text {
+        font-size: 11px;
+        line-height: 14px;
+        color: #fff;
+        font-weight: 500;
+        white-space: nowrap;
+    }
+}
 </style>

+ 6 - 4
src/views/old_mini/agri_file/fileMap.js

@@ -85,8 +85,10 @@ function createHiDpiCanvas(cssWidth, cssHeight) {
 }
 
 function iconFromCanvas(canvas, dpr, anchor) {
+    // 用 canvas 本体,避免 toDataURL:跨域封面无 CORS 时 canvas 会污染,导出失败导致缩略图空白
     return new Icon({
-        src: canvas.toDataURL(),
+        img: canvas,
+        imgSize: [canvas.width, canvas.height],
         scale: 1 / dpr,
         anchor,
         anchorXUnits: "fraction",
@@ -193,9 +195,7 @@ function loadImage(src) {
             return;
         }
         const img = new Image();
-        if (/^https?:\/\//i.test(String(src))) {
-            img.crossOrigin = "anonymous";
-        }
+        // 不设 crossOrigin:相册 cloud_url 常无 CORS,强制 anonymous 会 onerror,标记只剩灰底
         img.onload = () => resolve(img);
         img.onerror = () => resolve(null);
         img.src = src;
@@ -455,7 +455,9 @@ class FileMap {
             feature.setStyle(createPhotoMarkerStyle(null, item.count));
             source.addFeature(feature);
             loadImage(item.cover).then((img) => {
+                if (!img) return;
                 feature.setStyle(createPhotoMarkerStyle(img, item.count));
+                feature.changed();
             });
         });
 

+ 4 - 25
src/views/old_mini/agri_file/index.vue

@@ -127,15 +127,6 @@
         <album-upload-popup v-model:show="showUploadPopup" />
         <complete-farm-info-popup v-model:show="showCompleteFarmPopup" @confirm="goCompleteFarmInfo" />
 
-        <!-- 异常巡检上传成功(接口 200 后弹出) -->
-        <tip-popup
-            v-model:show="showInspectSuccessPopup"
-            type="executeSuccess"
-            text="您已上传成功"
-            text2="诊断报告已生成"
-            buttonText="完成"
-        />
-
         <!-- 诊断报告弹窗 -->
         <diagnosis-report-popup ref="diagnosisReportPopupRef" />
 
@@ -166,7 +157,6 @@ import * as util from "@/common/ol_common.js";
 import farmHeader from "@/components/farmHeader.vue";
 import albumUploadPopup from "./components/albumUploadPopup.vue";
 import completeFarmInfoPopup from "@/components/popup/completeFarmInfoPopup.vue";
-import tipPopup from "@/components/popup/tipPopup.vue";
 import diagnosisReportPopup from "@/components/popup/diagnosisReportPopup.vue";
 import restorePlantingPopup from "@/components/popup/restorePlantingPopup.vue";
 import proxyAuthPopup from "@/components/popup/proxyAuthPopup.vue";
@@ -182,23 +172,14 @@ const router = useRouter();
 const tabBarHeight = computed(() => store.state.home.tabBarHeight);
 const diagnosisReportPopupRef = ref(null);
 
-/** 与 growthTrack 异常巡检约定:接口成功后弹出成功窗 */
-const INSPECT_SUCCESS_KEY = "AGRI_INSPECT_UPLOAD_SUCCESS";
+/** 与 growthTrack 异常巡检约定:成功后刷新列表(弹窗已由 App 全局承接) */
 const INSPECT_SUCCESS_EVENT = "inspect-upload-success";
-const showInspectSuccessPopup = ref(false);
 
-function openInspectSuccessPopup() {
-    sessionStorage.removeItem(INSPECT_SUCCESS_KEY);
-    showInspectSuccessPopup.value = true;
+function onInspectSuccess() {
     fetchReportList();
     fetchCropArchiveList();
 }
 
-function tryShowInspectSuccessPopup() {
-    if (sessionStorage.getItem(INSPECT_SUCCESS_KEY) !== "1") return;
-    openInspectSuccessPopup();
-}
-
 /** 恢复种植确认「已到达」后,再检查是否弹出诊断报告 */
 const onPhenologyReached = () => {
     diagnosisReportPopupRef.value?.checkShouldShow?.();
@@ -944,18 +925,16 @@ const goAlbumDetail = (item) => {
 onMounted(() => {
     initAlbumMap();
     tryShowGuide();
-    tryShowInspectSuccessPopup();
-    eventBus.on(INSPECT_SUCCESS_EVENT, openInspectSuccessPopup);
+    eventBus.on(INSPECT_SUCCESS_EVENT, onInspectSuccess);
     document.addEventListener("click", handleOutsideClick, true);
 });
 onActivated(() => {
     loadPatrolContent();
     initAlbumMap();
     tryShowGuide();
-    tryShowInspectSuccessPopup();
 });
 onBeforeUnmount(() => {
-    eventBus.off(INSPECT_SUCCESS_EVENT, openInspectSuccessPopup);
+    eventBus.off(INSPECT_SUCCESS_EVENT, onInspectSuccess);
     clearMapOverlays();
     document.removeEventListener("click", handleOutsideClick, true);
 });

+ 10 - 10
src/views/old_mini/agri_file/pages/diagnosisReport.vue

@@ -369,7 +369,7 @@ const handleShare = () => {
         }
 
         &__desc {
-            font-size: 13px;
+            font-size: 14px;
             line-height: 20px;
             font-weight: 400;
             opacity: 0.95;
@@ -384,7 +384,7 @@ const handleShare = () => {
 
     .base-bg {
         width: 100%;
-        height: 335px;
+        height: 380px;
         margin: 12px 0;
         padding: 5px;
         box-sizing: border-box;
@@ -409,7 +409,7 @@ const handleShare = () => {
             border: 1px solid #FFFFFF;
             padding: 12px 14px;
             margin-top: -10px;
-            font-size: 13px;
+            font-size: 14px;
             line-height: 22px;
 
             &__row {
@@ -446,7 +446,7 @@ const handleShare = () => {
         border-radius: 10px;
         background: #eef0f3;
         color: #86909c;
-        font-size: 12px;
+        font-size: 14px;
         line-height: 16px;
         box-sizing: border-box;
         border: 1px solid transparent;
@@ -552,7 +552,7 @@ const handleShare = () => {
             margin-bottom: 0;
 
             .report-block__chart-img {
-                height: 400px;
+                height: 550px;
             }
         }
     }
@@ -561,23 +561,23 @@ const handleShare = () => {
         display: block;
         width: auto;
         max-width: none;
-        height: 145px;
+        height: 175px;
 
         &--natural {
-            height: 245px;
+            height: 285px;
         }
     }
 
     &__intro {
         margin: 0 0 10px;
-        font-size: 13px;
+        font-size: 14px;
         line-height: 20px;
         color: #1d2129;
     }
 
     &__note {
         margin: 0 0 12px;
-        font-size: 12px;
+        font-size: 14px;
         line-height: 18px;
         color: #86909c;
     }
@@ -621,7 +621,7 @@ const handleShare = () => {
 
     &__text {
         margin: 0;
-        font-size: 13px;
+        font-size: 14px;
         line-height: 20px;
         color: #4e5969;
     }

+ 11 - 1
src/views/old_mini/agri_file/pages/growthTrack.vue

@@ -133,6 +133,10 @@ const ENTRY_FARM_DATA_KEY = "ENTRY_FARM_DATA";
 /** 异常巡检成功后,回农事档案页弹出成功提示 */
 const INSPECT_SUCCESS_KEY = "AGRI_INSPECT_UPLOAD_SUCCESS";
 const INSPECT_SUCCESS_EVENT = "inspect-upload-success";
+/** 异常巡检进行中:档案页显示悬浮 loading */
+const INSPECT_PENDING_KEY = "AGRI_INSPECT_PENDING";
+const INSPECT_PENDING_EVENT = "inspect-upload-pending";
+const INSPECT_DONE_EVENT = "inspect-upload-done";
 
 const isAbnormal = computed(() => route.query.type === "abnormal");
 const pageTitle = computed(() => route.query.pageName || "巡园要点");
@@ -383,7 +387,9 @@ function startAbnormalInspect(images) {
         return;
     }
 
-    ElMessage.success("报告正在生成中...");
+    // 先回档案页展示悬浮 loading,接口结束后再关掉
+    sessionStorage.setItem(INSPECT_PENDING_KEY, "1");
+    eventBus.emit(INSPECT_PENDING_EVENT);
     router.replace("/agri_file");
 
     VE_API.questionnaire
@@ -408,6 +414,10 @@ function startAbnormalInspect(images) {
         })
         .catch(() => {
             ElMessage.error("提交失败,请稍后再试");
+        })
+        .finally(() => {
+            sessionStorage.removeItem(INSPECT_PENDING_KEY);
+            eventBus.emit(INSPECT_DONE_EVENT);
         });
 }