diff --git a/lib/apis/api.dart b/lib/apis/api.dart index 7aac115..7ca0889 100644 --- a/lib/apis/api.dart +++ b/lib/apis/api.dart @@ -15,6 +15,11 @@ class Api { ); } + /// 获取权限资源 + static Future getResources() { + return DioService.dio.get(Urls.accountResources); + } + /// 获取分页角色列表 static Future> getRoles(Map params) { return DioService.dio.get(Urls.roles, diff --git a/lib/app_theme.dart b/lib/app_theme.dart index 80f9ec8..70506b6 100644 --- a/lib/app_theme.dart +++ b/lib/app_theme.dart @@ -27,7 +27,7 @@ class AppTheme { static const Color dividerColor = Color.fromARGB(255, 224, 224, 224); static const Color appbarBgColor = AppTheme.primaryColor; static const Color scaffoldBackgroundColor = Color(0XFFe9f0fd); - static const Color inputFillColor = Color(0xFFf5f8ff); + static const Color inputFillColor = Color(0xfffefefe); } final theme = ThemeData( @@ -48,17 +48,29 @@ final theme = ThemeData( fontFamily: AppTheme.fontName, textButtonTheme: TextButtonThemeData( style: ButtonStyle( + textStyle: MaterialStateProperty.all(TextStyle( + fontSize: ScreenAdaper.height(26), + )), // 设置文本样式为白色 foregroundColor: MaterialStateProperty.all(AppTheme.primaryColor), // 设置文本颜色为红色 )), - floatingActionButtonTheme: FloatingActionButtonThemeData( + floatingActionButtonTheme: const FloatingActionButtonThemeData( backgroundColor: AppTheme.primaryColorLight, ), + dialogTheme: const DialogTheme( + elevation: 0.2, + backgroundColor: AppTheme.nearlyWhite, + ), + dialogBackgroundColor: AppTheme.nearlyWhite, + colorScheme: ColorScheme.fromSeed( + onPrimary: AppTheme.nearlyWhite, + seedColor: AppTheme.primaryColor, + primary: AppTheme.primaryColor), datePickerTheme: DatePickerThemeData( confirmButtonStyle: ButtonStyle( textStyle: MaterialStateProperty.resolveWith( (Set states) { - return const TextStyle(color: AppTheme.primaryColor); + return TextStyle(color: AppTheme.primaryColor); }, ), ), @@ -84,6 +96,7 @@ final theme = ThemeData( visualDensity: VisualDensity.adaptivePlatformDensity, primaryColor: AppTheme.primaryColor, primaryColorDark: AppTheme.primaryColorDark, + textTheme: TextTheme(bodySmall: TextStyle(fontSize: ScreenAdaper.height(26))), progressIndicatorTheme: const ProgressIndicatorThemeData(color: AppTheme.primaryColor), dividerColor: AppTheme.dividerColor, diff --git a/lib/constants/global_url.dart b/lib/constants/global_url.dart index 247a839..4f4e398 100644 --- a/lib/constants/global_url.dart +++ b/lib/constants/global_url.dart @@ -14,7 +14,7 @@ class Urls { static String getDictType = 'system/dict-type/all'; static String uploadAttachemnt = 'tools/upload'; static String systemParamConfig = 'system/param-config'; - static String accountMenus = 'account/menus'; + static String accountResources = 'account/menus'; static String depts = 'system/depts'; static String roles = 'system/roles'; } diff --git a/lib/constants/router.dart b/lib/constants/router.dart index ae8675c..4ddbfde 100644 --- a/lib/constants/router.dart +++ b/lib/constants/router.dart @@ -14,8 +14,8 @@ class RouteConfig { static const String login = '/login'; static const String userinfo = '/userinfo'; static const String inventory = '/inventory'; - static const String saleQuotation = '/sale_quotation'; - static const String hrManage = '/hr_manage'; + static const String saleQuotation = '/workbench/sale_quotation'; + static const String hrManage = '/workbench/hr_manage'; static const String employeeDetail = '/employee_detail'; static final List getPages = [ diff --git a/lib/global.dart b/lib/global.dart index 9da3c04..3647ea3 100644 --- a/lib/global.dart +++ b/lib/global.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:sk_base_mobile/store/dict.store.dart'; +import 'package:sk_base_mobile/store/resource.store.dart'; import 'package:sk_base_mobile/util/loading_util.dart'; import 'package:timeago/timeago.dart' as timeago; import 'package:sk_base_mobile/constants/cache_key.dart'; @@ -48,6 +49,9 @@ class Global { /// 依赖注入字典信息 await Get.putAsync(() => DictService().init()); + /// 依赖注入资源信息 + await Get.putAsync(() => ResourceService().init()); + if (StorageService.to.getString(CacheKeys.token, isWithUser: false) != null) { /// 这里做一些缓存初始化后的操作 diff --git a/lib/index.dart b/lib/index.dart index cda9f95..3217f6c 100644 --- a/lib/index.dart +++ b/lib/index.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:sk_base_mobile/config.dart'; @@ -31,7 +32,16 @@ class IndexPage extends StatelessWidget { maxOverScrollExtent: 80, footerTriggerDistance: 150, child: GetMaterialApp( - theme: theme, + locale: const Locale('zh', 'CN'), // 设置为中文 + localizationsDelegates: const [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, // 添加这一行 + ], + supportedLocales: const [ + Locale('zh', 'CN'), // 支持的语言 + ], + theme: _getAppTheme(), title: GloablConfig.DOMAIN_NAME, getPages: RouteConfig.getPages, initialRoute: getInitialRoute(), @@ -55,4 +65,8 @@ class IndexPage extends StatelessWidget { bool isLogined = token != null; return isLogined ? RouteConfig.home : RouteConfig.login; } + + ThemeData _getAppTheme() { + return theme; + } } diff --git a/lib/models/resource.model.dart b/lib/models/resource.model.dart new file mode 100644 index 0000000..1e2332b --- /dev/null +++ b/lib/models/resource.model.dart @@ -0,0 +1,98 @@ +class ResourceModel { + ResourceModel({ + required this.id, + required this.path, + required this.component, + required this.name, + required this.meta, + required this.redirect, + required this.children, + }); + + final int? id; + final String? path; + final String? component; + final String? name; + final Meta? meta; + final String? redirect; + final List children; + + factory ResourceModel.fromJson(Map json) { + return ResourceModel( + id: json["id"], + path: json["path"], + component: json["component"], + name: json["name"], + meta: json["meta"] == null ? null : Meta.fromJson(json["meta"]), + redirect: json["redirect"], + children: json["children"] == null + ? [] + : List.from( + json["children"]!.map((x) => ResourceModel.fromJson(x))), + ); + } + + Map toJson() => { + "id": id, + "path": path, + "component": component, + "name": name, + "meta": meta?.toJson(), + "redirect": redirect, + "children": children.map((x) => x?.toJson()).toList(), + }; +} + +class Meta { + Meta({ + required this.title, + required this.icon, + required this.isExt, + required this.extOpenMode, + required this.type, + required this.orderNo, + required this.show, + required this.activeMenu, + required this.status, + required this.keepAlive, + }); + + final String? title; + final String? icon; + final bool? isExt; + final int? extOpenMode; + final int? type; + final int? orderNo; + final int? show; + final String? activeMenu; + final int? status; + final int? keepAlive; + + factory Meta.fromJson(Map json) { + return Meta( + title: json["title"], + icon: json["icon"], + isExt: json["isExt"], + extOpenMode: json["extOpenMode"], + type: json["type"], + orderNo: json["orderNo"], + show: json["show"], + activeMenu: json["activeMenu"], + status: json["status"], + keepAlive: json["keepAlive"], + ); + } + + Map toJson() => { + "title": title, + "icon": icon, + "isExt": isExt, + "extOpenMode": extOpenMode, + "type": type, + "orderNo": orderNo, + "show": show, + "activeMenu": activeMenu, + "status": status, + "keepAlive": keepAlive, + }; +} diff --git a/lib/screens/hr_manage/components/edit_userinfo.dart b/lib/screens/hr_manage/components/edit_userinfo.dart index 9fbfa21..759134c 100644 --- a/lib/screens/hr_manage/components/edit_userinfo.dart +++ b/lib/screens/hr_manage/components/edit_userinfo.dart @@ -194,7 +194,7 @@ class EditUserInfo extends StatelessWidget { image: controller.filePath.value.isNotEmpty ? FileImage(File(controller.filePath.value)) : NetworkImage(MediaUtil.getMediaUrl( - controller.userInfo.value!.avatar!)) + controller.userInfo.value.avatar)) as ImageProvider), )), ), diff --git a/lib/screens/hr_manage/components/employee_detail.dart b/lib/screens/hr_manage/components/employee_detail.dart index 74e165e..b82eb4c 100644 --- a/lib/screens/hr_manage/components/employee_detail.dart +++ b/lib/screens/hr_manage/components/employee_detail.dart @@ -7,6 +7,7 @@ import 'package:sk_base_mobile/constants/bg_color.dart'; import 'package:sk_base_mobile/models/user_info.model.dart'; import 'package:sk_base_mobile/screens/inventory_inout/components/responsive.dart'; import 'package:sk_base_mobile/util/screen_adaper_util.dart'; +import 'package:sk_base_mobile/widgets/core/sk_avatar.dart'; import 'package:sk_base_mobile/widgets/core/sk_tag.dart'; import 'package:sk_base_mobile/widgets/fade_in_cache_image.dart'; import 'package:sk_base_mobile/widgets/core/sk_appbar.dart'; @@ -44,13 +45,7 @@ class EmployeeDetail extends StatelessWidget { color: AppTheme.white, child: Row( children: [ - ClipRRect( - borderRadius: const BorderRadius.all(Radius.circular(30)), - child: FadeInCacheImage( - height: ScreenAdaper.height(80), - width: ScreenAdaper.height(80), - url: '${GloablConfig.OSS_URL}${userInfo.avatar}'), - ), + SkAvatar(url: userInfo.avatar), SizedBox( width: ScreenAdaper.width(defaultPadding), ), diff --git a/lib/screens/hr_manage/hr_manage.dart b/lib/screens/hr_manage/hr_manage.dart index b0afc81..6a7baed 100644 --- a/lib/screens/hr_manage/hr_manage.dart +++ b/lib/screens/hr_manage/hr_manage.dart @@ -13,8 +13,10 @@ import 'package:sk_base_mobile/util/debouncer.dart'; import 'package:sk_base_mobile/util/device.util.dart'; import 'package:sk_base_mobile/util/media_util.dart'; import 'package:sk_base_mobile/util/modal.util.dart'; +import 'package:sk_base_mobile/util/router.util.dart'; import 'package:sk_base_mobile/util/screen_adaper_util.dart'; import 'package:sk_base_mobile/util/snack_bar.util.dart'; +import 'package:sk_base_mobile/widgets/core/sk_avatar.dart'; import 'package:sk_base_mobile/widgets/core/sk_ink.dart'; import 'package:sk_base_mobile/widgets/core/sk_tag.dart'; import 'package:sk_base_mobile/widgets/form_item/sk_text_input.dart'; @@ -149,7 +151,7 @@ class HrManagePage extends StatelessWidget { Widget buildUserCard(int index) { return SkInk( onTap: () { - Get.toNamed(RouteConfig.employeeDetail, + RouterUtil.toNamed(RouteConfig.employeeDetail, arguments: controller.list[index]); }, margin: EdgeInsets.only(bottom: ScreenAdaper.height(defaultPadding)), @@ -163,14 +165,7 @@ class HrManagePage extends StatelessWidget { Row( children: [ // 头像 - ClipRRect( - borderRadius: const BorderRadius.all(Radius.circular(30)), - child: FadeInCacheImage( - height: ScreenAdaper.height(80), - width: ScreenAdaper.height(80), - url: - MediaUtil.getMediaUrl(controller.list[index].avatar)), - ), + SkAvatar(url: controller.list[index].avatar), SizedBox( width: ScreenAdaper.height(defaultPadding), ), diff --git a/lib/screens/new_inventory_inout/new_inventory_inout.dart b/lib/screens/new_inventory_inout/new_inventory_inout.dart index 58dc7ae..1a7b261 100644 --- a/lib/screens/new_inventory_inout/new_inventory_inout.dart +++ b/lib/screens/new_inventory_inout/new_inventory_inout.dart @@ -13,6 +13,7 @@ import 'package:sk_base_mobile/screens/new_inventory_inout/components/inventory_ import 'package:sk_base_mobile/screens/new_inventory_inout/components/product_search.dart'; import 'package:sk_base_mobile/store/dict.store.dart'; import 'package:sk_base_mobile/util/util.dart'; +import 'package:sk_base_mobile/widgets/form_item/sk_datetime_picker.dart'; import 'package:sk_base_mobile/widgets/form_item/sk_number_input.dart'; import 'package:sk_base_mobile/widgets/form_item/sk_search_select.dart'; import 'package:sk_base_mobile/widgets/form_item/sk_date_picker.dart'; @@ -75,28 +76,35 @@ class NewInventoryInout extends StatelessWidget { SizedBox( height: ScreenAdaper.height(formVerticalGap), ), - Row( - children: [ - if (inOrOut == InventoryInOrOutEnum.In) ...[ + if (inOrOut == InventoryInOrOutEnum.In) ...[ + Row( + children: [ Expanded(flex: 1, child: buildUnitPrice()), SizedBox( width: ScreenAdaper.width(formHorizontalGap), ), Expanded(flex: 1, child: buildAmount()) ], - ], - ), - SizedBox( - height: ScreenAdaper.height(formVerticalGap), - ), - // buildDatePicker(), - // SizedBox( - // height: ScreenAdaper.height(formVerticalGap), - // ), - buildAgent(), - SizedBox( - height: ScreenAdaper.height(formVerticalGap), - ), + ), + SizedBox( + height: ScreenAdaper.height(formVerticalGap), + ), + ], + if (inOrOut == InventoryInOrOutEnum.In) ...[ + Row( + children: [ + Expanded(child: buildDatePicker()), + SizedBox( + width: ScreenAdaper.width(formHorizontalGap), + ), + Expanded(child: buildAgent()), + ], + ), + SizedBox( + height: ScreenAdaper.height(formVerticalGap), + ), + ], + if (inOrOut == InventoryInOrOutEnum.Out) buildAgent(), if (inOrOut == InventoryInOrOutEnum.In) buildPositionBottomPicker(), SizedBox( height: ScreenAdaper.height(formVerticalGap), @@ -281,15 +289,16 @@ class NewInventoryInout extends StatelessWidget { /// 时间 Widget buildDatePicker() { - return SkDatePicker( + return SkDateTimePicker( + initialDate: DateTime.tryParse('${controller.payload['time'] ?? ''}'), textController: controller.dateTextController, onClear: () { controller.payload.remove('time'); }, - onDateSelected: (date) { + onSelected: (date) { if (date != null) { controller.dateTextController.text = SkDateUtil.format(date); - controller.payload['time'] = controller.dateTextController.text; + controller.payload['time'] = date.millisecondsSinceEpoch; } }, ); diff --git a/lib/screens/new_inventory_inout/new_inventory_inout_controller.dart b/lib/screens/new_inventory_inout/new_inventory_inout_controller.dart index c7e9c99..c1d2b6d 100644 --- a/lib/screens/new_inventory_inout/new_inventory_inout_controller.dart +++ b/lib/screens/new_inventory_inout/new_inventory_inout_controller.dart @@ -75,7 +75,7 @@ class NewInventoryInoutController extends GetxController { onReady() { super.onReady(); dateTextController.text = SkDateUtil.format(DateTime.now()); - payload['time'] = SkDateUtil.format(DateTime.now()); + payload['time'] = DateTime.now().microsecondsSinceEpoch; payload['inOrOut'] = inOrOut; } @@ -128,29 +128,8 @@ class NewInventoryInoutController extends GetxController { ); return; } - // 暂时时间定位提交时间 - // if (payload['time'] == null) { - // SnackBarUtil().error( - // '时间不能为空', - // ); - // return; - // } - payload['time'] = SkDateUtil.format(DateTime.now(), formats: [ - 'yyyy', - '-', - 'mm', - '-', - 'dd', - ' ', - 'HH', - ':', - 'nn', - ":", - 'ss' - ]); payload['quantity'] = quantityTextController.text; - if (payload['quantity'].isEmpty || payload['quantity'] == '0') { SnackBarUtil().error( '数量必须大于1', @@ -186,11 +165,10 @@ class NewInventoryInoutController extends GetxController { } else { payload['amount'] = amountTextController.text; } - + payload['time'] = payload['time'] ?? DateTime.now().microsecondsSinceEpoch; payload['remark'] = remarkTextController.text; await LoadingUtil.to.show(status: '提交中请稍后...'); // uploadImgFilesPath - try { // final recordId = res.data as int; // 批量同时上传 diff --git a/lib/screens/workbench/workbench_controller.dart b/lib/screens/workbench/workbench_controller.dart index 1072994..e7ae3b0 100644 --- a/lib/screens/workbench/workbench_controller.dart +++ b/lib/screens/workbench/workbench_controller.dart @@ -1,4 +1,5 @@ import 'package:get/get.dart'; +import 'package:sk_base_mobile/constants/constants.dart'; import 'package:sk_base_mobile/models/workbench.model.dart'; class WorkBenchController extends GetxController { @@ -6,11 +7,13 @@ class WorkBenchController extends GetxController { WorkBenchModel(title: '库存', route: '/inventory', icon: 'inventory.svg'), WorkBenchModel(title: '产品', route: '/product', icon: 'product.svg'), WorkBenchModel(title: '合同', route: '/contract', icon: 'contract.svg'), - WorkBenchModel(title: '人事', route: '/hr_manage', icon: 'hr.svg'), + WorkBenchModel(title: '人事', route: RouteConfig.hrManage, icon: 'hr.svg'), WorkBenchModel(title: '公车', route: '/vehicle', icon: 'vehicle.svg'), WorkBenchModel(title: '任务', route: '/task_manage', icon: 'task_manage.svg'), WorkBenchModel(title: '报表', route: '/report', icon: 'report.svg'), WorkBenchModel( - title: '报价计算', route: '/sale_quotation', icon: 'sale_quotation.svg'), + title: '报价计算', + route: RouteConfig.saleQuotation, + icon: 'sale_quotation.svg'), ]; } diff --git a/lib/store/resource.store.dart b/lib/store/resource.store.dart new file mode 100644 index 0000000..abadbab --- /dev/null +++ b/lib/store/resource.store.dart @@ -0,0 +1,32 @@ +import 'package:get/get.dart'; +import 'package:sk_base_mobile/apis/api.dart'; +import 'package:sk_base_mobile/models/resource.model.dart'; +import 'package:sk_base_mobile/store/auth.store.dart'; +import 'package:sk_base_mobile/util/logger_util.dart'; + +class ResourceService extends GetxService { + static ResourceService get to => Get.find(); + Future init() async { + if (AuthStore.to.userInfo.value.id == null) return this; + + await getResources(); + return this; + } + + RxList resources = RxList([]); + Future getResources() async { + try { + final response = await Api.getResources(); + resources.value = (response.data as List) + .map((item) => ResourceModel.fromJson(item)) + .toList(); + } catch (e) { + LoggerUtil().error('getResources error: $e'); + } + } + + // List getDictItemsByCode(String code) { + // return dictTypes.firstWhereOrNull((item) => item.code == code)?.dictItems ?? + // []; + // } +} diff --git a/lib/util/router.util.dart b/lib/util/router.util.dart new file mode 100644 index 0000000..714ca27 --- /dev/null +++ b/lib/util/router.util.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +class RouterUtil { + static Future toNamed(String routeName, {arguments}) async { + //关闭键盘 + if (Get.context != null) { + FocusScope.of(Get.context!).requestFocus(FocusNode()); + } + return await Get.toNamed(routeName, arguments: arguments); + } +} diff --git a/lib/widgets/core/sk_avatar.dart b/lib/widgets/core/sk_avatar.dart new file mode 100644 index 0000000..fadb486 --- /dev/null +++ b/lib/widgets/core/sk_avatar.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; +import 'package:sk_base_mobile/app_theme.dart'; +import 'package:sk_base_mobile/util/media_util.dart'; +import 'package:sk_base_mobile/util/screen_adaper_util.dart'; +import 'package:sk_base_mobile/widgets/fade_in_cache_image.dart'; + +class SkAvatar extends StatelessWidget { + final String? url; + const SkAvatar({super.key, this.url}); + + @override + Widget build(BuildContext context) { + return ClipRRect( + borderRadius: const BorderRadius.all(Radius.circular(40)), + child: Container( + decoration: BoxDecoration( + border: Border.all(color: AppTheme.dividerColor), + borderRadius: const BorderRadius.all(Radius.circular(40))), + child: FadeInCacheImage( + defaultWidget: Icon(Icons.person_2_outlined, + size: ScreenAdaper.height(60), color: AppTheme.grey), + height: ScreenAdaper.height(80), + width: ScreenAdaper.height(80), + url: MediaUtil.getMediaUrl(url)), + ), + ); + } +} diff --git a/lib/widgets/fade_in_cache_image.dart b/lib/widgets/fade_in_cache_image.dart index 0326cf1..4acd7f2 100644 --- a/lib/widgets/fade_in_cache_image.dart +++ b/lib/widgets/fade_in_cache_image.dart @@ -11,11 +11,13 @@ class FadeInCacheImage extends StatefulWidget { final BoxFit? fit; final bool compress; final bool canFullscreen; + final Widget? defaultWidget; const FadeInCacheImage( {super.key, this.width, this.height, this.url, + this.defaultWidget, this.fit = BoxFit.cover, this.compress = false, this.canFullscreen = false}); @@ -78,9 +80,10 @@ class _FadeInCacheImageState extends State { alignment: Alignment.center, width: widget.width, height: widget.height, - child: Icon(Icons.image_not_supported, - size: ScreenAdaper.height((widget.width ?? 200)), - color: AppTheme.grey), + child: widget.defaultWidget ?? + Icon(Icons.image_not_supported, + size: ScreenAdaper.height((widget.width ?? 200)), + color: AppTheme.grey), ); } } diff --git a/lib/widgets/form_item/sk_datetime_picker.dart b/lib/widgets/form_item/sk_datetime_picker.dart new file mode 100644 index 0000000..5cd1eed --- /dev/null +++ b/lib/widgets/form_item/sk_datetime_picker.dart @@ -0,0 +1,114 @@ +import 'package:flutter/material.dart'; +import 'package:sk_base_mobile/app_theme.dart'; +import 'package:sk_base_mobile/util/screen_adaper_util.dart'; +import 'package:sk_datetime_picker/sk_datetime_picker.dart'; + +class SkDateTimePicker extends StatelessWidget { + final TextEditingController textController; + final VoidCallback? onClear; + final Function(DateTime?)? onSelected; + final bool isRequired; + final String labelText; + final DateTime? initialDate; + const SkDateTimePicker({ + super.key, + this.onClear, + this.onSelected, + this.initialDate, + this.labelText = '日期', + this.isRequired = false, + required this.textController, + }); + + @override + Widget build(BuildContext context) { + return TextFormField( + controller: textController, + onTapOutside: (event) { + FocusScope.of(context).unfocus(); + }, + decoration: InputDecoration( + floatingLabelBehavior: FloatingLabelBehavior.always, + prefixIcon: Icon( + Icons.date_range_outlined, + size: ScreenAdaper.height(40), + ), + suffixIcon: textController.text.isNotEmpty + ? IconButton( + icon: const Icon(Icons.clear), + // 当点击这个按钮时,清除TextFormField的值 + onPressed: () { + textController.clear(); + if (onClear != null) { + onClear!(); + } + }, + ) + : const SizedBox(), + hintText: '请选择', + label: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + if (isRequired) + Text( + "*", + style: TextStyle( + color: Colors.red, fontSize: ScreenAdaper.height(30)), + ), + Text( + labelText, + style: TextStyle(fontSize: ScreenAdaper.height(30)), + ), + ])), + keyboardType: TextInputType.none, + onTap: () async { + DateTime? dateTime = await showSkDateTimePicker( + theme: theme, + is24HourMode: true, + title: Container( + padding: EdgeInsets.symmetric(vertical: ScreenAdaper.height(10)), + child: Text( + '选择日期时间', + style: TextStyle(fontSize: ScreenAdaper.height(30)), + ), + ), + context: context, + initialDate: initialDate ?? DateTime.now(), + firstDate: DateTime(1600).subtract(const Duration(days: 3652)), + lastDate: DateTime.now().add( + const Duration(days: 3652), + ), + isForce2Digits: true, + isShowSeconds: false, + minutesInterval: 1, + secondsInterval: 1, + borderRadius: const BorderRadius.all(Radius.circular(16)), + constraints: const BoxConstraints( + maxWidth: 350, + maxHeight: 650, + ), + transitionBuilder: (context, anim1, anim2, child) { + return FadeTransition( + opacity: anim1.drive( + Tween( + begin: 0, + end: 1, + ), + ), + child: child, + ); + }, + transitionDuration: const Duration(milliseconds: 200), + barrierDismissible: true, + selectableDayPredicate: (dateTime) { + return true; + }, + ); + if (onSelected != null) { + onSelected!(dateTime); + } + }, + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index a180c01..024efae 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -334,6 +334,11 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" flutter_native_splash: dependency: "direct main" description: @@ -532,10 +537,10 @@ packages: dependency: transitive description: name: intl - sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" url: "https://pub.dev" source: hosted - version: "0.19.0" + version: "0.18.1" js: dependency: transitive description: @@ -896,6 +901,15 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.2" + sk_datetime_picker: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: "2a7073a2e7fee1ddf0ba67ce87ab2716de876e25" + url: "https://gitee.com/lu-zixun/sk-date-time-picker.git" + source: git + version: "1.0.9" sky_engine: dependency: transitive description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index e6be3f6..3f23455 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,7 +30,8 @@ environment: dependencies: flutter: sdk: flutter - + flutter_localizations: + sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 @@ -68,6 +69,11 @@ dependencies: math_expressions: ^2.4.0 install_plugin: ^2.1.0 url_launcher: ^6.2.5 + sk_datetime_picker: + git: + url: https://gitee.com/lu-zixun/sk-date-time-picker.git + # sk_datetime_picker: + # path: ./lib/widgets/common/datetime_picker dev_dependencies: flutter_test: sdk: flutter