feat: 增加搜索设备页、团队管理页

This commit is contained in:
liyi 2025-09-05 09:20:35 +08:00
parent 8501b5ea48
commit 5bca96a4cf
21 changed files with 1017 additions and 42 deletions

View File

@ -39,6 +39,10 @@ class _AppState extends State<App> {
dialogBackgroundColor: Colors.white,
appBarTheme: AppBarTheme(
backgroundColor: Colors.white,
elevation: 0,
surfaceTintColor: Colors.transparent,
shadowColor: Colors.transparent,
scrolledUnderElevation: 0,
)),
//
localizationsDelegates: const [

View File

@ -4,12 +4,11 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.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/service/common_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/i18n/app_i18n.dart';
import 'package:starwork_flutter/views/login/login_controller.dart';
import 'package:starwork_flutter/views/main/main_controller.dart';
@ -20,7 +19,7 @@ class AppInitialization {
setSystemStatusBar();
await SharedPreferencesUtils.init();
initEasyLoading();
StarCloudSDK.init(clientId: 'clientId', clientSecret: 'clientSecret');
Get.put(BaseApiService());
Get.put(CommonApiService(Get.find<BaseApiService>()));
Get.put(UserApiService(Get.find<BaseApiService>()));

View File

@ -0,0 +1,5 @@
import 'dart:ui';
class AppColors {
static Color scaffoldBackgroundColor = const Color(0xFFF6F7FB);
}

View 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;
}

View File

@ -1,5 +1,7 @@
import 'package:get/get.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_view.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/main/main_binding.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_view.dart';
import 'package:starwork_flutter/views/mine/mine_binding.dart';
@ -67,5 +73,20 @@ class AppPages {
page: () => const SearchDeviceView(),
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(),
),
];
}

View File

@ -9,4 +9,7 @@ class AppRoutes{
static const String forgotPassword = '/forgotPassword';
static const String setNewPassword = '/setNewPassword';
static const String searchDevice = '/searchDevice';
static const String confirmPairDevice = '/confirmPairDevice';
static const String teamNotice = '/teamNotice';
static const String teamNoticeDetails = '/teamNoticeDetails';
}

View File

@ -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());
}
}

View File

@ -0,0 +1,5 @@
import 'package:starwork_flutter/base/base_controller.dart';
class ConfirmPairDeviceController extends BaseController{
}

View 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,
),
),
)
],
),
),
);
}
}

View File

@ -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: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/routes/app_routes.dart';
import 'package:starwork_flutter/views/device/searchDevice/search_device_model.dart';
class SearchDeviceController extends BaseController {
//
final RxBool _isSearching = false.obs;
//
final RxList<SearchDeviceItem> deviceList = <SearchDeviceItem>[].obs;
// Getter
bool get isSearching => _isSearching.value;
@override
void onInit() async {
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);
}
}

View 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,
});
}

View File

@ -12,12 +12,18 @@ class SearchDeviceView extends GetView<SearchDeviceController> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFF6F7FB),
appBar: AppBar(
title: Row(
children: [
Obx(() => Text(
controller.isSearching ? '搜索设备中'.tr : '搜索设备'.tr,
)),
Text(
'搜索设备中'.tr,
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.w500,
color: Colors.black87,
),
),
SizedBox(
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(
// TODO:
child: Center(
child: Text('设备搜索页面'),
body: Column(
children: [
//
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,
),
)
],
),
),
);

View File

@ -1,13 +1,16 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:starwork_flutter/routes/app_routes.dart';
class HomeTeamNoticeRowWidget extends StatefulWidget {
const HomeTeamNoticeRowWidget({super.key});
@override
State<HomeTeamNoticeRowWidget> createState() => _HomeTeamNoticeRowWidgetState();
State<HomeTeamNoticeRowWidget> createState() =>
_HomeTeamNoticeRowWidgetState();
}
class _HomeTeamNoticeRowWidgetState extends State<HomeTeamNoticeRowWidget> {
@ -67,32 +70,37 @@ class _HomeTeamNoticeRowWidgetState extends State<HomeTeamNoticeRowWidget> {
],
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
RichText(
text: TextSpan(
children: [
TextSpan(
text: '全部'.tr,
style: TextStyle(
color: Colors.grey,
fontSize: 14.sp,
fontWeight: FontWeight.w400,
GestureDetector(
onTap: () {
Get.toNamed(AppRoutes.teamNotice);
},
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
RichText(
text: TextSpan(
children: [
TextSpan(
text: '全部'.tr,
style: TextStyle(
color: Colors.grey,
fontSize: 14.sp,
fontWeight: FontWeight.w400,
),
),
),
],
],
),
),
),
SizedBox(
width: 4.w,
),
Icon(
Icons.arrow_forward_ios_rounded,
color: Colors.grey,
size: 12.sp,
)
],
SizedBox(
width: 4.w,
),
Icon(
Icons.arrow_forward_ios_rounded,
color: Colors.grey,
size: 12.sp,
)
],
),
),
],
),

View File

@ -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());
}
}

View File

@ -0,0 +1,3 @@
import 'package:starwork_flutter/base/base_controller.dart';
class TeamNoticeDetailsController extends BaseController{}

View File

@ -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();
}
}

View 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());
}
}

View 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();
}
}

View 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,
),
),
),
)
],
);
}
}

View File

@ -25,6 +25,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
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:
dependency: transitive
description:
@ -89,6 +97,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
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:
dependency: "direct main"
description:
@ -134,6 +150,54 @@ packages:
description: flutter
source: sdk
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:
dependency: "direct main"
description:
@ -421,6 +485,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
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:
dependency: "direct main"
description:
@ -506,6 +578,13 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.11.1"
starcloud:
dependency: "direct main"
description:
path: "../starcloud-sdk-flutter"
relative: true
source: path
version: "0.1.2"
stream_channel:
dependency: transitive
description:

View File

@ -36,6 +36,9 @@ dependencies:
carousel_slider: ^5.1.1
# 气泡提示框
super_tooltip: ^2.0.8
# 星云flutter SDK
starcloud:
path: ../starcloud-sdk-flutter
dev_dependencies: