瀏覽代碼

feat:修改农事规划页面UI样式

wangsisi 7 小時之前
父節點
當前提交
0c66f7c46d

二進制
src/assets/img/common/rz-icon.png


+ 82 - 40
src/components/pageComponents/ArchivesFarmTimeLine.vue

@@ -38,7 +38,7 @@
                                 <div class="card-content">
                                     <div class="card-left" @click.stop="handleStatusDetail(fw)" style="width: 100%">
                                         <div class="left-info">
-                                            <div class="left-date">{{ formatDate(fw.createTime) }}</div>
+                                            <!-- <div class="left-date">{{ formatDate(fw.createTime) }}</div> -->
                                             <div class="text">
                                                 <span class="van-ellipsis">{{ fw.title }}</span>
                                                 <div class="text-status" v-if="farmWorkTypeObj[fw.farm_work_type]" :style="farmWorkTypeObjColor[fw.farm_work_type]">{{ farmWorkTypeObj[fw.farm_work_type] }}</div>
@@ -63,8 +63,10 @@
                                         </div>
                                     </div>
                                     <div class="status-right" :style="getStatusColorObj(fw)"
-                                        v-if="fw.work_status !== 3 && fw.work_status !== 5">{{
-                                            workStatusObj[fw.work_status] }}</div>
+                                        v-if="fw.work_status !== 3 && fw.work_status !== 5">
+                                        <img v-if="fw.work_status === 4" src="@/assets/img/common/rz-icon.png" alt="">
+                                        <span>{{ workStatusObj[fw.work_status] }}</span>
+                                    </div>
                                 </div>
                             </div>
                         </div>
@@ -214,28 +216,60 @@ const hasSavedTimelineScrollBeyondTop = () => {
 const getAgriRecordParentScrollKey = () =>
     `agriRecordArchivesOuterScroll:${props.farmId ?? "none"}:${route.path}`;
 
-/** 外层滚动:任意已写入数值(含 0)均视为已建立缓存,避免返回后被 scrollIntoView 拉走 */
-const hasSavedParentArchivesScroll = () => {
+/** 外层滚动:仅当明显离开过顶部时才视为有效缓存,避免 scrollTop=0 误挡首次定位 */
+const hasSavedParentArchivesScrollBeyondTop = () => {
     const raw = sessionStorage.getItem(getAgriRecordParentScrollKey());
     if (raw == null) return false;
     const n = Number(raw);
-    return !Number.isNaN(n);
+    return !Number.isNaN(n) && n > 4;
+};
+
+const clearSavedParentArchivesScroll = () => {
+    sessionStorage.removeItem(getAgriRecordParentScrollKey());
+};
+
+/** 查找可滚动的祖先容器(优先匹配农事记录页外层 `.archives-time-line-content`) */
+const findScrollParentForCard = (card) => {
+    if (!card) return null;
+    const archivesArea = card.closest(".archives-time-line-content");
+    if (archivesArea) return archivesArea;
+    let node = card.parentElement;
+    while (node && node !== document.body) {
+        const style = window.getComputedStyle(node);
+        const canScrollY =
+            (style.overflowY === "auto" || style.overflowY === "scroll") &&
+            node.scrollHeight > node.clientHeight + 1;
+        const canScrollX =
+            (style.overflowX === "auto" || style.overflowX === "scroll") &&
+            node.scrollWidth > node.clientWidth + 1;
+        if (canScrollY || canScrollX) return node;
+        node = node.parentElement;
+    }
+    return null;
 };
 
 /**
- * 在「农事记录」等页面中,真正滚动的是外层 `.archives-time-line`,本组件 `.timeline-container` 往往随内容撑开、不产生内部滚动条,
- * 只改 timeline 的 scrollTop 无效。使用 scrollIntoView 让浏览器滚动实际产生滚动的祖先容器,并把目标块垂直居中。
+ * 在「农事记录」等页面中,真正滚动的是外层 `.archives-time-line-content`,本组件 `.timeline-container` 往往随内容撑开、不产生内部滚动条
+ * 手动计算 scrollTop / scrollLeft,将目标卡片对齐到滚动区域顶部
  */
-const scrollCardIntoNearestScrollportCenter = (card) => {
-    card.scrollIntoView({ block: "center", behavior: "auto", inline: "nearest" });
+const scrollCardIntoNearestScrollportTop = (card) => {
+    const scrollParent = findScrollParentForCard(card);
+    if (!scrollParent) {
+        card.scrollIntoView({ block: "start", behavior: "auto", inline: "start" });
+        return;
+    }
+    const cardRect = card.getBoundingClientRect();
+    const parentRect = scrollParent.getBoundingClientRect();
+    scrollParent.scrollTop += cardRect.top - parentRect.top;
+    scrollParent.scrollLeft += cardRect.left - parentRect.left;
 };
 
-/** 默认滚动到首个「待执行」(work_status=2),并在可视滚动区域内垂直居中;若无则回退到首个右侧有状态标签的卡片(3、5 不展示标签) */
+/** 默认滚动到首个「待执行」(work_status=2),并在可视滚动区域内对齐顶部;若无则回退到首个右侧有状态标签的卡片(3、5 不展示标签) */
 const scrollToFirstVisibleStatusCard = () => {
     const root = timelineContainerRef.value;
     if (!root || isEmpty.value) return;
     if (hasSavedTimelineScrollBeyondTop()) return;
-    if (hasSavedParentArchivesScroll()) return;
+    if (hasSavedParentArchivesScrollBeyondTop()) return;
     const cards = root.querySelectorAll(".arrange-card[data-work-status]");
 
     let target = null;
@@ -258,21 +292,19 @@ const scrollToFirstVisibleStatusCard = () => {
         }
     }
     if (!target) return;
-    scrollCardIntoNearestScrollportCenter(target);
+    scrollCardIntoNearestScrollportTop(target);
 };
 
 const scrollToFirstVisibleStatusCardAfterPaint = () => {
+    const tryScroll = () => scrollToFirstVisibleStatusCard();
     nextTick(() => {
         requestAnimationFrame(() => {
-            scrollToFirstVisibleStatusCard();
-            // 外层布局(flex/高度)晚一帧才稳定时再滚一次,避免第一次滚到错误视口
-            requestAnimationFrame(() => {
-                scrollToFirstVisibleStatusCard();
+            tryScroll();
+            requestAnimationFrame(tryScroll);
+            // 与父页 restoreArchivesOuterScrollTopWithRetry 异步布局错开,多次尝试确保滚到位
+            [120, 300, 500, 800].forEach((ms) => {
+                window.setTimeout(tryScroll, ms);
             });
-            // 与父页 `restoreArchivesOuterScrollTopWithRetry` 等异步布局错开,避免刚滚好又被恢复成旧位置
-            window.setTimeout(() => {
-                scrollToFirstVisibleStatusCard();
-            }, 120);
         });
     });
 };
@@ -372,7 +404,7 @@ const getStatusColorObj = (fw) => {
             color = "#FF6A6A";
             background = "#fff";
         }else{
-            color = "#2199F8";
+            color = "#8B8B8B";
             background = "#fff";
         }
     }
@@ -401,7 +433,7 @@ const getArrangeStatusClass = (fw) => {
             return "status-normal";
         }
     }
-    if (status === 0 || status === 1) return "status-normal";
+    if (status === 0 || status === 1 || status === 4) return "status-normal";
     return "future-card";
 };
 
@@ -574,6 +606,7 @@ watch(
             oldFarmId == null || farmId !== oldFarmId || tab !== oldTab;
         if (scopeChanged) {
             lastRequestedScopeKey.value = null;
+            clearSavedParentArchivesScroll();
         }
         updateFarmWorkPlan();
     },
@@ -652,21 +685,21 @@ onBeforeRouteLeave(() => {
         background: $content-bg;
     }
 
-    .card-left {
-        .title-text {
-            @if $color !=null {
-                color: $color;
-            }
+    // .card-left {
+    //     .title-text {
+    //         @if $color !=null {
+    //             color: $color;
+    //         }
 
-            @if $content-color !=null {
-                background: $content-color;
-            }
+    //         @if $content-color !=null {
+    //             background: $content-color;
+    //         }
 
-            @if $border-color !=null {
-                border-color: $border-color;
-            }
-        }
-    }
+    //         @if $border-color !=null {
+    //             border-color: $border-color;
+    //         }
+    //     }
+    // }
 
     &::before {
         border-right-color: $color;
@@ -872,6 +905,7 @@ onBeforeRouteLeave(() => {
                                     align-items: center;
                                     gap: 4px;
                                     width: calc(100% - 90px);
+                                    color: #414141;
                                 }
                                 .text-status {
                                     background: rgba(33, 153, 248, 0.1);
@@ -896,7 +930,7 @@ onBeforeRouteLeave(() => {
                                     top: -5px;
                                     width: 13px;
                                     height: 13px;
-                                    background: #2199F8;
+                                    background: #C5C5C5;
                                     border-radius: 50%;
                                     display: flex;
                                     align-items: center;
@@ -909,12 +943,12 @@ onBeforeRouteLeave(() => {
                                 width: fit-content;
                                 max-width: 100%;
                                 text-align: left;
-                                color: rgba(0, 0, 0, 0.4);
+                                color: rgba(91, 91, 91, 0.6);
                                 padding: 0 6px;
                                 border-radius: 2px;
                                 font-size: 12px;
                                 box-sizing: border-box;
-                                border: 0.5px solid rgba(0, 0, 0, 0.4);
+                                border: 0.5px solid rgba(91, 91, 91, 0.2);
                                 position: relative;
                             }
 
@@ -948,6 +982,13 @@ onBeforeRouteLeave(() => {
                             background: #FF953D;
                             border-radius: 0 8px 0 4px;
                             padding: 0 5px;
+                            display: flex;
+                            align-items: center;
+                            gap: 3px;
+                            img{
+                                width: 12px;
+                                height: 13px;
+                            }
                         }
                     }
 
@@ -966,7 +1007,8 @@ onBeforeRouteLeave(() => {
                 }
 
                 .arrange-card.status-normal {
-                    @include arrange-card-status(#2199F8, null, #2199F8, null);
+                    @include arrange-card-status(#2199F8, null, #2199F8, rgba(33, 153, 248, 0.1));
+                    border-width: 0.8px;
                 }
 
                 .arrange-card.status-orange {

+ 2 - 1
src/views/old_mini/agri_record/index.vue

@@ -67,7 +67,8 @@ const restoreArchivesOuterScrollTop = () => {
     const raw = sessionStorage.getItem(getArchivesOuterScrollKey());
     if (raw == null) return false;
     const scrollTop = Number(raw);
-    if (Number.isNaN(scrollTop)) return false;
+    // scrollTop=0 视为未建立有效滚动位置,留给子组件自动定位到「待执行」
+    if (Number.isNaN(scrollTop) || scrollTop <= 4) return false;
     const el = archivesScrollAreaRef.value;
     const maxScrollTop = Math.max(0, (el.scrollHeight || 0) - (el.clientHeight || 0));
     el.scrollTop = Math.min(scrollTop, maxScrollTop);