Commit bd25deab by tanghuan

游客登录、微信绑定、二维码扫码绑定

1 parent 6304208d
...@@ -6,6 +6,7 @@ import 'package:appframe/config/locator.dart'; ...@@ -6,6 +6,7 @@ import 'package:appframe/config/locator.dart';
import 'package:appframe/config/routes.dart'; import 'package:appframe/config/routes.dart';
import 'package:appframe/data/repositories/user_auth_repository.dart'; import 'package:appframe/data/repositories/user_auth_repository.dart';
import 'package:appframe/data/repositories/wechat_auth_repository.dart'; import 'package:appframe/data/repositories/wechat_auth_repository.dart';
import 'package:appframe/utils/login_util.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
...@@ -181,37 +182,44 @@ class LoginMainCubit extends Cubit<LoginMainState> with WidgetsBindingObserver { ...@@ -181,37 +182,44 @@ class LoginMainCubit extends Cubit<LoginMainState> with WidgetsBindingObserver {
var data = resultData['data'] as Map<String, dynamic>; var data = resultData['data'] as Map<String, dynamic>;
int binding = resultData['binding']; int binding = resultData['binding'];
if (binding == 1) { var visitor = binding == 1 ? 0 : 1;
_handleLoginSuccess(data); if (visitor == 1) {
} else { var sharedPreferences = getIt.get<SharedPreferences>();
// 未绑定时,也会返回 sessionCode 和 userCode sharedPreferences.setString('auth_visitor_type', 'apple');
if (state.wechatInstalled) { sharedPreferences.setString('auth_visitor_id', credential.userIdentifier!);
// 已安装微信APP,直接拉起微信授权,不使用 sessionCode 和 userCode }
// 设置 appleUserIdentifier 状态,通知用户需要授权微信认证 LoginUtil.handleLoginSuccess(data, visitor, 'router');
emit(state.copyWith(appleUserIdentifier: data['appleUid']!, showNeedWechatForApple: true)); // if (binding == 1) {
} else { // _handleLoginSuccess(data, 0);
// 未安装微信APP,使用 sessionCode 和 userCode // } else {
_handleLoginSuccess(data); // // 未绑定时,也会返回 sessionCode 和 userCode
} // if (state.wechatInstalled) {
} // // 已安装微信APP,直接拉起微信授权,不使用 sessionCode 和 userCode
} // // 设置 appleUserIdentifier 状态,通知用户需要授权微信认证
// emit(state.copyWith(appleUserIdentifier: data['appleUid']!, showNeedWechatForApple: true));
Future<void> wechatAuthForApple() async { // } else {
emit(state.copyWith(showNeedWechatForApple: false, loginType: 2)); // // 未安装微信APP,使用 sessionCode 和 userCode
// _handleLoginSuccess(data, 1);
var authResult = await _fluwx.authBy( // }
which: NormalAuth(scope: 'snsapi_userinfo', state: 'wechat_sdk_test'), // }
); }
if (!authResult) { // Future<void> wechatAuthForApple() async {
Fluttertoast.showToast(msg: '微信授权处理失败', gravity: ToastGravity.TOP, backgroundColor: Colors.red); // emit(state.copyWith(showNeedWechatForApple: false, loginType: 2));
return; //
} // var authResult = await _fluwx.authBy(
// which: NormalAuth(scope: 'snsapi_userinfo', state: 'wechat_sdk_test'),
// 控制显示加载框,并启动等待微信授权回调的兜底机制 // );
emit(state.copyWith(loading: true)); //
_startWechatAuthWaiting(); // if (!authResult) {
} // Fluttertoast.showToast(msg: '微信授权处理失败', gravity: ToastGravity.TOP, backgroundColor: Colors.red);
// return;
// }
//
// // 控制显示加载框,并启动等待微信授权回调的兜底机制
// emit(state.copyWith(loading: true));
// _startWechatAuthWaiting();
// }
Future<void> wechatAuth() async { Future<void> wechatAuth() async {
emit(state.copyWith(loginType: 1)); emit(state.copyWith(loginType: 1));
...@@ -267,102 +275,8 @@ class LoginMainCubit extends Cubit<LoginMainState> with WidgetsBindingObserver { ...@@ -267,102 +275,8 @@ class LoginMainCubit extends Cubit<LoginMainState> with WidgetsBindingObserver {
} }
var data = resultData['data'] as Map<String, dynamic>; var data = resultData['data'] as Map<String, dynamic>;
_handleLoginSuccess(data); LoginUtil.handleLoginSuccess(data, 0, 'router');
}
} }
void _handleLoginSuccess(Map<String, dynamic> data) {
var roles = data['roles'];
// 过滤出家长角色的数据
if (roles?.isNotEmpty ?? false) {
roles.removeWhere((element) => element['userType'] != 2);
} else {
roles = [];
}
var sessionCode = data['sessionCode'];
var userCode = data['userCode'];
var classCode = '';
var userType = 0;
var stuId = '';
var className = '';
var stuName = '';
var relation = '';
var sharedPreferences = getIt.get<SharedPreferences>();
if (roles.isNotEmpty) {
var role = roles[0];
classCode = role['classCode'];
userType = role['userType'];
stuId = role['stuId'];
className = role['className'];
stuName = role['stuName'];
relation = role['relation'] ?? '';
List<String> classIdList = [];
for (var role in roles) {
classIdList.add(role['classCode'] as String);
}
debugPrint('classCodeIds:-------------- $classIdList');
sharedPreferences.setStringList(Constant.classIdSetKey, classIdList);
} else {
sharedPreferences.setStringList(Constant.classIdSetKey, []);
}
var preUserCode = sharedPreferences.getString('pre_userCode') ?? '';
if (userCode != preUserCode) {
sharedPreferences.setString('pre_userCode', userCode);
sharedPreferences.setString('pre_classCode', classCode);
sharedPreferences.setInt('pre_userType', userType);
sharedPreferences.setString('pre_stuId', stuId);
} else {
var preClassCode = sharedPreferences.getString('pre_classCode') ?? '';
var preUserType = sharedPreferences.getInt('pre_userType') ?? 0;
var preStuId = sharedPreferences.getString('pre_stuId') ?? '';
if (preClassCode != '' &&
roles.any((element) =>
element['classCode'] == preClassCode &&
element['userType'] == preUserType &&
element['stuId'] == preStuId)) {
classCode = preClassCode;
userType = preUserType;
stuId = preStuId;
} else {
sharedPreferences.setString('pre_userCode', userCode);
sharedPreferences.setString('pre_classCode', classCode);
sharedPreferences.setInt('pre_userType', userType);
sharedPreferences.setString('pre_stuId', stuId);
}
}
sharedPreferences.setString('auth_sessionCode', sessionCode);
sharedPreferences.setString('auth_userCode', userCode);
sharedPreferences.setString('auth_classCode', classCode);
sharedPreferences.setInt('auth_userType', userType);
sharedPreferences.setString('auth_stuId', stuId);
sharedPreferences.setString('auth_className', className);
sharedPreferences.setString('auth_stuName', stuName);
sharedPreferences.setString('auth_relation', relation);
debugPrint('loginType: ${state.loginType} appleUid: ${state.appleUserIdentifier}');
// 针对 Apple 登录
if (state.loginType == 2 && state.appleUserIdentifier.isNotEmpty) {
// appleUserIdentifier未绑定,则进行绑定
_userAuthRepository.newBinding(state.appleUserIdentifier, userCode);
}
router.go(
'/web',
extra: {
'sessionCode': sessionCode,
'userCode': userCode,
'classCode': classCode,
'userType': userType,
'stuId': stuId,
},
);
} }
@override @override
......
import 'dart:async'; import 'dart:async';
import 'package:appframe/config/constant.dart';
import 'package:appframe/config/locator.dart'; import 'package:appframe/config/locator.dart';
import 'package:appframe/config/routes.dart'; import 'package:appframe/config/routes.dart';
import 'package:appframe/data/repositories/phone_auth_repository.dart'; import 'package:appframe/data/repositories/phone_auth_repository.dart';
import 'package:appframe/utils/login_util.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
...@@ -97,7 +97,7 @@ class LoginPhoneCubit extends Cubit<LoginPhoneState> { ...@@ -97,7 +97,7 @@ class LoginPhoneCubit extends Cubit<LoginPhoneState> {
} }
// 发送验证码 // 发送验证码
var result = await _phoneAuthRepository.verifyCode(phone, 0); var result = await _phoneAuthRepository.verifyCode(phone, 1);
if (result['code'] != 0) { if (result['code'] != 0) {
Fluttertoast.showToast(msg: result['error'], gravity: ToastGravity.TOP, backgroundColor: Colors.red); Fluttertoast.showToast(msg: result['error'], gravity: ToastGravity.TOP, backgroundColor: Colors.red);
return; return;
...@@ -140,97 +140,15 @@ class LoginPhoneCubit extends Cubit<LoginPhoneState> { ...@@ -140,97 +140,15 @@ class LoginPhoneCubit extends Cubit<LoginPhoneState> {
} }
var data = resultData['data'] as Map<String, dynamic>; var data = resultData['data'] as Map<String, dynamic>;
_handleLoginSuccess(data); int binding = resultData['binding'];
} // binding=1 代表已绑定,不是游客
var visitor = binding == 1 ? 0 : 1;
void _handleLoginSuccess(Map<String, dynamic> data) { if (visitor == 1) {
var roles = data['roles'];
// 过滤出家长角色的数据
if (roles?.isNotEmpty ?? false) {
roles.removeWhere((element) => element['userType'] != 2);
} else {
roles = [];
}
var sessionCode = data['sessionCode'];
var userCode = data['userCode'];
var classCode = '';
var userType = 0;
var stuId = '';
var className = '';
var stuName = '';
var relation = '';
var sharedPreferences = getIt.get<SharedPreferences>(); var sharedPreferences = getIt.get<SharedPreferences>();
sharedPreferences.setString('auth_visitor_type', 'phone');
if (roles.isNotEmpty) { sharedPreferences.setString('auth_visitor_id', phone);
var role = roles[0];
classCode = role['classCode'];
userType = role['userType'];
stuId = role['stuId'];
className = role['className'];
stuName = role['stuName'];
relation = role['relation'] ?? '';
// 将角色中的班级数据处理后,进行缓存
List<String> classIdList = [];
for (var role in roles) {
classIdList.add(role['classCode'] as String);
}
debugPrint('classCodeIds:-------------- $classIdList');
sharedPreferences.setStringList(Constant.classIdSetKey, classIdList);
} else {
sharedPreferences.setStringList(Constant.classIdSetKey, []);
}
var preUserCode = sharedPreferences.getString('pre_userCode') ?? '';
if (userCode != preUserCode) {
// 新用户登录
sharedPreferences.setString('pre_userCode', userCode);
sharedPreferences.setString('pre_classCode', classCode);
sharedPreferences.setInt('pre_userType', userType);
sharedPreferences.setString('pre_stuId', stuId);
} else {
// 前一个登录用户重新登录
var preClassCode = sharedPreferences.getString('pre_classCode') ?? '';
var preUserType = sharedPreferences.getInt('pre_userType') ?? 0;
var preStuId = sharedPreferences.getString('pre_stuId') ?? '';
if (preClassCode != '' &&
roles.any((element) =>
element['classCode'] == preClassCode &&
element['userType'] == preUserType &&
element['stuId'] == preStuId)) {
classCode = preClassCode;
userType = preUserType;
stuId = preStuId;
} else {
sharedPreferences.setString('pre_userCode', userCode);
sharedPreferences.setString('pre_classCode', classCode);
sharedPreferences.setInt('pre_userType', userType);
sharedPreferences.setString('pre_stuId', stuId);
}
} }
LoginUtil.handleLoginSuccess(data, visitor, 'router');
sharedPreferences.setString('auth_sessionCode', sessionCode);
sharedPreferences.setString('auth_userCode', userCode);
sharedPreferences.setString('auth_classCode', classCode);
sharedPreferences.setInt('auth_userType', userType);
sharedPreferences.setString('auth_stuId', stuId);
sharedPreferences.setString('auth_className', className);
sharedPreferences.setString('auth_stuName', stuName);
sharedPreferences.setString('auth_relation', relation);
router.go(
'/web',
extra: {
'sessionCode': sessionCode,
'userCode': userCode,
'classCode': classCode,
'userType': userType,
'stuId': stuId,
},
);
} }
void toggleAgreed(bool value) { void toggleAgreed(bool value) {
......
...@@ -4,6 +4,7 @@ import 'package:appframe/config/constant.dart'; ...@@ -4,6 +4,7 @@ import 'package:appframe/config/constant.dart';
import 'package:appframe/config/locator.dart'; import 'package:appframe/config/locator.dart';
import 'package:appframe/config/routes.dart'; import 'package:appframe/config/routes.dart';
import 'package:appframe/data/repositories/wechat_auth_repository.dart'; import 'package:appframe/data/repositories/wechat_auth_repository.dart';
import 'package:appframe/utils/login_util.dart';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
...@@ -11,7 +12,6 @@ import 'package:flutter/material.dart'; ...@@ -11,7 +12,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:fluwx/fluwx.dart'; import 'package:fluwx/fluwx.dart';
import 'package:shared_preferences/shared_preferences.dart';
class LoginQrState extends Equatable { class LoginQrState extends Equatable {
final int status; final int status;
...@@ -157,97 +157,7 @@ class LoginQrCubit extends Cubit<LoginQrState> { ...@@ -157,97 +157,7 @@ class LoginQrCubit extends Cubit<LoginQrState> {
} }
var data = resultData['data'] as Map<String, dynamic>; var data = resultData['data'] as Map<String, dynamic>;
_handleLoginSuccess(data); LoginUtil.handleLoginSuccess(data, 0, 'router');
}
void _handleLoginSuccess(Map<String, dynamic> data) {
var roles = data['roles'];
// 过滤出家长角色的数据
if (roles?.isNotEmpty ?? false) {
roles.removeWhere((element) => element['userType'] != 2);
} else {
roles = [];
}
var sessionCode = data['sessionCode'];
var userCode = data['userCode'];
var classCode = '';
var userType = 0;
var stuId = '';
var className = '';
var stuName = '';
var relation = '';
var sharedPreferences = getIt.get<SharedPreferences>();
if (roles.isNotEmpty) {
var role = roles[0];
classCode = role['classCode'];
userType = role['userType'];
stuId = role['stuId'];
className = role['className'];
stuName = role['stuName'];
relation = role['relation'];
// 将角色中的班级数据处理后,进行缓存
List<String> classIdList = [];
for (var role in roles) {
classIdList.add(role['classCode'] as String);
}
debugPrint('classCodeIds:-------------- $classIdList');
sharedPreferences.setStringList(Constant.classIdSetKey, classIdList);
} else {
sharedPreferences.setStringList(Constant.classIdSetKey, []);
}
var preUserCode = sharedPreferences.getString('pre_userCode') ?? '';
if (userCode != preUserCode) {
// 新用户登录
sharedPreferences.setString('pre_userCode', userCode);
sharedPreferences.setString('pre_classCode', classCode);
sharedPreferences.setInt('pre_userType', userType);
sharedPreferences.setString('pre_stuId', stuId);
} else {
// 前一个登录用户重新登录
var preClassCode = sharedPreferences.getString('pre_classCode') ?? '';
var preUserType = sharedPreferences.getInt('pre_userType') ?? 0;
var preStuId = sharedPreferences.getString('pre_stuId') ?? '';
if (preClassCode != '' &&
roles.any((element) =>
element['classCode'] == preClassCode &&
element['userType'] == preUserType &&
element['stuId'] == preStuId)) {
classCode = preClassCode;
userType = preUserType;
stuId = preStuId;
} else {
sharedPreferences.setString('pre_userCode', userCode);
sharedPreferences.setString('pre_classCode', classCode);
sharedPreferences.setInt('pre_userType', userType);
sharedPreferences.setString('pre_stuId', stuId);
}
}
sharedPreferences.setString('auth_sessionCode', sessionCode);
sharedPreferences.setString('auth_userCode', userCode);
sharedPreferences.setString('auth_classCode', classCode);
sharedPreferences.setInt('auth_userType', userType);
sharedPreferences.setString('auth_stuId', stuId);
sharedPreferences.setString('auth_className', className);
sharedPreferences.setString('auth_stuName', stuName);
sharedPreferences.setString('auth_relation', relation);
router.go(
'/web',
extra: {
'sessionCode': sessionCode,
'userCode': userCode,
'classCode': classCode,
'userType': userType,
'stuId': stuId,
},
);
} }
void goLoginMain() { void goLoginMain() {
......
...@@ -6,6 +6,7 @@ import 'package:app_settings/app_settings.dart'; ...@@ -6,6 +6,7 @@ import 'package:app_settings/app_settings.dart';
import 'package:appframe/config/constant.dart'; import 'package:appframe/config/constant.dart';
import 'package:appframe/config/locator.dart'; import 'package:appframe/config/locator.dart';
import 'package:appframe/config/routes.dart'; import 'package:appframe/config/routes.dart';
import 'package:appframe/ui/widgets/wechat_qr_bind_dialog.dart';
import 'package:appframe/data/models/message/h5_message.dart'; import 'package:appframe/data/models/message/h5_message.dart';
import 'package:appframe/services/dispatcher.dart'; import 'package:appframe/services/dispatcher.dart';
import 'package:appframe/services/im_service.dart'; import 'package:appframe/services/im_service.dart';
...@@ -18,7 +19,6 @@ import 'package:equatable/equatable.dart'; ...@@ -18,7 +19,6 @@ import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:fluwx/fluwx.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
...@@ -47,6 +47,8 @@ class WebState extends Equatable { ...@@ -47,6 +47,8 @@ class WebState extends Equatable {
// 用来控制是否需要判断处理加群、退群等逻辑 // 用来控制是否需要判断处理加群、退群等逻辑
final bool loginOpFlag; final bool loginOpFlag;
// 没有对应身份的游客
final int? visitor;
final String? sessionCode; final String? sessionCode;
final String? userCode; final String? userCode;
final String? classCode; final String? classCode;
...@@ -69,6 +71,9 @@ class WebState extends Equatable { ...@@ -69,6 +71,9 @@ class WebState extends Equatable {
final bool chooseVideoCmdFlag; final bool chooseVideoCmdFlag;
final String chooseVideoCmdMessage; final String chooseVideoCmdMessage;
/// wechatQrBindCmd
final bool wechatQrBindCmdFlag;
/// 用于测试监测问题 /// 用于测试监测问题
final String testMsg; final String testMsg;
...@@ -85,6 +90,7 @@ class WebState extends Equatable { ...@@ -85,6 +90,7 @@ class WebState extends Equatable {
this.showAppBar = true, this.showAppBar = true,
this.showBottomNavBar = false, this.showBottomNavBar = false,
this.loginOpFlag = false, this.loginOpFlag = false,
this.visitor,
this.sessionCode, this.sessionCode,
this.userCode, this.userCode,
this.classCode, this.classCode,
...@@ -98,6 +104,7 @@ class WebState extends Equatable { ...@@ -98,6 +104,7 @@ class WebState extends Equatable {
this.chooseImageCmdMessage = '', this.chooseImageCmdMessage = '',
this.chooseVideoCmdFlag = false, this.chooseVideoCmdFlag = false,
this.chooseVideoCmdMessage = '', this.chooseVideoCmdMessage = '',
this.wechatQrBindCmdFlag = false,
this.testMsg = '', this.testMsg = '',
}); });
...@@ -114,6 +121,7 @@ class WebState extends Equatable { ...@@ -114,6 +121,7 @@ class WebState extends Equatable {
bool? showAppBar, bool? showAppBar,
bool? showBottomNavBar, bool? showBottomNavBar,
bool? loginOpFlag, bool? loginOpFlag,
int? visitor,
String? sessionCode, String? sessionCode,
String? userCode, String? userCode,
String? classCode, String? classCode,
...@@ -127,6 +135,7 @@ class WebState extends Equatable { ...@@ -127,6 +135,7 @@ class WebState extends Equatable {
String? chooseImageCmdMessage, String? chooseImageCmdMessage,
bool? chooseVideoCmdFlag, bool? chooseVideoCmdFlag,
String? chooseVideoCmdMessage, String? chooseVideoCmdMessage,
bool? wechatQrBindCmdFlag,
String? testMsg, String? testMsg,
}) { }) {
return WebState( return WebState(
...@@ -142,6 +151,7 @@ class WebState extends Equatable { ...@@ -142,6 +151,7 @@ class WebState extends Equatable {
showAppBar: showAppBar ?? this.showAppBar, showAppBar: showAppBar ?? this.showAppBar,
showBottomNavBar: showBottomNavBar ?? this.showBottomNavBar, showBottomNavBar: showBottomNavBar ?? this.showBottomNavBar,
loginOpFlag: loginOpFlag ?? this.loginOpFlag, loginOpFlag: loginOpFlag ?? this.loginOpFlag,
visitor: visitor ?? this.visitor,
sessionCode: sessionCode ?? this.sessionCode, sessionCode: sessionCode ?? this.sessionCode,
userCode: userCode ?? this.userCode, userCode: userCode ?? this.userCode,
classCode: classCode ?? this.classCode, classCode: classCode ?? this.classCode,
...@@ -155,6 +165,7 @@ class WebState extends Equatable { ...@@ -155,6 +165,7 @@ class WebState extends Equatable {
chooseImageCmdMessage: chooseImageCmdMessage ?? this.chooseImageCmdMessage, chooseImageCmdMessage: chooseImageCmdMessage ?? this.chooseImageCmdMessage,
chooseVideoCmdFlag: chooseVideoCmdFlag ?? this.chooseVideoCmdFlag, chooseVideoCmdFlag: chooseVideoCmdFlag ?? this.chooseVideoCmdFlag,
chooseVideoCmdMessage: chooseVideoCmdMessage ?? this.chooseVideoCmdMessage, chooseVideoCmdMessage: chooseVideoCmdMessage ?? this.chooseVideoCmdMessage,
wechatQrBindCmdFlag: wechatQrBindCmdFlag ?? this.wechatQrBindCmdFlag,
testMsg: testMsg ?? this.testMsg, testMsg: testMsg ?? this.testMsg,
); );
} }
...@@ -172,6 +183,7 @@ class WebState extends Equatable { ...@@ -172,6 +183,7 @@ class WebState extends Equatable {
setting, setting,
showAppBar, showAppBar,
showBottomNavBar, showBottomNavBar,
visitor,
sessionCode, sessionCode,
userCode, userCode,
classCode, classCode,
...@@ -185,6 +197,7 @@ class WebState extends Equatable { ...@@ -185,6 +197,7 @@ class WebState extends Equatable {
chooseImageCmdMessage, chooseImageCmdMessage,
chooseVideoCmdFlag, chooseVideoCmdFlag,
chooseVideoCmdMessage, chooseVideoCmdMessage,
wechatQrBindCmdFlag,
testMsg, testMsg,
]; ];
} }
...@@ -370,6 +383,7 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver { ...@@ -370,6 +383,7 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
// 构造函数中已拦截判断未登录的情况进行了处理,所以这里不再处理未登录的情况 // 构造函数中已拦截判断未登录的情况进行了处理,所以这里不再处理未登录的情况
final String serverUrl = '${Constant.localServerUrl}/index.html' final String serverUrl = '${Constant.localServerUrl}/index.html'
'#/h5/login/pages/applogin?' '#/h5/login/pages/applogin?'
'visitor=${state.visitor}&'
'sessionCode=${state.sessionCode}&' 'sessionCode=${state.sessionCode}&'
'userCode=${state.userCode}&' 'userCode=${state.userCode}&'
'classCode=${state.classCode}&' 'classCode=${state.classCode}&'
...@@ -381,7 +395,38 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver { ...@@ -381,7 +395,38 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
_controller.loadRequest(Uri.parse(serverUrl)); _controller.loadRequest(Uri.parse(serverUrl));
} }
/// 微信绑定成功后,更新身份信息并重新加载 H5 页面
/// 避免销毁重建整个 WebPage,保留本地服务器和 WebView 控制器
void reloadWithIdentity({
required int visitor,
required String sessionCode,
required String userCode,
required String classCode,
required int userType,
required String stuId,
}) {
emit(state.copyWith(
loginOpFlag: true,
visitor: visitor,
sessionCode: sessionCode,
userCode: userCode,
classCode: classCode,
userType: userType,
stuId: stuId,
));
// 重新加载 H5 页面(_loadHtml 读取的是 state 中的值)
_loadHtml();
// 用新身份重新登录 IM
_loginIM();
}
Future<void> _loginIM() async { Future<void> _loginIM() async {
// 游客身份不处理IM登录
if(state.visitor == 1) {
return;
}
if (Constant.needIM) { if (Constant.needIM) {
var imService = getIt.get<ImService>(); var imService = getIt.get<ImService>();
var loginResult = await imService.login(state.userCode!); var loginResult = await imService.login(state.userCode!);
...@@ -1070,6 +1115,21 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver { ...@@ -1070,6 +1115,21 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
_sendResponse(resp); _sendResponse(resp);
} }
void setWechatQrBindCmdFlag(bool wechatQrBindCmdFlag) {
emit(state.copyWith(wechatQrBindCmdFlag: wechatQrBindCmdFlag));
}
void showWechatQrBindDialog(BuildContext context) {
setWechatQrBindCmdFlag(false);
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext dialogContext) {
return WechatQrBindDialog();
},
);
}
void setWindowInfoCmdFlag(bool windowInfoCmdFlag, String windowInfoCmdMessage) { void setWindowInfoCmdFlag(bool windowInfoCmdFlag, String windowInfoCmdMessage) {
emit(state.copyWith(windowInfoCmdFlag: windowInfoCmdFlag, windowInfoCmdMessage: windowInfoCmdMessage)); emit(state.copyWith(windowInfoCmdFlag: windowInfoCmdFlag, windowInfoCmdMessage: windowInfoCmdMessage));
} }
......
...@@ -116,6 +116,6 @@ class Constant { ...@@ -116,6 +116,6 @@ class Constant {
static const String hasShownPrivacyFirstTimeKey = 'has_shown_privacy_first_time'; static const String hasShownPrivacyFirstTimeKey = 'has_shown_privacy_first_time';
/// 测试阶段使用 /// 测试阶段使用
static const bool needIM = true; static const bool needIM = false;
static const bool needUpgrade = true; static const bool needUpgrade = true;
} }
...@@ -36,6 +36,8 @@ import 'package:appframe/data/repositories/message/upload_cancel_handler.dart'; ...@@ -36,6 +36,8 @@ import 'package:appframe/data/repositories/message/upload_cancel_handler.dart';
import 'package:appframe/data/repositories/message/upload_file.dart'; import 'package:appframe/data/repositories/message/upload_file.dart';
import 'package:appframe/data/repositories/message/upload_start_handler.dart'; import 'package:appframe/data/repositories/message/upload_start_handler.dart';
import 'package:appframe/data/repositories/message/vibrate_short_handler.dart'; import 'package:appframe/data/repositories/message/vibrate_short_handler.dart';
import 'package:appframe/data/repositories/message/wechat_bind_handler.dart';
import 'package:appframe/data/repositories/message/wechat_qr_bind_handler.dart';
import 'package:appframe/data/repositories/message/video_info_handler.dart'; import 'package:appframe/data/repositories/message/video_info_handler.dart';
import 'package:appframe/data/repositories/message/wifi_info_handler.dart'; import 'package:appframe/data/repositories/message/wifi_info_handler.dart';
import 'package:appframe/data/repositories/message/window_info_handler.dart'; import 'package:appframe/data/repositories/message/window_info_handler.dart';
...@@ -211,6 +213,12 @@ Future<void> setupLocator() async { ...@@ -211,6 +213,12 @@ Future<void> setupLocator() async {
/// 设置用户角色信息 /// 设置用户角色信息
getIt.registerLazySingleton<MessageHandler>(() => RoleInfoHandler(), instanceName: 'setRoleInfo'); getIt.registerLazySingleton<MessageHandler>(() => RoleInfoHandler(), instanceName: 'setRoleInfo');
/// 微信绑定
getIt.registerLazySingleton<MessageHandler>(() => WechatBindHandler(), instanceName: 'wechatBind');
/// 微信二维码绑定
getIt.registerLazySingleton<MessageHandler>(() => WechatQrBindHandler(), instanceName: 'wechatQrBind');
/// 设置屏幕模式 /// 设置屏幕模式
getIt.registerLazySingleton<MessageHandler>(() => ScreenHandler(), instanceName: 'setScreen'); getIt.registerLazySingleton<MessageHandler>(() => ScreenHandler(), instanceName: 'setScreen');
......
import 'dart:async';
import 'package:appframe/config/locator.dart';
import 'package:appframe/data/repositories/user_auth_repository.dart';
import 'package:appframe/data/repositories/wechat_auth_repository.dart';
import 'package:appframe/services/dispatcher.dart';
import 'package:appframe/utils/login_util.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:fluwx/fluwx.dart';
import 'package:shared_preferences/shared_preferences.dart';
class WechatBindHandler extends MessageHandler {
late final Fluwx _fluwx;
late final FluwxCancelable _fluwxCancelable;
late final WechatAuthRepository _wechatAuthRepository;
late final UserAuthRepository _userAuthRepository;
// 是否正在等待微信授权回调
bool _waitingWechatAuth = false;
// 总超时定时器
Timer? _wechatAuthTimeoutTimer;
// App 回到前台后的短延时定时器
Timer? _wechatAuthResumeTimer;
WechatBindHandler() {
_fluwx = getIt.get<Fluwx>();
_wechatAuthRepository = getIt.get<WechatAuthRepository>();
_userAuthRepository = getIt.get<UserAuthRepository>();
}
@override
Future<dynamic> handleMessage(params) async {
if (!await _fluwx.isWeChatInstalled) {
// throw Exception('设备上未安装微信App,不支持微信绑定');
Fluttertoast.showToast(msg: '设备上未安装微信App,不支持微信绑定', gravity: ToastGravity.TOP, backgroundColor: Colors.red);
return null;
}
_fluwxCancelable = _fluwx.addSubscriber(_responseListener);
var authResult = await _fluwx.authBy(
which: NormalAuth(scope: 'snsapi_userinfo', state: 'wechat_bind'),
);
if (!authResult) {
_fluwxCancelable.cancel();
// throw Exception('微信授权处理失败');
Fluttertoast.showToast(msg: '微信授权处理失败', gravity: ToastGravity.TOP, backgroundColor: Colors.red);
return null;
}
// 启动等待微信授权回调的兜底机制
_startWechatAuthWaiting();
// 微信授权为异步回调,不返回结果给H5
return null;
}
void _responseListener(WeChatResponse response) async {
if (response is WeChatAuthResponse) {
// 收到正式回调,结束等待状态
_finishWechatAuthWaiting();
if (response.code == null || response.code == '') {
Fluttertoast.showToast(msg: '微信授权取消', gravity: ToastGravity.TOP);
_cleanup();
return;
}
try {
// 1. 用code换取会话信息
var resultData = await _wechatAuthRepository.codeToSk(response.code!) as Map<String, dynamic>?;
// 请求接口异常
if (resultData == null) {
Fluttertoast.showToast(msg: '绑定请求处理失败', gravity: ToastGravity.TOP);
_cleanup();
return;
}
// 状态码错误
if (resultData['resultCode'] != '001') {
Fluttertoast.showToast(msg: '绑定请求状态失败', gravity: ToastGravity.TOP);
_cleanup();
return;
}
var data = resultData['data'] as Map<String, dynamic>;
var wechatUserCode = data['userCode'] as String;
// 2. 从SharedPreferences获取当前用户信息
var sharedPreferences = getIt.get<SharedPreferences>();
var visitorId = sharedPreferences.getString('auth_visitor_id') ?? '';
var visitorType = sharedPreferences.getString('auth_visitor_type') ?? '';
if (visitorId.isEmpty || visitorType.isEmpty) {
Fluttertoast.showToast(msg: '用户信息获取失败,请重新登录', gravity: ToastGravity.TOP);
_cleanup();
return;
}
if (visitorType != 'apple' && visitorType != 'phone') {
Fluttertoast.showToast(msg: '用户信息错误,请重新登录', gravity: ToastGravity.TOP);
_cleanup();
return;
}
// 3. 调用绑定接口
var bindResult = await _userAuthRepository.newBinding(
visitorId,
wechatUserCode,
visitorType
) as Map<String, dynamic>?;
if (bindResult != null && bindResult['code'] == 0) {
// Fluttertoast.showToast(msg: '微信绑定成功', gravity: ToastGravity.TOP);
LoginUtil.handleLoginSuccess(data, 0, 'reload');
} else {
var errorMsg = bindResult?['error'] ?? '微信绑定失败';
Fluttertoast.showToast(msg: errorMsg, gravity: ToastGravity.TOP);
}
} catch (e) {
debugPrint('wechatBind error: $e');
Fluttertoast.showToast(msg: '微信绑定异常', gravity: ToastGravity.TOP);
} finally {
_cleanup();
}
}
}
// 标记进入"等待微信授权回调"状态,并启动总超时
void _startWechatAuthWaiting() {
_waitingWechatAuth = true;
_wechatAuthTimeoutTimer?.cancel();
_wechatAuthTimeoutTimer = Timer(const Duration(seconds: 30), () {
if (_waitingWechatAuth) {
_finishWechatAuthWaiting(reason: _WechatBindFinishReason.timeout);
}
});
}
// 结束等待,按场景给出提示
void _finishWechatAuthWaiting({
_WechatBindFinishReason reason = _WechatBindFinishReason.response,
}) {
if (!_waitingWechatAuth) return;
_waitingWechatAuth = false;
_wechatAuthTimeoutTimer?.cancel();
_wechatAuthResumeTimer?.cancel();
_wechatAuthTimeoutTimer = null;
_wechatAuthResumeTimer = null;
switch (reason) {
case _WechatBindFinishReason.cancel:
Fluttertoast.showToast(msg: '已取消微信授权', gravity: ToastGravity.TOP);
_cleanup();
break;
case _WechatBindFinishReason.timeout:
Fluttertoast.showToast(msg: '微信授权超时,请重试', gravity: ToastGravity.TOP);
_cleanup();
break;
case _WechatBindFinishReason.response:
// 正常收到回调时不弹提示
break;
}
}
// 清理资源
void _cleanup() {
_fluwxCancelable.cancel();
_wechatAuthTimeoutTimer?.cancel();
_wechatAuthResumeTimer?.cancel();
}
}
enum _WechatBindFinishReason {
// 收到了正式的 WeChatAuthResponse
response,
// App 已回到前台但仍无回调,判定为取消
cancel,
// 总超时
timeout,
}
import 'package:appframe/bloc/web_cubit.dart';
import 'package:appframe/services/dispatcher.dart';
class WechatQrBindHandler extends MessageHandler {
late WebCubit? _webCubit;
@override
void setCubit(WebCubit cubit) {
_webCubit = cubit;
}
void _unfollowCubit() {
_webCubit = null;
}
@override
Future<dynamic> handleMessage(params) async {
try {
_webCubit!.setWechatQrBindCmdFlag(true);
} finally {
_unfollowCubit();
}
// 二维码绑定流程为异步,不返回结果给H5
return null;
}
}
...@@ -78,7 +78,7 @@ class PhoneAuthRepository { ...@@ -78,7 +78,7 @@ class PhoneAuthRepository {
/// ///
Future<dynamic> login(String phone, String verifyCode) async { Future<dynamic> login(String phone, String verifyCode) async {
Response resp = await _appService.post( Response resp = await _appService.post(
'/api/v1/comm/phone/login', '/api/v1/comm/phone/loginv2',
{ {
"phone": phone, "phone": phone,
"verifyCode": verifyCode, "verifyCode": verifyCode,
......
...@@ -64,13 +64,13 @@ class UserAuthRepository { ...@@ -64,13 +64,13 @@ class UserAuthRepository {
/// "error": "", /// "error": "",
/// "code": 0, /// "code": 0,
/// } /// }
Future<dynamic> newBinding(String userid, String bxeUserId) async { Future<dynamic> newBinding(String userid, String bxeUserId, String type) async {
Response resp = await _appService.post( Response resp = await _appService.post(
'/api/v1/comm/user/newbinding', '/api/v1/comm/user/newbinding',
{ {
"userId": userid, "userId": userid,
"bxeUserId": bxeUserId, "bxeUserId": bxeUserId,
"type": "apple", "type": type,
}, },
); );
return resp.statusCode == HttpStatus.ok ? resp.data : null; return resp.statusCode == HttpStatus.ok ? resp.data : null;
......
...@@ -64,7 +64,8 @@ class MessageDispatcher { ...@@ -64,7 +64,8 @@ class MessageDispatcher {
h5Message.cmd.startsWith("setTitlebar") || h5Message.cmd.startsWith("setTitlebar") ||
h5Message.cmd == "audioPlay" || h5Message.cmd == "audioPlay" ||
h5Message.cmd == "openLink" || h5Message.cmd == "openLink" ||
h5Message.cmd == "uploadStart") { h5Message.cmd == "uploadStart" ||
h5Message.cmd == "wechatQrBind") {
handler.setCubit(webCubit!); handler.setCubit(webCubit!);
handler.setMessage(message); handler.setMessage(message);
} }
......
...@@ -161,7 +161,7 @@ class LoginMainPage extends StatelessWidget { ...@@ -161,7 +161,7 @@ class LoginMainPage extends StatelessWidget {
if (state.showAgreed) { if (state.showAgreed) {
_showAgreementDialog(context, context.read<LoginMainCubit>()); _showAgreementDialog(context, context.read<LoginMainCubit>());
} else if (state.showNeedWechatForApple) { } else if (state.showNeedWechatForApple) {
_showNeedWechatDialogForApple(context, context.read<LoginMainCubit>()); // _showNeedWechatDialogForApple(context, context.read<LoginMainCubit>());
} else if (state.showPrivacyFirstTime) { } else if (state.showPrivacyFirstTime) {
_showPrivacyFirstTimeDialog(context, context.read<LoginMainCubit>()); _showPrivacyFirstTimeDialog(context, context.read<LoginMainCubit>());
} }
...@@ -381,59 +381,59 @@ class LoginMainPage extends StatelessWidget { ...@@ -381,59 +381,59 @@ class LoginMainPage extends StatelessWidget {
); );
} }
void _showNeedWechatDialogForApple(BuildContext context, LoginMainCubit loginMainCubit) { // void _showNeedWechatDialogForApple(BuildContext context, LoginMainCubit loginMainCubit) {
showDialog( // showDialog(
context: context, // context: context,
barrierDismissible: false, // barrierDismissible: false,
builder: (BuildContext ctx) { // builder: (BuildContext ctx) {
return PopScope( // return PopScope(
canPop: false, // canPop: false,
child: AlertDialog( // child: AlertDialog(
shape: RoundedRectangleBorder( // shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all( // borderRadius: BorderRadius.all(
Radius.circular(5), // Radius.circular(5),
), // ),
), // ),
title: Text( // title: Text(
'温馨提示', // '温馨提示',
style: TextStyle( // style: TextStyle(
fontSize: 17, // fontSize: 17,
color: Color(0xFF000000), // color: Color(0xFF000000),
// fontWeight: FontWeight.bold, // // fontWeight: FontWeight.bold,
), // ),
textAlign: TextAlign.center, // textAlign: TextAlign.center,
), // ),
content: Text.rich( // content: Text.rich(
TextSpan( // TextSpan(
text: '为了避免您之前在微信小程序的使用数据不丢失,必须绑定微信才可以继续!', // text: '为了避免您之前在微信小程序的使用数据不丢失,必须绑定微信才可以继续!',
style: TextStyle(color: Color(0xFF666666), fontSize: 14), // style: TextStyle(color: Color(0xFF666666), fontSize: 14),
), // ),
), // ),
actions: [ // actions: [
Center( // Center(
child: TextButton( // child: TextButton(
onPressed: () { // onPressed: () {
Navigator.of(ctx).pop('OK'); // Navigator.of(ctx).pop('OK');
loginMainCubit.wechatAuthForApple(); // loginMainCubit.wechatAuthForApple();
}, // },
style: TextButton.styleFrom( // style: TextButton.styleFrom(
foregroundColor: Color(0xFF7691FA), // foregroundColor: Color(0xFF7691FA),
textStyle: TextStyle(fontSize: 17), // textStyle: TextStyle(fontSize: 17),
minimumSize: Size.fromHeight(40), // minimumSize: Size.fromHeight(40),
padding: EdgeInsets.zero, // padding: EdgeInsets.zero,
shape: RoundedRectangleBorder( // shape: RoundedRectangleBorder(
borderRadius: BorderRadius.zero, // borderRadius: BorderRadius.zero,
), // ),
), // ),
child: Text('绑定微信'), // child: Text('绑定微信'),
), // ),
), // ),
], // ],
), // ),
); // );
}, // },
); // );
} // }
// 首次打开显示个人信息收集提示弹窗 // 首次打开显示个人信息收集提示弹窗
Future<void> _showPrivacyFirstTimeDialog(BuildContext context, LoginMainCubit loginMainCubit) async { Future<void> _showPrivacyFirstTimeDialog(BuildContext context, LoginMainCubit loginMainCubit) async {
......
...@@ -231,7 +231,7 @@ class LoginMainPageV3 extends StatelessWidget { ...@@ -231,7 +231,7 @@ class LoginMainPageV3 extends StatelessWidget {
if (state.showAgreed) { if (state.showAgreed) {
_showAgreementDialog(context, context.read<LoginMainCubit>()); _showAgreementDialog(context, context.read<LoginMainCubit>());
} else if (state.showNeedWechatForApple) { } else if (state.showNeedWechatForApple) {
_showNeedWechatDialogForApple(context, context.read<LoginMainCubit>()); //_showNeedWechatDialogForApple(context, context.read<LoginMainCubit>());
} else if (state.showPrivacyFirstTime) { } else if (state.showPrivacyFirstTime) {
_showPrivacyFirstTimeDialog(context, context.read<LoginMainCubit>()); _showPrivacyFirstTimeDialog(context, context.read<LoginMainCubit>());
} }
...@@ -450,59 +450,59 @@ class LoginMainPageV3 extends StatelessWidget { ...@@ -450,59 +450,59 @@ class LoginMainPageV3 extends StatelessWidget {
); );
} }
void _showNeedWechatDialogForApple(BuildContext context, LoginMainCubit loginMainCubit) { // void _showNeedWechatDialogForApple(BuildContext context, LoginMainCubit loginMainCubit) {
showDialog( // showDialog(
context: context, // context: context,
barrierDismissible: false, // barrierDismissible: false,
builder: (BuildContext ctx) { // builder: (BuildContext ctx) {
return PopScope( // return PopScope(
canPop: false, // canPop: false,
child: AlertDialog( // child: AlertDialog(
shape: RoundedRectangleBorder( // shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all( // borderRadius: BorderRadius.all(
Radius.circular(5), // Radius.circular(5),
), // ),
), // ),
title: Text( // title: Text(
'温馨提示', // '温馨提示',
style: TextStyle( // style: TextStyle(
fontSize: 17, // fontSize: 17,
color: Color(0xFF000000), // color: Color(0xFF000000),
// fontWeight: FontWeight.bold, // // fontWeight: FontWeight.bold,
), // ),
textAlign: TextAlign.center, // textAlign: TextAlign.center,
), // ),
content: Text.rich( // content: Text.rich(
TextSpan( // TextSpan(
text: '为了避免您之前在微信小程序的使用数据不丢失,必须绑定微信才可以继续!', // text: '为了避免您之前在微信小程序的使用数据不丢失,必须绑定微信才可以继续!',
style: TextStyle(color: Color(0xFF666666), fontSize: 14), // style: TextStyle(color: Color(0xFF666666), fontSize: 14),
), // ),
), // ),
actions: [ // actions: [
Center( // Center(
child: TextButton( // child: TextButton(
onPressed: () { // onPressed: () {
Navigator.of(ctx).pop('OK'); // Navigator.of(ctx).pop('OK');
loginMainCubit.wechatAuthForApple(); // loginMainCubit.wechatAuthForApple();
}, // },
style: TextButton.styleFrom( // style: TextButton.styleFrom(
foregroundColor: Color(0xFF7691FA), // foregroundColor: Color(0xFF7691FA),
textStyle: TextStyle(fontSize: 17), // textStyle: TextStyle(fontSize: 17),
minimumSize: Size.fromHeight(40), // minimumSize: Size.fromHeight(40),
padding: EdgeInsets.zero, // padding: EdgeInsets.zero,
shape: RoundedRectangleBorder( // shape: RoundedRectangleBorder(
borderRadius: BorderRadius.zero, // borderRadius: BorderRadius.zero,
), // ),
), // ),
child: Text('绑定微信'), // child: Text('绑定微信'),
), // ),
), // ),
], // ],
), // ),
); // );
}, // },
); // );
} // }
/// 首次打开显示个人信息收集提示弹窗 /// 首次打开显示个人信息收集提示弹窗
/// 值针对iOS,Android用原生界面显示 /// 值针对iOS,Android用原生界面显示
......
...@@ -19,6 +19,7 @@ class WebPage extends StatelessWidget { ...@@ -19,6 +19,7 @@ class WebPage extends StatelessWidget {
var loginOpFlag = true; var loginOpFlag = true;
var visitor = extraData?['visitor'];
var sessionCode = extraData?['sessionCode']; var sessionCode = extraData?['sessionCode'];
var userCode = extraData?['userCode']; var userCode = extraData?['userCode'];
var classCode = extraData?['classCode']; var classCode = extraData?['classCode'];
...@@ -29,6 +30,7 @@ class WebPage extends StatelessWidget { ...@@ -29,6 +30,7 @@ class WebPage extends StatelessWidget {
loginOpFlag = false; loginOpFlag = false;
var sharedPreferences = getIt.get<SharedPreferences>(); var sharedPreferences = getIt.get<SharedPreferences>();
visitor = sharedPreferences.getInt('auth_visitor');
sessionCode = sharedPreferences.getString('auth_sessionCode'); sessionCode = sharedPreferences.getString('auth_sessionCode');
userCode = sharedPreferences.getString('auth_userCode'); userCode = sharedPreferences.getString('auth_userCode');
classCode = sharedPreferences.getString('auth_classCode'); classCode = sharedPreferences.getString('auth_classCode');
...@@ -41,6 +43,7 @@ class WebPage extends StatelessWidget { ...@@ -41,6 +43,7 @@ class WebPage extends StatelessWidget {
final webCubit = WebCubit( final webCubit = WebCubit(
WebState( WebState(
loginOpFlag: loginOpFlag, loginOpFlag: loginOpFlag,
visitor: visitor,
sessionCode: sessionCode, sessionCode: sessionCode,
userCode: userCode, userCode: userCode,
classCode: classCode, classCode: classCode,
...@@ -171,6 +174,8 @@ class WebPage extends StatelessWidget { ...@@ -171,6 +174,8 @@ class WebPage extends StatelessWidget {
context.read<WebCubit>().chooseImage(context); context.read<WebCubit>().chooseImage(context);
} else if (state.chooseVideoCmdFlag) { } else if (state.chooseVideoCmdFlag) {
context.read<WebCubit>().chooseVideo(context); context.read<WebCubit>().chooseVideo(context);
} else if (state.wechatQrBindCmdFlag) {
context.read<WebCubit>().showWechatQrBindDialog(context);
} }
}, },
), ),
......
import 'package:appframe/config/constant.dart';
import 'package:appframe/config/locator.dart';
import 'package:appframe/config/routes.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
/// 登录成功后的公共处理逻辑
class LoginUtil {
/// 处理登录成功后的数据解析、缓存持久化和路由跳转
///
/// [data] 登录接口返回的 data 字段
/// [visitor] 是否为游客(0=非游客,1=游客)
/// [loginType] 登录类型,router=跳转路由,reload=重新加载
static void handleLoginSuccess(Map<String, dynamic> data, int visitor, String loginType) {
var roles = data['roles'];
// 过滤出家长角色的数据
if (roles?.isNotEmpty ?? false) {
roles.removeWhere((element) => element['userType'] != 2);
} else {
roles = [];
}
var sessionCode = data['sessionCode'];
var userCode = data['userCode'];
var classCode = '';
var userType = 0;
var stuId = '';
var className = '';
var stuName = '';
var relation = '';
var sharedPreferences = getIt.get<SharedPreferences>();
if (roles.isNotEmpty) {
var role = roles[0];
classCode = role['classCode'];
userType = role['userType'];
stuId = role['stuId'];
className = role['className'];
stuName = role['stuName'];
relation = role['relation'] ?? '';
// 将角色中的班级数据处理后,进行缓存
List<String> classIdList = [];
for (var role in roles) {
classIdList.add(role['classCode'] as String);
}
debugPrint('classCodeIds:-------------- $classIdList');
sharedPreferences.setStringList(Constant.classIdSetKey, classIdList);
} else {
sharedPreferences.setStringList(Constant.classIdSetKey, []);
}
var preUserCode = sharedPreferences.getString('pre_userCode') ?? '';
if (userCode != preUserCode) {
// 新用户登录
sharedPreferences.setString('pre_userCode', userCode);
sharedPreferences.setString('pre_classCode', classCode);
sharedPreferences.setInt('pre_userType', userType);
sharedPreferences.setString('pre_stuId', stuId);
} else {
// 前一个登录用户重新登录
var preClassCode = sharedPreferences.getString('pre_classCode') ?? '';
var preUserType = sharedPreferences.getInt('pre_userType') ?? 0;
var preStuId = sharedPreferences.getString('pre_stuId') ?? '';
if (preClassCode != '' &&
roles.any((element) =>
element['classCode'] == preClassCode &&
element['userType'] == preUserType &&
element['stuId'] == preStuId)) {
classCode = preClassCode;
userType = preUserType;
stuId = preStuId;
} else {
sharedPreferences.setString('pre_userCode', userCode);
sharedPreferences.setString('pre_classCode', classCode);
sharedPreferences.setInt('pre_userType', userType);
sharedPreferences.setString('pre_stuId', stuId);
}
}
sharedPreferences.setInt('auth_visitor', visitor);
sharedPreferences.setString('auth_sessionCode', sessionCode);
sharedPreferences.setString('auth_userCode', userCode);
sharedPreferences.setString('auth_classCode', classCode);
sharedPreferences.setInt('auth_userType', userType);
sharedPreferences.setString('auth_stuId', stuId);
sharedPreferences.setString('auth_className', className);
sharedPreferences.setString('auth_stuName', stuName);
sharedPreferences.setString('auth_relation', relation);
if (loginType == 'router') {
router.go(
'/web',
extra: {
'visitor': visitor,
'sessionCode': sessionCode,
'userCode': userCode,
'classCode': classCode,
'userType': userType,
'stuId': stuId,
},
);
} else if (loginType == 'reload') {
// 通知当前 WebCubit 更新身份信息并重新加载 H5,避免销毁重建整个页面
WebCubitHolder.instance?.reloadWithIdentity(
visitor: 0,
sessionCode: sessionCode,
userCode: userCode,
classCode: classCode,
userType: userType,
stuId: stuId,
);
}
}
}
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!