23 changed files with 658 additions and 908 deletions
Split View
Diff Options
-
1android/app/src/main/AndroidManifest.xml
-
13lib/components/page_appbar.dart
-
13lib/controller/mine/login_controller.dart
-
5lib/controller/mine/mine_controller.dart
-
2lib/controller/mine/user_controller.dart
-
90lib/controller/mine/user_info_controller.dart
-
103lib/controller/setting/notification_controller.dart
-
230lib/controller/setting/setting_controller.dart
-
4lib/main.dart
-
12lib/model/mine/user_data.dart
-
1lib/network/network_config.dart
-
2lib/pages/home/report_page.dart
-
6lib/pages/mine/auth_center_page.dart
-
174lib/pages/mine/login_controller.dart
-
5lib/pages/mine/mine_page.dart
-
6lib/pages/mine/phone_page.dart
-
6lib/pages/mine/real_name_page.dart
-
410lib/pages/mine/setting_page.dart
-
111lib/pages/mine/user_info_page.dart
-
0lib/pages/setting/blacklist_page.dart
-
114lib/pages/setting/notice_page.dart
-
256lib/pages/setting/setting_page.dart
-
2pubspec.yaml
@ -0,0 +1,103 @@ |
|||
// controllers/notification_controller.dart |
|||
import 'package:get/get.dart'; |
|||
import 'package:permission_handler/permission_handler.dart'; |
|||
import 'package:app_settings/app_settings.dart'; |
|||
|
|||
class NotificationController extends GetxController { |
|||
// 权限状态 |
|||
final Rx<PermissionStatus> notificationStatus = PermissionStatus.denied.obs; |
|||
final RxBool checking = false.obs; |
|||
|
|||
// 初始化时检查权限 |
|||
@override |
|||
void onInit() { |
|||
super.onInit(); |
|||
// 延迟检查,确保服务已初始化 |
|||
checkPermission(); |
|||
} |
|||
|
|||
// 检查通知权限状态 |
|||
Future<PermissionStatus> checkPermission() async { |
|||
checking.value = true; |
|||
try { |
|||
// 检查通知权限 |
|||
final status = await Permission.notification.status; |
|||
notificationStatus.value = status; |
|||
|
|||
print('通知权限状态: $status'); |
|||
return status; |
|||
} catch (e) { |
|||
print('检查通知权限失败: $e'); |
|||
return PermissionStatus.denied; |
|||
} finally { |
|||
checking.value = false; |
|||
} |
|||
} |
|||
|
|||
// 请求通知权限 |
|||
Future<PermissionStatus> requestNotificationPermission() async { |
|||
try { |
|||
final status = await Permission.notification.request(); |
|||
notificationStatus.value = status; |
|||
|
|||
print('请求通知权限结果: $status'); |
|||
return status; |
|||
} catch (e) { |
|||
print('请求通知权限失败: $e'); |
|||
return PermissionStatus.denied; |
|||
} |
|||
} |
|||
|
|||
// 打开应用设置页面(让用户手动开启权限) |
|||
Future<void> openSettings() async { |
|||
try { |
|||
AppSettings.openAppSettings( |
|||
type: AppSettingsType.notification, |
|||
); |
|||
} catch (e) { |
|||
print('打开设置页面失败: $e'); |
|||
} |
|||
} |
|||
|
|||
// 检查是否有通知权限的便捷方法 |
|||
// Future<bool> hasNotificationPermission() async { |
|||
// final status = await checkNotificationPermission(); |
|||
// return status.isGranted || status.isLimited; |
|||
// } |
|||
|
|||
// 获取权限状态描述 |
|||
String getPermissionStatusText() { |
|||
switch (notificationStatus.value) { |
|||
case PermissionStatus.granted: |
|||
return '已开启'; |
|||
case PermissionStatus.denied: |
|||
return '已拒绝'; |
|||
case PermissionStatus.restricted: |
|||
return '受限制'; |
|||
case PermissionStatus.limited: |
|||
return '部分授权'; |
|||
case PermissionStatus.permanentlyDenied: |
|||
return '永久拒绝'; |
|||
case PermissionStatus.provisional: |
|||
return '临时授权'; |
|||
} |
|||
} |
|||
|
|||
// 获取权限状态颜色 |
|||
String getPermissionStatusColor() { |
|||
switch (notificationStatus.value) { |
|||
case PermissionStatus.granted: |
|||
return '绿色'; |
|||
case PermissionStatus.denied: |
|||
return '橙色'; |
|||
case PermissionStatus.restricted: |
|||
return '红色'; |
|||
case PermissionStatus.limited: |
|||
return '蓝色'; |
|||
case PermissionStatus.permanentlyDenied: |
|||
return '红色'; |
|||
case PermissionStatus.provisional: |
|||
return '黄色'; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,230 @@ |
|||
import 'dart:async'; |
|||
import 'package:dating_touchme_app/controller/global.dart'; |
|||
import 'package:dating_touchme_app/extension/ex_widget.dart'; |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
|||
import 'package:get/get.dart'; |
|||
import 'package:get_storage/get_storage.dart'; |
|||
import 'package:tdesign_flutter/tdesign_flutter.dart'; |
|||
import '../../generated/assets.dart'; |
|||
import 'package:package_info_plus/package_info_plus.dart'; |
|||
|
|||
class SettingController extends GetxController { |
|||
|
|||
final storage = GetStorage(); |
|||
final appName = ''.obs; |
|||
final packageName = ''.obs; |
|||
final version = ''.obs; |
|||
final buildNumber = ''.obs; |
|||
|
|||
@override |
|||
Future<void> onInit() async { |
|||
super.onInit(); |
|||
// 从全局依赖中获取UserApi |
|||
await getAppInfo(); |
|||
} |
|||
// 获取验证码 |
|||
Future<void> getAppInfo() async { |
|||
try { |
|||
PackageInfo packageInfo = await PackageInfo.fromPlatform(); |
|||
appName.value = packageInfo.appName; |
|||
packageName.value = packageInfo.packageName; |
|||
version.value = packageInfo.version; |
|||
buildNumber.value = packageInfo.buildNumber; |
|||
} catch (e) { |
|||
print('获取应用信息失败: $e'); |
|||
} |
|||
} |
|||
|
|||
Future<void> checkVersion() async { |
|||
try { |
|||
_showUpdateDialog(); |
|||
} catch (e) { |
|||
print('检测版本跟新失败: $e'); |
|||
} |
|||
} |
|||
|
|||
void logout(){ |
|||
storage.erase(); |
|||
GlobalData().logout(); |
|||
} |
|||
|
|||
// 弹出版本升级的dialog |
|||
void _showUpdateDialog(){ |
|||
Navigator.of(Get.context!).push(TDSlidePopupRoute( |
|||
modalBarrierColor: TDTheme.of(Get.context!).fontGyColor2, |
|||
slideTransitionFrom: SlideTransitionFrom.center, |
|||
builder: (context) { |
|||
return Material( |
|||
color: Colors.transparent, |
|||
child: Container( |
|||
color: Colors.transparent, |
|||
width: 299.w, |
|||
padding: EdgeInsets.only(top: 56.w), |
|||
child: Stack( |
|||
clipBehavior: Clip.none, |
|||
children: [ |
|||
Container( |
|||
width: 299.w, |
|||
padding: EdgeInsets.only( |
|||
top: 147.w, |
|||
left: 30.w, |
|||
right: 30.w, |
|||
bottom: 25.w |
|||
), |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.all(Radius.circular(18.w)), |
|||
color: Colors.white |
|||
), |
|||
child: Column( |
|||
crossAxisAlignment: CrossAxisAlignment.start, |
|||
mainAxisSize: MainAxisSize.min, |
|||
children: [ |
|||
Text( |
|||
"体验全新升级v1.2.0", |
|||
style: TextStyle( |
|||
fontSize: 16.w, |
|||
fontWeight: FontWeight.w500 |
|||
), |
|||
), |
|||
SizedBox(height: 14.w,), |
|||
Row( |
|||
crossAxisAlignment: CrossAxisAlignment.start, |
|||
children: [ |
|||
Container( |
|||
width: 2.w, |
|||
height: 5.w, |
|||
margin: EdgeInsets.only( |
|||
right: 10.w, |
|||
top: 6.w |
|||
), |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.all(Radius.circular(2.w)), |
|||
color: const Color.fromRGBO(51, 51, 51, 1) |
|||
), |
|||
), |
|||
SizedBox( |
|||
width: 204.w, |
|||
child: Text( |
|||
"首页风格改版,更全面的内容,恍然一新的视觉用户体验。", |
|||
style: TextStyle( |
|||
fontSize: 12.w, |
|||
), |
|||
), |
|||
) |
|||
], |
|||
), |
|||
SizedBox(height: 8.w,), |
|||
Row( |
|||
crossAxisAlignment: CrossAxisAlignment.start, |
|||
children: [ |
|||
Container( |
|||
width: 2.w, |
|||
height: 5.w, |
|||
margin: EdgeInsets.only( |
|||
right: 10.w, |
|||
top: 6.w |
|||
), |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.all(Radius.circular(2.w)), |
|||
color: const Color.fromRGBO(51, 51, 51, 1) |
|||
), |
|||
), |
|||
SizedBox( |
|||
width: 204.w, |
|||
child: Text( |
|||
"优化了动画细节,让产品更流畅。", |
|||
style: TextStyle( |
|||
fontSize: 12.w, |
|||
), |
|||
), |
|||
) |
|||
], |
|||
), |
|||
SizedBox(height: 32.w,), |
|||
Row( |
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|||
children: [ |
|||
Container( |
|||
width: 113.w, |
|||
height: 40.w, |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.all(Radius.circular(9.w)), |
|||
color: const Color.fromRGBO(245, 245, 245, 1) |
|||
), |
|||
child: Center( |
|||
child: Text( |
|||
"暂不更新", |
|||
style: TextStyle( |
|||
fontSize: 15.w, |
|||
color: const Color.fromRGBO(144, 144, 144, 1) |
|||
), |
|||
), |
|||
), |
|||
).onTap((){ |
|||
Navigator.of(context).pop(); |
|||
}), |
|||
Container( |
|||
width: 113.w, |
|||
height: 40.w, |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.all(Radius.circular(9.w)), |
|||
color: const Color.fromRGBO(245, 245, 245, 1), |
|||
gradient: const LinearGradient( |
|||
begin: Alignment.centerLeft, |
|||
end: Alignment.centerRight, // 对应 CSS 90deg |
|||
colors: [ |
|||
Color.fromRGBO(131, 89, 255, 1), // rgba(131, 89, 255, 1) |
|||
Color.fromRGBO(61, 138, 224, 1), // rgba(61, 138, 224, 1) |
|||
], |
|||
), |
|||
), |
|||
child: Center( |
|||
child: Text( |
|||
"立即升级", |
|||
style: TextStyle( |
|||
fontSize: 15.w, |
|||
fontWeight: FontWeight.w500, |
|||
color: Colors.white |
|||
), |
|||
), |
|||
), |
|||
), |
|||
], |
|||
) |
|||
], |
|||
), |
|||
), |
|||
Positioned( |
|||
left: 0, |
|||
top: -56.w, |
|||
child: Image.asset( |
|||
Assets.imagesUpdataBg, |
|||
width: 299.w, |
|||
), |
|||
), |
|||
Positioned( |
|||
left: 11.w, |
|||
top: -14.w, |
|||
child: Image.asset( |
|||
Assets.imagesUpdataIcon, |
|||
width: 36.w, |
|||
), |
|||
), |
|||
Positioned( |
|||
left: 43.w, |
|||
top: 29.w, |
|||
child: Image.asset( |
|||
Assets.imagesUpdataFont, |
|||
width: 76.w, |
|||
), |
|||
) |
|||
], |
|||
), |
|||
), |
|||
); |
|||
})); |
|||
} |
|||
|
|||
} |
|||
|
|||
@ -1,174 +0,0 @@ |
|||
// import 'dart:async'; |
|||
// import 'package:dating_touchme_app/pages/main/main_page.dart'; |
|||
// import 'package:get/get.dart'; |
|||
// import 'package:get_storage/get_storage.dart'; |
|||
// import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; |
|||
// import 'package:dating_touchme_app/network/user_api.dart'; |
|||
// import 'package:dating_touchme_app/pages/mine/user_info_page.dart'; |
|||
// |
|||
// |
|||
// class LoginController extends GetxController { |
|||
// // 手机号输入 |
|||
// final phoneNumber = ''.obs; |
|||
// // 验证码输入 |
|||
// final verificationCode = ''.obs; |
|||
// // 是否正在发送验证码 |
|||
// final isSendingCode = false.obs; |
|||
// // 倒计时秒数 |
|||
// final countdownSeconds = 0.obs; |
|||
// // 是否正在登录中 |
|||
// final isLoggingIn = false.obs; |
|||
// |
|||
// // 从GetX依赖注入中获取UserApi实例 |
|||
// late UserApi _userApi; |
|||
// // GetStorage实例,用于存储token等信息 |
|||
// final storage = GetStorage(); |
|||
// |
|||
// @override |
|||
// void onInit() { |
|||
// super.onInit(); |
|||
// // 从全局依赖中获取UserApi |
|||
// _userApi = Get.find<UserApi>(); |
|||
// } |
|||
// |
|||
// // 获取验证码 |
|||
// Future<void> getVerificationCode() async { |
|||
// // 验证手机号格式 |
|||
// if (phoneNumber.value.isEmpty || phoneNumber.value.length != 11) { |
|||
// SmartDialog.showToast('请输入正确的手机号'); |
|||
// return; |
|||
// } |
|||
// |
|||
// isSendingCode.value = true; |
|||
// |
|||
// try { |
|||
// // 构建请求参数 |
|||
// final params = { |
|||
// 'purpose': 1, // 认证 |
|||
// 'verifiableAccount': phoneNumber.value, |
|||
// 'verifiableAccountType': 1, // 手机 |
|||
// }; |
|||
// |
|||
// // 调用UserApi中的验证码接口 |
|||
// final response = await _userApi.getVerificationCode(params); |
|||
// |
|||
// // 处理响应 |
|||
// if (response.data.isSuccess) { |
|||
// // 生产环境移除打印,可考虑使用正式的日志框架 |
|||
// // print('验证码发送成功'); |
|||
// // 开始倒计时 |
|||
// startCountdown(); |
|||
// } else { |
|||
// SmartDialog.showToast(response.data.message); |
|||
// } |
|||
// } catch (e) { |
|||
// SmartDialog.showToast('网络请求失败,请重试'); |
|||
// } finally { |
|||
// isSendingCode.value = false; |
|||
// } |
|||
// } |
|||
// |
|||
// // 开始倒计时 |
|||
// void startCountdown() { |
|||
// countdownSeconds.value = 60; |
|||
// Timer.periodic(const Duration(seconds: 1), (timer) { |
|||
// countdownSeconds.value--; |
|||
// if (countdownSeconds.value <= 0) { |
|||
// timer.cancel(); |
|||
// } |
|||
// }); |
|||
// } |
|||
// |
|||
// // 清除错误信息 - 由于使用SmartDialog,此方法不再需要 |
|||
// // void clearErrorMessage() {} |
|||
// |
|||
// |
|||
// // 登录方法 |
|||
// Future<void> login() async { |
|||
// // 验证输入 |
|||
// if (phoneNumber.value.isEmpty || phoneNumber.value.length != 11) { |
|||
// SmartDialog.showToast('请输入正确的手机号'); |
|||
// return; |
|||
// } |
|||
// |
|||
// if (verificationCode.value.isEmpty) { |
|||
// SmartDialog.showToast('请输入验证码'); |
|||
// return; |
|||
// } |
|||
// |
|||
// isLoggingIn.value = true; |
|||
// |
|||
// try { |
|||
// // 构建登录请求参数 |
|||
// final params = { |
|||
// 'account': phoneNumber.value, |
|||
// 'accountType': 2, // 手机号类型 |
|||
// 'captcha': verificationCode.value, |
|||
// }; |
|||
// |
|||
// // 调用登录接口 |
|||
// final response = await _userApi.login(params); |
|||
// |
|||
// // 处理响应 |
|||
// if (response.data.isSuccess) { |
|||
// // 保存token和用户信息 |
|||
// if (response.data.data != null) { |
|||
// final loginData = response.data.data!; |
|||
// await storage.write('token', loginData.token); |
|||
// await storage.write('userId', loginData.userId); |
|||
// // 保存用户信息 |
|||
// await storage.write('userInfo', loginData.toJson()); |
|||
// |
|||
// // 登录成功后获取用户基础信息 |
|||
// await _getBaseUserInfo(loginData.userId); |
|||
// } |
|||
// } else { |
|||
// SmartDialog.showToast(response.data.message); |
|||
// } |
|||
// } catch (e) { |
|||
// SmartDialog.showToast('网络请求失败,请检查网络连接'); |
|||
// } finally { |
|||
// isLoggingIn.value = false; |
|||
// } |
|||
// } |
|||
// |
|||
// // 获取用户基础信息 |
|||
// Future<void> _getBaseUserInfo(String userId) async { |
|||
// try { |
|||
// final response = await _userApi.getBaseUserInfo(userId); |
|||
// |
|||
// if (response.data.isSuccess && response.data.data != null) { |
|||
// // 成功获取基础信息后,调用获取婚姻信息详情接口 |
|||
// await _getMarriageInformationDetail(); |
|||
// } else { |
|||
// SmartDialog.showToast(response.data.message); |
|||
// } |
|||
// } catch (e) { |
|||
// // 获取用户信息失败不影响登录流程 |
|||
// SmartDialog.showToast('获取用户信息失败'); |
|||
// } |
|||
// } |
|||
// |
|||
// // 获取用户婚姻信息详情 |
|||
// Future<void> _getMarriageInformationDetail() async { |
|||
// try { |
|||
// final response = await _userApi.getMarriageInformationDetail(); |
|||
// if (response.data.isSuccess) { |
|||
// // 检查data是否为null或者是空对象 |
|||
// if(response.data.data == null){ |
|||
// //跳转到完善信息 |
|||
// SmartDialog.showToast('转到完善信息'); |
|||
// // 导航到完善信息页面 |
|||
// Get.offAll(() => UserInfoPage()); |
|||
// }else{ |
|||
// Get.offAll(MainPage()); |
|||
// } |
|||
// } else { |
|||
// // 获取婚姻信息失败不影响登录流程 |
|||
// } |
|||
// } catch (e) { |
|||
// // 获取婚姻信息失败不影响登录流程 |
|||
// print('获取婚姻信息异常: $e'); |
|||
// } |
|||
// } |
|||
// } |
|||
@ -1,410 +0,0 @@ |
|||
import 'package:dating_touchme_app/components/page_appbar.dart'; |
|||
import 'package:dating_touchme_app/extension/ex_widget.dart'; |
|||
import 'package:dating_touchme_app/generated/assets.dart'; |
|||
import 'package:dating_touchme_app/pages/mine/blacklist_page.dart'; |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
|||
import 'package:get/get.dart'; |
|||
import 'package:get/get_core/src/get_main.dart'; |
|||
import 'package:tdesign_flutter/tdesign_flutter.dart'; |
|||
|
|||
class SettingPage extends StatefulWidget { |
|||
const SettingPage({super.key}); |
|||
|
|||
@override |
|||
State<SettingPage> createState() => _SettingPageState(); |
|||
} |
|||
|
|||
class _SettingPageState extends State<SettingPage> { |
|||
|
|||
|
|||
bool blockUser = false; |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return Scaffold( |
|||
backgroundColor: const Color.fromRGBO(250, 250, 250, 1), |
|||
appBar: PageAppbar(title: "设置"), |
|||
body: SingleChildScrollView( |
|||
child: Container( |
|||
padding: EdgeInsets.symmetric( |
|||
vertical: 15.w, |
|||
horizontal: 10.w |
|||
), |
|||
child: Column( |
|||
children: [ |
|||
BlockItem( |
|||
children: [ |
|||
Item( |
|||
label: "后台播放", |
|||
child: TDSwitch( |
|||
isOn: blockUser, |
|||
trackOnColor: const Color.fromRGBO(117, 98, 249, 1), |
|||
onChanged: (bool e){ |
|||
print(e); |
|||
blockUser = e; |
|||
setState(() { |
|||
|
|||
}); |
|||
return e; |
|||
}, |
|||
), |
|||
), |
|||
LineItem(), |
|||
Item( |
|||
label: "语音/视频通话提示音", |
|||
child: TDSwitch( |
|||
isOn: blockUser, |
|||
trackOnColor: const Color.fromRGBO(117, 98, 249, 1), |
|||
onChanged: (bool e){ |
|||
print(e); |
|||
blockUser = e; |
|||
setState(() { |
|||
|
|||
}); |
|||
return e; |
|||
}, |
|||
), |
|||
), |
|||
], |
|||
), |
|||
BlockItem( |
|||
children: [ |
|||
Item( |
|||
label: "安全中心", |
|||
child: Icon( |
|||
Icons.keyboard_arrow_right, |
|||
size: 10.w, |
|||
color: const Color.fromRGBO(191, 191, 191, 1), |
|||
), |
|||
), |
|||
LineItem(), |
|||
Item( |
|||
label: "黑名单", |
|||
child: Icon( |
|||
Icons.keyboard_arrow_right, |
|||
size: 10.w, |
|||
color: const Color.fromRGBO(191, 191, 191, 1), |
|||
), |
|||
).onTap((){ |
|||
Get.to(() => BlacklistPage()); |
|||
}), |
|||
], |
|||
), |
|||
BlockItem( |
|||
children: [ |
|||
Item( |
|||
label: "隐私设置", |
|||
child: Icon( |
|||
Icons.keyboard_arrow_right, |
|||
size: 10.w, |
|||
color: const Color.fromRGBO(191, 191, 191, 1), |
|||
), |
|||
), |
|||
LineItem(), |
|||
Item( |
|||
label: "青少年模式", |
|||
child: Icon( |
|||
Icons.keyboard_arrow_right, |
|||
size: 10.w, |
|||
color: const Color.fromRGBO(191, 191, 191, 1), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
BlockItem( |
|||
children: [ |
|||
Item( |
|||
label: "系统权限管理", |
|||
child: Icon( |
|||
Icons.keyboard_arrow_right, |
|||
size: 10.w, |
|||
color: const Color.fromRGBO(191, 191, 191, 1), |
|||
), |
|||
), |
|||
LineItem(), |
|||
Item( |
|||
label: "消息通知", |
|||
child: Icon( |
|||
Icons.keyboard_arrow_right, |
|||
size: 10.w, |
|||
color: const Color.fromRGBO(191, 191, 191, 1), |
|||
), |
|||
), |
|||
LineItem(), |
|||
Item( |
|||
label: "检查更新", |
|||
child: Row( |
|||
children: [ |
|||
Text( |
|||
"版本号 1.0.000", |
|||
style: TextStyle( |
|||
fontSize: 13.w, |
|||
color: const Color.fromRGBO(117, 98, 249, 1) |
|||
), |
|||
), |
|||
SizedBox(width: 10.w,), |
|||
Icon( |
|||
Icons.keyboard_arrow_right, |
|||
size: 10.w, |
|||
color: const Color.fromRGBO(191, 191, 191, 1), |
|||
) |
|||
], |
|||
), |
|||
).onTap((){ |
|||
Navigator.of(context).push(TDSlidePopupRoute( |
|||
modalBarrierColor: TDTheme.of(context).fontGyColor2, |
|||
slideTransitionFrom: SlideTransitionFrom.center, |
|||
builder: (context) { |
|||
return Material( |
|||
color: Colors.transparent, |
|||
child: Container( |
|||
color: Colors.transparent, |
|||
width: 299.w, |
|||
padding: EdgeInsets.only( |
|||
top: 56.w |
|||
), |
|||
child: Stack( |
|||
clipBehavior: Clip.none, |
|||
children: [ |
|||
Container( |
|||
width: 299.w, |
|||
padding: EdgeInsets.only( |
|||
top: 147.w, |
|||
left: 30.w, |
|||
right: 30.w, |
|||
bottom: 25.w |
|||
), |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.all(Radius.circular(18.w)), |
|||
color: Colors.white |
|||
), |
|||
child: Column( |
|||
crossAxisAlignment: CrossAxisAlignment.start, |
|||
mainAxisSize: MainAxisSize.min, |
|||
children: [ |
|||
Text( |
|||
"体验全新升级v1.2.0", |
|||
style: TextStyle( |
|||
fontSize: 16.w, |
|||
fontWeight: FontWeight.w500 |
|||
), |
|||
), |
|||
SizedBox(height: 14.w,), |
|||
Row( |
|||
crossAxisAlignment: CrossAxisAlignment.start, |
|||
children: [ |
|||
Container( |
|||
width: 2.w, |
|||
height: 5.w, |
|||
margin: EdgeInsets.only( |
|||
right: 10.w, |
|||
top: 6.w |
|||
), |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.all(Radius.circular(2.w)), |
|||
color: const Color.fromRGBO(51, 51, 51, 1) |
|||
), |
|||
), |
|||
SizedBox( |
|||
width: 204.w, |
|||
child: Text( |
|||
"首页风格改版,更全面的内容,恍然一新的视觉用户体验。", |
|||
style: TextStyle( |
|||
fontSize: 12.w, |
|||
), |
|||
), |
|||
) |
|||
], |
|||
), |
|||
SizedBox(height: 8.w,), |
|||
Row( |
|||
crossAxisAlignment: CrossAxisAlignment.start, |
|||
children: [ |
|||
Container( |
|||
width: 2.w, |
|||
height: 5.w, |
|||
margin: EdgeInsets.only( |
|||
right: 10.w, |
|||
top: 6.w |
|||
), |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.all(Radius.circular(2.w)), |
|||
color: const Color.fromRGBO(51, 51, 51, 1) |
|||
), |
|||
), |
|||
SizedBox( |
|||
width: 204.w, |
|||
child: Text( |
|||
"优化了动画细节,让产品更流畅。", |
|||
style: TextStyle( |
|||
fontSize: 12.w, |
|||
), |
|||
), |
|||
) |
|||
], |
|||
), |
|||
SizedBox(height: 32.w,), |
|||
Row( |
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|||
children: [ |
|||
Container( |
|||
width: 113.w, |
|||
height: 40.w, |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.all(Radius.circular(9.w)), |
|||
color: const Color.fromRGBO(245, 245, 245, 1) |
|||
), |
|||
child: Center( |
|||
child: Text( |
|||
"暂不更新", |
|||
style: TextStyle( |
|||
fontSize: 15.w, |
|||
color: const Color.fromRGBO(144, 144, 144, 1) |
|||
), |
|||
), |
|||
), |
|||
), |
|||
Container( |
|||
width: 113.w, |
|||
height: 40.w, |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.all(Radius.circular(9.w)), |
|||
color: const Color.fromRGBO(245, 245, 245, 1), |
|||
gradient: const LinearGradient( |
|||
begin: Alignment.centerLeft, |
|||
end: Alignment.centerRight, // 对应 CSS 90deg |
|||
colors: [ |
|||
Color.fromRGBO(131, 89, 255, 1), // rgba(131, 89, 255, 1) |
|||
Color.fromRGBO(61, 138, 224, 1), // rgba(61, 138, 224, 1) |
|||
], |
|||
), |
|||
), |
|||
child: Center( |
|||
child: Text( |
|||
"立即升级", |
|||
style: TextStyle( |
|||
fontSize: 15.w, |
|||
fontWeight: FontWeight.w500, |
|||
color: Colors.white |
|||
), |
|||
), |
|||
), |
|||
), |
|||
], |
|||
) |
|||
], |
|||
), |
|||
), |
|||
Positioned( |
|||
left: 0, |
|||
top: -56.w, |
|||
child: Image.asset( |
|||
Assets.imagesUpdataBg, |
|||
width: 299.w, |
|||
), |
|||
), |
|||
Positioned( |
|||
left: 11.w, |
|||
top: -14.w, |
|||
child: Image.asset( |
|||
Assets.imagesUpdataIcon, |
|||
width: 36.w, |
|||
), |
|||
), |
|||
Positioned( |
|||
left: 43.w, |
|||
top: 29.w, |
|||
child: Image.asset( |
|||
Assets.imagesUpdataFont, |
|||
width: 76.w, |
|||
), |
|||
) |
|||
], |
|||
), |
|||
), |
|||
); |
|||
})); |
|||
}), |
|||
], |
|||
), |
|||
], |
|||
), |
|||
), |
|||
), |
|||
); |
|||
} |
|||
} |
|||
|
|||
class BlockItem extends StatefulWidget { |
|||
final List<Widget> children; |
|||
const BlockItem({super.key, required this.children}); |
|||
|
|||
@override |
|||
State<BlockItem> createState() => _BlockItemState(); |
|||
} |
|||
|
|||
class _BlockItemState extends State<BlockItem> { |
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return Container( |
|||
padding: EdgeInsets.symmetric( |
|||
horizontal: 14.w |
|||
), |
|||
margin: EdgeInsets.only( |
|||
bottom: 10.w |
|||
), |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.all(Radius.circular(9.w)), |
|||
color: Colors.white |
|||
), |
|||
child: Column( |
|||
children: widget.children, |
|||
), |
|||
); |
|||
} |
|||
} |
|||
|
|||
class Item extends StatefulWidget { |
|||
final String label; |
|||
final Widget child; |
|||
const Item({super.key, required this.label, required this.child}); |
|||
|
|||
@override |
|||
State<Item> createState() => _ItemState(); |
|||
} |
|||
|
|||
class _ItemState extends State<Item> { |
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return SizedBox( |
|||
height: 54.w, |
|||
child: Row( |
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|||
children: [ |
|||
Text( |
|||
widget.label, |
|||
style: TextStyle( |
|||
fontSize: 13.w, |
|||
fontWeight: FontWeight.w500 |
|||
), |
|||
), |
|||
widget.child |
|||
], |
|||
), |
|||
); |
|||
} |
|||
} |
|||
|
|||
class LineItem extends StatelessWidget { |
|||
const LineItem({super.key}); |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return Container( |
|||
width: 320.w, |
|||
height: 2.w, |
|||
color: const Color.fromRGBO(245, 245, 245, 1), |
|||
); |
|||
} |
|||
} |
|||
@ -1,79 +1,77 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
|||
import 'package:get/get.dart'; |
|||
import 'package:tdesign_flutter/tdesign_flutter.dart'; |
|||
|
|||
class NoticePage extends StatefulWidget { |
|||
const NoticePage({super.key}); |
|||
import '../../components/page_appbar.dart'; |
|||
import '../../controller/setting/notification_controller.dart'; |
|||
|
|||
@override |
|||
State<NoticePage> createState() => _NoticePageState(); |
|||
} |
|||
class NoticePage extends StatelessWidget { |
|||
NoticePage({super.key}); |
|||
|
|||
class _NoticePageState extends State<NoticePage> with AutomaticKeepAliveClientMixin{ |
|||
final NotificationController controller = Get.put(NotificationController()); |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
super.build(context); |
|||
return Scaffold( |
|||
backgroundColor: Color(0xffF5F5F5), |
|||
appBar: AppBar( |
|||
title: Text('消息通知', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), |
|||
centerTitle: true, |
|||
backgroundColor: Colors.white, |
|||
), |
|||
appBar: PageAppbar(title: "消息通知"), |
|||
body: Expanded( |
|||
child: SingleChildScrollView( |
|||
padding: EdgeInsetsGeometry.symmetric(vertical: 16.w), |
|||
child: Column( |
|||
children: [ |
|||
TDCellGroup( |
|||
theme: TDCellGroupTheme.cardTheme, |
|||
cells: [ |
|||
TDCell( |
|||
arrow: true, |
|||
title: '接受推送通知', |
|||
description: '已开启', |
|||
), |
|||
TDCell( |
|||
arrow: false, |
|||
title: '接受推送通知', |
|||
description: '一段很长很长的内容文字', |
|||
rightIconWidget: TDSwitch( |
|||
isOn: false, |
|||
trackOnColor: const Color.fromRGBO(117, 98, 249, 1), |
|||
onChanged: (bool e){ |
|||
return false; |
|||
}, |
|||
) |
|||
), |
|||
], |
|||
), |
|||
const SizedBox(height: 12), |
|||
TDCellGroup( |
|||
theme: TDCellGroupTheme.cardTheme, |
|||
cells: [ |
|||
TDCell( |
|||
arrow: false, |
|||
title: '后台播放', |
|||
description: '一段很长很长的内容文字', |
|||
rightIconWidget: TDSwitch( |
|||
isOn: true, |
|||
trackOnColor: const Color.fromRGBO(117, 98, 249, 1), |
|||
onChanged: (bool e){ |
|||
return false; |
|||
}, |
|||
) |
|||
), |
|||
], |
|||
), |
|||
], |
|||
), |
|||
child: Obx(() { |
|||
return Column( |
|||
children: [ |
|||
TDCellGroup( |
|||
theme: TDCellGroupTheme.cardTheme, |
|||
cells: [ |
|||
TDCell( |
|||
arrow: true, |
|||
title: '接受推送通知', |
|||
description: controller.getPermissionStatusText(), |
|||
onClick: (cell){ |
|||
controller.openSettings(); |
|||
}, |
|||
), |
|||
TDCell( |
|||
arrow: false, |
|||
title: '接受推送通知', |
|||
description: '一段很长很长的内容文字', |
|||
rightIconWidget: TDSwitch( |
|||
isOn: false, |
|||
trackOnColor: const Color.fromRGBO(117, 98, 249, 1), |
|||
onChanged: (bool e){ |
|||
return false; |
|||
}, |
|||
) |
|||
), |
|||
], |
|||
), |
|||
const SizedBox(height: 12), |
|||
TDCellGroup( |
|||
theme: TDCellGroupTheme.cardTheme, |
|||
cells: [ |
|||
TDCell( |
|||
arrow: false, |
|||
title: '后台播放', |
|||
description: '一段很长很长的内容文字', |
|||
rightIconWidget: TDSwitch( |
|||
isOn: true, |
|||
trackOnColor: const Color.fromRGBO(117, 98, 249, 1), |
|||
onChanged: (bool e){ |
|||
return false; |
|||
}, |
|||
) |
|||
), |
|||
], |
|||
), |
|||
], |
|||
); |
|||
}), |
|||
), |
|||
), |
|||
); |
|||
} |
|||
|
|||
@override |
|||
bool get wantKeepAlive => true; |
|||
} |
|||
|
|||
@ -1,155 +1,153 @@ |
|||
import 'package:dating_touchme_app/components/home_appbar.dart'; |
|||
import 'package:dating_touchme_app/generated/assets.dart'; |
|||
import 'package:dating_touchme_app/pages/discover/live_room_page.dart'; |
|||
import 'package:dating_touchme_app/pages/mine/login_page.dart'; |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
|||
import 'package:get/get.dart'; |
|||
import 'package:tdesign_flutter/tdesign_flutter.dart'; |
|||
|
|||
import '../../components/page_appbar.dart'; |
|||
import '../../controller/setting/setting_controller.dart'; |
|||
import 'blacklist_page.dart'; |
|||
import 'notice_page.dart'; |
|||
|
|||
class SettingPage extends StatefulWidget { |
|||
const SettingPage({super.key}); |
|||
class SettingPage extends StatelessWidget { |
|||
|
|||
@override |
|||
State<SettingPage> createState() => _SettingPageState(); |
|||
} |
|||
|
|||
class _SettingPageState extends State<SettingPage> with AutomaticKeepAliveClientMixin{ |
|||
SettingPage({super.key}); |
|||
final SettingController controller = Get.put(SettingController()); |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
super.build(context); |
|||
return Scaffold( |
|||
backgroundColor: Color(0xffF5F5F5), |
|||
appBar: AppBar( |
|||
title: Text('设置', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), |
|||
centerTitle: true, |
|||
backgroundColor: Colors.white, |
|||
), |
|||
appBar: PageAppbar(title: "设置"), |
|||
body: Expanded( |
|||
child: SingleChildScrollView( |
|||
padding: EdgeInsetsGeometry.symmetric(vertical: 16.w), |
|||
child: Column( |
|||
children: [ |
|||
TDCellGroup( |
|||
theme: TDCellGroupTheme.cardTheme, |
|||
cells: [ |
|||
TDCell( |
|||
arrow: false, |
|||
title: '允许中间邀请弹窗', |
|||
rightIconWidget: TDSwitch( |
|||
isOn: false, |
|||
trackOnColor: const Color.fromRGBO(117, 98, 249, 1), |
|||
onChanged: (bool e){ |
|||
return false; |
|||
child: Obx(() { |
|||
return Column( |
|||
children: [ |
|||
TDCellGroup( |
|||
theme: TDCellGroupTheme.cardTheme, |
|||
cells: [ |
|||
TDCell( |
|||
arrow: false, |
|||
title: '允许中间邀请弹窗', |
|||
rightIconWidget: TDSwitch(isOn: false,trackOnColor: const Color.fromRGBO(117, 98, 249, 1),onChanged: (bool e) { |
|||
return false; |
|||
}) |
|||
), |
|||
TDCell( |
|||
arrow: false, |
|||
title: '后台播放', |
|||
rightIconWidget: TDSwitch( |
|||
isOn: true, |
|||
trackOnColor: const Color.fromRGBO(117, 98, 249, 1), |
|||
onChanged: (bool e) { |
|||
return false; |
|||
}, |
|||
) |
|||
), |
|||
TDCell( |
|||
arrow: false, |
|||
title: '语音/视频通话提示音', |
|||
rightIconWidget: TDSwitch(isOn: false,trackOnColor: const Color.fromRGBO(117, 98, 249, 1),onChanged: (bool e) { |
|||
|
|||
return false; |
|||
}) |
|||
), |
|||
], |
|||
), |
|||
const SizedBox(height: 12), |
|||
TDCellGroup( |
|||
theme: TDCellGroupTheme.cardTheme, |
|||
cells: [ |
|||
TDCell(arrow: true, title: '安全中心', onClick: (cell) { |
|||
print('安全中心'); |
|||
}), |
|||
TDCell(arrow: true, title: '黑名单', onClick: (cell) { |
|||
Get.to(() => BlacklistPage()); |
|||
}), |
|||
], |
|||
), |
|||
const SizedBox(height: 12), |
|||
TDCellGroup( |
|||
theme: TDCellGroupTheme.cardTheme, |
|||
cells: [ |
|||
TDCell(arrow: true, title: '系统权限管理'), |
|||
TDCell(arrow: true, title: '消息通知', onClick: (cell) { |
|||
Get.to(() => NoticePage()); |
|||
}), |
|||
TDCell(arrow: true, title: '检查更新', onClick: (cell) { |
|||
// _showUpdateDialog(); |
|||
controller.checkVersion(); |
|||
}, |
|||
noteWidget: Text('当前版本:${controller.version.value}',style: TextStyle(fontSize: 13.w,color: const Color.fromRGBO(117, 98, 249, 1))), |
|||
) |
|||
), |
|||
TDCell( |
|||
arrow: false, |
|||
title: '后台播放', |
|||
rightIconWidget: TDSwitch( |
|||
isOn: true, |
|||
trackOnColor: const Color.fromRGBO(117, 98, 249, 1), |
|||
onChanged: (bool e){ |
|||
return false; |
|||
}, |
|||
) |
|||
), |
|||
TDCell(arrow: false, title: '单行标题'), |
|||
], |
|||
), |
|||
const SizedBox(height: 12), |
|||
TDCellGroup( |
|||
theme: TDCellGroupTheme.cardTheme, |
|||
cells: [ |
|||
TDCell(arrow: true, title: '黑名单',onClick: (cell) { |
|||
print('单行标题'); |
|||
} |
|||
), |
|||
], |
|||
), |
|||
const SizedBox(height: 12), |
|||
TDCellGroup( |
|||
theme: TDCellGroupTheme.cardTheme, |
|||
cells: [ |
|||
TDCell(arrow: true, title: '单行标题'), |
|||
TDCell(arrow: true, title: '单行标题'), |
|||
TDCell(arrow: true, title: '消息通知',onClick: (cell) { |
|||
Get.to(()=> NoticePage()); |
|||
} |
|||
), |
|||
], |
|||
), |
|||
const SizedBox(height: 36), |
|||
TDButton( |
|||
text: '退出登录', |
|||
width: MediaQuery.of(context).size.width - 40, |
|||
size: TDButtonSize.large, |
|||
type: TDButtonType.fill, |
|||
shape: TDButtonShape.round, |
|||
theme: TDButtonTheme.danger, |
|||
onTap: (){ |
|||
// showGeneralDialog( |
|||
// context: context, |
|||
// pageBuilder: (BuildContext buildContext, Animation<double> animation, |
|||
// Animation<double> secondaryAnimation) { |
|||
// return TDConfirmDialog( |
|||
// title: '是否退出当前账号?', |
|||
// |
|||
// ); |
|||
// }, |
|||
// ); |
|||
showGeneralDialog( |
|||
context: context, |
|||
pageBuilder: (BuildContext buildContext, Animation<double> animation, |
|||
Animation<double> secondaryAnimation) { |
|||
return TDAlertDialog( |
|||
title: '是否退出当前账号?', |
|||
buttonWidget:Container( |
|||
padding: EdgeInsetsGeometry.only(top: 16.w, right: 30.w, left: 30.w, bottom: 32.w), |
|||
child: Row( |
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|||
children: [ |
|||
TDButton( |
|||
text: '取 消', |
|||
width: 120, |
|||
size: TDButtonSize.large, |
|||
type: TDButtonType.fill, |
|||
shape: TDButtonShape.round, |
|||
theme: TDButtonTheme.defaultTheme, |
|||
onTap: (){ |
|||
Navigator.of(context).pop(); |
|||
}, |
|||
), |
|||
TDButton( |
|||
text: '确 定', |
|||
width: 120, |
|||
size: TDButtonSize.large, |
|||
type: TDButtonType.fill, |
|||
shape: TDButtonShape.round, |
|||
theme: TDButtonTheme.danger, |
|||
onTap: (){ |
|||
Navigator.of(context).pop(); |
|||
}, |
|||
], |
|||
), |
|||
const SizedBox(height: 64), |
|||
TDButton( |
|||
text: '退出登录', |
|||
width: MediaQuery.of(context).size.width - 40, |
|||
size: TDButtonSize.large, |
|||
type: TDButtonType.fill, |
|||
shape: TDButtonShape.round, |
|||
theme: TDButtonTheme.danger, |
|||
onTap: () { |
|||
showGeneralDialog( |
|||
context: context, |
|||
pageBuilder: (BuildContext buildContext, Animation< |
|||
double> animation, |
|||
Animation<double> secondaryAnimation) { |
|||
return TDAlertDialog( |
|||
title: '是否退出当前账号?', |
|||
buttonWidget: Container( |
|||
padding: EdgeInsetsGeometry.only(top: 16.w, |
|||
right: 30.w, |
|||
left: 30.w, |
|||
bottom: 32.w), |
|||
child: Row( |
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|||
children: [ |
|||
TDButton( |
|||
text: '取 消', |
|||
width: 120, |
|||
size: TDButtonSize.large, |
|||
type: TDButtonType.fill, |
|||
shape: TDButtonShape.round, |
|||
theme: TDButtonTheme.defaultTheme, |
|||
onTap: () { |
|||
Navigator.of(context).pop(); |
|||
}, |
|||
), |
|||
TDButton( |
|||
text: '确 定', |
|||
width: 120, |
|||
size: TDButtonSize.large, |
|||
type: TDButtonType.fill, |
|||
shape: TDButtonShape.round, |
|||
theme: TDButtonTheme.danger, |
|||
onTap: () { |
|||
controller.logout(); |
|||
Navigator.of(context).pop(); |
|||
Get.offAll(() => LoginPage()); |
|||
}, |
|||
), |
|||
], |
|||
), |
|||
], |
|||
), |
|||
) |
|||
); |
|||
}, |
|||
); |
|||
}, |
|||
), |
|||
], |
|||
), |
|||
) |
|||
); |
|||
}, |
|||
); |
|||
}, |
|||
), |
|||
const SizedBox(height: 24), |
|||
], |
|||
); |
|||
}), |
|||
), |
|||
), |
|||
); |
|||
} |
|||
|
|||
@override |
|||
bool get wantKeepAlive => true; |
|||
} |
|||
|
|||
Write
Preview
Loading…
Cancel
Save