From c1f7a8baee5f90284e016af81783363a2fd2c6d7 Mon Sep 17 00:00:00 2001 From: tanlongsheng <252620078@qq.com> Date: Fri, 21 Mar 2025 19:13:14 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BC=9A=E8=AE=AE=E5=8A=A9?= =?UTF-8?q?=E6=89=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/meeting_controller.dart | 13 + .../meeting/model/meeting_details_model.dart | 26 ++ lib/modules/meeting/model/meeting_model.dart | 29 ++ lib/modules/meeting/views/meeting_view.dart | 313 +++++++++++++++++- 4 files changed, 377 insertions(+), 4 deletions(-) create mode 100644 lib/modules/meeting/model/meeting_details_model.dart create mode 100644 lib/modules/meeting/model/meeting_model.dart diff --git a/lib/modules/meeting/controllers/meeting_controller.dart b/lib/modules/meeting/controllers/meeting_controller.dart index da440e590..42d951ee0 100644 --- a/lib/modules/meeting/controllers/meeting_controller.dart +++ b/lib/modules/meeting/controllers/meeting_controller.dart @@ -1,6 +1,17 @@ +import 'package:flutter/material.dart'; import 'package:get/get.dart'; class MeetingController extends GetxController { + final ScrollController listController = ScrollController(); + + // 是否还有更多数据 + bool isLoadingMore = true; + int page = 1; + + TextEditingController titleController = TextEditingController(); // 录音标题 + + RxList dataList = [].obs; + @override void onInit() { super.onInit(); @@ -8,6 +19,8 @@ class MeetingController extends GetxController { @override void onClose() { + listController.dispose(); + titleController.dispose(); super.onClose(); } } diff --git a/lib/modules/meeting/model/meeting_details_model.dart b/lib/modules/meeting/model/meeting_details_model.dart new file mode 100644 index 000000000..e314222a7 --- /dev/null +++ b/lib/modules/meeting/model/meeting_details_model.dart @@ -0,0 +1,26 @@ +import 'dart:typed_data'; + +class MeetingDetailsModel { + MeetingDetailsModel(); + + late int id; + late int noteid; + late Uint8List audio; + late String content; + + factory MeetingDetailsModel.fromJson(Map map) => + MeetingDetailsModel() + ..id = map["id"] + ..noteid = map["noteid"] + ..audio = map["audio"] + ..content = map["content"]; + + Map toJson() { + final data = {}; + data['id'] = id; + data['noteid'] = noteid; + data['audio'] = audio; + data['content'] = content; + return data; + } +} diff --git a/lib/modules/meeting/model/meeting_model.dart b/lib/modules/meeting/model/meeting_model.dart new file mode 100644 index 000000000..db7d5488b --- /dev/null +++ b/lib/modules/meeting/model/meeting_model.dart @@ -0,0 +1,29 @@ +class MeetingModel { + MeetingModel(); + + late int id; + late String title; + late String content; + late String language; + late int seconds; + late int creationtime; + + factory MeetingModel.fromJson(Map map) => MeetingModel() + ..id = map["id"] + ..title = map["title"] + ..content = map["content"] + ..language = map["language"] + ..seconds = map["seconds"] + ..creationtime = map["creationtime"]; + + Map toJson() { + final data = {}; + data['id'] = id; + data['title'] = title; + data['content'] = content; + data['language'] = language; + data['seconds'] = seconds; + data['creationtime'] = creationtime; + return data; + } +} diff --git a/lib/modules/meeting/views/meeting_view.dart b/lib/modules/meeting/views/meeting_view.dart index def4b3405..beebef661 100644 --- a/lib/modules/meeting/views/meeting_view.dart +++ b/lib/modules/meeting/views/meeting_view.dart @@ -1,8 +1,12 @@ +import 'package:common_utils/common_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import '../../../core/theme/app_colors.dart'; +import '../../../routes/app_routes.dart'; import '../controllers/meeting_controller.dart'; +import '../model/meeting_model.dart'; class MeetingView extends GetView { const MeetingView({super.key}); @@ -14,7 +18,7 @@ class MeetingView extends GetView { return Scaffold( backgroundColor: isDarkMode ? Colors.black : Colors.grey[50], appBar: _buildAppBar(isDarkMode), - body: _buildBody(isDarkMode), + body: _buildBody(context, isDarkMode), ); } @@ -29,14 +33,315 @@ class MeetingView extends GetView { color: isDarkMode ? Colors.white : Colors.black, size: 20.sp, ), - onPressed: () {}, + onPressed: () => Get.back(), + ), + title: Text( + 'conferenceAssistant'.tr, // 商务会议助手 + style: TextStyle( + fontSize: 17.sp, + fontWeight: FontWeight.w600, + color: isDarkMode ? Colors.white : Colors.black, + ), ), centerTitle: true, ); } // 构建主体内容 - Widget _buildBody(bool isDarkMode) { - return Container(); + Widget _buildBody(BuildContext context, bool isDarkMode) { + return Stack( + children: [ + Obx( + () => ListView.builder( + itemCount: controller.dataList.length, + padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 5.w), + itemBuilder: (BuildContext context, int index) { + // MeetingModel data = + // MeetingModel.fromJson(controller.dataList[index]); + return _item(context, isDarkMode); + }, + ), + ), + Align( + alignment: Alignment.bottomCenter, + child: GestureDetector( + onTap: () { + _bottomSheet(context, isDarkMode); + }, + child: Container( + width: 130.w, + height: 48.w, + margin: EdgeInsets.symmetric(vertical: 20.w), + decoration: BoxDecoration( + color: isDarkMode ? AppColors.primary : Colors.blue, + borderRadius: BorderRadius.circular(12.w), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon(Icons.keyboard_voice, color: Colors.white), + 5.horizontalSpace, + Text( + '录音', + style: TextStyle(color: Colors.white, fontSize: 16.sp), + ), + ], + ), + ), + ), + ), + ], + ); + } + + Widget _item(BuildContext context, bool isDarkMode) { + return GestureDetector( + onTap: () {}, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 15.w, vertical: 8.w), + margin: EdgeInsets.symmetric(vertical: 5.w), + decoration: BoxDecoration( + color: isDarkMode ? Colors.white.withOpacity(0.05) : Colors.white, + borderRadius: BorderRadius.circular(12.w), + boxShadow: [ + BoxShadow( + color: isDarkMode + ? Colors.black.withOpacity(0.2) + : Colors.black.withOpacity(0.05), + blurRadius: 10, + offset: const Offset(0, 2), + ), + ], + ), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'data.title', + style: TextStyle( + color: isDarkMode ? Colors.white : Colors.black87, + fontSize: 16.sp, + ), + overflow: TextOverflow.ellipsis, + ), + Text( + '无内容', + style: TextStyle( + color: isDarkMode ? Colors.white70 : Colors.black54, + fontSize: 12.sp, + ), + overflow: TextOverflow.ellipsis, + ), + Text( + '12-13', + style: TextStyle( + color: isDarkMode ? Colors.white70 : Colors.black54, + fontSize: 12.sp, + ), + ), + ], + ), + ), + Container( + width: 76.w, + height: 28.w, + margin: EdgeInsets.only(left: 10.w), + alignment: Alignment.center, + decoration: BoxDecoration( + color: isDarkMode ? AppColors.primary : Colors.blue, + borderRadius: BorderRadius.circular(28.w), + ), + child: Text( + '00:00:00', + style: TextStyle(color: Colors.white, fontSize: 14.sp), + ), + ), + ], + ), + ), + ); + } + + void _bottomSheet(BuildContext context, bool isDarkMode) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + clipBehavior: Clip.hardEdge, + builder: (BuildContext context) { + return Padding( + padding: MediaQuery.of(context).viewInsets, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 20.w), + color: isDarkMode ? AppColors.darkBackground : Colors.grey[50], + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + '录音语言转换', + style: TextStyle( + color: isDarkMode ? Colors.white : Colors.black87, + fontSize: 17.sp, + ), + ), + Container( + height: 48.w, + margin: EdgeInsets.only(top: 10.w, bottom: 20.w), + decoration: BoxDecoration( + color: isDarkMode + ? Colors.white.withOpacity(0.05) + : Colors.white, + borderRadius: BorderRadius.circular(12.w), + boxShadow: [ + BoxShadow( + color: isDarkMode + ? Colors.black.withOpacity(0.2) + : Colors.black.withOpacity(0.05), + blurRadius: 10, + offset: const Offset(0, 2), + ), + ], + ), + child: GestureDetector( + onTap: () {}, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 10.w), + child: Row( + children: [ + Expanded( + child: Text( + '中文', + style: TextStyle( + color: + isDarkMode ? Colors.white : Colors.black87, + fontSize: 16.sp, + ), + ), + ), + Icon( + Icons.keyboard_arrow_right, + color: isDarkMode ? Colors.white : Colors.black87, + ), + ], + ), + ), + ), + ), + Text( + '录音标题(非必填)', + style: TextStyle( + color: isDarkMode ? Colors.white : Colors.black87, + fontSize: 16.sp, + ), + ), + Container( + height: 48.w, + margin: EdgeInsets.only(top: 10.w, bottom: 20.w), + alignment: Alignment.center, + decoration: BoxDecoration( + color: isDarkMode + ? Colors.white.withOpacity(0.05) + : Colors.white, + borderRadius: BorderRadius.circular(12.w), + boxShadow: [ + BoxShadow( + color: isDarkMode + ? Colors.black.withOpacity(0.2) + : Colors.black.withOpacity(0.05), + blurRadius: 10, + offset: const Offset(0, 2), + ), + ], + ), + child: TextField( + controller: controller.titleController, + style: TextStyle( + color: isDarkMode ? Colors.white : Colors.black87, + fontSize: 16.sp, + ), + decoration: InputDecoration( + hintText: '最多50个字符', + hintStyle: TextStyle( + color: isDarkMode ? Colors.white70 : Colors.black54, + fontSize: 16.sp, + ), + fillColor: Colors.transparent, + border: InputBorder.none, + contentPadding: EdgeInsets.symmetric(horizontal: 10.w), + ), + ), + ), + Padding( + padding: EdgeInsets.only(top: 30.w), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + GestureDetector( + onTap: () { + Get.back(); + }, + child: Container( + width: 120.w, + height: 40.w, + alignment: Alignment.center, + decoration: BoxDecoration( + border: Border.all( + width: 2.w, + color: + isDarkMode ? AppColors.primary : Colors.blue, + ), + borderRadius: BorderRadius.circular(12.w), + ), + child: Text( + '取消', + style: TextStyle( + fontSize: 14.sp, + color: + isDarkMode ? AppColors.primary : Colors.blue, + ), + ), + ), + ), + GestureDetector( + onTap: () { + int time = DateTime.now().millisecondsSinceEpoch; + if (controller.titleController.text.isEmpty) { + controller.titleController.text = + '${DateUtil.formatDateMs(time, format: DateFormats.y_mo_d)} 录音'; + } + Get.back(); + Get.toNamed(Routes.meetingRecord); + }, + child: Container( + width: 120.w, + height: 40.w, + alignment: Alignment.center, + decoration: BoxDecoration( + color: isDarkMode ? AppColors.primary : Colors.blue, + borderRadius: BorderRadius.circular(12.w), + ), + child: Text( + '确定', + style: TextStyle( + color: Colors.white, + fontSize: 14.sp, + ), + ), + ), + ), + ], + ), + ), + ], + ), + ), + ); + }, + ).then((value) { + controller.titleController.text = ''; + }); } }