refactor(mp): 架构重构 — usePageData 统一数据加载 + Store 解耦 + 大页面拆分

新增 usePageData hook(useDidShow 节流 + usePullDownRefresh + loadingRef 防重入 + enabled 条件守卫),
44/58 页面迁移接入,消灭 4 种数据加载模式并存。

- 新增 hooks/usePageData.ts — 统一页面数据加载生命周期
- 新增 stores/index.ts — resetAllStores() 解耦 auth↔health store 依赖
- 新增 pages/index/useHomeData.ts — 首页数据 hook(424→282 行)
- 新增 pages/health/useHealthData.ts — 健康页数据 hook(422→254 行)
- 44 个页面迁移到 usePageData(9 患者端 + 15 医生端 + 20 子包)
- auth store logout 不再直接导入 health store

构建通过,测试 74/75(1 个预存失败)。
This commit is contained in:
iven
2026-05-15 01:13:01 +08:00
parent 0f58af245d
commit 1fd2c7a533
52 changed files with 791 additions and 664 deletions

View File

@@ -1,7 +1,7 @@
import React, { useState, useCallback, useRef } from 'react';
import React, { useState, useCallback } from 'react';
import { View, Text } from '@tarojs/components';
import Taro, { useReachBottom, usePullDownRefresh } from '@tarojs/taro';
import { useThrottledDidShow } from '@/hooks/useThrottledDidShow';
import Taro, { useReachBottom } from '@tarojs/taro';
import { usePageData } from '@/hooks/usePageData';
import { listMyTransactions } from '../../../services/points';
import type { PointsTransaction } from '../../../services/points';
import { usePointsStore } from '../../../stores/points';
@@ -25,12 +25,9 @@ export default function PointsDetail() {
const [page, setPage] = useState(1);
const [total, setTotal] = useState(0);
const [loading, setLoading] = useState(false);
const loadingRef = useRef(false);
const fetchTransactions = useCallback(
async (pageNum: number, type: string, isRefresh = false) => {
if (loadingRef.current) return;
loadingRef.current = true;
setLoading(true);
try {
const res = await listMyTransactions({
@@ -51,7 +48,6 @@ export default function PointsDetail() {
} catch {
Taro.showToast({ title: '加载失败', icon: 'none' });
} finally {
loadingRef.current = false;
setLoading(false);
}
},
@@ -66,16 +62,13 @@ export default function PointsDetail() {
[refreshPoints, fetchTransactions, activeTab],
);
useThrottledDidShow(() => {
Taro.setNavigationBarTitle({ title: '积分明细' });
loadAll();
}, 10000);
usePullDownRefresh(() => {
loadAll().finally(() => {
Taro.stopPullDownRefresh();
});
});
usePageData(
useCallback(async () => {
Taro.setNavigationBarTitle({ title: '积分明细' });
await loadAll();
}, [loadAll]),
{ throttleMs: 10000, enablePullDown: true },
);
useReachBottom(() => {
if (!loading && transactions.length < total) {

View File

@@ -1,7 +1,7 @@
import React, { useState, useCallback } from 'react';
import { View, Text } from '@tarojs/components';
import Taro from '@tarojs/taro';
import { useThrottledDidShow } from '@/hooks/useThrottledDidShow';
import { usePageData } from '@/hooks/usePageData';
import {
listProducts,
exchangeProduct,
@@ -40,11 +40,6 @@ export default function ExchangeConfirm() {
const [submitting, setSubmitting] = useState(false);
const { safeSetTimeout } = useSafeTimeout();
useThrottledDidShow(() => {
Taro.setNavigationBarTitle({ title: '确认兑换' });
loadData();
}, 10000);
const loadData = useCallback(async () => {
const instance = Taro.getCurrentInstance();
const productId = instance.router?.params?.product_id;
@@ -75,6 +70,14 @@ export default function ExchangeConfirm() {
}
}, [refreshPoints]);
usePageData(
useCallback(async () => {
Taro.setNavigationBarTitle({ title: '确认兑换' });
await loadData();
}, [loadData]),
{ throttleMs: 10000, enablePullDown: false },
);
const balance = account?.balance ?? 0;
const cost = product?.points_cost ?? 0;
const insufficient = balance < cost;

View File

@@ -1,7 +1,7 @@
import React, { useState, useCallback, useRef } from 'react';
import React, { useState, useCallback } from 'react';
import { View, Text } from '@tarojs/components';
import Taro, { useReachBottom, usePullDownRefresh } from '@tarojs/taro';
import { useThrottledDidShow } from '@/hooks/useThrottledDidShow';
import Taro, { useReachBottom } from '@tarojs/taro';
import { usePageData } from '@/hooks/usePageData';
import { listMyOrders } from '../../../services/points';
import type { PointsOrder } from '../../../services/points';
import EmptyState from '../../../components/EmptyState';
@@ -30,12 +30,9 @@ export default function MallOrders() {
const [page, setPage] = useState(1);
const [total, setTotal] = useState(0);
const [loading, setLoading] = useState(false);
const loadingRef = useRef(false);
const fetchOrders = useCallback(
async (pageNum: number, status: string, isRefresh = false) => {
if (loadingRef.current) return;
loadingRef.current = true;
setLoading(true);
try {
const res = await listMyOrders({
@@ -56,7 +53,6 @@ export default function MallOrders() {
} catch {
Taro.showToast({ title: '加载失败', icon: 'none' });
} finally {
loadingRef.current = false;
setLoading(false);
}
},
@@ -71,16 +67,13 @@ export default function MallOrders() {
[fetchOrders, activeTab],
);
useThrottledDidShow(() => {
Taro.setNavigationBarTitle({ title: '我的订单' });
loadAll();
}, 10000);
usePullDownRefresh(() => {
loadAll().finally(() => {
Taro.stopPullDownRefresh();
});
});
usePageData(
useCallback(async () => {
Taro.setNavigationBarTitle({ title: '我的订单' });
await loadAll();
}, [loadAll]),
{ throttleMs: 10000, enablePullDown: true },
);
useReachBottom(() => {
if (!loading && orders.length < total) {