You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

347 lines
10 KiB

import 'dart:ui';
import '/modules/devices/controllers/devices_controller.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import '/core/theme/app_colors.dart';
import '/data/models/user_Info.dart';
import '../controllers/devices_controller.dart';
// 设备类型枚举
enum DeviceType {
Unknown(0),
Classic_bluetooth_Headset(1),
BLE_Bluetooth_Headset(2),
Smart_Voice_Recorder(3),
SmartEye(4);
const DeviceType(this.value);
final int value;
// 使用getter获取多语言显示名称
String get displayName {
switch (this) {
case DeviceType.Unknown:
return "deviceTypeUnknown".tr;
case DeviceType.Classic_bluetooth_Headset:
return "deviceTypeClassicBluetoothHeadset".tr;
case DeviceType.BLE_Bluetooth_Headset:
return "deviceTypeBleBluetoothHeadset".tr;
case DeviceType.Smart_Voice_Recorder:
return "deviceTypeSmartVoiceRecorder".tr;
case DeviceType.SmartEye:
return "deviceTypeSmartEye".tr;
}
}
static DeviceType fromValue(int value) {
return DeviceType.values.firstWhere(
(type) => type.value == value,
orElse: () => DeviceType.Unknown,
);
}
IconData get icon {
switch (this) {
case DeviceType.Classic_bluetooth_Headset:
case DeviceType.BLE_Bluetooth_Headset:
return Icons.headphones;
case DeviceType.Smart_Voice_Recorder:
return Icons.mic;
case DeviceType.SmartEye:
return Icons.visibility;
default:
return Icons.device_unknown;
}
}
}
class DevicesView extends GetView<DevicesController> {
const DevicesView({super.key});
@override
Widget build(BuildContext context) {
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
return Scaffold(
backgroundColor: isDarkMode ? AppColors.darkBackground : Colors.white,
body: Column(
children: [
// 顶部标题栏
Container(
padding: EdgeInsets.only(
top: MediaQuery.of(context).padding.top + 10.h,
left: 20.w,
right: 20.w,
bottom: 20.h,
),
decoration: BoxDecoration(
color: isDarkMode ? Colors.black : Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Row(
children: [
GestureDetector(
onTap: () => Get.back(),
child: Icon(
Icons.arrow_back_ios,
color: isDarkMode ? Colors.white : Colors.black,
size: 24.sp,
),
),
SizedBox(width: 16.w),
Text(
"deviceManagement".tr,
style: TextStyle(
fontSize: 20.sp,
fontWeight: FontWeight.w600,
color: isDarkMode ? Colors.white : Colors.black,
),
),
],
),
),
// 设备列表内容
Expanded(
child: _buildDevicesList(isDarkMode),
),
],
),
);
}
Widget _buildDevicesList(bool isDarkMode) {
return Obx(() {
// 使用控制器的响应式数据,这会触发控制器的实例化
final groupedDevices = controller.devices;
if (groupedDevices.isEmpty) {
return _buildEmptyState(isDarkMode);
}
return ListView(
padding: EdgeInsets.all(20.w),
children: [
// 遍历每个设备类型
...groupedDevices.entries.map((entry) {
final deviceTypeValue = entry.key;
final deviceList = entry.value;
final deviceType = DeviceType.fromValue(deviceTypeValue);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 设备类型标题
Padding(
padding: EdgeInsets.only(bottom: 12.h),
child: Text(
deviceType.displayName,
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color: isDarkMode ? Colors.white : Colors.black87,
),
),
),
// 该类型下的设备列表
...deviceList.map((device) => _buildDeviceCard(
device: device,
deviceType: deviceType,
isDarkMode: isDarkMode,
)),
SizedBox(height: 20.h),
],
);
}).toList(),
],
);
});
}
Widget _buildEmptyState(bool isDarkMode) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.devices_other,
size: 80.sp,
color: isDarkMode ? Colors.white54 : Colors.grey[400],
),
SizedBox(height: 20.h),
Text(
"noDevicesBound".tr,
style: TextStyle(
fontSize: 16.sp,
color: isDarkMode ? Colors.white70 : Colors.grey[600],
),
),
SizedBox(height: 12.h),
Text(
"pleaseBindDeviceFirst".tr,
style: TextStyle(
fontSize: 14.sp,
color: isDarkMode ? Colors.white54 : Colors.grey[500],
),
),
],
),
);
}
Widget _buildDeviceCard({
required UserDevice device,
required DeviceType deviceType,
required bool isDarkMode,
}) {
return Container(
margin: EdgeInsets.only(bottom: 12.h),
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: isDarkMode ? AppColors.cardBackground : Colors.white,
borderRadius: BorderRadius.circular(12.r),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: Row(
children: [
// 设备图标
Container(
width: 48.w,
height: 48.w,
decoration: BoxDecoration(
color:
isDarkMode ? Colors.white.withOpacity(0.1) : Colors.grey[100],
borderRadius: BorderRadius.circular(12.r),
),
child: Icon(
deviceType.icon,
color: isDarkMode ? Colors.white : Colors.black87,
size: 24.sp,
),
),
SizedBox(width: 16.w),
// 设备信息
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
device.devicename.isNotEmpty
? device.devicename
: "deviceTypeUnknown".tr,
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w500,
color: isDarkMode ? Colors.white : Colors.black87,
),
),
SizedBox(height: 4.h),
Text(
device.devicemac.isNotEmpty
? device.devicemac
: "noMacAddress".tr,
style: TextStyle(
fontSize: 14.sp,
color: isDarkMode ? Colors.white70 : Colors.grey[600],
),
),
if (device.license.isNotEmpty) ...[
SizedBox(height: 4.h),
Text(
"${"licenseCode".tr}: ${device.license}",
style: TextStyle(
fontSize: 12.sp,
color: isDarkMode ? Colors.white54 : Colors.grey[500],
),
),
],
],
),
),
// 解绑按钮
GestureDetector(
onTap: () => _showUnbindDialog(device, isDarkMode),
child: Container(
padding: EdgeInsets.symmetric(
horizontal: 12.w,
vertical: 6.h,
),
decoration: BoxDecoration(
color: Colors.red.withOpacity(0.1),
borderRadius: BorderRadius.circular(6.r),
border: Border.all(
color: Colors.red.withOpacity(0.3),
width: 1,
),
),
child: Text(
"unbind".tr,
style: TextStyle(
fontSize: 12.sp,
color: Colors.red,
fontWeight: FontWeight.w500,
),
),
),
),
],
),
);
}
void _showUnbindDialog(UserDevice device, bool isDarkMode) {
Get.dialog(
AlertDialog(
backgroundColor: isDarkMode ? AppColors.cardBackground : Colors.white,
title: Text(
"confirmUnbind".tr,
style: TextStyle(
color: isDarkMode ? Colors.white : Colors.black87,
),
),
content: Text(
"confirmUnbindMessage"
.tr
.replaceAll('{deviceName}', device.devicename),
style: TextStyle(
color: isDarkMode ? Colors.white70 : Colors.black54,
),
),
actions: [
TextButton(
onPressed: () => Get.back(),
child: Text(
"cancel".tr,
style: TextStyle(
color: isDarkMode ? Colors.white70 : Colors.grey[600],
),
),
),
TextButton(
onPressed: () {
Get.back();
controller.unbindearphone(device);
},
child: Text(
"confirmUnbindAction".tr,
style: const TextStyle(color: Colors.red),
),
),
],
),
);
}
}