From 014907eb31c4bd120445ae43526f08ec68449ed1 Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Sat, 7 Jun 2025 15:02:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(core):=20=E6=B7=BB=E5=8A=A0=E6=9D=83?= =?UTF-8?q?=E9=99=90=E8=AF=B7=E6=B1=82=E5=B7=A5=E5=85=B7=E7=B1=BB=E5=B9=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=B6=88=E6=81=AF=E6=B0=94=E6=B3=A1=E5=B8=83?= =?UTF-8?q?=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 PermissionUtil 工具类,用于检查和请求权限 - 修改 AgentController,引入 PermissionUtil - 调整 MessageBubble 布局,优化 AI 消息显示 --- lib/core/utils/permission_util.dart | 134 ++++++++++++++++++ .../agent/controllers/agent_controller.dart | 1 + lib/modules/agent/views/message_bubble.dart | 3 +- 3 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 lib/core/utils/permission_util.dart diff --git a/lib/core/utils/permission_util.dart b/lib/core/utils/permission_util.dart new file mode 100644 index 000000000..7b91cc246 --- /dev/null +++ b/lib/core/utils/permission_util.dart @@ -0,0 +1,134 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:app_settings/app_settings.dart'; + +class PermissionUtil { + /// 检查并请求多个权限 + /// + /// [permissions] 要检查的权限列表,如 [Permission.microphone, Permission.location] + /// [rationaleTitle] 弹窗标题 + /// [rationaleMessage] 权限用途说明内容(支持多行) + /// + /// 返回是否所有权限都已被授予 + static Future checkAndRequestPermissions({ + required List permissions, + required String rationaleTitle, + required List rationaleMessage, + }) async { + try { + Map statuses = {}; + + // 检查是否都已授权 + bool allGranted = true; + for (var permission in permissions) { + final status = await permission.status; + if (!status.isGranted) { + allGranted = false; + statuses[permission] = status; + } + } + + if (allGranted) return true; + + // 判断是否包含永久拒绝 + bool hasPermanentDenied = + statuses.values.any((status) => status.isPermanentlyDenied); + + // 显示提示弹窗 + _showPermissionDialog( + isPermanent: hasPermanentDenied, + title: rationaleTitle, + messages: rationaleMessage, + onConfirm: () async { + if (hasPermanentDenied) { + AppSettings.openAppSettings(); + } else { + final newStatuses = await permissions.request(); + final allGrantedNow = + newStatuses.values.every((status) => status.isGranted); + if (!allGrantedNow) { + print("部分权限被拒绝: $newStatuses"); + } + } + }, + ); + + return false; + } catch (e) { + print("权限检查异常: $e"); + return false; + } + } + + /// 权限说明弹窗 + static void _showPermissionDialog({ + required bool isPermanent, + required String title, + required List messages, + required VoidCallback onConfirm, + }) { + Get.generalDialog( + barrierDismissible: false, + barrierLabel: '权限提示', + transitionBuilder: (context, anim1, anim2, child) { + return SlideTransition( + position: Tween( + begin: Offset(0, -1), + end: Offset(0, 0), + ).animate(CurvedAnimation(parent: anim1, curve: Curves.easeOut)), + child: child, + ); + }, + pageBuilder: (context, anim1, anim2) { + return SafeArea( + child: Align( + alignment: Alignment.topCenter, + child: Padding( + padding: const EdgeInsets.only(top: 80, left: 24, right: 24), + child: Material( + borderRadius: BorderRadius.circular(12), + color: Colors.white, + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(title, + style: TextStyle( + fontSize: 18, fontWeight: FontWeight.bold)), + const SizedBox(height: 12), + ...messages.map((msg) => Padding( + padding: const EdgeInsets.only(bottom: 8), + child: Text("• $msg"), + )), + const SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton( + onPressed: () => Get.back(), + child: const Text('取消'), + ), + const SizedBox(width: 8), + TextButton( + onPressed: () { + Get.back(); + onConfirm(); + }, + child: Text(isPermanent ? '前往设置' : '授权'), + ), + ], + ), + ], + ), + ), + ), + ), + ), + ); + }, + ); + } +} diff --git a/lib/modules/agent/controllers/agent_controller.dart b/lib/modules/agent/controllers/agent_controller.dart index 842aba4f4..530f498ea 100644 --- a/lib/modules/agent/controllers/agent_controller.dart +++ b/lib/modules/agent/controllers/agent_controller.dart @@ -16,6 +16,7 @@ import 'package:app_settings/app_settings.dart'; import 'package:deep_voice/core/utils/logger.dart'; import 'package:path_provider/path_provider.dart'; import 'package:photo_view/photo_view.dart'; +import '../../../core/utils/permission_util.dart'; class Message { final bool isUser; //标识信息是否来自用户还是AI diff --git a/lib/modules/agent/views/message_bubble.dart b/lib/modules/agent/views/message_bubble.dart index 6cc443704..1035bc83d 100644 --- a/lib/modules/agent/views/message_bubble.dart +++ b/lib/modules/agent/views/message_bubble.dart @@ -91,7 +91,7 @@ class MessageBubble extends GetView { Row( mainAxisAlignment: isUser ? MainAxisAlignment.end - : MainAxisAlignment.start, + : MainAxisAlignment.spaceBetween, children: [ // 时间戳(左对齐或右对齐) Text( @@ -104,7 +104,6 @@ class MessageBubble extends GetView { fontWeight: FontWeight.w400, ), ), - const Spacer(), // AI标识(仅在AI消息时显示) if (!isUser) Padding(