feat(family): 详情页接入关爱对象列表与成员列表真实渲染

- 详情页新增「关爱对象」区:getCareMemberList 拉取并渲染姓名+联系人摘要,上限判定改以实际列表长度为准
- 成员区 HomeMember 主键按 transferOwner 入参修正为 memberId,显示名兼容 nickName/name 兜底
- 两个列表空态给出提示文案,不再渲染空白卡片
This commit is contained in:
ozh 2026-09-17 11:38:28 +08:00
parent 83a211ebd6
commit f68bd299a7
4 changed files with 63 additions and 13 deletions

View File

@ -19,14 +19,14 @@ export interface CareMemberSaveParams {
contacts: CareContact[] // 最多 5 名
}
// 列表项(响应字段文档未给出,按保存入参推断,联调修正)
// 列表项(响应字段文档为泛型占位未给出,按保存入参推断,联调实测修正)
export interface CareMember {
memberId: string
homeId: string
name: string
idNumber: string
address: string
contacts: CareContact[]
contacts: CareContact[] | null
}
export function saveCareMember(params: CareMemberSaveParams): Promise<void> {

View File

@ -12,10 +12,11 @@ export interface HomeInfo {
deviceCount: number
}
// 响应字段文档为泛型占位未给出;主键按 transferOwner/updateMemberNickName 入参的 memberId 推断,联调实测修正
export interface HomeMember {
userId: string
memberId: string
nickName: string
isOwner: boolean
isOwner?: boolean
mobile?: string
}

View File

@ -73,3 +73,17 @@
.section {
margin-top: 24px;
}
.sectionTitle {
display: block;
font-size: 26px;
color: $color-text-secondary;
margin: 8px 8px 16px;
}
.sectionEmpty {
display: block;
padding: 32px 8px;
font-size: 26px;
color: $color-text-tertiary;
}

View File

@ -7,12 +7,26 @@ import { StateView } from '@/components/state-view'
import { FamilyCard } from '@/components/family-card'
import { ListRow, ListRowGroup } from '@/components/list-row'
import { getHomeDetail, getHomeMemberList, type HomeInfo, type HomeMember } from '@/api/home'
import { getCareMemberList, type CareMember } from '@/api/careMember'
import { MAX_CARED_PER_FAMILY } from '@/constants/family'
import { ROUTES } from '@/constants/routes'
import { navigateBack, navigateTo } from '@/utils/navigation'
import { showToast } from '@/utils/toast'
import styles from './detail.module.scss'
// 成员显示名:nickName 字段名未实测确认,兼容 userName/name 兜底
const memberName = (m: HomeMember): string =>
m.nickName ?? (m as unknown as { userName?: string; name?: string }).name ?? '成员'
// 关爱对象联系人摘要:最多显示前 2 位姓名,其余以 +N 概括
const contactsSummary = (c: CareMember): string => {
const list = c.contacts ?? []
if (list.length === 0) return '未填联系人'
const head = list.slice(0, 2).map((ct) => ct.name).join('、')
const rest = list.length > 2 ? ` 等 ${list.length} 人` : ''
return `${head}${rest}`
}
export default function FamilyDetail() {
const router = useRouter()
const familyId = router.params.id ?? ''
@ -20,18 +34,20 @@ export default function FamilyDetail() {
const [loading, setLoading] = useState(true)
const [family, setFamily] = useState<HomeInfo | null>(null)
const [members, setMembers] = useState<HomeMember[]>([])
const [caredCount, setCaredCount] = useState(0)
const [caredList, setCaredList] = useState<CareMember[]>([])
const load = async () => {
setLoading(true)
try {
const [home, memberList] = await Promise.all([
const [home, memberList, careList] = await Promise.all([
getHomeDetail(familyId),
getHomeMemberList(familyId)
getHomeMemberList(familyId),
getCareMemberList(familyId)
])
setFamily(home)
setMembers(memberList)
setCaredCount(home.careMemberCount)
// 上限判定以关爱对象实际列表为准,家庭卡计数仅展示
setCaredList(careList)
} catch {
setFamily(null)
} finally {
@ -72,6 +88,7 @@ export default function FamilyDetail() {
)
}
const caredCount = caredList.length
const canAdd = caredCount < MAX_CARED_PER_FAMILY
const stub = (tip: string) => () => showToast(tip)
@ -101,11 +118,29 @@ export default function FamilyDetail() {
</View>
<View className={styles.section}>
<Text className={styles.sectionTitle}>关爱对象</Text>
{caredCount === 0 ? (
<Text className={styles.sectionEmpty}>暂无关爱对象,点击上方卡片添加</Text>
) : (
<ListRowGroup>
{members.map((m) => (
<ListRow key={m.userId} label={m.nickName} value={m.isOwner ? '群主' : '成员'} />
{caredList.map((c) => (
<ListRow key={c.memberId} label={c.name} value={contactsSummary(c)} />
))}
</ListRowGroup>
)}
</View>
<View className={styles.section}>
<Text className={styles.sectionTitle}>家庭成员</Text>
{members.length === 0 ? (
<Text className={styles.sectionEmpty}>暂无其他成员</Text>
) : (
<ListRowGroup>
{members.map((m) => (
<ListRow key={m.memberId} label={memberName(m)} value={m.isOwner ? '群主' : '成员'} />
))}
</ListRowGroup>
)}
</View>
<View className={styles.section}>