feat: 新增全局确认弹窗、多页面UI优化与网络日志开关
1. 新增全局二次确认弹窗组件confirm_box,支持自定义参数并对标小程序实现
2. 优化班级板块多处UI:
- 修复point_rank_view中Web端字体溢出问题,使用FittedBox自适应缩放
- 重构class_update_widgets的PostCard,新增卡片背景控制开关并替换光晕实现
- 优化class_update_view的在线同学栏与头像组布局,支持动态计算展示数量
- 调整my_update_detail_page的评论区结构,修复评论高亮与删除浮层定位问题
3. 为dio_client新增网络日志总开关,可按需开启请求响应打印
4. 修复多处代码格式与注释细节问题
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
@@ -25,6 +27,7 @@ class PostCard extends StatelessWidget {
|
||||
required this.onLike,
|
||||
required this.onComment,
|
||||
this.showCommentComposer = true,
|
||||
this.hasCardBackground = true,
|
||||
});
|
||||
|
||||
final UserPostDto post;
|
||||
@@ -34,6 +37,9 @@ class PostCard extends StatelessWidget {
|
||||
/// 是否显示卡片内嵌的评论预览 + 输入框(列表页 true;详情页由全量留言接管)
|
||||
final bool showCommentComposer;
|
||||
|
||||
/// 是否显示白色卡片背景(列表页 true;详情页与留言区共用一张大卡片 → false)
|
||||
final bool hasCardBackground;
|
||||
|
||||
String get _avatar {
|
||||
final url = ImgUrl.build(post.avatar);
|
||||
return url.isEmpty
|
||||
@@ -54,6 +60,54 @@ class PostCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final card = Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: 85.h,
|
||||
child: IgnorePointer(
|
||||
// 卡片顶部右上角光晕,对标 Vue SubjectCard::before 的双层 radial-gradient
|
||||
child: CustomPaint(painter: _CardTopGlowPainter()),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 21.h),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
CardHeader(
|
||||
avatar: _avatar,
|
||||
name: _name,
|
||||
subject: _subject,
|
||||
time: _time,
|
||||
),
|
||||
if (post.type == 1) ...[
|
||||
SizedBox(height: 5.h),
|
||||
ResolveProblemBox(desc: post.content),
|
||||
],
|
||||
if (post.type == 2 || post.type == 3) ...[
|
||||
SizedBox(height: 15.h),
|
||||
AlbumDesc(text: post.content),
|
||||
],
|
||||
if (post.urls.isNotEmpty) ...[
|
||||
SizedBox(height: 15.h),
|
||||
AlbumGrid(urls: post.urls.map(ImgUrl.build).toList()),
|
||||
],
|
||||
SizedBox(height: 10.h),
|
||||
LikeCommentBar(
|
||||
post: post,
|
||||
onLike: onLike,
|
||||
onComment: onComment,
|
||||
showComposer: showCommentComposer,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
if (!hasCardBackground) return card;
|
||||
return Container(
|
||||
margin: EdgeInsets.only(bottom: 10.h),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
@@ -61,67 +115,65 @@ class PostCard extends StatelessWidget {
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(15.r),
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: 85.h,
|
||||
child: IgnorePointer(
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topRight,
|
||||
end: Alignment.bottomLeft,
|
||||
colors: [
|
||||
const Color(0xFFCEE9FF).withValues(alpha: 0.9),
|
||||
const Color(0xFFF6FBFF).withValues(alpha: 0.0),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 21.h),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
CardHeader(
|
||||
avatar: _avatar,
|
||||
name: _name,
|
||||
subject: _subject,
|
||||
time: _time,
|
||||
),
|
||||
if (post.type == 1) ...[
|
||||
SizedBox(height: 5.h),
|
||||
ResolveProblemBox(desc: post.content),
|
||||
],
|
||||
if (post.type == 2 || post.type == 3) ...[
|
||||
SizedBox(height: 15.h),
|
||||
AlbumDesc(text: post.content),
|
||||
],
|
||||
if (post.urls.isNotEmpty) ...[
|
||||
SizedBox(height: 15.h),
|
||||
AlbumGrid(urls: post.urls.map(ImgUrl.build).toList()),
|
||||
],
|
||||
SizedBox(height: 10.h),
|
||||
LikeCommentBar(
|
||||
post: post,
|
||||
onLike: onLike,
|
||||
onComment: onComment,
|
||||
showComposer: showCommentComposer,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: card,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 卡片顶部光晕:对标 Vue `SubjectCard::before` 的两层 radial-gradient
|
||||
/// (椭圆均以右上角为圆心,CSS 先写的在上层):
|
||||
/// radial-gradient(120% 85% at 100% 0%,
|
||||
/// rgba(206,233,255,1) 0%, rgba(206,233,255,.26) 10%, rgba(255,255,255,0) 58%)
|
||||
/// radial-gradient(75% 55% at 100% 0%,
|
||||
/// rgba(196,226,255,.88) 0%, rgba(255,255,255,1) 64%)
|
||||
class _CardTopGlowPainter extends CustomPainter {
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
// 先画下层(更小、偏白的光晕),再画上层(更大的浅蓝光晕)
|
||||
_paintGlow(
|
||||
canvas,
|
||||
size,
|
||||
rx: size.width * 0.75,
|
||||
ry: size.height * 0.55,
|
||||
colors: [const Color(0xFFC4E2FF).withValues(alpha: 0.88), Colors.white],
|
||||
stops: const [0, 0.64],
|
||||
);
|
||||
_paintGlow(
|
||||
canvas,
|
||||
size,
|
||||
rx: size.width * 1.20,
|
||||
ry: size.height * 0.85,
|
||||
colors: [
|
||||
const Color(0xFFCEE9FF),
|
||||
const Color(0xFFCEE9FF).withValues(alpha: 0.26),
|
||||
Colors.white.withValues(alpha: 0.0),
|
||||
],
|
||||
stops: const [0, 0.10, 0.58],
|
||||
);
|
||||
}
|
||||
|
||||
/// 用 canvas.scale 把圆形径向渐变拉成 CSS 的椭圆(圆心 = 右上角)
|
||||
void _paintGlow(
|
||||
Canvas canvas,
|
||||
Size size, {
|
||||
required double rx,
|
||||
required double ry,
|
||||
required List<Color> colors,
|
||||
required List<double> stops,
|
||||
}) {
|
||||
canvas.save();
|
||||
canvas.translate(size.width, 0);
|
||||
canvas.scale(rx, ry);
|
||||
final Paint paint = Paint()
|
||||
..shader = ui.Gradient.radial(Offset.zero, 1.0, colors, stops);
|
||||
canvas.drawRect(const Rect.fromLTWH(-1, 0, 1, 1), paint);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
|
||||
}
|
||||
|
||||
/// 卡片标题:头像 + 姓名 + 学科标签 + 时间
|
||||
class CardHeader extends StatelessWidget {
|
||||
const CardHeader({
|
||||
|
||||
Reference in New Issue
Block a user