refactor: simplify device binding home layout

This commit is contained in:
czz
2026-05-07 16:30:36 +08:00
parent 991b542b8c
commit 2e00ee93ce
2 changed files with 18 additions and 194 deletions

View File

@@ -57,6 +57,7 @@
.device-header__add { .device-header__add {
width: 36rpx; width: 36rpx;
height: 36rpx; height: 36rpx;
margin-top: 28rpx;
border: 2rpx solid rgba(255, 255, 255, 0.86); border: 2rpx solid rgba(255, 255, 255, 0.86);
border-radius: 50%; border-radius: 50%;
color: #ffffff; color: #ffffff;
@@ -97,8 +98,7 @@
font-size: 28rpx; font-size: 28rpx;
} }
.device-actions-card, .device-actions-card {
.device-status-card {
position: relative; position: relative;
z-index: 1; z-index: 1;
border-radius: 24rpx; border-radius: 24rpx;
@@ -176,124 +176,6 @@
letter-spacing: 1rpx; letter-spacing: 1rpx;
} }
.device-status-card {
margin-top: 22rpx;
padding: 24rpx;
}
.device-status-card__header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12rpx;
}
.device-status-card__title {
color: #edf3ff;
font-size: 24rpx;
font-weight: 600;
}
.device-status-card__tag {
padding: 6rpx 16rpx;
border-radius: 999rpx;
font-size: 20rpx;
line-height: 1.2;
}
.device-status-card__tag--idle {
background: rgba(125, 136, 164, 0.18);
color: #b8c0d5;
}
.device-status-card__tag--searching {
background: rgba(54, 228, 170, 0.14);
color: #63f0c0;
}
.device-status-card__tag--empty {
background: rgba(255, 157, 87, 0.14);
color: #ffb173;
}
.device-status-card__tag--success {
background: rgba(72, 214, 165, 0.18);
color: #7cf0c4;
}
.device-status-card__hint {
display: block;
color: #f1f5ff;
font-size: 24rpx;
line-height: 1.7;
}
.device-status-card__subhint {
display: block;
margin-top: 8rpx;
color: #8f98ad;
font-size: 22rpx;
line-height: 1.6;
}
.device-list {
margin-top: 20rpx;
}
.device-list__item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx 22rpx;
border-radius: 18rpx;
background: rgba(25, 31, 44, 0.88);
}
.device-list__item + .device-list__item {
margin-top: 16rpx;
}
.device-list__name {
display: block;
color: #f3f7ff;
font-size: 24rpx;
font-weight: 600;
}
.device-list__meta {
display: block;
margin-top: 6rpx;
color: #8992a8;
font-size: 20rpx;
}
.device-list__action {
color: #3de5af;
font-size: 24rpx;
font-weight: 600;
}
.device-success {
margin-top: 18rpx;
padding: 18rpx 22rpx;
border-radius: 18rpx;
background: rgba(61, 229, 175, 0.1);
}
.device-success__title {
display: block;
color: #88f5cc;
font-size: 20rpx;
}
.device-success__name {
display: block;
margin-top: 6rpx;
color: #f3f7ff;
font-size: 24rpx;
font-weight: 600;
}
.device-notice-card { .device-notice-card {
position: relative; position: relative;
z-index: 1; z-index: 1;

View File

@@ -31,13 +31,6 @@ const mockBluetoothDevices: DeviceCandidate[] = [
{ id: "mock-thermo-02", name: "体征监测设备 B2", source: "mock" } { id: "mock-thermo-02", name: "体征监测设备 B2", source: "mock" }
]; ];
const bluetoothStateText: Record<BluetoothStatus, string> = {
idle: "点击蓝牙按钮后,将在这里显示附近设备搜索状态。",
searching: "正在搜索附近设备,请保持设备开机并靠近手机。",
empty: "未发现可连接设备,请确认设备已开机并已开启蓝牙与定位。",
success: "设备绑定成功,后续可在这里继续展示同步状态。"
};
function parseDeviceCode(result?: string) { function parseDeviceCode(result?: string) {
if (!result) { if (!result) {
return ""; return "";
@@ -60,9 +53,6 @@ function parseDeviceCode(result?: string) {
export default function Index() { export default function Index() {
const [deviceCount, setDeviceCount] = useState(0); const [deviceCount, setDeviceCount] = useState(0);
const [bluetoothStatus, setBluetoothStatus] = useState<BluetoothStatus>("idle"); const [bluetoothStatus, setBluetoothStatus] = useState<BluetoothStatus>("idle");
const [bluetoothDevices, setBluetoothDevices] = useState<DeviceCandidate[]>([]);
const [recentDeviceName, setRecentDeviceName] = useState("");
const [statusHint, setStatusHint] = useState("可通过扫码或蓝牙搜索完成设备绑定。");
const [topSafeHeight, setTopSafeHeight] = useState(0); const [topSafeHeight, setTopSafeHeight] = useState(0);
const [menuSafeWidth, setMenuSafeWidth] = useState(0); const [menuSafeWidth, setMenuSafeWidth] = useState(0);
const discoveryTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null); const discoveryTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
@@ -94,8 +84,7 @@ export default function Index() {
}); });
}; };
const bindDevice = async (name: string, sourceLabel: string) => { const bindDevice = async (_name: string, _sourceLabel: string) => {
setStatusHint(`正在连接 ${name}`);
showToast("设备配对连接中"); showToast("设备配对连接中");
await new Promise((resolve) => { await new Promise((resolve) => {
@@ -103,9 +92,7 @@ export default function Index() {
}); });
setBluetoothStatus("success"); setBluetoothStatus("success");
setRecentDeviceName(name);
setDeviceCount(1); setDeviceCount(1);
setStatusHint(`${sourceLabel}绑定成功,已可开始同步健康数据。`);
showToast("设备绑定成功"); showToast("设备绑定成功");
}; };
@@ -127,8 +114,6 @@ export default function Index() {
const handleScanBind = async () => { const handleScanBind = async () => {
try { try {
setStatusHint("等待扫码识别设备编码。");
const result = await Taro.scanCode({ const result = await Taro.scanCode({
scanType: ["qrCode", "barCode"] scanType: ["qrCode", "barCode"]
}); });
@@ -137,11 +122,9 @@ export default function Index() {
if (!deviceCode) { if (!deviceCode) {
showToast("二维码无法识别"); showToast("二维码无法识别");
setStatusHint("扫码成功,但未识别出可绑定的设备编码。");
return; return;
} }
setStatusHint(`正在查询设备 ${deviceCode}`);
showToast("正在查询设备"); showToast("正在查询设备");
await bindDevice(`扫码设备 ${deviceCode}`, "扫码设备"); await bindDevice(`扫码设备 ${deviceCode}`, "扫码设备");
} catch (error) { } catch (error) {
@@ -149,18 +132,15 @@ export default function Index() {
if (message.includes("cancel")) { if (message.includes("cancel")) {
showToast("已取消扫码"); showToast("已取消扫码");
setStatusHint("你取消了本次扫码绑定。");
return; return;
} }
if (message.includes("auth deny") || message.includes("authorize")) { if (message.includes("auth deny") || message.includes("authorize")) {
showToast("请开启相机权限"); showToast("请开启相机权限");
setStatusHint("扫码功能需要相机权限,请前往系统设置开启。");
return; return;
} }
showToast("扫码失败,请重试"); showToast("扫码失败,请重试");
setStatusHint("扫码失败,可能是权限不足或二维码无法识别。");
} }
}; };
@@ -177,7 +157,6 @@ export default function Index() {
return true; return true;
} catch { } catch {
showToast("请开启定位权限"); showToast("请开启定位权限");
setStatusHint("蓝牙搜索依赖定位权限,请先授权。");
return false; return false;
} }
}; };
@@ -192,15 +171,12 @@ export default function Index() {
if (!hasPermission) { if (!hasPermission) {
setBluetoothStatus("idle"); setBluetoothStatus("idle");
setBluetoothDevices([]);
return; return;
} }
try { try {
await Taro.openBluetoothAdapter(); await Taro.openBluetoothAdapter();
setBluetoothStatus("searching"); setBluetoothStatus("searching");
setBluetoothDevices([]);
setStatusHint("正在搜索附近设备。");
showToast("正在搜索附近设备"); showToast("正在搜索附近设备");
const foundDevices = new Map<string, DeviceCandidate>(); const foundDevices = new Map<string, DeviceCandidate>();
@@ -219,8 +195,6 @@ export default function Index() {
source: "ble" source: "ble"
}); });
}); });
setBluetoothDevices(Array.from(foundDevices.values()).slice(0, 6));
}); });
await Taro.startBluetoothDevicesDiscovery({ await Taro.startBluetoothDevicesDiscovery({
@@ -228,15 +202,25 @@ export default function Index() {
}); });
discoveryTimerRef.current = setTimeout(async () => { discoveryTimerRef.current = setTimeout(async () => {
const nextDevices = foundDevices.size > 0 ? Array.from(foundDevices.values()) : mockBluetoothDevices; const nextDevices = (foundDevices.size > 0 ? Array.from(foundDevices.values()) : mockBluetoothDevices).slice(0, 6);
setBluetoothDevices(nextDevices);
if (nextDevices.length > 0) { if (nextDevices.length > 0) {
setStatusHint("已找到附近设备,请点击列表完成绑定。"); await Taro.showActionSheet({
itemList: nextDevices.map((item) => item.name)
})
.then(({ tapIndex }) =>
bindDevice(nextDevices[tapIndex].name, nextDevices[tapIndex].source === "ble" ? "蓝牙设备" : "演示设备")
)
.catch((error) => {
const message = error instanceof Error ? error.message : "";
if (message.includes("cancel")) {
showToast("已取消选择设备");
}
});
} else { } else {
setBluetoothStatus("empty"); setBluetoothStatus("empty");
setStatusHint(bluetoothStateText.empty); showToast("未发现可连接设备");
} }
await Taro.stopBluetoothDevicesDiscovery().catch(() => undefined); await Taro.stopBluetoothDevicesDiscovery().catch(() => undefined);
@@ -246,21 +230,14 @@ export default function Index() {
if (message.includes("not available") || message.includes("10001")) { if (message.includes("not available") || message.includes("10001")) {
showToast("请先开启系统蓝牙"); showToast("请先开启系统蓝牙");
setStatusHint("系统蓝牙未开启,暂时无法搜索设备。");
} else { } else {
showToast("蓝牙搜索失败"); showToast("蓝牙搜索失败");
setStatusHint("蓝牙搜索未成功启动,请稍后重试。");
} }
setBluetoothStatus("idle"); setBluetoothStatus("idle");
setBluetoothDevices([]);
} }
}; };
const handleDeviceSelect = async (device: DeviceCandidate) => {
await bindDevice(device.name, device.source === "ble" ? "蓝牙设备" : "演示设备");
};
const pageStyle = { const pageStyle = {
"--top-safe-height": `${topSafeHeight}px`, "--top-safe-height": `${topSafeHeight}px`,
"--menu-safe-width": `${menuSafeWidth}px` "--menu-safe-width": `${menuSafeWidth}px`
@@ -301,41 +278,6 @@ export default function Index() {
</View> </View>
</View> </View>
<View className="device-status-card">
<View className="device-status-card__header">
<Text className="device-status-card__title"></Text>
<Text className={`device-status-card__tag device-status-card__tag--${bluetoothStatus}`}>
{bluetoothStatus === "searching" ? "搜索中" : bluetoothStatus === "empty" ? "无设备" : bluetoothStatus === "success" ? "成功" : "待开始"}
</Text>
</View>
<Text className="device-status-card__hint">{statusHint}</Text>
<Text className="device-status-card__subhint">{bluetoothStateText[bluetoothStatus]}</Text>
{bluetoothDevices.length > 0 ? (
<View className="device-list">
{bluetoothDevices.map((item) => (
<View className="device-list__item" key={item.id} onClick={() => handleDeviceSelect(item)}>
<View>
<Text className="device-list__name">{item.name}</Text>
<Text className="device-list__meta">
{item.source === "ble" ? "附近蓝牙设备" : "开发占位设备"}
</Text>
</View>
<Text className="device-list__action"></Text>
</View>
))}
</View>
) : null}
{recentDeviceName ? (
<View className="device-success">
<Text className="device-success__title"></Text>
<Text className="device-success__name">{recentDeviceName}</Text>
</View>
) : null}
</View>
<View className="device-notice-card"> <View className="device-notice-card">
<View className="device-notice-card__title-row"> <View className="device-notice-card__title-row">
<View className="device-notice-card__horn" /> <View className="device-notice-card__horn" />