feat: 新增过渡页面路由、上传组件及完善跳转逻辑

- 为conquerPackage模块添加过渡页面路由并实现页面跳转逻辑
- 新增通用多图上传组件Upload,支持多种模式与图片操作功能
- 新增任务相关的API及Model基础文件
- 注释课前课中页面的测试试题内容
This commit is contained in:
chenshuainan
2026-09-14 09:09:25 +08:00
parent fe86b6d824
commit 847986f861
8 changed files with 853 additions and 4 deletions
+38 -2
View File
@@ -1,4 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
import 'package:new_learn/core/components/audio_player_card.dart';
import 'package:new_learn/core/components/video_player_view.dart';
@@ -79,13 +81,47 @@ class RichTextContent extends StatelessWidget {
textStyle: textStyle,
onTapUrl: onTapUrl ?? _defaultOnTapUrl,
customStylesBuilder: customStylesBuilder,
customWidgetBuilder: _combinedCustomWidget,
customWidgetBuilder: _combinedCustomWidget(context),
renderMode: renderMode,
);
}
/// 合并默认替换 + 用户自定义替换
CustomWidgetBuilder get _combinedCustomWidget => (element) {
CustomWidgetBuilder _combinedCustomWidget(BuildContext context) => (element) {
// 内置:<img src="*.svg"> → flutter_svg 行内渲染
// core 版 flutter_widget_from_html 不支持 SVG,手动处理
if (element.localName == 'img') {
final src = element.attributes['src'];
if (src != null && src.toLowerCase().endsWith('.svg')) {
final width = double.tryParse(element.attributes['width'] ?? '');
final height = double.tryParse(element.attributes['height'] ?? '');
final w = width != null ? width.w : null;
final h = height != null ? height.h : null;
// 超采样(SSAA):SVG 以 3 倍尺寸光栅化再缩回来,消除真机边缘锯齿
const scale = 3.0;
return InlineCustomWidget(
child: SizedBox(
width: w,
height: h,
child: OverflowBox(
maxWidth: w != null ? w * scale : double.infinity,
maxHeight: h != null ? h * scale : double.infinity,
child: Transform.scale(
scale: 1 / scale,
alignment: Alignment.center,
child: SvgPicture.network(
src,
width: w != null ? w * scale : null,
height: h != null ? h * scale : null,
fit: BoxFit.contain,
clipBehavior: Clip.antiAlias,
),
),
),
),
);
}
}
// 内置:<audio> → 本项目 AudioPlayerCard
if (element.localName == 'audio') {
final src = element.attributes['src'];