Compare commits

..

No commits in common. "fda1f144fccda2207916658a88a873d4815fcba3" and "1dedbcfa736bae09cf8d35cea1df26dd66773847" have entirely different histories.

6 changed files with 11 additions and 144 deletions

View File

@ -2,11 +2,9 @@ import type { BleDevice } from '@/ble/hooks/useBle'
// 设备型号 → 启用的按钮 key 列表。 // 设备型号 → 启用的按钮 key 列表。
// 后续如需让其他型号裁剪按钮,只需新增映射条目。 // 后续如需让其他型号裁剪按钮,只需新增映射条目。
// 参数配置/服务器配置尚未接入,先从卡片隐藏(原 ['WIFI', 'PARAMS', 'SERVER'])
export const DEVICE_ACTION_KEYS: Record<string, readonly string[]> = Object.freeze({ export const DEVICE_ACTION_KEYS: Record<string, readonly string[]> = Object.freeze({
EP832: ['WIFI'], EP832: ['WIFI'],
DEFAULT: ['WIFI'] DEFAULT: ['WIFI', 'PARAMS', 'SERVER']
// DEFAULT: ['WIFI', 'PARAMS', 'SERVER']
}) })
// 按钮注册表:label / 忙态文案。 // 按钮注册表:label / 忙态文案。

View File

@ -34,99 +34,6 @@
color: #ffffff; color: #ffffff;
} }
// ===== 游客首页:功能介绍卡 + 底部登录引导(先浏览体验,后自主选择登录) =====
.guestSection {
padding: 0 24px;
}
.guestCard {
margin-bottom: 24px;
padding: 28px;
background: $color-bg-white;
border-radius: $radius-lg;
box-shadow: $shadow-card;
display: flex;
align-items: center;
}
.guestCardIcon {
flex-shrink: 0;
width: 72px;
height: 72px;
border-radius: $radius-md;
background: $color-primary-light-bg;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20px;
}
.guestCardIconText {
font-size: 32px;
}
.guestCardBody {
flex: 1;
min-width: 0;
}
.guestCardTitle {
font-size: 30px;
font-weight: 600;
color: $color-text;
}
.guestCardDesc {
display: block;
margin-top: 8px;
font-size: 24px;
color: $color-text-secondary;
}
// 底部登录引导卡:非阻断,用户可继续浏览其他 tab
.guestLoginCard {
margin: 8px 24px 0;
padding: 32px 28px;
background: $color-bg-white;
border-radius: $radius-lg;
box-shadow: $shadow-card;
display: flex;
align-items: center;
}
.guestLoginTexts {
flex: 1;
min-width: 0;
margin-right: 24px;
}
.guestLoginTitle {
font-size: 30px;
font-weight: 600;
color: $color-text;
}
.guestLoginSub {
display: block;
margin-top: 8px;
font-size: 24px;
line-height: 1.5;
color: $color-text-secondary;
}
.guestLoginCard .guestLoginBtn {
margin-top: 0;
padding: 0 36px;
height: 72px;
flex-shrink: 0;
}
.guestLoginCard .guestLoginBtnText {
font-size: 26px;
font-weight: 600;
color: #ffffff;
}
// ===== 家庭圈入口:渐变横幅卡 ===== // ===== 家庭圈入口:渐变横幅卡 =====
.familyEntry { .familyEntry {
margin: 24px; margin: 24px;

View File

@ -68,7 +68,12 @@ export default function Index() {
{loading ? ( {loading ? (
<View className={styles.stateWrap}><Loading /></View> <View className={styles.stateWrap}><Loading /></View>
) : guest ? ( ) : guest ? (
<GuestHome onLogin={() => navigateTo(ROUTES.LOGIN)} /> <View className={styles.stateWrap}>
<Empty text="登录后查看家人动态" mode="message" subText="浏览功能无需登录,需要查看告警与设备时再登录" />
<View className={styles.guestLoginBtn} hoverClass={styles.guestLoginBtnPressed} onClick={() => navigateTo(ROUTES.LOGIN)}>
<Text className={styles.guestLoginText}>去登录</Text>
</View>
</View>
) : loadError ? ( ) : loadError ? (
<StateView status="error" onRetry={loadAlerts} /> <StateView status="error" onRetry={loadAlerts} />
) : ( ) : (
@ -110,42 +115,6 @@ function FamilyEntry({ onClick }: { onClick: () => void }) {
) )
} }
// 游客首页:功能介绍可自由浏览,登录引导放底部非阻断(微信审核:先体验后自主选择登录)
function GuestHome({ onLogin }: { onLogin: () => void }) {
const features = [
{ icon: '◉', title: '健康雷达守护', desc: '睡眠呼吸、心率监测,异常实时提醒' },
{ icon: '⚠', title: '跌倒自动告警', desc: '跌倒检测雷达全天值守,紧急联系人速达' },
{ icon: '👪', title: '家庭圈共享', desc: '家人共同守护长辈,告警动态一起看' }
]
return (
<>
<FamilyEntry onClick={onLogin} />
<View className={styles.guestSection}>
{features.map((f) => (
<View key={f.title} className={styles.guestCard}>
<View className={styles.guestCardIcon}>
<Text className={styles.guestCardIconText}>{f.icon}</Text>
</View>
<View className={styles.guestCardBody}>
<Text className={styles.guestCardTitle}>{f.title}</Text>
<Text className={styles.guestCardDesc}>{f.desc}</Text>
</View>
</View>
))}
</View>
<View className={styles.guestLoginCard}>
<View className={styles.guestLoginTexts}>
<Text className={styles.guestLoginTitle}>登录后开启守护</Text>
<Text className={styles.guestLoginSub}>绑定设备、查看告警动态需要登录,可随时在下方自主选择</Text>
</View>
<View className={styles.guestLoginBtn} hoverClass={styles.guestLoginBtnPressed} onClick={onLogin}>
<Text className={styles.guestLoginBtnText}>微信登录</Text>
</View>
</View>
</>
)
}
function UnhandledAlert({ alert, onClick }: { alert: HomeAlarm; onClick: () => void }) { function UnhandledAlert({ alert, onClick }: { alert: HomeAlarm; onClick: () => void }) {
return ( return (
<View className={styles.unhandledCard} onClick={onClick}> <View className={styles.unhandledCard} onClick={onClick}>

View File

@ -47,10 +47,7 @@ export default function Mine() {
<View className={styles.menuCard}> <View className={styles.menuCard}>
{loggedOut ? ( {loggedOut ? (
<ListRowGroup> <ListRowGroup>
{/* 游客态:配置设备纯蓝牙操作无需登录照常展示;场所管理依赖账号数据,引导登录 */} {/* 游客态:菜单收起,只留一个登录入口(微信审核要求不强制授权) */}
<ListRow label="配置设备" arrow onClick={() => navigateTo(ROUTES.DEVICE_BLE_CONFIG)} />
<ListRow label="场所管理" arrow onClick={goLogin} />
<ListRow label="当前版本" value="2.8.44" />
<ListRow label="登录后使用完整功能" arrow onClick={goLogin} /> <ListRow label="登录后使用完整功能" arrow onClick={goLogin} />
</ListRowGroup> </ListRowGroup>
) : ( ) : (

View File

@ -7,16 +7,14 @@ import { ROUTES } from '@/constants/routes'
// 游客可浏览页面(微信审核要求:进入首页即要求授权登录会被拒, // 游客可浏览页面(微信审核要求:进入首页即要求授权登录会被拒,
// tab 页与登录页放开,操作型页面按需登录;协议全文页游客可读—— // tab 页与登录页放开,操作型页面按需登录;协议全文页游客可读——
// 登录前需可查看协议内容才能完成勾选同意; // 登录前需可查看协议内容才能完成勾选同意)
// BLE 配网页纯本地蓝牙操作不依赖账号,游客放行供设备试连体验)
export const PUBLIC_PAGES = new Set<string>([ export const PUBLIC_PAGES = new Set<string>([
ROUTES.LOGIN, ROUTES.LOGIN,
ROUTES.HOME, ROUTES.HOME,
ROUTES.DEVICE_LIST, ROUTES.DEVICE_LIST,
ROUTES.EVENT, ROUTES.EVENT,
ROUTES.MINE, ROUTES.MINE,
ROUTES.AGREEMENT, ROUTES.AGREEMENT
ROUTES.DEVICE_BLE_CONFIG
]) ])
// 登录页路径(navigation 守卫改投目标) // 登录页路径(navigation 守卫改投目标)

View File

@ -88,14 +88,12 @@ describe('navigation 登录守卫', () => {
}) })
describe('isProtectedPage', () => { describe('isProtectedPage', () => {
it('登录页、四个 tab 页与协议/BLE 配网页返回 false(游客可浏览),其余页面返回 true', () => { it('登录页与四个 tab 页返回 false(游客可浏览),其余页面返回 true', () => {
expect(isProtectedPage(ROUTES.LOGIN)).toBe(false) expect(isProtectedPage(ROUTES.LOGIN)).toBe(false)
expect(isProtectedPage(ROUTES.HOME)).toBe(false) expect(isProtectedPage(ROUTES.HOME)).toBe(false)
expect(isProtectedPage(ROUTES.DEVICE_LIST)).toBe(false) expect(isProtectedPage(ROUTES.DEVICE_LIST)).toBe(false)
expect(isProtectedPage(ROUTES.EVENT)).toBe(false) expect(isProtectedPage(ROUTES.EVENT)).toBe(false)
expect(isProtectedPage(ROUTES.MINE)).toBe(false) expect(isProtectedPage(ROUTES.MINE)).toBe(false)
expect(isProtectedPage(ROUTES.AGREEMENT)).toBe(false)
expect(isProtectedPage(ROUTES.DEVICE_BLE_CONFIG)).toBe(false)
expect(isProtectedPage(ROUTES.FAMILY)).toBe(true) expect(isProtectedPage(ROUTES.FAMILY)).toBe(true)
expect(isProtectedPage(`${ROUTES.LOGIN}?from=xxx`)).toBe(false) expect(isProtectedPage(`${ROUTES.LOGIN}?from=xxx`)).toBe(false)
}) })