Browse Source

Merge branch 'new_dev' of https://github.com/deepcloud2048/deep_voice into new_dev

weicu
lxm 1 year ago
parent
commit
f563de5bb4
  1. 43
      lib/modules/devices/controllers/devices_controller.dart
  2. 2
      lib/modules/meeting/controllers/meeting_controller.dart
  3. 12
      lib/modules/meeting/views/meeting_home_view.dart
  4. 170
      lib/modules/meeting/views/meeting_view.dart
  5. 79
      local_plugins/chat_api/ios/chat_api/Sources/chat_api/SystemFunctionHandler.swift

43
lib/modules/devices/controllers/devices_controller.dart

@ -14,31 +14,48 @@ import 'package:get/get_state_manager/src/simple/get_controllers.dart';
*/ */
class DevicesController extends GetxController { class DevicesController extends GetxController {
late final BleManager _bleManager; late final BleManager _bleManager;
late final Map<int, List<UserDevice>> devices;
// 修改为响应式变量
final RxMap<int, List<UserDevice>> devices = <int, List<UserDevice>>{}.obs;
// 或者使用这种方式
// final Rx<Map<int, List<UserDevice>>> devices = Rx<Map<int, List<UserDevice>>>({});
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
_bleManager = Get.find<BleManager>(); _bleManager = Get.find<BleManager>();
// 在初始化时加载设备数据
_loadDevices();
} }
@override // 加载设备数据
void onClose() { void _loadDevices() {
super.onClose(); devices.clear();
for (var device in User.instance.devices) { for (var device in User.instance.devices) {
if (!devices.containsKey(device.id)) { if (!devices.containsKey(device.devicetype)) {
devices[device.devicetype] = []; devices[device.devicetype] = [];
} }
devices[device.devicetype]!.add(device); devices[device.devicetype]!.add(device);
} }
} }
@override
void onClose() {
super.onClose();
// onClose 中不应该修改数据,这里应该是清理资源
}
void unbindearphone(UserDevice device) async { void unbindearphone(UserDevice device) async {
final response = await Api.unbinddevice({ final response = await Api.unbinddevice({
"id": device.id, "id": device.id,
}); });
if (response != null) { if (response != null) {
devices[device.devicetype]!.remove(device); // 响应式更新
devices[device.devicetype]?.remove(device);
devices.refresh(); // 触发UI更新
User.instance.removeUserDevice(device.id); User.instance.removeUserDevice(device.id);
_bleManager.clearPairedDevices(); _bleManager.clearPairedDevices();
_bleManager.disconnect(); _bleManager.disconnect();
@ -48,4 +65,18 @@ class DevicesController extends GetxController {
return; return;
} }
} }
// 添加设备
void addDevice(UserDevice device) {
if (!devices.containsKey(device.devicetype)) {
devices[device.devicetype] = [];
}
devices[device.devicetype]!.add(device);
devices.refresh(); // 触发UI更新
}
// 获取指定类型的设备列表
List<UserDevice> getDevicesByType(int deviceType) {
return devices[deviceType] ?? [];
}
} }

2
lib/modules/meeting/controllers/meeting_controller.dart

@ -15,6 +15,8 @@ class MeetingController extends GetxController {
const MeetingMineView(), const MeetingMineView(),
]; ];
int type = 1;
RxInt pageIndex = 0.obs; RxInt pageIndex = 0.obs;
RxMap user = {}.obs; RxMap user = {}.obs;

12
lib/modules/meeting/views/meeting_home_view.dart

@ -87,8 +87,8 @@ class _MeetingHomeViewState extends State<MeetingHomeView>
vertical: 10.w, vertical: 10.w,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isDarkMode color: isDarkMode
? MeetingUIUtils.getTranslucentWhite(0.05) ? MeetingUIUtils.getTranslucentWhite(0.05)
: MeetingUIUtils.getCardColor(isDarkMode), : MeetingUIUtils.getCardColor(isDarkMode),
borderRadius: BorderRadius.circular(12.w), borderRadius: BorderRadius.circular(12.w),
boxShadow: MeetingUIUtils.getCardShadow(isDarkMode), boxShadow: MeetingUIUtils.getCardShadow(isDarkMode),
@ -127,8 +127,8 @@ class _MeetingHomeViewState extends State<MeetingHomeView>
vertical: 10.w, vertical: 10.w,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isDarkMode color: isDarkMode
? MeetingUIUtils.getTranslucentWhite(0.05) ? MeetingUIUtils.getTranslucentWhite(0.05)
: MeetingUIUtils.getCardColor(isDarkMode), : MeetingUIUtils.getCardColor(isDarkMode),
borderRadius: BorderRadius.circular(50.w), borderRadius: BorderRadius.circular(50.w),
boxShadow: MeetingUIUtils.getCardShadow(isDarkMode), boxShadow: MeetingUIUtils.getCardShadow(isDarkMode),
@ -220,8 +220,8 @@ class _MeetingHomeViewState extends State<MeetingHomeView>
padding: EdgeInsets.symmetric(horizontal: 15.w, vertical: 10.w), padding: EdgeInsets.symmetric(horizontal: 15.w, vertical: 10.w),
margin: EdgeInsets.symmetric(vertical: 5.w), margin: EdgeInsets.symmetric(vertical: 5.w),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isDarkMode color: isDarkMode
? MeetingUIUtils.getTranslucentWhite(0.05) ? MeetingUIUtils.getTranslucentWhite(0.05)
: MeetingUIUtils.getCardColor(isDarkMode), : MeetingUIUtils.getCardColor(isDarkMode),
borderRadius: BorderRadius.circular(12.w), borderRadius: BorderRadius.circular(12.w),
boxShadow: MeetingUIUtils.getCardShadow(isDarkMode), boxShadow: MeetingUIUtils.getCardShadow(isDarkMode),

170
lib/modules/meeting/views/meeting_view.dart

@ -30,93 +30,97 @@ class MeetingView extends GetView<MeetingController> {
child: const FiltrateDrawer(), child: const FiltrateDrawer(),
), ),
drawerEnableOpenDragGesture: false, drawerEnableOpenDragGesture: false,
bottomNavigationBar: Stack( bottomNavigationBar: controller.type == 0
alignment: Alignment.center, ? Stack(
clipBehavior: Clip.none, alignment: Alignment.center,
children: [ clipBehavior: Clip.none,
Obx( children: [
() => BottomNavigationBar( Obx(
items: const [ () => BottomNavigationBar(
BottomNavigationBarItem( items: const [
icon: Icon(Icons.folder_outlined), BottomNavigationBarItem(
activeIcon: Icon(Icons.folder), icon: Icon(Icons.folder_outlined),
label: '文件', activeIcon: Icon(Icons.folder),
), label: '文件',
BottomNavigationBarItem( ),
icon: SizedBox(), BottomNavigationBarItem(
label: '', icon: SizedBox(),
), label: '',
BottomNavigationBarItem( ),
icon: Icon(Icons.person_outline), BottomNavigationBarItem(
activeIcon: Icon(Icons.person), icon: Icon(Icons.person_outline),
label: '我的', activeIcon: Icon(Icons.person),
), label: '我的',
], ),
backgroundColor: ],
isDarkMode ? const Color(0xFF1A1A1A) : Colors.white, backgroundColor:
currentIndex: controller.pageIndex.value, isDarkMode ? const Color(0xFF1A1A1A) : Colors.white,
unselectedItemColor: Colors.grey, currentIndex: controller.pageIndex.value,
selectedItemColor: isDarkMode ? Colors.white : Colors.blue, unselectedItemColor: Colors.grey,
unselectedFontSize: 10.sp, selectedItemColor: isDarkMode ? Colors.white : Colors.blue,
selectedFontSize: 10.sp, unselectedFontSize: 10.sp,
onTap: (int index) { selectedFontSize: 10.sp,
if (index == 1 || index == controller.pageIndex.value) return; onTap: (int index) {
if (index == 0) { if (index == 1 || index == controller.pageIndex.value)
controller.pageIndex.value = 0; return;
controller.pageController.jumpToPage(0); if (index == 0) {
} else { controller.pageIndex.value = 0;
controller.pageIndex.value = 2; controller.pageController.jumpToPage(0);
controller.pageController.jumpToPage(1); } else {
} controller.pageIndex.value = 2;
}, controller.pageController.jumpToPage(1);
), }
), },
Positioned(
top: -18.w,
child: GestureDetector(
onTap: () {
Get.bottomSheet(
BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
child: const NavigationBarBottomSheet(),
), ),
isScrollControlled: true,
);
},
child: Container(
width: 60.w,
height: 60.w,
padding: EdgeInsets.all(5.w),
alignment: Alignment.center,
decoration: BoxDecoration(
color: isDarkMode ? const Color(0xFF1A1A1A) : Colors.white,
borderRadius: BorderRadius.circular(60.w),
boxShadow: [
BoxShadow(
color: Colors.black
.withValues(alpha: isDarkMode ? 0.3 : 0.1),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
), ),
child: Container( Positioned(
alignment: Alignment.center, top: -18.w,
decoration: BoxDecoration( child: GestureDetector(
color: MeetingUIUtils.getButtonColor(isDarkMode), onTap: () {
borderRadius: BorderRadius.circular(60.w), Get.bottomSheet(
), BackdropFilter(
child: Icon( filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
Icons.add, child: const NavigationBarBottomSheet(),
color: Colors.white, ),
size: 30.w, isScrollControlled: true,
);
},
child: Container(
width: 60.w,
height: 60.w,
padding: EdgeInsets.all(5.w),
alignment: Alignment.center,
decoration: BoxDecoration(
color:
isDarkMode ? const Color(0xFF1A1A1A) : Colors.white,
borderRadius: BorderRadius.circular(60.w),
boxShadow: [
BoxShadow(
color: Colors.black
.withValues(alpha: isDarkMode ? 0.3 : 0.1),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: MeetingUIUtils.getButtonColor(isDarkMode),
borderRadius: BorderRadius.circular(60.w),
),
child: Icon(
Icons.add,
color: Colors.white,
size: 30.w,
),
),
),
), ),
), ),
), ],
), )
), : null,
],
),
); );
} }
} }

79
local_plugins/chat_api/ios/chat_api/Sources/chat_api/SystemFunctionHandler.swift

@ -4,6 +4,7 @@ import EventKit
import CoreLocation import CoreLocation
import MessageUI import MessageUI
import location_service import location_service
import user_portrait // 添加这行
/// 结果结构体 /// 结果结构体
public struct Result { public struct Result {
@ -65,6 +66,9 @@ public class SystemFunctionHandler: NSObject {
// 注册打开录音机功能 // 注册打开录音机功能
registerOpenRecorderFunction(client: client) registerOpenRecorderFunction(client: client)
// 注册用户画像更新功能
registerSetUserProfileFieldFunction(client: client)
} catch { } catch {
// 静默处理错误 // 静默处理错误
} }
@ -720,3 +724,78 @@ private class OpenRecorderHandler: FunctionHandler {
// private enum LocationError: Error { // private enum LocationError: Error {
// ... // ...
// } // }
/// 注册设置用户画像字段函数
private func registerSetUserProfileFieldFunction(client: MCPClient) {
let parameters: [String: Any] = [
"type": "object",
"properties": [
"key": [
"type": "string",
"description": "画像字段名,例如:age、tone、工作经历、device_preference"
],
"value": [
"type": "string",
"description": "字段对应的值"
]
],
"required": ["key", "value"]
]
let handler = SetUserProfileFieldHandler()
_ = client.registerLocalFunction(
name: "set_user_profile_field",
description: "设置或更新用户画像中的某一个字段",
parameters: parameters,
handler: handler
)
}
/// 设置用户画像字段处理器
private class SetUserProfileFieldHandler: FunctionHandler {
func handle(arguments: [String: Any]) async throws -> String {
guard let key = arguments["key"] as? String,
let value = arguments["value"] as? String else {
throw ChatApiException("缺少必要参数:key 和 value")
}
// 验证参数
if key.isEmpty {
throw ChatApiException("画像字段名不能为空")
}
if value.isEmpty {
throw ChatApiException("字段值不能为空")
}
let result = await setUserProfileField(key: key, value: value)
return "{\"result\": \"\(result.message)\", \"key\": \"\(key)\", \"value\": \"\(value)\"}\"}"
}
private func setUserProfileField(key: String, value: String) async -> Result {
return await withCheckedContinuation { continuation in
DispatchQueue.main.async {
do {
// 使用 UserPortrait 单例设置画像字段
UserPortrait.shared.set(key: key, value: value)
// 发送通知给其他模块
UserPortrait.shared.sendUpdateNotification(key: key, value: value)
print("[SetUserProfileFieldHandler] 成功设置用户画像字段: \(key) = \(value)")
continuation.resume(returning: Result(
success: true,
message: "成功设置用户画像字段 \(key) 为 \(value)"
))
} catch {
print("[SetUserProfileFieldHandler] 设置用户画像字段失败: \(error.localizedDescription)")
continuation.resume(returning: Result(
success: false,
message: "设置用户画像字段失败:\(error.localizedDescription)"
))
}
}
}
}
}

Loading…
Cancel
Save