|
|
@@ -4,6 +4,7 @@ import 'package:keyboard/resource/string.gen.dart';
|
|
|
|
|
|
import '../../../resource/assets.gen.dart';
|
|
|
import '../../../resource/colors.gen.dart';
|
|
|
+import '../../../widget/animated_progress_bar.dart';
|
|
|
import '../../../widget/markdown/markdown_viewer.dart';
|
|
|
|
|
|
/// 亲密度报告组件
|
|
|
@@ -15,9 +16,352 @@ class IntimacyAnalyseReportWidget extends StatelessWidget {
|
|
|
|
|
|
@override
|
|
|
Widget build(BuildContext context) {
|
|
|
- // 卡片背景
|
|
|
+ return reportContent.isEmpty
|
|
|
+ // 报告生成中
|
|
|
+ ? CreatingReportCardWidget()
|
|
|
+ // 已出报告
|
|
|
+ : ExistReportCardWidget(reportContent: reportContent);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/// 已有报告组件
|
|
|
+class ExistReportCardWidget extends StatelessWidget {
|
|
|
+ /// 报告内容,Markdown格式
|
|
|
+ final String reportContent;
|
|
|
+
|
|
|
+ const ExistReportCardWidget({super.key, required this.reportContent});
|
|
|
+
|
|
|
+ @override
|
|
|
+ Widget build(BuildContext context) {
|
|
|
+ return ReportCardFrameWidget(
|
|
|
+ height: 825.h,
|
|
|
+ child: Column(
|
|
|
+ mainAxisSize: MainAxisSize.min,
|
|
|
+ children: [
|
|
|
+ _buildReportOverview(),
|
|
|
+ SizedBox(height: 10.h),
|
|
|
+ _buildReportDetail(),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 报告概览,包含概览数值和图表
|
|
|
+ Widget _buildReportOverview() {
|
|
|
+ // 圆角背景
|
|
|
+ return Container(
|
|
|
+ padding: EdgeInsets.only(left: 12.w, right: 12.w, top: 12.h),
|
|
|
+ decoration: BoxDecoration(
|
|
|
+ color: ColorName.white,
|
|
|
+ borderRadius: BorderRadius.circular(20.r),
|
|
|
+ ),
|
|
|
+ child: Column(
|
|
|
+ mainAxisSize: MainAxisSize.min,
|
|
|
+ children: [
|
|
|
+ // 概览数值
|
|
|
+ Container(
|
|
|
+ decoration: BoxDecoration(
|
|
|
+ color: ColorName.bgReportOverview,
|
|
|
+ borderRadius: BorderRadius.all(Radius.circular(10.r)),
|
|
|
+ ),
|
|
|
+ child: Row(
|
|
|
+ children: [
|
|
|
+ _buildIntimacyOverviewItem("30"),
|
|
|
+ SizedBox(width: 29.w),
|
|
|
+ _buildOverviewDivider(),
|
|
|
+ SizedBox(width: 29.w),
|
|
|
+ _buildCurrentStageOverviewItem("相互了解"),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ SizedBox(height: 12.h),
|
|
|
+ // 图表
|
|
|
+ _buildChart(),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 概览数值的分割线
|
|
|
+ Widget _buildOverviewDivider() {
|
|
|
+ return Container(
|
|
|
+ height: 44.h,
|
|
|
+ width: 1.w,
|
|
|
+ decoration: BoxDecoration(color: ColorName.black5),
|
|
|
+ margin: EdgeInsets.symmetric(vertical: 10.h),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 概览亲密度的数值项
|
|
|
+ Widget _buildIntimacyOverviewItem(String value) {
|
|
|
+ return Expanded(
|
|
|
+ child: Row(
|
|
|
+ children: [
|
|
|
+ // 图表
|
|
|
+ Assets.images.iconIntimacyAnalyseReportOverviewLove.image(
|
|
|
+ height: 22.w,
|
|
|
+ width: 22.w,
|
|
|
+ ),
|
|
|
+ SizedBox(width: 14.w),
|
|
|
+ Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: [
|
|
|
+ // 数值区域
|
|
|
+ Row(
|
|
|
+ children: [
|
|
|
+ // 数值
|
|
|
+ Text(
|
|
|
+ value,
|
|
|
+ style: TextStyle(
|
|
|
+ color: ColorName.black80,
|
|
|
+ fontSize: 20.sp,
|
|
|
+ fontWeight: FontWeight.w700,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ SizedBox(width: 2.w),
|
|
|
+ // 百分比符号
|
|
|
+ Text(
|
|
|
+ StringName.intimacyValuePercent,
|
|
|
+ style: TextStyle(
|
|
|
+ color: ColorName.black46,
|
|
|
+ fontSize: 13.sp,
|
|
|
+ fontWeight: FontWeight.w700,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ // 描述
|
|
|
+ Text(
|
|
|
+ StringName.intimacyValue,
|
|
|
+ style: TextStyle(
|
|
|
+ color: ColorName.textReportOverviewValueDesc,
|
|
|
+ fontSize: 12.sp,
|
|
|
+ fontWeight: FontWeight.w400,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 概览目前阶段的数值项
|
|
|
+ Widget _buildCurrentStageOverviewItem(String value) {
|
|
|
+ return Expanded(
|
|
|
+ child: Row(
|
|
|
+ children: [
|
|
|
+ // 图标
|
|
|
+ Assets.images.iconIntimacyAnalyseReportOverviewStage.image(
|
|
|
+ height: 22.w,
|
|
|
+ width: 22.w,
|
|
|
+ ),
|
|
|
+ SizedBox(width: 14.w),
|
|
|
+ Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: [
|
|
|
+ // 数值
|
|
|
+ Text(
|
|
|
+ value,
|
|
|
+ style: TextStyle(
|
|
|
+ color: ColorName.black80,
|
|
|
+ fontSize: 14.sp,
|
|
|
+ fontWeight: FontWeight.w700,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ // 描述
|
|
|
+ Text(
|
|
|
+ StringName.intimacyCurrentStage,
|
|
|
+ style: TextStyle(
|
|
|
+ color: ColorName.textReportOverviewValueDesc,
|
|
|
+ fontSize: 12.sp,
|
|
|
+ fontWeight: FontWeight.w400,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 报告图表
|
|
|
+ Widget _buildChart() {
|
|
|
+ return Column(
|
|
|
+ mainAxisSize: MainAxisSize.min,
|
|
|
+ children: [
|
|
|
+ _buildValueItem(
|
|
|
+ iconProvider: Assets.images.iconEmojiLike.provider(),
|
|
|
+ title: "互动好感度",
|
|
|
+ value: 0.5,
|
|
|
+ progressColors: [ColorName.blueGradient1, ColorName.blueGradient2],
|
|
|
+ ),
|
|
|
+ SizedBox(height: 18.h),
|
|
|
+ _buildValueItem(
|
|
|
+ iconProvider: Assets.images.iconEmojiChat.provider(),
|
|
|
+ title: "话题好感度",
|
|
|
+ value: 0.35,
|
|
|
+ progressColors: [ColorName.greenGradient1, ColorName.greenGradient2],
|
|
|
+ ),
|
|
|
+ SizedBox(height: 18.h),
|
|
|
+ _buildValueItem(
|
|
|
+ iconProvider: Assets.images.iconEmojiLike.provider(),
|
|
|
+ title: "情绪回应",
|
|
|
+ value: 1.0,
|
|
|
+ progressColors: [
|
|
|
+ ColorName.yellowGradient1,
|
|
|
+ ColorName.yellowGradient2,
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ SizedBox(height: 18.h),
|
|
|
+ _buildValueItem(
|
|
|
+ iconProvider: Assets.images.iconEmojiPercent.provider(),
|
|
|
+ title: "亲密词占比",
|
|
|
+ value: 0.4,
|
|
|
+ progressColors: [ColorName.pinkGradient1, ColorName.pinkGradient2],
|
|
|
+ ),
|
|
|
+ SizedBox(height: 18.h),
|
|
|
+ _buildValueItem(
|
|
|
+ iconProvider: Assets.images.iconEmojiLove.provider(),
|
|
|
+ title: "缘分指数",
|
|
|
+ value: 0.15,
|
|
|
+ progressColors: [
|
|
|
+ ColorName.purpleGradient1,
|
|
|
+ ColorName.purpleGradient2,
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ SizedBox(height: 12, width: double.infinity),
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 构建数值Item
|
|
|
+ /// [iconProvider] icon图标的ImageProvider
|
|
|
+ /// [title] 标题
|
|
|
+ /// [progressColors] 进度条渐变色
|
|
|
+ /// [value] 进度条的数值,从0到1.0
|
|
|
+ Widget _buildValueItem({
|
|
|
+ required ImageProvider iconProvider,
|
|
|
+ required String title,
|
|
|
+ required List<Color> progressColors,
|
|
|
+ required double value,
|
|
|
+ }) {
|
|
|
+ return Row(
|
|
|
+ mainAxisSize: MainAxisSize.min,
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
+ children: [
|
|
|
+ // 图标
|
|
|
+ Container(
|
|
|
+ padding: EdgeInsets.all(6.w),
|
|
|
+ decoration: BoxDecoration(
|
|
|
+ // 圆形背景
|
|
|
+ shape: BoxShape.circle,
|
|
|
+ color: ColorName.bgReportValueIcon,
|
|
|
+ ),
|
|
|
+ child: ClipOval(
|
|
|
+ child: Image(
|
|
|
+ image: iconProvider,
|
|
|
+ width: 15.w,
|
|
|
+ height: 15.w,
|
|
|
+ fit: BoxFit.fill,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ SizedBox(width: 5.w),
|
|
|
+ // 文字
|
|
|
+ Text(title),
|
|
|
+ SizedBox(width: 10.w),
|
|
|
+ // 进度条
|
|
|
+ Expanded(
|
|
|
+ child: AnimatedGradientProgressBar(
|
|
|
+ targetValue: value,
|
|
|
+ // 渐变色
|
|
|
+ gradient: LinearGradient(colors: progressColors),
|
|
|
+ duration: const Duration(seconds: 1),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 报告详情
|
|
|
+ Widget _buildReportDetail() {
|
|
|
return Container(
|
|
|
height: 424.h,
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ color: ColorName.white,
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ borderRadius: BorderRadius.circular(30.r),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ child: MarkdownViewer(content: reportContent),
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/// 报告生成中的卡片
|
|
|
+class CreatingReportCardWidget extends StatelessWidget {
|
|
|
+ const CreatingReportCardWidget({super.key});
|
|
|
+
|
|
|
+ @override
|
|
|
+ Widget build(BuildContext context) {
|
|
|
+ return ReportCardFrameWidget(
|
|
|
+ height: 300.h,
|
|
|
+ child: Container(
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ color: ColorName.white,
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ borderRadius: BorderRadius.circular(30.r),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ child: Center(
|
|
|
+ child: Column(
|
|
|
+ // 垂直水平都居中
|
|
|
+ mainAxisAlignment: MainAxisAlignment.center,
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
+ children: [
|
|
|
+ // 图标
|
|
|
+ Assets.images.iconIntimacyAnalysisReportCreating.image(
|
|
|
+ width: 82,
|
|
|
+ height: 82,
|
|
|
+ ),
|
|
|
+ SizedBox(height: 3.h),
|
|
|
+ // 文字
|
|
|
+ Text(
|
|
|
+ StringName.intimacyAnalyseReportCreating,
|
|
|
+ style: TextStyle(
|
|
|
+ fontSize: 14.sp,
|
|
|
+ color: ColorName.black60,
|
|
|
+ fontWeight: FontWeight.w400,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/// 报告卡片框架组件,只定义报告卡片的基本框架,例如卡片背景和顶部的标题,内容由子组件来实现
|
|
|
+class ReportCardFrameWidget extends StatelessWidget {
|
|
|
+ // 卡片高度
|
|
|
+ final double height;
|
|
|
+
|
|
|
+ /// 内容子组件
|
|
|
+ final Widget child;
|
|
|
+
|
|
|
+ const ReportCardFrameWidget({
|
|
|
+ super.key,
|
|
|
+ required this.height,
|
|
|
+ required this.child,
|
|
|
+ });
|
|
|
+
|
|
|
+ @override
|
|
|
+ Widget build(BuildContext context) {
|
|
|
+ // 卡片背景
|
|
|
+ return Container(
|
|
|
+ height: height,
|
|
|
margin: EdgeInsets.only(left: 12, right: 12, bottom: 0),
|
|
|
padding: EdgeInsets.only(bottom: 12),
|
|
|
decoration: BoxDecoration(
|
|
|
@@ -28,22 +372,10 @@ class IntimacyAnalyseReportWidget extends StatelessWidget {
|
|
|
),
|
|
|
child: Stack(
|
|
|
children: [
|
|
|
- // 图标和标题
|
|
|
- _buildReportTopLayout(),
|
|
|
- // 内容
|
|
|
- Container(
|
|
|
- margin: EdgeInsets.only(top: 51, left: 12, right: 12, bottom: 5),
|
|
|
- decoration: ShapeDecoration(
|
|
|
- color: ColorName.white,
|
|
|
- shape: RoundedRectangleBorder(
|
|
|
- borderRadius: BorderRadius.circular(30.r),
|
|
|
- ),
|
|
|
- ),
|
|
|
- child:
|
|
|
- reportContent.isEmpty
|
|
|
- ? _buildCreatingLayout()
|
|
|
- : _buildReportContentLayout(),
|
|
|
- ),
|
|
|
+ // 顶部的图标和标题
|
|
|
+ Positioned(left: 0, right: 0, top: 0, child: _buildReportTopLayout()),
|
|
|
+ // 内容区域
|
|
|
+ Positioned(top: 51, left: 12, right: 12, bottom: 5, child: child),
|
|
|
],
|
|
|
),
|
|
|
);
|
|
|
@@ -64,37 +396,4 @@ class IntimacyAnalyseReportWidget extends StatelessWidget {
|
|
|
],
|
|
|
);
|
|
|
}
|
|
|
-
|
|
|
- /// 报告内容布局
|
|
|
- Widget _buildReportContentLayout() {
|
|
|
- return MarkdownViewer(content: reportContent);
|
|
|
- }
|
|
|
-
|
|
|
- /// 生成中布局
|
|
|
- Widget _buildCreatingLayout() {
|
|
|
- return Center(
|
|
|
- child: Column(
|
|
|
- // 垂直水平都居中
|
|
|
- mainAxisAlignment: MainAxisAlignment.center,
|
|
|
- crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
- children: [
|
|
|
- // 图标
|
|
|
- Assets.images.iconIntimacyAnalysisReportCreating.image(
|
|
|
- width: 82,
|
|
|
- height: 82,
|
|
|
- ),
|
|
|
- SizedBox(height: 3.h),
|
|
|
- // 文字
|
|
|
- Text(
|
|
|
- StringName.intimacyAnalyseReportCreating,
|
|
|
- style: TextStyle(
|
|
|
- fontSize: 14.sp,
|
|
|
- color: ColorName.black60,
|
|
|
- fontWeight: FontWeight.w400,
|
|
|
- ),
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- );
|
|
|
- }
|
|
|
}
|