Commit 2847354b by tanghuan

IM消息推送的需求,部分调整

1 parent 36914fc1
import 'package:appframe/config/constant.dart';
import 'package:appframe/config/locator.dart';
import 'package:appframe/config/routes.dart';
import 'package:appframe/data/repositories/wechat_auth_repository.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fluwx/fluwx.dart';
import 'package:shared_preferences/shared_preferences.dart';
......@@ -131,14 +133,25 @@ class LoginMainCubit extends Cubit<LoginMainState> {
var userType = 0;
var stuId = '';
var sharedPreferences = getIt.get<SharedPreferences>();
if (roles.isNotEmpty) {
var role = roles[0];
classCode = role['classCode'];
userType = role['userType'];
stuId = role['stuId'];
// 将角色中的班级数据处理后,进行缓存
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 sharedPreferences = getIt.get<SharedPreferences>();
var preUserCode = sharedPreferences.getString('pre_userCode') ?? '';
if (userCode != preUserCode) {
// 新用户登录
......
import 'dart:async';
import 'package:appframe/config/constant.dart';
import 'package:appframe/config/locator.dart';
import 'package:appframe/config/routes.dart';
import 'package:appframe/data/repositories/phone_auth_repository.dart';
......@@ -163,14 +164,25 @@ class LoginPhoneCubit extends Cubit<LoginPhoneState> {
var userType = 0;
var stuId = '';
var sharedPreferences = getIt.get<SharedPreferences>();
if (roles.isNotEmpty) {
var role = roles[0];
classCode = role['classCode'];
userType = role['userType'];
stuId = role['stuId'];
// 将角色中的班级数据处理后,进行缓存
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 sharedPreferences = getIt.get<SharedPreferences>();
var preUserCode = sharedPreferences.getString('pre_userCode') ?? '';
if (userCode != preUserCode) {
// 新用户登录
......@@ -186,7 +198,7 @@ class LoginPhoneCubit extends Cubit<LoginPhoneState> {
if (preClassCode != '' &&
roles.any((element) =>
element['classCode'] == preClassCode &&
element['classCode'] == preClassCode &&
element['userType'] == preUserType &&
element['stuId'] == preStuId)) {
classCode = preClassCode;
......
......@@ -7,6 +7,7 @@ import 'package:appframe/config/routes.dart';
import 'package:appframe/data/repositories/wechat_auth_repository.dart';
import 'package:crypto/crypto.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fluwx/fluwx.dart';
import 'package:shared_preferences/shared_preferences.dart';
......@@ -173,14 +174,25 @@ class LoginQrCubit extends Cubit<LoginQrState> {
var userType = 0;
var stuId = '';
var sharedPreferences = getIt.get<SharedPreferences>();
if (roles.isNotEmpty) {
var role = roles[0];
classCode = role['classCode'];
userType = role['userType'];
stuId = role['stuId'];
// 将角色中的班级数据处理后,进行缓存
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 sharedPreferences = getIt.get<SharedPreferences>();
var preUserCode = sharedPreferences.getString('pre_userCode') ?? '';
if (userCode != preUserCode) {
// 新用户登录
......
......@@ -39,6 +39,10 @@ class WebState extends Equatable {
final String opIcon;
final bool showBottomNavBar;
// 是否通过登录操作进入
// 用来控制是否需要判断处理加群、退群等逻辑
final bool loginOpFlag;
final String? sessionCode;
final String? userCode;
final String? classCode;
......@@ -61,6 +65,10 @@ class WebState extends Equatable {
final bool chooseVideoCmdFlag;
final String chooseVideoCmdMessage;
/// 提示信息
final bool showSnackBar;
final String snackBarMsg;
final String h5Version;
/// 用于测试监测问题
......@@ -76,6 +84,7 @@ class WebState extends Equatable {
this.bgColor = 0xFF7691FA,
this.opIcon = 'none',
this.showBottomNavBar = false,
this.loginOpFlag = false,
this.sessionCode,
this.userCode,
this.classCode,
......@@ -89,6 +98,8 @@ class WebState extends Equatable {
this.chooseImageCmdMessage = '',
this.chooseVideoCmdFlag = false,
this.chooseVideoCmdMessage = '',
this.showSnackBar = false,
this.snackBarMsg = '',
this.h5Version = '',
this.testMsg = '',
});
......@@ -104,6 +115,7 @@ class WebState extends Equatable {
String? opIcon,
bool? showNavBar,
bool? showBottomNavBar,
bool? loginOpFlag,
String? sessionCode,
String? userCode,
String? classCode,
......@@ -117,6 +129,8 @@ class WebState extends Equatable {
String? chooseImageCmdMessage,
bool? chooseVideoCmdFlag,
String? chooseVideoCmdMessage,
bool? showSnackBar,
String? snackBarMsg,
String? h5Version,
String? testMsg,
}) {
......@@ -130,6 +144,7 @@ class WebState extends Equatable {
bgColor: bgColor ?? this.bgColor,
opIcon: opIcon ?? this.opIcon,
showBottomNavBar: showBottomNavBar ?? this.showBottomNavBar,
loginOpFlag: loginOpFlag ?? this.loginOpFlag,
sessionCode: sessionCode ?? this.sessionCode,
userCode: userCode ?? this.userCode,
classCode: classCode ?? this.classCode,
......@@ -143,6 +158,8 @@ class WebState extends Equatable {
chooseImageCmdMessage: chooseImageCmdMessage ?? this.chooseImageCmdMessage,
chooseVideoCmdFlag: chooseVideoCmdFlag ?? this.chooseVideoCmdFlag,
chooseVideoCmdMessage: chooseVideoCmdMessage ?? this.chooseVideoCmdMessage,
showSnackBar: showSnackBar ?? this.showSnackBar,
snackBarMsg: snackBarMsg ?? this.snackBarMsg,
h5Version: h5Version ?? this.h5Version,
testMsg: testMsg ?? this.testMsg,
);
......@@ -172,6 +189,8 @@ class WebState extends Equatable {
chooseImageCmdMessage,
chooseVideoCmdFlag,
chooseVideoCmdMessage,
showSnackBar,
snackBarMsg,
h5Version,
testMsg,
];
......@@ -382,12 +401,62 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
var imService = getIt.get<ImService>();
var loginResult = await imService.login(state.userCode!);
if (loginResult) {
print("缓存自动登录处,IM 登录成功");
await imService.registerPush();
debugPrint("缓存自动登录处,IM 登录成功");
// 注册推送服务
imService.registerPush();
//
if (state.loginOpFlag) {
_getPendingGroup();
}
} else {
print("缓存自动登录处,IM 登录失败");
debugPrint("缓存自动登录处,IM 登录失败");
}
}
}
///
/// 获取待加群和待退群
///
Future<Map<String, List<String>>> _getPendingGroup() async {
var classIds = getIt.get<SharedPreferences>().getStringList(Constant.classIdSetKey);
List<String> classIdList = [];
if (classIds != null) {
// 转换和去重
classIdList = Set<String>.from(classIds).toList();
}
var unjoinedGroupIdList = <String>[];
var leaveGroupIdList = <String>[];
Map<String, List<String>> result = {
'unjoinedGroupIdList': unjoinedGroupIdList,
'leaveGroupIdList': leaveGroupIdList,
};
var imService = getIt.get<ImService>();
var joinedGroupIdList = await imService.getJoinedGroupList();
// 获取群组列表失败,joinedGroupIdList=null
if (joinedGroupIdList == null) {
return result;
}
// 需要加群
for (var classId in classIdList) {
if (!joinedGroupIdList.contains(classId)) {
unjoinedGroupIdList.add(classId);
}
}
// 需要退群
for (var joinedGroupId in joinedGroupIdList) {
if (!classIdList.contains(joinedGroupId)) {
leaveGroupIdList.add(joinedGroupId);
}
}
debugPrint('待加群: $unjoinedGroupIdList');
debugPrint('待退群: $leaveGroupIdList');
return result;
}
void _onMessageReceived(JavaScriptMessage message) async {
......
......@@ -93,6 +93,11 @@ class Constant {
? 'kM4yqbehB3io9UiLvH6eHvM7xAhfYxoyyaO1tLoHgKltcaI7MZXkUbpFaWdeQIqe'
: 'GkMkhAnrCThYrZxApCBdFidcAC8USwVnhoqMGzqmSvmcegRCvETtDR2Te9btarnG';
/// Key
/// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
static const String classIdSetKey = 'auth_class_ids';
/// 测试阶段使用
static const bool needIM = false;
static const bool needUpgrade = true;
......
......@@ -11,6 +11,7 @@ import 'package:tencent_cloud_chat_sdk/enum/log_level_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/login_status.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_elem_type.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_receipt.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
......@@ -20,7 +21,7 @@ import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
class ImService {
// sdkListener 事件监听器
V2TimSDKListener sdkListener = V2TimSDKListener(
final V2TimSDKListener _sdkListener = V2TimSDKListener(
onConnectFailed: (int code, String error) {
// 连接失败的回调函数
// code 错误码
......@@ -41,6 +42,7 @@ class ImService {
},
onUserSigExpired: () {
// 在线时票据过期:此时您需要生成新的 userSig 并再次调用 V2TIMManager 的 login() 函数重新登录。
// 如果收到 onUserSigExpired 回调,说明您登录用的 UserSig 票据已经过期,请使用新签发的 UserSig 进行重新登录。如果继续使用过期的 UserSig,会导致 IM SDK 登录进入死循环。
},
onUserStatusChanged: (List<V2TimUserStatus> userStatusList) {
//用户状态变更通知
......@@ -78,10 +80,9 @@ class ImService {
// message.textElem?.text;
// 时间戳转换
// DateTime timestamp = DateTime.fromMillisecondsSinceEpoch(message.timestamp! * 1000);
// String formattedTime = DateFormat('yyyy-MM-dd HH:mm:ss').format(timestamp);
//
// print("收到IM消息—— 发送时间:$formattedTime 发送者:${message.sender} 内容:${message.textElem?.text}");
DateTime dt = DateTime.fromMillisecondsSinceEpoch(message.timestamp! * 1000);
print(
"收到IM消息—— 时间:${dt.year}-${dt.month}-${dt.day} ${dt.hour}:${dt.minute}:${dt.second} 发送者:${message.sender} 内容:${message.textElem?.text}");
// 目前只会有文本消息,所以其他消息类型暂不处理,直接return
return;
......@@ -184,22 +185,22 @@ class ImService {
V2TimAdvancedMsgListener get msgListener => _msgListener;
///
/// 初始化 IM SDK
///
Future<bool> initSdk() async {
// 初始化SDK
var initSDKRes = await TencentImSDKPlugin.v2TIMManager.initSDK(
sdkAppID: Constant.imSdkAppId,
loglevel: LogLevelEnum.V2TIM_LOG_ALL,
listener: sdkListener,
listener: _sdkListener,
);
if (initSDKRes.code == 0) {
print("IM初始化成功--------");
print("IM SDK 初始化成功-------- ${initSDKRes.data}");
return true;
} else {
print("IM初始化失败--------");
/// 失败后的处理,
print("IM SDK 初始化失败-------- ${initSDKRes.data}");
return false;
}
}
......@@ -224,10 +225,13 @@ class ImService {
Future<bool> login(String userID) async {
// 登录前先判断登录状态
var loginStatus = await TencentImSDKPlugin.v2TIMManager.getLoginStatus();
print('IM 登录状态:${loginStatus.code}');
if (loginStatus.code == LoginStatus.V2TIM_STATUS_LOGINED) {
// 已经登录,不需要再次登录
return true;
if (loginStatus.code == 0) {
debugPrint('登录前检测 IM 登录状态:${loginStatus.data}');
if (loginStatus.data == LoginStatus.V2TIM_STATUS_LOGINED) {
// 已经登录,不需要再次登录
debugPrint('IM 已经登录,不需要再次登录');
return true;
}
}
final apiService = getIt.get<ApiService>(instanceName: "appApiService");
......@@ -240,13 +244,17 @@ class ImService {
V2TimCallback res = await TencentImSDKPlugin.v2TIMManager.login(userID: userID, userSig: userSig);
loginStatus = await TencentImSDKPlugin.v2TIMManager.getLoginStatus();
print('IM 登录状态2:${loginStatus.code}');
print('IM 登录状态${loginStatus.data}');
if (res.code == 0) {
print("IM 登录成功--------");
// 添加消息的事件监听器
// await TencentImSDKPlugin.v2TIMManager.getMessageManager().addAdvancedMsgListener(listener: msgListener);
await addMsgListener(_msgListener);
var loginUserResp = await TencentImSDKPlugin.v2TIMManager.getLoginUser();
print("当前登录用户:${loginUserResp.data}");
return true;
} else {
// 登录失败逻辑
......@@ -255,7 +263,9 @@ class ImService {
}
}
///
/// 登出
/// 一般不需要使用,IM与App生命周期一致即可
///
Future<bool> logout() async {
var logoutRes = await TencentImSDKPlugin.v2TIMManager.logout();
......@@ -268,6 +278,18 @@ class ImService {
}
}
Future<List<String>?> getJoinedGroupList() async {
var groupListRes = await TencentImSDKPlugin.v2TIMManager.getGroupManager().getJoinedGroupList();
if (groupListRes.code == 0) {
debugPrint("获取群列表成功--------");
List<V2TimGroupInfo>? groupList = groupListRes.data;
return groupList?.map((ele) => ele.groupID).toList();
} else {
debugPrint('获取群列表失败 Res.code = ${groupListRes.code}');
return null;
}
}
void _onNotificationClicked({required String ext, String? userID, String? groupID}) {
print("收到推送消息--------");
print("_onNotificationClicked: $ext, userID: $userID, groupID: $groupID");
......@@ -309,19 +331,19 @@ class ImService {
///
TencentCloudChatPush().addPushListener(listener: timPushListener);
// var getIdRes = await TencentCloudChatPush().getRegistrationID();
// if (getIdRes.code == 0) {
// print('getRegistrationID: ${getIdRes.data}');
// } else {
// print('getRegistrationID: ${getIdRes.errorMessage}');
// }
//
// var tokenRes = await TencentCloudChatPush().getAndroidPushToken();
// if (tokenRes.code == 0) {
// print('android Token: ${tokenRes.data}');
// } else {
// print('android Token: ${tokenRes.errorMessage}');
// }
var getIdRes = await TencentCloudChatPush().getRegistrationID();
if (getIdRes.code == 0) {
print('getRegistrationID: ${getIdRes.data}');
} else {
print('getRegistrationID: ${getIdRes.errorMessage}');
}
var tokenRes = await TencentCloudChatPush().getAndroidPushToken();
if (tokenRes.code == 0) {
print('android Token: ${tokenRes.data}');
} else {
print('android Token: ${tokenRes.errorMessage}');
}
} else {
print('注册推送失败--------');
print('${res.errorMessage}');
......
......@@ -3,6 +3,9 @@ import 'package:appframe/config/constant.dart';
import 'package:appframe/config/env_config.dart';
import 'package:appframe/config/locator.dart';
import 'package:appframe/config/routes.dart';
import 'package:appframe/ui/widgets/tip_overlay_widget.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
......@@ -16,6 +19,8 @@ class WebPage extends StatelessWidget {
Widget build(BuildContext buildContext) {
final Map<String, dynamic>? extraData = GoRouterState.of(buildContext).extra as Map<String, dynamic>?;
var loginOpFlag = true;
var sessionCode = extraData?['sessionCode'];
var userCode = extraData?['userCode'];
var classCode = extraData?['classCode'];
......@@ -23,6 +28,8 @@ class WebPage extends StatelessWidget {
var stuId = extraData?['stuId'];
if (sessionCode == null || sessionCode == '') {
loginOpFlag = false;
var sharedPreferences = getIt.get<SharedPreferences>();
sessionCode = sharedPreferences.getString('auth_sessionCode');
userCode = sharedPreferences.getString('auth_userCode');
......@@ -34,6 +41,7 @@ class WebPage extends StatelessWidget {
return BlocProvider(
create: (context) => WebCubit(
WebState(
loginOpFlag: loginOpFlag,
sessionCode: sessionCode,
userCode: userCode,
classCode: classCode,
......@@ -130,6 +138,8 @@ class WebPage extends StatelessWidget {
context.read<WebCubit>().chooseImage(context);
} else if (state.chooseVideoCmdFlag) {
context.read<WebCubit>().chooseVideo(context);
} else if (state.showSnackBar) {
TipOverlayUtil.showTip(context, state.snackBarMsg);
}
},
),
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!