提交 f50a125d authored 作者: maodou's avatar maodou

Merge remote-tracking branch 'origin/test' into test

...@@ -141,7 +141,7 @@ abstract class LibraryAPI { ...@@ -141,7 +141,7 @@ abstract class LibraryAPI {
return ReportModel.fromJson(result.data); return ReportModel.fromJson(result.data);
} }
/// 7、阅读页笔记列表 /// 7、阅读页 章节笔记列表
/// ///
static Future<List<NoteModel>> noteList( static Future<List<NoteModel>> noteList(
{int page = 1, {int page = 1,
...@@ -163,7 +163,7 @@ abstract class LibraryAPI { ...@@ -163,7 +163,7 @@ abstract class LibraryAPI {
}); });
} }
/// 8、笔记详情列表 /// 8、阅读页 章节讨论列表
/// ///
static Future<List<DiscussModel>> discussList( static Future<List<DiscussModel>> discussList(
{int page = 1, {int page = 1,
...@@ -185,5 +185,79 @@ abstract class LibraryAPI { ...@@ -185,5 +185,79 @@ abstract class LibraryAPI {
}); });
} }
/// 9、添加阅读时长
static Future <bool> addReadTime({
required String bookId,
required String readTypes
}) async {
final result = await HttpService.to.post(
'/v1/book/Information/addReadTime',
params: {
'book_id':bookId,
'read_types':readTypes
},
);
if (result.data is Map && result.data['is_success'] == 1){
return true;
}
return false;
}
/// 10、发布讨论回复
static Future <bool> addDiscuss({
required String bookId,
required String chapterId,
required String commentId,
required String quoteContent,
required String title,
required String content,
}) async {
final result = await HttpService.to.post(
'/v1/book/Information/addComment',
params: {
'book_id':bookId,
'chapter_id':chapterId,
'comment_id':commentId,
'quote_content':quoteContent,
'title':title,
'content':content
},
);
if (result.data is Map && result.data['is_success'] == 1){
return true;
}
return false;
}
/// 11、离线下载
static Future <BookDownloadModel> bookDownload({
required String bookId,
}) async {
final result = await HttpService.to.post(
'/v1/book/Information/bookDownload',
params: {
'book_id':bookId,
},
);
if (result.data is! Map) return BookDownloadModel();
return BookDownloadModel.fromJson(result.data);
}
/// 12、离线重连 上传笔记、高亮、划线
static Future <bool> uploadContent({
required String bookId,
required String readTypes
}) async {
final result = await HttpService.to.post(
'/v1/book/Information/addOfflineNotes',
params: {
'book_id':bookId,
},
);
if (result.data is Map && result.data['is_success'] == 1){
return true;
}
return false;
}
} }
\ No newline at end of file
...@@ -220,7 +220,9 @@ class BookDetailModel { ...@@ -220,7 +220,9 @@ class BookDetailModel {
this.pressName, this.pressName,
this.producersName, this.producersName,
this.chapterId, this.chapterId,
this.chapterName,}); this.chapterName,
this.readChapterId,
});
BookDetailModel.fromJson(dynamic json) { BookDetailModel.fromJson(dynamic json) {
bookId = json['book_id']; bookId = json['book_id'];
...@@ -246,6 +248,7 @@ class BookDetailModel { ...@@ -246,6 +248,7 @@ class BookDetailModel {
producersName = json['producers_name']; producersName = json['producers_name'];
chapterId = json['chapter_id']; chapterId = json['chapter_id'];
chapterName = json['chapter_name']; chapterName = json['chapter_name'];
readChapterId = json['read_chapter_id'];
} }
num? bookId; num? bookId;
String? bookName; String? bookName;
...@@ -270,6 +273,7 @@ class BookDetailModel { ...@@ -270,6 +273,7 @@ class BookDetailModel {
String? producersName; String? producersName;
num? chapterId; num? chapterId;
String? chapterName; String? chapterName;
num? readChapterId;
BookDetailModel copyWith({ num? bookId, BookDetailModel copyWith({ num? bookId,
String? bookName, String? bookName,
String? img, String? img,
...@@ -293,6 +297,7 @@ class BookDetailModel { ...@@ -293,6 +297,7 @@ class BookDetailModel {
String? producersName, String? producersName,
num? chapterId, num? chapterId,
String? chapterName, String? chapterName,
num? readChapterId,
}) => BookDetailModel( bookId: bookId ?? this.bookId, }) => BookDetailModel( bookId: bookId ?? this.bookId,
bookName: bookName ?? this.bookName, bookName: bookName ?? this.bookName,
img: img ?? this.img, img: img ?? this.img,
...@@ -316,6 +321,7 @@ class BookDetailModel { ...@@ -316,6 +321,7 @@ class BookDetailModel {
producersName: producersName ?? this.producersName, producersName: producersName ?? this.producersName,
chapterId: chapterId ?? this.chapterId, chapterId: chapterId ?? this.chapterId,
chapterName: chapterName ?? this.chapterName, chapterName: chapterName ?? this.chapterName,
readChapterId: readChapterId?? this.readChapterId,
); );
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final map = <String, dynamic>{}; final map = <String, dynamic>{};
...@@ -342,6 +348,7 @@ class BookDetailModel { ...@@ -342,6 +348,7 @@ class BookDetailModel {
map['producers_name'] = producersName; map['producers_name'] = producersName;
map['chapter_id'] = chapterId; map['chapter_id'] = chapterId;
map['chapter_name'] = chapterName; map['chapter_name'] = chapterName;
map['read_chapter_id'] = readChapterId;
return map; return map;
} }
...@@ -462,3 +469,29 @@ class ReportModel { ...@@ -462,3 +469,29 @@ class ReportModel {
} }
class BookDownloadModel {
BookDownloadModel({
this.bookIv,
this.download,});
BookDownloadModel.fromJson(dynamic json) {
bookIv = json['book_iv'];
download = json['download'];
}
String? bookIv;
String? download;
BookDownloadModel copyWith({ String? bookIv,
String? download,
}) => BookDownloadModel( bookIv: bookIv ?? this.bookIv,
download: download ?? this.download,
);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['book_iv'] = bookIv;
map['download'] = download;
return map;
}
}
library bai_ke;
import 'package:flutter/material.dart';
import 'package:flutter_book/utils/index.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
part 'view.dart';
\ No newline at end of file
part of bai_ke;
class BaiKePage extends StatefulWidget {
final String keyword;
const BaiKePage({
Key? key,
required this.keyword
}) : super(key: key);
@override
State<BaiKePage> createState() => _BaiKePageState();
}
class _BaiKePageState extends State<BaiKePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: false,
title: Text('${widget.keyword}百度百科',style: TextStyle(fontSize: 14.w,fontWeight: Fonts.medium,color: Colours.c3),),
),
body: InAppWebView(
initialUrlRequest: URLRequest(
url: Uri.parse('https://baike.baidu.com/item/${widget.keyword}?fromModule=lemma_search-box'),
),
),
);
}
}
...@@ -125,12 +125,16 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid ...@@ -125,12 +125,16 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid
Expanded( Expanded(
child: GestureDetector( child: GestureDetector(
onTap: () async{ onTap: () async{
// context.pushNamed(Routes.creditPoints).then((value){
// print('---------------------$value'); // 1免费 0 不免费
// }); if(controller.bookDetails.isFree == 1){
/// 没有购买并且没有试读直接跳转 购买页 context.pushNamed(Routes.web,queryParameters: {'book_id': controller.bookDetails.bookId.toString(),'chapter_id': controller.bookDetails.chapterId.toString(),'chapter_name':controller.bookDetails.chapterName.toString});
bool noTryRead = true; }
if(controller.bookDetails.isHave == 0 && noTryRead){ else {
// 没有购买
if (controller.bookDetails.isHave ==0){
// 没有试读
if (controller.bookDetails.readChapterId ==0){
List<CourseModel> buy = []; List<CourseModel> buy = [];
CourseModel model= CourseModel( CourseModel model= CourseModel(
bookId: controller.bookDetails.bookId, bookId: controller.bookDetails.bookId,
...@@ -149,8 +153,13 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid ...@@ -149,8 +153,13 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid
controller.getBookDetails(); controller.getBookDetails();
} }
} }
else { else{
context.pushNamed(Routes.web); context.pushNamed(Routes.web,queryParameters: {'book_id': controller.bookDetails.bookId.toString(),'chapter_id': controller.bookDetails.chapterId.toString(),'chapter_name':controller.bookDetails.chapterName.toString()});
}
}
else{
context.pushNamed(Routes.web,queryParameters: {'book_id': controller.bookDetails.bookId.toString(),'chapter_id': controller.bookDetails.chapterId.toString(),'chapter_name':controller.bookDetails.chapterName.toString()});
}
} }
}, },
child: Container( child: Container(
......
...@@ -23,7 +23,7 @@ class _HomePageState extends State<HomePage> { ...@@ -23,7 +23,7 @@ class _HomePageState extends State<HomePage> {
}, },
child: Container( child: Container(
color: Colors.cyan, color: Colors.cyan,
child: Text('web'), child: Text('read_web'),
height: 40, height: 40,
// width: double.infinity, // width: double.infinity,
alignment: Alignment.center, alignment: Alignment.center,
......
...@@ -203,18 +203,18 @@ class _LoginPageState extends State<LoginPage> { ...@@ -203,18 +203,18 @@ class _LoginPageState extends State<LoginPage> {
), ),
), ),
Gaps.hGaps5, Gaps.hGaps5,
Text('我已阅读并同意',style: TextStyle(color: Colours.c9,fontSize:10.w)), Text('我已阅读并同意',style: TextStyle(color: Colours.c9,fontSize:10.w,height: 1.4)),
], ],
), ),
), ),
GestureDetector( GestureDetector(
child: Text('《用户协议》',style: TextStyle(color: Colours.cBlue,fontSize:10.w)), child: Text('《用户协议》',style: TextStyle(color: Colours.cBlue,fontSize:10.w,height: 1.4)),
onTap: (){ onTap: (){
context.pushNamed(Routes.terms); context.pushNamed(Routes.terms);
}, },
), ),
GestureDetector( GestureDetector(
child: Text('《隐私政策》',style: TextStyle(color: Colours.cBlue,fontSize:10.w)), child: Text('《隐私政策》',style: TextStyle(color: Colours.cBlue,fontSize:10.w,height: 1.4)),
onTap: (){ onTap: (){
context.pushNamed(Routes.terms); context.pushNamed(Routes.terms);
}, },
......
...@@ -11,7 +11,6 @@ import '../../routes/index.dart'; ...@@ -11,7 +11,6 @@ import '../../routes/index.dart';
import '../../store/index.dart'; import '../../store/index.dart';
import '../book_shop/index.dart'; import '../book_shop/index.dart';
import '../course/index.dart'; import '../course/index.dart';
import '../web/index.dart';
......
...@@ -2,6 +2,11 @@ part of web; ...@@ -2,6 +2,11 @@ part of web;
class ReadController extends FullLifeCycleController with GetSingleTickerProviderStateMixin{ class ReadController extends FullLifeCycleController with GetSingleTickerProviderStateMixin{
final String bookId;
final String chapterId;
final String chapterName;
ReadController({required this.bookId, required this.chapterId,required this.chapterName});
// 目录 // 目录
List <ChapterModel> chapters = []; List <ChapterModel> chapters = [];
List <ToolModel> tools = [ List <ToolModel> tools = [
...@@ -12,11 +17,6 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide ...@@ -12,11 +17,6 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
late ToolModel toolModel = tools.first; late ToolModel toolModel = tools.first;
// late final PageController pageController;
//
// //默认显示
// int currentPage = 1;
bool showChat = false; bool showChat = false;
final FocusNode discussTitleFocusNode = FocusNode(); final FocusNode discussTitleFocusNode = FocusNode();
...@@ -24,8 +24,54 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide ...@@ -24,8 +24,54 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
late AnimationController _controller; late AnimationController _controller;
bool _show = true; bool _show = true;
bool get show => _show; bool get show => _show;
// 讨论添加的图片数组
List <String> discussInputImages= [];
// 讨论话题标题
final TextEditingController titleInput = TextEditingController();
// 讨论内容
final TextEditingController contentInput = TextEditingController();
//
///------------------------------------------ 页面 生命周期--------------------------------------------------------
@override
void onInit() {
// pageController = PageController(initialPage: currentPage);
discussTitleFocusNode.addListener(_onCommentFocusChanged);
/// 默认不显示状态栏
// SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
/// 初始化
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 100),
);
super.onInit();
}
@override
void onReady() {
// 上报开始阅读时间
print('000000000000000000000--------------------------------$bookId');
_addReadTime(type: 'open');
_getChapters();
super.onReady();
}
@override
void onClose() {
// 上报阅读结束时间
_addReadTime(type: 'close');
_controller.dispose();
discussTitleFocusNode.removeListener(_onCommentFocusChanged);
discussTitleFocusNode.dispose();
titleInput.dispose();
contentInput.dispose();
super.onClose();
}
///------------------------------------------ 页面 生命周期--------------------------------------------------------
void setShow(bool value) { void setShow(bool value) {
_show = !value; _show = !value;
if (_show) { if (_show) {
...@@ -43,6 +89,77 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide ...@@ -43,6 +89,77 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
update(); update();
} }
// 添加讨论图片
void addDiscussInputImages(String path){
discussInputImages.add(path);
print('discussInputImages--------------------------------$path');
update();
}
// 删除讨论图片
void delDiscussInputImages(String path){
discussInputImages.remove(path);
print('delDiscussInputImages--------------------------------$path');
update();
}
// 清空讨论图片
void clearDiscussInputImages(){
discussInputImages.clear();
print('clearDiscussInputImages--------------------------------');
update();
}
// 上传文件
Future<String> upload({
required String path
}) async {
String result = await CommonAPI.upload(path:path,fileTypes: 'comment');
return result;
}
// 发表评论
// {String commentId ='0',String quoteContent ='',String title = ''}
Future<bool> addDiscuss() async{
// 音频链接数组
List<String> audios = [];
// 图片链接数组
List<String> images = [];
// 循环上传图片获取地址
for(String path in discussInputImages){
final url = await upload(path: path);
images.add(url);
}
Map<String,dynamic> contentMap = {
'text':contentInput.text,
'audio':audios,
'image':images
};
final result = await LibraryAPI.addDiscuss(
bookId: bookId,
chapterId: chapterId,
commentId: '0',
quoteContent: '',
title: titleInput.text,
content: jsonEncode(contentMap)
);
if(result){
Toast.show('话题发表成功');
}
else{
Toast.show('话题发表失败');
}
titleInput.text = '';
contentInput.text = '';
setShowChat(false);
return result;
}
void chooseTool(ToolModel selectedModel){ void chooseTool(ToolModel selectedModel){
for (var model in tools) { for (var model in tools) {
...@@ -75,60 +192,51 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide ...@@ -75,60 +192,51 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
update(); update();
} }
@override
void onInit() {
// pageController = PageController(initialPage: currentPage);
discussTitleFocusNode.addListener(_onCommentFocusChanged);
/// 默认不显示状态栏
// SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
/// 初始化
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 100),
);
super.onInit();
}
@override
void onReady() {
_getChapters();
super.onReady();
}
@override /// 获取目录信息
void onClose() { void _getChapters() async {
_controller.dispose(); chapters = await LibraryAPI.chapters(bookId: bookId);
discussTitleFocusNode.removeListener(_onCommentFocusChanged); update();
discussTitleFocusNode.dispose();
super.onClose();
} }
/// 添加阅读时长
void onPageChanged(int page) { void _addReadTime({required type}) async{
// currentPage = page; final result = await LibraryAPI.addReadTime(bookId: bookId, readTypes: type);
update(['navigation']);
} }
///------------------------------------------ app 生命周期--------------------------------------------------------
// 当应用程序从后台切换到前台并变为活动状态时调用。这通常在用户从其他应用程序返回到你的应用程序时发生
void onResumed(){ void onResumed(){
print('onResumed'); print('onResumed');
// open
// 上报开始阅读时间
_addReadTime(type: 'open');
} }
// 当应用程序失去焦点并进入非活动状态时调用。这可能是因为用户切换到其他应用程序或将应用程序最小化
void onPaused(){ void onPaused(){
// close
print('onPaused'); print('onPaused');
// 上报阅读结束时间
_addReadTime(type: 'close');
} }
// 当应用程序失去焦点但仍然可见时调用。通常,在用户切换到另一个应用程序或显示系统对话框时,应用程序可能会处于非活动状态,但仍然是可见的
void onInactive(){ void onInactive(){
print('onInactive'); print('onInactive');
// close
// 上报阅读结束时间
_addReadTime(type: 'close');
} }
// 当应用程序被挂起,可能是由于用户关闭应用程序或系统资源不足时调用。在这个状态下,应用程序的代码将不再运行,并且可能被系统终止
void onDetached(){ void onDetached(){
print('onDetached'); print('onDetached');
// close
// 上报阅读结束时间
_addReadTime(type: 'close');
} }
///------------------------------------------ app 生命周期--------------------------------------------------------
/// 获取目录信息
void _getChapters() async {
chapters = await LibraryAPI.chapters(bookId: '110');
update();
}
} }
class ToolModel { class ToolModel {
......
library web; library web;
import 'dart:convert';
import 'package:easy_refresh/easy_refresh.dart'; import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
...@@ -9,9 +11,12 @@ import 'package:flutter_inappwebview/flutter_inappwebview.dart'; ...@@ -9,9 +11,12 @@ import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_book/utils/index.dart'; import 'package:flutter_book/utils/index.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:go_router/go_router.dart';
import '../../apis/index.dart'; import '../../apis/index.dart';
import '../../models/index.dart'; import '../../models/index.dart';
import '../../routes/index.dart';
import '../../store/index.dart';
import '../../widgets/index.dart'; import '../../widgets/index.dart';
import '../book_category/index.dart'; import '../book_category/index.dart';
import '../user_discuss_des/index.dart'; import '../user_discuss_des/index.dart';
......
part of web; part of web;
final GlobalKey _chatContainerKey = GlobalKey();
class ReadPage extends StatefulWidget { class ReadPage extends StatefulWidget {
const ReadPage({Key? key}) : super(key: key); final String bookId;
final String chapterId;
final String chapterName;
const ReadPage({
Key? key,
required this.bookId,
required this.chapterId,
required this.chapterName,
}) : super(key: key);
@override @override
State<ReadPage> createState() => _ReadPageState(); State<ReadPage> createState() => _ReadPageState();
...@@ -11,19 +17,21 @@ class ReadPage extends StatefulWidget { ...@@ -11,19 +17,21 @@ class ReadPage extends StatefulWidget {
class _ReadPageState extends State<ReadPage> { class _ReadPageState extends State<ReadPage> {
int currentIndex = 0;
final GlobalKey webViewKey = GlobalKey();
InAppWebViewController? webViewController;
late ContextMenu contextMenu;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
print('+++++++++++++++++++++++${widget.bookId}');
return GetBuilder<ReadController>( return GetBuilder<ReadController>(
init: ReadController(), init: ReadController(bookId: widget.bookId, chapterId: widget.chapterId,chapterName: widget.chapterName),
builder: (readController) => Scaffold( builder: (readController) => Scaffold(
appBar: AppBar(
title: Text(widget.chapterName),
centerTitle: false,
),
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
floatingActionButton: readController.show?GestureDetector( floatingActionButton: readController.show?GestureDetector(
onTap: (){ onTap: (){
...@@ -45,36 +53,76 @@ class _ReadPageState extends State<ReadPage> { ...@@ -45,36 +53,76 @@ class _ReadPageState extends State<ReadPage> {
), ),
InAppWebView( InAppWebView(
initialUrlRequest: URLRequest( initialUrlRequest: URLRequest(
url: Uri.parse('http://192.168.11.39:5500/'), url: Uri.parse('http://192.168.11.46:9200/read.html'),
), ),
onWebViewCreated: (InAppWebViewController controller) { onWebViewCreated: (InAppWebViewController controller) {
webViewController = controller;
}, },
contextMenu: ContextMenu(
options: ContextMenuOptions(hideDefaultSystemContextMenuItems: true),
),
// onLoadStart: (InAppWebViewController controller, Uri? url) async {
//
// },
// onConsoleMessage: (controller, consoleMessage) {
// print("Received message from WebView: ${consoleMessage.message}");
// },
onLoadStop: (controller, url) { onLoadStop: (controller, url) {
controller.addJavaScriptHandler(handlerName: 'onTap', callback: (args){
readController.setShow(readController.show);
}); // flutter 主动给 js 传参数
Map<String, dynamic> param = {
'book_id': 110,
'chapter_id': 1,
'token':UserStore.to.token
};
controller.evaluateJavascript(source: 'callbackInFlutterComponent("$param");');
// 添加单击事件
controller.evaluateJavascript(source: ''' controller.evaluateJavascript(source: '''
document.addEventListener('click', function() { document.addEventListener('click', function() {
window.flutter_inappwebview.callHandler('onTap'); window.flutter_inappwebview.callHandler('onTap');
}); });
'''); ''');
// 监听js单击回调
controller.addJavaScriptHandler(handlerName: 'onTap', callback: (args){
readController.setShow(readController.show);
});
// 监听笔记回调
controller.addJavaScriptHandler(handlerName: 'noteCallBack', callback: (args){
print('----------------------noteCallBack--------------------------$args');
});
// 监听百科回调
controller.addJavaScriptHandler(handlerName: 'baikeCallBack', callback: (args){
print('----------------------baikeCallBack--------------------------$args');
context.pushNamed(Routes.baiKe,queryParameters: {'keyword':args});
});
// 监听讨论回调
controller.addJavaScriptHandler(handlerName: 'discussCallBack', callback: (args){
print('----------------------discussCallBack--------------------------$args');
});
}, },
), ),
AnimatedPositioned( // AnimatedPositioned(
duration: readController.controller.duration!, // duration: readController.controller.duration!,
curve: Curves.easeInOut, // curve: Curves.easeInOut,
top: readController.show ? 0 : -100, // 负值隐藏,0 显示 // top: readController.show ? 0 : -100, // 负值隐藏,0 显示
left: 0, // left: 0,
right: 0, // right: 0,
height: 100, // height: 100,
child: Container( // child: Container(
color: Colors.limeAccent, // color: Colors.limeAccent,
alignment: Alignment.center, // alignment: Alignment.center,
child: Text('top View'), // child: Text('top View'),
), // ),
), // ),
Positioned( Positioned(
left: 0, left: 0,
right: 0, right: 0,
......
...@@ -15,6 +15,7 @@ class _ReadInputDiscussState extends State<ReadInputDiscuss> { ...@@ -15,6 +15,7 @@ class _ReadInputDiscussState extends State<ReadInputDiscuss> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
color: Colors.green,
margin: EdgeInsets.symmetric(horizontal: 15.w), margin: EdgeInsets.symmetric(horizontal: 15.w),
child: Column( child: Column(
children: [ children: [
...@@ -29,6 +30,7 @@ class _ReadInputDiscussState extends State<ReadInputDiscuss> { ...@@ -29,6 +30,7 @@ class _ReadInputDiscussState extends State<ReadInputDiscuss> {
borderRadius: BorderRadius.circular(4), borderRadius: BorderRadius.circular(4),
child: TextField( child: TextField(
focusNode: widget.controller.discussTitleFocusNode, focusNode: widget.controller.discussTitleFocusNode,
controller: widget.controller.titleInput,
autofocus: true, autofocus: true,
decoration: InputDecoration( decoration: InputDecoration(
border: InputBorder.none, border: InputBorder.none,
...@@ -57,6 +59,7 @@ class _ReadInputDiscussState extends State<ReadInputDiscuss> { ...@@ -57,6 +59,7 @@ class _ReadInputDiscussState extends State<ReadInputDiscuss> {
TextField( TextField(
focusNode: widget.controller.discussContentFocusNode, focusNode: widget.controller.discussContentFocusNode,
maxLines: null, maxLines: null,
controller: widget.controller.contentInput,
decoration: InputDecoration( decoration: InputDecoration(
border: InputBorder.none, border: InputBorder.none,
enabledBorder: InputBorder.none, enabledBorder: InputBorder.none,
...@@ -83,12 +86,29 @@ class _ReadInputDiscussState extends State<ReadInputDiscuss> { ...@@ -83,12 +86,29 @@ class _ReadInputDiscussState extends State<ReadInputDiscuss> {
childAspectRatio: 1 childAspectRatio: 1
), ),
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return Container( return Stack(
color: Colors.red, children: [
child: Center(child: Text('图片')), Positioned(
left:0,
right: 0,
top:0,
bottom: 0,
child: CustomImage.file(url:widget.controller.discussInputImages[index])
),
Positioned(
right: 5.w,
top: 5.w,
child: GestureDetector(
onTap: (){
widget.controller.delDiscussInputImages(widget.controller.discussInputImages[index]);
},
child: Image.asset('assets/images/del_close.png',width: 12.w,height: 12.w,)
)
)
],
); );
}, },
itemCount: 0, itemCount: widget.controller.discussInputImages.length,
), ),
), ),
Container( Container(
...@@ -131,19 +151,35 @@ class _ReadInputDiscussState extends State<ReadInputDiscuss> { ...@@ -131,19 +151,35 @@ class _ReadInputDiscussState extends State<ReadInputDiscuss> {
), ),
), ),
), ),
Row( Container(
padding: EdgeInsets.symmetric(vertical: 10.w),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Row( Row(
children: [ children: [
Image.asset('assets/images/read_add_img.png'), GestureDetector(
onTap: () async{
final assets = await AssetsPicker.image(
context: context,
);
widget.controller.addDiscussInputImages(assets!.path);
},
child: Image.asset('assets/images/read_add_img.png')),
Gaps.hGaps10, Gaps.hGaps10,
Image.asset('assets/images/read_add_audio.png'), GestureDetector(
onTap: () async {
},
child: Image.asset('assets/images/read_add_audio.png')
),
], ],
), ),
GestureDetector( GestureDetector(
onTap: (){}, onTap: (){
widget.controller.addDiscuss();
},
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.w), borderRadius: BorderRadius.circular(15.w),
...@@ -159,6 +195,7 @@ class _ReadInputDiscussState extends State<ReadInputDiscuss> { ...@@ -159,6 +195,7 @@ class _ReadInputDiscussState extends State<ReadInputDiscuss> {
), ),
) )
], ],
),
) )
], ],
) )
......
...@@ -60,7 +60,7 @@ class BuildCard extends StatelessWidget { ...@@ -60,7 +60,7 @@ class BuildCard extends StatelessWidget {
Container( Container(
height: 120.w, height: 120.w,
width: 100.w, width: 100.w,
child: CustomImage.asset(url: model.img??''), child: CustomImage.network(url: model.img??''),
) )
], ],
), ),
......
...@@ -40,14 +40,15 @@ import 'package:flutter_book/pages/user_security/index.dart'; ...@@ -40,14 +40,15 @@ import 'package:flutter_book/pages/user_security/index.dart';
import 'package:flutter_book/pages/user_set/index.dart'; import 'package:flutter_book/pages/user_set/index.dart';
import 'package:flutter_book/pages/user_wrong/index.dart'; import 'package:flutter_book/pages/user_wrong/index.dart';
import 'package:flutter_book/pages/version_des/index.dart'; import 'package:flutter_book/pages/version_des/index.dart';
import 'package:flutter_book/pages/web/index.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import '../models/index.dart'; import '../models/index.dart';
import '../pages/bai_ke/index.dart';
import '../pages/read_web/index.dart';
import '../pages/user_order/index.dart';
import '../pages/user_order_evaluate/index.dart'; import '../pages/user_order_evaluate/index.dart';
import '../pages/pay_coupon/index.dart'; import '../pages/pay_coupon/index.dart';
import '../pages/user_about/index.dart'; import '../pages/user_about/index.dart';
import '../pages/user_order/index.dart';
import '../pages/user_terms/index.dart'; import '../pages/user_terms/index.dart';
import '../pages/version/index.dart'; import '../pages/version/index.dart';
import '../store/index.dart'; import '../store/index.dart';
......
...@@ -8,7 +8,7 @@ abstract class Routes { ...@@ -8,7 +8,7 @@ abstract class Routes {
static const main = 'main'; static const main = 'main';
static const ad = 'ad'; static const ad = 'ad';
static const web = 'web'; static const web = 'read_web';
// 支付界面 // 支付界面
static const bookPay = 'book_pay'; static const bookPay = 'book_pay';
...@@ -37,6 +37,8 @@ abstract class Routes { ...@@ -37,6 +37,8 @@ abstract class Routes {
/// 图书馆模块 /// 图书馆模块
// 百科
static const baiKe = 'bai_ke';
/// 书架模块 /// 书架模块
...@@ -181,7 +183,11 @@ abstract class Routes { ...@@ -181,7 +183,11 @@ abstract class Routes {
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) =>CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const ReadPage() child: ReadPage(
bookId: state.uri.queryParameters['book_id'].toString(),
chapterId: state.uri.queryParameters['chapter_id'].toString(),
chapterName: state.uri.queryParameters['chapter_name'].toString(),
)
) )
), ),
GoRoute( GoRoute(
...@@ -534,6 +540,17 @@ abstract class Routes { ...@@ -534,6 +540,17 @@ abstract class Routes {
child: UserOrderRefundedPage(orderNum: state.uri.queryParameters['orderNum'].toString()) child: UserOrderRefundedPage(orderNum: state.uri.queryParameters['orderNum'].toString())
) )
), ),
GoRoute( // 百科
path: '/$baiKe',
name: baiKe,
pageBuilder: (context, state) =>CupertinoPage(
name: state.uri.toString(),
key: state.pageKey,
child: BaiKePage(
keyword: state.uri.queryParameters['keyword'].toString(),
)
)
),
] ]
); );
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论