refactor: simplify device binding home layout
This commit is contained in:
@@ -57,6 +57,7 @@
|
||||
.device-header__add {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin-top: 28rpx;
|
||||
border: 2rpx solid rgba(255, 255, 255, 0.86);
|
||||
border-radius: 50%;
|
||||
color: #ffffff;
|
||||
@@ -97,8 +98,7 @@
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.device-actions-card,
|
||||
.device-status-card {
|
||||
.device-actions-card {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
border-radius: 24rpx;
|
||||
@@ -176,124 +176,6 @@
|
||||
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 {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
@@ -31,13 +31,6 @@ const mockBluetoothDevices: DeviceCandidate[] = [
|
||||
{ id: "mock-thermo-02", name: "体征监测设备 B2", source: "mock" }
|
||||
];
|
||||
|
||||
const bluetoothStateText: Record<BluetoothStatus, string> = {
|
||||
idle: "点击蓝牙按钮后,将在这里显示附近设备搜索状态。",
|
||||
searching: "正在搜索附近设备,请保持设备开机并靠近手机。",
|
||||
empty: "未发现可连接设备,请确认设备已开机并已开启蓝牙与定位。",
|
||||
success: "设备绑定成功,后续可在这里继续展示同步状态。"
|
||||
};
|
||||
|
||||
function parseDeviceCode(result?: string) {
|
||||
if (!result) {
|
||||
return "";
|
||||
@@ -60,9 +53,6 @@ function parseDeviceCode(result?: string) {
|
||||
export default function Index() {
|
||||
const [deviceCount, setDeviceCount] = useState(0);
|
||||
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 [menuSafeWidth, setMenuSafeWidth] = useState(0);
|
||||
const discoveryTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
@@ -94,8 +84,7 @@ export default function Index() {
|
||||
});
|
||||
};
|
||||
|
||||
const bindDevice = async (name: string, sourceLabel: string) => {
|
||||
setStatusHint(`正在连接 ${name}`);
|
||||
const bindDevice = async (_name: string, _sourceLabel: string) => {
|
||||
showToast("设备配对连接中");
|
||||
|
||||
await new Promise((resolve) => {
|
||||
@@ -103,9 +92,7 @@ export default function Index() {
|
||||
});
|
||||
|
||||
setBluetoothStatus("success");
|
||||
setRecentDeviceName(name);
|
||||
setDeviceCount(1);
|
||||
setStatusHint(`${sourceLabel}绑定成功,已可开始同步健康数据。`);
|
||||
showToast("设备绑定成功");
|
||||
};
|
||||
|
||||
@@ -127,8 +114,6 @@ export default function Index() {
|
||||
|
||||
const handleScanBind = async () => {
|
||||
try {
|
||||
setStatusHint("等待扫码识别设备编码。");
|
||||
|
||||
const result = await Taro.scanCode({
|
||||
scanType: ["qrCode", "barCode"]
|
||||
});
|
||||
@@ -137,11 +122,9 @@ export default function Index() {
|
||||
|
||||
if (!deviceCode) {
|
||||
showToast("二维码无法识别");
|
||||
setStatusHint("扫码成功,但未识别出可绑定的设备编码。");
|
||||
return;
|
||||
}
|
||||
|
||||
setStatusHint(`正在查询设备 ${deviceCode}`);
|
||||
showToast("正在查询设备");
|
||||
await bindDevice(`扫码设备 ${deviceCode}`, "扫码设备");
|
||||
} catch (error) {
|
||||
@@ -149,18 +132,15 @@ export default function Index() {
|
||||
|
||||
if (message.includes("cancel")) {
|
||||
showToast("已取消扫码");
|
||||
setStatusHint("你取消了本次扫码绑定。");
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.includes("auth deny") || message.includes("authorize")) {
|
||||
showToast("请开启相机权限");
|
||||
setStatusHint("扫码功能需要相机权限,请前往系统设置开启。");
|
||||
return;
|
||||
}
|
||||
|
||||
showToast("扫码失败,请重试");
|
||||
setStatusHint("扫码失败,可能是权限不足或二维码无法识别。");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -177,7 +157,6 @@ export default function Index() {
|
||||
return true;
|
||||
} catch {
|
||||
showToast("请开启定位权限");
|
||||
setStatusHint("蓝牙搜索依赖定位权限,请先授权。");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -192,15 +171,12 @@ export default function Index() {
|
||||
|
||||
if (!hasPermission) {
|
||||
setBluetoothStatus("idle");
|
||||
setBluetoothDevices([]);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await Taro.openBluetoothAdapter();
|
||||
setBluetoothStatus("searching");
|
||||
setBluetoothDevices([]);
|
||||
setStatusHint("正在搜索附近设备。");
|
||||
showToast("正在搜索附近设备");
|
||||
|
||||
const foundDevices = new Map<string, DeviceCandidate>();
|
||||
@@ -219,8 +195,6 @@ export default function Index() {
|
||||
source: "ble"
|
||||
});
|
||||
});
|
||||
|
||||
setBluetoothDevices(Array.from(foundDevices.values()).slice(0, 6));
|
||||
});
|
||||
|
||||
await Taro.startBluetoothDevicesDiscovery({
|
||||
@@ -228,15 +202,25 @@ export default function Index() {
|
||||
});
|
||||
|
||||
discoveryTimerRef.current = setTimeout(async () => {
|
||||
const nextDevices = foundDevices.size > 0 ? Array.from(foundDevices.values()) : mockBluetoothDevices;
|
||||
|
||||
setBluetoothDevices(nextDevices);
|
||||
const nextDevices = (foundDevices.size > 0 ? Array.from(foundDevices.values()) : mockBluetoothDevices).slice(0, 6);
|
||||
|
||||
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 {
|
||||
setBluetoothStatus("empty");
|
||||
setStatusHint(bluetoothStateText.empty);
|
||||
showToast("未发现可连接设备");
|
||||
}
|
||||
|
||||
await Taro.stopBluetoothDevicesDiscovery().catch(() => undefined);
|
||||
@@ -246,21 +230,14 @@ export default function Index() {
|
||||
|
||||
if (message.includes("not available") || message.includes("10001")) {
|
||||
showToast("请先开启系统蓝牙");
|
||||
setStatusHint("系统蓝牙未开启,暂时无法搜索设备。");
|
||||
} else {
|
||||
showToast("蓝牙搜索失败");
|
||||
setStatusHint("蓝牙搜索未成功启动,请稍后重试。");
|
||||
}
|
||||
|
||||
setBluetoothStatus("idle");
|
||||
setBluetoothDevices([]);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeviceSelect = async (device: DeviceCandidate) => {
|
||||
await bindDevice(device.name, device.source === "ble" ? "蓝牙设备" : "演示设备");
|
||||
};
|
||||
|
||||
const pageStyle = {
|
||||
"--top-safe-height": `${topSafeHeight}px`,
|
||||
"--menu-safe-width": `${menuSafeWidth}px`
|
||||
@@ -301,41 +278,6 @@ export default function Index() {
|
||||
</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__title-row">
|
||||
<View className="device-notice-card__horn" />
|
||||
|
||||
Reference in New Issue
Block a user