fix(family): 详情页加载降级与分享卡直达兜底

- load 拆分依赖:家庭详情必须成功;成员/关爱对象列表失败降级为空
  (受邀者未入圈时这两接口报权限错,不应整页判为家庭不存在)
- load 返回本次成员列表,autoJoin 改用返回值判断避免 stale state
- 加入失败时若详情也未拉到则重拉一次,保证页面可退出
- 加载失败分支改为"重新加载"+ 新增"回首页"按钮(分享卡直达页面栈
  仅一页,navigateBack 会卡死)
This commit is contained in:
ozh 2026-10-09 15:47:21 +08:00
parent 42b6ceb69c
commit 56e990c028
2 changed files with 45 additions and 12 deletions

View File

@ -122,6 +122,28 @@
color: $color-primary-deep; color: $color-primary-deep;
} }
// 加载失败分支的兜底回首页按钮(分享卡直达时页面栈无上一页,navigateBack 卡死)
.fallbackBtn {
margin: 24px auto 0;
padding: 0 64px;
height: 80px;
background: $color-primary-grad;
border-radius: $radius-pill;
display: flex;
align-items: center;
justify-content: center;
}
.fallbackBtnPressed {
opacity: 0.85;
}
.fallbackBtnText {
font-size: 28px;
font-weight: 600;
color: #ffffff;
}
.sectionEmpty { .sectionEmpty {
display: block; display: block;
padding: 32px 8px; padding: 32px 8px;

View File

@ -13,7 +13,7 @@ import { getHomeDetail, getHomeMemberList, joinHome, transferOwner, updateMember
import { getCareMemberList, type CareMember } from '@/api/careMember' import { getCareMemberList, type CareMember } from '@/api/careMember'
import { MAX_CARED_PER_FAMILY } from '@/constants/family' import { MAX_CARED_PER_FAMILY } from '@/constants/family'
import { ROUTES } from '@/constants/routes' import { ROUTES } from '@/constants/routes'
import { navigateBack, navigateTo, reLaunch } from '@/utils/navigation' import { navigateTo, reLaunch } from '@/utils/navigation'
import { showToast } from '@/utils/toast' import { showToast } from '@/utils/toast'
import styles from './detail.module.scss' import styles from './detail.module.scss'
@ -62,26 +62,31 @@ export default function FamilyDetail() {
// 改昵称:点击成员行触发 // 改昵称:点击成员行触发
const [renaming, setRenaming] = useState(false) const [renaming, setRenaming] = useState(false)
const load = async () => { // 拉取家庭数据:详情必须成功;成员/关爱对象列表失败降级为空(受邀者尚未入圈,
// 这两个接口会报权限错,不能因此把整个页面判成「家庭不存在」)
// 返回本次拉到的成员列表(供 autoJoin 用最新数据判断,避免 stale state)
const load = async (): Promise<HomeMember[] | null> => {
// 分享卡直达本页且未登录:先去登录,登录后回跳本页 // 分享卡直达本页且未登录:先去登录,登录后回跳本页
if (!token) { if (!token) {
const target = encodeURIComponent(`${ROUTES.FAMILY_DETAIL}?id=${familyId}&invite=1`) const target = encodeURIComponent(`${ROUTES.FAMILY_DETAIL}?id=${familyId}&invite=1`)
reLaunch(`${ROUTES.LOGIN}?redirect=${target}`) reLaunch(`${ROUTES.LOGIN}?redirect=${target}`)
return return null
} }
setLoading(true) setLoading(true)
try { try {
const [home, memberList, careList] = await Promise.all([ const home = await getHomeDetail(familyId)
getHomeDetail(familyId), const [memberList, careList] = await Promise.all([
getHomeMemberList(familyId), getHomeMemberList(familyId).catch(() => [] as HomeMember[]),
getCareMemberList(familyId) getCareMemberList(familyId).catch(() => [] as CareMember[])
]) ])
setFamily(home) setFamily(home)
setMembers(memberList) setMembers(memberList)
// 上限判定以关爱对象实际列表为准,家庭卡计数仅展示 // 上限判定以关爱对象实际列表为准,家庭卡计数仅展示
setCaredList(careList) setCaredList(careList)
return memberList
} catch { } catch {
setFamily(null) setFamily(null)
return null
} finally { } finally {
setLoading(false) setLoading(false)
} }
@ -89,10 +94,10 @@ export default function FamilyDetail() {
// 从添加表单返回时刷新;受邀进入且尚未是成员时自动加入(跳过手动点击步骤) // 从添加表单返回时刷新;受邀进入且尚未是成员时自动加入(跳过手动点击步骤)
useDidShow(() => { useDidShow(() => {
load().then(() => { load().then((memberList) => {
if ( if (
!isInviteEnter || joining || myUserId == null || !isInviteEnter || joining || myUserId == null ||
members.length === 0 || members.some((m) => m.memberId === myUserId) !memberList || memberList.length === 0 || memberList.some((m) => m.memberId === myUserId)
) return ) return
autoJoin(familyId) autoJoin(familyId)
}) })
@ -107,7 +112,9 @@ export default function FamilyDetail() {
showToast('已加入家庭') showToast('已加入家庭')
await load() await load()
} catch (e) { } catch (e) {
// 加入失败(如接口异常)也要让页面可退出:详情能拉到就展示,拉不到走「家庭不存在」分支(带返回按钮)
showToast(e instanceof Error ? e.message : '加入失败') showToast(e instanceof Error ? e.message : '加入失败')
if (!family) await load()
} finally { } finally {
setJoining(false) setJoining(false)
} }
@ -205,10 +212,14 @@ export default function FamilyDetail() {
<StateView <StateView
status="error" status="error"
mode="list" mode="list"
text="该家庭不存在" text="无法获取家庭信息"
retryText="返回列表" retryText="重新加载"
onRetry={() => navigateBack()} onRetry={() => load()}
/> />
{/* 分享卡直达时页面栈只有本页,navigateBack 无处可退会卡死——退回首页 */}
<View className={styles.fallbackBtn} hoverClass={styles.fallbackBtnPressed} onClick={() => reLaunch(ROUTES.HOME)}>
<Text className={styles.fallbackBtnText}>回首页</Text>
</View>
</View> </View>
) )
} }