Ver código fonte

[feat]亲密度分析,UI样式调整

hezihao 7 meses atrás
pai
commit
231aac2800

BIN
assets/images/icon_default_avatar_female.webp


BIN
assets/images/icon_default_avatar_male.webp


+ 11 - 18
lib/module/intimacy_analyse/analyse_report/intimacy_analyse_report_view.dart

@@ -9,6 +9,7 @@ import '../../../data/bean/intimacy_analyse_report.dart';
 import '../../../resource/assets.gen.dart';
 import '../../../resource/colors.gen.dart';
 import '../../../widget/avatar/avatar_image_widget.dart';
+import '../../../widget/markdown/markdown_viewer.dart';
 import '../widget/intimacy_user_widget.dart';
 import 'intimacy_analyse_report_view_controller.dart';
 
@@ -146,7 +147,6 @@ class IntimacyAnalyseReportView
                     padding: const EdgeInsets.only(
                       left: 14,
                       right: 14,
-                      top: 20,
                       bottom: 14,
                     ),
                     // 内容
@@ -154,10 +154,10 @@ class IntimacyAnalyseReportView
                       // 撑满父组件
                       fit: StackFit.expand,
                       children: [
-                        SingleChildScrollView(
-                          child: _buildReportContent(
-                            controller.reportPreviewData.value,
-                          ),
+                        MarkdownViewer(
+                          content: controller.reportPreviewData.value,
+                          // 允许滚动
+                          enableContentScroll: true,
                         ),
                       ],
                     ),
@@ -182,23 +182,12 @@ class IntimacyAnalyseReportView
     });
   }
 
-  /// 报告内容
-  Widget _buildReportContent(IntimacyAnalyseReport report) {
-    return Column(
-      children: [
-        // 报告列表
-        ...report.list.map((ele) {
-          return ReportItemWidget(item: ele);
-        }),
-      ],
-    );
-  }
-
   /// 底部布局
   Widget _buildBottomLayout(BuildContext context) {
     return Column(
       // 高度包裹内容,否则会撑满父组件
       mainAxisSize: MainAxisSize.min,
+      crossAxisAlignment: CrossAxisAlignment.start,
       children: [
         _buildReportPreviewBubble(),
         _buildUnlockBtn(context),
@@ -210,7 +199,7 @@ class IntimacyAnalyseReportView
   /// 报告预览布局-气泡
   Widget _buildReportPreviewBubble() {
     return Container(
-      margin: EdgeInsets.only(left: 16, right: 58, bottom: 3),
+      margin: EdgeInsets.only(left: 16, bottom: 3),
       padding: EdgeInsets.only(bottom: 3, right: 15),
       decoration: BoxDecoration(
         image: DecorationImage(
@@ -229,6 +218,10 @@ class IntimacyAnalyseReportView
             padding: EdgeInsets.only(left: 38, top: 7, bottom: 8),
             child: Text(
               controller.reportPreviewBubbleText.value,
+              // 超出则显示省略号
+              overflow: TextOverflow.ellipsis,
+              // 单行显示
+              maxLines: 1,
               style: TextStyle(
                 color: ColorName.black65,
                 fontSize: 11.sp,

+ 19 - 30
lib/module/intimacy_analyse/analyse_report/intimacy_analyse_report_view_controller.dart

@@ -3,8 +3,6 @@ import 'package:get/get.dart';
 import 'package:injectable/injectable.dart';
 import 'package:keyboard/base/base_controller.dart';
 import 'package:wechat_assets_picker/wechat_assets_picker.dart';
-
-import '../../../data/bean/intimacy_analyse_report.dart';
 import '../../../utils/image_picker_util.dart';
 import '../intimacy_analyse_upload/intimacy_analyse_upload_page.dart';
 
@@ -12,34 +10,25 @@ import '../intimacy_analyse_upload/intimacy_analyse_upload_page.dart';
 @injectable
 class IntimacyAnalyseReportController extends BaseController {
   /// 报告预览数据
-  Rx<IntimacyAnalyseReport> reportPreviewData =
-      IntimacyAnalyseReport(
-        list: [
-          AnalyseItem(
-            title: "性格匹配度",
-            sections: [
-              "互补型:一方外向活泼,另一方沉稳内敛,形成动态平衡。",
-              "相似型:三观一致,兴趣重叠,减少摩擦但需警惕新鲜感流失。",
-              "关键结论:差异是火花的来源,但核心价值观需一致(如家庭观、金钱观)。",
-            ],
-          ),
-          AnalyseItem(
-            title: "沟通模式分析",
-            sections: [
-              "语言风格:幽默调侃型 vs 理性分析型 → 需找到共同表达方式。",
-              "冲突解决:回避型 vs 直面型 → 建议建立“冷静-沟通”机制。",
-              "情感需求:一方需要高频互动,另一方偏好独立空间 → 需协商平衡点。",
-            ],
-          ),
-          AnalyseItem(
-            title: "爱情语言测试",
-            sections: [
-              "根据盖瑞·查普曼的“五种爱之语”理论,分析双方的情感表达偏好:",
-              "你的主要爱语:肯定的言辞(如情话、鼓励)",
-            ],
-          ),
-        ],
-      ).obs;
+  RxString reportPreviewData =
+      '''
+  **性格匹配度**
+
+  ● 互补型:一方外向活泼,另一方沉稳内敛,形成动态平衡。
+  ● 相似型:三观一致,兴趣重叠,减少摩擦但需警惕新鲜感流失。
+  ● 关键结论:差异是火花的来源,但核心价值观需一致(如家庭观、金钱观)。
+
+  **沟通模式分析**
+
+  ● 语言风格:幽默调侃型 vs 理性分析型 → 需找到共同表达方式。
+  ● 冲突解决:回避型 vs 直面型 → 建议建立“冷静-沟通”机制。
+  ● 情感需求:一方需要高频互动,另一方偏好独立空间 → 需协商平衡点。
+
+  **爱情语言测试**
+
+  ● 根据盖瑞·查普曼的“五种爱之语”理论,分析双方的情感表达偏好:
+  ● 你的主要爱语:肯定的言辞(如情话、鼓励)
+  '''.obs;
 
   /// 报告预览-气泡文本
   RxString reportPreviewBubbleText = '报告还有2565字未显示,点击按钮查看完整报告'.obs;

+ 1 - 1
lib/module/intimacy_analyse/intimacy_analyse_upload/intimacy_analyse_upload_controller.dart

@@ -27,7 +27,7 @@ class IntimacyAnalyseUploadController extends BaseController {
       <OptionSelectConfig>[].obs;
 
   /// 是否上传页
-  RxBool isUploadPage = false.obs;
+  RxBool isUploadPage = true.obs;
 
   /// 报告的markdown数据
   RxString reportMarkdownData = '''

+ 1 - 1
lib/module/intimacy_analyse/intimacy_analyse_upload/intimacy_analyse_upload_page.dart

@@ -185,7 +185,7 @@ class IntimacyAnalyseUploadPage
       contentWidget: Column(
         children: [
           Container(
-            margin: EdgeInsets.only(left: 12.w, right: 12.w),
+            margin: EdgeInsets.only(left: 12.w, top: 17.h, right: 12.w),
             padding: EdgeInsets.only(
               left: 12.w,
               top: 12.h,

+ 10 - 4
lib/module/intimacy_analyse/intimacy_analyse_upload/popup/ai_model_select_popup.dart

@@ -38,7 +38,7 @@ class AiModelSelectPopup {
       return;
     }
 
-    double popupWidth = 140.w;
+    double popupWidth = 145.w;
 
     SmartDialog.showAttach(
       // 绑定唯一tag
@@ -65,12 +65,18 @@ class AiModelSelectPopup {
         final anchorPosition = anchorRenderBox.localToGlobal(Offset.zero);
         final anchorSize = anchorRenderBox.size;
 
-        // 计算弹窗位置
+        // 计算X轴的偏移量,距离屏幕左边有一段距离
+        double leftOffset = 6.w;
         double popupX =
-            anchorPosition.dx + anchorSize.width / 2 - popupWidth / 2;
+            anchorPosition.dx +
+            (anchorSize.width / 2) -
+            (popupWidth / 2) +
+            leftOffset;
 
         // 计算Y轴的偏移量(默认是在按钮的上边显示,UI设计要求盖着按钮,所以需要增加偏移量)
-        double popupY = anchorPosition.dy + 46.h;
+        double bottomOffset = 46.h;
+        double popupY = anchorPosition.dy + bottomOffset;
+
         return Offset(popupX, popupY);
       },
       // 构建弹窗内容

+ 6 - 1
lib/module/intimacy_analyse/widget/intimacy_analyse_report_widget.dart

@@ -309,7 +309,12 @@ class ExistReportCardWidget extends StatelessWidget {
           borderRadius: BorderRadius.circular(30.r),
         ),
       ),
-      child: MarkdownViewer(content: reportContent),
+      child: MarkdownViewer(
+        // 内容
+        content: reportContent,
+        // 不允许滚动
+        enableContentScroll: false,
+      ),
     );
   }
 }

+ 13 - 3
lib/widget/markdown/markdown_viewer.dart

@@ -7,7 +7,14 @@ class MarkdownViewer extends StatelessWidget {
   /// 内容
   final String content;
 
-  const MarkdownViewer({super.key, required this.content});
+  /// 内容是否可以滚动
+  final bool enableContentScroll;
+
+  const MarkdownViewer({
+    super.key,
+    required this.content,
+    required this.enableContentScroll,
+  });
 
   @override
   Widget build(BuildContext context) {
@@ -15,9 +22,12 @@ class MarkdownViewer extends StatelessWidget {
       // 文档内容
       data: content,
       // 让Markdown高度自适应内容
-      shrinkWrap: true,
+      shrinkWrap: !enableContentScroll,
       // 禁用自身滚动
-      physics: const NeverScrollableScrollPhysics(),
+      physics:
+          enableContentScroll
+              ? BouncingScrollPhysics()
+              : const NeverScrollableScrollPhysics(),
       // 配置图片加载器
       imageBuilder:
           (uri, title, alt) => CachedNetworkImage(imageUrl: uri.toString()),