feat(family): 新增 FamilyCard 家庭圈卡片组件

This commit is contained in:
ozh 2026-09-09 15:06:09 +08:00
parent 576bb7f5a8
commit 3779a7a019
2 changed files with 143 additions and 0 deletions

View File

@ -0,0 +1,99 @@
// 浅绿底卡变体:卡身浅绿 + 右上淡绿圆装饰(spec §9)
.card {
position: relative;
overflow: hidden;
background: $color-primary-light-bg;
border: 1px solid $color-primary-light-border;
border-radius: $radius-lg;
padding: 32px;
}
.cardPressed {
opacity: 0.85;
}
// 装饰圆用真实元素而非 ::after:小程序部分场景伪元素渲染兼容性差
.decor {
position: absolute;
top: -60px;
right: -60px;
width: 240px;
height: 240px;
border-radius: $radius-circle;
background: rgba(44, 203, 152, 0.08);
}
.head {
display: flex;
align-items: center;
margin-bottom: 24px;
}
// 圆图标:品牌渐变底 + 白字首字,对齐设备网格 icon 风格
.icon {
width: 88px;
height: 88px;
border-radius: $radius-circle;
background: $color-primary-grad;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20px;
}
.iconText {
font-size: 36px;
font-weight: 600;
color: #ffffff;
}
.headMain {
flex: 1;
min-width: 0;
display: flex;
align-items: center;
}
.name {
flex: 1;
min-width: 0;
font-size: 32px;
font-weight: 600;
color: $color-text;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
// 人数徽标:白底胶囊——浅绿卡身上无米色 token,白底对比最清晰
.memberBadge {
flex-shrink: 0;
margin-left: 16px;
padding: 4px 16px;
background: $color-bg-white;
border: 1px solid $color-primary-light-border;
border-radius: $radius-pill;
font-size: 22px;
color: $color-primary-deep;
}
.rows {
display: flex;
align-items: center;
justify-content: space-between;
min-height: 56px;
}
.rowLabel {
font-size: 26px;
color: $color-text-secondary;
}
.rowValue {
margin-left: 24px;
font-size: 26px;
color: $color-text;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

View File

@ -0,0 +1,44 @@
import { View, Text } from '@tarojs/components'
import type { Family } from '@/api/family'
import styles from './index.module.scss'
interface Props {
family: Family
onClick?: (id: string) => void
}
export function FamilyCard({ family, onClick }: Props) {
const first = family.name.slice(0, 1)
return (
<View
className={styles.card}
hoverClass={onClick ? styles.cardPressed : 'none'}
onClick={() => onClick?.(family.id)}
>
{/* 右上淡绿圆装饰 */}
<View className={styles.decor} />
<View className={styles.head}>
<View className={styles.icon}>
<Text className={styles.iconText}>{first}</Text>
</View>
<View className={styles.headMain}>
<Text className={styles.name}>{family.name}</Text>
<Text className={styles.memberBadge}>{family.memberCount} 人</Text>
</View>
</View>
<View className={styles.rows}>
<Text className={styles.rowLabel}>关爱对象</Text>
<Text className={styles.rowValue}>{family.caredLabel}</Text>
</View>
<View className={styles.rows}>
<Text className={styles.rowLabel}>关爱地址</Text>
<Text className={styles.rowValue}>{family.address}</Text>
</View>
<View className={styles.rows}>
<Text className={styles.rowLabel}>设备数量</Text>
<Text className={styles.rowValue}>{family.deviceCount}</Text>
</View>
</View>
)
}