提交 6b193aa0 authored 作者: yueweilu's avatar yueweilu

图书详情界面 接口调试与数据绑定

上级 811b4ba5
...@@ -69,5 +69,37 @@ abstract class LibraryAPI { ...@@ -69,5 +69,37 @@ abstract class LibraryAPI {
}); });
} }
/// 5、获取书籍目录
///
static Future <List<ChapterModel>> chapters({
required String bookId
}) async {
final result = await HttpService.to.post(
'/v1/book/Information/getBookChapter',
params: {
'book_id':bookId
},
);
if (result.data is! Map && result.data['list'] is! List) return [];
return List.generate(result.data['list'].length, (index){
return ChapterModel.fromJson(result.data['list'][index]);
});
}
/// 6、获取书籍详情
///
static Future <BookDetailModel> details({
required String bookId
}) async {
final result = await HttpService.to.post(
'/v1/book/Information/getBookInformation',
params: {
'book_id':bookId
},
);
if (result.data is! Map) return BookDetailModel();
return BookDetailModel.fromJson(result.data);
}
} }
\ No newline at end of file
part of models; part of models;
/// 1、图书分类模型 /// 1、----------------------------图书分类模型----------------------------
/// ///
class CategoryModel { class CategoryModel {
CategoryModel({ CategoryModel({
...@@ -27,7 +27,7 @@ class CategoryModel { ...@@ -27,7 +27,7 @@ class CategoryModel {
} }
/// 2、图书标签模型 /// 2、----------------------------图书标签模型----------------------------
/// ///
class LabelModel { class LabelModel {
LabelModel({ LabelModel({
...@@ -55,15 +55,8 @@ class LabelModel { ...@@ -55,15 +55,8 @@ class LabelModel {
} }
/// 3、书籍评价模型 /// 3、----------------------------书籍评价模型----------------------------
/// ///
/// book_comment_id : 4
/// comments : "bbbbbbb"
/// rating : 4.5
/// create_time : "2021-09-01 18:38:27"
/// members_id : 385
/// users : "王多余5"
/// users_img : ""
class ScoreModel { class ScoreModel {
ScoreModel({ ScoreModel({
...@@ -121,4 +114,228 @@ class ScoreModel { ...@@ -121,4 +114,228 @@ class ScoreModel {
} }
/// 4、----------------------------章节模型----------------------------
///
class ChapterModel {
ChapterModel({
this.id,
this.name,
this.pid,
this.bookId,
this.isReading,
this.sort,
this.seen,
this.children
});
ChapterModel.fromJson(dynamic json) {
id = json['id'];
name = json['name'];
pid = json['pid'];
bookId = json['book_id'];
isReading = json['is_reading'];
sort = json['sort'];
seen = json['seen'];
if (json['children'] != null) {
children = [];
json['children'].forEach((v) {
children?.add(ChapterModel.fromJson(v));
});
}
}
num? id;
String? name;
num? pid;
num? bookId;
num? isReading;
num? sort;
num? seen;
List<ChapterModel>? children;
ChapterModel copyWith({ num? id,
String? name,
num? pid,
num? bookId,
num? isReading,
num? sort,
num? seen,
List<ChapterModel>? children,
}) => ChapterModel( id: id ?? this.id,
name: name ?? this.name,
pid: pid ?? this.pid,
bookId: bookId ?? this.bookId,
isReading: isReading ?? this.isReading,
sort: sort ?? this.sort,
seen: seen ?? this.seen,
children: children ?? this.children,
);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['name'] = name;
map['pid'] = pid;
map['book_id'] = bookId;
map['is_reading'] = isReading;
map['sort'] = sort;
map['seen'] = seen;
if (children != null) {
map['children'] = children?.map((v) => v.toJson()).toList();
}
return map;
}
}
/// 5、----------------------------图书详细模型----------------------------
///
class BookDetailModel {
BookDetailModel({
this.bookId,
this.bookName,
this.img,
this.price,
this.vipPrice,
this.rating,
this.readNum,
this.content,
this.isFree,
this.authors,
this.onsaleTime,
this.categoryId,
this.pressId,
this.producersId,
this.isHave,
this.isCollection,
this.ratingCount,
this.ratingList,
this.categoryName,
this.pressName,
this.producersName,
this.chapterId,
this.chapterName,});
BookDetailModel.fromJson(dynamic json) {
bookId = json['book_id'];
bookName = json['book_name'];
img = json['img'];
price = json['price'];
vipPrice = json['vip_price'];
rating = json['rating'];
readNum = json['read_num'];
content = json['content'];
isFree = json['is_free'];
authors = json['authors'];
onsaleTime = json['onsale_time'];
categoryId = json['category_id'];
pressId = json['press_id'];
producersId = json['producers_id'];
isHave = json['is_have'];
isCollection = json['is_collection'];
ratingCount = json['rating_count'];
ratingList = json['rating_list'] != null ? json['rating_list'].cast<num>() : [];
categoryName = json['category_name'];
pressName = json['press_name'];
producersName = json['producers_name'];
chapterId = json['chapter_id'];
chapterName = json['chapter_name'];
}
num? bookId;
String? bookName;
String? img;
String? price;
String? vipPrice;
String? rating;
num? readNum;
String? content;
num? isFree;
String? authors;
num? onsaleTime;
num? categoryId;
num? pressId;
num? producersId;
num? isHave;
num? isCollection;
num? ratingCount;
List<num>? ratingList;
String? categoryName;
String? pressName;
String? producersName;
num? chapterId;
String? chapterName;
BookDetailModel copyWith({ num? bookId,
String? bookName,
String? img,
String? price,
String? vipPrice,
String? rating,
num? readNum,
String? content,
num? isFree,
String? authors,
num? onsaleTime,
num? categoryId,
num? pressId,
num? producersId,
num? isHave,
num? isCollection,
num? ratingCount,
List<num>? ratingList,
String? categoryName,
String? pressName,
String? producersName,
num? chapterId,
String? chapterName,
}) => BookDetailModel( bookId: bookId ?? this.bookId,
bookName: bookName ?? this.bookName,
img: img ?? this.img,
price: price ?? this.price,
vipPrice: vipPrice ?? this.vipPrice,
rating: rating ?? this.rating,
readNum: readNum ?? this.readNum,
content: content ?? this.content,
isFree: isFree ?? this.isFree,
authors: authors ?? this.authors,
onsaleTime: onsaleTime ?? this.onsaleTime,
categoryId: categoryId ?? this.categoryId,
pressId: pressId ?? this.pressId,
producersId: producersId ?? this.producersId,
isHave: isHave ?? this.isHave,
isCollection: isCollection ?? this.isCollection,
ratingCount: ratingCount ?? this.ratingCount,
ratingList: ratingList ?? this.ratingList,
categoryName: categoryName ?? this.categoryName,
pressName: pressName ?? this.pressName,
producersName: producersName ?? this.producersName,
chapterId: chapterId ?? this.chapterId,
chapterName: chapterName ?? this.chapterName,
);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['book_id'] = bookId;
map['book_name'] = bookName;
map['img'] = img;
map['price'] = price;
map['vip_price'] = vipPrice;
map['rating'] = rating;
map['read_num'] = readNum;
map['content'] = content;
map['is_free'] = isFree;
map['authors'] = authors;
map['onsale_time'] = onsaleTime;
map['category_id'] = categoryId;
map['press_id'] = pressId;
map['producers_id'] = producersId;
map['is_have'] = isHave;
map['is_collection'] = isCollection;
map['rating_count'] = ratingCount;
map['rating_list'] = ratingList;
map['category_name'] = categoryName;
map['press_name'] = pressName;
map['producers_name'] = producersName;
map['chapter_id'] = chapterId;
map['chapter_name'] = chapterName;
return map;
}
}
...@@ -3,5 +3,7 @@ library book_category; ...@@ -3,5 +3,7 @@ library book_category;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_book/utils/index.dart'; import 'package:flutter_book/utils/index.dart';
import '../../models/index.dart';
part 'view.dart'; part 'view.dart';
part 'widgets/item.dart'; part 'widgets/item.dart';
\ No newline at end of file
...@@ -2,7 +2,11 @@ part of book_category; ...@@ -2,7 +2,11 @@ part of book_category;
class BookCategoryPage extends StatefulWidget { class BookCategoryPage extends StatefulWidget {
const BookCategoryPage({Key? key}) : super(key: key); final List <ChapterModel> chapters;
const BookCategoryPage({
Key? key,
required this.chapters
}) : super(key: key);
@override @override
State<BookCategoryPage> createState() => _BookCategoryPageState(); State<BookCategoryPage> createState() => _BookCategoryPageState();
...@@ -16,9 +20,9 @@ class _BookCategoryPageState extends State<BookCategoryPage> { ...@@ -16,9 +20,9 @@ class _BookCategoryPageState extends State<BookCategoryPage> {
Expanded( Expanded(
child: ListView.builder( child: ListView.builder(
itemBuilder:(BuildContext context, int index){ itemBuilder:(BuildContext context, int index){
return BuildItem(); return BuildItem(model: widget.chapters[index],);
}, },
itemCount: 6, itemCount: widget.chapters.length,
), ),
), ),
], ],
......
part of book_category; part of book_category;
class BuildItem extends StatefulWidget { class BuildItem extends StatelessWidget {
const BuildItem({Key? key}) : super(key: key); final ChapterModel model;
const BuildItem({
Key? key,
required this.model
}) : super(key: key);
@override
State<BuildItem> createState() => _BuildItemState();
}
class _BuildItemState extends State<BuildItem> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
children: [ children: [
/// 章节名称容器 /// 章节名称容器
Container( Container(
margin: EdgeInsets.symmetric(horizontal: 15), margin: const EdgeInsets.symmetric(horizontal: 15),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text('第二章,你好好啊哈',style: TextStyle(fontSize: 14,color: Colours.c3,fontWeight: Fonts.medium,height: 1.6),), Text(model.name??'',style: const TextStyle(fontSize: 14,color: Colours.c3,fontWeight: Fonts.medium,height: 1.6),),
Container( Container(
width: 14, width: 14,
height: 4, height: 4,
...@@ -32,21 +31,21 @@ class _BuildItemState extends State<BuildItem> { ...@@ -32,21 +31,21 @@ class _BuildItemState extends State<BuildItem> {
visible: true, visible: true,
child: ListView.builder( child: ListView.builder(
shrinkWrap: true, shrinkWrap: true,
physics: NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index){ itemBuilder: (BuildContext context, int index){
return _buildSection(); return _buildSection(model.children![index]);
}, },
itemCount: 5, itemCount: model.children!.length,
) )
) )
], ],
); );
} }
Widget _buildSection(){ Widget _buildSection(ChapterModel model){
return Container( return Container(
margin: EdgeInsets.only(left: 60), margin: const EdgeInsets.only(left: 60),
child: Text('第一节 加入权利游侠',style: TextStyle(fontSize: 12,color: Colours.c3,height: 1.6),), child: Text(model.name??'',style: const TextStyle(fontSize: 12,color: Colours.c3,height: 1.6),),
); );
} }
} }
part of book_detail; part of book_detail;
class BookDetailController extends GetxController with GetSingleTickerProviderStateMixin{ class BookDetailController extends GetxController with GetSingleTickerProviderStateMixin{
final String bookId;
BookDetailController(this.bookId);
late TabController tabController; late TabController tabController;
final PageController pageController = PageController(initialPage: 0); final PageController pageController = PageController(initialPage: 0);
List <Widget>tabs = [ List <Widget>tabs = [
...@@ -9,15 +13,64 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt ...@@ -9,15 +13,64 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt
const Tab(text: '本书信息',), const Tab(text: '本书信息',),
]; ];
// 目录
List <ChapterModel> chapters = [];
// 图书
BookDetailModel bookDetails = BookDetailModel();
@override @override
void onInit() { void onInit() {
tabController = TabController(length: tabs.length, vsync: this); tabController = TabController(length: tabs.length, vsync: this);
super.onInit(); super.onInit();
} }
@override
void onReady() {
_getBookDetails();
_getChapters();
super.onReady();
}
@override @override
void onClose() { void onClose() {
tabController.dispose();
pageController.dispose();
super.onClose(); super.onClose();
} }
/// 获取目录信息
void _getChapters() async {
chapters = await LibraryAPI.chapters(bookId: bookId);
update();
}
/// 获取图书详细信息
void _getBookDetails() async {
bookDetails = await LibraryAPI.details(bookId:bookId);
update();
}
/// 收藏 与 取消收藏
void love({
required String bookId,
required num isCollection
}) async {
if (isCollection == 0) {
isCollection = 1;
}
else {
isCollection = 0;
}
bool result = await CommonAPI.love(
bookId: bookId, love: isCollection.toString());
if (result) {
_getBookDetails();
}
}
} }
\ No newline at end of file
library book_detail; library book_detail;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_book/apis/index.dart';
import 'package:flutter_book/theme.dart'; import 'package:flutter_book/theme.dart';
import 'package:flutter_book/utils/index.dart'; import 'package:flutter_book/utils/index.dart';
import 'package:flutter_book/widgets/index.dart'; import 'package:flutter_book/widgets/index.dart';
import 'package:flutter_star/custom_rating.dart';
import 'package:flutter_star/star.dart'; import 'package:flutter_star/star.dart';
import 'package:flutter_star/star_score.dart'; import 'package:flutter_star/star_score.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
...@@ -11,6 +13,7 @@ import 'package:get/get_state_manager/src/simple/get_controllers.dart'; ...@@ -11,6 +13,7 @@ import 'package:get/get_state_manager/src/simple/get_controllers.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:ionicons/ionicons.dart'; import 'package:ionicons/ionicons.dart';
import '../../models/index.dart';
import '../../routes/index.dart'; import '../../routes/index.dart';
import '../book_category/index.dart'; import '../book_category/index.dart';
import '../book_info/index.dart'; import '../book_info/index.dart';
......
...@@ -3,7 +3,11 @@ part of book_detail; ...@@ -3,7 +3,11 @@ part of book_detail;
class BookDetailPage extends StatefulWidget { class BookDetailPage extends StatefulWidget {
const BookDetailPage({Key? key}) : super(key: key); final String bookId;
const BookDetailPage({
Key? key,
required this.bookId
}) : super(key: key);
@override @override
State<BookDetailPage> createState() => _BookDetailPageState(); State<BookDetailPage> createState() => _BookDetailPageState();
...@@ -15,7 +19,7 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid ...@@ -15,7 +19,7 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GetBuilder<BookDetailController>( return GetBuilder<BookDetailController>(
init:BookDetailController(), init:BookDetailController(widget.bookId),
builder: (controller)=> Scaffold( builder: (controller)=> Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
backgroundColor: const Color(0xFFAB1941).withOpacity(0.02), backgroundColor: const Color(0xFFAB1941).withOpacity(0.02),
...@@ -24,26 +28,30 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid ...@@ -24,26 +28,30 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid
CustomButton.icon( CustomButton.icon(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
icon: const Icon(Ionicons.timer), icon: Image.asset('assets/images/shop.png'),
onPressed: () => context.pushNamed(Routes.msgs), onPressed: () => context.pushNamed(Routes.shop),
), ),
CustomButton.icon( CustomButton.icon(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
icon: const Icon(Ionicons.timer), icon: Image.asset(
onPressed: () => context.pushNamed(Routes.msgs), controller.bookDetails.isCollection == 0? 'assets/images/unlove.png':'assets/images/love.png',
),
onPressed: () {
controller.love(bookId: controller.bookDetails.bookId.toString(), isCollection: controller.bookDetails.isCollection!);
},
), ),
], ],
), ),
body: body:
Column( Column(
children: [ children: [
const BuildBook(), BuildBook(model: controller.bookDetails,),
Container( Container(
height: 10, height: 10,
color: const Color(0xFFF9F9F9), color: const Color(0xFFF9F9F9),
), ),
const BuildStudy(), BuildStudy(model:controller.bookDetails,),
Container( Container(
height: 2, height: 2,
color: const Color(0xFFF9F9F9), color: const Color(0xFFF9F9F9),
...@@ -64,11 +72,13 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid ...@@ -64,11 +72,13 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid
child: TabBarView( child: TabBarView(
controller: controller.tabController, controller: controller.tabController,
children: [ children: [
BookCategoryPage(), BookCategoryPage(chapters: controller.chapters,),
Container( Container(
color: Colors.lightBlue, margin: const EdgeInsets.only(left: 15,right: 15,top:12),
// color: Colors.lightBlue,
child: Text(controller.bookDetails.content??'',style: const TextStyle(fontSize: 12,height: 1.5,color: Colours.c3),),
), ),
BookInfoPage() BookInfoPage(model:controller.bookDetails,)
], ],
), ),
), ),
...@@ -77,7 +87,7 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid ...@@ -77,7 +87,7 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid
), ),
bottomNavigationBar: SafeArea( bottomNavigationBar: SafeArea(
child: Container( child: Container(
margin: EdgeInsets.symmetric(horizontal: 15), margin: const EdgeInsets.symmetric(horizontal: 15),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
...@@ -117,8 +127,8 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid ...@@ -117,8 +127,8 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid
), ),
height: 35, height: 35,
alignment: Alignment.center, alignment: Alignment.center,
padding: EdgeInsets.symmetric(vertical: 8), padding: const EdgeInsets.symmetric(vertical: 8),
child: Text('阅读',style: TextStyle(fontSize: 13,color: AppTheme.primary,height: 1.5),), child: const Text('阅读',style: TextStyle(fontSize: 13,color: AppTheme.primary,height: 1.5),),
), ),
), ),
) )
...@@ -131,36 +141,4 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid ...@@ -131,36 +141,4 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid
} }
Widget test(){
return NestedScrollView(
headerSliverBuilder: (BuildContext context ,bool innerBoxIsScrolled){
return [
SliverList(
delegate: SliverChildListDelegate([
const BuildBook(),
Container(
height: 10,
color: const Color(0xFFF9F9F9),
),
const BuildStudy(),
Container(
height: 2,
color: const Color(0xFFF9F9F9),
),
])
)
];
},
body: ListView.builder(
itemCount: 50,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text('Item $index'),
);
},
),
);
}
} }
part of book_detail; part of book_detail;
class BuildBook extends StatelessWidget { class BuildBook extends StatelessWidget {
const BuildBook({Key? key}) : super(key: key); final BookDetailModel model;
const BuildBook({
Key? key,
required this.model
}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -29,10 +33,10 @@ class BuildBook extends StatelessWidget { ...@@ -29,10 +33,10 @@ class BuildBook extends StatelessWidget {
borderRadius: BorderRadius.circular(3), borderRadius: BorderRadius.circular(3),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
color: Color(0xFF707070).withOpacity(0.5), color: const Color(0xFF707070).withOpacity(0.5),
spreadRadius: 2, spreadRadius: 0,
blurRadius: 5, blurRadius: 4.5,
offset: Offset(3, 0), // changes the position of the shadow offset: const Offset(0, 0), // changes the position of the shadow
), ),
] ]
), ),
...@@ -40,10 +44,8 @@ class BuildBook extends StatelessWidget { ...@@ -40,10 +44,8 @@ class BuildBook extends StatelessWidget {
height: 102, height: 102,
width: 85, width: 85,
child: Container( child: Container(
padding: EdgeInsets.all(2), padding: const EdgeInsets.all(1),
child: Container( child: CustomImage.network(url: model.img??'')
color: Colors.cyan,
),
), ),
) )
...@@ -54,24 +56,29 @@ class BuildBook extends StatelessWidget { ...@@ -54,24 +56,29 @@ class BuildBook extends StatelessWidget {
Expanded( Expanded(
child: Container( child: Container(
// color: Colors.cyan, // color: Colors.cyan,
padding: const EdgeInsets.only(top: 12,bottom: 10), padding: const EdgeInsets.only(top: 12,bottom: 15),
child: const Column( child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text('一想到还有95%的问题留给人',style: TextStyle(fontSize: 16,fontWeight: Fonts.medium,color: Colours.c3),maxLines: 1,overflow: TextOverflow.ellipsis,), Text(model.bookName??'',style: const TextStyle(fontSize: 16,fontWeight: Fonts.medium,color: Colours.c3),maxLines: 1,overflow: TextOverflow.ellipsis,),
SizedBox(height: 5,), const SizedBox(height: 5,),
Text('威廉·莎士比亚',style: TextStyle(fontSize: 13,fontWeight: FontWeight.w400,color: Colours.c6)), Text(model.authors??'',style: const TextStyle(fontSize: 13,fontWeight: FontWeight.w400,color: Colours.c6)),
], ],
), ),
Row( Row(
children: [ children: [
Text('¥88',style: TextStyle(fontSize: 14,fontWeight: FontWeight.w500,color: AppTheme.primary)), Text('¥${model.vipPrice}',style: const TextStyle(fontSize: 14,fontWeight: FontWeight.w500,color: AppTheme.primary)),
Gaps.hGaps10, Gaps.hGaps10,
Text('¥88',style: TextStyle(fontSize: 12,color: Colours.c9)), Text('¥${model.price}',style: const TextStyle(
fontSize: 12,color: Colours.c9,
decoration: TextDecoration.lineThrough,
decorationColor: Colours.c9, // 可选,指定删除线的颜色
decorationThickness: 1
)),
], ],
) )
], ],
......
part of book_detail; part of book_detail;
class BuildStudy extends StatefulWidget { class BuildStudy extends StatefulWidget {
const BuildStudy({Key? key}) : super(key: key); final BookDetailModel model;
const BuildStudy({
Key? key,
required this.model
}) : super(key: key);
@override @override
State<BuildStudy> createState() => _BuildStudyState(); State<BuildStudy> createState() => _BuildStudyState();
...@@ -17,50 +21,50 @@ class _BuildStudyState extends State<BuildStudy> { ...@@ -17,50 +21,50 @@ class _BuildStudyState extends State<BuildStudy> {
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
Expanded( Expanded(
child: Container( child: Column(
// color: Colors.red, mainAxisAlignment: MainAxisAlignment.center,
child: Column( children: [
mainAxisAlignment: MainAxisAlignment.center, Row(
children: [ mainAxisAlignment: MainAxisAlignment.center,
Row( children: [
mainAxisAlignment: MainAxisAlignment.center, Text(widget.model.rating??'',style:const TextStyle(fontSize: 16,height: 1.5,fontWeight: Fonts.medium,color: AppTheme.primary)),
children: [ const Text('/5.0',style: TextStyle(fontSize: 13,height: 1.5,fontWeight: Fonts.medium,color: Colours.c9),)
Text('4.8'), ],
Text('/5.0') ),
], AbsorbPointer(
absorbing: true,
child: CustomRating(
max: 5,
score:widget.model.rating !=null ?double.parse(widget.model.rating!):0,
star: const Star(
progress: 7,
fillColor: AppTheme.primary,
size: 12,
emptyColor: Colours.cE2,
), onRating: (double a) {},
), ),
StarScore( ),
score: 4.5, ],
star: Star(
fillColor: AppTheme.primary,
size: 12,
emptyColor: Color(0xFFEBEBEB)),
),
],
),
), ),
), ),
Expanded( Expanded(
child: Container( child: Column(
// color: Colors.cyan, mainAxisAlignment: MainAxisAlignment.center,
child: Column( children: [
mainAxisAlignment: MainAxisAlignment.center, RichText(text:TextSpan(
children: [ children: [
RichText(text:TextSpan( TextSpan(
children: [ text: widget.model.readNum.toString(),
TextSpan( style: const TextStyle(fontSize: 16,color: Colours.c3,fontWeight: Fonts.medium,height: 1.3)
text: '110', ),
style: TextStyle(fontSize: 16,color: Colours.c3,fontWeight: Fonts.medium,height: 1.3) // TextSpan(
), // text: '万',
TextSpan( // style: TextStyle(fontSize: 16,color: Colours.c3,)
text: '万', // )
style: TextStyle(fontSize: 16,color: Colours.c3,) ]
) )),
] const Text('学习次数', style: TextStyle(fontSize: 12,color: Colours.c9,height: 1.3)),
)), ],
Text('学习次数', style: TextStyle(fontSize: 12,color: Colours.c9,height: 1.3)),
],
),
), ),
) )
], ],
......
...@@ -3,10 +3,12 @@ library book_info; ...@@ -3,10 +3,12 @@ library book_info;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_book/utils/index.dart'; import 'package:flutter_book/utils/index.dart';
import 'package:flutter_star/custom_rating.dart';
import 'package:flutter_star/star.dart'; import 'package:flutter_star/star.dart';
import 'package:flutter_star/star_score.dart'; import 'package:flutter_star/star_score.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import '../../models/index.dart';
import '../../routes/index.dart'; import '../../routes/index.dart';
import '../../theme.dart'; import '../../theme.dart';
......
part of book_info; part of book_info;
class BookInfoPage extends StatefulWidget { class BookInfoPage extends StatelessWidget {
const BookInfoPage({Key? key}) : super(key: key); final BookDetailModel model;
const BookInfoPage({
Key? key,
required this.model
}) : super(key: key);
@override
State<BookInfoPage> createState() => _BookInfoPageState();
}
class _BookInfoPageState extends State<BookInfoPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
...@@ -17,68 +16,65 @@ class _BookInfoPageState extends State<BookInfoPage> { ...@@ -17,68 +16,65 @@ class _BookInfoPageState extends State<BookInfoPage> {
// 评分容器 // 评分容器
Column( Column(
children: [ children: [
Container( Row(
color: Colors.red, mainAxisAlignment: MainAxisAlignment.spaceBetween,
child: Row( children: [
mainAxisAlignment: MainAxisAlignment.spaceBetween, const Text('评分及书评',style: TextStyle(fontSize: 14,color: Colours.c3,height: 1.6,fontWeight: Fonts.medium),),
children: [ Row(
const Text('评分及书评',style: TextStyle(fontSize: 14,color: Colours.c3,height: 1.6,fontWeight: Fonts.medium),), children: [
Container( GestureDetector(
child: Row( child: const Text('查看全部',style: TextStyle(fontSize: 11,color: Colours.c9),),
children: [ onTap: (){
GestureDetector( context.pushNamed(Routes.bookScore,queryParameters: {'book_id':'110'});
child: const Text('查看全部',style: TextStyle(fontSize: 11,color: Colours.c9),), },
onTap: (){ ),
context.pushNamed(Routes.bookScore,queryParameters: {'book_id':'110'}); Gaps.hGaps5,
}, SizedBox(
), width: 5,
Gaps.hGaps5, height: 8,
Container( // color: Colors.cyan,
width: 5, child: Image.asset(
height: 8, 'assets/images/right_arrow.png',
// color: Colors.cyan, ),
child: Image.asset( )
'assets/images/right_arrow.png', ]
), )
) ],
]
),
)
],
),
), ),
Container( Container(
margin: EdgeInsets.symmetric(vertical: 10), margin: const EdgeInsets.symmetric(vertical: 10),
child: Row( child: Row(
children: [ children: [
const Column( Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
// crossAxisAlignment: CrossAxisAlignment.center, // crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text('4.8',style: TextStyle(fontSize: 35,height: 1.5,fontWeight: Fonts.boldSemi,color: AppTheme.primary),), Text(model.rating??'',style: const TextStyle(fontSize: 35,height: 1.5,fontWeight: Fonts.boldSemi,color: AppTheme.primary),),
StarScore( AbsorbPointer(
score: 4.5, absorbing: true,
star: Star( child: CustomRating(
max: 5,
score:model.rating !=null ?double.parse(model.rating!):0,
star: const Star(
progress: 7,
fillColor: AppTheme.primary, fillColor: AppTheme.primary,
size: 12, size: 12,
emptyColor: Color(0xFFEBEBEB)), emptyColor: Colours.cE2,
), onRating: (double a) {},
),
), ),
], ],
), ),
Expanded( Expanded(
child: Container( child: SizedBox(
height: 90, height: 90,
color: Colors.green, // color: Colors.green,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: List.generate(model.ratingList!.length, (index){
_buildProgrss(5, 0.2), return _buildProgrss(5- index.toDouble(), model.ratingList![index].toDouble()/model.ratingCount!);
_buildProgrss(4, 0.5), }).toList()
_buildProgrss(3, 0.8),
_buildProgrss(2, 0.2),
_buildProgrss(1, 0.1),
],
), ),
), ),
) )
...@@ -90,29 +86,26 @@ class _BookInfoPageState extends State<BookInfoPage> { ...@@ -90,29 +86,26 @@ class _BookInfoPageState extends State<BookInfoPage> {
Container(height: 1,width: double.infinity,color: Colours.cF2,), Container(height: 1,width: double.infinity,color: Colours.cF2,),
Gaps.vGaps15, Gaps.vGaps15,
// 书籍信息 // 书籍信息
Container( Column(
color: Colors.red, mainAxisAlignment: MainAxisAlignment.end,
child: Column( crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.end, children: ['书名','作者','分类','出品方','出版社','上架时间'].map((item){
crossAxisAlignment: CrossAxisAlignment.start, return Row(
children: ['书名','作者','分类','出品方','出版社','上架时间'].map((item){ children: [
return Row( Container(
// mainAxisAlignment: MainAxisAlignment.end, // color: Colors.cyan,
children: [ alignment: Alignment.centerRight,
Container( width: 50,
color: Colors.cyan, child: Text(item,style: const TextStyle(fontSize: 11,height: 2.1,color: Colours.c3),),
alignment: Alignment.centerRight, ),
child: Text(item,style: TextStyle(fontSize: 11,height: 2.1,color: Colours.c3),), Gaps.hGaps20,
), Container(
Gaps.hGaps20, alignment: Alignment.centerLeft,
Container( child: Text(item,style: const TextStyle(fontSize: 11,height: 2.1,color: Colours.c9),textAlign: TextAlign.end,),
alignment: Alignment.centerLeft, ),
child: Text(item,style: TextStyle(fontSize: 11,height: 2.1,color: Colours.c9),textAlign: TextAlign.end,), ],
), );
], }).toList(),
);
}).toList(),
),
) )
], ],
), ),
......
...@@ -86,10 +86,12 @@ class _CoursePageState extends State<CoursePage> { ...@@ -86,10 +86,12 @@ class _CoursePageState extends State<CoursePage> {
childAspectRatio: 0.85 childAspectRatio: 0.85
), ),
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
CourseModel model = controller.courses[index];
return GestureDetector( return GestureDetector(
child: Book(model: controller.courses[index],), child: Book(model: model,),
onTap: (){ onTap: (){
context.pushNamed(Routes.bookDetail); context.pushNamed(Routes.bookDetail,queryParameters: {'book_id':model.bookId.toString()});
}, },
); );
}, },
......
...@@ -27,7 +27,7 @@ class _LibraryPageState extends State<LibraryPage> with SingleTickerProviderStat ...@@ -27,7 +27,7 @@ class _LibraryPageState extends State<LibraryPage> with SingleTickerProviderStat
), ),
], ],
bottom: PreferredSize( bottom: PreferredSize(
preferredSize: Size.fromHeight(38), preferredSize: const Size.fromHeight(38),
child: Container( child: Container(
color: Colors.white, color: Colors.white,
width: double.infinity, width: double.infinity,
...@@ -40,26 +40,17 @@ class _LibraryPageState extends State<LibraryPage> with SingleTickerProviderStat ...@@ -40,26 +40,17 @@ class _LibraryPageState extends State<LibraryPage> with SingleTickerProviderStat
Expanded( Expanded(
child: TabBar( child: TabBar(
indicator: BoxDecoration( indicator: BoxDecoration(
border: Border(bottom: BorderSide(color: Colors.transparent, width: 0.0)), // 将指示器的底边框颜色设置为透明 border: const Border(bottom: BorderSide(color: Colors.transparent, width: 0.0)), // 将指示器的底边框颜色设置为透明
color: Color(0xFFC0D55).withOpacity(0.08) color: const Color(0xFFC02D55).withOpacity(0.08)
), ),
labelStyle: TextStyle(color: AppTheme.primary,fontSize: 14,height: 1.5,fontWeight: Fonts.medium), labelStyle: const TextStyle(color: AppTheme.primary,fontSize: 14,height: 1.5,fontWeight: Fonts.medium),
unselectedLabelColor: Colours.c9, unselectedLabelColor: Colours.c9,
unselectedLabelStyle: TextStyle(color: Colours.c9,fontSize: 14,height: 1.5), unselectedLabelStyle: const TextStyle(color: Colours.c9,fontSize: 14,height: 1.5),
controller: controller.tabController, controller: controller.tabController,
isScrollable: true, isScrollable: true,
tabs: controller.categories.map((model){ tabs: controller.categories.map((model){
return Tab(text: model.name); return Tab(text: model.name);
}).toList(), }).toList(),
// [
// Tab(text: '全部'),
// Tab(text: '职业证书'),
// Tab(text: '人文艺术'),
// Tab(text: '财经管理'),
// Tab(text: '待评价'),
// Tab(text: '待评价1'),
// Tab(text: '待评价2'),
// ],
), ),
), ),
GestureDetector( GestureDetector(
...@@ -104,15 +95,6 @@ class _LibraryPageState extends State<LibraryPage> with SingleTickerProviderStat ...@@ -104,15 +95,6 @@ class _LibraryPageState extends State<LibraryPage> with SingleTickerProviderStat
); );
} }
// /// 列表
// Widget createListView(){
// return ListView.builder(
// itemBuilder: (BuildContext context, int index){
// return LibraryCell();
// },
// itemCount: 2,
// );
// }
// @override // @override
// // TODO: implement wantKeepAlive // // TODO: implement wantKeepAlive
......
...@@ -57,10 +57,10 @@ class LibraryCell extends StatelessWidget { ...@@ -57,10 +57,10 @@ class LibraryCell extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text(model.authors??'',style: TextStyle(fontSize: 11,color: Colours.c9,height: 1.5),), Text(model.authors??'',style: const TextStyle(fontSize: 11,color: Colours.c9,height: 1.5),),
Row( Row(
children: [ children: [
Text('${model.readNum.toString()}人读过',style:TextStyle(fontSize: 11,height: 1.5,color: Colours.cC7)), Text('${model.readNum.toString()}人读过',style:const TextStyle(fontSize: 11,height: 1.5,color: Colours.cC7)),
Gaps.hGaps5, Gaps.hGaps5,
GestureDetector( GestureDetector(
onTap: onTap, onTap: onTap,
......
...@@ -18,7 +18,7 @@ class _LibraryContentPageState extends State<LibraryContentPage> { ...@@ -18,7 +18,7 @@ class _LibraryContentPageState extends State<LibraryContentPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
children: [ children: [
Container( SizedBox(
height: 43, height: 43,
// color: Colors.green, // color: Colors.green,
child: ListView.builder( child: ListView.builder(
...@@ -57,9 +57,14 @@ class _LibraryContentPageState extends State<LibraryContentPage> { ...@@ -57,9 +57,14 @@ class _LibraryContentPageState extends State<LibraryContentPage> {
itemCount: widget.controller.books.length, itemCount: widget.controller.books.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
CourseModel model = widget.controller.books[index]; CourseModel model = widget.controller.books[index];
return LibraryCell(model: model,onTap: (){ return GestureDetector(
widget.controller.love(bookId: model.bookId.toString(), isCollection: model.isCollection!); onTap: (){
},); context.pushNamed(Routes.bookDetail,queryParameters: {'book_id':model.bookId.toString()});
},
child: LibraryCell(model: model,onTap: (){
widget.controller.love(bookId: model.bookId.toString(), isCollection: model.isCollection!);
},),
);
}, },
), ),
), ),
......
...@@ -7,6 +7,7 @@ import 'package:flutter_book/pages/ad/index.dart'; ...@@ -7,6 +7,7 @@ import 'package:flutter_book/pages/ad/index.dart';
import 'package:flutter_book/pages/book_detail/index.dart'; import 'package:flutter_book/pages/book_detail/index.dart';
import 'package:flutter_book/pages/book_pay/index.dart'; import 'package:flutter_book/pages/book_pay/index.dart';
import 'package:flutter_book/pages/book_score/index.dart'; import 'package:flutter_book/pages/book_score/index.dart';
import 'package:flutter_book/pages/book_shop/index.dart';
import 'package:flutter_book/pages/credit_points/index.dart'; import 'package:flutter_book/pages/credit_points/index.dart';
import 'package:flutter_book/pages/forget_pwd/index.dart'; import 'package:flutter_book/pages/forget_pwd/index.dart';
import 'package:flutter_book/pages/login/index.dart'; import 'package:flutter_book/pages/login/index.dart';
......
...@@ -41,6 +41,7 @@ abstract class Routes { ...@@ -41,6 +41,7 @@ abstract class Routes {
/// 书架模块 /// 书架模块
static const creditPoints = 'credit_points'; static const creditPoints = 'credit_points';
static const shop = 'shop';
...@@ -213,7 +214,9 @@ abstract class Routes { ...@@ -213,7 +214,9 @@ 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 BookDetailPage() child: BookDetailPage(
bookId: state.uri.queryParameters['book_id'].toString(),
)
) )
), ),
GoRoute( GoRoute(
...@@ -272,6 +275,15 @@ abstract class Routes { ...@@ -272,6 +275,15 @@ abstract class Routes {
child: const UserLovePage() child: const UserLovePage()
) )
), ),
GoRoute(
path: '/$shop',
name: shop,
pageBuilder: (context, state) =>CupertinoPage(
name: state.uri.toString(),
key: state.pageKey,
child: const BookShopPage()
)
),
] ]
); );
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论