diff --git a/android/app/build.gradle b/android/app/build.gradle index 3279597..86fb159 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -29,15 +29,15 @@ if (flutterVersionName == null) { android { namespace "com.sdkj.skt" - compileSdkVersion flutter.compileSdkVersion + compileSdkVersion 34 ndkVersion flutter.ndkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '17' } sourceSets { @@ -50,8 +50,7 @@ android { // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. minSdkVersion flutter.minSdkVersion - targetSdkVersion flutter.targetSdkVersion - compileSdkVersion 34 + targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } diff --git a/android/app/src/main/kotlin/com/sdkj/sk_base_mobile/MainActivity.kt b/android/app/src/main/kotlin/com/sdkj/sk_base_mobile/MainActivity.kt new file mode 100644 index 0000000..671f27e --- /dev/null +++ b/android/app/src/main/kotlin/com/sdkj/sk_base_mobile/MainActivity.kt @@ -0,0 +1,6 @@ +package com.sdkj.sk_base_mobile + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/android/build.gradle b/android/build.gradle index 1611b65..7fcf849 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.7.10' + ext.kotlin_version = '1.9.22' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.0' // Change this to a version that supports compileSdkVersion 34 + classpath 'com.android.tools.build:gradle:8.0.2' // Change this to a version that supports compileSdkVersion 34 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/lib/screens/hr_manage/components/edit_userinfo.dart b/lib/screens/hr_manage/components/edit_userinfo.dart index 6818708..d1eb51e 100644 --- a/lib/screens/hr_manage/components/edit_userinfo.dart +++ b/lib/screens/hr_manage/components/edit_userinfo.dart @@ -16,6 +16,7 @@ import 'package:sk_base_mobile/util/logger_util.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/util/snack_bar.util.dart'; +import 'package:sk_base_mobile/util/util.dart'; import 'package:sk_base_mobile/widgets/common/multi-picker/models/value_item.dart'; import 'package:sk_base_mobile/widgets/core/sk_cascade_picker.dart'; import 'package:sk_base_mobile/widgets/core/sk_dialog_header.dart'; @@ -392,9 +393,19 @@ class EditUserInfoController extends GetxController { } Future photoPicker() async { - XFile? pickedFile = await MediaUtil().getImageFromGallery(); - if (pickedFile != null) { - filePath.value = pickedFile.path; - } + await MediaUtil().showPicker(callback: (path) async { + if (path != null) { + filePath.value = path; + // 拿到照片大小多少MB + final file = File(path); + final size = await file.length(); + final sizeInMb = size / (1024 * 1024); + print(sizeInMb); + // if (sizeInMb > 2) { + // SnackBarUtil().error('图片大小不能超过2MB'); + // filePath.value = ''; + // } + } + }); } } diff --git a/lib/screens/inventory_inout/components/inventory_inout_card.dart b/lib/screens/inventory_inout/components/inventory_inout_card.dart index a2a509b..285d768 100644 --- a/lib/screens/inventory_inout/components/inventory_inout_card.dart +++ b/lib/screens/inventory_inout/components/inventory_inout_card.dart @@ -10,16 +10,15 @@ import 'package:sk_base_mobile/widgets/fade_in_cache_image.dart'; import '../../../constants/enum.dart'; class InventoryInoutCard extends StatelessWidget { - InventoryInoutCard({super.key, required this.index, required this.ind}); + InventoryInoutCard({super.key, required this.index}); final int index; - final int ind; final controller = Get.find(); @override Widget build(BuildContext context) { return InkWell( onTap: () { controller - .showInventoryInoutInfoDialog(controller.list[ind][index].id!); + .showInventoryInoutInfoDialog(controller.inoutList[index].id!); }, child: Stack( children: [ @@ -67,7 +66,7 @@ class InventoryInoutCard extends StatelessWidget { children: [ Expanded( child: Text( - controller.list[ind][index].product?.name ?? '-', + controller.inoutList[index].product?.name ?? '-', overflow: TextOverflow.ellipsis, style: TextStyle( color: Colors.black, @@ -77,7 +76,7 @@ class InventoryInoutCard extends StatelessWidget { ], ), Text( - controller.list[ind][index].product?.company?.name ?? '-', + controller.inoutList[index].product?.company?.name ?? '-', style: TextStyle( color: AppTheme.grey, fontSize: ScreenAdaper.height(20)), ), @@ -88,7 +87,7 @@ class InventoryInoutCard extends StatelessWidget { children: [ Expanded( child: Text( - '${controller.list[ind][index].project?.name}', + '${controller.inoutList[index].project?.name}', style: TextStyle( color: AppTheme.grey, fontSize: ScreenAdaper.height(20)), ), @@ -102,18 +101,18 @@ class InventoryInoutCard extends StatelessWidget { children: [ Expanded( child: Text( - '${controller.list[ind][index].quantity} ${controller.list[ind][index].product?.unit?.label ?? '-'}', + '${controller.inoutList[index].quantity} ${controller.inoutList[index].product?.unit?.label ?? '-'}', style: TextStyle( fontSize: ScreenAdaper.height(20), fontWeight: FontWeight.w600), ), ), Text( - '${SkDateUtil.format(controller.list[ind][index].time!, formats: [ + '${SkDateUtil.format(controller.inoutList[index].time!, formats: [ 'HH', ':', "nn" - ])} ${controller.list[ind][index].agent ?? '-'}', + ])} ${controller.inoutList[index].agent ?? '-'}', style: TextStyle( fontSize: ScreenAdaper.height(20), fontWeight: FontWeight.w600), @@ -132,19 +131,19 @@ class InventoryInoutCard extends StatelessWidget { child: FadeInCacheImage( width: ScreenAdaper.height(150), height: ScreenAdaper.height(150), - url: controller.list[ind][index].files.isNotEmpty - ? '${GloablConfig.OSS_URL}${controller.list[ind][index].files[0].path}' + url: controller.inoutList[index].files.isNotEmpty + ? '${GloablConfig.OSS_URL}${controller.inoutList[index].files[0].path}' : ''), )); } Widget buildInOrOut() { final bgColor = - controller.list[ind][index].inOrOut == InventoryInOrOutEnum.In + controller.inoutList[index].inOrOut == InventoryInOrOutEnum.In ? AppTheme.snackbarSuccessBackgroudColor : AppTheme.snackbarErrorBackgroudColor; final textInOut = - controller.list[ind][index].inOrOut == InventoryInOrOutEnum.In + controller.inoutList[index].inOrOut == InventoryInOrOutEnum.In ? '入' : '出'; return Container( diff --git a/lib/screens/inventory_inout/components/inventory_inout_view_item.dart b/lib/screens/inventory_inout/components/inventory_inout_view_item.dart index 72ea80f..a0f5fc1 100644 --- a/lib/screens/inventory_inout/components/inventory_inout_view_item.dart +++ b/lib/screens/inventory_inout/components/inventory_inout_view_item.dart @@ -17,33 +17,26 @@ class InventoryInoutViewItem extends StatelessWidget { return Responsive( tablet: Grid( columnNum: 2, - ind: index, ), largeTablet: Grid( columnNum: 3, - ind: index, ), mobile: Grid( columnNum: 1, - ind: index, )); } } class Grid extends StatelessWidget { final int columnNum; - int ind; final controller = Get.find(); - Grid({super.key, required this.columnNum, required this.ind}); + Grid({super.key, required this.columnNum}); @override Widget build(BuildContext context) { - if (controller.currentIndex.value != ind) { - ind = controller.currentIndex.value; - } return Obx( () => controller.loading.value ? const LoadingIndicator(common: true) - : controller.list[ind].isEmpty + : controller.inoutList.isEmpty ? Center( child: Text( TextEnum.noInventoryInout, @@ -57,11 +50,10 @@ class Grid extends StatelessWidget { : MasonryGridView.count( padding: EdgeInsets.only(top: ScreenAdaper.height(60)), crossAxisCount: columnNum, - itemCount: controller.list[ind].length, + itemCount: controller.inoutList.length, itemBuilder: (context, index) { return InventoryInoutCard( index: index, - ind: ind, ); }, ), diff --git a/lib/screens/inventory_inout/inventory_inout_controller.dart b/lib/screens/inventory_inout/inventory_inout_controller.dart index 6661769..a47066a 100644 --- a/lib/screens/inventory_inout/inventory_inout_controller.dart +++ b/lib/screens/inventory_inout/inventory_inout_controller.dart @@ -19,17 +19,8 @@ class InventoryInoutController extends GetxController { final PageController pageController = PageController(); Rx endTime = Rx(DateTime.now()); final DbHelper db = DbHelper(); - List> list = [ - [].obs, - [].obs, - [].obs, - [].obs, - [].obs, - [].obs, - [].obs, - ].obs; + RxList inoutList = [].obs; RxInt barIndex = 0.obs; - RxList model = [].obs; final ScrollController scrollController = ScrollController(); final RefreshController refreshController = RefreshController(); final daysNum = 20; @@ -242,7 +233,7 @@ class InventoryInoutController extends GetxController { ).then((value) => {Get.delete()}); } - Future> getInoutHistory() async { + Future getInoutHistory() async { loading.value = true; await Future.delayed(const Duration(milliseconds: 500)); final selectedDate = SkDateUtil.format( @@ -252,24 +243,17 @@ class InventoryInoutController extends GetxController { 'time': [selectedDate, selectedDate] }); if (res.data != null) { - return res.data!.items + inoutList.assignAll(res.data!.items .map((e) => InventoryInOutModel.fromJson(e)) - .toList(); + .toList()); } - return []; - } catch (e) { - print(e); - return []; } finally { loading.value = false; } } getData() async { - getInoutHistory().then((value) { - model.value = value; - getSepretLists(); - }); + await getInoutHistory(); } setEndTime(DateTime newEndTime) async { @@ -292,23 +276,6 @@ class InventoryInoutController extends GetxController { endTime.value.add(Duration(days: -(daysNum - value)))); } - getSepretLists() { - List> tempList = []; - for (int i = daysNum; i > 0; i--) { - RxList tempList1 = [].obs; - tempList1.clear(); - for (int j = 0; j < model.length; j++) { - final sourceDateStr = SkDateUtil.format(model[j].time); - final currentDateStr = getDateAccordingTabs(i); - if (sourceDateStr == currentDateStr) { - tempList1.add(model[j]); - } - } - tempList.add(tempList1); - } - list.assignAll(tempList); - } - onMoveNextPage() { if (currentIndex.value > 0) { setIndex(currentIndex.value - 1); diff --git a/lib/screens/sale_quotation/sale_quotation.dart b/lib/screens/sale_quotation/sale_quotation.dart index b8054e6..294e1e3 100644 --- a/lib/screens/sale_quotation/sale_quotation.dart +++ b/lib/screens/sale_quotation/sale_quotation.dart @@ -538,7 +538,7 @@ class SaleQuotationPage extends StatelessWidget { alignment: Alignment.center, width: ScreenAdaper.width(unitPriceWidth), child: Text( - CommonUtil.toNumberWithout0(controller + CommonUtil.toNumberWithoutZero(controller .groups[groupIndex].items[rowIndex].unitPrice), style: TextStyle(fontSize: ScreenAdaper.height(25)), ), @@ -553,7 +553,7 @@ class SaleQuotationPage extends StatelessWidget { alignment: Alignment.center, width: ScreenAdaper.width(amountWidth), child: Text( - CommonUtil.toNumberWithout0( + CommonUtil.toNumberWithoutZero( controller.groups[groupIndex].items[rowIndex].amount), style: TextStyle(fontSize: ScreenAdaper.height(25)), ), @@ -607,8 +607,9 @@ class SaleQuotationPage extends StatelessWidget { horizontal: ScreenAdaper.width(20), vertical: ScreenAdaper.height(10)), textController: TextEditingController( - text: - value == 0 ? '' : CommonUtil.toNumberWithout0(value))), + text: value == 0 + ? '' + : CommonUtil.toNumberWithoutZero(value))), ) : InkWell( onTap: () { diff --git a/lib/services/dio.service.dart b/lib/services/dio.service.dart index 3fe2d90..12d6732 100644 --- a/lib/services/dio.service.dart +++ b/lib/services/dio.service.dart @@ -127,7 +127,7 @@ class DioService extends get_package.GetxService { } void onResponse(Response response, ResponseInterceptorHandler handler) async { - /* LoggerUtil().info('[Service-dio] ${response.data}'); */ + LoggerUtil().info('[Service-dio] ${response.data}'); if (whiteList.firstWhereOrNull( (item) => response.requestOptions.path.contains(item)) != diff --git a/lib/util/common.util.dart b/lib/util/common.util.dart index 898c4b2..b0b0a23 100644 --- a/lib/util/common.util.dart +++ b/lib/util/common.util.dart @@ -37,9 +37,13 @@ class CommonUtil { return result; } - static String toNumberWithout0(num num) { + static String toNumberWithoutZero(num num) { return num.toStringAsFixed(num.truncateToDouble() == num ? 0 : 2); } + + static String addZeroOnFront(num num) { + return num.toString().padLeft(2, '0'); + } } class TreeNode { diff --git a/lib/util/media_util.dart b/lib/util/media_util.dart index 16e4f05..a1642fb 100644 --- a/lib/util/media_util.dart +++ b/lib/util/media_util.dart @@ -2,14 +2,57 @@ import 'dart:io'; import 'dart:typed_data'; import 'package:dio/dio.dart' as dio_package; import 'package:dio/dio.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get/get_core/src/get_main.dart'; import 'package:image_gallery_saver/image_gallery_saver.dart'; import 'package:sk_base_mobile/apis/api.dart'; import 'package:image_picker/image_picker.dart'; +import 'package:sk_base_mobile/app_theme.dart'; import 'package:sk_base_mobile/config.dart'; import 'package:sk_base_mobile/models/upload_result.model.dart'; +import 'package:sk_base_mobile/router/router.util.dart'; import 'package:sk_base_mobile/services/service.dart'; class MediaUtil { + /// 选择获取图片的方式,并返回路径 + showPicker({Function(String?)? callback, String title = '请选择上传方式'}) async { + await showCupertinoModalPopup( + context: Get.overlayContext!, + builder: (BuildContext ctx) { + return CupertinoActionSheet( + title: Text(title), + cancelButton: CupertinoActionSheetAction( + onPressed: () { + RouterUtil.back(); + }, + child: const Text( + '取消', + style: TextStyle(color: Color(0xffcdcdcd)), + )), + actions: ['拍照', '相册'] + .map((item) => CupertinoActionSheetAction( + onPressed: () async { + await RouterUtil.back(); + XFile? pickedFile = item == '拍照' + ? await MediaUtil().getImageFromCamera() + : await MediaUtil().getImageFromGallery(); + if (pickedFile != null) { + if (callback != null) { + callback(pickedFile.path); + } + } + }, + child: Text( + item, + style: const TextStyle(color: AppTheme.primaryColor), + ))) + .toList(), + ); + }); + } + static String getMediaUrl(String? url) { if ((url ?? '').isEmpty) { return ''; @@ -28,6 +71,7 @@ class MediaUtil { } AppInfoService.to.isCameraing.value = true; pickedFile = await ImagePicker().pickImage( + imageQuality: 40, source: ImageSource.camera, maxWidth: maxWidth ?? 2000, preferredCameraDevice: @@ -46,7 +90,7 @@ class MediaUtil { } AppInfoService.to.isCameraing.value = true; XFile? pickedFile = await ImagePicker() - .pickImage(source: ImageSource.gallery, imageQuality: 60); + .pickImage(source: ImageSource.gallery, imageQuality: 40); AppInfoService.to.isCameraing.value = false; return pickedFile; } diff --git a/lib/util/photo_picker_util.dart b/lib/util/photo_picker_util.dart deleted file mode 100644 index c39a339..0000000 --- a/lib/util/photo_picker_util.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:get/get.dart'; -import 'package:image_picker/image_picker.dart'; -import 'package:sk_base_mobile/router/router.util.dart'; -import 'package:sk_base_mobile/util/media_util.dart'; -import 'package:sk_base_mobile/app_theme.dart'; - -class PhotoPickerUtil { - showPicker({Function? callback, String title = '请选择上传方式'}) async { - return showCupertinoModalPopup( - context: Get.context!, - builder: (BuildContext ctx) { - return CupertinoActionSheet( - title: Text(title), - cancelButton: CupertinoActionSheetAction( - onPressed: () { - RouterUtil.back(); - }, - child: const Text( - '取消', - style: TextStyle(color: Color(0xffcdcdcd)), - )), - actions: ['拍照', '相册'] - .map((item) => CupertinoActionSheetAction( - onPressed: () async { - await RouterUtil.back(); - XFile? pickedFile = item == '拍照' - ? await MediaUtil().getImageFromCamera() - : await MediaUtil().getImageFromGallery(); - if (pickedFile != null) { - if (callback != null) { - callback(pickedFile); - } - } - }, - child: Text( - item, - style: const TextStyle(color: AppTheme.primaryColor), - ))) - .toList(), - ); - }); - } -} diff --git a/lib/util/util.dart b/lib/util/util.dart index e5a4a74..2da9262 100644 --- a/lib/util/util.dart +++ b/lib/util/util.dart @@ -3,7 +3,6 @@ library store; export 'snack_bar.util.dart'; export 'loading_util.dart'; export 'media_util.dart'; -export 'photo_picker_util.dart'; export 'screen_adaper_util.dart'; export 'validator_util.dart'; export 'date.util.dart'; diff --git a/lib/widgets/core/sk_base_date_picker.dart b/lib/widgets/core/sk_base_date_picker.dart index 489f901..47d3018 100644 --- a/lib/widgets/core/sk_base_date_picker.dart +++ b/lib/widgets/core/sk_base_date_picker.dart @@ -47,7 +47,10 @@ class SkBaseDatePicker extends StatelessWidget { if (int.parse(month) < 10) { month = '0$month'; } - final day = dayController.selectedItem + 1; + String day = '${dayController.selectedItem + 1}'; + if (int.parse(day) < 10) { + day = '0$day'; + } if (onDateTimeChanged != null) { onDateTimeChanged!('$year-$month-$day'); } diff --git a/lib/widgets/my_avatar.dart b/lib/widgets/my_avatar.dart index 6944726..3a4bea4 100644 --- a/lib/widgets/my_avatar.dart +++ b/lib/widgets/my_avatar.dart @@ -69,7 +69,7 @@ class MyAvatarWidget extends StatelessWidget { class MyAvatarController extends GetxController { final uploadImgFilePath = ''.obs; Future photoPicker() async { - await PhotoPickerUtil().showPicker(callback: (XFile pickedFile) async { + await MediaUtil().showPicker(callback: (String? pickedFile) async { await LoadingUtil.to.show(status: 'Uploading...'); try { // UploadResultModel? res = await MediaUtil().uploadImg(File(pickedFile.path)); diff --git a/pubspec.yaml b/pubspec.yaml index 2128cbc..5013d36 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.devz # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.0.3+1 +version: 1.0.4+1 environment: sdk: '>=3.2.6 <4.0.0'