Index: lib/page/main/main_controller.dart
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
<+>import 'package:flutter/material.dart';\nimport 'package:flutter_smart_dialog/flutter_smart_dialog.dart';\nimport 'package:public_lib/net/config/core_config.dart';\nimport 'package:get/get.dart';\nimport 'package:public_lib/net/model/result_data.dart';\nimport 'package:smps_flutter_pda/common/spms_application.dart';\nimport 'package:smps_flutter_pda/page/domestic/home/cn_home_page.dart';\nimport 'package:smps_flutter_pda/page/domestic/other/other_page.dart';\nimport 'package:smps_flutter_pda/page/hi_getcontroller.dart';\nimport 'package:smps_flutter_pda/page/main/update_dialog_view.dart';\nimport 'package:smps_flutter_pda/page/main/update_vo.dart';\nimport 'package:smps_flutter_pda/page/message/msg_page.dart';\nimport 'package:smps_flutter_pda/page/my/my_page.dart';\nimport 'package:smps_flutter_pda/page/my/widget/update_widget.dart';\nimport 'package:smps_flutter_pda/page/offline/offline_page.dart';\n\nimport 'package:smps_flutter_pda/page/overseas/home/overseas_home_page.dart';\nimport 'package:smps_flutter_pda/utils/minio_manager.dart';\nimport '../../common/android_channel/android_channel_manager.dart';\nimport '../../common/common.dart';\n\n\nclass MainController extends HiGetController {\n\n  ///当前现实的页面 0主页(根据当前工厂，需判断为海外仓还是国内仓)，1消息，2离线 ， 3我的 ，\n  int currentPage = 0;\n\n  ///标签\n  List<TabItem> tabItems=[];\n\n  ///刷新整个mainpagge的id\n  String updateMain = 'updateMain';\n  @override\n  void onInit() {\n    super.onInit();\n    if(CoreConfig.manufacturer=='Urovo'){\n      AndroidChannelManager().startScanManager();\n      AndroidChannelManager(). channel.setMethodCallHandler(\n              (call) => AndroidChannelManager().acceptNativeMsg(call));\n    }\n    _initPages();\n    checkUpdate();\n  }\n\n  void _initPages(){\n    if (SPMSApplication().isOverseas) {\n      tabItems=[\n        TabItem(\"icon_home_select.png\",\"icon_home_unselect.png\",Ids.frontPage.tr,OverseasHomePage.routeName,OverseasHomePage()),\n        TabItem(\"icon_msg_select.png\",\"icon_msg_unselect.png\",Ids.information.tr,MsgPage.routeName,MsgPage()),\n        TabItem(\"icon_offline_select.png\",\"icon_offline_unselect.png\",Ids.offline.tr,OfflinePage.routeName,OfflinePage()),\n        TabItem(\"icon_my_select.png\",\"icon_my_unselect.png\",Ids.mine.tr,MyPage.routeName,MyPage()),\n      ];\n    } else {\n      tabItems=[\n        TabItem(\"icon_home_select.png\",\"icon_home_unselect.png\",Ids.frontPage.tr,CNHomePage.routeName,const CNHomePage()),\n        TabItem(\"icon_msg_select.png\",\"icon_msg_unselect.png\",Ids.information.tr,OtherPage.routeName,OtherPage()),\n        TabItem(\"icon_my_select.png\",\"icon_my_unselect.png\",Ids.mine.tr,MyPage.routeName,MyPage()),\n      ];\n    }\n  }\n\n  ///检查更新信息,\n  void checkUpdate({bool noUpdateToast=false})async{\n    ResultData resultData=await apiService.getLastUpdateVersion();\n    if(resultData.isSuccess()) {\n      UpdateVo updateVo=resultData.data;\n      if(updateVo!=null){\n        Vo? vo=updateVo!.vo;\n        if(vo!=null){\n          int lastedVersion=int.parse(vo.versionCode??\"1\");\n          if(lastedVersion>SPMSApplication().versionCode){\n            SmartDialog.show(\n              builder: (context) {\n                return UpdateDialogView(\n                    vo.updateType==\"1\",\n                    '${vo.versionName}',\n                    '${vo.comments}',\n                    '${vo.attachmentUrl}');\n              },\n              alignment: Alignment.center,\n              clickMaskDismiss: vo.updateType==\"2\",\n            );\n          }else{\n            if(noUpdateToast){\n              SmartManager().showCenterToast(Ids.currentVersionIsTheLatest.tr);\n            }\n          }\n        }\n      }\n    }else{\n      SmartManager().showCenterToast(resultData.msg);\n    }\n\n  }\n\n  /**\n   * {\n      \"code\": 200,\n      \"msg\": \"请求成功\",\n      \"data\": {\n        \"vo\": {\n        \"comments\": \"测试文本\",\n        \"attachmentUrl\": \"https://minio-prd.sunda.com/spms/20240311161539spms-release%20%281%29.apk\",\n        \"updateUser\": \"null\",\n        \"updateTime\": \"null\",\n        \"versionName\": \"v1.0.5\",\n        \"uuid\": \"53b8de536ffc46d68719175d943ac6b5\",\n        \"versionCode\": \"15\",\n        \"createTime\": \"2024-03-11 16:16:26\",\n        \"attachmentName\": \"spms-release (1).apk\",\n        \"createUser\": \"10043398\",\n        \"updateType\": \"2\"\n        }\n      }\n    }\n   */\n  ///更新\n  void updateMainPage() {\n    _initPages();\n    update([updateMain]);\n  }\n\n\n  void tabChange(int index){\n    currentPage = index;\n    SPMSApplication().mainRoute = tabItems[index].routeName!;\n    update([updateMain]);\n  }\n\n}\n\nclass TabItem{\n    String? selectImage;\n    String? unselectImage;\n    String? label;\n    String? routeName;\n    ///对应的页面\n    Widget? page;\n    TabItem(this.selectImage,this.unselectImage, this.label, this.routeName,this.page);\n}\n
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/lib/page/main/main_controller.dart b/lib/page/main/main_controller.dart
--- a/lib/page/main/main_controller.dart	(revision 7a02fce56783d3de50e090857f5f0ae0e5fcb1f4)
+++ b/lib/page/main/main_controller.dart	(date 1721792380143)
@@ -1,12 +1,15 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
+import 'package:isar/isar.dart';
 import 'package:public_lib/net/config/core_config.dart';
 import 'package:get/get.dart';
 import 'package:public_lib/net/model/result_data.dart';
+import 'package:smps_flutter_pda/common/db/database_manager.dart';
 import 'package:smps_flutter_pda/common/spms_application.dart';
 import 'package:smps_flutter_pda/page/domestic/home/cn_home_page.dart';
 import 'package:smps_flutter_pda/page/domestic/other/other_page.dart';
 import 'package:smps_flutter_pda/page/hi_getcontroller.dart';
+import 'package:smps_flutter_pda/page/login/model/log_model.dart';
 import 'package:smps_flutter_pda/page/main/update_dialog_view.dart';
 import 'package:smps_flutter_pda/page/main/update_vo.dart';
 import 'package:smps_flutter_pda/page/message/msg_page.dart';
@@ -90,6 +93,19 @@
     }else{
       SmartManager().showCenterToast(resultData.msg);
     }
+    // Isar? isar = DatabaseManager().isar;
+    //
+    //
+    // List<LogModel> list=[];
+    // for(int i=0;i<10000;i++){
+    //   list.add(LogModel()
+    //     ..time=DateTime.now().toString()
+    //     ..event="logTest"
+    //     ..userId="${SPMSApplication().userInfo?.userInfo?.userId}"
+    //     ..mapJson=jsonEncode(SPMSApplication().userInfo?.userWhs?.map((e) => e.toString()).toList()));
+    // }
+
+    // await DatabaseManager().saveData(() => isar?.logModels.putAll(list));
 
   }
 
Index: lib/page/domestic/take_off/cn_take_off_details_controller.dart
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
<+>import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';\nimport 'package:public_lib/extension/json_parse_utils.dart';\nimport 'package:public_lib/net/config/core_config.dart';\nimport 'package:public_lib/net/model/result_data.dart';\nimport 'package:smps_flutter_pda/common/android_channel/android_channel_mixin.dart';\nimport 'package:smps_flutter_pda/common/common.dart';\nimport 'package:smps_flutter_pda/common/page_state.dart';\nimport 'package:smps_flutter_pda/page/domestic/domestic_shift/model/domestic_shift_model.dart';\nimport 'package:smps_flutter_pda/page/domestic/domestic_shift/model/domestic_storage_model.dart';\nimport 'package:smps_flutter_pda/page/domestic/take_off/cn_take_off_details_page.dart';\nimport 'package:smps_flutter_pda/page/domestic/take_off/model/boxes_loc.dart';\nimport 'package:smps_flutter_pda/page/domestic/take_off/model/take_off_details_model.dart';\nimport 'package:smps_flutter_pda/page/domestic/take_off/take_off_list_page.dart';\nimport 'package:smps_flutter_pda/page/hi_getcontroller.dart';\nimport 'package:smps_flutter_pda/page/overseas/shift/model/storage_model.dart';\nimport 'package:smps_flutter_pda/utils/domestic_api_utils.dart';\nimport 'package:smps_flutter_pda/utils/smart_manager.dart';\nimport 'package:smps_flutter_pda/widget/calendar_dialog.dart';\nimport 'package:collection/collection.dart';\n\nclass CNTakeOffDetailsController extends HiGetController with GetSingleTickerProviderStateMixin ,AndroidChannelMixin{\n\n  Rx<PageState<TakeOffDetailsModel>> modelStatus =\n      PageState<TakeOffDetailsModel>().obs;\n  RxDouble keyboardHeight = 0.0.obs;\n\n  late TabController tabController;\n  List<String> tabName = [\n    Ids.pickingOffTheShelf.tr,\n    Ids.temporaryInstallation.tr\n  ];\n\n  TextEditingController searchTextEditingController = TextEditingController();\n\n  FocusNode searchFocusNode = FocusNode();\n\n  TextEditingController addTextEditingController = TextEditingController();\n\n  FocusNode addFocusNode = FocusNode();\n\n  List<TakeOffDetailsModel> allData = [];\n  ///用于展示搜索结果\n  // List<TakeOffDetailsModel> itemData = [];\n\n  RxBool selectAll = false.obs;\n\n  RxBool canSubmit = false.obs;\n\n  String uuid = '';\n\n  RxString title = Ids.removalDetails.tr.obs;\n\n  int account = 0;\n  ///按箱号 按储位\n  List<String> searchList = ['BOX', 'LOC'];\n\n  int searchType = 0;\n\n  int addType = 0;\n\n  String werks = '';\n\n  // String whsCode = '';\n\n  RxList<ShelfOffTaskDtls> addList = <ShelfOffTaskDtls>[].obs;\n\n  List<WhsStorageList> storageModelList = [];\n\n  String packageList = '';\n\n  WhsOut? whsOut;\n\n  ShelfOffTask? shelfOffTask;\n\n  List<ShelfOffTaskDtls>? shelfOffTaskDtls;\n  List<WhsOutDtl>? whsOutDtl;\n\n  TextEditingController cabinetNumber = TextEditingController();\n\n  TextEditingController leadSeal = TextEditingController();\n\n  TextEditingController installation = TextEditingController();\n\n  TextEditingController cabinetInstallation = TextEditingController();\n\n  TextEditingController inspectionResults = TextEditingController();\n\n  TextEditingController remark = TextEditingController();\n  ///选择的日期\n  List<DateTime> dateTime = [];\n\n  ///时间文案\n  RxString time = ''.obs;\n\n  int _cannotSelectCount=0;\n  RxInt updateInt=0.obs;//仅作为Obx刷新界面的变量，无实际意义\n  List<WhsOutDtl> searchResultList=[];//搜索结果\n\n  @override\n  void onInit(){\n    super.onInit();\n    TakeOffDetailsAr ar = Get.arguments;\n    uuid = ar.uuid;\n    werks = ar.werks;\n    packageList = ar.packageList;\n    tabController = TabController(length: 2, vsync: this);\n    listener.addListener(_scanListener);\n    DomesticApiUtils().getWhsStorageListAll(whsLocationCode: ar.whsCode,werks: werks).then((value) {\n      storageModelList = value?.whsStorageList ?? [];\n      getStorageModelList();//调一下在渲染之前先将对象创建好\n      // modelStatus.refresh();\n    }\n    ).then((value) => getTakeOffDetails());\n\n\n  }\n\n\n\n  void _scanListener(){\n    if(tabController.index==0){\n      searchTextEditingController.text = listener.eventParameter;\n      if (searchType == 0) {\n        searchResultList=searchByBox();\n        updateInt++;\n      } else {\n        searchResultList=searchByLOC();\n        updateInt++;\n      }\n    }else{\n      addTextEditingController.text = listener.eventParameter;\n      getBoxInfo();\n    }\n  }\n\n  @override\n  void didChangeMetrics() {\n    super.didChangeMetrics();\n    //这是ui的操作，本来应该写在ui页的，但是当前ui采用的是stateless，缺乏生命周期，所以只能在这里监听键盘高度的变化\n    WidgetsBinding.instance.addPersistentFrameCallback((timeStamp) {\n      if(keyboardHeight.value!=MediaQuery.of(Get.context!).viewInsets.bottom){\n        keyboardHeight.value=MediaQuery.of(Get.context!).viewInsets.bottom;//改变scrollview的内容，使其可滑动\n      }\n    });\n  }\n\n\n\n  @override\n  onClose(){\n    listener.removeListener(_scanListener);\n    tabController.dispose();\n    searchTextEditingController.dispose();\n    addTextEditingController.dispose();\n    cabinetInstallation.dispose();\n    leadSeal.dispose();\n    inspectionResults.dispose();\n    installation.dispose();\n    cabinetNumber.dispose();\n    remark.dispose();\n    super.onClose();\n  }\n\n  late TakeOffDetailsModel model;\n  Future<void> getTakeOffDetails() async {\n    modelStatus.put('uuid', uuid);\n    modelStatus.put('goodsType', 'X');\n    ResultData resultData =\n    await modelStatus.request(apiService.getTakeOffDetails);\n\n    if (resultData.isSuccess()) {\n      model = resultData.data;\n      shelfOffTask = model.shelfOffTask;\n      whsOut = model.whsOut;\n      shelfOffTaskDtls=model.shelfOffTaskDtls;\n      whsOutDtl=model.whsOutDtl;\n      _initCannotCount();\n      // if (model.shelfOffTaskDtls != null &&\n      //     model.shelfOffTaskDtls!.isNotEmpty) {\n      //   account = model.shelfOffTaskDtls?.length ?? 0;\n      //   title.value = '${Ids.removalDetails.tr}(0/$account)';\n      //   Map<String?, List<ShelfOffTaskDtls>> grouped =\n      //   groupBy(model.shelfOffTaskDtls ?? [], (p0) => p0.unplanned);\n      //   List<TakeOffDetailsModel> list = grouped.entries\n      //       .map((e) => TakeOffDetailsModel(\n      //       unplanned: e.key == '1' ,//1为计划外，其他值为计划内\n      //       shelfOffTaskDtls: e.value))\n      //       .toList();\n      //   allData = list;\n      //   itemData = list;\n      //   modelStatus.refresh();\n      // }\n      if (model.whsOutDtl != null &&\n          model.whsOutDtl!.isNotEmpty) {\n        account = model.whsOutDtl?.length ?? 0;\n        title.value = '${Ids.removalDetails.tr}(0/$account)';\n        Map<String?, List<WhsOutDtl>> grouped = groupBy(model.whsOutDtl ?? [], (p0) => p0.unplanned);\n        List<TakeOffDetailsModel> list = grouped.entries\n            .map((e) => TakeOffDetailsModel(\n            unplanned: e.key == '1' ,//1为计划外，其他值为计划内\n            whsOutDtl: e.value))\n            .toList();\n        allData = list;\n        // itemData = list;\n        modelStatus.refresh();\n      }\n\n    }\n  }\n\n  List<WhsOutDtl> searchBy(){\n    if (searchType == 0) {\n      return searchByBox();\n    } else {\n      return searchByLOC();\n    }\n  }\n\n  final List<StorageModel> _cacheStorageModelList=[];\n  List<StorageModel> getStorageModelList(){\n    if(_cacheStorageModelList.isEmpty){\n      _cacheStorageModelList.addAll(storageModelList.map((e) => StorageModel(\n          storageNo: e.storageNo,\n          uuid: e.uuid)).toList());\n    }\n    return _cacheStorageModelList;\n  }\n\n  List<WhsOutDtl> searchByBox() {\n    // if (searchTextEditingController.text.isEmpty) {//输入框空的时候展示全部，非空的时候展示搜索的结果\n    //   itemData = allData;\n    //   modelStatus.refresh();\n    //   return;\n    // }\n\n\n    // itemData = allData.map((e) => e.clone()).toList();//先复制一份，再分别做选择\n    List<WhsOutDtl> whsOutDtls=[];\n    //保存的数据\n    for (var element in allData) {\n      if(!isListEmpty(element.whsOutDtl)){\n        whsOutDtls.addAll(tickSelect(element));\n      }\n    }\n    //展示的搜索结果，需要筛选裁剪\n    // for (var element in itemData) {\n    //   if(!isListEmpty(element.whsOutDtl)){\n    //     //如果所扫描的结果在本组中，则将其作为结果\n    //     if(element.whsOutDtl!.where((e) =>e!.boxNote==searchTextEditingController.text ).length==1){\n    //       itemData=[element..whsOutDtl=tickSelect(element)];\n    //       break;\n    //     }\n    //   }\n    // }\n\n    checkCanSubmit();\n    updateInt++;\n    modelStatus.refresh();\n    return whsOutDtls;\n  }\n\n  ///搜索结果打钩，返回搜索结果\n  List<WhsOutDtl> tickSelect(TakeOffDetailsModel detailModel) {\n    List<WhsOutDtl> whsOutDtls = detailModel.whsOutDtl!\n        .where((e) => e.boxNote == searchTextEditingController.text)\n        .toList();\n    if(whsOutDtls.isNotEmpty){\n      //需求，扫描到的结果直接勾选\n      for (var element in whsOutDtls) {\n        //如果没有储位，不能勾选\n        if(element.storageNo?.isNotEmpty??false){\n          element.hasSelect = true;\n          //将扫描到的项提到最前面\n          detailModel.whsOutDtl!.remove(element);\n          detailModel.whsOutDtl!.insert(0,element);\n        }\n\n      }\n      return whsOutDtls;\n    }else{\n      return [];\n    }\n\n  }\n\n\n  void checkCanSubmit() {\n    List<bool> list = [];\n    for (var element in allData) {\n      element.whsOutDtl?.forEach((element) {\n        list.add(element.hasSelect!);\n      });\n    }\n    selectAll.value = list.where((element) => element==true).length==list.length-_cannotSelectCount;//所有可选的选项都选上了，即显示全选\n    canSubmit.value = list.contains(true);\n    title.value = '${Ids.removalDetails.tr}(${list.where((element) => element).toList().length}/$account)';\n  }\n\n  List<WhsOutDtl>  searchByLOC() {\n    // if (searchTextEditingController.text.isEmpty) {\n    //   itemData = allData;\n    //   modelStatus.refresh();\n    //   return;\n    // }\n\n    // List<TakeOffDetailsModel> list = allData.map((e) => e.clone()).toList();\n    // itemData = allData\n    //     .where((element) => element.whsOutDtl!\n    //     .map((e) => e.storageNo == searchTextEditingController.text)\n    //     .toList()\n    //     .isNotEmpty)\n    //     .toList();\n\n    List<WhsOutDtl> whsOutDtls = model.whsOutDtl!\n        .where((element) => element.storageNo== searchTextEditingController.text)\n        .toList();\n    updateInt++;\n    modelStatus.refresh();\n    return whsOutDtls;\n  }\n\n  void changeModel(WhsOutDtl model, bool unplanned,\n      {StorageModel? storageModel, bool? hasSelect}) {\n    if (storageModel != null) {\n      model.storageNo = storageModel.storageNo;\n      model.targetStorage = storageModel.uuid;\n    }\n    //这里过滤一下，没有储位的，不能勾选\n    if(model.storageNo?.isEmpty??true){\n      return;\n    }\n    if (hasSelect != null) {\n      model.hasSelect = hasSelect;\n    }\n    //在列表中更改选中的项\n    _changeItem(allData,model);\n    //在展示列表中更改选中的项\n    // _changeItem(itemData,model);\n    checkCanSubmit();\n    updateInt++;\n    modelStatus.refresh();\n  }\n  //在列表中更改选中的项\n  void _changeItem(List<TakeOffDetailsModel> dataList,WhsOutDtl model) {\n    for (var element in dataList) {\n      int? index = element.whsOutDtl?.indexWhere((e) => e.boxNote == model.boxNote);\n      if(index!=null&&index>-1){\n        element.whsOutDtl![index] = model;\n      }\n    }\n  }\n\n  void clickAll() {\n    selectAll.value = !selectAll.value;\n    for (var element in allData) {\n      element.whsOutDtl?.forEach((element) {\n        //这里过滤一下，没有储位的，不能勾选\n        if(element.storageNo?.isNotEmpty??false){\n          element.hasSelect = selectAll.value;\n        }\n      });\n    }\n\n    // for (var element in itemData) {\n    //   element.whsOutDtl?.forEach((element) {\n    //     //这里过滤一下，没有储位的，不能勾选\n    //     if(element.storageNo?.isNotEmpty??false){\n    //       element.hasSelect = selectAll.value;\n    //     }\n    //   });\n    // }\n    canSubmit.value = selectAll.value;\n    title.value =\n    '${Ids.removalDetails.tr}(${selectAll.value ? account : 0}/$account)';\n    checkCanSubmit();\n    updateInt++;\n    modelStatus.refresh();\n  }\n\n\n  void getBox(){\n    if (addType == 0) {\n      getBoxInfo();\n    } else {\n      getBoxInfoList();\n    }\n  }\n\n  Future<void> getBoxInfo() async {\n    if (addTextEditingController.text.isEmpty) {\n      SmartManager().showCenterToast(Ids.pleaseEnter.tr);\n      return;\n    }\n    Map<String, dynamic> map = {}\n      ..put('boxNote', addTextEditingController.text)\n      ..put('werks', whsOut?.werks)\n      ..put('whsLocationCode', whsOut?.whsLocationCode)\n      ..put('pageNo', 1)\n      ..put('pageSize', 20);\n    ResultData resultData = await apiService.getBoxInfoList(map);\n    if (resultData.isSuccess()) {\n      DomesticShiftModel model = resultData.data;\n      String uuid=\"\";\n      try{\n        List<WhsStorageList> list = storageModelList\n            .where((element) => element.storageNo == model.boxInfo?.records?.first.storageNo)//first是个危险操作，但业务上只能同个工厂仓库的情况下\n            .toList();\n        uuid = list.isNotEmpty ? list.first.uuid ?? '' : '';\n      }catch(e){\n        SmartManager().showCenterToast(\"${Ids.cannotBeFoundUnderThisWarehouse.tr}:${addTextEditingController.text}\");\n      }\n\n      if (!isListEmpty(model.boxInfo?.records)) {\n        ShelfOffTaskDtls item = ShelfOffTaskDtls(\n            boxNote: addTextEditingController.text,\n            storageNo: model.boxInfo?.records?.first.storageNo,\n            recommendStorageNo: model.boxInfo?.records?.first.storageNo,\n            recommendStorageUuid: storageModelList\n                .where((e) =>\n            e.storageNo == model.boxInfo?.records?.first.storageNo)\n                .toList()\n                .first\n                .uuid ??\n                '',\n            uuid: shelfOffTask?.uuid,//此处应为上下架任务的uuid\n            unplanned: '1');\n        //不存在才加到列表，还要个过滤条件：如果这个箱码已经在任务列表中，也不能加进来\n        if (_boxNoteCanAddTemp(item.boxNote!)) {\n          addList.add(item);\n        }\n      }\n    }else{\n      SmartManager().showCenterToast(resultData.msg);\n    }\n\n  }\n  //箱码是否能被添加到临时加装\n  bool _boxNoteCanAddTemp(String boxNote){\n    //新加列表中不包含\n    if(addList.map((element) => element.boxNote).toList().contains(boxNote)){\n      SmartManager().showCenterToast(Ids.duplicateBoxCodesCannotBeAdded.tr);\n      return false;\n    }\n    //原有列表不包含\n    if(!isListEmpty(whsOutDtl)){\n      if(whsOutDtl!.map((element) => element.boxNote).toList().contains(boxNote)){\n        SmartManager().showCenterToast(Ids.duplicateBoxCodesCannotBeAdded.tr);\n        return false;\n      }\n    }\n    return true;\n  }\n\n  Future<void> getBoxInfoList() async {\n    if (addTextEditingController.text.isEmpty) {\n      SmartManager().showCenterToast(Ids.pleaseEnter.tr);\n      return;\n    }\n    Map<String, dynamic> map = {}\n      ..put('pageNo', 1)\n      ..put('pageSize', 1000)\n      ..put('storageNo', addTextEditingController.text)\n      ..put('werks', werks)\n      ..put('whsLocationCode', allData.first.whsOut?.whsLocationCode);\n    ResultData resultData = await apiService.getBoxInfoList(map);\n    SmartManager().showCenterToast(resultData.msg);\n    if (resultData.isSuccess()) {\n      DomesticShiftModel model = resultData.data;\n      List<ShelfOffTaskDtls> list = model.boxInfo?.records\n          ?.map((e) => ShelfOffTaskDtls(\n          boxNote: addTextEditingController.text,\n          storageNo: e.storageNo,\n          uuid: shelfOffTask?.uuid,\n          unplanned: '1'))\n          .toList() ??\n          [];\n      // for (var value in list) {\n      //   int index = storageModelList\n      //       .indexWhere((element) => element.storageNo == value.storageNo);\n      //   if (index != -1) {\n      //     value.uuid = storageModelList[index].uuid;\n      //   }\n      // }\n      addList.addAll(list);\n    }\n  }\n\n  void addItem(ShelfOffTaskDtls model) {\n    //上下架任务和出入库任务是一一对应的，所以这里需要构造一个出入库任务进列表\n    WhsOutDtl? whsOutDtl0;\n    if(!isListEmpty(this.whsOutDtl)){\n      whsOutDtl0=this.whsOutDtl!.firstWhere((element) => (element.unplanned!=\"1\")&&(element.unplanned!=1));\n    }\n\n    WhsOutDtl whsOutDtl=WhsOutDtl(\n      packageList: whsOut?.packageList,\n      actualOperateQty: 1,\n      boxNote: model.boxNote,\n      storageNo: model.storageNo,\n      loadingType: whsOut?.loadingType,\n      targetStorage: model.recommendStorageUuid,\n      unplanned: \"1\",\n      shipper: whsOutDtl0?.shipper,//几个属性默认复制计划内的\n      bukrs: whsOutDtl0?.bukrs,//几个属性默认复制计划内的\n      actualReceivingWerks: whsOutDtl0?.actualReceivingWerks,//几个属性默认复制计划内的\n      consignee: whsOutDtl0?.consignee,//几个属性默认复制计划内的\n      receivingWerks: whsOutDtl0?.receivingWerks,//几个属性默认复制计划内的\n      cabinetModel: whsOutDtl0?.cabinetModel,//几个属性默认复制计划内的\n    );\n\n    //allData只会有两个大类\n    int index = allData.indexWhere((element) => element.unplanned == true);\n    if(index>=0){\n      allData[index].shelfOffTaskDtls?.add(model);\n      allData[index].whsOutDtl?.add(whsOutDtl);\n    }else{\n      allData.add(TakeOffDetailsModel(unplanned: true, shelfOffTaskDtls: [model],whsOutDtl: [whsOutDtl]));//临时添加都是计划外的\n    }\n    shelfOffTaskDtls?.add(model);//要提交的数据也要同步\n    account += 1;\n    List<bool> list = [];\n    for (var element in allData) {\n      element.whsOutDtl?.forEach((element) {\n        list.add(element.hasSelect!);\n      });\n    }\n    title.value = '${Ids.removalDetails.tr}(${list.where((element) => element).toList().length}/$account)';\n    addList.remove(model);\n    selectAll.value = false;\n    SmartManager().showCenterToast(Ids.addSuccessfully.tr);\n    updateInt++;\n    modelStatus.refresh();\n  }\n\n  void deleteItem(WhsOutDtl model) {\n\n    for (var element in allData) {\n      if(element.whsOutDtl!.contains(model)){\n        element.whsOutDtl!.remove(model);//删除对应的数据\n        if(element.whsOutDtl!.isEmpty){//如果组中没数据，连组也删除了\n          allData.remove(element);\n        }\n        break;\n      }\n    }\n\n    shelfOffTaskDtls?.removeWhere((element) => element.boxNote==model.boxNote);\n\n    account -= 1;\n    checkCanSubmit();\n    updateInt++;\n    modelStatus.refresh();\n  }\n\n  void changeItem(ShelfOffTaskDtls model, StorageModel storageModel) {\n    model.storageNo = storageModel.storageNo;\n    model.uuid = storageModel.uuid;\n    int index =\n    addList.indexWhere((element) => element.boxNote == model.boxNote);\n    addList[index] = model;\n    addList.refresh();\n  }\n\n  Future<void> postTakeOffDetails() async {\n    String regexPattern = r'^[A-Z]{4}\\d{7}$';\n    RegExp regExp = RegExp(regexPattern);\n\n    bool isMatch = regExp.hasMatch(cabinetNumber.text);\n    if (!isMatch) {\n      SmartManager().showCenterToast(\n          Ids.verificationOfCabinetNumberFailedAndItMustStartWith4UppercaseLettersAndEndWith7Digits.tr);\n      return;\n    }\n\n    List<WhsOutDtl> whsOutDtlList = await _handlePostData();\n\n    Map<String, dynamic> map = {}\n      // ..put('targetStatus', '2')\n      ..put('submitDate', time.value)\n      ..put(\n          'shelfOnTask',\n          shelfOffTask\n            ?..currentStatus = shelfOffTask?.taskStatus\n            ..targetStatus = '3')//PC端传的是这个状态\n      ..put(\n          'whsOut',\n          whsOut\n            ?..currentStatus = whsOut?.taskStatus\n            ..cabinetNumber = cabinetNumber.text\n            ..pdaSN=CoreConfig.DEVICE_NAME\n            ..pdaTime=timeForNow()\n            ..leadSeal = leadSeal.text\n            ..monitorLoading = installation.text\n            ..cabinetCheckResult = inspectionResults.text\n            ..remarks = remark.text\n            ..loadingType = cabinetInstallation.text\n            ..targetStatus = '2'\n            ..actualLoadingDate = time.value)\n      ..put(\n          'shelfOnTaskDtls',\n          shelfOffTaskDtls)\n      ..put('whsOutDtl', whsOutDtlList)\n      ..put('remainingBoxNote', [])\n    ;\n    // String res=jsonEncode(map);\n    // Get.log(res);\n    SmartDialog.showLoading(msg: \"${Ids.pleaseWait.tr}...\",backDismiss: false);\n    try{\n      ResultData resultData = await apiService.postTakeOffDetails(map);\n      await SmartDialog.dismiss();\n      SmartManager().showCenterToast(resultData.msg);\n      if (resultData.isSuccess()) {\n        NavigatorUtils.pop(true);\n        getTakeOffDetails();\n      }\n    }catch(e){\n      SmartDialog.dismiss();\n    }\n\n  }\n\n  Future<List<WhsOutDtl>> _handlePostData() async{\n    List<WhsOutDtl> whsOutDtlList = [];//待提交的数据\n    for (var element in allData) {\n      whsOutDtlList.addAll(element.whsOutDtl ?? []);\n    }\n\n    //先批量查询选中箱码的仓库位置\n    await exceptionBoxDontOut(whsOutDtlList);\n\n    //同步下架\n    if(shelfOffTaskDtls!=null&&shelfOffTaskDtls!.isNotEmpty){\n      for(var shBean in shelfOffTaskDtls!) {\n        WhsOutDtl whBean=whsOutDtlList.firstWhere((element) => element.boxNote==shBean.boxNote);\n        whBean.cabinetModel=whsOut?.cabinetModel;//柜型需要复制头项目中的信息\n        if(whBean.hasSelect==true){\n          shBean.hasSelect=true;\n          shBean.quantity=1;\n          whBean.actualOperateQty=1;\n          shBean.actualOperateQty=1;\n          shBean.targetStorage=shBean.recommendStorageUuid;\n        }else{\n          shBean.hasSelect=false;\n          shBean.quantity=0;\n          whBean.actualOperateQty=0;\n          shBean.actualOperateQty=0;\n        }\n      }\n    }\n    return whsOutDtlList;\n  }\n  //异常箱码不出库\n  Future<void> exceptionBoxDontOut(List<WhsOutDtl> whsOutDtlList) async {\n    List<WhsOutDtl> wait4CheckList=whsOutDtlList.where((element) => element.hasSelect==true).toList();\n    ResultData resultData=await apiService.getWSInventoryByBoxNote({\n      \"boxNote\":wait4CheckList.map((e) => e.boxNote).toList(),\n    });\n    if(resultData.isSuccess()){\n      BoxesLoc loc=resultData.data;\n      //箱码所在的仓库与当前实际仓库不一致的情况下，不能在当前的仓库出库。要做一个提醒\n      List<StorageInv>? exceptionBoxes= loc.storageInvList?.where((element) =>\n          element.werks!=whsOut!.werks||\n          element.whsLocationCode!=whsOut!.whsLocationCode).toList();\n      if(exceptionBoxes!=null){\n        for (StorageInv inv in exceptionBoxes) {\n          WhsOutDtl? dtl= whsOutDtlList.firstWhereOrNull((element) => element.boxNote==inv.boxNote);\n          dtl?.hasSelect=false;//仓库不对的行不加入出库任务\n        }\n      }\n    }\n  }\n\n  void showCalendar() {\n    SmartManager().showCenterDialog(CalendarDialog(\n      value: dateTime,\n      callback: (dates) {\n        List<DateTime> newDates = dates.map((e) => e!).toList();\n        dateTime = newDates;\n        if (dateTime.length == 1) {\n          time.value = dateTime.first.toString().substring(0, 10);\n        }\n      },\n    ));\n  }\n  ///统计一下不可选的数量，作用于控制全选按钮状态\n  void _initCannotCount(){\n    if(!isListEmpty(whsOutDtl)){\n      int canSelectCount=0;\n      for (var element in whsOutDtl!) {\n        if(strNotEmpty(element.storageNo)){\n          canSelectCount++;\n        }\n      }\n      _cannotSelectCount=whsOutDtl!.length-canSelectCount;\n    }\n  }\n\n}\n
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/lib/page/domestic/take_off/cn_take_off_details_controller.dart b/lib/page/domestic/take_off/cn_take_off_details_controller.dart
--- a/lib/page/domestic/take_off/cn_take_off_details_controller.dart	(revision 7a02fce56783d3de50e090857f5f0ae0e5fcb1f4)
+++ b/lib/page/domestic/take_off/cn_take_off_details_controller.dart	(date 1721792380141)
@@ -333,7 +333,7 @@
       model.hasSelect = hasSelect;
     }
     //在列表中更改选中的项
-    _changeItem(allData,model);
+    _changeItem(allData,model);//本来就是同个对象，还需要再操作一遍？
     //在展示列表中更改选中的项
     // _changeItem(itemData,model);
     checkCanSubmit();
Index: lib/common/http/common_http_manager.dart
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
<+>import 'dart:io';\n\nimport 'package:dio/src/dio.dart';\nimport 'package:dio/src/dio_exception.dart';\nimport 'package:dio/src/dio_mixin.dart';\nimport 'package:dio_cache_interceptor/src/model/cache_options.dart';\nimport 'package:flutter/foundation.dart';\nimport 'package:flutter_smart_dialog/flutter_smart_dialog.dart';\nimport 'package:public_lib/net/abstract/http_manager.dart';\nimport 'package:public_lib/net/abstract/net_dio_abstract.dart';\nimport 'package:public_lib/net/config/core_config.dart';\nimport 'package:public_lib/net/interceptors/logs_interceptors.dart';\nimport 'package:public_lib/net/model/result_data.dart';\nimport 'package:public_lib/utils/file_utils.dart';\nimport 'package:public_lib/utils/platform_utils.dart';\nimport 'package:sentry_flutter/sentry_flutter.dart';\nimport 'package:smps_flutter_pda/common/db/database_manager.dart';\nimport 'package:smps_flutter_pda/common/sentry_init.dart';\nimport 'package:smps_flutter_pda/common/smps_core_config.dart';\nimport 'package:smps_flutter_pda/common/spms_application.dart';\nimport 'package:smps_flutter_pda/page/login/controller/login_controller.dart';\nimport 'package:smps_flutter_pda/page/login/login_page.dart';\nimport 'package:smps_flutter_pda/page/login/model/login_model.dart';\nimport 'package:smps_flutter_pda/utils/navigator_utils.dart';\nimport 'package:sp_util/sp_util.dart';\nimport 'package:dio_cache_interceptor_file_store/dio_cache_interceptor_file_store.dart';\nimport 'package:dio_cache_interceptor/dio_cache_interceptor.dart';\nimport 'package:get/get.dart';\n\n///在这里定义基础的请求配置信息\nclass CommonHttpManager extends NetDioAbstract {\n  static final CommonHttpManager _instance = CommonHttpManager._();\n\n  factory CommonHttpManager() {\n    return _instance;\n  }\n\n  CommonHttpManager._();\n\n\n  ///提供给外部使用\n  static String get getBaseUrl {\n    //debug模式下，默认用develop的域名环境比较合理\n    bool useDevEnv=kDebugMode&&(SpUtil.getString(SPMSCoreConfig.ENV)!=SPMSCoreConfig.release);\n    String url=(useDevEnv?SPMSCoreConfig.HOST_PRO:SPMSCoreConfig.HOST_RES)+SPMSCoreConfig.PROJECT;\n    if(SpUtil.getString(SPMSCoreConfig.ENV)==SPMSCoreConfig.develop){\n      url=SPMSCoreConfig.HOST_PRO+SPMSCoreConfig.PROJECT;\n    }\n    return url;\n  }\n\n  ///使用提供给外部的拦截器\n  @override\n  List<Interceptor> dioAddInterceptors(Dio dio) {\n    return [SentryInterceptor()];\n    // return [];\n  }\n\n  @override\n  Map<String, dynamic> baseHeaders() {\n    Map<String, dynamic> queryParameters = {};\n    //token\n    queryParameters['token'] = SPMSApplication().userInfo?.token;\n    // queryParameters['token'] = SPMSApplication().userInfo?.token?.toUpperCase();//临时测试token变化时拦截错误\n    return queryParameters;\n  }\n\n  @override\n  Future<CacheOptions> getCacheOptions() async {\n    Directory directory = await FileUtils.getAppDirectory();\n    CacheOptions cacheOptions = CacheOptions(\n      store: FileCacheStore(\"${directory.path}dio_cache\"),\n      policy: CachePolicy.request,\n      hitCacheOnErrorExcept: [401, 403],\n      maxStale: const Duration(days: 7),\n      priority: CachePriority.normal,\n      keyBuilder: createKeyBuilder,\n    );\n    return cacheOptions;\n  }\n\n  @override\n  bool openProxyMan() {\n    return  false;//todo 注意发布的时候代理要关掉\n  }\n\n  @override\n  String proxyHost() {\n    return '192.168.3.12';\n  }\n\n  @override\n  String proxyPost() {\n    return '9090';\n  }\n\n  @override\n  String baseUrl() =>getBaseUrl;\n\n  @override\n  void addSSlPinning() {}\n}\n//token失效：401，重定向到登录页\nclass TokenInvalidInterceptor extends LogsInterceptors{\n  @override\n  void onError(DioError err, ErrorInterceptorHandler handler) {\n    Get.log(\"发生错误：${err.response?.statusCode}\");\n    if(err.response?.statusCode==401){\n      Get.put(LoginController());\n      NavigatorUtils.offAllNamed(LoginPage.routeName);\n      return;\n    }\n    super.onError(err, handler);\n  }\n}\n\nclass SentryInterceptor extends InterceptorsWrapper{\n  @override\n  void onError(DioException err, ErrorInterceptorHandler handler) {\n    String path = '\\n path: ${err.requestOptions.path},';\n    String error = '\\n error: ${err.message},';\n    String request = '\\n request: ${err.requestOptions.data},';\n    String response = '\\n response: ${err.response?.data}';\n    String account = '\\n account: ${SPMSApplication().userInfo?.userInfo?.userId}';\n    String msg = '$path$error$request$response$account';\n    String errMsg = '${err.toString()} $msg';\n    SentryEvent event = SentryInit.getNetSentryEvent(\n      error: err,\n      stackTrace: err.stackTrace,\n      message: errMsg,\n      path: err.requestOptions.path,\n    );\n    SentryInit.senNetLog(event);\n    super.onError(err, handler);\n  }\n}\n
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/lib/common/http/common_http_manager.dart b/lib/common/http/common_http_manager.dart
--- a/lib/common/http/common_http_manager.dart	(revision 7a02fce56783d3de50e090857f5f0ae0e5fcb1f4)
+++ b/lib/common/http/common_http_manager.dart	(date 1727406532141)
@@ -81,7 +81,7 @@
 
   @override
   bool openProxyMan() {
-    return  false;//todo 注意发布的时候代理要关掉
+    return  true;//todo 注意发布的时候代理要关掉
   }
 
   @override
Index: lib/main.dart
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
<+>import 'dart:io';\n\nimport 'package:flutter/material.dart';\nimport 'package:flutter_smart_dialog/flutter_smart_dialog.dart';\nimport 'package:form_builder_validators/form_builder_validators.dart';\nimport 'package:get/get.dart';\nimport 'package:public_lib/global/global.dart';\nimport 'package:public_lib/net/config/core_config.dart';\nimport 'package:public_lib/utils/language_util.dart';\nimport 'package:smps_flutter_pda/common/android_channel/android_channel_listener.dart';\nimport 'package:smps_flutter_pda/common/app_ui.dart';\nimport 'package:smps_flutter_pda/common/app_ui_config.dart';\nimport 'package:smps_flutter_pda/common/db/database_manager.dart';\nimport 'package:smps_flutter_pda/common/http/common_http_manager.dart';\nimport 'package:smps_flutter_pda/common/http/http.dart';\nimport 'package:smps_flutter_pda/common/route/app_pages.dart';\nimport 'package:flutter_localizations/flutter_localizations.dart';\nimport 'package:smps_flutter_pda/common/sentry_init.dart';\nimport 'package:smps_flutter_pda/common/smps_core_config.dart';\nimport 'package:smps_flutter_pda/common/spms_application.dart';\nimport 'package:smps_flutter_pda/common/spms_navigator_observer.dart';\nimport 'package:smps_flutter_pda/common/ume_init.dart';\nimport 'package:smps_flutter_pda/page/login/login_page.dart';\nimport 'package:smps_flutter_pda/page/login/model/account_model.dart';\nimport 'package:smps_flutter_pda/page/login/model/login_model.dart';\nimport 'package:smps_flutter_pda/page/main/main_page.dart';\nimport 'package:smps_flutter_pda/res/translation_service.dart';\nimport 'package:smps_flutter_pda/utils/log_pretty.dart';\n\nimport 'common/imageloader/app_image_config.dart';\nimport 'package:public_lib/ui/imageloader/image_loader.dart';\nimport 'package:flutter_screenutil/flutter_screenutil.dart';\n\nvoid main() {\n  //https://b089332284a949259ca8c6d05d3e378f@sentry.globaltradecoo.com/4\n  WidgetsFlutterBinding.ensureInitialized();\n  LogPretty.getxLogPrettyConfig();//美化GetX日志\n  Global.init((){\n    Get.put(ApiService(CommonHttpManager()));\n    Get.put(AndroidChannelListener());\n  }).then((value) async{\n    await CommonHttpManager().initNetDio(CommonHttpManager().setDio());\n    await AppUI.init(AppUiConfig());\n    await ImageLoader.init(AppImageConfig());\n    // HttpManager.init(CommonHttpManager());\n    await DatabaseManager().openDatabase();\n    await SPMSApplication().init();\n    await checkLogin();\n  }).then((value){\n    HttpOverrides.global = MyHttpOverrides();//忽略证书验证的话，打开注释即可\n    if(CoreConfig.DEBUG||CoreConfig.kProfileMode){\n      SentryInit.sentryInit(child: UMEInit.init(_buildApp()));\n    }else{\n      SentryInit.sentryInit(child: _buildApp());\n    }\n  });\n}\n\nclass MyHttpOverrides extends HttpOverrides{\n  @override\n  HttpClient createHttpClient(SecurityContext? context){\n    return super.createHttpClient(context)\n      ..badCertificateCallback = (X509Certificate cert, String host, int port)=> true;\n  }\n}\n//用登录信息来检查是否需要到登录页\nFuture<void> checkLogin()async{\n  LoginModel? loginModel = await DatabaseManager().isar?.loginModels.get(1);\n  if(loginModel!=null){\n    SPMSApplication().userInfo=loginModel;\n  }\n}\nWidget _buildApp(){\n  return ScreenUtilInit(\n    builder: () {\n      return GetMaterialApp(\n        title: 'SMPS',\n        theme: ThemeData(\n          primarySwatch: Colors.blue,\n        ),\n        // enableLog: CoreConfig.kProfileMode,\n        // initialRoute:SPMSApplication().isLogin?MainPage.routeName:LoginPage.routeName,\n        initialRoute:LoginPage.routeName,\n        getPages: AppPages.routes,\n        locale: LanguageUtil.initLanguage().toLocale(),\n        supportedLocales: Global.languages.map((e) => e.toLocale()).toList(),\n        localizationsDelegates: const [\n          GlobalMaterialLocalizations.delegate,\n          GlobalWidgetsLocalizations.delegate,\n          GlobalCupertinoLocalizations.delegate,\n          FormBuilderLocalizations.delegate,\n        ],\n        navigatorObservers: [\n          SPMSNavigatorObserver()\n        ],\n        translations: TranslationService(),\n        builder: FlutterSmartDialog.init(),\n      );\n    },\n    designSize: const Size(SPMSCoreConfig.WIDTH, SPMSCoreConfig.HEIGHT),\n  );\n}\n\n\n\n
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/lib/main.dart b/lib/main.dart
--- a/lib/main.dart	(revision 7a02fce56783d3de50e090857f5f0ae0e5fcb1f4)
+++ b/lib/main.dart	(date 1727406655609)
@@ -49,8 +49,8 @@
   }).then((value){
     HttpOverrides.global = MyHttpOverrides();//忽略证书验证的话，打开注释即可
     if(CoreConfig.DEBUG||CoreConfig.kProfileMode){
-      SentryInit.sentryInit(child: UMEInit.init(_buildApp()));
-    }else{
+    //   SentryInit.sentryInit(child: UMEInit.init(_buildApp()));
+    // }else{
       SentryInit.sentryInit(child: _buildApp());
     }
   });
Index: lib/page/login/controller/login_controller.dart
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
<+>import 'package:smps_flutter_pda/page/hi_getcontroller.dart';\nimport 'package:smps_flutter_pda/res/strings.dart';\nimport 'package:flutter/cupertino.dart';\nimport 'package:flutter_smart_dialog/flutter_smart_dialog.dart';\nimport 'package:isar/isar.dart';\nimport 'package:public_lib/extension/json_parse_utils.dart';\nimport 'package:public_lib/model/language_model.dart';\nimport 'package:public_lib/net/model/result_data.dart';\nimport 'package:public_lib/ui/base_getx.dart';\nimport 'package:get/get.dart';\nimport 'package:public_lib/utils/language_util.dart';\nimport 'package:smps_flutter_pda/common/db/database_manager.dart';\nimport 'package:smps_flutter_pda/common/http/common_http_manager.dart';\nimport 'package:smps_flutter_pda/common/smps_core_config.dart';\nimport 'package:smps_flutter_pda/common/spms_application.dart';\nimport 'package:smps_flutter_pda/page/login/model/account_model.dart';\nimport 'package:smps_flutter_pda/page/login/model/login_model.dart';\nimport 'package:smps_flutter_pda/page/main/main_page.dart';\nimport 'package:smps_flutter_pda/utils/navigator_utils.dart';\nimport 'package:smps_flutter_pda/utils/smart_manager.dart';\nimport 'package:sp_util/sp_util.dart';\n\nimport '../../../common/http/http.dart';\n\nclass LoginBindings extends BaseBindings {\n  @override\n  void dependencies() {\n    Get.lazyPut<LoginController>(() => LoginController());\n  }\n}\n\nclass LoginController extends HiGetController {\n\n  ///账号\n  TextEditingController account = TextEditingController();\n\n  ///密码\n  TextEditingController password = TextEditingController();\n\n  ///账号焦点\n  FocusNode accountFN = FocusNode();\n\n  ///密码焦点\n  FocusNode passwordFN = FocusNode();\n\n  ///是否显示密码\n  RxBool showPassword = true.obs;\n\n  ///是否记住密码\n  RxBool rememberPassword = false.obs;\n\n  ///是否可以点击登陆\n  RxBool canLogin = false.obs;\n\n  ///语言切换\n  List<LanguageModel> languages = [\n    LanguageModel('English', 'en', 'US'),\n    LanguageModel('简体中文', 'zh', 'CN'),\n    LanguageModel('Français', 'fr', 'FR'),\n    LanguageModel('Русский язык', 'ru', 'RU'),\n    // LanguageModel('kiswahili', 'sw', 'SW')\n  ];\n  @override\n  void onInit() async{\n    super.onInit();\n    accountFN.addListener(_accountFnListener);\n    passwordFN.addListener(_psdFnListener);\n    account.addListener(_accountListener);\n    password.addListener(_accountListener);\n    AccountModel? accountModel =\n        await DatabaseManager().isar?.accountModels.get(1);\n    if (accountModel != null && accountModel.userId!.isNotEmpty) {\n      account.text = accountModel.userId ?? '';\n      password.text = accountModel.password ?? '';\n    }\n  }\n\n  @override\n  onClose(){\n    accountFN.removeListener(_accountFnListener);\n    passwordFN.removeListener(_psdFnListener);\n    account.removeListener(_accountListener);\n    password.removeListener(_accountListener);\n    account.dispose();\n    password.dispose();\n  }\n\n  void _accountFnListener(){\n    if (accountFN.hasFocus) {\n      passwordFN.unfocus();\n    }\n  }\n\n  void _accountListener() {\n    canLogin.value = account.text.isNotEmpty && password.text.isNotEmpty;\n  }\n\n  void _psdFnListener() {\n    if (passwordFN.hasFocus) {\n      accountFN.unfocus();\n    }\n  }\n\n  ///清除密码\n  void clearPassword() {\n    account.text = '';\n    password.text = '';\n  }\n\n  List<String> wareList=[];\n  ///登陆\n  Future<bool> login(\n      {String? account, String? password, bool? showDialog}) async {\n    // if(account==null){\n    //   wareList.clear();\n    //   wareList.addAll([\"1\"]);\n    //\n    //   return false;\n    // }\n\n\n\n    if (account == null && password == null) {\n      if (this.account.text.isEmpty) {\n        SmartManager().showCenterToast(Ids.loginAccountCannotBeEmpty.tr);\n        return false;\n      }\n      if (!_getPasswordErrorMessage(this.password.text.trim())) {\n        return false;\n      }\n    }\n    Map<String, dynamic> map = {}\n      ..put('password', password ?? this.password.text)\n      ..put('userId', account ?? this.account.text);\n    ResultData resultData = await apiService.login(map, showDialog ?? true);\n    if (resultData.isSuccess()) {\n      LoginModel loginModel = resultData.data;\n      SPMSApplication().userInfo = loginModel;\n      SPMSApplication().initWareWhsLocationBeans();\n      Isar? isar = DatabaseManager().isar;\n      isar?.writeTxn(() async {\n        await isar.loginModels.put(loginModel);\n      });\n      String accountStr = '';\n      String passwordStr = '';\n      //记住密码的时候需要保存账号密码，用于下次直接登陆\n      AccountModel? accountModelGet =\n          await DatabaseManager().isar?.accountModels.get(1);\n      if (accountModelGet != null && accountModelGet.userId!.isNotEmpty) {\n        accountStr = accountModelGet.userId ?? '';\n        passwordStr = accountModelGet.password ?? '';\n      }\n      AccountModel accountModel = AccountModel(\n          userId: this.account.text.isEmpty ? accountStr : this.account.text,\n          password:\n              this.password.text.isEmpty ? passwordStr : this.password.text);\n      DatabaseManager().saveData(() => isar?.accountModels.put(accountModel));\n      //登陆之后，通过权限默认第一个仓库\n      if( SpUtil.getString(SPMSCoreConfig.WARE_HOUSE)==null|| SpUtil.getString(SPMSCoreConfig.WARE_HOUSE)!.isEmpty){\n        SpUtil.putString(SPMSCoreConfig.WARE_HOUSE,\n            SPMSApplication().userInfo?.userWhs?.first.werks ?? '');\n      }\n      //初始化工厂集\n      if(SPMSApplication().wareList!.isEmpty){\n        SPMSApplication().setWareList([SPMSApplication().userInfo?.userWhs?.first.werks ?? '']);\n      }\n      Get.log(\"登录成功：工厂集：${SPMSApplication().wareList}\");\n      NavigatorUtils.offPage(MainPage.routeName);\n    }else{\n      SmartManager().showCenterToast(resultData.msg);\n    }\n\n    return resultData.isSuccess();\n  }\n\n  ///校对密码格式\n  bool _getPasswordErrorMessage(String password) {\n    if (password.length < 8) {\n      SmartManager().showCenterToast(Ids.passwordMustContainAtLeast8Characters.tr);\n      return false;\n    }\n    if (!RegExp(r'[a-z]').hasMatch(password)) {\n      SmartManager().showCenterToast(Ids.passwordMustContainAtLeastOneLowercaseLetter.tr);\n      return false;\n    }\n    if (!RegExp(r'[A-Z]').hasMatch(password)) {\n      SmartManager().showCenterToast(Ids.passwordMustContainAtLeastOneUppercaseLetter.tr);\n      return false;\n    }\n    if (!RegExp(r'\\d').hasMatch(password)) {\n      SmartManager().showCenterToast(Ids.passwordMustContainAtLeastOneNumber.tr);\n      return false;\n    }\n    return true;\n  }\n\n  ///更新语言\n  Future<void> changeLanguage(LanguageModel model) async {\n    LanguageUtil.setLocalModel(model, false);\n    SmartDialog.dismiss();\n  }\n}\n
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/lib/page/login/controller/login_controller.dart b/lib/page/login/controller/login_controller.dart
--- a/lib/page/login/controller/login_controller.dart	(revision 7a02fce56783d3de50e090857f5f0ae0e5fcb1f4)
+++ b/lib/page/login/controller/login_controller.dart	(date 1727404754099)
@@ -32,10 +32,10 @@
 class LoginController extends HiGetController {
 
   ///账号
-  TextEditingController account = TextEditingController();
+  TextEditingController account = TextEditingController()..text='10043398';
 
   ///密码
-  TextEditingController password = TextEditingController();
+  TextEditingController password = TextEditingController()..text='Spms123456';
 
   ///账号焦点
   FocusNode accountFN = FocusNode();
Index: lib/common/db/database_manager.dart
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
<+>import 'package:flutter/material.dart';\nimport 'package:isar/isar.dart';\nimport 'package:path_provider/path_provider.dart';\nimport 'package:smps_flutter_pda/page/login/model/account_model.dart';\nimport 'package:smps_flutter_pda/page/login/model/login_model.dart';\nimport 'package:smps_flutter_pda/page/message/application_details/model/application_details_data_model.dart';\nimport 'package:smps_flutter_pda/page/message/model/application_list_model.dart';\nimport 'package:smps_flutter_pda/page/message/return_apply_details/model/return_apply_details_data_model.dart';\nimport 'package:smps_flutter_pda/page/message/return_apply_list/model/return_apply_list_model.dart';\nimport 'package:smps_flutter_pda/page/offline/model/offline_post_list_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/dump_task/model/dump_task_list_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/dump_task_details/model/dump_task_details_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/inbound_list/model/all_oversea_inbound_task_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/inbound_list/model/other_delivery_task_data_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/inbound_list/model/other_inbound_dateils_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/inbound_list/model/oversea_inbound_detalis_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/inventory/model/inventory_list_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/inventory_details/model/inventory_details_data_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/other_delivery_details/model/other_delivery_details_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/out_warehouse_details/model/out_warehouse_details_data_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/out_warehouse_list/model/out_warehouse_list_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/oversea_delivery_details/model/oversea_delivery_note_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/overseas_delivery/model/other_delivery_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/overseas_delivery/model/oversea_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/return_warehouse_details/model/return_warehouse_details_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/return_warehouse_list/model/return_warehouse_list_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/shift/model/all_storage_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/shift/model/materials_model.dart';\nimport 'package:smps_flutter_pda/page/overseas/stock/model/stock_list_model.dart';\n\nclass DatabaseManager {\n  static final DatabaseManager _instance = DatabaseManager._();\n\n  factory DatabaseManager() {\n    return _instance;\n  }\n\n  DatabaseManager._();\n\n  Isar? isar;\n\n  Future<void> openDatabase() async {\n    final dir = await getApplicationDocumentsDirectory();\n    isar = await Isar.open([\n      //用户信息\n      LoginModelSchema,\n      //账号密码\n      AccountModelSchema,\n      //离线提交列表\n      OfflinePostListModelSchema,\n      //所有物料基础信息\n      MaterialsModelSchema,\n      //所有储位信息\n      AllStorageModelSchema,\n      //海运收货列表\n      OverseaModelSchema,\n      //其他收货列表\n      OtherDeliveryModelSchema,\n      //海运收货所有的交货单明细\n      OverseaDeliveryNoteModelSchema,\n      //其他收货所有的交货单明细\n      OtherDeliveryDetailsModelSchema,\n      //所有入库列表-海运收货的入库任务\n      AllOverseaInboundTaskModelSchema,\n      //所有入库列表-海运收货的入库任务明细\n      OverseaInboundDetalisModelSchema,\n      //入库列表-本地采购所有的入库单任务\n      OtherDeliveryTaskDataModelSchema,\n      //入库列表-本地采购所有入库明细\n      OtherInboundDateilsModelSchema,\n      //所有领用申请\n      ApplicationListModelSchema,\n      //所有领用单详情\n      AllApplicationDetailsDataModelSchema,\n      //所有退料申请\n      ReturnApplyListModelSchema,\n      //所有退料申请明细\n      ReturnApplyDetailsDataModelSchema,\n      //转储列表\n      DumpTaskListModelSchema,\n      //所有转储详情\n      DumpTaskDetailsModelSchema,\n      //所有出库列表数据\n      OutWarehouseListModelSchema,\n      //所有出库详情\n      OutWarehouseDetailsDataModelSchema,\n      //所有退库列表\n      ReturnWarehouseListModelSchema,\n      //所有退库详情\n      ReturnWarehouseDetailsModelSchema,\n      //盘点列表\n      InventoryListModelSchema,\n      //盘点详情\n      InventoryDetailsDataModelSchema,\n      //库存明细\n      StockListModelSchema,\n    ], directory: dir.path, name: 'spms-db.isar');\n  }\n\n  ///写入或者修改数据库\n  Future<void> saveData(Function() fun) async {\n    await isar?.writeTxn(() async {\n      try {\n        await fun();\n      } catch (e) {\n        debugPrint('saveData  error--- ${e.toString}');\n      }\n    });\n  }\n}\n
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/lib/common/db/database_manager.dart b/lib/common/db/database_manager.dart
--- a/lib/common/db/database_manager.dart	(revision 7a02fce56783d3de50e090857f5f0ae0e5fcb1f4)
+++ b/lib/common/db/database_manager.dart	(date 1721792380134)
@@ -2,6 +2,7 @@
 import 'package:isar/isar.dart';
 import 'package:path_provider/path_provider.dart';
 import 'package:smps_flutter_pda/page/login/model/account_model.dart';
+import 'package:smps_flutter_pda/page/login/model/log_model.dart';
 import 'package:smps_flutter_pda/page/login/model/login_model.dart';
 import 'package:smps_flutter_pda/page/message/application_details/model/application_details_data_model.dart';
 import 'package:smps_flutter_pda/page/message/model/application_list_model.dart';
@@ -94,6 +95,8 @@
       InventoryDetailsDataModelSchema,
       //库存明细
       StockListModelSchema,
+      //日志模型（测试）
+      LogModelSchema,
     ], directory: dir.path, name: 'spms-db.isar');
   }
 
