|
|
@@ -61,11 +61,7 @@
|
|
|
</div>
|
|
|
<div class="title-wrap van-ellipsis" v-show="shouldShowBlue(p)">
|
|
|
<div class="title-text" v-if="fw.flowStatus != null">{{ fw.flowStatus ==
|
|
|
- null ? '未激活' : '已激活' }}</div>
|
|
|
- <!-- <div class="expert-info">
|
|
|
- <el-avatar :size="14" src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png" />
|
|
|
- <span>专家下发</span>
|
|
|
- </div> -->
|
|
|
+ 3 ? '待认证' : '已过期' }}</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="card-right"
|
|
|
@@ -118,13 +114,14 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { ref, nextTick, watch, onMounted, onUnmounted, computed } from "vue";
|
|
|
-import { useRouter } from "vue-router";
|
|
|
+import { ref, nextTick, watch, onMounted, onUnmounted, onActivated, onDeactivated, computed } from "vue";
|
|
|
+import { useRouter, useRoute, onBeforeRouteLeave } from "vue-router";
|
|
|
import { ElMessage } from "element-plus";
|
|
|
import { Empty, showImagePreview } from "vant";
|
|
|
import { base_img_url2 } from "@/api/config";
|
|
|
|
|
|
const router = useRouter();
|
|
|
+const route = useRoute();
|
|
|
|
|
|
const props = defineProps({
|
|
|
// 农场 ID,用于请求农事规划数据
|
|
|
@@ -210,6 +207,36 @@ const phenologyStartDates = computed(() => {
|
|
|
});
|
|
|
const timelineContainerRef = ref(null);
|
|
|
const timelineListRef = ref(null);
|
|
|
+const getTimelineScrollKey = () =>
|
|
|
+ `timelineScrollTop:${props.pageType}:${props.farmId ?? "none"}:${props.regionId ?? "none"}:${props.containerId ?? "none"}:${route.path}`;
|
|
|
+
|
|
|
+const saveTimelineScrollTop = () => {
|
|
|
+ if (!timelineContainerRef.value) return;
|
|
|
+ const scrollTop = timelineContainerRef.value.scrollTop || 0;
|
|
|
+ sessionStorage.setItem(getTimelineScrollKey(), scrollTop.toString());
|
|
|
+};
|
|
|
+
|
|
|
+const restoreTimelineScrollTop = () => {
|
|
|
+ if (!timelineContainerRef.value) return false;
|
|
|
+ const savedScrollTop = sessionStorage.getItem(getTimelineScrollKey());
|
|
|
+ if (savedScrollTop == null) return false;
|
|
|
+ const scrollTop = Number(savedScrollTop);
|
|
|
+ if (Number.isNaN(scrollTop)) return false;
|
|
|
+ const maxScrollTop = Math.max(
|
|
|
+ 0,
|
|
|
+ (timelineContainerRef.value.scrollHeight || 0) - (timelineContainerRef.value.clientHeight || 0)
|
|
|
+ );
|
|
|
+ timelineContainerRef.value.scrollTop = Math.min(scrollTop, maxScrollTop);
|
|
|
+ return true;
|
|
|
+};
|
|
|
+const restoreTimelineScrollTopWithRetry = (retryCount = 4) => {
|
|
|
+ const restored = restoreTimelineScrollTop();
|
|
|
+ if (restored || retryCount <= 0) return restored;
|
|
|
+ setTimeout(() => {
|
|
|
+ restoreTimelineScrollTopWithRetry(retryCount - 1);
|
|
|
+ }, 60);
|
|
|
+ return false;
|
|
|
+};
|
|
|
// 标记是否为首次加载
|
|
|
const isInitialLoad = ref(true);
|
|
|
// 存储timeline-list的实际渲染高度
|
|
|
@@ -538,7 +565,8 @@ const handleSeasonClick = (seasonValue) => {
|
|
|
const getArrangeStatusClass = (fw) => {
|
|
|
const t = props.pageType === 'agri_record' ? fw?.flowStatus : fw?.sourceType;
|
|
|
if (props.pageType === 'agri_record') {
|
|
|
- if (t == null) return "status-default";
|
|
|
+ if (t == null || t == 0) return "status-default";
|
|
|
+ if (t ==3) return "status-complete";
|
|
|
return "status-act";
|
|
|
} else {
|
|
|
if (t == 10) return "status-complete";
|
|
|
@@ -548,22 +576,19 @@ const getArrangeStatusClass = (fw) => {
|
|
|
};
|
|
|
|
|
|
const handleRowClick = (item) => {
|
|
|
- // 记录当前页面滚动位置
|
|
|
- if (timelineContainerRef.value) {
|
|
|
- const scrollTop = timelineContainerRef.value.scrollTop || 0;
|
|
|
- sessionStorage.setItem("timelineScrollTop", scrollTop.toString());
|
|
|
- }
|
|
|
+ // 跳转前记录当前滚动位置
|
|
|
+ saveTimelineScrollTop();
|
|
|
emits("row-click", item);
|
|
|
};
|
|
|
|
|
|
// 获取农事规划数据
|
|
|
const getFarmWorkPlan = () => {
|
|
|
if (!props.farmId) return;
|
|
|
- // 如果正在请求,或者 farmId 与上次请求的相同,直接返回,防止重复请求
|
|
|
- if (isRequesting.value || lastRequestedFarmId.value === props.farmId) return;
|
|
|
- // 设置请求标志和记录 farmId
|
|
|
+ // 如果正在请求,或者 regionId 与上次请求的相同,直接返回,防止重复请求
|
|
|
+ if (isRequesting.value || lastRequestedFarmId.value === props.regionId) return;
|
|
|
+ // 设置请求标志和记录 regionId
|
|
|
isRequesting.value = true;
|
|
|
- lastRequestedFarmId.value = props.farmId;
|
|
|
+ lastRequestedFarmId.value = props.regionId;
|
|
|
// 更新时间戳,确保key变化,触发DOM重新渲染
|
|
|
uniqueTimestamp.value = Date.now();
|
|
|
// 重置测量高度,等待重新测量
|
|
|
@@ -689,47 +714,33 @@ const getFarmWorkPlan = () => {
|
|
|
timelineListRef.value.offsetHeight || timelineListRef.value.clientHeight;
|
|
|
if (height > 0) {
|
|
|
timelineListHeight.value = height;
|
|
|
-
|
|
|
- // 如果是首次加载,滚动到当前季节对应的节气
|
|
|
- if (isInitialLoad.value) {
|
|
|
- const currentSeason = getCurrentSeason();
|
|
|
- handleSeasonClick(currentSeason);
|
|
|
- isInitialLoad.value = false;
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ const hasRestoredScrollTop = restoreTimelineScrollTopWithRetry();
|
|
|
if (isInitialLoad.value) {
|
|
|
- // 如果测量失败,延迟一下再尝试滚动
|
|
|
- setTimeout(() => {
|
|
|
- if (timelineListRef.value) {
|
|
|
- const height =
|
|
|
- timelineListRef.value.offsetHeight ||
|
|
|
- timelineListRef.value.clientHeight;
|
|
|
- if (height > 0) {
|
|
|
- timelineListHeight.value = height;
|
|
|
- }
|
|
|
- }
|
|
|
- const currentSeason = getCurrentSeason();
|
|
|
- handleSeasonClick(currentSeason);
|
|
|
+ if (hasRestoredScrollTop) {
|
|
|
isInitialLoad.value = false;
|
|
|
- }, 200);
|
|
|
- } else {
|
|
|
- // 尝试恢复之前保存的滚动位置
|
|
|
- const savedScrollTopFromStorage = sessionStorage.getItem("timelineScrollTop");
|
|
|
- if (savedScrollTopFromStorage) {
|
|
|
- // 等待 DOM 完全渲染后再恢复滚动位置
|
|
|
- nextTick(() => {
|
|
|
- requestAnimationFrame(() => {
|
|
|
- if (timelineContainerRef.value) {
|
|
|
- const scrollTop = Number(savedScrollTopFromStorage);
|
|
|
- timelineContainerRef.value.scrollTop = scrollTop;
|
|
|
- // 恢复后清除保存的位置,避免下次误恢复
|
|
|
- sessionStorage.removeItem("timelineScrollTop");
|
|
|
+ } else {
|
|
|
+ // 如果测量失败,延迟一下再尝试滚动
|
|
|
+ setTimeout(() => {
|
|
|
+ if (timelineListRef.value) {
|
|
|
+ const height =
|
|
|
+ timelineListRef.value.offsetHeight ||
|
|
|
+ timelineListRef.value.clientHeight;
|
|
|
+ if (height > 0) {
|
|
|
+ timelineListHeight.value = height;
|
|
|
}
|
|
|
- });
|
|
|
- });
|
|
|
- } else if (timelineContainerRef.value && savedScrollTop > 0) {
|
|
|
+ }
|
|
|
+ if (!restoreTimelineScrollTopWithRetry()) {
|
|
|
+ const currentSeason = getCurrentSeason();
|
|
|
+ handleSeasonClick(currentSeason);
|
|
|
+ }
|
|
|
+ isInitialLoad.value = false;
|
|
|
+ }, 200);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!hasRestoredScrollTop && timelineContainerRef.value && savedScrollTop > 0) {
|
|
|
timelineContainerRef.value.scrollTop = savedScrollTop;
|
|
|
}
|
|
|
}
|
|
|
@@ -796,7 +807,7 @@ const updateFarmWorkPlan = () => {
|
|
|
};
|
|
|
|
|
|
watch(
|
|
|
- () => props.farmId,
|
|
|
+ () => props.regionId,
|
|
|
(val, oldVal) => {
|
|
|
// 如果 farmId 没有值,则不触发
|
|
|
if (!val) return;
|
|
|
@@ -812,7 +823,8 @@ watch(
|
|
|
);
|
|
|
|
|
|
const handleStatusDetail = (fw) => {
|
|
|
- console.log('fw', fw);
|
|
|
+ // 跳转前记录当前滚动位置
|
|
|
+ saveTimelineScrollTop();
|
|
|
router.push({
|
|
|
path: props.pageType === 'agri_plan' ? "/agricultural_detail" : "/work_detail",
|
|
|
query: {
|
|
|
@@ -973,18 +985,36 @@ onMounted(() => {
|
|
|
nextTick(() => {
|
|
|
requestAnimationFrame(() => {
|
|
|
setupResizeObserver();
|
|
|
+ restoreTimelineScrollTopWithRetry();
|
|
|
});
|
|
|
});
|
|
|
});
|
|
|
|
|
|
// 组件卸载前清理 ResizeObserver
|
|
|
onUnmounted(() => {
|
|
|
+ saveTimelineScrollTop();
|
|
|
if (resizeObserver) {
|
|
|
resizeObserver.disconnect();
|
|
|
resizeObserver = null;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
+onActivated(() => {
|
|
|
+ nextTick(() => {
|
|
|
+ requestAnimationFrame(() => {
|
|
|
+ restoreTimelineScrollTopWithRetry();
|
|
|
+ });
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+onDeactivated(() => {
|
|
|
+ saveTimelineScrollTop();
|
|
|
+});
|
|
|
+
|
|
|
+onBeforeRouteLeave(() => {
|
|
|
+ saveTimelineScrollTop();
|
|
|
+});
|
|
|
+
|
|
|
// 在数据更新后重新设置 ResizeObserver
|
|
|
watch(
|
|
|
() => phenologyList.value.length,
|