feat: support assigning child to existing device
This commit is contained in:
@@ -68,6 +68,41 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pending-device-card {
|
||||||
|
margin: 0 48px 48px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 24px;
|
||||||
|
padding: 48px 40px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pending-device-title {
|
||||||
|
font-size: 34px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1A1A1A;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pending-device-id {
|
||||||
|
max-width: 100%;
|
||||||
|
font-size: 28px;
|
||||||
|
color: #FF8C42;
|
||||||
|
font-weight: 600;
|
||||||
|
word-break: break-all;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pending-device-desc {
|
||||||
|
font-size: 26px;
|
||||||
|
color: #666666;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
.scan-frame {
|
.scan-frame {
|
||||||
background: #FFFFFF;
|
background: #FFFFFF;
|
||||||
border-radius: 24px;
|
border-radius: 24px;
|
||||||
|
|||||||
@@ -350,6 +350,16 @@ export default function Bind() {
|
|||||||
<Text className='title'>{isPendingBinding ? '补全绑定' : '扫码贴卡绑定设备'}</Text>
|
<Text className='title'>{isPendingBinding ? '补全绑定' : '扫码贴卡绑定设备'}</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
{isPendingBinding ? (
|
||||||
|
<View className='pending-device-card'>
|
||||||
|
<View className='icon-bg orange'>
|
||||||
|
<Image className='control-icon-img' src={require('../../assets/tab-icons/rings.png')} mode='aspectFit' />
|
||||||
|
</View>
|
||||||
|
<Text className='pending-device-title'>关联现有设备</Text>
|
||||||
|
<Text className='pending-device-id'>{pendingDeviceId}</Text>
|
||||||
|
<Text className='pending-device-desc'>选择已有孩子,或新建孩子后完成关联</Text>
|
||||||
|
</View>
|
||||||
|
) : (
|
||||||
<View className='scan-area'>
|
<View className='scan-area'>
|
||||||
<View className='scan-frame' onClick={handleScanCode}>
|
<View className='scan-frame' onClick={handleScanCode}>
|
||||||
<View className='icon-bg orange'>
|
<View className='icon-bg orange'>
|
||||||
@@ -370,6 +380,7 @@ export default function Bind() {
|
|||||||
<View className='corner bottom-right'></View>
|
<View className='corner bottom-right'></View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
<View className='bind-form'>
|
<View className='bind-form'>
|
||||||
<View className='form-card'>
|
<View className='form-card'>
|
||||||
@@ -413,12 +424,17 @@ export default function Bind() {
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
<Text className='field-hint'>
|
<Text className='field-hint'>
|
||||||
{children.length > 0
|
{isPendingBinding
|
||||||
|
? children.length > 0
|
||||||
|
? '可以选已有儿童,也可以新建一个儿童后关联当前设备'
|
||||||
|
: '当前还没有儿童资料,请先创建一个儿童资料后关联设备'
|
||||||
|
: children.length > 0
|
||||||
? '可以选已有儿童,也可以在这里新建一个儿童后再绑定设备'
|
? '可以选已有儿童,也可以在这里新建一个儿童后再绑定设备'
|
||||||
: '当前还没有儿童资料,请先创建一个儿童资料'}
|
: '当前还没有儿童资料,请先创建一个儿童资料'}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
{!isPendingBinding && (
|
||||||
<View className='form-card'>
|
<View className='form-card'>
|
||||||
<Text className='form-title'>设备信息</Text>
|
<Text className='form-title'>设备信息</Text>
|
||||||
|
|
||||||
@@ -457,6 +473,7 @@ export default function Bind() {
|
|||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
className='submit-btn'
|
className='submit-btn'
|
||||||
@@ -476,11 +493,11 @@ export default function Bind() {
|
|||||||
</View>
|
</View>
|
||||||
<View className='tip-item'>
|
<View className='tip-item'>
|
||||||
<Text className='tip-number'>2</Text>
|
<Text className='tip-number'>2</Text>
|
||||||
<Text className='tip-text'>扫描设备二维码,确认设备号和序列号正确</Text>
|
<Text className='tip-text'>{isPendingBinding ? '确认当前待关联设备,再选择要关联的孩子' : '扫描设备二维码,确认设备号和序列号正确'}</Text>
|
||||||
</View>
|
</View>
|
||||||
<View className='tip-item'>
|
<View className='tip-item'>
|
||||||
<Text className='tip-number'>3</Text>
|
<Text className='tip-number'>3</Text>
|
||||||
<Text className='tip-text'>点击发送绑卡指令,然后去设备上贴自己的卡完成确认</Text>
|
<Text className='tip-text'>{isPendingBinding ? '点击完成儿童关联,设备会出现在该孩子下面' : '点击发送绑卡指令,然后去设备上贴自己的卡完成确认'}</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
{systemBanner}
|
{systemBanner}
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ export default function Sleep() {
|
|||||||
const [showDeleteChildModal, setShowDeleteChildModal] = useState(false)
|
const [showDeleteChildModal, setShowDeleteChildModal] = useState(false)
|
||||||
const [showRoleModal, setShowRoleModal] = useState(false)
|
const [showRoleModal, setShowRoleModal] = useState(false)
|
||||||
const [showFamilyModal, setShowFamilyModal] = useState(false)
|
const [showFamilyModal, setShowFamilyModal] = useState(false)
|
||||||
|
const [showAssignDeviceModal, setShowAssignDeviceModal] = useState(false)
|
||||||
const [modalType, setModalType] = useState<'add' | 'edit'>('add')
|
const [modalType, setModalType] = useState<'add' | 'edit'>('add')
|
||||||
const [childName, setChildName] = useState('')
|
const [childName, setChildName] = useState('')
|
||||||
const [editingChildId, setEditingChildId] = useState<number | null>(null)
|
const [editingChildId, setEditingChildId] = useState<number | null>(null)
|
||||||
@@ -334,9 +335,17 @@ export default function Sleep() {
|
|||||||
|
|
||||||
const handleOpenAddChildFromSwitch = () => {
|
const handleOpenAddChildFromSwitch = () => {
|
||||||
setShowChildModal(false)
|
setShowChildModal(false)
|
||||||
|
setShowAssignDeviceModal(false)
|
||||||
handleOpenModal('add')
|
handleOpenModal('add')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleAssignExistingDevice = (targetBinding: BindingListItem) => {
|
||||||
|
if (!targetBinding?.device_id) return
|
||||||
|
setSelectedBindingDeviceId(targetBinding.device_id)
|
||||||
|
setShowAssignDeviceModal(false)
|
||||||
|
Taro.navigateTo({ url: '/pages/bind/index' })
|
||||||
|
}
|
||||||
|
|
||||||
const handleSubmitModal = async () => {
|
const handleSubmitModal = async () => {
|
||||||
const normalizedName = childName.trim()
|
const normalizedName = childName.trim()
|
||||||
if (!normalizedName) {
|
if (!normalizedName) {
|
||||||
@@ -544,6 +553,11 @@ export default function Sleep() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item.name === '关联现有设备') {
|
||||||
|
setShowAssignDeviceModal(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (item.name === '绑定设备') {
|
if (item.name === '绑定设备') {
|
||||||
if (!currentChild) {
|
if (!currentChild) {
|
||||||
handleOpenModal('add')
|
handleOpenModal('add')
|
||||||
@@ -584,6 +598,7 @@ export default function Sleep() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const parentDisplayName = parentInfo.nickname?.trim() || '家长'
|
const parentDisplayName = parentInfo.nickname?.trim() || '家长'
|
||||||
|
const unassignedBindings = bindings.filter((item) => item.device_id && item.child_id === null)
|
||||||
const currentFirmwareLabel = firmwareStatus?.current_version || '--'
|
const currentFirmwareLabel = firmwareStatus?.current_version || '--'
|
||||||
const latestFirmwareLabel = firmwareStatus?.latest_version || '--'
|
const latestFirmwareLabel = firmwareStatus?.latest_version || '--'
|
||||||
const currentUserId = getCurrentUserId()
|
const currentUserId = getCurrentUserId()
|
||||||
@@ -637,6 +652,15 @@ export default function Sleep() {
|
|||||||
arrow: true,
|
arrow: true,
|
||||||
disabled: children.length === 0,
|
disabled: children.length === 0,
|
||||||
},
|
},
|
||||||
|
...(unassignedBindings.length > 0
|
||||||
|
? [{
|
||||||
|
icon: require('../../assets/tab-icons/rings.png'),
|
||||||
|
iconBgClass: 'green',
|
||||||
|
name: '关联现有设备',
|
||||||
|
value: `${unassignedBindings.length} 台待关联`,
|
||||||
|
arrow: true,
|
||||||
|
}]
|
||||||
|
: []),
|
||||||
{
|
{
|
||||||
icon: require('../../assets/tab-icons/rings.png'),
|
icon: require('../../assets/tab-icons/rings.png'),
|
||||||
iconBgClass: 'green',
|
iconBgClass: 'green',
|
||||||
@@ -856,6 +880,48 @@ export default function Sleep() {
|
|||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{showAssignDeviceModal && (
|
||||||
|
<View className='modal-mask' onClick={() => setShowAssignDeviceModal(false)}>
|
||||||
|
<View
|
||||||
|
className='modal-card device-switch-card'
|
||||||
|
onClick={(event) => {
|
||||||
|
event.stopPropagation()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text className='modal-title'>关联现有设备</Text>
|
||||||
|
{unassignedBindings.length === 0 ? (
|
||||||
|
<Text className='device-switch-empty'>当前没有待关联设备</Text>
|
||||||
|
) : (
|
||||||
|
<View className='device-switch-list'>
|
||||||
|
{unassignedBindings.map((item) => (
|
||||||
|
<View
|
||||||
|
key={item.device_id}
|
||||||
|
className='device-switch-item'
|
||||||
|
onClick={() => handleAssignExistingDevice(item)}
|
||||||
|
>
|
||||||
|
<View className='device-switch-head'>
|
||||||
|
<Text className='device-switch-id'>{item.device_id}</Text>
|
||||||
|
<Text className='device-switch-tag'>待关联</Text>
|
||||||
|
</View>
|
||||||
|
<Text className='device-switch-name'>未关联孩子</Text>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
<View className='device-switch-footer'>
|
||||||
|
<Text className='device-switch-add' onClick={handleOpenAddChildFromSwitch}>
|
||||||
|
+ 新增孩子
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View className='modal-actions'>
|
||||||
|
<Text className='modal-action cancel' onClick={() => setShowAssignDeviceModal(false)}>
|
||||||
|
关闭
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
{showModal && (
|
{showModal && (
|
||||||
<View className='modal-mask'>
|
<View className='modal-mask'>
|
||||||
<View className='modal-card'>
|
<View className='modal-card'>
|
||||||
|
|||||||
Reference in New Issue
Block a user