Browse Source

上传移动cmei码显示

newdev_shunjiawei
liwei1dao 7 months ago
parent
commit
6ac8b2a9c3
  1. 4
      lib/data/models/user_Info.dart
  2. 463
      lib/modules/devices/views/devices_view.dart
  3. 0
      preview/yidong.html

4
lib/data/models/user_Info.dart

@ -217,6 +217,7 @@ class UserDevice {
String devicename; String devicename;
String devicemac; String devicemac;
String license; String license;
String cmei;
UserDevice({ UserDevice({
required this.id, required this.id,
required this.uid, required this.uid,
@ -225,6 +226,7 @@ class UserDevice {
required this.devicename, required this.devicename,
required this.devicemac, required this.devicemac,
required this.license, required this.license,
this.cmei = '',
}); });
factory UserDevice.fromJson(Map<String, dynamic> json) => UserDevice( factory UserDevice.fromJson(Map<String, dynamic> json) => UserDevice(
@ -235,6 +237,7 @@ class UserDevice {
devicename: json['devicename'] as String, devicename: json['devicename'] as String,
devicemac: json['devicemac'] as String, devicemac: json['devicemac'] as String,
license: json['license'] as String, license: json['license'] as String,
cmei: json['cmei'] as String? ?? '',
); );
toJson() => { toJson() => {
@ -245,5 +248,6 @@ class UserDevice {
'devicename': devicename, 'devicename': devicename,
'devicemac': devicemac, 'devicemac': devicemac,
'license': license, 'license': license,
'cmei': cmei,
}; };
} }

463
lib/modules/devices/views/devices_view.dart

@ -1,12 +1,10 @@
import 'dart:ui';
import '../../../routes/app_routes.dart'; import '../../../routes/app_routes.dart';
import '/modules/devices/controllers/devices_controller.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import '/core/theme/app_colors.dart'; import '/core/theme/app_colors.dart';
import '/data/models/user_Info.dart'; import '/data/models/user_Info.dart';
import '/data/services/ble_manager.dart';
import '../controllers/devices_controller.dart'; import '../controllers/devices_controller.dart';
// 设备类型枚举 // 设备类型枚举
@ -20,7 +18,6 @@ enum DeviceType {
const DeviceType(this.value); const DeviceType(this.value);
final int value; final int value;
// 使用getter获取多语言显示名称
String get displayName { String get displayName {
switch (this) { switch (this) {
case DeviceType.Unknown: case DeviceType.Unknown:
@ -61,112 +58,240 @@ enum DeviceType {
class DevicesView extends GetView<DevicesController> { class DevicesView extends GetView<DevicesController> {
const DevicesView({super.key}); const DevicesView({super.key});
bool _isConnected(UserDevice device) {
try {
final bleManager = Get.find<BleManager>();
return bleManager.currentDeviceAddress != null &&
bleManager.currentDeviceAddress == device.devicemac;
} catch (_) {
return false;
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final isDarkMode = Theme.of(context).brightness == Brightness.dark; final isDark = Theme.of(context).brightness == Brightness.dark;
final bg = isDark ? const Color(0xFF0A0A0F) : const Color(0xFFF5F6FA);
final topBg = isDark ? const Color(0xFF0F1018) : const Color(0xFFF0F1F6);
return Scaffold( return Scaffold(
backgroundColor: isDarkMode ? AppColors.darkBackground : Colors.white, backgroundColor: bg,
body: Column( body: Column(
children: [ children: [
// 顶部标题栏 // 顶部区域
Container( _buildTopArea(context, isDark, bg, topBg),
// 设备列表
Expanded(child: _buildDevicesList(isDark, topBg)),
],
),
);
}
Widget _buildTopArea(
BuildContext context, bool isDark, Color bg, Color topBg) {
return Container(
padding: EdgeInsets.only( padding: EdgeInsets.only(
top: MediaQuery.of(context).padding.top + 10.h, top: MediaQuery.of(context).padding.top + 8.h,
left: 20.w, left: 20.w,
right: 20.w, right: 20.w,
bottom: 20.h, bottom: 24.h,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(color: bg),
color: isDarkMode ? Colors.black : Colors.white, child: Column(
boxShadow: [ crossAxisAlignment: CrossAxisAlignment.start,
BoxShadow( children: [
color: Colors.black.withOpacity(0.05), // 导航栏
blurRadius: 10, Row(
offset: const Offset(0, 2),
),
],
),
child: Row(
children: [ children: [
GestureDetector( GestureDetector(
onTap: () => Get.back(), onTap: () => Get.back(),
child: Container(
width: 40.w,
height: 40.w,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: isDark
? Colors.white.withOpacity(0.06)
: Colors.black.withOpacity(0.04),
),
child: Icon( child: Icon(
Icons.arrow_back_ios, Icons.arrow_back_ios_new,
color: isDarkMode ? Colors.white : Colors.black, size: 18.sp,
size: 24.sp, color: isDark ? Colors.white : const Color(0xFF222222),
),
), ),
), ),
SizedBox(width: 16.w), SizedBox(width: 16.w),
Text( Text(
"deviceManagement".tr, "deviceManagement".tr,
style: TextStyle( style: TextStyle(
fontSize: 20.sp, fontSize: 26.sp,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w800,
color: isDarkMode ? Colors.white : Colors.black, color: isDark ? Colors.white : const Color(0xFF111111),
letterSpacing: -0.5,
), ),
), ),
], ],
), ),
SizedBox(height: 20.h),
// 摘要卡片
Obx(() {
final totalDevices = controller.devices.values
.fold<int>(0, (sum, list) => sum + list.length);
final connectedCount = controller.devices.values
.expand((list) => list)
.where((d) => _isConnected(d))
.length;
return Row(
children: [
_buildSummaryCard(
number: totalDevices.toString(),
label: "boundDevices".tr,
isActive: true,
isDark: isDark,
),
SizedBox(width: 12.w),
_buildSummaryCard(
number: connectedCount.toString(),
label: "currentConnection".tr,
isActive: false,
isDark: isDark,
),
],
);
}),
],
),
);
}
Widget _buildSummaryCard({
required String number,
required String label,
required bool isActive,
required bool isDark,
}) {
final activeGradient = isDark
? [
const Color(0xFF6366F1).withOpacity(0.15),
const Color(0xFF8B5CF6).withOpacity(0.1),
]
: [const Color(0xFFEEF2FF), const Color(0xFFF5F3FF)];
return Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 14.h),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16.r),
gradient: isActive ? LinearGradient(colors: activeGradient) : null,
color: isActive
? null
: (isDark
? Colors.white.withOpacity(0.04)
: Colors.white),
border: Border.all(
color: isActive
? (isDark
? const Color(0xFF6366F1).withOpacity(0.2)
: const Color(0xFF6366F1).withOpacity(0.15))
: (isDark
? Colors.white.withOpacity(0.06)
: Colors.black.withOpacity(0.04)),
),
boxShadow: isDark
? null
: [
BoxShadow(
color: Colors.black.withOpacity(0.04),
blurRadius: 4,
offset: const Offset(0, 1),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
number,
style: TextStyle(
fontSize: 24.sp,
fontWeight: FontWeight.w700,
color: isActive
? (isDark
? const Color(0xFFA5B4FC)
: const Color(0xFF6366F1))
: (isDark ? Colors.white : const Color(0xFF222222)),
),
),
SizedBox(height: 2.h),
Text(
label,
style: TextStyle(
fontSize: 11.sp,
fontWeight: FontWeight.w500,
color: isActive
? (isDark
? const Color(0xFFA5B4FC).withOpacity(0.6)
: const Color(0xFF818CF8))
: (isDark
? Colors.white.withOpacity(0.35)
: const Color(0xFF999999)),
), ),
// 设备列表内容
Expanded(
child: _buildDevicesList(isDarkMode),
), ),
], ],
), ),
),
); );
} }
Widget _buildDevicesList(bool isDarkMode) { Widget _buildDevicesList(bool isDark, Color topBg) {
return Obx(() { return Obx(() {
// 使用控制器的响应式数据,这会触发控制器的实例化
final groupedDevices = controller.devices; final groupedDevices = controller.devices;
if (groupedDevices.isEmpty) { if (groupedDevices.isEmpty) {
return _buildEmptyState(isDarkMode); return _buildEmptyState(isDark);
} }
return ListView( return ListView(
padding: EdgeInsets.all(20.w), padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 20.h),
children: [ children: [
// 遍历每个设备类型
...groupedDevices.entries.map((entry) { ...groupedDevices.entries.map((entry) {
final deviceTypeValue = entry.key; final deviceType = DeviceType.fromValue(entry.key);
final deviceList = entry.value; final deviceList = entry.value;
final deviceType = DeviceType.fromValue(deviceTypeValue);
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// 设备类型标题 // 分类标题
Padding( Padding(
padding: EdgeInsets.only(bottom: 12.h), padding: EdgeInsets.only(left: 8.w, bottom: 12.h),
child: Text( child: Text(
deviceType.displayName, deviceType.displayName.toUpperCase(),
style: TextStyle( style: TextStyle(
fontSize: 16.sp, fontSize: 12.sp,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: isDarkMode ? Colors.white : Colors.black87, color: isDark
? Colors.white.withOpacity(0.25)
: const Color(0xFFAAAAAA),
letterSpacing: 1.5,
), ),
), ),
), ),
// 该类型下的设备列表
...deviceList.map((device) => _buildDeviceCard( ...deviceList.map((device) => _buildDeviceCard(
device: device, device: device,
deviceType: deviceType, deviceType: deviceType,
isDarkMode: isDarkMode, isDark: isDark,
)), )),
SizedBox(height: 20.h), SizedBox(height: 16.h),
], ],
); );
}).toList(), }),
], ],
); );
}); });
} }
Widget _buildEmptyState(bool isDarkMode) { Widget _buildEmptyState(bool isDark) {
return Center( return Center(
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
@ -174,14 +299,14 @@ class DevicesView extends GetView<DevicesController> {
Icon( Icon(
Icons.devices_other, Icons.devices_other,
size: 80.sp, size: 80.sp,
color: isDarkMode ? Colors.white54 : Colors.grey[400], color: isDark ? Colors.white54 : Colors.grey[400],
), ),
SizedBox(height: 20.h), SizedBox(height: 20.h),
Text( Text(
"noDevicesBound".tr, "noDevicesBound".tr,
style: TextStyle( style: TextStyle(
fontSize: 16.sp, fontSize: 16.sp,
color: isDarkMode ? Colors.white70 : Colors.grey[600], color: isDark ? Colors.white70 : Colors.grey[600],
), ),
), ),
SizedBox(height: 12.h), SizedBox(height: 12.h),
@ -189,7 +314,7 @@ class DevicesView extends GetView<DevicesController> {
"pleaseBindDeviceFirst".tr, "pleaseBindDeviceFirst".tr,
style: TextStyle( style: TextStyle(
fontSize: 14.sp, fontSize: 14.sp,
color: isDarkMode ? Colors.white54 : Colors.grey[500], color: isDark ? Colors.white54 : Colors.grey[500],
), ),
), ),
], ],
@ -200,47 +325,82 @@ class DevicesView extends GetView<DevicesController> {
Widget _buildDeviceCard({ Widget _buildDeviceCard({
required UserDevice device, required UserDevice device,
required DeviceType deviceType, required DeviceType deviceType,
required bool isDarkMode, required bool isDark,
}) { }) {
final connected = _isConnected(device);
final connectedColor = const Color(0xFF22C55E);
return GestureDetector( return GestureDetector(
onTap: () => Get.toNamed(Routes.eqSettings), onTap: () => Get.toNamed(Routes.eqSettings),
child: Container( child: Container(
margin: EdgeInsets.only(bottom: 12.h), margin: EdgeInsets.only(bottom: 10.h),
padding: EdgeInsets.all(16.w), padding: EdgeInsets.all(20.w),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isDarkMode ? AppColors.cardBackground : Colors.white, borderRadius: BorderRadius.circular(20.r),
borderRadius: BorderRadius.circular(12.r), color: isDark
boxShadow: [ ? (connected
? connectedColor.withOpacity(0.04)
: Colors.white.withOpacity(0.03))
: (connected
? connectedColor.withOpacity(0.03)
: Colors.white),
border: Border.all(
color: connected
? connectedColor.withOpacity(0.2)
: (isDark
? Colors.white.withOpacity(0.05)
: Colors.black.withOpacity(0.04)),
),
boxShadow: isDark
? null
: [
BoxShadow( BoxShadow(
color: Colors.black.withOpacity(0.05), color: Colors.black.withOpacity(0.03),
blurRadius: 8, blurRadius: 12,
offset: const Offset(0, 2), offset: const Offset(0, 2),
), ),
], ],
), ),
child: Row( child: Column(
children: [
// 上部:图标 + 名称/MAC + 解绑
Row(
children: [ children: [
// 设备图标 // 设备图标
Container( Container(
width: 48.w, width: 46.w,
height: 48.w, height: 46.w,
decoration: BoxDecoration( decoration: BoxDecoration(
color: isDarkMode borderRadius: BorderRadius.circular(14.r),
? Colors.white.withOpacity(0.1) gradient: LinearGradient(
: Colors.grey[100], begin: Alignment.topLeft,
borderRadius: BorderRadius.circular(12.r), end: Alignment.bottomRight,
colors: connected
? [connectedColor, const Color(0xFF16A34A)]
: [const Color(0xFF6366F1), const Color(0xFF8B5CF6)],
),
boxShadow: [
BoxShadow(
color: (connected ? connectedColor : const Color(0xFF6366F1))
.withOpacity(0.3),
blurRadius: 16,
offset: const Offset(0, 4),
),
],
), ),
child: Icon( child: Icon(
deviceType.icon, deviceType.icon,
color: isDarkMode ? Colors.white : Colors.black87, color: Colors.white,
size: 24.sp, size: 22.sp,
), ),
), ),
SizedBox(width: 16.w), SizedBox(width: 14.w),
// 设备信息 // 设备名 + MAC
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [ children: [
Text( Text(
device.devicename.isNotEmpty device.devicename.isNotEmpty
@ -248,73 +408,180 @@ class DevicesView extends GetView<DevicesController> {
: "deviceTypeUnknown".tr, : "deviceTypeUnknown".tr,
style: TextStyle( style: TextStyle(
fontSize: 16.sp, fontSize: 16.sp,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w700,
color: isDarkMode ? Colors.white : Colors.black87, color: isDark
? Colors.white
: const Color(0xFF1A1A2E),
), ),
), ),
SizedBox(height: 4.h), if (connected) ...[
Text( SizedBox(width: 8.w),
device.devicemac.isNotEmpty Container(
? device.devicemac width: 6.w,
: "noMacAddress".tr, height: 6.w,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: connectedColor,
boxShadow: [
BoxShadow(
color: connectedColor.withOpacity(0.6),
blurRadius: 8,
),
],
),
),
SizedBox(width: 6.w),
Container(
padding: EdgeInsets.symmetric(
horizontal: 8.w, vertical: 3.h),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.r),
color: connectedColor.withOpacity(0.1),
),
child: Text(
"connected".tr,
style: TextStyle( style: TextStyle(
fontSize: 14.sp, fontSize: 10.sp,
color: isDarkMode ? Colors.white70 : Colors.grey[600], fontWeight: FontWeight.w600,
color: connectedColor,
),
), ),
), ),
if (device.license.isNotEmpty) ...[ ],
SizedBox(height: 4.h), ],
),
SizedBox(height: 3.h),
Text( Text(
"${"licenseCode".tr}: ${device.license}", device.devicemac.isNotEmpty
? device.devicemac
: "noMacAddress".tr,
style: TextStyle( style: TextStyle(
fontSize: 12.sp, fontSize: 12.sp,
color: isDarkMode ? Colors.white54 : Colors.grey[500], fontWeight: FontWeight.w500,
color: isDark
? Colors.white.withOpacity(0.3)
: const Color(0xFF999999),
fontFamily: 'Menlo',
letterSpacing: 0.5,
), ),
), ),
], ],
],
), ),
), ),
// 解绑按钮 // 解绑按钮
GestureDetector( GestureDetector(
onTap: () => _showUnbindDialog(device, isDarkMode), onTap: () => _showUnbindDialog(device, isDark),
child: Container( child: Container(
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
horizontal: 12.w, horizontal: 14.w, vertical: 8.h),
vertical: 6.h,
),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.red.withOpacity(0.1), borderRadius: BorderRadius.circular(10.r),
borderRadius: BorderRadius.circular(6.r),
border: Border.all( border: Border.all(
color: Colors.red.withOpacity(0.3), color: isDark
width: 1, ? Colors.white.withOpacity(0.08)
: Colors.black.withOpacity(0.08),
), ),
), ),
child: Text( child: Text(
"unbind".tr, "unbind".tr,
style: TextStyle( style: TextStyle(
fontSize: 12.sp, fontSize: 12.sp,
color: Colors.red, fontWeight: FontWeight.w600,
fontWeight: FontWeight.w500, color: isDark
? Colors.white.withOpacity(0.4)
: const Color(0xFF999999),
),
),
),
),
],
),
// 下部:授权码 / CMEI
if (device.license.isNotEmpty || device.cmei.isNotEmpty) ...[
SizedBox(height: 16.h),
Container(
padding: EdgeInsets.all(12.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12.r),
color: isDark
? Colors.white.withOpacity(0.03)
: const Color(0xFFF7F7FA),
), ),
child: Column(
children: [
if (device.license.isNotEmpty)
_buildFieldRow(
label: "licenseCode".tr,
value: device.license,
isDark: isDark,
),
if (device.license.isNotEmpty && device.cmei.isNotEmpty)
SizedBox(height: 8.h),
if (device.cmei.isNotEmpty)
_buildFieldRow(
label: "CMEI",
value: device.cmei,
isDark: isDark,
), ),
],
), ),
), ),
], ],
],
), ),
), ),
); );
} }
void _showUnbindDialog(UserDevice device, bool isDarkMode) { Widget _buildFieldRow({
required String label,
required String value,
required bool isDark,
}) {
return Row(
children: [
SizedBox(
width: 44.w,
child: Text(
label,
style: TextStyle(
fontSize: 10.sp,
fontWeight: FontWeight.w600,
color: isDark
? Colors.white.withOpacity(0.2)
: const Color(0xFFBBBBBB),
letterSpacing: 0.5,
),
),
),
SizedBox(width: 8.w),
Expanded(
child: Text(
value,
style: TextStyle(
fontSize: 11.sp,
fontWeight: FontWeight.w500,
color: isDark
? Colors.white.withOpacity(0.5)
: const Color(0xFF666666),
fontFamily: 'Menlo',
letterSpacing: 0.3,
),
overflow: TextOverflow.ellipsis,
),
),
],
);
}
void _showUnbindDialog(UserDevice device, bool isDark) {
Get.dialog( Get.dialog(
AlertDialog( AlertDialog(
backgroundColor: isDarkMode ? AppColors.cardBackground : Colors.white, backgroundColor: isDark ? AppColors.cardBackground : Colors.white,
title: Text( title: Text(
"confirmUnbind".tr, "confirmUnbind".tr,
style: TextStyle( style: TextStyle(
color: isDarkMode ? Colors.white : Colors.black87, color: isDark ? Colors.white : Colors.black87,
), ),
), ),
content: Text( content: Text(
@ -322,7 +589,7 @@ class DevicesView extends GetView<DevicesController> {
.tr .tr
.replaceAll('{deviceName}', device.devicename), .replaceAll('{deviceName}', device.devicename),
style: TextStyle( style: TextStyle(
color: isDarkMode ? Colors.white70 : Colors.black54, color: isDark ? Colors.white70 : Colors.black54,
), ),
), ),
actions: [ actions: [
@ -331,7 +598,7 @@ class DevicesView extends GetView<DevicesController> {
child: Text( child: Text(
"cancel".tr, "cancel".tr,
style: TextStyle( style: TextStyle(
color: isDarkMode ? Colors.white70 : Colors.grey[600], color: isDark ? Colors.white70 : Colors.grey[600],
), ),
), ),
), ),

0
ui/yidong.html → preview/yidong.html

Loading…
Cancel
Save