Commit b489b6e0 by tanghuan

dev

1 parent e732a20e
...@@ -204,7 +204,7 @@ class WebCubit extends Cubit<WebState> { ...@@ -204,7 +204,7 @@ class WebCubit extends Cubit<WebState> {
// 版本不一致则需要升级 // 版本不一致则需要升级
// 需要强制升级时,一直等待下载完成 // 需要强制升级时,一直等待下载完成
// 不需要强制升级时,异步下载,下载完后弹框提示用户进行确认操作 // 不需要强制升级时,异步下载,下载完后弹框提示用户进行确认操作
if (curVersion != configVersion) { if (Constant.needUpgrade && curVersion != configVersion) {
if (force == "1") { if (force == "1") {
// 一直等待升级完成 // 一直等待升级完成
// 遮罩界面 // 遮罩界面
...@@ -456,6 +456,21 @@ class WebCubit extends Cubit<WebState> { ...@@ -456,6 +456,21 @@ class WebCubit extends Cubit<WebState> {
_sendResponse(resp); _sendResponse(resp);
} }
Future<void> handleToggleDebug() async {
var sharedPreferences = getIt.get<SharedPreferences>();
var debug = sharedPreferences.getInt('debug') ?? 0;
debug = (debug == 0 ? 1 : 0);
sharedPreferences.setInt('debug', debug);
var resp = {
'unique': '',
'cmd': 'toggleDebug',
'data': {'debug': debug},
'errMsg': ''
};
_sendResponse(resp);
}
bool setTitleBar(String title, String color, String bgColor, String icon) { bool setTitleBar(String title, String color, String bgColor, String icon) {
int parsedTitleColor = _hexStringToInt(color); int parsedTitleColor = _hexStringToInt(color);
int parsedBgColor = _hexStringToInt(bgColor); int parsedBgColor = _hexStringToInt(bgColor);
......
...@@ -91,4 +91,5 @@ class Constant { ...@@ -91,4 +91,5 @@ class Constant {
/// 测试阶段使用 /// 测试阶段使用
static const bool needIM = false; static const bool needIM = false;
static const bool needUpgrade = false;
} }
...@@ -20,6 +20,7 @@ import 'package:appframe/data/repositories/message/open_document_handler.dart'; ...@@ -20,6 +20,7 @@ import 'package:appframe/data/repositories/message/open_document_handler.dart';
import 'package:appframe/data/repositories/message/open_link_handler.dart'; import 'package:appframe/data/repositories/message/open_link_handler.dart';
import 'package:appframe/data/repositories/message/open_weapp_handler.dart'; import 'package:appframe/data/repositories/message/open_weapp_handler.dart';
import 'package:appframe/data/repositories/message/orientation_handler.dart'; import 'package:appframe/data/repositories/message/orientation_handler.dart';
import 'package:appframe/data/repositories/message/role_info_handler.dart';
import 'package:appframe/data/repositories/message/save_file_to_disk_handler.dart'; import 'package:appframe/data/repositories/message/save_file_to_disk_handler.dart';
import 'package:appframe/data/repositories/message/save_to_album_handler.dart'; import 'package:appframe/data/repositories/message/save_to_album_handler.dart';
import 'package:appframe/data/repositories/message/scan_code_handler.dart'; import 'package:appframe/data/repositories/message/scan_code_handler.dart';
...@@ -184,6 +185,9 @@ Future<void> setupLocator() async { ...@@ -184,6 +185,9 @@ Future<void> setupLocator() async {
/// 登录 /// 登录
getIt.registerLazySingleton<MessageHandler>(() => GoLoginHandler(), instanceName: 'goLogin'); getIt.registerLazySingleton<MessageHandler>(() => GoLoginHandler(), instanceName: 'goLogin');
/// 设置用户角色信息
getIt.registerLazySingleton<MessageHandler>(() => RoleInfoHandler(), instanceName: 'setRoleInfo');
/// service /// service
/// ///
/// local server /// local server
......
import 'package:appframe/config/locator.dart';
import 'package:appframe/services/dispatcher.dart';
import 'package:shared_preferences/shared_preferences.dart';
class RoleInfoHandler extends MessageHandler {
@override
Future<bool> handleMessage(params) async {
if (params is! Map<String, dynamic>) {
throw Exception('参数错误');
}
final String userId = params['userId'] as String;
final String classCode = params['classCode'] as String;
final int userType = params['userType'] as int;
final String stuId = params['stuId'] as String ?? '';
var sharedPreferences = getIt.get<SharedPreferences>();
sharedPreferences.setString('auth_userCode', userId);
sharedPreferences.setString('auth_classCode', classCode);
sharedPreferences.setInt('auth_userType', userType);
sharedPreferences.setString('auth_stuId', stuId);
return true;
}
}
...@@ -8,6 +8,7 @@ import 'package:tencent_cloud_chat_push/tencent_cloud_chat_push.dart'; ...@@ -8,6 +8,7 @@ import 'package:tencent_cloud_chat_push/tencent_cloud_chat_push.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimAdvancedMsgListener.dart'; import 'package:tencent_cloud_chat_sdk/enum/V2TimAdvancedMsgListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimSDKListener.dart'; import 'package:tencent_cloud_chat_sdk/enum/V2TimSDKListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/log_level_enum.dart'; 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/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_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
...@@ -74,9 +75,16 @@ class ImService { ...@@ -74,9 +75,16 @@ class ImService {
onRecvNewMessage: (V2TimMessage message) async { onRecvNewMessage: (V2TimMessage message) async {
// 处理文本消息 // 处理文本消息
if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT) { if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT) {
message.textElem?.text; // message.textElem?.text;
print("收到IM消息-------- ${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}");
// 目前只会有文本消息,所以其他消息类型暂不处理,直接return
return;
} }
// 使用自定义消息 // 使用自定义消息
if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_CUSTOM) { if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_CUSTOM) {
...@@ -214,10 +222,13 @@ class ImService { ...@@ -214,10 +222,13 @@ class ImService {
/// 登录 IM /// 登录 IM
/// ///
Future<bool> login(String userID) async { Future<bool> login(String userID) async {
/*var userSig = GenerateTestUserSig(sdkappid: Constant.imSdkAppId, key: Constant.imAppSecure).genSig( // 登录前先判断登录状态
identifier: userID, var loginStatus = await TencentImSDKPlugin.v2TIMManager.getLoginStatus();
expire: 86400 * 30, print('IM 登录状态:${loginStatus.code}');
);*/ if (loginStatus.code == LoginStatus.V2TIM_STATUS_LOGINED) {
// 已经登录,不需要再次登录
return true;
}
final apiService = getIt.get<ApiService>(instanceName: "appApiService"); final apiService = getIt.get<ApiService>(instanceName: "appApiService");
var response = await apiService.get('/api/v1/im/sign', queryParameters: {'userID': userID}); var response = await apiService.get('/api/v1/im/sign', queryParameters: {'userID': userID});
...@@ -227,6 +238,10 @@ class ImService { ...@@ -227,6 +238,10 @@ class ImService {
var userSig = response.data['userSig']; var userSig = response.data['userSig'];
V2TimCallback res = await TencentImSDKPlugin.v2TIMManager.login(userID: userID, userSig: userSig); V2TimCallback res = await TencentImSDKPlugin.v2TIMManager.login(userID: userID, userSig: userSig);
loginStatus = await TencentImSDKPlugin.v2TIMManager.getLoginStatus();
print('IM 登录状态2:${loginStatus.code}');
if (res.code == 0) { if (res.code == 0) {
print("IM 登录成功--------"); print("IM 登录成功--------");
// 添加消息的事件监听器 // 添加消息的事件监听器
......
...@@ -69,7 +69,7 @@ class AccountPage extends StatelessWidget { ...@@ -69,7 +69,7 @@ class AccountPage extends StatelessWidget {
color: Colors.grey, color: Colors.grey,
), ),
), ),
trailing: Icon(Icons.arrow_forward_ios), trailing: Icon(Icons.arrow_forward_ios, size: 14),
onTap: () { onTap: () {
context.read<AccountCubit>().goBind(); context.read<AccountCubit>().goBind();
}, },
......
...@@ -42,7 +42,7 @@ class AccountPhonePage extends StatelessWidget { ...@@ -42,7 +42,7 @@ class AccountPhonePage extends StatelessWidget {
]), ]),
) )
: Padding( : Padding(
padding: EdgeInsets.all(20), padding: EdgeInsets.all(60),
child: Column( child: Column(
children: [ children: [
SizedBox(height: 120), SizedBox(height: 120),
......
import 'package:appframe/bloc/web_cubit.dart'; import 'package:appframe/bloc/web_cubit.dart';
import 'package:appframe/config/constant.dart'; import 'package:appframe/config/constant.dart';
import 'package:appframe/config/evn_config.dart';
import 'package:appframe/config/locator.dart'; import 'package:appframe/config/locator.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';
...@@ -47,136 +48,8 @@ class WebPage extends StatelessWidget { ...@@ -47,136 +48,8 @@ class WebPage extends StatelessWidget {
ctx.read<WebCubit>().handleBack(); ctx.read<WebCubit>().handleBack();
}, },
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: _buildAppBar(ctx, state),
title: Text(state.title, style: TextStyle(color: Color(state.titleColor), fontSize: 18)), endDrawer: _buildDrawer(ctx, state),
centerTitle: true,
automaticallyImplyLeading: false,
backgroundColor: Color(state.bgColor),
actionsIconTheme: IconThemeData(color: Colors.white),
leading: state.opIcon == 'back'
? IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
ctx.read<WebCubit>().handleBack();
},
)
: (state.opIcon == 'home'
? IconButton(
icon: const Icon(Icons.home, color: Colors.white),
onPressed: () {
ctx.read<WebCubit>().handleHome();
},
)
: null),
),
endDrawer: Drawer(
width: MediaQuery.of(ctx).size.width * 0.8,
child: Column(children: [
DrawerHeader(
decoration: BoxDecoration(
color: Color(0xFF7691FA),
),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'设置',
style: TextStyle(
// color: Theme.of(ctx).colorScheme.onPrimary,
fontSize: 24,
color: Colors.white,
),
),
),
),
Expanded(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
/*ListTile(
leading: const Icon(Icons.chat_bubble_outline),
title: const Text('消息测试'),
onTap: () {
Navigator.pop(ctx);
ctx.read<WebCubit>().goIm();
},
),
ListTile(
leading: const Icon(Icons.accessibility_new),
title: const Text('身份认证'),
onTap: () {
Navigator.pop(ctx);
ctx.read<WebCubit>().goAuth();
},
),
ListTile(
leading: const Icon(Icons.app_blocking_sharp),
title: const Text('打开小程序'),
onTap: () {
Navigator.pop(ctx);
ctx.read<WebCubit>().goMiniProgram();
},
),*/
ListTile(
leading: const Icon(Icons.lock),
title: const Text('账号与安全'),
onTap: () {
Navigator.pop(ctx);
ctx.read<WebCubit>().goAccount();
},
),
/*ListTile(
leading: const Icon(Icons.refresh),
title: const Text('刷新'),
onTap: () {
Navigator.pop(ctx);
// ctx.read<WebCubit>().refresh();
ctx.read<WebCubit>().handleRefreshPage();
},
),*/
ListTile(
leading: const Icon(Icons.cleaning_services),
title: const Text('清理缓存'),
onTap: () {
Navigator.pop(ctx);
_showClearCacheDialog(ctx);
},
),
ListTile(
leading: const Icon(Icons.logout),
title: const Text('退出登录'),
onTap: () {
Navigator.pop(ctx);
ctx.read<WebCubit>().logout();
},
),
],
),
),
),
const Divider(),
Container(
width: double.infinity,
padding: const EdgeInsets.all(16.0),
child: Center(
child: Column(
children: [
Text(
'Version ${Constant.appVersion}-${state.h5Version}',
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
SizedBox(height: 8),
Text(
'Copyright © 中山班小二科技有限公司',
),
],
),
),
),
])),
body: Stack( body: Stack(
children: [ children: [
state.loaded state.loaded
...@@ -262,6 +135,206 @@ class WebPage extends StatelessWidget { ...@@ -262,6 +135,206 @@ class WebPage extends StatelessWidget {
); );
} }
AppBar _buildAppBar(BuildContext ctx, WebState state) {
return AppBar(
title: Text(state.title, style: TextStyle(color: Color(state.titleColor), fontSize: 18)),
centerTitle: true,
automaticallyImplyLeading: false,
backgroundColor: Color(state.bgColor),
actionsIconTheme: IconThemeData(color: Colors.white),
leading: state.opIcon == 'back'
? IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
ctx.read<WebCubit>().handleBack();
},
)
: (state.opIcon == 'home'
? IconButton(
icon: const Icon(Icons.home, color: Colors.white),
onPressed: () {
ctx.read<WebCubit>().handleHome();
},
)
: null),
);
}
Drawer _buildDrawer(BuildContext ctx, WebState state) {
return Drawer(
width: MediaQuery.of(ctx).size.width * 0.8,
child: Column(children: [
DrawerHeader(
decoration: BoxDecoration(
color: Color(0xFF7691FA),
),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'设置',
style: TextStyle(
// color: Theme.of(ctx).colorScheme.onPrimary,
fontSize: 24,
color: Colors.white,
),
),
),
),
Expanded(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 2), // 减小垂直间距
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
child: Column(
children: [
ListTile(
leading: const Icon(Icons.lock, size: 20),
// 减小图标大小
title: const Text('账号与安全', style: TextStyle(fontSize: 14)),
// 设置字体大小
onTap: () {
Navigator.pop(ctx);
ctx.read<WebCubit>().goAccount();
},
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
trailing: Icon(Icons.arrow_forward_ios, size: 14),
// 调整内边距
dense: true,
// 使用紧凑布局
visualDensity: VisualDensity.compact, // 视觉密度设为紧凑
),
],
),
),
SizedBox(height: 8),
Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 2), // 减小垂直间距
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
child: Column(
children: [
ListTile(
leading: const Icon(Icons.book_outlined, size: 20),
// 减小图标大小
title: const Text('用户协议', style: TextStyle(fontSize: 14)),
// 设置字体大小
onTap: () {
Navigator.pop(ctx);
},
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
trailing: Icon(Icons.arrow_forward_ios, size: 14),
// 调整内边距
dense: true,
// 使用紧凑布局
visualDensity: VisualDensity.compact, // 视觉密度设为紧凑
),
],
),
),
SizedBox(height: 8),
Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
child: Column(
children: [
ListTile(
leading: const Icon(Icons.cleaning_services, size: 20),
title: const Text('清理缓存', style: TextStyle(fontSize: 14)),
onTap: () {
Navigator.pop(ctx);
_showClearCacheDialog(ctx);
},
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
dense: true,
visualDensity: VisualDensity.compact,
),
ListTile(
leading: const Icon(Icons.logout, size: 20),
title: const Text('退出登录', style: TextStyle(fontSize: 14)),
onTap: () {
Navigator.pop(ctx);
ctx.read<WebCubit>().logout();
},
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
dense: true,
visualDensity: VisualDensity.compact,
),
],
),
),
SizedBox(height: 8),
Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 2), // 减小垂直间距
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
child: Column(
children: [
ListTile(
leading: const Icon(Icons.timeline, size: 20),
// 减小图标大小
title: const Text('切换日志模式', style: TextStyle(fontSize: 14)),
// 设置字体大小
onTap: () {
Navigator.pop(ctx);
ctx.read<WebCubit>().handleToggleDebug();
},
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
// trailing: Icon(Icons.arrow_forward_ios, size: 14),
// 调整内边距
dense: true,
// 使用紧凑布局
visualDensity: VisualDensity.compact, // 视觉密度设为紧凑
),
],
),
),
],
),
),
),
const Divider(),
Container(
width: double.infinity,
// padding: const EdgeInsets.all(16.0),
child: Center(
child: Column(
children: [
Text(
EnvConfig.isDev() ? '开发版' : '正式版',
style: TextStyle(
color: Colors.grey,
fontSize: 14,
),
),
SizedBox(height: 4),
Text(
'Version ${Constant.appVersion}-${state.h5Version}',
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
SizedBox(height: 8),
Text(
'Copyright © 中山班小二科技有限公司',
),
SizedBox(height: 8),
],
),
),
),
]));
}
void _showClearCacheDialog(BuildContext ctx) { void _showClearCacheDialog(BuildContext ctx) {
showDialog( showDialog(
context: ctx, context: ctx,
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!