合入家庭共享与设备消息能力
This commit is contained in:
3
banban-mini/src/pages/family-invite/index.config.ts
Normal file
3
banban-mini/src/pages/family-invite/index.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '家庭邀请',
|
||||
})
|
||||
76
banban-mini/src/pages/family-invite/index.scss
Normal file
76
banban-mini/src/pages/family-invite/index.scss
Normal file
@@ -0,0 +1,76 @@
|
||||
.family-invite-page {
|
||||
min-height: 100%;
|
||||
background: #F5F7FA;
|
||||
padding: 96px 24px 48px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.invite-panel {
|
||||
background: #FFFFFF;
|
||||
border-radius: 20px;
|
||||
padding: 32px 28px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.invite-title {
|
||||
display: block;
|
||||
font-size: 38px;
|
||||
font-weight: 700;
|
||||
color: #1A1A1A;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.invite-desc {
|
||||
display: block;
|
||||
font-size: 28px;
|
||||
line-height: 1.6;
|
||||
color: #666666;
|
||||
|
||||
&.danger {
|
||||
color: #E5484D;
|
||||
}
|
||||
}
|
||||
|
||||
.invite-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 24px;
|
||||
padding: 22px 0;
|
||||
border-bottom: 1px solid #F2F2F2;
|
||||
}
|
||||
|
||||
.invite-label {
|
||||
flex-shrink: 0;
|
||||
font-size: 28px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.invite-value {
|
||||
min-width: 0;
|
||||
font-size: 29px;
|
||||
color: #1A1A1A;
|
||||
font-weight: 600;
|
||||
text-align: right;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.invite-action {
|
||||
height: 92px;
|
||||
margin-top: 36px;
|
||||
border-radius: 18px;
|
||||
background: #FF8C42;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&.disabled {
|
||||
background: #CBD5E1;
|
||||
}
|
||||
}
|
||||
|
||||
.invite-action-text {
|
||||
font-size: 30px;
|
||||
color: #FFFFFF;
|
||||
font-weight: 700;
|
||||
}
|
||||
103
banban-mini/src/pages/family-invite/index.tsx
Normal file
103
banban-mini/src/pages/family-invite/index.tsx
Normal file
@@ -0,0 +1,103 @@
|
||||
import { View, Text } from '@tarojs/components'
|
||||
import Taro, { useDidShow, useRouter } from '@tarojs/taro'
|
||||
import { useState } from 'react'
|
||||
|
||||
import { getToken } from '@/services/auth'
|
||||
import { acceptFamilyInvitation, FamilyInvitation, getFamilyInvitation } from '@/services/family'
|
||||
import './index.scss'
|
||||
|
||||
export default function FamilyInvite() {
|
||||
const router = useRouter()
|
||||
const inviteToken = String(router.params?.token || '').trim()
|
||||
const redirectUrl = `/pages/family-invite/index?token=${inviteToken}`
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [joining, setJoining] = useState(false)
|
||||
const [invitation, setInvitation] = useState<FamilyInvitation | null>(null)
|
||||
const [errorText, setErrorText] = useState('')
|
||||
|
||||
useDidShow(() => {
|
||||
void loadInvitation()
|
||||
})
|
||||
|
||||
const loadInvitation = async () => {
|
||||
if (!getToken()) {
|
||||
Taro.setStorageSync('postLoginRedirect', redirectUrl)
|
||||
Taro.reLaunch({ url: '/pages/login/index' })
|
||||
return
|
||||
}
|
||||
if (!inviteToken) {
|
||||
setErrorText('邀请无效')
|
||||
setLoading(false)
|
||||
return
|
||||
}
|
||||
|
||||
setLoading(true)
|
||||
setErrorText('')
|
||||
try {
|
||||
const nextInvitation = await getFamilyInvitation(inviteToken)
|
||||
setInvitation(nextInvitation)
|
||||
} catch (error: any) {
|
||||
setInvitation(null)
|
||||
setErrorText(error?.message || '邀请加载失败')
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
const handleAccept = async () => {
|
||||
if (!inviteToken || joining) return
|
||||
|
||||
setJoining(true)
|
||||
try {
|
||||
await acceptFamilyInvitation(inviteToken)
|
||||
Taro.showToast({ title: '已加入家庭', icon: 'success' })
|
||||
setTimeout(() => {
|
||||
Taro.switchTab({ url: '/pages/device/index' })
|
||||
}, 600)
|
||||
} catch (error: any) {
|
||||
Taro.showToast({
|
||||
title: error?.message || '加入失败',
|
||||
icon: 'none',
|
||||
})
|
||||
} finally {
|
||||
setJoining(false)
|
||||
}
|
||||
}
|
||||
|
||||
const targetName = invitation?.child_name || invitation?.device_id || '--'
|
||||
const statusText = invitation?.status === 1 ? '等待确认加入' : '邀请已失效'
|
||||
|
||||
return (
|
||||
<View className='family-invite-page'>
|
||||
<View className='invite-panel'>
|
||||
<Text className='invite-title'>家庭共享邀请</Text>
|
||||
{loading ? (
|
||||
<Text className='invite-desc'>加载中...</Text>
|
||||
) : errorText ? (
|
||||
<Text className='invite-desc danger'>{errorText}</Text>
|
||||
) : (
|
||||
<>
|
||||
<View className='invite-row'>
|
||||
<Text className='invite-label'>共享对象</Text>
|
||||
<Text className='invite-value'>{targetName}</Text>
|
||||
</View>
|
||||
<View className='invite-row'>
|
||||
<Text className='invite-label'>设备</Text>
|
||||
<Text className='invite-value'>{invitation?.device_id || '--'}</Text>
|
||||
</View>
|
||||
<View className='invite-row'>
|
||||
<Text className='invite-label'>状态</Text>
|
||||
<Text className='invite-value'>{statusText}</Text>
|
||||
</View>
|
||||
<View
|
||||
className={`invite-action ${invitation?.status === 1 && !joining ? '' : 'disabled'}`}
|
||||
onClick={invitation?.status === 1 && !joining ? handleAccept : undefined}
|
||||
>
|
||||
<Text className='invite-action-text'>{joining ? '加入中...' : '加入家庭'}</Text>
|
||||
</View>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user