Commit b489b6e0 by tanghuan

dev

1 parent e732a20e
......@@ -204,7 +204,7 @@ class WebCubit extends Cubit<WebState> {
// 版本不一致则需要升级
// 需要强制升级时,一直等待下载完成
// 不需要强制升级时,异步下载,下载完后弹框提示用户进行确认操作
if (curVersion != configVersion) {
if (Constant.needUpgrade && curVersion != configVersion) {
if (force == "1") {
// 一直等待升级完成
// 遮罩界面
......@@ -456,6 +456,21 @@ class WebCubit extends Cubit<WebState> {
_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) {
int parsedTitleColor = _hexStringToInt(color);
int parsedBgColor = _hexStringToInt(bgColor);
......
......@@ -91,4 +91,5 @@ class Constant {
/// 测试阶段使用
static const bool needIM = false;
static const bool needUpgrade = false;
}
......@@ -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_weapp_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_to_album_handler.dart';
import 'package:appframe/data/repositories/message/scan_code_handler.dart';
......@@ -184,6 +185,9 @@ Future<void> setupLocator() async {
/// 登录
getIt.registerLazySingleton<MessageHandler>(() => GoLoginHandler(), instanceName: 'goLogin');
/// 设置用户角色信息
getIt.registerLazySingleton<MessageHandler>(() => RoleInfoHandler(), instanceName: 'setRoleInfo');
/// service
///
/// 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';
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/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_message.dart';
......@@ -74,9 +75,16 @@ class ImService {
onRecvNewMessage: (V2TimMessage message) async {
// 处理文本消息
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) {
......@@ -214,10 +222,13 @@ class ImService {
/// 登录 IM
///
Future<bool> login(String userID) async {
/*var userSig = GenerateTestUserSig(sdkappid: Constant.imSdkAppId, key: Constant.imAppSecure).genSig(
identifier: userID,
expire: 86400 * 30,
);*/
// 登录前先判断登录状态
var loginStatus = await TencentImSDKPlugin.v2TIMManager.getLoginStatus();
print('IM 登录状态:${loginStatus.code}');
if (loginStatus.code == LoginStatus.V2TIM_STATUS_LOGINED) {
// 已经登录,不需要再次登录
return true;
}
final apiService = getIt.get<ApiService>(instanceName: "appApiService");
var response = await apiService.get('/api/v1/im/sign', queryParameters: {'userID': userID});
......@@ -227,6 +238,10 @@ class ImService {
var userSig = response.data['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) {
print("IM 登录成功--------");
// 添加消息的事件监听器
......
......@@ -69,7 +69,7 @@ class AccountPage extends StatelessWidget {
color: Colors.grey,
),
),
trailing: Icon(Icons.arrow_forward_ios),
trailing: Icon(Icons.arrow_forward_ios, size: 14),
onTap: () {
context.read<AccountCubit>().goBind();
},
......
......@@ -42,7 +42,7 @@ class AccountPhonePage extends StatelessWidget {
]),
)
: Padding(
padding: EdgeInsets.all(20),
padding: EdgeInsets.all(60),
child: Column(
children: [
SizedBox(height: 120),
......
import 'package:appframe/bloc/web_cubit.dart';
import 'package:appframe/config/constant.dart';
import 'package:appframe/config/evn_config.dart';
import 'package:appframe/config/locator.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
......@@ -47,7 +48,95 @@ class WebPage extends StatelessWidget {
ctx.read<WebCubit>().handleBack();
},
child: Scaffold(
appBar: AppBar(
appBar: _buildAppBar(ctx, state),
endDrawer: _buildDrawer(ctx, state),
body: Stack(
children: [
state.loaded
? SizedBox(
height: MediaQuery.of(ctx).size.height - 60, // 减去100像素留空
child: WebViewWidget(controller: ctx.read<WebCubit>().controller),
)
: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
SizedBox(height: 16),
Text('加载中...'),
],
),
),
// 添加升级遮罩层
if (state.isUpgrading)
Container(
color: Colors.black54,
child: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
SizedBox(height: 16),
Text('资源更新中...', style: TextStyle(color: Colors.white)),
],
),
),
),
],
),
bottomNavigationBar: state.showBottomNavBar
? BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: state.selectedIndex,
selectedItemColor: Color(0xFF7691fa),
unselectedItemColor: Color(0xFF969799),
onTap: (index) {
// 更新选中索引
ctx.read<WebCubit>().updateSelectedIndex(index);
// 根据 index 执行相应的操作
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home, size: 32),
label: '我的班级',
),
BottomNavigationBarItem(
icon: Icon(Icons.contact_page, size: 32),
label: '通讯录',
),
BottomNavigationBarItem(
icon: Icon(Icons.find_in_page, size: 32),
label: '发现',
),
BottomNavigationBarItem(
icon: Icon(Icons.person, size: 32),
label: '我的',
),
],
)
: null,
),
);
},
listener: (context, state) {
if (state.suggestUpgrade) {
context.read<WebCubit>().suggestUpgrade(context);
} else if (state.orientationCmdFlag) {
context.read<WebCubit>().getOrientation(context);
} else if (state.windowInfoCmdFlag) {
context.read<WebCubit>().getWindowInfo(context);
} else if (state.chooseImageCmdFlag) {
context.read<WebCubit>().chooseImage(context);
} else if (state.chooseVideoCmdFlag) {
context.read<WebCubit>().chooseVideo(context);
}
},
),
);
}
AppBar _buildAppBar(BuildContext ctx, WebState state) {
return AppBar(
title: Text(state.title, style: TextStyle(color: Color(state.titleColor), fontSize: 18)),
centerTitle: true,
automaticallyImplyLeading: false,
......@@ -68,8 +157,11 @@ class WebPage extends StatelessWidget {
},
)
: null),
),
endDrawer: Drawer(
);
}
Drawer _buildDrawer(BuildContext ctx, WebState state) {
return Drawer(
width: MediaQuery.of(ctx).size.width * 0.8,
child: Column(children: [
DrawerHeader(
......@@ -93,62 +185,117 @@ class WebPage extends StatelessWidget {
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();
},
Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 2), // 减小垂直间距
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
child: Column(
children: [
ListTile(
leading: const Icon(Icons.accessibility_new),
title: const Text('身份认证'),
leading: const Icon(Icons.lock, size: 20),
// 减小图标大小
title: const Text('账号与安全', style: TextStyle(fontSize: 14)),
// 设置字体大小
onTap: () {
Navigator.pop(ctx);
ctx.read<WebCubit>().goAuth();
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.app_blocking_sharp),
title: const Text('打开小程序'),
leading: const Icon(Icons.book_outlined, size: 20),
// 减小图标大小
title: const Text('用户协议', style: TextStyle(fontSize: 14)),
// 设置字体大小
onTap: () {
Navigator.pop(ctx);
ctx.read<WebCubit>().goMiniProgram();
},
),*/
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.lock),
title: const Text('账号与安全'),
leading: const Icon(Icons.cleaning_services, size: 20),
title: const Text('清理缓存', style: TextStyle(fontSize: 14)),
onTap: () {
Navigator.pop(ctx);
ctx.read<WebCubit>().goAccount();
_showClearCacheDialog(ctx);
},
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
dense: true,
visualDensity: VisualDensity.compact,
),
/*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('清理缓存'),
leading: const Icon(Icons.logout, size: 20),
title: const Text('退出登录', style: TextStyle(fontSize: 14)),
onTap: () {
Navigator.pop(ctx);
_showClearCacheDialog(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.logout),
title: const Text('退出登录'),
leading: const Icon(Icons.timeline, size: 20),
// 减小图标大小
title: const Text('切换日志模式', style: TextStyle(fontSize: 14)),
// 设置字体大小
onTap: () {
Navigator.pop(ctx);
ctx.read<WebCubit>().logout();
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, // 视觉密度设为紧凑
),
],
),
),
],
),
......@@ -157,11 +304,19 @@ class WebPage extends StatelessWidget {
const Divider(),
Container(
width: double.infinity,
padding: const EdgeInsets.all(16.0),
// 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,
......@@ -172,94 +327,12 @@ class WebPage extends StatelessWidget {
Text(
'Copyright © 中山班小二科技有限公司',
),
SizedBox(height: 8),
],
),
),
),
])),
body: Stack(
children: [
state.loaded
? SizedBox(
height: MediaQuery.of(ctx).size.height - 60, // 减去100像素留空
child: WebViewWidget(controller: ctx.read<WebCubit>().controller),
)
: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
SizedBox(height: 16),
Text('加载中...'),
],
),
),
// 添加升级遮罩层
if (state.isUpgrading)
Container(
color: Colors.black54,
child: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
SizedBox(height: 16),
Text('资源更新中...', style: TextStyle(color: Colors.white)),
],
),
),
),
],
),
bottomNavigationBar: state.showBottomNavBar
? BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: state.selectedIndex,
selectedItemColor: Color(0xFF7691fa),
unselectedItemColor: Color(0xFF969799),
onTap: (index) {
// 更新选中索引
ctx.read<WebCubit>().updateSelectedIndex(index);
// 根据 index 执行相应的操作
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home, size: 32),
label: '我的班级',
),
BottomNavigationBarItem(
icon: Icon(Icons.contact_page, size: 32),
label: '通讯录',
),
BottomNavigationBarItem(
icon: Icon(Icons.find_in_page, size: 32),
label: '发现',
),
BottomNavigationBarItem(
icon: Icon(Icons.person, size: 32),
label: '我的',
),
],
)
: null,
),
);
},
listener: (context, state) {
if (state.suggestUpgrade) {
context.read<WebCubit>().suggestUpgrade(context);
} else if (state.orientationCmdFlag) {
context.read<WebCubit>().getOrientation(context);
} else if (state.windowInfoCmdFlag) {
context.read<WebCubit>().getWindowInfo(context);
} else if (state.chooseImageCmdFlag) {
context.read<WebCubit>().chooseImage(context);
} else if (state.chooseVideoCmdFlag) {
context.read<WebCubit>().chooseVideo(context);
}
},
),
);
]));
}
void _showClearCacheDialog(BuildContext ctx) {
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!