Merge branch 'map_dev' into dev

# Conflicts:
#	ln_jq_app/android/app/src/main/AndroidManifest.xml
#	ln_jq_app/ios/Runner/Info.plist
This commit is contained in:
2026-03-31 13:49:42 +08:00
123 changed files with 6711 additions and 149 deletions

View File

@@ -71,6 +71,9 @@ void initHttpSet() {
HttpService.to.dio.interceptors.add(TokenInterceptor(tokenKey: 'asoco-token'));
HttpService.to.setOnResponseHandler((response) async {
try {
if (response.data == null) {
return null;
}
final baseModel = BaseModel.fromJson(response.data);
if (baseModel.code == 0 || baseModel.code == 200) {
return null;

View File

@@ -0,0 +1,129 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:getx_scaffold/common/common.dart';
import 'package:getx_scaffold/getx_scaffold.dart';
/// 原生地图页面
class NativePageIOS extends StatefulWidget {
const NativePageIOS({super.key});
@override
State<NativePageIOS> createState() => _NativePageIOSState();
}
class _NativePageIOSState extends State<NativePageIOS> {
bool _androidPermissionReady = false;
@override
void initState() {
super.initState();
if (Platform.isAndroid) {
requestAndroidPermission();
} else {
// iOS 已经在原生端处理好,直接置为 true
_androidPermissionReady = true;
}
}
@override
Widget build(BuildContext context) {
if (Platform.isIOS) {
return _buildIOSView(context);
} else if (Platform.isAndroid) {
// 如果安卓权限还没处理完,显示加载中,不加载原生 View
if (!_androidPermissionReady) {
return const Center(
child: CircularProgressIndicator(color: Color(0xFF017137)),
);
}
return _buildAndroidView(context);
} else {
return const Center(child: Text('不支持的平台', style: TextStyle(fontSize: 16)));
}
}
/// 构建iOS Platform View
Widget _buildIOSView(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height - 100,
color: Colors.white,
child: UiKitView(
viewType: 'NativeFirstPage',
// 与iOS原生端注册的标识一致
gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>{}.toSet(),
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
creationParamsCodec: const StandardMessageCodec(),
layoutDirection: TextDirection.ltr,
),
);
}
/// 构建Android Platform View
Widget _buildAndroidView(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height - 100,
color: Colors.white,
child: PlatformViewLink(
viewType: 'NativeFirstPage',
surfaceFactory: (context, controller) {
return AndroidViewSurface(
controller: controller as AndroidViewController,
gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{},
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
);
},
onCreatePlatformView: (params) {
// 使用 initSurfaceAndroidView 强制开启 Hybrid Composition
return PlatformViewsService.initSurfaceAndroidView(
id: params.id,
viewType: 'NativeFirstPage',
layoutDirection: TextDirection.ltr,
creationParams: {},
// 你的参数
creationParamsCodec: const StandardMessageCodec(),
onFocus: () {
params.onFocusChanged(true);
},
)
..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
..create();
},
),
);
}
void requestAndroidPermission() async {
try {
final deviceInfo = await DeviceInfoPlugin().androidInfo;
final sdkInt = deviceInfo.version.sdkInt;
List<Permission> permissions = [Permission.location];
if (sdkInt < 33) {
permissions.add(Permission.storage);
}
// 发起请求
Map<Permission, PermissionStatus> statuses = await permissions.request();
if (statuses[Permission.location]?.isDenied ?? false) {
Toast.show("定位权限被拒绝,会影响相关功能使用");
}
} catch (e) {
debugPrint("权限申请异常: $e");
} finally {
if (mounted) {
setState(() {
_androidPermissionReady = true;
});
}
}
}
}

View File

@@ -1,10 +1,9 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:getx_scaffold/getx_scaffold.dart';
import 'package:ln_jq_app/common/login_util.dart';
import 'package:ln_jq_app/pages/c_page/base_widgets/NativePageIOS.dart';
import 'package:ln_jq_app/pages/c_page/car_info/view.dart';
import 'package:ln_jq_app/pages/c_page/mall/mall_view.dart';
import 'package:ln_jq_app/pages/c_page/map/view.dart';
import 'package:ln_jq_app/pages/c_page/mine/view.dart';
import 'package:ln_jq_app/pages/c_page/reservation/view.dart';
@@ -34,7 +33,7 @@ class BaseWidgetsPage extends GetView<BaseWidgetsController> {
}
List<Widget> _buildPages() {
return [ReservationPage(), MapPage(), MallPage(), CarInfoPage(), MinePage()];
return [ReservationPage(), NativePageIOS(), CarInfoPage(), MinePage()];
}
// 自定义导航栏 (悬浮胶囊样式)

View File

@@ -3,6 +3,7 @@ import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:getx_scaffold/common/utils/log_util.dart';
import 'package:ln_jq_app/common/model/vehicle_info.dart';
import 'package:shared_preferences/shared_preferences.dart';
/// 定义登录渠道的枚举类型
enum LoginChannel {
@@ -105,10 +106,16 @@ class StorageService extends GetxService {
await _box.write(_nameKey, name);
await _box.write(_phoneKey, phone);
await _box.write(_idCardKey, idCard);
final SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('token', token);
}
Future<void> saveVehicleInfo(VehicleInfo data) async {
await _box.write(_vehicleInfoKey, vehicleInfoToJson(data));
final SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('plateNumber', data.plateNumber);
}
Future<void> saveStationCredentials(String account, String password) async {
@@ -128,6 +135,10 @@ class StorageService extends GetxService {
Future<void> clearVehicleInfo() async {
await _box.remove(_vehicleInfoKey);
final SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.remove('plateNumber');
await prefs.remove('token');
}
Future<void> clearStationCredentials() async {