From a056214fcffe321edef7cc966c316cb391086e02 Mon Sep 17 00:00:00 2001 From: tanlongsheng <252620078@qq.com> Date: Fri, 27 Jun 2025 14:47:02 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9askai?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../meeting/views/ai_bottom_sheet.dart | 218 ++++++++++++++++-- 1 file changed, 198 insertions(+), 20 deletions(-) diff --git a/lib/modules/meeting/views/ai_bottom_sheet.dart b/lib/modules/meeting/views/ai_bottom_sheet.dart index 9243acad8..db5f964df 100644 --- a/lib/modules/meeting/views/ai_bottom_sheet.dart +++ b/lib/modules/meeting/views/ai_bottom_sheet.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; @@ -14,6 +15,8 @@ class AIBottomSheet extends StatefulWidget { class _AIBottomSheetState extends State { final _controller = Get.find(); + final TextEditingController _texController = TextEditingController(); + List _dataList = []; final List _cruxList = [ @@ -22,11 +25,21 @@ class _AIBottomSheetState extends State { '生成关键指标', ]; + bool _isLoading = false; + + @override + void dispose() { + _texController.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return Container( - height: 1.sh - 50.h, padding: EdgeInsets.symmetric(horizontal: 12.w), + constraints: BoxConstraints( + maxHeight: 1.sh - 50.h - MediaQuery.of(context).viewInsets.bottom, + ), child: Column( children: [ Container( @@ -49,7 +62,7 @@ class _AIBottomSheetState extends State { width: 26.w, height: 26.w, decoration: BoxDecoration( - color: Colors.white, + color: Colors.grey[100], borderRadius: BorderRadius.circular(26.r), ), child: Icon( @@ -58,12 +71,25 @@ class _AIBottomSheetState extends State { color: Colors.grey[400], ), ), - ) + ), ], ), ), Expanded( - child: _dataList.isNotEmpty ? SizedBox() : _empty(), + child: _dataList.isNotEmpty + ? Align( + alignment: Alignment.topCenter, + child: ListView.builder( + itemCount: _dataList.length, + shrinkWrap: true, + reverse: true, + itemBuilder: (BuildContext context, int index) { + Map data = _dataList[index]; + return _item(data, index == 0); + }, + ), + ) + : _empty(), ), _inputBox(), ], @@ -71,6 +97,50 @@ class _AIBottomSheetState extends State { ); } + Widget _item(Map data, bool isBorder) { + return Container( + padding: EdgeInsets.symmetric(vertical: 20.w), + decoration: BoxDecoration( + border: isBorder + ? null + : Border( + bottom: BorderSide( + width: 1, + color: Colors.grey[400]!, + ), + ), + ), + child: Column( + children: [ + Align( + alignment: Alignment.centerRight, + child: Container( + padding: EdgeInsets.all(10.w), + decoration: BoxDecoration( + color: Colors.grey[200], + borderRadius: BorderRadius.circular(12.r), + ), + child: Text( + data['user'], + style: TextStyle( + fontSize: 14.sp, + ), + ), + ), + ), + if (data['assistant'].isNotEmpty) + Container( + padding: EdgeInsets.symmetric(vertical: 20.w), + alignment: Alignment.centerLeft, + child: MarkdownBody( + data: data['assistant'], + ), + ), + ], + ), + ); + } + Widget _empty() { return Padding( padding: EdgeInsets.symmetric(vertical: 10.w), @@ -106,20 +176,25 @@ class _AIBottomSheetState extends State { ), ...List.generate( _cruxList.length, - (int index) => Container( - width: double.infinity, - padding: EdgeInsets.symmetric(horizontal: 15.w, vertical: 8.w), - margin: EdgeInsets.symmetric(vertical: 5.w), - decoration: BoxDecoration( - color: Colors.grey[100], - borderRadius: BorderRadius.circular(20.r), - border: Border.all( - color: Colors.grey[300]!, + (int index) => GestureDetector( + onTap: () { + _sendMessage(_cruxList[index]); + }, + child: Container( + width: double.infinity, + padding: EdgeInsets.symmetric(horizontal: 15.w, vertical: 8.w), + margin: EdgeInsets.symmetric(vertical: 5.w), + decoration: BoxDecoration( + color: Colors.grey[100], + borderRadius: BorderRadius.circular(20.r), + border: Border.all( + color: Colors.grey[300]!, + ), + ), + child: Text( + _cruxList[index], + style: TextStyle(fontSize: 12.sp), ), - ), - child: Text( - _cruxList[index], - style: TextStyle(fontSize: 12.sp), ), ), ), @@ -130,12 +205,115 @@ class _AIBottomSheetState extends State { Widget _inputBox() { return Container( - height: 40.w, + height: 42.w, padding: EdgeInsets.symmetric(horizontal: 10.w), - decoration: BoxDecoration(), + margin: EdgeInsets.only(bottom: 10.w), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(42.r), + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: [ + const Color(0xFFab47bc).withOpacity(0.1), // 薰衣草紫 + const Color(0xFFec407a).withOpacity(0.2), // 品红 + ], + ), + ), child: Row( - children: [], + children: [ + 5.horizontalSpace, + Expanded( + child: TextField( + controller: _texController, + style: TextStyle( + fontSize: 16.sp, + color: Colors.black87, + letterSpacing: 0, + height: 1.4, + ), + decoration: InputDecoration( + hintText: '问 AI ...', + hintStyle: TextStyle( + fontSize: 16.sp, + color: Colors.grey[400], + letterSpacing: 0, + height: 1.4, + ), + isDense: true, + fillColor: Colors.transparent, + border: InputBorder.none, + contentPadding: EdgeInsets.zero, + ), + onSubmitted: _sendMessage, + ), + ), + 10.horizontalSpace, + GestureDetector( + onTap: () { + _sendMessage(_texController.text); + }, + child: Container( + width: 26.w, + height: 26.w, + decoration: BoxDecoration( + color: Colors.grey, + borderRadius: BorderRadius.circular(26.r), + ), + child: Icon( + Icons.arrow_upward, + size: 18.w, + color: Colors.white, + ), + ), + ), + ], ), ); } + + void _sendMessage(String value) { + if (_isLoading || value.isEmpty) return; + setState(() { + _isLoading = true; + }); + _dataList.insert(0, { + 'user': value, + 'assistant': ''' +# 角色 +你是一名卓越的会议记录专家,拥有超强的信息归纳与细分能力。不仅能高效处理各类通用场景会议,精准提炼会议核心内容,为后续思维导图生成奠定坚实基础,还能将整理好的会议记录巧妙转化为清晰直观的思维导图。 + +## 技能 +### 技能 1: 通用会议内容深度细分 +1. 深入全面剖析给定的通用场景会议内容,精准区分不同主题板块,如会议目标、讨论事项、决策结果、行动安排、问题与挑战等。 +2. 对每个主题板块进行细致分解,形成具体要点与细节。若涉及人员,人员名称保留[],清晰明确其角色与贡献;涉及流程,梳理出关键步骤与节点。 +3. 以层次分明、逻辑紧密的方式整理细分内容,使其契合思维导图的结构特点。 +===回复示例=== +- **会议目标**: + - 目标 1:[详细且全面阐述目标 1] + - 目标 2:[如有多个目标,依次详细罗列] +- **讨论事项**: + - 事项 1: + - 观点 1:[详细说明提出观点 1 的人员及具体内容] + - 观点 2:[详细阐述不同观点及相关人员] + - 事项 2:[按此格式详细罗列其他讨论事项] +- **决策结果**: + - 决策 1:[具体且完整表述决策内容] + - 决策 2:[详细列出其他决策] +- **行动安排**: + - 任务 1: + - 负责人:[具体姓名] + - 时间节点:[精确到具体时间] + - 任务内容:[详细描述任务具体内容] + - 任务 2:[依此格式详细罗列其他任务] +- **问题与挑战**: + - 问题 1:[具体清晰描述问题] + - 挑战 1:[详细说明面临的挑战及相关说明] +===示例结束=== +''', + }); + _texController.clear(); + setState(() { + _isLoading = false; + }); + } }