登录调通

This commit is contained in:
2025-11-05 13:14:01 +08:00
parent ea18b71523
commit 36910b8b32
7 changed files with 85 additions and 42 deletions

View File

@@ -1,14 +1,9 @@
import 'package:encrypt/encrypt.dart';
class LoginUtil {
// 定义密钥
// 对于ECB模式我们只需要Key不需要IV (初始化向量)
static final _keyString = '915eae87951a448c86c47796e44c1fcf';
static final _key = Key.fromUtf8(_keyString);
// 【核心修改】创建使用 ECB 模式的加密器实例
// 1. mode: AESMode.ecb -> 使用ECB模式它不需要IV。
// 2. padding: 'PKCS7' -> 在encrypt库中PKCS5和PKCS7的填充方式是兼容的。
static final _encrypter = Encrypter(AES(_key, mode: AESMode.ecb, padding: 'PKCS7'));
/// AES 加密方法
@@ -16,10 +11,8 @@ class LoginUtil {
if (plainText.isEmpty) {
return '';
}
// 【核心修改】调用 encrypt 方法时不再需要传递 iv
final encrypted = _encrypter.encrypt(plainText);
// 返回Base64编码的密文这是网络传输的标准做法
return encrypted.base64;
}

View File

@@ -1,6 +1,5 @@
import 'package:flutter/foundation.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart';
import 'package:getx_scaffold/common/common.dart';
import 'package:get_storage/get_storage.dart';
import 'package:getx_scaffold/getx_scaffold.dart';
import 'package:ln_jq_app/common/model/base_model.dart';
import 'package:ln_jq_app/storage_service.dart';
@@ -9,10 +8,14 @@ import 'common/styles/theme.dart';
import 'pages/home/view.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
WidgetsBinding widgetsBinding = await init(isDebug: true, logTag: '小羚羚');
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
await GetStorage.init();
await Get.putAsync(() => StorageService().init());
initHttpSet();
runApp(

View File

@@ -18,24 +18,21 @@ class HomeController extends GetxController with BaseControllerMixin {
FlutterNativeSplash.remove();
}
//登录状态 未登录跳转登录页
bool isLoggedIn = false;
// 登录渠道 加氢站b_login 司机端c_login
String loginChannel = "c_login";
String loginChannel_b = "b_login";
// 根据登录状态和登录渠道返回不同的首页
Widget getHomePage(bool isLoggedIn, String loginChannel) {
if (!isLoggedIn) {
return LoginPage(); // 未登录,跳转到登录页面
Widget getHomePage() {
//登录状态跳转
if (StorageService.to.isLoggedIn) {
// 如果已登录,再判断是哪个渠道
if (StorageService.to.loginChannel == LoginChannel.station) {
return B_BaseWidgetsPage(); // 站点首页
} else if (StorageService.to.loginChannel == LoginChannel.driver) {
return BaseWidgetsPage(); // 司机首页
} else {
// 已登录,根据渠道判断跳转到不同的页面
if (loginChannel == "b_login") {
return BaseWidgetsPage(); // 渠道A进入 BaseWidgetsPage
return LoginPage();
}
} else {
return StorageService.to.isLoggedIn ? B_BaseWidgetsPage() : LoginPage(); // 渠道B进入 B_BaseWidgetsPage
}
// 未登录,直接去登录页
return LoginPage();
}
}
}

View File

@@ -16,7 +16,7 @@ class HomePage extends GetView<HomeController> {
init: HomeController(),
id: 'home',
builder: (_) {
return controller.getHomePage(false, controller.loginChannel);
return controller.getHomePage();
},
);
}

View File

@@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'package:getx_scaffold/getx_scaffold.dart';
import '../../storage_service.dart';
class LoginController extends GetxController with BaseControllerMixin {
@override
String get builderId => 'login';
@@ -14,6 +16,7 @@ class LoginController extends GetxController with BaseControllerMixin {
@override
void onInit() {
super.onInit();
}

View File

@@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:getx_scaffold/getx_scaffold.dart';
import 'package:ln_jq_app/common/login_util.dart';
@@ -255,19 +257,31 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
return;
}
final responseMap = responseData.data as Map<String, dynamic>;
try {
var result = BaseModel.fromJson(responseData.data);
//保存用户信息
String token = responseMap['token'] ?? '';
String token = result.data['token'] ?? '';
//hydrogenId
String userId = responseMap['userId'] ?? '';
await StorageService.to.saveLoginInfo(token: token, userId: userId);
String userId = result.data['userId'] ?? '';
await StorageService.to.saveLoginInfo(
token: token,
userId: userId,
channel: "station",
);
dismissLoading();
showToast('登录成功,欢迎您');
HttpService.to.setAuthorization(token);
// 跳转到主页,并清除所有历史页面
Get.offAll(() => B_BaseWidgetsPage());
} catch (e) {
// 如果解析 JSON 失败
dismissLoading();
showToast('登录失败:返回数据解析失败${e.toString()}');
}
} catch (e) {
dismissLoading();
}

View File

@@ -1,12 +1,21 @@
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
/// 定义登录渠道的枚举类型
enum LoginChannel {
station, // 站点
driver, // 司机
none, // 未登录或未知
}
class StorageService extends GetxService {
late final GetStorage _box;
// 定义存储时使用的键名Key
// --- 定义存储时使用的键名 (Key) ---
static const String _tokenKey = 'user_token';
static const String _userIdKey = 'user_id';
// 定义登录渠道的存储键名
static const String _channelKey = 'login_channel';
// 提供一个静态的 'to' 方法,方便全局访问
static StorageService get to => Get.find();
@@ -17,6 +26,8 @@ class StorageService extends GetxService {
return this;
}
/// --- Getter 方法,用于读取状态 ---
/// 判断是否已登录 (通过检查 token 是否存在且不为空)
bool get isLoggedIn =>
_box
@@ -29,15 +40,37 @@ class StorageService extends GetxService {
/// 获取 UserId
String? get userId => _box.read<String?>(_userIdKey);
/// 保存用户信息
Future<void> saveLoginInfo({required String token, required String userId}) async {
await _box.write(_tokenKey, token);
await _box.write(_userIdKey, userId);
///获取当前登录渠道
/// 从存储中读取字符串,并转换为枚举类型
LoginChannel get loginChannel {
final channelString = _box.read<String?>(_channelKey);
if (channelString == 'station') {
return LoginChannel.station;
} else if (channelString == 'driver') {
return LoginChannel.driver;
}
return LoginChannel.none;
}
/// 3. 删除用户信息 (用于退出登录)
/// --- 操作方法 ---
/// 保存用户信息
/// @param channel - 登录渠道station 或 driver
Future<void> saveLoginInfo({
required String token,
required String userId,
required String channel, // 接收一个字符串类型的渠道
}) async {
await _box.write(_tokenKey, token);
await _box.write(_userIdKey, userId);
// 将渠道字符串存入本地
await _box.write(_channelKey, channel);
}
///删除用户信息,增加删除渠道信息
Future<void> clearLoginInfo() async {
await _box.remove(_tokenKey);
await _box.remove(_userIdKey);
// 退出登录时,一并清除渠道信息
await _box.remove(_channelKey);
}
}