wzx 2 лет назад
Родитель
Сommit
4158ff7562
42 измененных файлов с 924 добавлено и 1519 удалено
  1. 1 1
      android/app/src/main/kotlin/com/beswell/asistent_app/MainActivity.kt
  2. 1 1
      gen_proto.bat
  3. 55 22
      lib/bindings.dart
  4. 6 0
      lib/generated/assets.dart
  5. 114 0
      lib/generated/base.pb.dart
  6. 36 0
      lib/generated/base.pbenum.dart
  7. 59 0
      lib/generated/base.pbjson.dart
  8. 5 4
      lib/global.dart
  9. 2 2
      lib/main.dart
  10. 2 2
      lib/model.dart
  11. 62 62
      lib/model/m_control_point.dart
  12. 19 0
      lib/model/m_net_image.dart
  13. 19 18
      lib/model/map_info.dart
  14. 4 6
      lib/pb.dart
  15. 21 26
      lib/route.dart
  16. 3 3
      lib/service/all_init.dart
  17. 154 379
      lib/service/api.dart
  18. 15 11
      lib/service/app.dart
  19. 25 3
      lib/service/app_map.dart
  20. 4 2
      lib/service/database.dart
  21. 22 22
      lib/service/game/game_model.dart
  22. 53 764
      lib/service/map/map.dart
  23. 4 4
      lib/service/map/map_status.dart
  24. 2 2
      lib/service/mock.dart
  25. 12 12
      lib/service/user_profile.dart
  26. 24 4
      lib/utils.dart
  27. 32 32
      lib/view/app_update_view.dart
  28. 13 14
      lib/view/home/home_controller.dart
  29. 7 7
      lib/view/home/home_view.dart
  30. 11 17
      lib/view/login/login_controller.dart
  31. 2 2
      lib/view/login/login_view.dart
  32. 11 12
      lib/view/maplist/map_list_controller.dart
  33. 32 22
      lib/view/maplist/map_list_view.dart
  34. 6 5
      lib/view/mapto/activity_view.dart
  35. 6 5
      lib/view/mapto/map_to_controller.dart
  36. 7 1
      lib/view/mapto/map_to_view.dart
  37. 1 1
      lib/view/privacy/privacy_settings_view.dart
  38. 58 47
      lib/widget/app_net_image.dart
  39. 4 3
      lib/widget/page_frame.dart
  40. 1 1
      protos/app_api
  41. 8 0
      pubspec.lock
  42. 1 0
      pubspec.yaml

+ 1 - 1
android/app/src/main/kotlin/com/beswell/asistent_app/MainActivity.kt

@@ -15,7 +15,7 @@ import io.flutter.plugin.common.MethodChannel
 
 class MainActivity: FlutterActivity() {
     companion object{
-        private const val CHANNEL = "com.beswell.app/api"
+        private const val CHANNEL = "com.beswell.toapp/api"
         private const val REQUEST_CODE_ENABLE_NFC = 1
         private const val TAG = "MainActivity"
         private const val ERROR_NOT_SUPPORT = "ERROR_NOT_SUPPORT"

+ 1 - 1
gen_proto.bat

@@ -1,2 +1,2 @@
-protoc -I protos/app_api app_api.proto --dart_out=grpc:lib/generated google/protobuf/timestamp.proto google/protobuf/duration.proto google/protobuf/any.proto
+protoc -I protos/app_api to_app_api.proto --dart_out=grpc:lib/generated google/protobuf/timestamp.proto google/protobuf/duration.proto google/protobuf/any.proto
 protoc -I protos/app_api base.proto --dart_out=grpc:lib/generated google/protobuf/timestamp.proto google/protobuf/duration.proto google/protobuf/any.proto

+ 55 - 22
lib/bindings.dart

@@ -1,11 +1,14 @@
 import 'package:get/get.dart';
 import 'package:trackoffical_app/app_init_page.dart';
 import 'package:trackoffical_app/route.dart';
-import 'package:trackoffical_app/view/app_need_update_view.dart';
-import 'package:trackoffical_app/view/home/home_save_user_info_view.dart';
+import 'package:trackoffical_app/service/app.dart';
+// import 'package:trackoffical_app/view/app_need_update_view.dart';
+// import 'package:trackoffical_app/view/home/home_save_user_info_view.dart';
 import 'package:trackoffical_app/view/home/home_view.dart';
 // import 'package:trackoffical_app/view/ingame/settlement_view.dart';
 import 'package:trackoffical_app/view/login/login_view.dart';
+import 'package:trackoffical_app/view/maplist/map_list_view.dart';
+import 'package:trackoffical_app/view/mapto/map_to_view.dart';
 import 'package:trackoffical_app/view/test/test_view.dart';
 // import 'package:trackoffical_app/view/ingame/in_game_loading.dart';
 
@@ -15,37 +18,67 @@ class AppBindings{
     return [
       GetPage(
           name: RouteName.init,
-          page: ()=>const AppInitPage(),
+          page: () => const AppInitPage(),
           binding: AppInitPage.bindings()),
-      GetPage(
-          name: RouteName.test,
-          page: ()=>const TestView(),
-          binding: TestView.bindings()),
-      GetPage(
-          name: RouteName.home,
-          page: ()=>const HomeView(),
-          binding: HomeView.bindings()),
       GetPage(
         name: RouteName.signIn,
-        page: ()=>const LoginView(),
+        page: () => const LoginView(),
         binding: LoginView.loginBind(),
       ),
+      GetPage(
+          name: RouteName.mapsList,
+          page: () => const MapListView(),
+          binding: MapListView.bindings()),
+      GetPage(
+          name: RouteName.mapTO,
+          // page: () => MapToView(mapId: App.to.selectedMapId.value),
+          page: () => const MapToView(),
+          binding: MapToView.bindings()),
+      // GetPage(
+      //     name: RouteName.userAdmin,
+      //     page: () => const MapToView(),
+      //     binding: MapToView.bindings()),
+      // GetPage(
+      //     name: RouteName.userRank,
+      //     page: () => const MapToView(),
+      //     binding: MapToView.bindings()),
+      // GetPage(
+      //     name: RouteName.groupRank,
+      //     page: () => const MapToView(),
+      //     binding: MapToView.bindings()),
+      // GetPage(
+      //     name: RouteName.sportData,
+      //     page: () => const MapToView(),
+      //     binding: MapToView.bindings()),
+      // GetPage(
+      //     name: RouteName.setting,
+      //     page: () => const MapToView(),
+      //     binding: MapToView.bindings()),
+
+      // GetPage(
+      //     name: RouteName.test,
+      //     page: () => const TestView(),
+      //     binding: TestView.bindings()),
+      // GetPage(
+      //     name: RouteName.home,
+      //     page: () => const HomeView(),
+      //     binding: HomeView.bindings()),
       // GetPage(
       //     name: RouteName.gameLoading,
-      //     page: ()=>const InGameLoadingView(),
+      //     page: () => const InGameLoadingView(),
       //     binding: InGameLoadingView.bindingsToGame()),
-      GetPage(
-          name: RouteName.needUpdate,
-          page: ()=>const AppNeedUpdateView(),
-          binding: AppNeedUpdateView.bindings()),
+      // GetPage(
+      //     name: RouteName.needUpdate,
+      //     page: () => const AppNeedUpdateView(),
+      //     binding: AppNeedUpdateView.bindings()),
       // GetPage(
       //     name: RouteName.settlement,
-      //     page: ()=>const SettlementView(),
+      //     page: () => const SettlementView(),
       //     binding: SettlementView.bindings()),
-      GetPage(
-          name: RouteName.homeSaveUserInfo,
-          page: ()=>const HomeSaveUserInfoView(),
-          binding: HomeSaveUserInfoView.bindings()),
+      // GetPage(
+      //     name: RouteName.homeSaveUserInfo,
+      //     page: () => const HomeSaveUserInfoView(),
+      //     binding: HomeSaveUserInfoView.bindings()),
     ];
   }
 }

+ 6 - 0
lib/generated/assets.dart

@@ -4,6 +4,7 @@ class Assets {
 
   static const String assetsImagesBkCheckPoint = 'assets/images/bk_check_point.svg';
   static const String commonPageBg = 'assets/images/common/page_bg.png';
+  static const String commonPageBgDark = 'assets/images/common/page_bg_dark.png';
   static const String dataRegion = 'assets/data/region.txt';
   static const String imagesAmAppStartArrow = 'assets/images/am_app_start_arrow.riv';
   static const String imagesAmPunchButtonFlash = 'assets/images/am_punch_button_flash.riv';
@@ -122,6 +123,9 @@ class Assets {
   static const String imagesIcFinishCal = 'assets/images/ic_finish_cal.png';
   static const String imagesIcFinishOdometer = 'assets/images/ic_finish_odometer.png';
   static const String imagesIcFinishTime = 'assets/images/ic_finish_time.png';
+  static const String imagesIcFlagBlue = 'assets/images/ic_flag_blue.png';
+  static const String imagesIcFlagRed = 'assets/images/ic_flag_red.png';
+  static const String imagesIcFlagYellow = 'assets/images/ic_flag_yellow.png';
   static const String imagesIcHeart = 'assets/images/ic_heart.png';
   static const String imagesIcHisDistance = 'assets/images/ic_his_distance.png';
   static const String imagesIcHisDuration = 'assets/images/ic_his_duration.png';
@@ -149,6 +153,8 @@ class Assets {
   static const String imagesIcQrCode = 'assets/images/ic_qr_code.png';
   static const String imagesIcRadio = 'assets/images/ic_radio.png';
   static const String imagesIcRadioSelected = 'assets/images/ic_radio_selected.png';
+  static const String imagesIcRadioSelectedGray = 'assets/images/ic_radio_selected_gray.png';
+  static const String imagesIcRadioSelectedOrange = 'assets/images/ic_radio_selected_orange.png';
   static const String imagesIcRank = 'assets/images/ic_rank.png';
   static const String imagesIcReLocation = 'assets/images/ic_re_location.png';
   static const String imagesIcRectAltitude = 'assets/images/ic_rect_altitude.png';

+ 114 - 0
lib/generated/base.pb.dart

@@ -282,6 +282,78 @@ class SignInReply extends $pb.GeneratedMessage {
   void clearToken() => clearField(1);
 }
 
+class GameArriveControlPoint extends $pb.GeneratedMessage {
+  factory GameArriveControlPoint() => create();
+  GameArriveControlPoint._() : super();
+  factory GameArriveControlPoint.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory GameArriveControlPoint.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'GameArriveControlPoint', package: const $pb.PackageName(_omitMessageNames ? '' : 'base.v1'), createEmptyInstance: create)
+    ..aInt64(1, _omitFieldNames ? '' : 'id')
+    ..aOS(2, _omitFieldNames ? '' : 'sn')
+    ..a<$core.int>(3, _omitFieldNames ? '' : 'orderNo', $pb.PbFieldType.O3, protoName: 'orderNo')
+    ..a<$core.int>(4, _omitFieldNames ? '' : 'totalNo', $pb.PbFieldType.O3, protoName: 'totalNo')
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  GameArriveControlPoint clone() => GameArriveControlPoint()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  GameArriveControlPoint copyWith(void Function(GameArriveControlPoint) updates) => super.copyWith((message) => updates(message as GameArriveControlPoint)) as GameArriveControlPoint;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static GameArriveControlPoint create() => GameArriveControlPoint._();
+  GameArriveControlPoint createEmptyInstance() => create();
+  static $pb.PbList<GameArriveControlPoint> createRepeated() => $pb.PbList<GameArriveControlPoint>();
+  @$core.pragma('dart2js:noInline')
+  static GameArriveControlPoint getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GameArriveControlPoint>(create);
+  static GameArriveControlPoint? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $fixnum.Int64 get id => $_getI64(0);
+  @$pb.TagNumber(1)
+  set id($fixnum.Int64 v) { $_setInt64(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get sn => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set sn($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasSn() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearSn() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.int get orderNo => $_getIZ(2);
+  @$pb.TagNumber(3)
+  set orderNo($core.int v) { $_setSignedInt32(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasOrderNo() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearOrderNo() => clearField(3);
+
+  @$pb.TagNumber(4)
+  $core.int get totalNo => $_getIZ(3);
+  @$pb.TagNumber(4)
+  set totalNo($core.int v) { $_setSignedInt32(3, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasTotalNo() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearTotalNo() => clearField(4);
+}
+
 class MapRoute extends $pb.GeneratedMessage {
   factory MapRoute() => create();
   MapRoute._() : super();
@@ -1088,6 +1160,48 @@ class BinaryPart extends $pb.GeneratedMessage {
   void clearNonce() => clearField(4);
 }
 
+class BinaryPartV2 extends $pb.GeneratedMessage {
+  factory BinaryPartV2() => create();
+  BinaryPartV2._() : super();
+  factory BinaryPartV2.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory BinaryPartV2.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'BinaryPartV2', package: const $pb.PackageName(_omitMessageNames ? '' : 'base.v1'), createEmptyInstance: create)
+    ..a<$core.List<$core.int>>(1, _omitFieldNames ? '' : 'data', $pb.PbFieldType.OY)
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  BinaryPartV2 clone() => BinaryPartV2()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  BinaryPartV2 copyWith(void Function(BinaryPartV2) updates) => super.copyWith((message) => updates(message as BinaryPartV2)) as BinaryPartV2;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static BinaryPartV2 create() => BinaryPartV2._();
+  BinaryPartV2 createEmptyInstance() => create();
+  static $pb.PbList<BinaryPartV2> createRepeated() => $pb.PbList<BinaryPartV2>();
+  @$core.pragma('dart2js:noInline')
+  static BinaryPartV2 getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<BinaryPartV2>(create);
+  static BinaryPartV2? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.List<$core.int> get data => $_getN(0);
+  @$pb.TagNumber(1)
+  set data($core.List<$core.int> v) { $_setBytes(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasData() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearData() => clearField(1);
+}
+
 class Image extends $pb.GeneratedMessage {
   factory Image() => create();
   Image._() : super();

+ 36 - 0
lib/generated/base.pbenum.dart

@@ -234,6 +234,42 @@ class GameState extends $pb.ProtobufEnum {
   const GameState._($core.int v, $core.String n) : super(v, n);
 }
 
+class GameHistorySource extends $pb.ProtobufEnum {
+  static const GameHistorySource GameHistorySourcAll = GameHistorySource._(0, _omitEnumNames ? '' : 'GameHistorySourcAll');
+  static const GameHistorySource GameHistorySourceOrienteer = GameHistorySource._(1, _omitEnumNames ? '' : 'GameHistorySourceOrienteer');
+  static const GameHistorySource GameHistorySourceAss = GameHistorySource._(2, _omitEnumNames ? '' : 'GameHistorySourceAss');
+
+  static const $core.List<GameHistorySource> values = <GameHistorySource> [
+    GameHistorySourcAll,
+    GameHistorySourceOrienteer,
+    GameHistorySourceAss,
+  ];
+
+  static final $core.Map<$core.int, GameHistorySource> _byValue = $pb.ProtobufEnum.initByValue(values);
+  static GameHistorySource? valueOf($core.int value) => _byValue[value];
+
+  const GameHistorySource._($core.int v, $core.String n) : super(v, n);
+}
+
+class BackGroundColor extends $pb.ProtobufEnum {
+  static const BackGroundColor UnKnowColor = BackGroundColor._(0, _omitEnumNames ? '' : 'UnKnowColor');
+  static const BackGroundColor BlueColor = BackGroundColor._(1, _omitEnumNames ? '' : 'BlueColor');
+  static const BackGroundColor GreenColor = BackGroundColor._(2, _omitEnumNames ? '' : 'GreenColor');
+  static const BackGroundColor BrownColor = BackGroundColor._(3, _omitEnumNames ? '' : 'BrownColor');
+
+  static const $core.List<BackGroundColor> values = <BackGroundColor> [
+    UnKnowColor,
+    BlueColor,
+    GreenColor,
+    BrownColor,
+  ];
+
+  static final $core.Map<$core.int, BackGroundColor> _byValue = $pb.ProtobufEnum.initByValue(values);
+  static BackGroundColor? valueOf($core.int value) => _byValue[value];
+
+  const BackGroundColor._($core.int v, $core.String n) : super(v, n);
+}
+
 class User_Sex extends $pb.ProtobufEnum {
   static const User_Sex UnDefine = User_Sex._(0, _omitEnumNames ? '' : 'UnDefine');
   static const User_Sex Male = User_Sex._(1, _omitEnumNames ? '' : 'Male');

+ 59 - 0
lib/generated/base.pbjson.dart

@@ -195,6 +195,37 @@ final $typed_data.Uint8List gameStateDescriptor = $convert.base64Decode(
     'CglHYW1lU3RhdGUSEAoMQWxsR2FtZVN0YXRlEAASEwoPTm9ybWFsR2FtZVN0YXRlEAESFQoRYW'
     'Jub3JtYWxHYW1lU3RhdGUQAg==');
 
+@$core.Deprecated('Use gameHistorySourceDescriptor instead')
+const GameHistorySource$json = {
+  '1': 'GameHistorySource',
+  '2': [
+    {'1': 'GameHistorySourcAll', '2': 0},
+    {'1': 'GameHistorySourceOrienteer', '2': 1},
+    {'1': 'GameHistorySourceAss', '2': 2},
+  ],
+};
+
+/// Descriptor for `GameHistorySource`. Decode as a `google.protobuf.EnumDescriptorProto`.
+final $typed_data.Uint8List gameHistorySourceDescriptor = $convert.base64Decode(
+    'ChFHYW1lSGlzdG9yeVNvdXJjZRIXChNHYW1lSGlzdG9yeVNvdXJjQWxsEAASHgoaR2FtZUhpc3'
+    'RvcnlTb3VyY2VPcmllbnRlZXIQARIYChRHYW1lSGlzdG9yeVNvdXJjZUFzcxAC');
+
+@$core.Deprecated('Use backGroundColorDescriptor instead')
+const BackGroundColor$json = {
+  '1': 'BackGroundColor',
+  '2': [
+    {'1': 'UnKnowColor', '2': 0},
+    {'1': 'BlueColor', '2': 1},
+    {'1': 'GreenColor', '2': 2},
+    {'1': 'BrownColor', '2': 3},
+  ],
+};
+
+/// Descriptor for `BackGroundColor`. Decode as a `google.protobuf.EnumDescriptorProto`.
+final $typed_data.Uint8List backGroundColorDescriptor = $convert.base64Decode(
+    'Cg9CYWNrR3JvdW5kQ29sb3ISDwoLVW5Lbm93Q29sb3IQABINCglCbHVlQ29sb3IQARIOCgpHcm'
+    'VlbkNvbG9yEAISDgoKQnJvd25Db2xvchAD');
+
 @$core.Deprecated('Use netImageDescriptor instead')
 const NetImage$json = {
   '1': 'NetImage',
@@ -273,6 +304,22 @@ const SignInReply$json = {
 final $typed_data.Uint8List signInReplyDescriptor = $convert.base64Decode(
     'CgtTaWduSW5SZXBseRIUCgV0b2tlbhgBIAEoCVIFdG9rZW4=');
 
+@$core.Deprecated('Use gameArriveControlPointDescriptor instead')
+const GameArriveControlPoint$json = {
+  '1': 'GameArriveControlPoint',
+  '2': [
+    {'1': 'id', '3': 1, '4': 1, '5': 3, '10': 'id'},
+    {'1': 'sn', '3': 2, '4': 1, '5': 9, '10': 'sn'},
+    {'1': 'orderNo', '3': 3, '4': 1, '5': 5, '10': 'orderNo'},
+    {'1': 'totalNo', '3': 4, '4': 1, '5': 5, '10': 'totalNo'},
+  ],
+};
+
+/// Descriptor for `GameArriveControlPoint`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List gameArriveControlPointDescriptor = $convert.base64Decode(
+    'ChZHYW1lQXJyaXZlQ29udHJvbFBvaW50Eg4KAmlkGAEgASgDUgJpZBIOCgJzbhgCIAEoCVICc2'
+    '4SGAoHb3JkZXJObxgDIAEoBVIHb3JkZXJObxIYCgd0b3RhbE5vGAQgASgFUgd0b3RhbE5v');
+
 @$core.Deprecated('Use mapRouteDescriptor instead')
 const MapRoute$json = {
   '1': 'MapRoute',
@@ -478,6 +525,18 @@ final $typed_data.Uint8List binaryPartDescriptor = $convert.base64Decode(
     'CgpCaW5hcnlQYXJ0EhAKA2V4dBgBIAEoCVIDZXh0EhIKBGRhdGEYAiABKAxSBGRhdGESGgoIYW'
     'xsQ291bnQYAyABKAVSCGFsbENvdW50EhQKBW5vbmNlGAQgASgMUgVub25jZQ==');
 
+@$core.Deprecated('Use binaryPartV2Descriptor instead')
+const BinaryPartV2$json = {
+  '1': 'BinaryPartV2',
+  '2': [
+    {'1': 'data', '3': 1, '4': 1, '5': 12, '10': 'data'},
+  ],
+};
+
+/// Descriptor for `BinaryPartV2`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List binaryPartV2Descriptor = $convert.base64Decode(
+    'CgxCaW5hcnlQYXJ0VjISEgoEZGF0YRgBIAEoDFIEZGF0YQ==');
+
 @$core.Deprecated('Use imageDescriptor instead')
 const Image$json = {
   '1': 'Image',

+ 5 - 4
lib/global.dart

@@ -2,11 +2,12 @@ import 'package:flutter/foundation.dart';
 
 class GlobalVar{
   static bool isMock = false;
-  static String apiHost = "otapi.beswell.com";
-  static int apiPort = 10001;
+  // static String apiHost = "otapi.beswell.com";
+  // static String apiHost = "t-otapi.beswell.com";
+  // static int apiPort = 10001;
+  static String apiHost = "192.168.0.3";
+  static int apiPort = 9099;
   static Flavor flavor=Flavor.normal;
-  // static String apiHost = "192.168.0.3";
-  // static int apiPort = 9091;
 
   /// 任意地点打点
   static bool isGpsTest = true && !kReleaseMode;

+ 2 - 2
lib/main.dart

@@ -17,8 +17,8 @@ Future<void> main() async {
 
   SystemChrome.setPreferredOrientations([
     // DeviceOrientation.portraitUp
-    // DeviceOrientation.landscapeLeft
-    DeviceOrientation.landscapeRight
+    DeviceOrientation.landscapeLeft
+    // DeviceOrientation.landscapeRight
   ]);
   runApp(FlavorBanner(
     color: Colors.blue,

+ 2 - 2
lib/model.dart

@@ -7,8 +7,8 @@ export 'model/map_mode.dart';
 export 'model/m_net_image.dart';
 export 'model/platform.dart';
 export 'model/m_position.dart';
-export 'model/project.dart';
-export 'model/provider.dart';
+// export 'model/project.dart';
+// export 'model/provider.dart';
 export 'model/sex.dart';
 export 'model/cp_extra_info.dart';
 export 'model/cp_extra_info_choice_question.dart';

+ 62 - 62
lib/model/m_control_point.dart

@@ -93,24 +93,24 @@ class MControlPoint {
     return Text(sn, style: textStyle);
   }
 
-  pb.GameSaveControlPoint toPbSave() {
-    final out = pb.GameSaveControlPoint()
-      ..controlPointId= intId
-      ..isCheckSuccess= isSuccess
-      ..checkAfterStart= checkAfterStart.toPb()
-      ..distinctAfterStart= checkDistanceAfterStart.m
-      ..answerCorrect= isAnswerCorrect
-      ..isAnswer= userAnswerIndex!= null
-    ;
-    if(userAnswerIndex!= null){
-      out.userAnswerIndex=userAnswerIndex!;
-    }
-    if(qbId!= null){
-      out.userAnswerIndex=qbId!;
-    }
-
-    return out;
-  }
+  // pb.GameSaveControlPoint toPbSave() {
+  //   final out = pb.GameSaveControlPoint()
+  //     ..controlPointId= intId
+  //     ..isCheckSuccess= isSuccess
+  //     ..checkAfterStart= checkAfterStart.toPb()
+  //     ..distinctAfterStart= checkDistanceAfterStart.m
+  //     ..answerCorrect= isAnswerCorrect
+  //     ..isAnswer= userAnswerIndex!= null
+  //   ;
+  //   if(userAnswerIndex!= null){
+  //     out.userAnswerIndex=userAnswerIndex!;
+  //   }
+  //   if(qbId!= null){
+  //     out.userAnswerIndex=qbId!;
+  //   }
+  //
+  //   return out;
+  // }
 
   void updateBySimple(pb.ControlPointSimple other) {
     areaId = other.sn;
@@ -147,23 +147,23 @@ class MControlPoint {
   }
 }
 
-extension PbGameSaveControlPointExt on pb.GameSaveControlPoint {
-  MControlPoint toModel() {
-    final one = MControlPoint();
-    one.intId = controlPointId;
-    one.isSuccess = isCheckSuccess;
-    one.checkAfterStart = checkAfterStart.toDuration();
-    one.checkDistanceAfterStart = distinctAfterStart.meter;
-    one.isAnswerCorrect = answerCorrect;
-    if (hasUserAnswerIndex()) {
-      one.userAnswerIndex = userAnswerIndex;
-    }
-    if (hasQbId()) {
-      one.qbId = qbId;
-    }
-    return one;
-  }
-}
+// extension PbGameSaveControlPointExt on pb.GameSaveControlPoint {
+//   MControlPoint toModel() {
+//     final one = MControlPoint();
+//     one.intId = controlPointId;
+//     one.isSuccess = isCheckSuccess;
+//     one.checkAfterStart = checkAfterStart.toDuration();
+//     one.checkDistanceAfterStart = distinctAfterStart.meter;
+//     one.isAnswerCorrect = answerCorrect;
+//     if (hasUserAnswerIndex()) {
+//       one.userAnswerIndex = userAnswerIndex;
+//     }
+//     if (hasQbId()) {
+//       one.qbId = qbId;
+//     }
+//     return one;
+//   }
+// }
 
 extension PbControlPointExt on pb.ControlPoint {
   MControlPoint toModel() {
@@ -203,33 +203,33 @@ extension PbControlPointSimpleExt on pb.ControlPointSimple {
 }
 
 /// 完赛后检查点
-extension PbGameControlPointExt on pb.GameControlPoint {
-  MControlPoint toModel() {
-    final one = MControlPoint();
-    one.areaId = sn;
-    one.intId = id;
-    if (cType == pb.CType.BeginType) {
-      one.isStart = true;
-    }
-    if (cType == pb.CType.MiddleType) {
-      if (orderNo != 0) {
-        one.sn = orderNo.toString();
-      }
-    }
-    if (cType == pb.CType.EndType) {
-      one.isFinish = true;
-    }
-    one.isSuccess = isCheckSuccess;
-    one.checkAfterPrev = checkAfterLast.toDuration();
-    one.checkAfterStart = checkAfterStart.toDuration();
-    one.checkDistanceAfterPrev = disAfterLast.meter;
-    one.distanceStraightToPrev = disStraightAfterLast.meter;
-    one.paceAfterPrev = paceAfterLast.seconds;
-    one.paceAfterStart = paceAfterStart.seconds;
-
-    return one;
-  }
-}
+// extension PbGameControlPointExt on pb.GameControlPoint {
+//   MControlPoint toModel() {
+//     final one = MControlPoint();
+//     one.areaId = sn;
+//     one.intId = id;
+//     if (cType == pb.CType.BeginType) {
+//       one.isStart = true;
+//     }
+//     if (cType == pb.CType.MiddleType) {
+//       if (orderNo != 0) {
+//         one.sn = orderNo.toString();
+//       }
+//     }
+//     if (cType == pb.CType.EndType) {
+//       one.isFinish = true;
+//     }
+//     one.isSuccess = isCheckSuccess;
+//     one.checkAfterPrev = checkAfterLast.toDuration();
+//     one.checkAfterStart = checkAfterStart.toDuration();
+//     one.checkDistanceAfterPrev = disAfterLast.meter;
+//     one.distanceStraightToPrev = disStraightAfterLast.meter;
+//     one.paceAfterPrev = paceAfterLast.seconds;
+//     one.paceAfterStart = paceAfterStart.seconds;
+//
+//     return one;
+//   }
+// }
 
 extension ControlPointInfoExt on pb.ControlPointInfo {
   CPExtraInfo toModel() {

+ 19 - 0
lib/model/m_net_image.dart

@@ -1,7 +1,11 @@
+import 'dart:io';
 import 'dart:typed_data';
+import 'package:f_cache/manager.dart';
+import 'package:http/http.dart' as http;
 import '../utils.dart';
 import '../pb.dart' as pb;
 
+
 class MNetImage{
   String url = '';
   Uint8List md5 = Uint8List(0);
@@ -17,6 +21,21 @@ class MNetImage{
       return md5.toHexString();
     }
   }
+
+  Future<Reader> readerBuilder()async{
+    final url = Uri.parse(this.url);
+    var request = http.Request('GET', url);
+    var response = await request.send();
+    if (response.statusCode != 200) {
+      throw HttpException('state: ${response.statusCode}', uri: url);
+    }
+    final length = response.contentLength ?? 0;
+    return Reader(response.stream, length);
+  }
+  Future<void> preload()async{
+    await CacheManager().getCached(id: md5Hex ?? '', readerBuilder: readerBuilder);
+  }
+
 }
 
 extension PbNetImageExtension on pb.NetImage{

+ 19 - 18
lib/model/map_info.dart

@@ -2,29 +2,30 @@ import 'package:trackoffical_app/model.dart';
 import 'package:trackoffical_app/pb.dart' as pb;
 
 class MapInfo{
-  int id=0;
-  String name='';
-  MPosition position=MPosition();
-  double distanceKm=0;
-  bool isRecommend=false;
-  int level=0;
-  MNetImage image =MNetImage();
-  bool isOpen=false;
-  bool needPin=false;
+  int mapId = 0;
+  String name = ''; // 地图名称
+  int mapScaleNumber = 0; // 比例尺,例:1:1500 为 1500
+  String description = ''; // 地图一句话简介
+  double distanceKm = 0;  // 距离
+  MNetImage image = MNetImage();  // 预览图片
+  MPosition position = MPosition();
+  bool isOpen = true;
+  bool needPin = false;
 }
 
 
-extension ExtMapSimple on pb.MapSimple{
+extension ExtMapSimple on pb.ToMapSimpleV2{
   MapInfo toModel(){
     return MapInfo()
-      ..id=id
-      ..name=name
-      ..position=position.toModel()
-      ..distanceKm=distance/1000
-      ..level=level
-      ..isOpen=isOpen
-      ..image=image.toModel()
-      ..needPin=isPinJoin
+      ..mapId = mapId
+      ..name = name
+      ..mapScaleNumber = mapScaleNumber
+      ..description = description
+      ..distanceKm = distance/1000
+      ..image = image.toModel()
+      // ..position=position.toModel()
+      // ..isOpen=isOpen
+      // ..needPin=isPinJoin
     ;
   }
 }

+ 4 - 6
lib/pb.dart

@@ -1,15 +1,13 @@
 library pb;
 
-import 'package:trackoffical_app/generated/app_api.pb.dart';
+import 'package:trackoffical_app/generated/to_app_api.pb.dart';
 
 export 'generated/google/protobuf/duration.pb.dart';
 export 'generated/google/protobuf/timestamp.pb.dart';
-export 'generated/app_api.pb.dart';
+export 'generated/to_app_api.pb.dart';
 export 'generated/base.pb.dart';
-export 'generated/app_api.pbgrpc.dart';
+export 'generated/to_app_api.pbgrpc.dart';
 
-
-
-typedef GameSettlement = GameDetailReply;
+// typedef GameSettlement = GameDetailReply;
 
 

+ 21 - 26
lib/route.dart

@@ -1,7 +1,7 @@
 import 'package:flutter/foundation.dart';
 import 'package:get/get.dart';
 
-class RouteName{
+class RouteName {
   static const start = '/start';
   static const init = '/init';
   static const test = '/test';
@@ -13,45 +13,40 @@ class RouteName{
   static const settlement = '/settlement';
   static const homeSaveUserInfo = '/homeSaveUserInfo';
 
-  static const mapsList = '/mapsList';    // 地图列表
-  static const mapTO = '/mapTO';          // 地图场控
-  static const userAdmin = '/userAdmin';  // 用户管理
-  static const personRank = '/personRank';// 个人排名
-  static const groupRank = '/groupRank';  // 分组排名
-  static const sportData = '/sportData';  // 数据详情
-  static const setting = '/setting';      // 设置
-
+  static const mapsList = '/mapsList'; // 地图列表
+  static const mapTO = '/mapTO'; // 地图场控
+  static const userAdmin = '/userAdmin'; // 用户管理
+  static const userRank = '/userRank'; // 个人排名
+  static const groupRank = '/groupRank'; // 分组排名
+  static const sportData = '/sportData'; // 数据详情
+  static const setting = '/setting'; // 设置
 }
 
-class Route{
-
+class Route {
   static Future<bool> toLogin({
-    bool canBack=true,
-    bool thenBack=false,
+    bool canBack = true,
+    bool thenBack = false,
     VoidCallback? thenToPageCall,
-  }) async{
-
+  }) async {
     dynamic arguments = thenToPageCall;
-    if (thenBack){
-      arguments = (){
-        Get.back(closeOverlays:true);
+    if (thenBack) {
+      arguments = () {
+        Get.back(closeOverlays: true);
       };
     }
+
     Future<dynamic>? r;
-    if(canBack){
+    if (canBack) {
       r = Get.toNamed(RouteName.signIn, arguments: arguments);
-    }else{
+    } else {
       r = Get.offAllNamed(RouteName.signIn, arguments: arguments);
     }
-    if (r!= null){
+    if (r != null) {
       final r2 = await r;
-      if(r2 is bool){
+      if (r2 is bool) {
         return r2;
       }
     }
     return false;
   }
-
-
-
-}
+}

+ 3 - 3
lib/service/all_init.dart

@@ -1,7 +1,7 @@
 import 'dart:io';
 import 'dart:ui';
 import 'package:trackoffical_app/route.dart';
-import 'package:trackoffical_app/service/game/game_manager_service.dart';
+// import 'package:trackoffical_app/service/game/game_manager_service.dart';
 import 'package:trackoffical_app/service/service.dart';
 import 'package:trackoffical_app/service/sport_wear.dart';
 import 'package:trackoffical_app/view/ask_premissions_view.dart';
@@ -70,8 +70,8 @@ Future<VoidCallback> initAllServicesAndThenCallback() async {
   //   };
   // }
 
-  // var toName = RouteName.test;
-  var toName = RouteName.signIn;
+  var toName = RouteName.mapsList;
+  // var toName = RouteName.signIn;
   // var toName = RouteName.home;
   // if (App.to.userProfile.age.val > 300) {
   //   toName = RouteName.homeSaveUserInfo;

+ 154 - 379
lib/service/api.dart

@@ -1,5 +1,7 @@
+import 'dart:async';
 import 'dart:math';
 import 'dart:typed_data';
+import 'package:f_cache/manager.dart';
 import 'package:grpc/grpc.dart';
 import 'package:fixnum/fixnum.dart' as fixnum;
 import 'package:trackoffical_app/model.dart';
@@ -17,7 +19,7 @@ class _Stub{
       this.stub
       );
   ClientChannel channel;
-  pb.ApiAppClient stub;
+  pb.ApiToAppClient stub;
 }
 
 class ApiService extends IService {
@@ -42,32 +44,37 @@ class ApiService extends IService {
     return ClientChannel(
       GlobalVar.apiHost,
       port: GlobalVar.apiPort,
-      options: const ChannelOptions(credentials: ChannelCredentials.secure()),
+      options: const ChannelOptions(credentials:
+      // ChannelCredentials.secure()
+        ChannelCredentials.insecure()
+      ),
     );
   }
 
-  pb.ApiAppClient _getStub({Duration? timeout, ClientChannel? channel}){
+  pb.ApiToAppClient _getStub({Duration? timeout, ClientChannel? channel}){
     if (this.channel == null) {
       throw Exception('$runtimeType 未初始化');
     }
     final metadata = <String, String>{
-      'source': "${pb.LoginSource.UserApp.value}"
+      'source': "${pb.LoginSource.ToApp.value}"
     };
     metadata['version'] = _appVersion;
     if (token != null) {
       metadata['token'] = token!;
     }
+    info("token: $token");
 
-    return pb.ApiAppClient(channel??this.channel!,
+    return pb.ApiToAppClient(channel??this.channel!,
         options: CallOptions(
           metadata: metadata,
           timeout: timeout,
         ));
   }
 
-  pb.ApiAppClient get stub {
+  pb.ApiToAppClient get stub {
     return _getStub(timeout: 10.seconds);
   }
+
   _Stub get _stubForStream {
     final ch = _newChannel();
     return _Stub(ch, _getStub(channel: ch)) ;
@@ -75,11 +82,11 @@ class ApiService extends IService {
 
 
   Future<void> syncTime()async{
-    try{
+    try {
       final serverNow = await serverTime();
       App.to.correctByServerNow(serverNow);
       info('服务器时间:${App.to.now}');
-    }catch(e){
+    } catch(e){
       warn("获取服务器时间失败: ", e);
     }
   }
@@ -99,226 +106,57 @@ class ApiService extends IService {
       return false;
     }
     if (token.isNotEmpty) {
-      try {
-        await flushUserInfo();
-      } catch (e) {
-        return false;
-      }
+      // try {
+      //   await flushUserInfo();
+      // } catch (e) {
+      //   return false;
+      // }
       return true;
     } else {
       return false;
     }
   }
 
+  // Future<void> getVfCode() async {
+  //   await stub.getVfPic(pb.DefaultRequest());
+  // }
 
-  Future<void> getVfCode() async {
-    await stub.getVfPic(pb.DefaultRequest());
-  }
-
+  // 获取短信验证码
   Future<void> authSendCodeToPhone(String phone, pb.SmsType smsType)async{
     info('authSendCodeToPhone [$phone]');
-    await stub.authSendCodeToPhone(pb.AuthSendCodeToPhoneRequest()
-      ..phone= phone
-      ..userType= pb.UserType.AppUser
-        ..smsType= smsType
-    );
-  }
-
-  Future<void> signUp(String phone, String code, String? name, pb.User_Sex sex)async{
-    info('signUp [$phone]');
-    var r =  await stub.signUp(pb.SignUpRequest()
+    await stub.toSendCodeToPhoneV2(pb.ToSendCodeToPhoneRequestV2()
       ..phone= phone
-      ..password= code
-      ..nickname= name??''
-      ..userType= pb.UserType.AppUser
-      ..sex= sex
+      ..smsType= smsType
     );
-    token = r.token;
   }
 
-  Future<void> signIn(String name, String password) async {
-    final r = await stub.signIn(pb.SignInRequest()
-      ..name = name
+  // 场控端_登录
+  Future<void> signIn(String userCode, String password, String ip) async {
+    final r = await stub.toSignInV2(pb.ToSignInRequestV2()
+      ..userCode = userCode
       ..password = password
+      ..ip = ip
     );
     token = r.token;
 
     debug('sign in success: $token');
   }
 
+  // 场控端_登出
   void signOut(){
-    stub.signOut(pb.SignOutRequest());
+    stub.toSignOutV2(pb.DefaultRequest());
     token = null;
   }
 
-  Future<pb.GameData> gameStart(
-    int actId,
-    fixnum.Int64 courseId,
-  ) async {
-    await syncTime();
-
-    final r = await stub.gameStart(pb.GameStartRequest()
-          ..actId= fixnum.Int64(actId)
-          ..courseId= courseId
-          ..hrBand= pb.HrBandType.UseHrBand
-        );
-
-    return r.gameData;
-  }
-
-  Future<void> gameSaveUpload(pb.GameSaveUploadRequest save) async {
-    info('gameSaveUpload');
-    final save2 = save.deepCopy();
-    save2.gameSave.gameHrInfos.clear();
-    save2.gameSave.gameGpsInfos.clear();
-
-    await stub.gameSaveUpload(save2);
-    return;
-  }
-
-
-  Future<pb.ActivityListReply> activityList({
-        MPosition? position
-  }) async {
-    info('call providerList $position');
-    final req = pb.PositionRequest();
-    if(position!= null){
-      req.position=position.toPb();
-    }
-
-    final r = await stub.activityList(req);
-    return r;
-  }
-
-  Future<pb.ActivityDetailReply> activityDetail(int id) async {
-    debug('call activityDetail $id');
-    final r =
-    await  stub.activityDetail(pb.IdRequest()..id= fixnum.Int64(id));
-    return r;
-  }
-
-  Future<void> flushUserInfo()async{
-    info('flushUserInfo');
-    final r = await stub.myUserQuery(pb.DefaultRequest());
-    final userProfile = App.to.userProfile;
-    userProfile.username.value = r.name;
-    userProfile.head.value = r.head.toModel();
-    userProfile.sex = r.sex.toModel();
-    userProfile.age.val = App.to.now.year - r.birthdayYear;
-    userProfile.heightCm.val = r.heightMillimeter / 10;
-    userProfile.weightKg.val = r.weightGram / 1000;
-    userProfile.rhr.val = r.staticHr;
-  }
-
-  Future<void> _userInfoEdit(
-      String nickName,
-      Sex sex,
-      int birthdayYear,
-      double heightCm,
-      double weightKg,
-      int rhr,
-      ){
-    return stub.userInfoEdit(pb.UserInfoEditRequest()
-      ..nickName=         nickName
-      ..sex=              sex.toPb()
-      ..birthdayYear=     birthdayYear
-      ..heightMillimeter= (heightCm * 10).toInt()
-      ..weightGram=      (weightKg*1000).toInt()
-      ..staticHr =        rhr
-    );
-  }
-  Future<void> saveUserInfo(){
-    App app = Get.find();
-    final userProfile = app.userProfile;
-    return _userInfoEdit(
-        userProfile.username.value,
-        userProfile.sex,
-        app.now.year - userProfile.age.val,
-        userProfile.heightCm.val,
-        userProfile.weightKg.val,
-        userProfile.rhr.val);
-  }
-
-  Future<pb.MyHistoryGameReply> gameHistory({
-    required pb.GameState state,
-    required int offset,
-    required int limit,
-  })async{
-
-    return await stub.myHistoryGame(pb.MyHistoryGameRequest()
-        ..state= state
-        ..offset= offset
-        ..limit=limit
-    );
-  }
-  Future<void> gameHistoryDel(fixnum.Int64 id){
-    return stub.historyGameDel(pb.IdRequest()..id= id);
-  }
-
-  Future<void> closeAccount()async{
-    await stub.unsubscribe(pb.DefaultRequest());
-  }
-
-  Future<void> gameGpsUpload(
-      fixnum.Int64 gameId,
-      List<MPosition> data,
-      int distanceMeter,
-      int paceSecond,
-      ){
-    info('gameGpsUpload');
-    List<pb.GameGpsInfo> l = data.map((p) => p.toPb2()).toList();
-    final req =  pb.GameGpsUploadRequest()
-      ..gameId= gameId.toInt()
-      ..distance= distanceMeter
-      ..pace= paceSecond
-      ..gameGpsInfos.addAll(l);
-
-
-    return stub.gameGpsUpload(req);
-  }
-  Future<void> gameHrUpload(
-      fixnum.Int64 gameId,
-      List<pb.HeartRate> data,
-      ){
-    info('gameHrUpload');
-    return stub.gameHrUpload(pb.GameHrUploadRequest()
-      ..gameId= gameId.toInt()
-      ..gameHrInfos.addAll(data)
-    );
-  }
-  Future<void> gameExerciseStateUpload(
-      fixnum.Int64 gameId,
-      int  avgHr,
-      int  maxHr,
-      /// 单位卡,不是千卡
-      int  cle,
-      double  ck,
-      double  ei,
-      int stepCount,
-      // %
-      int heartRatePercent
-      ){
-    info('gameExerciseStateUpload');
-    return stub.gameCleUpload(pb.GameCleUploadRequest()
-      ..gameId= gameId.toInt()
-      ..avgHr= avgHr
-      ..maxHr= maxHr
-      ..cle=   cle
-      ..ck= ck.round()
-      ..  ei= ei
-      ..stepNum= stepCount
-      ..heartRatePercent= heartRatePercent
-    );
-  }
-
   @override
   void onClose() {
     channel?.shutdown();
   }
 
+  // 获取系统时间
   Future<DateTime> serverTime() async {
     final begin = DateTime.now();
-    final r = await stub.getServerTime(pb.DefaultRequest());
+    final r = await stub.toGetServerTime(pb.DefaultRequest());
     final cost = DateTime.now().difference(begin);
     final serverNow = DateTime.fromMillisecondsSinceEpoch(
             r.millisecondStamp.toInt(),
@@ -327,162 +165,132 @@ class ApiService extends IService {
     return serverNow.add(cost);
   }
 
-  Future<String> getRegionCode() async{
-    final r =await stub.getRegion(pb.DefaultRequest());
-    info('位置:${r.name}');
-    return r.code;
-  }
-
-  Future<List<pb.Region>> getRegionList() async{
-    info('getRegionList');
-    final r =await stub.regionList(pb.RegionListRequest()..countryCode= "CN");
-    final list = r.region;
-    return list;
-  }
-
   Future<Duration> getSmsSendLeftTime(String phone)async{
-    final r = await stub.getSmsSendLeftTime(pb.GetSmsSendLeftTimeRequest()..phone= phone);
+    final r = await stub.toGetSmsSendLeftTimeV2(pb.GetSmsSendLeftTimeRequest()..phone= phone);
     info('getSmsSendLeftTime: $phone - ${r.second}s');
     return r.second.seconds;
   }
 
-  Future<pb.GetUpdateVersionReply> getUpdateVersion(String version)async{
-    info('getUpdateVersion: $version');
-    final r = await stub.getUpdateVersion(pb.GetUpdateVersionRequest()..vCode= version);
-    return r;
-  }
-
-  Future<pb.GameDetailReply> getGameHistoryDetail(fixnum.Int64 id)async{
-    info('getGameHistoryDetail: $id');
-    return await stub.historyGameDetail(id.toIdRequest());
-  }
+  // Future<pb.GetUpdateVersionReply> getUpdateVersion(String version)async{
+  //   info('getUpdateVersion: $version');
+  //   final r = await stub.getUpdateVersion(pb.GetUpdateVersionRequest()..vCode= version);
+  //   return r;
+  // }
 
-  Future<pb.GameDetailReply> gameFinish(fixnum.Int64 id, bool isDrop)async{
-    info('gameFinish: $id , isDrop: $isDrop');
-    return await stub.gameFinish(pb.GameFinishRequest()..gameId= id.toInt().. isDrop= isDrop);
-  }
+  // 场控端_地图列表
+  Future<List<MapInfo>> mapList(MPosition? position, int offset, int limit) async{
+    info('mapList: $position');
+    final req = pb.MapListRequestV2()
+      ..offset = offset
+      ..limit = limit;
+    if (position != null){
+      req.position = position.toPb();
+    }
 
-  Future<pb.GetInGameDataReply> getInGameData()async{
-    info('getInGameData');
-    return await stub.getInGameData(pb.DefaultRequest());
+    final r = await stub.toMapListV2(req);
+    return r.list.map((e) => e.toModel()).toList();
   }
 
-  Future<List<pb.CareTakerInfo>> guardianList()async{
-    info('guardianList');
-    final r = await stub.myCareTakerQuery(pb.DefaultRequest());
-    return r.list;
-  }
-  Future<List<pb.MyPupil>> underGuardianList()async{
-    info('underGuardianList');
-    final r = await stub.myPupilListQuery(pb.DefaultRequest());
-    return r.list;
-  }
+  // 场控端_地图自身信息
+  Future<pb.ToMapInfoV2> mapDetail(int mapId, String pin)async{
+    info('mapDetail mapId: $mapId pin: $pin');
 
-  Future<void> guardianAdd(String phone, String memo)async{
-    info('guardianAdd: $phone');
-    await stub.myCareTakerAdd(pb.CareTakerInfo()
-      ..cPhone= phone
-      ..memo= memo
+    final r = await stub.toMapDetailV2(pb.IdRequest()
+      ..id = fixnum.Int64(mapId)
     );
-    return;
-  }
-  Future<void> guardianDel(pb.CareTakerInfo v)async{
-    info('guardianAdd: ${v.crId}');
-    await stub.myCareTakerDel(v.crId.toIdRequest());
-    return;
-  }
-
-  Future<List<MapInfo>> mapRecommendList(MPosition? position)async{
-    info('mapRecommendList: $position');
-    final req = pb.PositionRequest();
-    if(position!= null){
-      req.position=position.toPb();
-    }
-
-    final r = await stub.mapRecommendList(req);
-    return r.mapList.map((e) => e.toModel()..isRecommend=true).toList();
-  }
-  Future<List<MapInfo>> mapList(MPosition? position, int offset, int limit)async{
-    info('mapList: $position');
-    final req = pb.MapListRequest()
-      ..offset=offset
-      ..limit=limit;
-    if(position!= null){
-      req.position=position.toPb();
-    }
-
-    final r = await stub.mapList(req);
-    return r.mapList.map((e) => e.toModel()).toList();
+    return r;
   }
 
-  StreamGuardianWatch guardianWatch(int id){
-    info('guardianWatch: $id');
-    final stub = _stubForStream;
-    final stream = stub.stub.pupilInGameWatch(id.toIdRequest());
+  // 场控端_地图内正在进行中的活动人员详情
+  Future<pb.ToUserDetailQueryReplyV2> userDetailQuery(int mapId, bool isFullQuery)async{
+    info('userDetailQuery mapId: $mapId isFullQuery: $isFullQuery');
 
-    return StreamGuardianWatch(stub.channel, stream);
+    final r = await stub.toUserDetailQueryV2(pb.ToUserDetailQueryRequestV2()
+      // ..mapId = fixnum.Int64(mapId)
+      ..mapId = mapId
+      ..isFullQuery = isFullQuery
+    );
+    return r;
   }
 
-  Future<Bin> getBinByMd5(Uint8List md5, OnPercentage onPercentage)async{
-    final stream = _getStub().getBinaryByMd5(pb.GetBinaryByMd5Request()..md5= md5);
-    String ext='';
-    Uint8List? data;
-    var nonce=Uint8List(0);
-    var i = 0;
-
-    await for (var one in stream){
-      if(data == null){
-        data = Uint8List(one.allCount);
-        ext = one.ext;
-        nonce= Uint8List.fromList(one.nonce);
-      }
+  // Future<Bin> getBinByMd5(Uint8List md5, OnPercentage onPercentage) async{
+  //   final stream = _getStub().toGetBinaryByMd5(pb.ToGetBinaryByMd5Request()..md5=md5);
+  //   String ext='';
+  //   Uint8List? data;
+  //   var nonce=Uint8List(0);
+  //   var i = 0;
+  //
+  //   await for (var one in stream){
+  //     if(data == null){
+  //       data = Uint8List(one.allCount);
+  //       ext = one.ext;
+  //       nonce= Uint8List.fromList(one.nonce);
+  //     }
+  //
+  //     for(var b in one.data){
+  //       data[i]=b;
+  //       i++;
+  //     }
+  //
+  //     onPercentage(i, data.length);
+  //   }
+  //
+  //
+  //   await stream.cancel();
+  //   return Bin()
+  //     ..ext=ext
+  //     ..data=data??Uint8List(0)
+  //     ..nonce=nonce;
+  //   return Bin();
+  // }
+
+  Future<BinReader> getBinReaderByMd5(Uint8List md5) async {
+    final stream = _getStub().toGetBinaryByMd5(pb.ToGetBinaryByMd5Request()..md5=md5);
+    final controller = StreamController<List<int>>();
+    controller.onCancel = (){
+      stream.cancel();
+    };
 
-      for(var b in one.data){
-        data[i]=b;
-        i++;
+    Future<void> rcv()async{
+      try{
+        await for(final one in stream){
+          controller.add(one.data);
+        }
+      }finally{
+        controller.close();
+        stream.cancel();
       }
-
-      onPercentage(i, data.length);
     }
-
-
-    await stream.cancel();
-    return Bin()
+    rcv();
+    stream.headers.then((value) => debug(value));
+    final headers = await stream.headers;
+    final lenStr = headers['all-length']!;
+    final length = int.parse(lenStr);
+    final nonce = headers['nonce']!;
+    final ext = headers['ext']!;
+
+    return BinReader(Reader( controller.stream, length))
       ..ext=ext
-      ..data=data??Uint8List(0)
-      ..nonce=nonce;
-  }
-
-
-  Future<void> userHeadEdit(String ext, Uint8List data)async{
-    await stub.userHeadEdit(pb.Image()..ext= ext ..data= data);
+      ..nonce=nonce
+    ;
   }
 
-  Future<pb.MapActivityListReply> mapActivityList(int mapId, String pin)async{
-    info('mapActivityList mapId: $mapId pin: $pin');
+}
 
-    final r = await stub.mapActivityList(pb.MapActivityListRequest()
-      ..id= mapId
-      ..pinCode= pin.trim()
-    );
-    return r;
-  }
-  Future<pb.MapActivityListReply> pinCodeActivityList(String pin)async{
-    info('pinCodeActivityList  pin: $pin');
-    final r = await stub.pinCodeActivityList(pb.PinCodeActivityListRequest()
-       .. pinCode= pin.trim()
-    );
-    return r;
-  }
+// class Bin{
+//   var ext='';
+//   var data = Uint8List(0);
+//   var nonce = Uint8List(0);
+// }
 
-}
-class Bin{
+class BinReader{
+  BinReader(this.reader);
   var ext='';
-  var data=Uint8List(0);
-  var nonce=Uint8List(0);
+  Reader reader;
+  var nonce='';
 }
 
-typedef OnPercentage = void Function(int, int);
+// typedef OnPercentage = void Function(int, int);
 
 class ApiServiceMock extends ApiService {
   @override
@@ -494,39 +302,7 @@ class ApiServiceMock extends ApiService {
   final random = Random();
 
   @override
-  Future<void> signIn(String name, String password) async {}
-
-  @override
-  Future<pb.GameData> gameStart(
-      int projectId, fixnum.Int64 mapRouteId) async {
-    info('gameStart Mock');
-    final data = pb.GameData();
-
-    final p1 = pb.ControlPoint()
-      ..id= fixnum.Int64(1)
-      ..info = pb.ControlPointInfo();
-    final p2 = pb.ControlPoint()..id= fixnum.Int64(2)
-      ..info = pb.ControlPointInfo();
-    p1.nfcIdList.add('0465be121c1291');
-    p2.nfcIdList.add('0465bd121c1291');
-
-    data.controlPointSortedList.addAll([p1, p2]);
-
-    data.mapZip = pb.NetImage()
-        ..url=
-            'https://p3.itc.cn/q_70/images03/20210317/94c7636527d042d8a7c9ed08529cc8b2.jpeg'
-        ..md5= [1, 1, 1];
-
-    data.maxDuration = pb.Duration()..seconds= fixnum.Int64(60) * 60;
-    return data;
-  }
-
-
-  @override
-  Future<void> gameSaveUpload(pb.GameSaveUploadRequest save) async {
-    return;
-  }
-
+  Future<void> signIn(String userCode, String password, String ip) async {}
 
   @override
   void onReady() {}
@@ -539,12 +315,14 @@ class ApiServiceMock extends ApiService {
     return DateTime.now();
   }
 
+/*
   @override
   Future<pb.MapActivityListReply> mapActivityList(int mapId, String pin)async{
     return pb.MapActivityListReply()
       ..list.addAll([
         pb.MapActivitySimpleInfo()
-          ..name= '穿越荒野:勇闯野性之旅-穿越荒野:勇闯野性之旅'
+          ..id=0
+          ..name= '穿越荒野:勇闯野性之旅-穿越荒野:勇闯野性之旅-穿越荒野:勇闯野性之旅-穿越荒野:勇闯野性之旅-穿越荒野:勇闯野性之旅'
           ..difficulty= 1
           ..distanceMinMeter= 217.1
           ..closeDoorTime= 190.minutes.toPb()
@@ -553,6 +331,7 @@ class ApiServiceMock extends ApiService {
           ..totalControlNum= 12
         ,
         pb.MapActivitySimpleInfo()
+          ..id=1
           ..name= '极限挑战 战胜重力'
           ..difficulty= 2
           ..distanceMinMeter= 8.1
@@ -564,6 +343,7 @@ class ApiServiceMock extends ApiService {
       ])
     ;
   }
+
   @override
   Future<pb.ActivityDetailReply> activityDetail(int id) async {
     final simple = pb.MapActivitySimpleInfo()
@@ -591,22 +371,24 @@ class ApiServiceMock extends ApiService {
         ])
     ;
   }
+*/
 
 
-  @override
+  // @override
   Future<List<MapInfo>> mapRecommendList(MPosition? position)async{
     info('mapRecommendList: $position');
 
     return [
       MapInfo()
         ..name= '英雄山风景区'
-        ..isOpen=true
-        ..isRecommend=true
+        // ..isOpen=true
+        // ..isRecommend=true
       ,
       MapInfo()..name= '板桥广场'
-        ..isRecommend=true
+        // ..isRecommend=true
     ];
   }
+
   @override
   Future<List<MapInfo>> mapList(MPosition? position, int offset, int limit)async{
     info('mapList: $position');
@@ -621,37 +403,30 @@ class ApiServiceMock extends ApiService {
 
     return out;
   }
-  @override
-  Future<String> getRegionCode() async{
-    return 'test';
-  }
 
-  @override
-  Future<List<pb.Region>> getRegionList() async{
-    info('getRegionList');
-    return [];
-  }
 }
 
+/*
 class StreamGuardianWatch{
   StreamGuardianWatch(
       this.channel,
       this.stream
       );
-
   ClientChannel channel;
   ResponseStream<pb.PupilInGameWatchReply> stream;
-
 }
-extension ExtInt64 on fixnum.Int64{
+*/
+
+extension ExtInt64 on fixnum.Int64 {
   pb.IdRequest toIdRequest(){
     return pb.IdRequest()
-      ..id=this;
+      ..id = this;
   }
 }
-extension ExtNum on num{
+
+extension ExtNum on num {
   pb.IdRequest toIdRequest(){
     return pb.IdRequest()
-      ..id=fixnum.Int64(toInt());
+      ..id = fixnum.Int64(toInt());
   }
 }

+ 15 - 11
lib/service/app.dart

@@ -17,7 +17,7 @@ import '../global.dart';
 import '../model/platform.dart';
 import '../logger.dart';
 import '../model/m_position.dart';
-import '../model/provider.dart';
+// import '../model/provider.dart';
 import 'package:trackoffical_app/pb.dart' as pb;
 import 'package:device_info_plus/device_info_plus.dart';
 import 'package:trackoffical_app/utils.dart' as utils;
@@ -26,7 +26,7 @@ import 'package:flutter/material.dart';
 class App extends IService{
   var screenSize = Size.zero;
   static App get to => Get.find();
-  static const _platform = MethodChannel('com.beswell.app/api');
+  static const _platform = MethodChannel('com.beswell.toapp/api');
   final _serverTime = _ServerTime();
   DateTime get now=>_serverTime.now();
   final userProfile = UserProfile();
@@ -39,6 +39,7 @@ class App extends IService{
   var devicePixelRatio = 1.0;
   var isShowHomeWarn = true;
   AssetsAudioPlayer? _audioPlayer;
+  var selectedMapId = 0.obs;
 
   double heightOneMM(){
     final dpi = xDpi;
@@ -64,8 +65,11 @@ class App extends IService{
   Future<void> initBeforeApp()async{
     final flavor = await getFlavor();
     if(flavor == 'dev'){
-      GlobalVar.apiHost='totapi-lc.beswell.com';
-      GlobalVar.flavor=Flavor.dev;
+      // GlobalVar.apiHost = 'totapi-lc.beswell.com';
+      // GlobalVar.apiHost = 't-otapi.beswell.com';
+      GlobalVar.apiHost = '192.168.0.3';
+      // GlobalVar.apiPort = 10000;
+      GlobalVar.flavor = Flavor.dev;
       info('版本:dev');
       FlavorConfig(
         name: "开发版",
@@ -106,7 +110,7 @@ class App extends IService{
   }
 
   final Rx<MPosition?> position = Rx(null);
-  final Rx<Provider?> selectedProvider = Rx(null);
+  // final Rx<Provider?> selectedProvider = Rx(null);
 
   void workCheckLocationService()async{
     while(!isClosed){
@@ -160,12 +164,12 @@ class App extends IService{
   }
 
   /// android升级App
-  Future<void> updateApp(pb.GetUpdateVersionReply info)async{
-    return await _platform.invokeMethod('updateApp', {
-      'url': info.vUrl,
-      'version': info.vCode
-    });
-  }
+  // Future<void> updateApp(pb.GetUpdateVersionReply info)async{
+  //   return await _platform.invokeMethod('updateApp', {
+  //     'url': info.vUrl,
+  //     'version': info.vCode
+  //   });
+  // }
   /// android升级App进度
   Future<float> getUpdateAppProcess()async{
     return await _platform.invokeMethod('getUpdateAppProcess');

+ 25 - 3
lib/service/app_map.dart

@@ -1,11 +1,13 @@
+import 'dart:convert';
 import 'dart:ui';
-
 import 'package:dio/dio.dart';
+import 'package:f_cache/f_cache.dart';
 import 'package:trackoffical_app/appcore/map_package.dart';
 import 'package:trackoffical_app/model/game_map.dart';
 import '../logger.dart';
 import '../model/m_net_image.dart';
-import 'package:trackoffical_app/service/image.dart';
+import 'api.dart' as api;
+import '../appcore/ffi.dart' as ffi;
 
 
 extension GameMapExtension on GameMap{
@@ -21,8 +23,28 @@ extension GameMapExtension on GameMap{
       ..md5=md5
     ;
 
-    data = await image.loadMemory(onReceiveProgress: onReceiveProgress);
+    // data = await image.loadMemory(onReceiveProgress: onReceiveProgress);
+    // debug('[加载地图](${image.md5Hex}) \n文件类型:${image.ext}\n 文件大小${data?.length}');
+
+    final r = await CacheManager().getCached( id: image.md5Hex!, onProcess: onReceiveProgress, readerBuilder: () async{
+      final bin = await api.ApiService.to.getBinReaderByMd5(md5);
+      final reader = bin.reader;
+      reader.meta['nonce']=bin.nonce;
+      reader.ext=bin.ext;
+      return bin.reader;
+    });
+    data = r.data;
+    image.ext = r.ext??'';
+    final nonceStr = r.meta['nonce']??'';
+    final nonce = base64Decode(nonceStr);
+    debug('解密地图');
+    data=await ffi.Crypto(bridge: ffi.api).decrypt(nonce: nonce, data: data!);
+    info('解密成功');
+
+
     debug('[加载地图](${image.md5Hex}) \n文件类型:${image.ext}\n 文件大小${data?.length}');
+
+
     if(image.ext != 'zip'){
       throw const FormatException('不是zip');
     }

+ 4 - 2
lib/service/database.dart

@@ -5,7 +5,7 @@ import 'package:trackoffical_app/service/service.dart';
 import 'package:trackoffical_app/utils.dart';
 import '../model/m_net_image.dart';
 import '../logger.dart';
-import '../model/game_state.dart';
+// import '../model/game_state.dart';
 import '../model/cache_image.dart';
 import 'package:path_provider/path_provider.dart';
 
@@ -17,13 +17,14 @@ class DatabaseService extends IService{
   Future<void> init() async {
     final dir = await getApplicationDocumentsDirectory();
     isar = await Isar.open([
-      GameStateDataSchema,
+      // GameStateDataSchema,
       CacheImageSchema,
     ],
       directory: dir.path
     );
   }
 
+/*
   Future<GameStateData?> getExistGameData() async{
     return await isar.gameStateDatas.get(0);
   }
@@ -44,6 +45,7 @@ class DatabaseService extends IService{
       warn('保存进度失败', e);
     }
   }
+*/
 
 
   Future<CacheImage?> getImage(String md5) async{

+ 22 - 22
lib/service/game/game_model.dart

@@ -17,17 +17,17 @@ import 'package:trackoffical_app/appcore/ffi.dart' as ffi;
 class GameModel{
 
   DateTime? get startAt {
-    final save = gameSrcState.value.pbGameSave;
-    return save.hasStartAt()? save.startAt.toModel(): null;
+    // final save = gameSrcState.value.pbGameSave;
+    // return save.hasStartAt()? save.startAt.toModel(): null;
   }
   DateTime? get endAt {
-    final save = gameSrcState.value.pbGameSave;
-    if(save.hasStopAt()){
-      if(save.stopAt.seconds==0){
-        return null;
-      }
-      return save.stopAt.toModel();
-    }
+    // final save = gameSrcState.value.pbGameSave;
+    // if(save.hasStopAt()){
+    //   if(save.stopAt.seconds==0){
+    //     return null;
+    //   }
+    //   return save.stopAt.toModel();
+    // }
 
     return null;
   }
@@ -79,17 +79,17 @@ class GameModel{
   /// 虚拟点打点有效半径冗余
   static const controlPointEffectiveAreaRadiusKmOffset=0.002;
   /// 虚拟点打点有效半径
-  double get controlPointEffectiveAreaRadiusKm =>
-      GlobalVar.isGpsTest? 100:
-      gameSrcState.value.pbGameData.vcpRadius.toDouble()/1000
-          + controlPointEffectiveAreaRadiusKmOffset;
+  double get controlPointEffectiveAreaRadiusKm => 100;
+      // GlobalVar.isGpsTest? 100:
+      // gameSrcState.value.pbGameData.vcpRadius.toDouble()/1000
+      //     + controlPointEffectiveAreaRadiusKmOffset;
 
   /// 是否允许在开始点前预览所有点
-  bool get isAllowPreviewControlPoint => gameSrcState.value.pbGameData.isPreview;
+  bool get isAllowPreviewControlPoint => true; //gameSrcState.value.pbGameData.isPreview;
   /// 是否允许显示地图
-  bool get isShowMap => gameSrcState.value.pbGameData.isShowMap;
+  bool get isShowMap => true; //gameSrcState.value.pbGameData.isShowMap;
   /// 是否允许跳点
-  bool get isAllowedPassCP => gameSrcState.value.pbGameData.maxPassPoint > 0;
+  bool get isAllowedPassCP => false; //gameSrcState.value.pbGameData.maxPassPoint > 0;
   final trajectoryPoints = <Offset>[].obs;
   /// 用户选项是否显示轨迹
   final isShowTrajectory = true.obs;
@@ -103,7 +103,7 @@ class GameModel{
   set isUseRealNorth(v){ App.to.userProfile.isCompassUseRealNorth.val = v; }
   var compassRealNorthOffset = 0.0;
   var deviceSpeed = 0.0;
-  Duration get gameQuestionShowDuration => gameSrcState.value.pbGameData.oiShowTime.seconds;
+  // Duration get gameQuestionShowDuration => gameSrcState.value.pbGameData.oiShowTime.seconds;
 
   Distance get myPositionHistoryLenFromLastCP{
     if(checkedPointsHistory.isEmpty){
@@ -129,11 +129,11 @@ class GameModel{
 
   int get checkedCount {
     var i = 0;
-    for (var one in gameSrcState.value.pbGameSave.checkedSortedList) {
-      if (one.isCheckSuccess) {
-        i++;
-      }
-    }
+    // for (var one in gameSrcState.value.pbGameSave.checkedSortedList) {
+    //   if (one.isCheckSuccess) {
+    //     i++;
+    //   }
+    // }
     return i;
   }
   final Rx<int?> nextPlanPointIndex=Rx(null);

+ 53 - 764
lib/service/map/map.dart

@@ -4,74 +4,44 @@ import 'package:flutter/cupertino.dart';
 import 'package:get/get.dart';
 import 'package:fixnum/fixnum.dart';
 import 'package:grpc/grpc.dart';
-import 'package:mobile_app/model/game_map.dart';
-import 'package:mobile_app/model/settlement.dart';
-import 'package:mobile_app/pb.dart' as pb;
-import 'package:mobile_app/service/app_map.dart';
-import 'package:mobile_app/service/game/game_model.dart';
-import 'package:mobile_app/service/game/plug.dart';
-import 'package:mobile_app/service/game/plug_location.dart';
-import 'package:mobile_app/service/game/plug_sport_wear.dart';
-import 'package:mobile_app/service/game/rule_in_order.dart';
-import 'package:mobile_app/service/game/show_position_controller.dart';
-import 'package:mobile_app/utils.dart';
-import 'package:mobile_app/view/ingame/settlement_view.dart';
+import 'package:trackoffical_app/model/game_map.dart';
+// import 'package:trackoffical_app/model/settlement.dart';
+import 'package:trackoffical_app/pb.dart' as pb;
+import 'package:trackoffical_app/service/app_map.dart';
+import 'package:trackoffical_app/service/game/game_model.dart';
+import 'package:trackoffical_app/service/game/plug.dart';
+// import 'package:trackoffical_app/service/game/plug_location.dart';
+// import 'package:trackoffical_app/service/game/plug_sport_wear.dart';
+// import 'package:trackoffical_app/service/game/rule_in_order.dart';
+import 'package:trackoffical_app/service/game/show_position_controller.dart';
+import 'package:trackoffical_app/utils.dart';
+// import 'package:trackoffical_app/view/ingame/settlement_view.dart';
 import 'package:vibration/vibration.dart';
 import 'package:wakelock/wakelock.dart';
 import '../../logger.dart';
+import '../../model/m_control_point.dart';
 import '../api.dart';
 import '../../model.dart';
 import '../app.dart';
 import '../database.dart';
 import 'map_status.dart';
 import 'plug_orientation.dart';
-import 'rule.dart';
-import '../image.dart';
+// import 'rule.dart';
+// import '../image.dart';
 
-enum GameStatus {
-  idle,
-  // 准备进入游戏
-  preparing,
-  loading,
-  playing,
-  settlement,
-}
-
-class GameService extends GetxService {
-  static GameService get to => Get.find();
+class MapService extends GetxService {
+  static MapService get to => Get.find();
   final DatabaseService _database = Get.find();
   final GameModel _model = Get.find();
   final App _app = Get.find();
+  final mapStatus = MapStatus();
   final errorMsg = ''.obs;
   final name = "".obs;
-  var activityId = 0;
-  var mapRouteId = Int64(0);
-  var _status = GameStatus.idle;
-  Rule rule = RuleMock();
-  GameStatus get status => _status;
-
-  set status(GameStatus v) {
-    info('游戏状态:[$v]');
-    _status = v;
-  }
-
-  pb.GameSettlement _lastGameSettlement = pb.GameDetailReply();
-
-  pb.GameSettlement get lastGameSettlement => _lastGameSettlement;
-
-  MPosition? get myPosition => _model.myPosition.value;
-
+  var mapId = 0;
   Offset? get positionOnMap => _model.myPositionOnMap.value;
 
-  double get myPositionHistoryLenKm => _model.myPositionHistoryLen.value.km;
-
-  final _plugs = <Plug>[];
-
-  GameState get gameState => _model.gameSrcState.value;
-  var isShowCompass = true.obs;
-  static const _progressMap = 0.6;
-  static const _progressApi = 0.2;
-  static const _progressFinal = 0.2;
+  // static const _progressMap = 0.6;
+  // static const _progressApi = 0.2;
   final _loadProgress = 0.0.obs;
 
   double get loadProgress => _loadProgress.value;
@@ -79,454 +49,17 @@ class GameService extends GetxService {
   List<MControlPoint> get controlPointWantSequence =>
       _model.controlPointWantSequence;
 
-  bool get isNfcScanUseDialog {
-    final platform = _app.platformInfo;
-    if (platform is PlatformInfoIOS) {
-      if (platform.deviceVersion >= 8) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  // 创建时间
-  DateTime get createTime => gameState.createTime;
-
-  // 关门时间
-  Duration get maxPassDuration => gameState.pbGameData.maxDuration.toDuration();
-
-  // 强制结束时间
-  Duration get maxForcedEndDuration =>
-      gameState.pbGameData.maxForcedEndDuration.toDuration();
-
-  DateTime get now => _app.now;
-
-  // 打开始点的时间
-  DateTime? get startAt => _model.startAt;
-
-  DateTime? get endAt => _model.endAt;
-
-  List<pb.ControlPoint> get _controlPointWantSequence =>
-      gameState.pbGameData.controlPointSortedList;
-
-  List<pb.ControlPointSimple> get _controlPointAll =>
-      gameState.pbGameData.controlPointAll;
-
-  var _lastCheckedPoint = Int64(0);
-  var _lastCheckedPointTime = DateTime(0);
-
-  List<MControlPoint> get checkedPointsHistory => _model.checkedPointsHistory;
-  final beginDuration = 0.seconds.obs;
-  final mapStatus = MapStatus();
-  Timer? _beginDurationTicker;
-  Timer? _checkStopTicker;
-
-  int get checkedCount => _model.checkedCount;
-
-  // 所有计分点数量
-  int get controlPointAllNum => _model.validCPAllNum;
-
-  // 打卡进度
-  double get checkProgress => _model.checkProgress;
-
-  bool get isOutBoundary {
-    final p = _model.myPositionOnMap.value;
-
-    if (p != null) {
-      final mapWidth = mapStatus.gameMapData.width;
-      final mapHeight = mapStatus.gameMapData.height;
-
-      if (p.dx <= 0 || p.dx >= mapWidth || p.dy <= 0 || p.dy >= mapHeight) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  AnimationController? showLocationController;
-
-  showLocation() {
-    final p = positionOnMap;
-    if (p != null) {
-      final dst = _model.mapRotateCenter;
-
-      if (_model.isEnableUserLocation && !_model.isAlwaysShowMyLocation) {
-        Get.find<ShowPositionController>().show();
-      }
-
-      if (dst != null) {
-        mapStatus.movePicPointTo(p, dst);
-      }
-    }
-  }
-
-  _setStartAt(DateTime? time) {
-    if (time != null) {
-      gameState.pbGameSave.startAt = time.toPb();
-    } else {
-      gameState.pbGameSave.clearStartAt();
-    }
-    _model.gameSrcState.refresh();
-  }
-
-  _setEndAt(DateTime? time) {
-    if (time != null) {
-      gameState.pbGameSave.stopAt = time.toPb();
-    } else {
-      gameState.pbGameSave.clearStopAt();
-    }
-    _model.gameSrcState.refresh();
-  }
-
-  _recordLastPoint(Int64 id) {
-    _lastCheckedPoint = id;
-    _lastCheckedPointTime = now;
-  }
-
-  bool _isCheckTooFast(Int64 id) {
-    return _lastCheckedPoint == id &&
-        now.difference(_lastCheckedPointTime) <= 10.seconds;
-  }
-
-  bool isPointStart(pb.GameSaveControlPoint p) {
-    final seq = _controlPointWantSequence;
-    if (seq.isNotEmpty) {
-      return p.controlPointId == seq.first.id;
-    }
-    return false;
-  }
-
-  bool isPointFinish(pb.GameSaveControlPoint p) {
-    final seq = _controlPointWantSequence;
-    if (seq.isNotEmpty) {
-      return p.controlPointId == seq.last.id;
-    }
-    return false;
-  }
-
-  void setBeginMatrix() {
-    if (mapStatus.isSetBeginMatrix) {
-      return;
-    }
-
-    final next = _model.nextPlanPoint;
-    final f = _model.mapRotateCenter;
-    if (next != null && f != null) {
-      mapStatus.movePicPointTo(next.onMap, f);
-      mapStatus.isSetBeginMatrix = true;
-    }
-  }
-
-  pb.ControlPointSimple gameSaveControlPointFindInProject(
-      pb.GameSaveControlPoint p) {
-    final all = gameState.pbGameData.controlPointAll;
-    for (final one in all) {
-      if (one.id == p.controlPointId) {
-        return one;
-      }
-    }
-    return pb.ControlPointSimple();
-  }
-
-  Future<List<MControlPoint>> _getControlPointWantSequence() async {
-    final out = <MControlPoint>[];
-    final checkedIndex = checkedCount;
-
-    for (var i = 0; i < _controlPointWantSequence.length; i++) {
-      final value = _controlPointWantSequence[i];
-      final one = value.toModel();
-      one.sn = '$i';
-      if (i == 0) {
-        one.isStart = true;
-      }
-      if (i == _controlPointWantSequence.length - 1) {
-        one.isFinish = true;
-      }
-
-      one.isSuccess = i < checkedIndex;
-      one.isNext = i == checkedIndex;
-      one.onMap =
-          await mapStatus.gameMapData.worldToPixel(value.mapPosition.toModel());
-
-      final extraInfo = one.extraInfo;
-      if(extraInfo is CPExtraInfoChoiceQuestion){
-        extraInfo.beanCount = gameState.pbGameData.answerSysPoint;
-        await extraInfo.image?.loadMemory();
-      }
-
-
-      out.add(one);
-    }
-
-    return out;
-  }
-
-  MControlPoint? getNextWantPoint(int offset) =>
-      _model.getNextWantPoint(offset);
-
-  MControlPoint? getLastCheckedPoint() {
-    if (checkedPointsHistory.isNotEmpty) {
-      return checkedPointsHistory.last;
-    } else {
-      return null;
-    }
-  }
-
-  void _checkGameStop({bool willToSettlementView = false}) {
-    if ([
-      GameStatus.preparing,
-      GameStatus.playing,
-    ].contains(status)) {
-      if (now.difference(createTime) > maxForcedEndDuration) {
-        gameGiveUp(willToSettlementView: willToSettlementView);
-      }
-    }
-  }
-
-  Future<void> _saveToDatabase() async {
-    await DatabaseService.to.saveGameState(gameState);
-  }
-
-  Future<void> _saveToServer() async {
-    while (!isClosed) {
-      try {
-        final save = gameState.pbGameSave;
-        await ApiService.to
-            .gameSaveUpload(pb.GameSaveUploadRequest()..gameSave= save);
-
-        return;
-      } on GrpcError catch (e) {
-        warn('上传失败:', e);
-        if (e.code != StatusCode.unavailable) {
-          return;
-        }
-      } catch (e) {
-        warn('上传失败:', e);
-        return;
-      }
+  Future<void> mapLoad() async {
+    info('载入地图[$mapId]');
+    // await _plugsClear();
 
-      await Future.delayed(500.milliseconds);
-    }
-  }
-
-  void _checkHistoryAdd(MControlPoint cp) {
-    checkedPointsHistory.add(cp);
-    gameState.pbGameSave.checkedSortedList.add(cp.toPbSave());
-  }
-
-  void _updateCheckHistory(){
-    gameState.pbGameSave.checkedSortedList.clear();
-    gameState.pbGameSave.checkedSortedList.addAll(checkedPointsHistory.map((e) => e.toPbSave()).toList());
-  }
-
-  void save() {
-    _updateCheckHistory();
-    _saveToDatabase().then((value) => info('本地存档完成'));
-    _saveToServer().then((value) => info('上传存档完成'));
-  }
-
-  Future<void> gameGiveUp({bool willToSettlementView = false}) async {
-    // if(status == GameStatus.idle || status == GameStatus.settlement){
-    //   return;
-    // }
-    _gameStopSetValues();
-    _updateCheckHistory();
-    _saveToDatabase().then((value) => info('本地存档完成'));
-    _settlement(isGiveUp: true, willToSettlementView: willToSettlementView);
-  }
-
-  void _gameStopSetValues({DateTime? now}) {
-    info('游戏结束');
-    if (now != null) {
-      _setEndAt(now);
-    } else {
-      _setEndAt(this.now);
-    }
-  }
-
-  void _updateNewCPState(MControlPoint point, {DateTime? now}) {
-    now = now ?? this.now;
-    point.checkAfterStart = now.difference(startAt ?? now);
-    point.checkAfterPrev = point.checkAfterStart;
-    point.checkDistanceAfterStart = _model.myPositionHistoryLen.value;
-    point.checkDistanceAfterPrev = point.checkDistanceAfterStart;
-    final last = getLastCheckedPoint();
-    if (last != null) {
-      point.checkAfterPrev = point.checkAfterStart - last.checkAfterStart;
-      point.checkDistanceAfterPrev = point.checkDistanceAfterStart - last.checkDistanceAfterStart;
-    }
-  }
-
-  checkPointNFC(
-    String identifier,
-      void Function(MControlPoint cp) onChecked,
-      Future<bool> Function () onConfirmFinish,
-    void Function(pb.ControlPointSimple point) onProjectPoint,
-    VoidCallback onNoPoint,
-  ) {
-    final checkedPoint = _findControlPointInRouteByNfcId(identifier);
-    if (checkedPoint != null) {
-      checkPoint(checkedPoint, onChecked, onConfirmFinish);
-    } else {
-      final point = _findControlPointInProjectByNfcId(identifier);
-      if (point != null) {
-        if (_isCheckTooFast(point.id)) {
-          return;
-        }
-        final result = point.toModel();
-        _updateNewCPState(result);
-        result.isSuccess = false;
-        _checkHistoryAdd(result);
-        save();
-        _recordLastPoint(point.id);
-        onProjectPoint(point);
-      } else {
-        onNoPoint();
-      }
-    }
-  }
-
-  checkPointGps(
-    void Function(MControlPoint cp) onChecked,
-      Future<bool> Function () onConfirmFinish,
-  ) {
-
-    if(_model.isInPlanControlPointArea){
-      pb.ControlPoint? checkedPoint;
-      final point = _model.nextPlanPoint;
-      if (point != null) {
-        checkedPoint = _findControlPointInRouteByM(point);
-      }
-      checkPoint(checkedPoint!, onChecked, onConfirmFinish);
-    }else if (_model.isInWantControlPointArea) {
-      pb.ControlPoint? checkedPoint;
-      final point = _model.getNextWantPoint(0);
-      if (point != null) {
-        checkedPoint = _findControlPointInRouteByM(point);
-      }
-      checkPoint(checkedPoint!, onChecked, onConfirmFinish);
-    }
-  }
-
-
-
-
-
-  Future<void> checkPoint(
-    pb.ControlPoint checkedPoint,
-    void Function (MControlPoint cp) onChecked,
-      /// 打了结束点,询问是否结束
-      Future<bool> Function () onConfirmFinish,
-  ) async{
-    final cp = checkedPoint.toModel();
-
-    if (rule.checkNeedReturn(cp)){
-      return;
-    }
-
-    final now = this.now;
-
-    final result = rule.checkPoint(checkedPoint.toModel());
-
-
-    var isFinish = result.isSuccess && result.isFinish;
-
-    if(!result.isSuccess && result.isFinish){
-      isFinish = await onConfirmFinish();
-      if(!isFinish){
-        return;
-      }
-    }
-
-    _updateNewCPState(result, now: now);
-
-    if(result.isStart && result.isSuccess){
-      _setStartAt(now);
-    }
-
-    if(isFinish){
-      _gameStopSetValues(now: now);
-    }
-
-    _checkHistoryAdd(result);
-
-    if(startAt!=null){
-      gameState.pbGameSave.duration = now.difference(startAt!).toPb();
-
-      if(endAt != null){
-        gameState.pbGameSave.duration = endAt!.difference(startAt!).toPb();
-      }
-    }
-
-    _model.gameSrcState.refresh();
-
-    if(isFinish){
-      _settlement();
-    }else{
-      save();
-    }
-    rule.recordLastPoint(cp);
-    onChecked(result);
-  }
-
-  void showNextPoint() {
-    final next = _model.nextPlanPoint;
-    final focalPoint = _model.mapRotateCenter;
-    if (next != null && focalPoint != null) {
-      mapStatus.movePicPointTo(next.onMap, focalPoint);
-    }
-  }
-
-  Future<void> gameGiveUpAndToFinishView({GameState? state}) async {
-    if (state != null) {
-      _model.gameSrcState.value = state;
-    }
-
-    gameGiveUp();
-    SettlementView.show();
-    // Get.offAll(() => const GameFinishView(),
-    //     binding: GameFinishView.bindings());
-  }
-
-  Future<void> _gameReset() async {
-    errorMsg.value = '';
-    _model.clear();
-    await _plugsClear();
-  }
-
-  Future<void> gameStart() async {
-    info('项目Id[$activityId]准备开始');
-    await _gameReset();
-
-    final data = await ApiService.to.gameStart(activityId, mapRouteId);
-    _model.gameSrcState.value = data.toGameState();
-    status = GameStatus.preparing;
-    _saveToDatabase();
-    info('活动Id[$activityId],游戏Id[${gameState.pbGameData.gameId}]已开始');
-  }
-
-  Future<void> gameLoad() async {
-    info('载入项目[$activityId], Id[${gameState.pbGameData.gameId}]');
-    await _plugsClear();
-
-    _loadProgress.value = 0;
-    status = GameStatus.loading;
-    _app.userProfile.cleanGameSettingsLock();
-    _app.userProfile.gameSettingsLoadLock(gameState.pbGameData.ruleList);
-
-    /// 游戏规则
-    // rule = RuleInOrder();
-    _model.compassRealNorthOffset = gameState.pbGameData.declination * pi / 180;
-
-    _loadProgress.value = _progressApi;
-
-    final gameMap = gameState.pbGameData.mapZip.toGameMap();
+    final gameMap = pb.ToMapInfoV2().zipImage.toGameMap();
     mapStatus.gameMapData = gameMap;
 
-    await gameMap.loadMemory(onReceiveProgress: (c, a) {
-      if (a > 0) {
-        var p = c.toDouble() / a;
-        p = p * _progressMap + _progressApi;
+    await gameMap.loadMemory(onReceiveProgress: (count, total) {
+      if (total > 0) {
+        var p = count.toDouble() / total;
+        // p = p * _progressMap + _progressApi;
         _loadProgress.value = p;
       }
     });
@@ -546,293 +79,49 @@ class GameService extends GetxService {
         Offset(screenSize.width / 2, screenSize.height / 2);
     await mapStatus.resetMatrix();
 
-    _model.controlPointWantSequence.value =
-        await _getControlPointWantSequence();
-    _gameLoadCheckedCP();
-
-    final plugLocation = PlugLocation(
-        gameMap: gameMap,
-        lastInfo: _model.gameSrcState.value.pbGameSave.gameGpsInfos);
+    // _model.controlPointWantSequence.value =
+    //     await _getControlPointWantSequence();
+    // _gameLoadCheckedCP();
+
+    // final plugLocation = PlugLocation(
+    //     gameMap: gameMap,
+    //     lastInfo: _model.gameSrcState.value.pbGameSave.gameGpsInfos);
+    //
+    // _plugs.add(plugLocation);
+    // _plugs.add(PlugSportWear(
+    //     lastHr: _model.gameSrcState.value.pbGameSave.gameHrInfos));
+    // _plugs.add(PlugOrientation(mapStatus: mapStatus));
+    //
+    // await _plugsAllInit();
 
-    _plugs.add(plugLocation);
-    _plugs.add(PlugSportWear(
-        lastHr: _model.gameSrcState.value.pbGameSave.gameHrInfos));
-    _plugs.add(PlugOrientation(mapStatus: mapStatus));
-
-    await _plugsAllInit();
-    _loadProgress.value = 1;
-    status = GameStatus.playing;
-    Wakelock.enable();
     info('载入完成');
   }
 
-  void _gameLoadCheckedCP() {
-    final controlPointWantIdValueMap = <Int64, MControlPoint>{};
-    final controlPointAllIdValueMap = <Int64, pb.ControlPointSimple>{};
-
-    for (var one in _model.controlPointWantSequence) {
-      controlPointWantIdValueMap[one.intId] = one;
-    }
-    for (var one in gameState.pbGameData.controlPointAll) {
-      controlPointAllIdValueMap[one.id] = one;
-    }
-    for (var i = 0; i < gameState.pbGameSave.checkedSortedList.length; i++) {
-      final one = gameState.pbGameSave.checkedSortedList[i];
-      final his = one.toModel();
-      final hisInfo1 = controlPointWantIdValueMap[his.intId];
-      final hisInfo2 = controlPointAllIdValueMap[his.intId];
-      if (hisInfo2 != null) {
-        his.updateBySimple(hisInfo2);
-      }
-      if (hisInfo1 != null) {
-        his.updateBy(hisInfo1);
-        his.type = hisInfo1.type;
-      }
-      checkedPointsHistory.add(his);
-    }
-
-    for (var i = 0; i < checkedPointsHistory.length; i++) {
-      final his = checkedPointsHistory[i];
-      if (i > 0) {
-        final last = checkedPointsHistory[i - 1];
-        his.checkAfterPrev = his.checkAfterStart - last.checkAfterStart;
-        his.checkDistanceAfterPrev = his.checkDistanceAfterStart - last.checkDistanceAfterStart;
-      } else {
-        his.checkAfterPrev = his.checkAfterStart;
-        his.checkDistanceAfterPrev = his.checkDistanceAfterStart;
-      }
-    }
-  }
-
-  Future<void> _plugsAllInit() async {
-    for (var one in _plugs) {
-      await one.init();
-    }
-  }
-
-  Future<void> _plugsClear() async {
-    for (var one in _plugs) {
-      one.close();
-    }
-    for (var one in _plugs) {
-      await one.join();
-    }
-    _plugs.clear();
-  }
-
-  Settlement getSettlement() {
-    return Settlement(
-        data: gameState.pbGameData,
-        save: gameState.pbGameSave,
-        durationAfterStartCheck: beginDuration.value);
-  }
-
-  pb.ControlPoint? _findControlPointInRouteByNfcId(String identifier) {
-    pb.ControlPoint? found;
-    for (var one in _controlPointWantSequence) {
-      for (var nfcId in one.nfcIdList) {
-        if (nfcId.toUpperCase() == identifier.toUpperCase()) {
-          found = one;
-          break;
-        }
-      }
-    }
-    return found;
-  }
-
-  pb.ControlPoint? _findControlPointInRouteByM(MControlPoint point) {
-    pb.ControlPoint? found;
-    for (var one in _controlPointWantSequence) {
-      if (one.id == point.intId) {
-        found = one;
-        break;
-      }
-    }
-    return found;
-  }
-
-  pb.ControlPointSimple? _findControlPointInProjectByNfcId(String identifier) {
-    for (var one in _controlPointAll) {
-      for (var nfcId in one.nfcIdList) {
-        if (nfcId.toUpperCase() == identifier.toUpperCase()) {
-          return one;
-        }
-      }
-    }
-    return null;
-  }
+  showLocation() {
+    final p = positionOnMap;
+    if (p != null) {
+      final dst = _model.mapRotateCenter;
 
-  Future<void> _settlementDeal(bool isGiveUp) async {
-    while (!isClosed) {
-      try {
-        final save = gameState.pbGameSave;
-        await ApiService.to
-            .gameSaveUpload(pb.GameSaveUploadRequest()..gameSave= save);
-        info('进度已上传');
-        break;
-      } on GrpcError catch (e) {
-        if (e.code == StatusCode.unavailable) {
-          errorMsg.value = '无法连接至服务器,正在重试';
-        } else {
-          break;
-        }
-        error(e);
-      } catch (e) {
-        error(e);
-        break;
+      if (_model.isEnableUserLocation && !_model.isAlwaysShowMyLocation) {
+        Get.find<ShowPositionController>().show();
       }
-    }
 
-    await _plugsClear();
-
-    while (!isClosed) {
-      try {
-        info('正在结算');
-        _lastGameSettlement = await ApiService.to
-            .gameFinish(gameState.pbGameData.gameId, isGiveUp);
-        info('结算完成');
-        break;
-      } on GrpcError catch (e) {
-        if (e.code == StatusCode.unavailable) {
-          errorMsg.value = '网络错误,正在重试';
-        } else {
-          break;
-        }
-        error(e);
-        Future.delayed(500.milliseconds);
-      } catch (e) {
-        error(e);
-        break;
+      if (dst != null) {
+        mapStatus.movePicPointTo(p, dst);
       }
     }
-
-    await _saveToDatabase();
-    status = GameStatus.idle;
-  }
-
-  _settlement({bool isGiveUp = false, bool willToSettlementView = false}) {
-    _updateCheckHistory();
-    status = GameStatus.settlement;
-    errorMsg.value = '';
-    _settlementDeal(isGiveUp).then((value) => info('结算完成'));
-    if (willToSettlementView) {
-      SettlementView.show();
-    }
   }
 
   @override
   void onReady() {
-    _beginDurationTicker = Timer.periodic(100.milliseconds, (timer) {
-      final startAt = this.startAt;
-      if (startAt != null) {
-        final end = endAt ?? now;
-        beginDuration.value = end.difference(startAt);
-      } else {
-        beginDuration.value = 0.seconds;
-      }
-    });
   }
 
   @override
   void onClose() {
-    _checkStopTicker?.cancel();
-    _beginDurationTicker?.cancel();
-  }
-
-  Future<bool> loadOnlineUnFinishGame() async {
-    try {
-      final online = await ApiService.to.getInGameData();
-      info('存在线上未完成游戏');
-      status = GameStatus.preparing;
-      _model.gameSrcState.value = GameState()
-        ..pbGameData = online.data
-        ..pbGameSave = online.save;
-      _checkGameStop();
-      return true;
-    } on GrpcError catch (e) {
-      if (e.code != StatusCode.notFound) {
-        warn(e);
-      }
-      return false;
-    } catch (e) {
-      warn(e);
-      return false;
-    }
-  }
-
-  void workAutoSave() async {
-    while (!isClosed) {
-      await Future.delayed(500.milliseconds);
-
-      if (_model.gameSrcState.value.pbGameData.gameId > 0 &&
-          _model.isStarted &&
-          !_model.isFinish) {
-        await _saveToDatabase();
-      }
-    }
-  }
-
-  void workTrajectory() async {
-    while (!isClosed) {
-      await Future.delayed(1000.milliseconds);
-      final duration = _app.userProfile.inGameTrajectorySeconds.val.seconds;
-
-      var out = <Offset>[];
-      for (var i = _model.myPositionHistory.length - 1; i >= 0; i--) {
-        var one = _model.myPositionHistory[i];
-        if (now.difference(one.timestamp) > duration) {
-          break;
-        }
-
-        out.add(await mapStatus.gameMapData.worldToPixel(one));
-      }
-      _model.trajectoryPoints.clear();
-      _model.trajectoryPoints.addAll(out);
-    }
   }
 
-  void workPace() async {
-    while (!isClosed) {
-      await Future.delayed(1000.milliseconds);
-      final startDuration = _model.startedDuration;
-      if (startDuration.inMilliseconds == 0) {
-        continue;
-      }
-
-      _model.paceSecondKm.value =
-          pacePerKm(myPositionHistoryLenKm.km, startDuration);
-      if (checkedPointsHistory.isEmpty) {
-        _model.paceSecondKmFromLastCP.value = _model.paceSecondKm.value;
-      } else {
-        final cp = checkedPointsHistory.last;
-        _model.paceSecondKmFromLastCP.value = pacePerKm(
-            _model.myPositionHistoryLenFromLastCP,
-            startDuration - cp.checkAfterStart);
-      }
-    }
-  }
-
-  static Future<GameService> init() async {
-    final gs = GameService();
-
-    gs.mapStatus.canVibrate = await Vibration.hasVibrator() ?? false;
-    final save = await gs._database.getExistGameData();
-    if (save != null) {
-      info('存在本地未完成游戏');
-      gs.status = GameStatus.preparing;
-      gs._model.gameSrcState.value = save.toState();
-      gs._checkGameStop();
-    } else {
-      gs.loadOnlineUnFinishGame();
-    }
-
-    gs._checkStopTicker = Timer.periodic(100.milliseconds, (timer) {
-      gs._checkGameStop(willToSettlementView: true);
-    });
-
-    gs.workAutoSave();
-    gs.workTrajectory();
-    gs.workPace();
+  static Future<MapService> init() async {
+    final gs = MapService();
     return gs;
   }
 }

+ 4 - 4
lib/service/map/map_status.dart

@@ -3,10 +3,10 @@ import 'dart:math';
 import 'dart:typed_data';
 import 'package:flutter/material.dart';
 import 'package:get/get.dart';
-import 'package:mobile_app/logger.dart';
-import 'package:mobile_app/model/game_map.dart';
-import 'package:mobile_app/service/app.dart';
-import 'package:mobile_app/service/game/game_model.dart';
+import 'package:trackoffical_app/logger.dart';
+import 'package:trackoffical_app/model/game_map.dart';
+import 'package:trackoffical_app/service/app.dart';
+import 'package:trackoffical_app/service/game/game_model.dart';
 import 'package:vibration/vibration.dart';
 import '../../model/map_mode.dart';
 import '../../widget/matrix_gesture_detector.dart';

+ 2 - 2
lib/service/mock.dart

@@ -1,7 +1,7 @@
 import 'package:get/get.dart';
 import 'package:trackoffical_app/service/database.dart';
 import 'package:trackoffical_app/service/app.dart';
-import 'package:trackoffical_app/service/game/game_manager_service.dart';
+// import 'package:trackoffical_app/service/game/game_manager_service.dart';
 import 'package:trackoffical_app/service/sport_wear.dart';
 import 'api.dart';
 
@@ -13,7 +13,7 @@ class Mock{
     Get.put<SportWearService>(SportWearService());
     Get.put<DatabaseService>(DatabaseService());
     Get.put<ApiService>(ApiServiceMock());
-    Get.put<GameManagerService>(GameManagerService());
+    // Get.put<GameManagerService>(GameManagerService());
   }
 }
 

+ 12 - 12
lib/service/user_profile.dart

@@ -129,18 +129,18 @@ class UserProfile {
     ]);
   }
 
-  void gameSettingsLoadLock(List<pb.ActivityRule> rules) {
-    var msg = '载入服务器配置:\n';
-    for (final rule in rules) {
-      final s = _gameSettingsIndex[rule.arName];
-      if (s != null && rule.isLock) {
-        s.parseStringLock(rule.arValue);
-        msg += '${rule.arName}: ${rule.arValue}';
-      }
-    }
-
-    info(msg);
-  }
+  // void gameSettingsLoadLock(List<pb.ActivityRule> rules) {
+  //   var msg = '载入服务器配置:\n';
+  //   for (final rule in rules) {
+  //     final s = _gameSettingsIndex[rule.arName];
+  //     if (s != null && rule.isLock) {
+  //       s.parseStringLock(rule.arValue);
+  //       msg += '${rule.arName}: ${rule.arValue}';
+  //     }
+  //   }
+  //
+  //   info(msg);
+  // }
 
   void cleanGameSettingsLock() {
     for (final one in _gameSettingsIndex.values) {

+ 24 - 4
lib/utils.dart

@@ -8,6 +8,7 @@ import 'package:trackoffical_app/exception/exception.dart';
 import 'package:trackoffical_app/logger.dart';
 import 'package:trackoffical_app/route.dart' as r;
 import 'package:sensor/sensor.dart';
+import 'generated/assets.dart';
 import 'generated/google/protobuf/timestamp.pb.dart' as pb;
 import 'generated/google/protobuf/duration.pb.dart' as pb;
 import 'package:geolocator/geolocator.dart' as geo;
@@ -142,6 +143,12 @@ const userMarkColors = <Color>[
   Color(0xFF850000),
 ];
 
+const userGroupFlag = <String>[
+  Assets.imagesIcFlagRed,
+  Assets.imagesIcFlagYellow,
+  Assets.imagesIcFlagBlue,
+];
+
 extension IntExtension on int {
   String twoDigits() {
     if (this >= 10) return "$this";
@@ -353,6 +360,21 @@ Duration pacePerKm(Distance distance, Duration d){
   return  (m / distance.km).milliseconds;
 }
 
+void snackbarInfo(String title, String message) {
+  Get.snackbar(title, message, colorText: Colors.green[300],
+  isDismissible: true, duration: 3.seconds);
+}
+
+void snackbarWarn(String title, String message) {
+  Get.snackbar(title, message, colorText: Colors.deepOrange[300],
+      isDismissible: true, duration: 3.seconds);
+}
+
+void snackbarError(String title, String message) {
+  Get.snackbar(title, message, colorText: Colors.red[300],
+      isDismissible: true, duration: 3.seconds);
+}
+
 Future<void> checkLocationService() async {
   // Test if location services are enabled.
   var serviceEnabled = await isLocationServiceEnabled();
@@ -368,13 +390,12 @@ Future<void> checkLocationService() async {
   }
 }
 
-
 Future<void> tryCatchApi(Future<void> Function() call, {
   String? errTitle,
   bool Function(GrpcError err)? onError,
   Future<void> Function()? onSuccess,
   VoidCallback? onFinally,
-})async{
+}) async{
 
   try {
     await call();
@@ -399,7 +420,6 @@ Future<void> tryCatchApi(Future<void> Function() call, {
             Get.snackbar(errTitle?? "出错了", "未知错误");
           }
         }
-
         break;
       case StatusCode.unknown:
         Get.snackbar(errTitle?? "出错了", "未知错误");
@@ -410,7 +430,7 @@ Future<void> tryCatchApi(Future<void> Function() call, {
   } catch (e) {
     warn(e);
     Get.snackbar(errTitle?? "出错了", "未知错误");
-  }finally{
+  } finally {
     onFinally?.call();
   }
 }

+ 32 - 32
lib/view/app_update_view.dart

@@ -14,17 +14,17 @@ class AppUpdateController extends GetxController {
 
   @override
   void onReady() {
-    var arg = Get.arguments;
-    if (arg is pb.GetUpdateVersionReply){
-      App.to.updateApp(arg).then((value){
-        info('下载完成');
-      }, onError: (e){
-        warn('安装失败:', e);
-      });
-    }
-    _ticker = Timer.periodic(100.milliseconds, (timer) {
-       App.to.getUpdateAppProcess().then((value) => downloadProcess.value = value);
-    });
+    // var arg = Get.arguments;
+    // if (arg is pb.GetUpdateVersionReply){
+    //   App.to.updateApp(arg).then((value){
+    //     info('下载完成');
+    //   }, onError: (e){
+    //     warn('安装失败:', e);
+    //   });
+    // }
+    // _ticker = Timer.periodic(100.milliseconds, (timer) {
+    //    App.to.getUpdateAppProcess().then((value) => downloadProcess.value = value);
+    // });
   }
 
   @override
@@ -34,23 +34,23 @@ class AppUpdateController extends GetxController {
 }
 
 class AppUpdateView extends GetView<AppUpdateController> {
-  final pb.GetUpdateVersionReply data;
-
-  const AppUpdateView(this.data, {super.key});
-
-  static Bindings bindings() {
-    return BindingsBuilder(() {
-      Get.put<AppUpdateController>(AppUpdateController());
-    });
-  }
-
-  static void show(pb.GetUpdateVersionReply updateInfo) {
-    Get.offAll(
-        AppUpdateView(updateInfo),
-        binding: AppUpdateView.bindings(),
-        arguments: updateInfo
-    );
-  }
+  // final pb.GetUpdateVersionReply data;
+  //
+  // const AppUpdateView(this.data, {super.key});
+  //
+  // static Bindings bindings() {
+  //   return BindingsBuilder(() {
+  //     Get.put<AppUpdateController>(AppUpdateController());
+  //   });
+  // }
+  //
+  // static void show(pb.GetUpdateVersionReply updateInfo) {
+  //   Get.offAll(
+  //       AppUpdateView(updateInfo),
+  //       binding: AppUpdateView.bindings(),
+  //       arguments: updateInfo
+  //   );
+  // }
 
   @override
   Widget build(BuildContext context) {
@@ -84,7 +84,7 @@ class AppUpdateView extends GetView<AppUpdateController> {
                           crossAxisAlignment: CrossAxisAlignment.start,
                           children: [
                             const Text('更新内容:'),
-                            Text(data.vMemo)
+                            // Text(data.vMemo)
                           ],
                         ) ,
                       ) ,
@@ -113,7 +113,7 @@ void main() async {
   c.downloadProcess.value = 0.5;
   Get.put(c);
 
-  runApp(GetMaterialApp(
-      theme: appThemeData(),
-      home: AppUpdateView(pb.GetUpdateVersionReply()..vMemo= "更新内容")));
+  // runApp(GetMaterialApp(
+  //     theme: appThemeData(),
+  //     home: AppUpdateView(pb.GetUpdateVersionReply()..vMemo= "更新内容")));
 }

+ 13 - 14
lib/view/home/home_controller.dart

@@ -14,7 +14,7 @@ import '../../service/api.dart';
 // import '../activity_detail/activity_detail_view.dart';
 import '../../widget/region_pick.dart';
 // import '../game_history.dart';
-import 'dialog_special_warn.dart';
+// import 'dialog_special_warn.dart';
 
 enum HomePage{
   discovery,
@@ -22,10 +22,9 @@ enum HomePage{
   // gameHistory,
 }
 
-
 class HomeController extends GetxController{
   final currentPage = HomePage.discovery.obs;
-  final galleryData = pb.ActivityListReply().obs;
+  // final galleryData = pb.ActivityListReply().obs;
   final _userProfile = App.to.userProfile;
   Rx<String> get username => _userProfile.username;
   Rx<MNetImage> get head => _userProfile.head;
@@ -51,7 +50,7 @@ class HomeController extends GetxController{
   }
   final isInGame = false.obs;
   final currentPageIndex = 0.obs;
-  final gameHistory = <pb.GameHistory>[].obs;
+  // final gameHistory = <pb.GameHistory>[].obs;
   final SportWearService _sportWearService = Get.find();
   SportWear? get connectedSportWear => _sportWearService.connectedSportWear.value;
   MPosition? get myPosition => App.to.position.value;
@@ -63,22 +62,22 @@ class HomeController extends GetxController{
 
   Future<void> flushGalleryData() async{
     final position = App.to.position.value;
-    final value = await ApiService.to.activityList(position: position);
-    galleryData.value = value;
+    // final value = await ApiService.to.activityList(position: position);
+    // galleryData.value = value;
   }
-  void onClickActivity(pb.ActivitySimpleInfo  data) {
+  // void onClickActivity(pb.ActivitySimpleInfo  data) {
     // Get.to(
     //       () => const ActivityDetailView(),
     //   binding: ActivityDetailView.bindings(),
     //   arguments: data,
     // )?.then((value) => flushGalleryData());
-  }
+  // }
 
 
   Future<void> flushMapData() async{
     final position = App.to.position.value;
-    final recommend = await _api.mapRecommendList(position);
-    _mapRecommendList.value = recommend;
+    // final recommend = await _api.mapRecommendList(position);
+    // _mapRecommendList.value = recommend;
     final l = await _api.mapList(position, 0, 8);
     _mapList.value = l;
   }
@@ -114,7 +113,7 @@ class HomeController extends GetxController{
   }
   onMy()async{
     tryCatchApi(()async{
-      await ApiService.to.flushUserInfo();
+      // await ApiService.to.flushUserInfo();
       currentPage.value = HomePage.personal;
     }, errTitle: '');
   }
@@ -139,9 +138,9 @@ class HomeController extends GetxController{
     try {
       while(App.to.regionList.isEmpty){
         try{
-          App.to.regionList.addAll(await ApiService.to.getRegionList()) ;
+          // App.to.regionList.addAll(await ApiService.to.getRegionList()) ;
           _setRegionMap();
-          regionCode.value = await ApiService.to.getRegionCode();
+          // regionCode.value = await ApiService.to.getRegionCode();
           break;
         }catch(e){
           await Future.delayed(1.seconds);
@@ -195,7 +194,7 @@ class HomeController extends GetxController{
 
     if(App.to.isShowHomeWarn&& App.to.userProfile.isEnableHomeSpecialWarn.val){
       App.to.isShowHomeWarn=false;
-      dialogHomeSpecialWarn();
+      // dialogHomeSpecialWarn();
     }
 
     mapInfoListScrollController.addListener(() {

+ 7 - 7
lib/view/home/home_view.dart

@@ -1,9 +1,9 @@
 import 'package:flutter/material.dart';
 import 'package:get/get.dart';
 // import 'package:trackoffical_app/view/game_history.dart';
-import 'package:trackoffical_app/view/home/home_gallery_view.dart';
-import 'package:trackoffical_app/view/home/home_map_view.dart';
-import '../ingame/game_std/game_std_view.dart';
+// import 'package:trackoffical_app/view/home/home_gallery_view.dart';
+// import 'package:trackoffical_app/view/home/home_map_view.dart';
+// import '../ingame/game_std/game_std_view.dart';
 // import 'home_bottom_bar.dart';
 // import 'home_personal_view.dart';
 import 'home_controller.dart';
@@ -16,7 +16,6 @@ class PageInfo{
   PageInfo(this.icon, this.label, this.page);
 }
 
-
 class HomeView extends GetView<HomeController> {
   const HomeView({super.key});
 
@@ -30,9 +29,10 @@ class HomeView extends GetView<HomeController> {
 
   @override
   Widget build(BuildContext context) {
-    return const Scaffold(
-      body: GameStdView()
-    );
+    return Container();
+    // return const Scaffold(
+    //   body: GameStdView()
+    // );
 
     // return Scaffold(
     //   body: Obx((){

+ 11 - 17
lib/view/login/login_controller.dart

@@ -1,15 +1,11 @@
 import 'dart:async';
-
-import 'package:flutter/foundation.dart';
-import 'package:flutter/scheduler.dart';
+import 'dart:ui';
+import 'package:flutter/material.dart';
 import 'package:get/get.dart';
 import 'package:grpc/grpc.dart';
 import 'package:trackoffical_app/logger.dart';
 import 'package:trackoffical_app/service/api.dart';
 import 'package:trackoffical_app/pb.dart' as pb;
-import 'package:trackoffical_app/service/game/game.dart';
-import 'package:trackoffical_app/service/game/game_manager_service.dart';
-import 'package:trackoffical_app/view/ingame/game_std/game_std_view.dart';
 import '../../route.dart';
 import '../../utils.dart';
 
@@ -58,10 +54,10 @@ class LoginController extends GetxController {
   }
 
   Future<void> onSignIn() async {
-    if (!isAgreeContract.value) {
-      Get.snackbar('请先', '阅读并同意协议');
-      return;
-    }
+    // if (!isAgreeContract.value) {
+    //   Get.snackbar('请先', '阅读并同意协议');
+    //   return;
+    // }
 
     if (!isSignInEnable) {
       return;
@@ -70,13 +66,11 @@ class LoginController extends GetxController {
       isSignInEnable = false;
 
       if (phone.value.isEmpty) {
-        Get.snackbar('手机号错误', "请重新输入",
-            isDismissible: true, duration: 3.seconds);
+        snackbarWarn('手机号错误', "请重新输入");
         return;
       }
       if (password.value.isEmpty) {
-        Get.snackbar('验证码错误', "请重新输入",
-            isDismissible: true, duration: 3.seconds);
+        snackbarWarn('验证码错误', "请重新输入");
         return;
       }
 
@@ -85,7 +79,7 @@ class LoginController extends GetxController {
       await tryCatchApi(
           () async {
             info("登录 ${phone.value} ${password.value}");
-            await ApiService.to.signIn(phone.value, password.value);
+            await ApiService.to.signIn(phone.value, password.value, '');
 
             if (Get.previousRoute == RouteName.signIn) {
               Get.offAllNamed(RouteName.home);
@@ -98,10 +92,10 @@ class LoginController extends GetxController {
           onError: (e) {
             switch (e.code) {
               case StatusCode.unauthenticated:
-                Get.snackbar('登录失败', "验证码错误");
+                snackbarWarn('登录失败', "验证码错误");
                 return true;
               case StatusCode.notFound:
-                Get.snackbar('用户未注册', "请先注册");
+                snackbarWarn('用户未注册', "请先注册");
                 return true;
 
               default:

+ 2 - 2
lib/view/login/login_view.dart

@@ -4,7 +4,7 @@ import 'package:get/get.dart';
 import 'package:rive/rive.dart';
 import 'package:trackoffical_app/generated/assets.dart';
 import 'package:trackoffical_app/screen.dart';
-import 'package:trackoffical_app/view/login/sign_up2_view.dart';
+// import 'package:trackoffical_app/view/login/sign_up2_view.dart';
 import 'package:trackoffical_app/view/web_view.dart';
 import '../../styles/color_schemes.g.dart';
 import '../../utils.dart';
@@ -370,7 +370,7 @@ class LoginView extends GetView<LoginController> {
                     style: const TextStyle(color: Color(0xffffb40b)),
                     recognizer: TapGestureRecognizer()
                       ..onTap = () {
-                        SignUpView.show();
+                        // SignUpView.show();
                       },
                   ),
                 ])),

+ 11 - 12
lib/view/maplist/map_list_controller.dart

@@ -38,11 +38,10 @@ class MapListController extends GetxController{
 
   Future<void> flushMapData() async{
     final position = App.to.position.value;
-    final recommend = await _api.mapRecommendList(position);
-    _mapRecommendList.value = recommend;
     final l = await _api.mapList(position, 0, 10);
     _mapList.value = l;
   }
+
   Future<void> mapGetMore() async{
     if(isMapGetMoreLoading){
       return;
@@ -62,16 +61,16 @@ class MapListController extends GetxController{
     isLocating.value = true;
 
     try {
-      while(App.to.regionList.isEmpty){
-        try{
-          App.to.regionList.addAll(await ApiService.to.getRegionList()) ;
-          _setRegionMap();
-          regionCode.value = await ApiService.to.getRegionCode();
-          break;
-        }catch(e){
-          await Future.delayed(1.seconds);
-        }
-      }
+      // while(App.to.regionList.isEmpty){
+      //   try{
+      //     App.to.regionList.addAll(await ApiService.to.getRegionList()) ;
+      //     _setRegionMap();
+      //     regionCode.value = await ApiService.to.getRegionCode();
+      //     break;
+      //   }catch(e){
+      //     await Future.delayed(1.seconds);
+      //   }
+      // }
       await App.to.getPosition(forceFlush: true, timeout: timeout);
       // var future = App.to.getPosition(forceFlush: true);
       // if (timeout != null){

+ 32 - 22
lib/view/maplist/map_list_view.dart

@@ -2,12 +2,15 @@ import 'package:flutter/material.dart';
 import 'package:get/get.dart';
 import '../../model.dart';
 import '../../generated/assets.dart';
+import '../../route.dart';
 import '../../screen.dart';
+import '../../service/app.dart';
 import '../../service/mock.dart';
 import '../../widget/app_dialog.dart';
 import '../../widget/app_net_image.dart';
 import '../../widget/hard_level.dart';
 import '../../widget/page_frame.dart';
+import '../mapto/map_to_view.dart';
 import 'map_list_controller.dart';
 
 class MapListView extends GetView<MapListController> {
@@ -15,6 +18,7 @@ class MapListView extends GetView<MapListController> {
 
   static Bindings bindings() {
     return BindingsBuilder(() {
+      Get.lazyPut<PageTopController>(() => PageTopController());
       Get.lazyPut<MapListController>(() => MapListController());
     });
   }
@@ -71,14 +75,13 @@ class MapListView extends GetView<MapListController> {
                   //   // child: Image.asset(Assets.imagesIcArrowLeft),
                   // ),
                   Expanded(
-                    child: Container (
-                      // color: Colors.blue,
-                      margin: const EdgeInsets.only(
-                          left: 30, right: 30, top: 10, bottom: 20),
-                      child: _dataView(context, data,
-                          controller.mapInfoListScrollController),
-                    )
-                  ),
+                      child: Container(
+                    // color: Colors.blue,
+                    margin: const EdgeInsets.only(
+                        left: 30, right: 30, top: 10, bottom: 20),
+                    child: _dataView(
+                        context, data, controller.mapInfoListScrollController),
+                  )),
                   // Container(
                   //   margin: const EdgeInsets.symmetric(horizontal: 18, vertical: 18),
                   //   width: 1.68.wp,
@@ -141,14 +144,18 @@ class GalleryCardWidget extends GetView<MapListController> {
         },
       ));
     }
-    // if (!isCancel) {
-    //   Get.to(() => ActivityListView(
-    //     mapName: data.name,
-    //     mapId: data.id,
-    //     pin: pin,
-    //     isDirectIn: false,
-    //   ));
-    // }
+    if (!isCancel) {
+      App.to.selectedMapId.value = data.mapId;
+      Get.toNamed(RouteName.mapTO);
+      // Get.to(
+      //     () => MapToView(
+      //           mapId: App.to.selectedMapId.value,
+      //           // mapName: data.name,
+      //           // pin: pin,
+      //           // isDirectIn: false,
+      //         ),
+      //     binding: MapToView.bindings());
+    }
   }
 
   @override
@@ -182,9 +189,9 @@ class GalleryCardWidget extends GetView<MapListController> {
                           maxLines: 1,
                           overflow: TextOverflow.ellipsis,
                         ),
-                        const Text(
-                          "边走边打卡",
-                          style: TextStyle(
+                        Text(
+                          data.description,
+                          style: const TextStyle(
                             color: Color(0xffc6c6c6),
                             fontSize: 11,
                             fontWeight: FontWeight.w500,
@@ -205,8 +212,8 @@ class GalleryCardWidget extends GetView<MapListController> {
                                 Image.asset(Assets.imagesIcRuler,
                                     height: 1.0.wp),
                                 const SizedBox(width: 1),
-                                const Text('1:1000',
-                                    style: TextStyle(
+                                Text('1:${data.mapScaleNumber}',
+                                    style: const TextStyle(
                                         color: Colors.black, fontSize: 10)),
                                 const SizedBox(width: 6),
                               ],
@@ -221,7 +228,10 @@ class GalleryCardWidget extends GetView<MapListController> {
                                   color: Color(0xffaaaaaa),
                                 ),
                                 const SizedBox(width: 1),
-                                getDistanceText(data),
+                                // getDistanceText(data),
+                                Text("${data.distanceKm.toStringAsFixed(1)} km",
+                                    style: const TextStyle(
+                                        color: Colors.black, fontSize: 10))
                               ],
                             ),
                             // HardLevel(data.level),

+ 6 - 5
lib/view/mapto/activity_view.dart

@@ -4,6 +4,7 @@ import 'package:trackoffical_app/utils.dart';
 import 'package:trackoffical_app/view/mapto/map_to_controller.dart';
 import '../../generated/app_api.pb.dart';
 import '../../generated/assets.dart';
+import '../../generated/to_app_api.pb.dart';
 import '../../screen.dart';
 import 'package:trackoffical_app/pb.dart' as pb;
 
@@ -53,7 +54,7 @@ class ActivityView extends GetView<MapToController> {
           child: ListView.builder(
               padding: EdgeInsets.only(top: 0.wp),
               // itemCount: mapActivitySimpleInfo.length,
-              itemCount: controller.mapActivityList.value.list.length,
+              itemCount: controller.toActionInfoList.value.list.length,
               itemBuilder: (ctx, i) {
                 return _wActivityElem(ctx, i);
               }));
@@ -62,7 +63,7 @@ class ActivityView extends GetView<MapToController> {
 
   Widget _wActivityElem(BuildContext ctx, int i) {
     // var info = mapActivitySimpleInfo[i].obs;
-    var info = controller.mapActivityList.value.list[i];
+    var info = controller.toActionInfoList.value.list[i];
     var expand = true.obs;
 
     return Obx(() {
@@ -88,7 +89,7 @@ class ActivityView extends GetView<MapToController> {
     });
   }
 
-  Widget _activityTitle(MapActivitySimpleInfo info, var expand) {
+  Widget _activityTitle(ToActionInfo info, var expand) {
     return Container(
       child: GestureDetector(
         onTap: () {
@@ -101,7 +102,7 @@ class ActivityView extends GetView<MapToController> {
           children: [
             SizedBox(
               width: 16.8.wp,
-              child: Text(info.name,
+              child: Text(info.actName,
                   softWrap: false,
                   maxLines: 1,
                   overflow: TextOverflow.ellipsis,
@@ -128,7 +129,7 @@ class ActivityView extends GetView<MapToController> {
     );
   }
 
-  Widget _activityControl(MapActivitySimpleInfo info) {
+  Widget _activityControl(ToActionInfo info) {
     return Container(
         margin: EdgeInsets.only(top: 0.6.wp),
         padding: EdgeInsets.symmetric(vertical: 0.5.wp, horizontal: 1.wp),

+ 6 - 5
lib/view/mapto/map_to_controller.dart

@@ -35,10 +35,11 @@ List<ModelUserInfo> itemUserInfoDatas = <ModelUserInfo>[
 
 class MapToController extends GetxController {
   var isMapExpanded = false.obs;
-  var mapId = 0.obs;
+  var mapId = App.to.selectedMapId;
   final _mapList = <MapInfo>[].obs;
-  final mapActivityList = pb.MapActivityListReply().obs;
+  final toActionInfoList = pb.ToUserDetailQueryReplyV2().obs;
   final userInfoList = <ModelUserInfo>[].obs;
+  bool isFullQuery = false;
 
   // pb.MapActivityListReply get mapActivityList{
   //   return _mapActivityList.value;
@@ -63,15 +64,15 @@ class MapToController extends GetxController {
 
   MPosition? get myPosition => App.to.position.value;
 
-  Future<void> getMapActivityList() async{
-    mapActivityList.value = await _api.mapActivityList(mapId.value, "");
+  Future<void> getUserDetailQuery() async{
+    toActionInfoList.value = await _api.userDetailQuery(mapId.value, isFullQuery);
   }
 
 
   @override
   void onReady() async{
     userInfoList.value = itemUserInfoDatas;
-    await getMapActivityList();
+    await getUserDetailQuery();
   }
 
 }

+ 7 - 1
lib/view/mapto/map_to_view.dart

@@ -11,10 +11,15 @@ import '../../widget/page_frame.dart';
 import 'map_to_controller.dart';
 
 class MapToView extends GetView<MapToController> {
-  const MapToView({super.key});
+  const MapToView({
+    super.key,
+    // required this.mapId
+  });
+  // final int mapId;
 
   static Bindings bindings() {
     return BindingsBuilder(() {
+      Get.lazyPut<PageTopController>(() => PageTopController());
       Get.lazyPut<MapToController>(() => MapToController());
     });
   }
@@ -65,4 +70,5 @@ void main() {
   Get.put(MapToController());
 
   runPreview(const MapToView());
+  // runPreview(const MapToView(mapId: 0));
 }

+ 1 - 1
lib/view/privacy/privacy_settings_view.dart

@@ -26,7 +26,7 @@ class PrivacySettingsView extends StatelessWidget{
                 title: const Text('警告!'),
                 content: const Text('账户注销后将无法恢复,确定要注销吗?'),
                 onConfirm: ()async{
-                  await ApiService.to.closeAccount();
+                  // await ApiService.to.closeAccount();
                   Get.offAllNamed(RouteName.home);
                 },
                 onConfirmText: '确定',

+ 58 - 47
lib/widget/app_net_image.dart

@@ -1,68 +1,79 @@
-import 'dart:typed_data';
+import 'dart:io';
+import 'package:f_cache/f_cache.dart';
 import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/service/image.dart';
+import '../logger.dart';
 import 'image_loading.dart';
 import '../model/m_net_image.dart';
+import 'package:http/http.dart' as http;
+
+class AppNetImage extends StatefulWidget{
+  const AppNetImage({
+    super.key,
+    required this.netImage,
+    this.fit,
+    this.onWidgetOk, this.width, this.height
+  });
 
-class AppNetImage extends StatelessWidget{
   final MNetImage netImage;
-  final memory = Uint8List(0).obs;
-  final progress = 0.0.obs;
   final BoxFit? fit;
   final VoidCallback? onWidgetOk;
+  final double? width;
+  final double? height;
 
-  AppNetImage({
-    super.key,
-    required this.netImage,
-    this.fit,
-    this.onWidgetOk
-  }){
-    netImage.loadMemory(
-      onReceiveProgress: (c, a){
-        if(a > 0){
-          progress.value = c.toDouble() / a;
-        }
-      }
-    ).then((value) {
-      if(value.isNotEmpty){
-        memory.value = value;
-      }
-    });
+  @override
+  State<StatefulWidget> createState() {
+    return _AppNetImageState();
   }
+}
+CachedReaderImage cachedProvider(MNetImage image){
+  return CachedReaderImage(image.md5Hex ?? '', image.readerBuilder);
+}
+class _AppNetImageState extends State<AppNetImage>{
 
+  late CachedReaderImage provider;
 
   @override
-  Widget build(BuildContext context) {
+  void initState() {
+    super.initState();
+    final image = widget.netImage;
+    provider =  cachedProvider(image);
+  }
 
 
-    return Obx((){
-      if (memory.value.isEmpty){
-        return ImageLoading(value: progress.value);
-      }else{
-        return _Image(memory.value, fit, onWidgetOk);
-        // return Image.memory(memory.value, fit: fit);
-      }
-    });
+  @override
+  void didUpdateWidget(covariant AppNetImage oldWidget) {
+    super.didUpdateWidget(oldWidget);
+    final image = widget.netImage;
+    provider =  cachedProvider(image);
   }
-}
-
-class _Image extends StatelessWidget{
-  const _Image(this.memory, this.fit, this.onWidgetOk);
-  final BoxFit? fit;
-  final VoidCallback? onWidgetOk;
-  final Uint8List memory;
 
   @override
   Widget build(BuildContext context) {
-    final onWidgetOk = this.onWidgetOk;
-    if(onWidgetOk!= null){
-      WidgetsBinding.instance.addPostFrameCallback((mag) {
-        onWidgetOk();
-      });
-    }
+    return Image(
+      image: provider,
+      loadingBuilder: (
+          BuildContext context,
+          Widget child,
+          ImageChunkEvent? loadingProgress){
 
-    onWidgetOk?.call();
-    return Image.memory(memory, fit: fit);
+        if(loadingProgress!= null){
+          var p = 0.0;
+          final all = loadingProgress.expectedTotalBytes?? 0;
+          if(all > 0){
+            p = loadingProgress.cumulativeBytesLoaded.toDouble() / all.toDouble();
+          }
+          return ImageLoading(value: p);
+        }else{
+          return child;
+        }
+      },
+      errorBuilder: (ctx, e, trace){
+        warn('图片加载失败: ${widget.netImage.url}  md5: ${widget.netImage.md5Hex}', e);
+        return Container(color: Colors.white, child:const Center(child: Icon(Icons.broken_image_outlined)));
+      },
+      width: widget.width,
+      height: widget.height,
+      fit: widget.fit,
+    );
   }
 }

+ 4 - 3
lib/widget/page_frame.dart

@@ -93,7 +93,7 @@ class PageTop extends GetView<PageTopController> {
       wNavText('地图', RouteName.mapsList),
       wNavText('场控', RouteName.mapTO),
       wNavText('用户管理', RouteName.userAdmin),
-      wNavText('个人排名', RouteName.personRank),
+      wNavText('个人排名', RouteName.userRank),
       wNavText('分组排名', RouteName.groupRank),
       wNavText('数据详情', RouteName.sportData),
       wNavText('设置', RouteName.setting),
@@ -128,8 +128,9 @@ class PageTop extends GetView<PageTopController> {
       child: GestureDetector(
         behavior: HitTestBehavior.opaque,
         onTap: () {
-          debugPrint("Get.currentRoute == ${Get.currentRoute}");
-          debugPrint("next Route == $routeName");
+          Get.toNamed(routeName);
+          // debugPrint("Get.currentRoute == ${Get.currentRoute}");
+          // debugPrint("next Route == $routeName");
         },
         child: Stack(
           alignment: Alignment.center,

+ 1 - 1
protos/app_api

@@ -1 +1 @@
-Subproject commit e8299cdff5e3676c5ee054cd9e9732f93bfdcd0e
+Subproject commit dd184fe3107a31410560413e9781014c9ac252e4

+ 8 - 0
pubspec.lock

@@ -313,6 +313,14 @@ packages:
       url: "https://pub.flutter-io.cn"
     source: hosted
     version: "5.2.1+1"
+  f_cache:
+    dependency: "direct main"
+    description:
+      name: f_cache
+      sha256: "4470e60d9585a69392f568ed0a1b798dbae967f005a814b3e3402048f7292ede"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "3.1.1"
   fake_async:
     dependency: transitive
     description:

+ 1 - 0
pubspec.yaml

@@ -87,6 +87,7 @@ dependencies:
   flutter_image_compress: ^2.0.3
   meta: ^1.9.1
   syncfusion_flutter_charts: ^22.1.34
+  f_cache: ^3.1.1
 
 dev_dependencies:
   integration_test: