[AI Generated]: refactor(Views): 重构连接设备页设备列表为统一循环并补全卡片样式
This commit is contained in:
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ClaudeCodeTabState">
|
||||||
|
<option name="tabCount" value="3" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -15,10 +15,7 @@ Page({
|
|||||||
*/
|
*/
|
||||||
status: 'idle',
|
status: 'idle',
|
||||||
|
|
||||||
/* 已连接的设备(null 表示没有) */
|
/* 设备列表(包含已连接和未连接,每项含 connected: boolean) */
|
||||||
connectedDevice: null,
|
|
||||||
|
|
||||||
/* 未连接的设备列表 */
|
|
||||||
deviceList: [],
|
deviceList: [],
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -38,7 +35,6 @@ Page({
|
|||||||
onStartSearch() {
|
onStartSearch() {
|
||||||
this.setData({
|
this.setData({
|
||||||
status: 'searching',
|
status: 'searching',
|
||||||
connectedDevice: null,
|
|
||||||
deviceList: [],
|
deviceList: [],
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -47,14 +43,10 @@ Page({
|
|||||||
if (MOCK_HAS_DEVICES) {
|
if (MOCK_HAS_DEVICES) {
|
||||||
this.setData({
|
this.setData({
|
||||||
status: 'found',
|
status: 'found',
|
||||||
connectedDevice: {
|
|
||||||
id: 'mock-connected',
|
|
||||||
name: '智能体重秤 Pro',
|
|
||||||
icon: '',
|
|
||||||
},
|
|
||||||
deviceList: [
|
deviceList: [
|
||||||
{ id: 'mock-1', name: '体重秤 Basic', icon: '' },
|
{ id: 'mock-connected', name: '智能体重秤 Pro', icon: '', connected: true },
|
||||||
{ id: 'mock-2', name: '体脂秤 Plus', icon: '' },
|
{ id: 'mock-1', name: '体重秤 Basic', icon: '', connected: false },
|
||||||
|
{ id: 'mock-2', name: '体脂秤 Plus', icon: '', connected: false },
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@@ -63,16 +55,24 @@ Page({
|
|||||||
}, MOCK_SEARCH_DURATION)
|
}, MOCK_SEARCH_DURATION)
|
||||||
},
|
},
|
||||||
|
|
||||||
/* 连接某台未连接设备 */
|
/* 连接某台设备:同时只能一台已连接,自动断开其他设备 */
|
||||||
onConnect(e) {
|
onConnect(e) {
|
||||||
const { id } = e.currentTarget.dataset
|
const { id } = e.currentTarget.dataset
|
||||||
console.log('连接设备:', id)
|
const deviceList = this.data.deviceList.map(item => ({
|
||||||
|
...item,
|
||||||
|
connected: item.id === id,
|
||||||
|
}))
|
||||||
|
this.setData({ deviceList })
|
||||||
/* TODO: 接入真实蓝牙连接逻辑 */
|
/* TODO: 接入真实蓝牙连接逻辑 */
|
||||||
},
|
},
|
||||||
|
|
||||||
/* 断开已连接设备 */
|
/* 断开当前已连接设备 */
|
||||||
onDisconnect() {
|
onDisconnect() {
|
||||||
console.log('断开连接')
|
const deviceList = this.data.deviceList.map(item => ({
|
||||||
|
...item,
|
||||||
|
connected: false,
|
||||||
|
}))
|
||||||
|
this.setData({ deviceList })
|
||||||
/* TODO: 接入真实蓝牙断开逻辑 */
|
/* TODO: 接入真实蓝牙断开逻辑 */
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@
|
|||||||
color: #808080;
|
color: #808080;
|
||||||
font-size: 30rpx;
|
font-size: 30rpx;
|
||||||
line-height: 30rpx;
|
line-height: 30rpx;
|
||||||
|
margin-right: 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.help-link {
|
.help-link {
|
||||||
@@ -68,11 +69,160 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.search-device {
|
.search-device {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.search-device-header {
|
||||||
|
width: 100%;
|
||||||
|
height: 32rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 38rpx;
|
||||||
|
|
||||||
|
.search-device-title {
|
||||||
|
color: #252535;
|
||||||
|
height: 32rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-device-count {
|
||||||
|
height: 32rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
|
||||||
|
.count-text {
|
||||||
|
color: #808080;
|
||||||
|
height: 32rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
line-height: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.count-num {
|
||||||
|
color: #1385FA;
|
||||||
|
height: 32rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 32rpx;
|
||||||
|
padding: 0 6rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.empty {
|
.empty {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 160rpx;
|
||||||
|
|
||||||
|
.empty-image {
|
||||||
|
width: 193rpx;
|
||||||
|
height: 138rpx;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-text {
|
||||||
|
color: #808080;
|
||||||
|
width: 100%;
|
||||||
|
height: 30rpx;
|
||||||
|
font-size: 30rpx;
|
||||||
|
line-height: 30rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.device-list {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.device-card {
|
||||||
|
width: 100%;
|
||||||
|
height: 150rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 30rpx;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
border: 2rpx solid #E6E6EA;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
|
||||||
|
.card-icon {
|
||||||
|
width: 90rpx;
|
||||||
|
height: 90rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
margin-right: 24rpx;
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-info {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.card-name {
|
||||||
|
color: #252535;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
height: 32rpx;
|
||||||
|
line-height: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-status {
|
||||||
|
margin-top: 18rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.card-dot {
|
||||||
|
width: 12rpx;
|
||||||
|
height: 12rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #2AC79F;
|
||||||
|
margin-right: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-status-text {
|
||||||
|
color: #2AC79F;
|
||||||
|
height: 28rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 28rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-btn-primary {
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-size: 24rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
width: 88rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
line-height: 48rpx;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
background-color: #2AC79F;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-btn-danger {
|
||||||
|
color: #F24439;
|
||||||
|
font-size: 24rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
width: 120rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
line-height: 44rpx;
|
||||||
|
text-align: center;
|
||||||
|
border: 2rpx solid #F24439;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,62 +23,52 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 搜索结果模块:found / empty 时整体显示 -->
|
<!-- 搜索结果模块:found / empty 时整体显示 -->
|
||||||
<view
|
<block wx:if="{{ status === 'found' || status === 'empty' }}">
|
||||||
wx:if="{{ status === 'found' || status === 'empty' }}"
|
<view class="search-device">
|
||||||
class="search-device"
|
|
||||||
>
|
|
||||||
|
|
||||||
<!-- 头部:标题 + 计数 -->
|
<!-- 头部:标题 + 计数 -->
|
||||||
<view class="search-device-header">
|
<view class="search-device-header">
|
||||||
<text class="search-device-title">搜索结果</text>
|
<text class="search-device-title">搜索结果</text>
|
||||||
<view class="search-device-count">
|
<view class="search-device-count">
|
||||||
<text class="count-text">发现</text>
|
<text class="count-text">发现</text>
|
||||||
<text class="count-num">{{ status === 'found' ? (deviceList.length + (connectedDevice ? 1 : 0)) : 0 }}</text>
|
<text class="count-num">{{ deviceList.length }}</text>
|
||||||
<text class="count-text"> 台设备</text>
|
<text class="count-text">台设备</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 空状态 -->
|
<!-- 空状态 -->
|
||||||
<view wx:if="{{ status === 'empty' }}" class="empty">
|
<block wx:if="{{ status === 'empty' }}">
|
||||||
|
<view class="empty">
|
||||||
<view class="empty-image"></view>
|
<view class="empty-image"></view>
|
||||||
<view class="empty-text">暂未搜索到可用设备,请重新搜索</view>
|
<view class="empty-text">暂未搜索到可用设备,请重新搜索</view>
|
||||||
</view>
|
</view>
|
||||||
|
</block>
|
||||||
|
|
||||||
<!-- 找到设备:已连接卡片 + 未连接列表 -->
|
<!-- 找到设备:统一循环,内部按 connected 切换 UI -->
|
||||||
<block wx:if="{{ status === 'found' }}">
|
<block wx:if="{{ status === 'found' }}">
|
||||||
|
<view class="device-list">
|
||||||
<!-- 已连接卡片 -->
|
<block wx:for="{{ deviceList }}" wx:key="id">
|
||||||
<view wx:if="{{ connectedDevice }}" class="connected-card">
|
<view class="device-card">
|
||||||
<view class="card-icon"></view>
|
<view class="card-icon"></view>
|
||||||
<view class="card-info">
|
<view class="card-info">
|
||||||
<view class="card-name">{{ connectedDevice.name }}</view>
|
<view class="card-name">{{ item.name }}</view>
|
||||||
|
<block wx:if="{{ item.connected }}">
|
||||||
<view class="card-status">
|
<view class="card-status">
|
||||||
<view class="card-dot"></view>
|
<view class="card-dot"></view>
|
||||||
<text class="card-status-text">已连接</text>
|
<text class="card-status-text">已连接</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
|
||||||
<view class="card-btn-danger" bind:tap="onDisconnect">断开连接</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 未连接列表 -->
|
|
||||||
<view class="device-list">
|
|
||||||
<view
|
|
||||||
wx:for="{{ deviceList }}"
|
|
||||||
wx:key="id"
|
|
||||||
class="device-card"
|
|
||||||
>
|
|
||||||
<view class="card-icon"></view>
|
|
||||||
<view class="card-name">{{ item.name }}</view>
|
|
||||||
<view
|
|
||||||
class="card-btn-primary"
|
|
||||||
data-id="{{ item.id }}"
|
|
||||||
bind:tap="onConnect"
|
|
||||||
>连接</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
</block>
|
</block>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
<block wx:if="{{ item.connected }}">
|
||||||
|
<view class="card-btn-danger" data-id="{{ item.id }}" bind:tap="onDisconnect">断开连接</view>
|
||||||
|
</block>
|
||||||
|
<block wx:else>
|
||||||
|
<view class="card-btn-primary" data-id="{{ item.id }}" bind:tap="onConnect">连接</view>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -1 +1,91 @@
|
|||||||
<view class="page">connectedWifi 占位</view>
|
<view class="connected-wifi">
|
||||||
|
|
||||||
|
<!-- 顶部装饰:configuring 显示三层同心圆动画;其余状态显示静态占位图 -->
|
||||||
|
<block wx:if="{{ status === 'configuring' }}">
|
||||||
|
<view class="ripple"></view>
|
||||||
|
</block>
|
||||||
|
<block wx:else>
|
||||||
|
<view class="hero"></view>
|
||||||
|
</block>
|
||||||
|
|
||||||
|
<!-- 主标题:随状态切换 -->
|
||||||
|
<view class="title">
|
||||||
|
{{
|
||||||
|
status === 'idle' ? '为设备配置 WiFi' :
|
||||||
|
status === 'configuring' ? '正在配网中...' :
|
||||||
|
status === 'success' ? '配网成功' : '配网失败'
|
||||||
|
}}
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 副标题:随状态切换 -->
|
||||||
|
<view class="sub-title">
|
||||||
|
{{
|
||||||
|
status === 'idle' ? '请输入 2.4G WiFi 名称和密码,确保设备处于配网状态' :
|
||||||
|
status === 'configuring' ? '请保持设备与手机靠近,正在传输配网信息' :
|
||||||
|
status === 'success' ? '设备已成功连入 WiFi 网络,可正常使用' : '请检查 WiFi 密码或设备状态后重试'
|
||||||
|
}}
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 配网表单:idle / configuring / failed 时显示 -->
|
||||||
|
<block wx:if="{{ status !== 'success' }}">
|
||||||
|
<view class="wifi-form">
|
||||||
|
|
||||||
|
<!-- WiFi 名称行 -->
|
||||||
|
<view class="form-row">
|
||||||
|
<text class="form-label">WiFi 名称</text>
|
||||||
|
<input
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
placeholder="请输入 WiFi 名称"
|
||||||
|
placeholder-class="form-placeholder"
|
||||||
|
value="{{ form.ssid }}"
|
||||||
|
disabled="{{ status === 'configuring' }}"
|
||||||
|
bindinput="onInputSsid"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- WiFi 密码行 -->
|
||||||
|
<view class="form-row">
|
||||||
|
<text class="form-label">WiFi 密码</text>
|
||||||
|
<input
|
||||||
|
class="form-input"
|
||||||
|
password="{{ !form.showPwd }}"
|
||||||
|
placeholder="请输入 WiFi 密码"
|
||||||
|
placeholder-class="form-placeholder"
|
||||||
|
value="{{ form.password }}"
|
||||||
|
disabled="{{ status === 'configuring' }}"
|
||||||
|
bindinput="onInputPwd"
|
||||||
|
/>
|
||||||
|
<view class="form-eye" bind:tap="onTogglePwd">
|
||||||
|
{{ form.showPwd ? '隐藏' : '显示' }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
|
||||||
|
<!-- 成功结果区:仅 success 显示 -->
|
||||||
|
<block wx:if="{{ status === 'success' }}">
|
||||||
|
<view class="result-success">
|
||||||
|
<view class="result-icon-success"></view>
|
||||||
|
<view class="result-text">设备已成功连接到 {{ form.ssid || '当前 WiFi' }}</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
|
||||||
|
<!-- 主按钮:文案与可用状态随 status 切换 -->
|
||||||
|
<view
|
||||||
|
class="submit-btn {{ status === 'configuring' ? 'submit-btn-disabled' : '' }}"
|
||||||
|
bind:tap="onSubmit"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
status === 'idle' ? '开始配网' :
|
||||||
|
status === 'configuring' ? '配网中...' :
|
||||||
|
status === 'success' ? '完成' : '重新配网'
|
||||||
|
}}
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 帮助文案 -->
|
||||||
|
<view class="help">
|
||||||
|
<text class="help-text">设备无法连接 WiFi?</text>
|
||||||
|
<text class="help-link" bind:tap="onOpenHelp">查看帮助</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|||||||
Reference in New Issue
Block a user