feat: 增加搜索设备页、团队管理页
This commit is contained in:
parent
8501b5ea48
commit
5bca96a4cf
@ -39,6 +39,10 @@ class _AppState extends State<App> {
|
|||||||
dialogBackgroundColor: Colors.white,
|
dialogBackgroundColor: Colors.white,
|
||||||
appBarTheme: AppBarTheme(
|
appBarTheme: AppBarTheme(
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
|
elevation: 0,
|
||||||
|
surfaceTintColor: Colors.transparent,
|
||||||
|
shadowColor: Colors.transparent,
|
||||||
|
scrolledUnderElevation: 0,
|
||||||
)),
|
)),
|
||||||
// 必须配置以下三个本地化代理
|
// 必须配置以下三个本地化代理
|
||||||
localizationsDelegates: const [
|
localizationsDelegates: const [
|
||||||
|
|||||||
@ -4,12 +4,11 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:starcloud/sdk/starcloud.dart';
|
||||||
import 'package:starwork_flutter/api/base_api_service.dart';
|
import 'package:starwork_flutter/api/base_api_service.dart';
|
||||||
import 'package:starwork_flutter/api/service/common_api_service.dart';
|
import 'package:starwork_flutter/api/service/common_api_service.dart';
|
||||||
import 'package:starwork_flutter/api/service/user_api_service.dart';
|
import 'package:starwork_flutter/api/service/user_api_service.dart';
|
||||||
import 'package:starwork_flutter/common/utils/shared_preferences_utils.dart';
|
import 'package:starwork_flutter/common/utils/shared_preferences_utils.dart';
|
||||||
import 'package:starwork_flutter/i18n/app_i18n.dart';
|
|
||||||
import 'package:starwork_flutter/views/login/login_controller.dart';
|
import 'package:starwork_flutter/views/login/login_controller.dart';
|
||||||
import 'package:starwork_flutter/views/main/main_controller.dart';
|
import 'package:starwork_flutter/views/main/main_controller.dart';
|
||||||
|
|
||||||
@ -20,7 +19,7 @@ class AppInitialization {
|
|||||||
setSystemStatusBar();
|
setSystemStatusBar();
|
||||||
await SharedPreferencesUtils.init();
|
await SharedPreferencesUtils.init();
|
||||||
initEasyLoading();
|
initEasyLoading();
|
||||||
|
StarCloudSDK.init(clientId: 'clientId', clientSecret: 'clientSecret');
|
||||||
Get.put(BaseApiService());
|
Get.put(BaseApiService());
|
||||||
Get.put(CommonApiService(Get.find<BaseApiService>()));
|
Get.put(CommonApiService(Get.find<BaseApiService>()));
|
||||||
Get.put(UserApiService(Get.find<BaseApiService>()));
|
Get.put(UserApiService(Get.find<BaseApiService>()));
|
||||||
|
|||||||
5
lib/common/constant/app_colors.dart
Normal file
5
lib/common/constant/app_colors.dart
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
class AppColors {
|
||||||
|
static Color scaffoldBackgroundColor = const Color(0xFFF6F7FB);
|
||||||
|
}
|
||||||
33
lib/common/constant/device_type.dart
Normal file
33
lib/common/constant/device_type.dart
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
class DeviceType {
|
||||||
|
static const lock = DeviceType('1', '锁');
|
||||||
|
static const gateway = DeviceType('2', '网关');
|
||||||
|
static const attendanceMachine = DeviceType('3', '考勤机');
|
||||||
|
final String value;
|
||||||
|
final String label;
|
||||||
|
|
||||||
|
const DeviceType(this.value, this.label);
|
||||||
|
|
||||||
|
// 支持通过字符串值查找枚举实例
|
||||||
|
static DeviceType? fromValue(String? value) {
|
||||||
|
return {
|
||||||
|
'1': lock,
|
||||||
|
'2': gateway,
|
||||||
|
'3': attendanceMachine,
|
||||||
|
}[value];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 支持 toString() 直接输出 value
|
||||||
|
@override
|
||||||
|
String toString() => value;
|
||||||
|
|
||||||
|
// 可选:支持 == 比较
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is DeviceType &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
value == other.value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => value.hashCode;
|
||||||
|
}
|
||||||
@ -1,5 +1,7 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:starwork_flutter/routes/app_routes.dart';
|
import 'package:starwork_flutter/routes/app_routes.dart';
|
||||||
|
import 'package:starwork_flutter/views/device/confirmPairDevice/confirm_pair_device_binding.dart';
|
||||||
|
import 'package:starwork_flutter/views/device/confirmPairDevice/confirm_pair_device_view.dart';
|
||||||
import 'package:starwork_flutter/views/device/searchDevice/search_device_binding.dart';
|
import 'package:starwork_flutter/views/device/searchDevice/search_device_binding.dart';
|
||||||
import 'package:starwork_flutter/views/device/searchDevice/search_device_view.dart';
|
import 'package:starwork_flutter/views/device/searchDevice/search_device_view.dart';
|
||||||
import 'package:starwork_flutter/views/home/home_binding.dart';
|
import 'package:starwork_flutter/views/home/home_binding.dart';
|
||||||
@ -14,6 +16,10 @@ import 'package:starwork_flutter/views/login/login_binding.dart';
|
|||||||
import 'package:starwork_flutter/views/login/login_view.dart';
|
import 'package:starwork_flutter/views/login/login_view.dart';
|
||||||
import 'package:starwork_flutter/views/main/main_binding.dart';
|
import 'package:starwork_flutter/views/main/main_binding.dart';
|
||||||
import 'package:starwork_flutter/views/main/main_view.dart';
|
import 'package:starwork_flutter/views/main/main_view.dart';
|
||||||
|
import 'package:starwork_flutter/views/main/teamNotice/teamNoticeDetails/team_notice_details_binding.dart';
|
||||||
|
import 'package:starwork_flutter/views/main/teamNotice/teamNoticeDetails/team_notice_details_view.dart';
|
||||||
|
import 'package:starwork_flutter/views/main/teamNotice/team_notice_binding.dart';
|
||||||
|
import 'package:starwork_flutter/views/main/teamNotice/team_notice_view.dart';
|
||||||
import 'package:starwork_flutter/views/messages/messages_binding.dart';
|
import 'package:starwork_flutter/views/messages/messages_binding.dart';
|
||||||
import 'package:starwork_flutter/views/messages/messages_view.dart';
|
import 'package:starwork_flutter/views/messages/messages_view.dart';
|
||||||
import 'package:starwork_flutter/views/mine/mine_binding.dart';
|
import 'package:starwork_flutter/views/mine/mine_binding.dart';
|
||||||
@ -67,5 +73,20 @@ class AppPages {
|
|||||||
page: () => const SearchDeviceView(),
|
page: () => const SearchDeviceView(),
|
||||||
binding: SearchDeviceBinding(),
|
binding: SearchDeviceBinding(),
|
||||||
),
|
),
|
||||||
|
GetPage(
|
||||||
|
name: AppRoutes.confirmPairDevice,
|
||||||
|
page: () => const ConfirmPairDeviceView(),
|
||||||
|
binding: ConfirmPairDeviceBinding(),
|
||||||
|
),
|
||||||
|
GetPage(
|
||||||
|
name: AppRoutes.teamNotice,
|
||||||
|
page: () => const TeamNoticeView(),
|
||||||
|
binding: TeamNoticeBinding(),
|
||||||
|
),
|
||||||
|
GetPage(
|
||||||
|
name: AppRoutes.teamNoticeDetails,
|
||||||
|
page: () => const TeamNoticeDetailsView(),
|
||||||
|
binding: TeamNoticeDetailsBinding(),
|
||||||
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,4 +9,7 @@ class AppRoutes{
|
|||||||
static const String forgotPassword = '/forgotPassword';
|
static const String forgotPassword = '/forgotPassword';
|
||||||
static const String setNewPassword = '/setNewPassword';
|
static const String setNewPassword = '/setNewPassword';
|
||||||
static const String searchDevice = '/searchDevice';
|
static const String searchDevice = '/searchDevice';
|
||||||
|
static const String confirmPairDevice = '/confirmPairDevice';
|
||||||
|
static const String teamNotice = '/teamNotice';
|
||||||
|
static const String teamNoticeDetails = '/teamNoticeDetails';
|
||||||
}
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/views/device/confirmPairDevice/confirm_pair_device_controller.dart';
|
||||||
|
|
||||||
|
class ConfirmPairDeviceBinding extends Bindings {
|
||||||
|
@override
|
||||||
|
void dependencies() {
|
||||||
|
Get.lazyPut<ConfirmPairDeviceController>(() => ConfirmPairDeviceController());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
import 'package:starwork_flutter/base/base_controller.dart';
|
||||||
|
|
||||||
|
class ConfirmPairDeviceController extends BaseController{
|
||||||
|
|
||||||
|
}
|
||||||
109
lib/views/device/confirmPairDevice/confirm_pair_device_view.dart
Normal file
109
lib/views/device/confirmPairDevice/confirm_pair_device_view.dart
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/src/widgets/framework.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/views/device/confirmPairDevice/confirm_pair_device_controller.dart';
|
||||||
|
|
||||||
|
class ConfirmPairDeviceView extends GetView<ConfirmPairDeviceController> {
|
||||||
|
const ConfirmPairDeviceView({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
FocusScope.of(context).unfocus();
|
||||||
|
},
|
||||||
|
child: Scaffold(
|
||||||
|
backgroundColor: const Color(0xFFF6F7FB),
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'确认连接设备'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black87,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 30.h,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 30.w,
|
||||||
|
),
|
||||||
|
child: TextField(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: '请输入内容',
|
||||||
|
// --- 边框设置 ---
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8.r), // 圆角
|
||||||
|
borderSide: const BorderSide(
|
||||||
|
color: Colors.blue, // 边框颜色
|
||||||
|
width: 1.5, // 边框宽度
|
||||||
|
),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
borderSide: const BorderSide(
|
||||||
|
color: Colors.grey, // 未获得焦点时的边框颜色
|
||||||
|
width: 1.5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
borderSide: const BorderSide(
|
||||||
|
color: Colors.blue, // 获得焦点时的边框颜色
|
||||||
|
width: 2.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// --- 内边距(可选,让文字不贴边)---
|
||||||
|
contentPadding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 10.w,
|
||||||
|
vertical: 14.h,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// --- 文字居中对齐 ---
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
// 可选:输入文本样式
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Colors.black87,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 30.h,
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.blue,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 80.w, vertical: 12.h),
|
||||||
|
// 或使用 EdgeInsets.all(16) 等
|
||||||
|
),
|
||||||
|
onPressed: () {},
|
||||||
|
child: Text(
|
||||||
|
'确认连接'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18.sp,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,22 +1,64 @@
|
|||||||
import 'dart:ui';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
|
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
|
||||||
import 'package:starwork_flutter/base/app_permission.dart';
|
|
||||||
import 'package:starwork_flutter/base/base_controller.dart';
|
import 'package:starwork_flutter/base/base_controller.dart';
|
||||||
|
import 'package:starwork_flutter/routes/app_routes.dart';
|
||||||
|
import 'package:starwork_flutter/views/device/searchDevice/search_device_model.dart';
|
||||||
|
|
||||||
class SearchDeviceController extends BaseController {
|
class SearchDeviceController extends BaseController {
|
||||||
// 搜索状态管理
|
// 搜索状态管理
|
||||||
final RxBool _isSearching = false.obs;
|
final RxBool _isSearching = false.obs;
|
||||||
|
|
||||||
|
// 设备列表管理
|
||||||
|
final RxList<SearchDeviceItem> deviceList = <SearchDeviceItem>[].obs;
|
||||||
|
|
||||||
// Getter
|
// Getter
|
||||||
bool get isSearching => _isSearching.value;
|
bool get isSearching => _isSearching.value;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() async {
|
void onInit() async {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
|
_initializeDevices();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化设备数据
|
||||||
|
void _initializeDevices() {
|
||||||
|
deviceList.value = [
|
||||||
|
SearchDeviceItem(
|
||||||
|
id: 'TMH_4564sa121dfsda',
|
||||||
|
name: 'TMH_4564sa121dfsda',
|
||||||
|
deviceType: '门禁设备',
|
||||||
|
isOnline: true,
|
||||||
|
),
|
||||||
|
SearchDeviceItem(
|
||||||
|
id: 'TMH_4564sa121dfsdv',
|
||||||
|
name: 'TMH_4564sa121dfsdv',
|
||||||
|
deviceType: '门禁设备',
|
||||||
|
isOnline: true,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新设备数据
|
||||||
|
Future<void> refreshDevices() async {
|
||||||
|
// 设置搜索状态
|
||||||
|
_isSearching.value = true;
|
||||||
|
showLoading();
|
||||||
|
|
||||||
|
// 模拟网络请求延迟
|
||||||
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
|
|
||||||
|
// 这里可以添加实际的设备搜索API调用
|
||||||
|
// 模拟刷新数据
|
||||||
|
_initializeDevices();
|
||||||
|
|
||||||
|
// 结束搜索状态
|
||||||
|
_isSearching.value = false;
|
||||||
|
|
||||||
|
hideLoading();
|
||||||
|
print('设备搜索刷新完成');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 连接设备
|
||||||
|
void connectingDevices() async {
|
||||||
|
Get.toNamed(AppRoutes.confirmPairDevice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
lib/views/device/searchDevice/search_device_model.dart
Normal file
16
lib/views/device/searchDevice/search_device_model.dart
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
// 设备模型类
|
||||||
|
class SearchDeviceItem {
|
||||||
|
final String id;
|
||||||
|
final String name;
|
||||||
|
final String deviceType;
|
||||||
|
final bool isOnline;
|
||||||
|
|
||||||
|
SearchDeviceItem({
|
||||||
|
required this.id,
|
||||||
|
required this.name,
|
||||||
|
required this.deviceType,
|
||||||
|
required this.isOnline,
|
||||||
|
});
|
||||||
|
}
|
||||||
@ -12,12 +12,18 @@ class SearchDeviceView extends GetView<SearchDeviceController> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
backgroundColor: const Color(0xFFF6F7FB),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Row(
|
title: Row(
|
||||||
children: [
|
children: [
|
||||||
Obx(() => Text(
|
Text(
|
||||||
controller.isSearching ? '搜索设备中'.tr : '搜索设备'.tr,
|
'搜索设备中'.tr,
|
||||||
)),
|
style: TextStyle(
|
||||||
|
fontSize: 18.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black87,
|
||||||
|
),
|
||||||
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 8.w,
|
width: 8.w,
|
||||||
),
|
),
|
||||||
@ -30,11 +36,177 @@ class SearchDeviceView extends GetView<SearchDeviceController> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: _onRefresh,
|
||||||
|
child: Text(
|
||||||
|
'刷新'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Colors.black87,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
body: Container(
|
body: Column(
|
||||||
// TODO: 添加设备搜索结果列表
|
children: [
|
||||||
child: Center(
|
// 设备列表
|
||||||
child: Text('设备搜索页面'),
|
Expanded(
|
||||||
|
child: _buildRefreshableDeviceList(),
|
||||||
|
),
|
||||||
|
// 固定在底部的提示信息
|
||||||
|
_buildDeviceTip(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建下拉刷新的设备列表
|
||||||
|
_buildRefreshableDeviceList() {
|
||||||
|
return RefreshIndicator(
|
||||||
|
onRefresh: _onRefresh,
|
||||||
|
// 基础样式配置
|
||||||
|
color: const Color(0xFF4A90E2),
|
||||||
|
// 刷新指示器颜色
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
// 背景颜色
|
||||||
|
|
||||||
|
// 控制下拉触发距离的关键属性
|
||||||
|
displacement: 60.0,
|
||||||
|
// 刷新指示器距离顶部的距离
|
||||||
|
|
||||||
|
// 控制下拉幅度的关键属性
|
||||||
|
triggerMode: RefreshIndicatorTriggerMode.onEdge,
|
||||||
|
// 触发模式
|
||||||
|
|
||||||
|
// 描边宽度
|
||||||
|
strokeWidth: 2.5,
|
||||||
|
// 刷新指示器的描边宽度
|
||||||
|
|
||||||
|
// 语义标签(用于无障碍功能)
|
||||||
|
semanticsLabel: '下拉刷新设备列表',
|
||||||
|
semanticsValue: '刷新中...',
|
||||||
|
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
physics: const AlwaysScrollableScrollPhysics(
|
||||||
|
// 控制滚动物理特性
|
||||||
|
parent: BouncingScrollPhysics(), // 添加弹性滚动效果
|
||||||
|
),
|
||||||
|
child: ConstrainedBox(
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
minHeight: MediaQuery.of(Get.context!).size.height -
|
||||||
|
MediaQuery.of(Get.context!).padding.top -
|
||||||
|
kToolbarHeight -
|
||||||
|
60.h, // 减去AppBar高度、状态栏高度和底部提示区域高度
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
_buildDeviceList(),
|
||||||
|
SizedBox(height: 16.h),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新方法
|
||||||
|
Future<void> _onRefresh() async {
|
||||||
|
// 调用controller的刷新方法
|
||||||
|
await controller.refreshDevices();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建设备列表
|
||||||
|
_buildDeviceList() {
|
||||||
|
return Obx(
|
||||||
|
() => Column(
|
||||||
|
children: [
|
||||||
|
// 动态生成设备列表项
|
||||||
|
...controller.deviceList.asMap().entries.map((entry) {
|
||||||
|
int index = entry.key;
|
||||||
|
var device = entry.value;
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
// 如果是第一项,显示间距
|
||||||
|
if (index == 0) SizedBox(height: 10.h),
|
||||||
|
_buildItem(device: device, index: index),
|
||||||
|
// 如果不是最后一项,显示间距
|
||||||
|
if (index < controller.deviceList.length - 1)
|
||||||
|
SizedBox(height: 10.h),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建底部提示信息
|
||||||
|
_buildDeviceTip() {
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.h),
|
||||||
|
child: Text(
|
||||||
|
'没有更多设备',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Colors.grey[500],
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_buildItem({required device, required int index}) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
controller.connectingDevices();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 10.w),
|
||||||
|
padding: EdgeInsets.all(10.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(8.r),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Icon(
|
||||||
|
Icons.lock,
|
||||||
|
color: Colors.blue,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 8.w,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
device.name,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Colors.black87,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
// 处理添加设备事件
|
||||||
|
print('添加设备 ${device.name}');
|
||||||
|
// 这里可以添加具体的添加设备逻辑
|
||||||
|
},
|
||||||
|
child: const Icon(
|
||||||
|
Icons.add,
|
||||||
|
color: Colors.blue,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,13 +1,16 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.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 'package:starwork_flutter/routes/app_routes.dart';
|
||||||
|
|
||||||
class HomeTeamNoticeRowWidget extends StatefulWidget {
|
class HomeTeamNoticeRowWidget extends StatefulWidget {
|
||||||
const HomeTeamNoticeRowWidget({super.key});
|
const HomeTeamNoticeRowWidget({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<HomeTeamNoticeRowWidget> createState() => _HomeTeamNoticeRowWidgetState();
|
State<HomeTeamNoticeRowWidget> createState() =>
|
||||||
|
_HomeTeamNoticeRowWidgetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _HomeTeamNoticeRowWidgetState extends State<HomeTeamNoticeRowWidget> {
|
class _HomeTeamNoticeRowWidgetState extends State<HomeTeamNoticeRowWidget> {
|
||||||
@ -67,32 +70,37 @@ class _HomeTeamNoticeRowWidgetState extends State<HomeTeamNoticeRowWidget> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Row(
|
GestureDetector(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
onTap: () {
|
||||||
children: [
|
Get.toNamed(AppRoutes.teamNotice);
|
||||||
RichText(
|
},
|
||||||
text: TextSpan(
|
child: Row(
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
TextSpan(
|
children: [
|
||||||
text: '全部'.tr,
|
RichText(
|
||||||
style: TextStyle(
|
text: TextSpan(
|
||||||
color: Colors.grey,
|
children: [
|
||||||
fontSize: 14.sp,
|
TextSpan(
|
||||||
fontWeight: FontWeight.w400,
|
text: '全部'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.grey,
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
SizedBox(
|
||||||
SizedBox(
|
width: 4.w,
|
||||||
width: 4.w,
|
),
|
||||||
),
|
Icon(
|
||||||
Icon(
|
Icons.arrow_forward_ios_rounded,
|
||||||
Icons.arrow_forward_ios_rounded,
|
color: Colors.grey,
|
||||||
color: Colors.grey,
|
size: 12.sp,
|
||||||
size: 12.sp,
|
)
|
||||||
)
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@ -0,0 +1,10 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/views/main/teamNotice/teamNoticeDetails/team_notice_details_controller.dart';
|
||||||
|
|
||||||
|
class TeamNoticeDetailsBinding extends Bindings{
|
||||||
|
@override
|
||||||
|
void dependencies() {
|
||||||
|
Get.lazyPut<TeamNoticeDetailsController>(() => TeamNoticeDetailsController());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
import 'package:starwork_flutter/base/base_controller.dart';
|
||||||
|
|
||||||
|
class TeamNoticeDetailsController extends BaseController{}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
import 'package:flutter/src/widgets/framework.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/views/main/teamNotice/teamNoticeDetails/team_notice_details_controller.dart';
|
||||||
|
|
||||||
|
class TeamNoticeDetailsView extends GetView<TeamNoticeDetailsController> {
|
||||||
|
const TeamNoticeDetailsView({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// TODO: implement build
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
9
lib/views/main/teamNotice/team_notice_binding.dart
Normal file
9
lib/views/main/teamNotice/team_notice_binding.dart
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/views/main/teamNotice/team_notice_controller.dart';
|
||||||
|
|
||||||
|
class TeamNoticeBinding extends Bindings {
|
||||||
|
@override
|
||||||
|
void dependencies() {
|
||||||
|
Get.lazyPut<TeamNoticeController>(() => TeamNoticeController());
|
||||||
|
}
|
||||||
|
}
|
||||||
27
lib/views/main/teamNotice/team_notice_controller.dart
Normal file
27
lib/views/main/teamNotice/team_notice_controller.dart
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get_state_manager/src/rx_flutter/rx_ticket_provider_mixin.dart';
|
||||||
|
import 'package:starwork_flutter/base/base_controller.dart';
|
||||||
|
|
||||||
|
class TeamNoticeController extends BaseController
|
||||||
|
with GetSingleTickerProviderStateMixin {
|
||||||
|
late TabController tabController;
|
||||||
|
|
||||||
|
// TabBar选项列表
|
||||||
|
final List<String> functionOptionList = ['公告管理', '公告栏'];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
super.onInit();
|
||||||
|
// 初始化TabController
|
||||||
|
tabController = TabController(
|
||||||
|
length: functionOptionList.length,
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onClose() {
|
||||||
|
tabController.dispose();
|
||||||
|
super.onClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
405
lib/views/main/teamNotice/team_notice_view.dart
Normal file
405
lib/views/main/teamNotice/team_notice_view.dart
Normal file
@ -0,0 +1,405 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/common/constant/app_colors.dart';
|
||||||
|
import 'package:starwork_flutter/views/main/teamNotice/team_notice_controller.dart';
|
||||||
|
|
||||||
|
class TeamNoticeView extends GetView<TeamNoticeController> {
|
||||||
|
const TeamNoticeView({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
elevation: 0,
|
||||||
|
surfaceTintColor: Colors.transparent,
|
||||||
|
shadowColor: Colors.transparent,
|
||||||
|
scrolledUnderElevation: 0,
|
||||||
|
leading: null,
|
||||||
|
automaticallyImplyLeading: false,
|
||||||
|
title: Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'公告'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black87,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
TabBar(
|
||||||
|
controller: controller.tabController,
|
||||||
|
isScrollable: false,
|
||||||
|
// 改为false让TabBar占满宽度
|
||||||
|
labelColor: Colors.blue,
|
||||||
|
// 选中文字颜色改为蓝色
|
||||||
|
unselectedLabelColor: Colors.grey,
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
unselectedLabelStyle: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
indicatorColor: Colors.blue,
|
||||||
|
// 下划线颜色改为蓝色
|
||||||
|
indicatorWeight: 2.h,
|
||||||
|
// 稍微增加下划线粗细
|
||||||
|
indicatorSize: TabBarIndicatorSize.tab,
|
||||||
|
// 改为tab让指示器占满每个选项卡宽度
|
||||||
|
dividerColor: Colors.transparent,
|
||||||
|
tabs: controller.functionOptionList
|
||||||
|
.map((title) => Tab(text: title))
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: TabBarView(
|
||||||
|
controller: controller.tabController,
|
||||||
|
children: [
|
||||||
|
_buildNoticeManagementPage(),
|
||||||
|
_buildNoticeBoardPage(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 构建公告管理页面
|
||||||
|
Widget _buildNoticeManagementPage() {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: AppColors.scaffoldBackgroundColor,
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
// 列表区域(可滚动)
|
||||||
|
Expanded(
|
||||||
|
child: _buildNoticeManageList(),
|
||||||
|
),
|
||||||
|
// 底部按钮(固定)
|
||||||
|
_buildBottomButtons(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 构建公告管理列表
|
||||||
|
Widget _buildNoticeManageList() {
|
||||||
|
return RefreshIndicator(
|
||||||
|
onRefresh: () async {
|
||||||
|
// 模拟下拉刷新
|
||||||
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
|
Get.snackbar('提示', '刷新成功');
|
||||||
|
},
|
||||||
|
color: Colors.blue,
|
||||||
|
displacement: 60.0,
|
||||||
|
child: ListView.separated(
|
||||||
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 16.w,
|
||||||
|
vertical: 16.h,
|
||||||
|
),
|
||||||
|
itemCount: 8,
|
||||||
|
// 模拟8条记录
|
||||||
|
separatorBuilder: (context, index) => SizedBox(height: 12.h),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return _buildNoticeManageListItem();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 构建底部按钮区域
|
||||||
|
Widget _buildBottomButtons() {
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.all(16.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey.withOpacity(0.1),
|
||||||
|
spreadRadius: 0,
|
||||||
|
blurRadius: 4,
|
||||||
|
offset: const Offset(0, -2),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
// 草稿箱按钮
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: OutlinedButton(
|
||||||
|
onPressed: () {
|
||||||
|
// 草稿箱功能
|
||||||
|
Get.snackbar('提示', '保存到草稿箱');
|
||||||
|
},
|
||||||
|
style: OutlinedButton.styleFrom(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 12.h),
|
||||||
|
side: BorderSide(color: Colors.grey[300]!),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'草稿箱',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Colors.grey[700],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(width: 12.w),
|
||||||
|
|
||||||
|
// 发布公告按钮
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
// 发布公告功能
|
||||||
|
Get.snackbar('提示', '公告发布成功');
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.blue,
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 12.h),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
elevation: 0,
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'发布公告',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Colors.white,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 构建公告栏页面
|
||||||
|
Widget _buildNoticeBoardPage() {
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.all(16.w),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'公告栏',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.black87,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 16.h),
|
||||||
|
Expanded(
|
||||||
|
child: ListView.builder(
|
||||||
|
itemCount: 5, // 模拟5条公告
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Container(
|
||||||
|
margin: EdgeInsets.only(bottom: 12.h),
|
||||||
|
padding: EdgeInsets.all(16.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey.withOpacity(0.1),
|
||||||
|
spreadRadius: 1,
|
||||||
|
blurRadius: 3,
|
||||||
|
offset: const Offset(0, 1),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 8.w,
|
||||||
|
vertical: 4.h,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.red[50],
|
||||||
|
borderRadius: BorderRadius.circular(4.r),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'重要',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Colors.red,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 8.w),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'公告标题 ${index + 1}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.black87,
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 8.h),
|
||||||
|
Text(
|
||||||
|
'这里是公告的详细内容,包含了重要的信息和通知事项。请各位同事仔细阅读并遵照执行。',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.grey[700],
|
||||||
|
height: 1.5,
|
||||||
|
),
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
SizedBox(height: 12.h),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'2024-01-${15 + index}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Colors.grey[500],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.visibility_outlined,
|
||||||
|
size: 16.w,
|
||||||
|
color: Colors.grey[500],
|
||||||
|
),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
Text(
|
||||||
|
'${(index + 1) * 23}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Colors.grey[500],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_buildNoticeManageListItem() {
|
||||||
|
return Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 10.w,
|
||||||
|
vertical: 10.h,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 0.8.sw, // 限制最大宽度
|
||||||
|
child: Text(
|
||||||
|
'1',
|
||||||
|
maxLines: 1, // 限制为一行
|
||||||
|
overflow: TextOverflow.ellipsis, // 超出部分显示省略号
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 24.sp,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.black87,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 4.h,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 0.8.sw, // 限制最大宽度
|
||||||
|
child: Text(
|
||||||
|
'112312',
|
||||||
|
maxLines: 3, // 限制为一行
|
||||||
|
overflow: TextOverflow.ellipsis, // 超出部分显示省略号
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Colors.black87,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 4.h,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'HHMMail 30015524 2024-12-17',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
right: 0.w,
|
||||||
|
top: 0.h,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 4.w, vertical: 4.h),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
bottomLeft: Radius.circular(8.r),
|
||||||
|
topRight: Radius.circular(8.r),
|
||||||
|
),
|
||||||
|
color: Colors.grey[300],
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'已撤回'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.sp,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
79
pubspec.lock
79
pubspec.lock
@ -25,6 +25,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.11.0"
|
version: "2.11.0"
|
||||||
|
bluez:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: bluez
|
||||||
|
sha256: "61a7204381925896a374301498f2f5399e59827c6498ae1e924aaa598751b545"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.8.3"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -89,6 +97,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.8"
|
version: "1.0.8"
|
||||||
|
dbus:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: dbus
|
||||||
|
sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.11"
|
||||||
dio:
|
dio:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -134,6 +150,54 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_blue_plus:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_blue_plus
|
||||||
|
sha256: bfae0d24619940516261045d8b3c74b4c80ca82222426e05ffbf7f3ea9dbfb1a
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.35.5"
|
||||||
|
flutter_blue_plus_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_blue_plus_android
|
||||||
|
sha256: "9723dd4ba7dcc3f27f8202e1159a302eb4cdb88ae482bb8e0dd733b82230a258"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.5"
|
||||||
|
flutter_blue_plus_darwin:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_blue_plus_darwin
|
||||||
|
sha256: f34123795352a9761e321589aa06356d3b53f007f13f7e23e3c940e733259b2d
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.1"
|
||||||
|
flutter_blue_plus_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_blue_plus_linux
|
||||||
|
sha256: "635443d1d333e3695733fd70e81ee0d87fa41e78aa81844103d2a8a854b0d593"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.2"
|
||||||
|
flutter_blue_plus_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_blue_plus_platform_interface
|
||||||
|
sha256: a4bb70fa6fd09e0be163b004d773bf19e31104e257a4eb846b67f884ddd87de2
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.2"
|
||||||
|
flutter_blue_plus_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_blue_plus_web
|
||||||
|
sha256: "03023c259dbbba1bc5ce0fcd4e88b364f43eec01d45425f393023b9b2722cf4d"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.1"
|
||||||
flutter_easyloading:
|
flutter_easyloading:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -421,6 +485,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.3"
|
version: "6.0.3"
|
||||||
|
rxdart:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: rxdart
|
||||||
|
sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.28.0"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -506,6 +578,13 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.1"
|
version: "1.11.1"
|
||||||
|
starcloud:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "../starcloud-sdk-flutter"
|
||||||
|
relative: true
|
||||||
|
source: path
|
||||||
|
version: "0.1.2"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@ -36,6 +36,9 @@ dependencies:
|
|||||||
carousel_slider: ^5.1.1
|
carousel_slider: ^5.1.1
|
||||||
# 气泡提示框
|
# 气泡提示框
|
||||||
super_tooltip: ^2.0.8
|
super_tooltip: ^2.0.8
|
||||||
|
# 星云flutter SDK
|
||||||
|
starcloud:
|
||||||
|
path: ../starcloud-sdk-flutter
|
||||||
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user