diff --git a/src/pages/TaskDisplay.jsx b/src/pages/TaskDisplay.jsx
index aeb6daf..c443c17 100644
--- a/src/pages/TaskDisplay.jsx
+++ b/src/pages/TaskDisplay.jsx
@@ -43,6 +43,9 @@ export default function TaskDisplay() {
const pageSize = cols * ROWS; // 2×2=4 或 2×3=6
const pageCount = Math.max(1, Math.ceil(tasks.length / pageSize));
const [countdown, setCountdown] = useState(Math.round(ROTATE_MS / 1000));
+ // 切换:page 为目标页,displayedPage 为当前展示页;切换时先显示「获取最新任务中」动画,1-2 秒后再切
+ const [displayedPage, setDisplayedPage] = useState(0);
+ const [switching, setSwitching] = useState(false);
useEffect(() => {
if (pageCount <= 1) { setPage(0); return; }
const t = setInterval(() => setPage((p) => (p + 1) % pageCount), ROTATE_MS);
@@ -56,13 +59,30 @@ export default function TaskDisplay() {
return () => clearInterval(t);
}, []);
+ // 页切换 → 显示加载动画,SWITCH_MS 后再切到新页
+ const SWITCH_MS = 1200;
+ useEffect(() => {
+ if (page === displayedPage) return;
+ setSwitching(true);
+ const t = setTimeout(() => { setDisplayedPage(page); setSwitching(false); }, SWITCH_MS);
+ return () => clearTimeout(t);
+ }, [page, displayedPage]);
+
+ // 手动/任务刷新 → 同样播放一次「获取最新任务中」
+ useEffect(() => {
+ if (refreshTick === 0) return;
+ setSwitching(true);
+ const t = setTimeout(() => setSwitching(false), SWITCH_MS);
+ return () => clearTimeout(t);
+ }, [refreshTick]);
+
const visible = useMemo(() => {
if (tasks.length === 0) return [];
- const start = page * pageSize;
+ const start = displayedPage * pageSize;
// 不足一页时按行补位(循环取),保证 2 行填满
const items = tasks.slice(start, start + pageSize);
return items.length ? items : Array.from({ length: pageSize }, (_, i) => tasks[i % tasks.length]);
- }, [tasks, page, pageSize]);
+ }, [tasks, displayedPage, pageSize]);
return (
@@ -76,7 +96,7 @@ export default function TaskDisplay() {
·
翻页 {pageCount > 1 ? `${countdown}s` : '—'}
·
- 页码 {pageCount > 1 ? `${page + 1}/${pageCount}` : '1/1'}
+ 页码 {pageCount > 1 ? `${displayedPage + 1}/${pageCount}` : '1/1'}
·
接单:抢单·竞标·指派·推荐
@@ -99,10 +119,17 @@ export default function TaskDisplay() {
{pageCount > 1 && (
{Array.from({ length: pageCount }).map((_, i) => (
-
+
))}
)}
+ {/* 切换/刷新加载遮罩 */}
+ {switching && (
+
+
+ 获取最新任务中…
+
+ )}
>
)}
diff --git a/src/styles/task-display.css b/src/styles/task-display.css
index ccb6766..eb7ece6 100644
--- a/src/styles/task-display.css
+++ b/src/styles/task-display.css
@@ -8,6 +8,7 @@
width: 100%;
height: 100%;
overflow: hidden;
+ position: relative; /* 供切换加载遮罩定位于此 */
background: radial-gradient(ellipse at 20% 0%, rgba(79, 135, 255, 0.08), transparent 55%),
radial-gradient(ellipse at 80% 100%, rgba(23, 178, 106, 0.06), transparent 55%);
}
@@ -115,3 +116,35 @@
.task-dots { display: flex; justify-content: center; gap: 8px; padding-bottom: 6px; }
.task-dot { width: 8px; height: 8px; border-radius: 50%; background: rgba(29, 44, 68, 0.15); transition: all 0.25s; }
.task-dot.on { background: var(--bd-blue, #2f6bff); width: 20px; border-radius: 999px; }
+
+/* ---- 切换/刷新加载遮罩:文字(获取最新任务中) + 旋转动画 ---- */
+.tasks-switch-overlay {
+ position: absolute;
+ inset: 0;
+ z-index: 5;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 14px;
+ background: rgba(255, 255, 255, 0.72);
+ backdrop-filter: blur(4px);
+ -webkit-backdrop-filter: blur(4px);
+}
+.tasks-spinner {
+ width: 42px;
+ height: 42px;
+ border-radius: 50%;
+ border: 4px solid rgba(47, 107, 255, 0.18);
+ border-top-color: var(--bd-blue, #2f6bff);
+ animation: tasks-spin 0.8s linear infinite;
+}
+.tasks-switch-text {
+ font-size: 15px;
+ font-weight: 600;
+ color: var(--bd-blue, #2f6bff);
+ letter-spacing: 0.05em;
+}
+@keyframes tasks-spin {
+ to { transform: rotate(360deg); }
+}