提交 11406f8d authored 作者: yueweilu's avatar yueweilu

学习报告数据绑定

上级 5aa4ad33
......@@ -4,5 +4,5 @@ keyPassword=123456
keyAlias=zijing
#storeFile=/Users/apple/zijiing_key.jks
storeFile=zijiing_key.jks
\ No newline at end of file
storeFile=/Users/apple/zijiing_key.jks
#storeFile=zijiing_key.jks
\ No newline at end of file
......@@ -34,6 +34,7 @@ abstract class CommonAPI {
);
if (result.data is! Map && result.data['list'] is! List) return [];
return List.generate(result.data['list'].length, (index){
print(result.data['list'][index]);
return MsgModel.fromJson(result.data['list'][index]);
});
}
......
......@@ -98,7 +98,7 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid
Expanded(
child: GestureDetector(
onTap: (){
context.pushNamed(Routes.studyReport);
context.pushNamed(Routes.studyReport,queryParameters: {'book_id':widget.bookId});
},
child: Container(
alignment: Alignment.center,
......
......@@ -60,12 +60,23 @@ class LoginController extends GetxController {
}
void setCanClick(){
if (ValidatorTool.isValidPhoneNumber(phoneInput.text) && ValidatorTool.isValidPassword(passwordInput.text)){
_enable = true;
if (loginType == 0){
if (ValidatorTool.isValidPhoneNumber(phoneInput.text) && ValidatorTool.isValidPassword(passwordInput.text)){
_enable = true;
}
else{
_enable = false;
}
}
else{
_enable = false;
else {
if (ValidatorTool.isValidPhoneNumber(phoneInput.text) && ValidatorTool.isValidCode(codeInput.text)){
_enable = true;
}
else{
_enable = false;
}
}
update();
}
......@@ -144,6 +155,10 @@ class LoginController extends GetxController {
}
void sendCode() async {
if (!agree) {
Toast.show('请先阅读并同意《用户协议》和《隐私政策》');
return;
}
final result = await AccountAPI.sendCode(phone: phoneInput.text, type: 'login');
if (result){
Toast.show('发送成功');
......
......@@ -113,6 +113,9 @@ class _LoginPageState extends State<LoginPage> {
hintText: '请输入验证码',
keyboardType: TextInputType.number,
controller: controller.codeInput,
onChanged: (text){
controller.setCanClick();
},
),
Positioned(
right: 10.w,
......
part of study_report;
class StudyReportController extends GetxController {
final String bookId;
StudyReportController(this.bookId);
ReportModel model = ReportModel();
@override
void onReady() {
_getReport();
super.onReady();
}
void _getReport() async {
model = await LibraryAPI.report(bookId: bookId);
update();
}
}
\ No newline at end of file
library study_report;
import 'package:flutter/material.dart';
import 'package:flutter_book/apis/index.dart';
import 'package:flutter_book/utils/index.dart';
import 'package:flutter_book/widgets/index.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get_state_manager/src/simple/get_controllers.dart';
import 'package:get/get_state_manager/src/simple/get_state.dart';
import '../../models/index.dart';
part 'view.dart';
part 'widgets/card.dart';
\ No newline at end of file
part 'widgets/card.dart';
part 'controller.dart';
\ No newline at end of file
part of study_report;
class StudyReportPage extends StatefulWidget {
const StudyReportPage({Key? key}) : super(key: key);
final String bookId;
const StudyReportPage({
Key? key,
required this.bookId
}) : super(key: key);
@override
State<StudyReportPage> createState() => _StudyReportPageState();
......@@ -9,122 +13,42 @@ class StudyReportPage extends StatefulWidget {
class _StudyReportPageState extends State<StudyReportPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('学习报告'),
),
body: Container(
margin: EdgeInsets.only(left: 10.w,top: 10.w,bottom: 10.w,right: 10.w),
child: SingleChildScrollView(
child: Column(
children: [
BuildCard(),
// Container(
// // height: 210,
// // width: 355,
// // color: Colors.cyan,
// child: Image.asset(
// 'assets/images/report_bg.png',
// ),
// ),
Gaps.vGaps10,
Row(
children: [
Expanded(
child: Column(
children: [
Container(
padding: EdgeInsets.only(left: 15.w,top: 15.w,bottom: 15.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.w),
color: Colors.yellow,
boxShadow: [
BoxShadow(
color: Colours.cC7.withOpacity(0.5),
offset: Offset(1, 3.w),
blurRadius: 10.w,
spreadRadius: 0,
),
],
),
height: 220.w,
child: Column(
children: [
Row(
children: [
Container(
width: 26.w,
height: 26.w,
color: Colors.cyan,
),
Gaps.hGaps10,
Text('笔记',style: TextStyle(fontSize: 16.w,height: 1.3,color: Colours.c3,fontWeight: Fonts.medium),)
],
)
],
),
),
Gaps.vGaps10,
Container(
padding: EdgeInsets.only(left: 15.w,top: 15.w,bottom: 15.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.w),
color: Colors.red,
boxShadow: [
BoxShadow(
color: Colours.cC7.withOpacity(0.5),
offset: Offset(1, 3.w),
blurRadius: 10.w,
spreadRadius: 0,
),
],
),
height: 110.w,
child: Column(
children: [
Row(
children: [
Container(
width: 26.w,
height: 26.w,
color: Colors.cyan,
),
Gaps.hGaps10,
Text('距离连续学习',style: TextStyle(fontSize: 16.w,height: 1.3,color: Colours.c3,fontWeight: Fonts.medium),)
],
)
],
),
)
],
),
),
Gaps.hGaps10,
Expanded(
child: Container(// color: Colors.limeAccent,
return GetBuilder<StudyReportController>(
init: StudyReportController(widget.bookId),
builder:(controller) => Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('学习报告'),
),
body: Container(
margin: EdgeInsets.only(left: 10.w,top: 10.w,bottom: 10.w,right: 10.w),
child: SingleChildScrollView(
child: Column(
children: [
BuildCard(model: controller.model,),
Gaps.vGaps10,
Row(
children: [
Expanded(
child: Column(
children: [
Container(
padding: EdgeInsets.only(left: 15.w,top: 15.w,bottom: 15.w),
height: 165,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.w),
color: Colors.cyan,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colours.cC7.withOpacity(0.5),
offset: Offset(1, 3.w),
offset: Offset(1, 3.w),
blurRadius: 10.w,
spreadRadius: 0,
),
],
),
height: 220.w,
child: Column(
children: [
Row(
......@@ -132,12 +56,24 @@ class _StudyReportPageState extends State<StudyReportPage> {
Container(
width: 26.w,
height: 26.w,
color: Colors.cyan,
// color: Colors.cyan,
child: Image.asset('assets/images/report_note.png'),
),
Gaps.hGaps10,
Text('知识测评',style: TextStyle(fontSize: 16.w,height: 1.3,color: Colours.c3,fontWeight: Fonts.medium),)
Text('笔记',style: TextStyle(fontSize: 16.w,height: 1.3,color: Colours.c3,fontWeight: Fonts.medium),)
],
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildItem(title: '划线', num: controller.model.lineNums.toString()),
_buildItem(title: '高亮', num: controller.model.colorNums.toString()),
_buildItem(title: '笔记', num: controller.model.noteNums.toString()),
],
),
)
],
),
......@@ -147,7 +83,7 @@ class _StudyReportPageState extends State<StudyReportPage> {
padding: EdgeInsets.only(left: 15.w,top: 15.w,bottom: 15.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.w),
color: Colors.green,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colours.cC7.withOpacity(0.5),
......@@ -157,36 +93,185 @@ class _StudyReportPageState extends State<StudyReportPage> {
),
],
),
height: 165.w,
height: 110.w,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 26.w,
height: 26.w,
color: Colors.cyan,
child: Image.asset('assets/images/report_study.png')
// color: Colors.cyan,
),
Gaps.hGaps10,
Text('讨论',style: TextStyle(fontSize: 16.w,height: 1.3,color: Colours.c3,fontWeight: Fonts.medium),)
Text('距离连续学习',style: TextStyle(fontSize: 16.w,height: 1.3,color: Colours.c3,fontWeight: Fonts.medium),)
],
)
),
Gaps.vGaps5,
RichText(text: TextSpan(
children: [
TextSpan(text: controller.model.maxSecond!=null?controller.model.maxSecond.toString():'',style: TextStyle(fontSize: 21.w,height: 1.5,color: Colours.c3,fontWeight: Fonts.medium)),
TextSpan(text: '分钟',style: TextStyle(fontSize: 13.w,height: 1.5,color: Colours.c3)),
]
))
],
),
)
],
),
),
)
]
)
],
Gaps.hGaps10,
Expanded(
child: Container(// color: Colors.limeAccent,
child: Column(
children: [
Container(
padding: EdgeInsets.only(left: 15.w,top: 15.w,bottom: 15.w,right: 30),
height: 165,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.w),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colours.cC7.withOpacity(0.5),
offset: Offset(1, 3.w),
blurRadius: 10.w,
spreadRadius: 0,
),
],
),
child: Column(
children: [
Row(
children: [
Container(
width: 26.w,
height: 26.w,
child: Image.asset('assets/images/report_test.png')
// color: Colors.cyan,
),
Gaps.hGaps10,
Text('知识测评',style: TextStyle(fontSize: 16.w,height: 1.3,color: Colours.c3,fontWeight: Fonts.medium),)
],
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: 80.w,
child: Text('总回顾',style: TextStyle(fontSize: 14.w,height: 1.5,color: Colours.c9),),
),
RichText(text: TextSpan(
children: [
TextSpan(text:controller.model.questionAllNums !=null? controller.model.questionAllNums.toString():'' ,style: TextStyle(fontSize: 21.w,height: 1.5,color: Colours.c3,fontWeight: Fonts.medium)),
TextSpan(text: '/条',style: TextStyle(fontSize: 13.w,height: 1.5,color: Colours.c3)),
]
))
],
),
Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: 80.w,
child: Text('评论正确率',style: TextStyle(fontSize: 14.w,height: 1.5,color: Colours.c9),),
),
RichText(text: TextSpan(
children: [
TextSpan(text:controller.model.questionAccuracy!=null?controller.model.questionAccuracy.toString():'' ,style: TextStyle(fontSize: 21.w,height: 1.5,color: Colours.c3,fontWeight: Fonts.medium)),
TextSpan(text: '%',style: TextStyle(fontSize: 13.w,height: 1.5,color: Colours.c3)),
]
))
],
),
],
)
)
],
),
),
Gaps.vGaps10,
Container(
padding: EdgeInsets.only(left: 15.w,top: 15.w,bottom: 15.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.w),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colours.cC7.withOpacity(0.5),
offset: Offset(1, 3.w),
blurRadius: 10.w,
spreadRadius: 0,
),
],
),
height: 165.w,
child: Column(
children: [
Row(
children: [
Container(
width: 26.w,
height: 26.w,
// color: Colors.cyan,
child: Image.asset('assets/images/report_discuss.png')
),
Gaps.hGaps10,
Text('讨论',style: TextStyle(fontSize: 16.w,height: 1.3,color: Colours.c3,fontWeight: Fonts.medium),)
],
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildItem(title: '发起讨论', num: controller.model.commentPostNums.toString()),
_buildItem(title: '参与讨论', num: controller.model.commentReplyNums.toString())
],
),
)
],
),
)
],
),
),
)
]
)
],
),
),
),
),
);
}
Widget _buildItem({
required String title,
required String num
}){
return Row(
children: [
Text(title,style: TextStyle(fontSize: 14.w,height: 1.5,color: Colours.c9),),
Gaps.hGaps5,
RichText(text: TextSpan(
children: [
TextSpan(text: num=='null'?'':num,style: TextStyle(fontSize: 21.w,height: 1.5,color: Colours.c3,fontWeight: Fonts.medium)),
TextSpan(text: '/条',style: TextStyle(fontSize: 13.w,height: 1.5,color: Colours.c3)),
]
))
],
);
}
}
part of study_report;
class BuildCard extends StatelessWidget {
const BuildCard({Key? key}) : super(key: key);
final ReportModel model;
const BuildCard({
Key? key,
required this.model
}) : super(key: key);
@override
Widget build(BuildContext context) {
......@@ -29,13 +33,13 @@ class BuildCard extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('恰如其分的孤独',style: TextStyle(fontSize: 20.w,height: 1.4,color: Colors.white,fontWeight: Fonts.medium),),
Text(model.bookName??'',style: TextStyle(fontSize: 20.w,height: 1.4,color: Colors.white,fontWeight: Fonts.medium),),
Gaps.vGaps15,
Row(
children: [
Text('学习总进度',style: TextStyle(fontSize: 13.w,height: 1.4,color: Colors.white),),
Gaps.hGaps15,
Text('4.98%',style: TextStyle(fontSize: 16.w,height: 1.4,color: Colors.white,fontWeight: Fonts.medium),),
Text(model.progress??'',style: TextStyle(fontSize: 16.w,height: 1.4,color: Colors.white,fontWeight: Fonts.medium),),
]
),
Gaps.vGaps10,
......@@ -43,20 +47,20 @@ class BuildCard extends StatelessWidget {
children: [
Text('学习总时长',style: TextStyle(fontSize: 13.w,height: 1.4,color: Colors.white),),
Gaps.hGaps15,
Text('30分钟',style: TextStyle(fontSize: 16.w,height: 1.4,color: Colors.white,fontWeight: Fonts.medium),),
Text('${model.readSecond??''}分钟',style: TextStyle(fontSize: 16.w,height: 1.4,color: Colors.white,fontWeight: Fonts.medium),),
]
),
Gaps.vGaps10,
Text('上次读到',style: TextStyle(fontSize: 13.w,height: 1.4,color: Colors.white),),
Gaps.vGaps5,
Text('第3章 情节…情节…情节情节情节情节',style: TextStyle(fontSize: 16.w,height: 1.4,color: Colors.white,fontWeight: Fonts.medium),maxLines: 1,overflow: TextOverflow.ellipsis,),
Text(model.lastChapter??'',style: TextStyle(fontSize: 16.w,height: 1.4,color: Colors.white,fontWeight: Fonts.medium),maxLines: 1,overflow: TextOverflow.ellipsis,),
]
),
),
Container(
height: 120.w,
width: 100.w,
color: Colors.lime,
child: CustomImage.asset(url: model.img??''),
)
],
),
......
......@@ -2,14 +2,14 @@ part of user_msg;
class MsgController extends GetxController {
List<MsgModel> msgs = [];
final EasyRefreshController refreshController = EasyRefreshController(
controlFinishLoad: true,
controlFinishRefresh: true,
);
List<MsgModel> msgs = [];
final int _limit = 20;
final int _limit = 10;
int _page = 1;
bool _noMore = false;
......
part of web;
class ReadController extends GetxController with GetSingleTickerProviderStateMixin{
class ReadController extends FullLifeCycleController with GetSingleTickerProviderStateMixin{
late AnimationController _controller;
bool _show = false;
......@@ -43,4 +43,17 @@ class ReadController extends GetxController with GetSingleTickerProviderStateMix
_controller.dispose();
super.onClose();
}
void onResumed(){
print('onResumed');
}
void onPaused(){
print('onPaused');
}
void onInactive(){
print('onInactive');
}
void onDetached(){
print('onDetached');
}
}
\ No newline at end of file
part of web;
class WebPage extends StatefulWidget {
const WebPage({Key? key}) : super(key: key);
class ReadPage extends StatefulWidget {
const ReadPage({Key? key}) : super(key: key);
@override
State<WebPage> createState() => _WebPageState();
State<ReadPage> createState() => _ReadPageState();
}
class _WebPageState extends State<WebPage> {
class _ReadPageState extends State<ReadPage> {
final GlobalKey webViewKey = GlobalKey();
InAppWebViewController? webViewController;
late ContextMenu contextMenu;
......
......@@ -173,7 +173,7 @@ abstract class Routes {
pageBuilder: (context, state) =>CupertinoPage(
name: state.uri.toString(),
key: state.pageKey,
child: const WebPage()
child: const ReadPage()
)
),
GoRoute(
......@@ -267,7 +267,9 @@ abstract class Routes {
pageBuilder: (context, state) =>CupertinoPage(
name: state.uri.toString(),
key: state.pageKey,
child: const StudyReportPage()
child: StudyReportPage(
bookId: state.uri.queryParameters['book_id'].toString(),
)
)
),
GoRoute(
......
......@@ -71,7 +71,7 @@ abstract class AppTheme {
static ThemeData get light {
var scheme = ColorScheme.light(
background: Colours.cF9,
background: Colors.white,
onBackground: const Color(0xFF333333),
surface: Colors.white,
onSurface: const Color(0xFF333333),
......
......@@ -96,6 +96,12 @@ class ValidatorTool {
RegExp passwordPattern = RegExp(r'^\d{6}$');
return passwordPattern.hasMatch(value);
}
static bool isValidCode(String value) {
// RegExp passwordPattern = RegExp(r'^[A-Za-z0-9!@#\$%^&*()_+{}\[\]:;<>,.?~\\/-]{8,12}$');
RegExp passwordPattern = RegExp(r'^\d{6}$');
return passwordPattern.hasMatch(value);
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论