From ebde2ae977ed6e1492ef13af93d294f7d7d3ce72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B4=94=E5=AE=9D=E6=96=B0?= Date: Mon, 7 Sep 2026 17:01:48 +0800 Subject: [PATCH] =?UTF-8?q?refactor(class):=20=E6=8A=BD=E7=A6=BB=E6=94=BB?= =?UTF-8?q?=E5=85=8B=E4=BB=BB=E5=8A=A1=E7=BB=84=E4=BB=B6=E5=B9=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=A0=B7=E5=BC=8F=E4=B8=8E=E8=B5=84=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 将ResolveProblemBox从class_update_widgets.dart抽离到公共组件目录 2. 替换静态渐变背景为CDN资源背景图,适配平板和手机端 3. 将点赞评论按钮的图标从内置Icons替换为本地png资源 4. 更新pubspec.yaml添加新的图片资源路径 5. 删除冗余的空行配置 --- assets/img/class/comment-icon.png | Bin 0 -> 901 bytes assets/img/class/like-check-icon.png | Bin 0 -> 519 bytes assets/img/class/like-icon.png | Bin 0 -> 744 bytes lib/core/components/resolve_problem_box.dart | 117 ++++++++++++++++++ .../class/widgets/class_update_widgets.dart | 86 +++---------- pubspec.yaml | 4 +- 6 files changed, 139 insertions(+), 68 deletions(-) create mode 100644 assets/img/class/comment-icon.png create mode 100644 assets/img/class/like-check-icon.png create mode 100644 assets/img/class/like-icon.png create mode 100644 lib/core/components/resolve_problem_box.dart diff --git a/assets/img/class/comment-icon.png b/assets/img/class/comment-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..77c1e6b85bcc8049e846abe9328846ee9c568768 GIT binary patch literal 901 zcmV;01A6?4P)5$s zKq?4SU>geHkpdtUNUp%#K|7g|R?fFTe?iOc&Ob9dFM!VmEPC*1=D7~QJt?Rw zz)J$C^5qS0Z8Xpy$5E^8R=+$nYnvkSP7*U=RVipI#P7Ux3kV!-1M0H^{)uz%WBU8` z5r}$uLL%__qHmTiOR49sZiuLVcU>F8zYP5m9fI`7W-8BnoT5E|(f z9NvAs=oBW-kP^S6ria^RZ4L!6nRzWx*hPfuG4efP><@r`{_Mi3>;JEFmZA z3l#@fAn*1;(u1=2&36G^*|L;<*iq0k2U#QReUwxX-VNx%EM3VAdmk+gUDog| zTyP-WURRq?0;UUpW&%#EuEl|wSnN1(pK606C<~kk=F7D?5@OEHBp0_@zd%Wl^gG0% z(ht0hcK7r29EdD3#U|kZJGfL*ok}B(fn=(jNv{ksyWwOVJ{y!8rH*M;8V-0fA(qx= zKC6;iP!d8}Ca5e9%VJEUuL67BMoMXSy7b@V_rTtx>`fM4JHKbAkOOLEaYP6Lc&<1w z0I6JDB)Hd3z;K1Jd)~u}q zZW zO`V$pZP7D3YYs!P-bDw8H(xHsPyj5W!7`p8c>?-*dtKWLx(uP000~a1^@s6lq3|;00009a7bBm000XU z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yPi1_`k9qAa&|s3d%?v?`XWQ1fqPd;~XG8QC z6a=l22ZbeseqQ;9S1KmiIeHEFmDfo;2+Kn#B0}T6=t{9QOi{ly!>*`(O}Websbzd0-F(^0Xqp2$t;a&|SS)EN+ms<8hOdd+<;AM17V-(L6Sm`34x)f~uG3r#b)t002ov JPDHLkV1j2&*R=ou literal 0 HcmV?d00001 diff --git a/assets/img/class/like-icon.png b/assets/img/class/like-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e3fd7c92f4d4bf310abf0d11799ebfe36e7b625a GIT binary patch literal 744 zcmVP)=Tsi`x3lv(wCe7I6>PJ z(43$zCn%gC;iX*@+U&y(a83}f10F?#J%jDoVay9`q7Cve=*yBu8UQ|;AZ#JmlX=VY z#5YiM&W|xl9G-qY95u1g7|c*#N}TWy{gR>K>9OB;wIiURNC7`Blpr?i1kn3)|JZf4 z(+I3XjELQg6fG46BB3J-PpIc=s}cAh7hVN4z6gW(OBl@fF@19^hX38biG;S%C5Q+8 zsdLUBt<@q&!O>LH9OJ-f3#Fzj2XfAE6sE40oWZyM9|xwWbOm#mBdrrb#~M>`=V%VR zO&fGUNht;tTuk?9FUuZPFZz&y1&YlygpeSwkCUW3dC z-8p#G(a;{FSyeOI2{<3-y32tDALLq}OvmB&LU3*Y3T~>l6viUY)+bo^)0pV(K3pe= z_WB#0o%li3p27`;4|$*e6_^U-t8D$`aS@*1KkB}#x`Ftf#9!>KPp}=B9iBl#SLLSh avE>C`T<2hrrBv|%0000= AppAdapt.tabletBreakpoint; + + final bgUrl = ImgUrl.build( + isPad + ? '/StaticResource/2026-06-02/resolve-bg2-pad1780388446390.png' + : '/StaticResource/2026-05-07/resolve-bg2.png', + ); + final cloudUrl = ImgUrl.build( + isPad + ? '/StaticResource/2026-06-02/cloud-pad1780388443051.png' + : '/StaticResource/2026-05-07/cloud.png', + ); + + final cloudHeight = isPad ? 107.h : 74.h; + + return Container( + width: double.infinity, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.r), + image: DecorationImage( + image: CachedNetworkImageProvider(bgUrl), + fit: BoxFit.fill, + alignment: Alignment.topCenter, + ), + ), + // 裁剪所有子元素到圆角内(对标 Vue overflow:hidden) + clipBehavior: Clip.antiAlias, + child: Stack( + // Stack 默认不裁剪 Positioned 子元素,必须显式设置 + clipBehavior: Clip.hardEdge, + children: [ + // 底部云朵装饰(贴底部,z-index 1) + Positioned( + left: 0, + right: 0, + bottom: 0, + child: CachedNetworkImage( + imageUrl: cloudUrl, + height: cloudHeight, + width: double.infinity, + fit: BoxFit.fitWidth, + ), + ), + // 文本层(padding 在云朵之上,z-index 2) + Padding( + padding: EdgeInsets.fromLTRB(19.w, 25.h, 19.w, 11.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + title, + style: const TextStyle( + fontSize: 15, + fontWeight: FontWeight.w900, + color: Color(0xFF1D2B47), + ), + ), + SizedBox(height: 3.h), + Text.rich( + TextSpan( + children: [ + TextSpan( + text: '「$desc」', + style: const TextStyle( + fontSize: 13, + fontWeight: FontWeight.w500, + color: Color(0xFF1D2B47), + ), + ), + const TextSpan( + text: ' 的所有高难考点!', + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.w500, + color: Color(0xFF45597E), + ), + ), + ], + ), + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/features/class/widgets/class_update_widgets.dart b/lib/features/class/widgets/class_update_widgets.dart index 649c1cf..696fae0 100644 --- a/lib/features/class/widgets/class_update_widgets.dart +++ b/lib/features/class/widgets/class_update_widgets.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:new_learn/core/api/class/model.dart'; import 'package:new_learn/core/components/image_preview_viewer.dart'; +import 'package:new_learn/core/components/resolve_problem_box.dart'; import 'package:new_learn/core/components/user_circle_avatar.dart'; import 'package:new_learn/core/utils/img_url.dart'; @@ -12,7 +13,8 @@ import 'package:new_learn/core/utils/img_url.dart'; /// 【班级动态组件】由 class_update_view.dart 抽离的展示组件 /// /// PostCard(动态卡片,按 type 分发内容 + 相册 + 点赞评论栏) -/// CardHeader / SubjectTag / ResolveProblemBox / AlbumDesc / AlbumGrid +/// CardHeader / SubjectTag / AlbumDesc / AlbumGrid / LikeCommentBar / ... +/// ResolveProblemBox 已抽离到 core/components/resolve_problem_box.dart /// LikeCommentBar / MetaButton / CommentPreview / CommentInput /// /// 原为 class_update_view.dart 内的私有组件,重命名去下划线后放到本文件。 @@ -263,65 +265,6 @@ class SubjectTag extends StatelessWidget { } } -/// 攻克任务卡(对标 ResolveProblem) -class ResolveProblemBox extends StatelessWidget { - const ResolveProblemBox({super.key, required this.desc}); - - final String desc; - - @override - Widget build(BuildContext context) { - return Container( - width: double.infinity, - padding: EdgeInsets.fromLTRB(19.w, 25.h, 19.w, 11.h), - decoration: BoxDecoration( - gradient: const LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [Color(0xFFEAF4FF), Color(0xFFFFFFFF)], - ), - borderRadius: BorderRadius.circular(10.r), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text( - '刚刚攻克了', - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.w900, - color: Color(0xFF1D2B47), - ), - ), - SizedBox(height: 3.h), - Text.rich( - TextSpan( - children: [ - TextSpan( - text: '「$desc」', - style: const TextStyle( - fontSize: 13, - fontWeight: FontWeight.w500, - color: Color(0xFF1D2B47), - ), - ), - const TextSpan( - text: ' 的所有高难考点!', - style: TextStyle( - fontSize: 13, - fontWeight: FontWeight.w500, - color: Color(0xFF45597E), - ), - ), - ], - ), - ), - ], - ), - ); - } -} - /// 纯文字笔记(album-desc,最多 2 行) class AlbumDesc extends StatelessWidget { const AlbumDesc({super.key, required this.text}); @@ -441,15 +384,26 @@ class LikeCommentBar extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.end, children: [ MetaButton( - icon: post.userLikeStatus - ? Icons.favorite - : Icons.favorite_border, + icon: Image.asset( + post.userLikeStatus + ? 'assets/img/class/like-check-icon.png' + : 'assets/img/class/like-icon.png', + width: 13.w, + height: 13.w, + ), count: post.likeCount, active: post.userLikeStatus, onTap: onLike, ), SizedBox(width: 8.w), - MetaButton(icon: Icons.chat_bubble_outline, count: post.replyCount), + MetaButton( + icon: Image.asset( + 'assets/img/class/comment-icon.png', + width: 13.w, + height: 13.w, + ), + count: post.replyCount, + ), ], ), if (showComposer) ...[ @@ -474,7 +428,7 @@ class MetaButton extends StatelessWidget { this.onTap, }); - final IconData icon; + final Widget icon; final int count; final bool active; final VoidCallback? onTap; @@ -496,7 +450,7 @@ class MetaButton extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(icon, size: 13.w, color: color), + icon, SizedBox(width: 4.w), Text('$count', style: TextStyle(fontSize: 13, color: color)), ], diff --git a/pubspec.yaml b/pubspec.yaml index 5101c6e..292c5b5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: new_learn description: "A new Flutter project." # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev +publish_to: "none" # Remove this line if you wish to publish to pub.dev # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 @@ -222,7 +222,6 @@ dev_dependencies: # The following section is specific to Flutter packages. flutter: - # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. @@ -236,6 +235,7 @@ flutter: - assets/img/tabbar/ - assets/img/tabbar/default/ - assets/audio/ + - assets/img/class/ # To add assets to your application, add an assets section, like this: # assets: