StudyInfoRecordingPage.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_markdown/flutter_markdown.dart';
  3. import 'package:flutter_habit/common/BaseArchitectural.dart';
  4. import 'package:flutter_habit/common/I18N.dart';
  5. import 'package:flutter_habit/common/components/PopMenus.dart';
  6. import 'package:flutter_habit/provider/DataProvider.dart';
  7. import 'package:flutter_habit/provider/UserProvider.dart';
  8. import 'package:flutter_habit/common/utils/ConvertUtils.dart';
  9. import 'package:flutter_habit/database/entity/StudyInfo.dart';
  10. import 'package:flutter_habit/database/mapper/StudyInfoMapper.dart';
  11. import 'package:flutter_habit/network/Repository.dart';
  12. import 'package:provider/provider.dart';
  13. class StudyInfoRecordingPage extends StatelessWidget {
  14. @override
  15. Widget build(BuildContext context) {
  16. return MultiProvider(
  17. providers: [
  18. ChangeNotifierProvider<StudyInfoRecordingPageService>(
  19. create: (_) => StudyInfoRecordingPageService(context)),
  20. ChangeNotifierProvider<StudyInfoRecordingPageModel>(
  21. create: (_) => StudyInfoRecordingPageModel(context)),
  22. ],
  23. child: _StudyInfoRecordingPageView(),
  24. );
  25. }
  26. }
  27. // model
  28. class StudyInfoRecordingPageModel extends BaseModel {
  29. StudyInfoRecordingPageModel(BuildContext context) : super(context);
  30. TextEditingController? courseNameController;
  31. int? isLate;
  32. int? isAbsent;
  33. int? isHomeWorkDone;
  34. TextEditingController? homeWorkController;
  35. int? difficulty;
  36. TextEditingController? troubleController;
  37. @override
  38. void init(BuildContext context) {
  39. super.init(context);
  40. courseNameController = TextEditingController();
  41. isLate = 0;
  42. isAbsent = 0;
  43. isHomeWorkDone = 1;
  44. homeWorkController = TextEditingController();
  45. difficulty = 0;
  46. troubleController = TextEditingController();
  47. }
  48. }
  49. // service
  50. class StudyInfoRecordingPageService extends BaseProvider {
  51. StudyInfoRecordingPageService(BuildContext context) : super(context);
  52. void setIsLate(BuildContext context, int? i) {
  53. StudyInfoRecordingPageModel model =
  54. Provider.of<StudyInfoRecordingPageModel>(context, listen: false);
  55. model.isLate = i;
  56. if (i == 0) {
  57. model.isAbsent = 0;
  58. }
  59. model.refresh();
  60. }
  61. void setIsAbsent(BuildContext context, int? i) {
  62. StudyInfoRecordingPageModel model =
  63. Provider.of<StudyInfoRecordingPageModel>(context, listen: false);
  64. model.isAbsent = i;
  65. if (i == 1) {
  66. model.isLate = 1;
  67. }
  68. model.refresh();
  69. }
  70. void setIsHomeWorkDone(BuildContext context, int? i) {
  71. StudyInfoRecordingPageModel model =
  72. Provider.of<StudyInfoRecordingPageModel>(context, listen: false);
  73. model.isHomeWorkDone = i;
  74. model.refresh();
  75. }
  76. void setDifficulty(BuildContext context, int? i) {
  77. StudyInfoRecordingPageModel model =
  78. Provider.of<StudyInfoRecordingPageModel>(context, listen: false);
  79. model.difficulty = i;
  80. model.refresh();
  81. }
  82. void preview(BuildContext context) {
  83. StudyInfoRecordingPageModel model =
  84. Provider.of<StudyInfoRecordingPageModel>(context, listen: false);
  85. Navigator.of(context).push(MaterialPageRoute(
  86. builder: (_) => Scaffold(
  87. appBar: AppBar(
  88. title: Text(I18N.of("MarkDown预览")),
  89. ),
  90. body: Markdown(
  91. data: model.troubleController!.text.toString(),
  92. ),
  93. )));
  94. }
  95. Future<void> record(BuildContext context) async {
  96. StudyInfoRecordingPageModel model =
  97. Provider.of<StudyInfoRecordingPageModel>(context, listen: false);
  98. if (model.courseNameController!.text.trim().isEmpty) {
  99. await PopMenus.attention(context: context,content: Text(I18N.of("课程主题不能为空")));
  100. return;
  101. }
  102. DateTime now = DateTime.now();
  103. StudyInfo studyInfo = StudyInfo();
  104. studyInfo.setDate(now.millisecondsSinceEpoch);
  105. studyInfo.setCourseName(model.courseNameController!.text);
  106. studyInfo.setIsLate(model.isLate);
  107. studyInfo.setIsAbsent(model.isAbsent);
  108. studyInfo.setIsHomeWorkDone(model.isHomeWorkDone);
  109. if (model.isHomeWorkDone == 0) {
  110. studyInfo.setHomeworks(model.homeWorkController!.text);
  111. }
  112. studyInfo.setDifficulty(model.difficulty);
  113. studyInfo.setIsTroublesSolved(1);
  114. if (model.difficulty == 2) {
  115. studyInfo.setIsTroublesSolved(0);
  116. studyInfo.setTroubles(model.troubleController!.text);
  117. }
  118. // 今日首次?
  119. List<StudyInfo> localStudyInfo = (await StudyInfoMapper().selectWhere(
  120. "date > ${ConvertUtils.dateOfDateTime(now).millisecondsSinceEpoch}"))!;
  121. if (localStudyInfo.isEmpty){
  122. // 今日首次
  123. // 增加金币
  124. UserProvider userProvider =
  125. Provider.of<UserProvider>(context, listen: false);
  126. if (userProvider.token != null) {
  127. int? increasedCoin = await Repository.getInstance()!
  128. .increaseCoin(context, userProvider.uid, userProvider.token);
  129. if (increasedCoin != null) {
  130. await PopMenus.coinAdd(
  131. context: context, addedCoins: increasedCoin);
  132. userProvider.coins += increasedCoin;
  133. userProvider.refresh();
  134. }
  135. }
  136. }
  137. // 插入
  138. await StudyInfoMapper().insert(studyInfo);
  139. await Provider.of<DataProvider>(context,listen: false).loadStudyInfoData();
  140. Navigator.of(context).pop();
  141. }
  142. }
  143. // view
  144. class _StudyInfoRecordingPageView extends StatelessWidget {
  145. @override
  146. Widget build(BuildContext context) {
  147. StudyInfoRecordingPageService service =
  148. Provider.of<StudyInfoRecordingPageService>(context, listen: false);
  149. StudyInfoRecordingPageModel model =
  150. Provider.of<StudyInfoRecordingPageModel>(context, listen: true);
  151. return Scaffold(
  152. appBar: AppBar(
  153. title: Text(I18N.of("记录课程学习")),
  154. ),
  155. body: Padding(
  156. padding: EdgeInsets.all(16),
  157. child: ListView(
  158. children: <Widget>[
  159. Padding(
  160. padding: EdgeInsets.only(top: 10, bottom: 10),
  161. child: TextFormField(
  162. controller: model.courseNameController,
  163. decoration: InputDecoration(
  164. border: OutlineInputBorder(),
  165. labelText: I18N.of("课程主题"),
  166. ),
  167. ),
  168. ),
  169. Row(
  170. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  171. children: <Widget>[
  172. Text(I18N.of("是否迟到")),
  173. Row(
  174. children: [I18N.of("是"), 1, I18N.of("否"), 0].map((i) {
  175. if (i is int) {
  176. return Radio<int>(
  177. value: i,
  178. groupValue: model.isLate,
  179. onChanged: (i) => service.setIsLate(context, i),
  180. );
  181. } else if (i is String) {
  182. return Text(i);
  183. }
  184. return Container();
  185. }).toList(),
  186. )
  187. ],
  188. ),
  189. Row(
  190. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  191. children: <Widget>[
  192. Text(I18N.of("是否缺席")),
  193. Row(
  194. children: [I18N.of("是"), 1, I18N.of("否"), 0].map((i) {
  195. if (i is int) {
  196. return Radio<int>(
  197. value: i,
  198. groupValue: model.isAbsent,
  199. onChanged: (i) => service.setIsAbsent(context, i),
  200. );
  201. } else if (i is String) {
  202. return Text(i);
  203. }
  204. return Container();
  205. }).toList(),
  206. )
  207. ],
  208. ),
  209. Row(
  210. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  211. children: <Widget>[
  212. Text(I18N.of("作业是否完成")),
  213. Row(
  214. children: [I18N.of("是"), 1, I18N.of("否"), 0].map((i) {
  215. if (i is int) {
  216. return Radio<int>(
  217. value: i,
  218. groupValue: model.isHomeWorkDone,
  219. onChanged: (i) => service.setIsHomeWorkDone(context, i),
  220. );
  221. } else if (i is String) {
  222. return Text(i);
  223. }
  224. return Container();
  225. }).toList(),
  226. )
  227. ],
  228. ),
  229. Padding(
  230. padding: EdgeInsets.only(top: 10, bottom: 10),
  231. child: TextFormField(
  232. enabled: model.isHomeWorkDone == 0,
  233. maxLines: model.isHomeWorkDone == 0 ? 5 : 1,
  234. controller: model.homeWorkController,
  235. decoration: InputDecoration(
  236. border: OutlineInputBorder(),
  237. labelText: I18N.of("未完成的作业"),
  238. ),
  239. ),
  240. ),
  241. Row(
  242. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  243. children: <Widget>[
  244. Text(I18N.of("课程难度")),
  245. Row(
  246. children: [
  247. I18N.of("简单"),
  248. 0,
  249. I18N.of("一般"),
  250. 1,
  251. I18N.of("困难"),
  252. 2
  253. ].map((i) {
  254. if (i is int) {
  255. return Radio<int>(
  256. value: i,
  257. groupValue: model.difficulty,
  258. onChanged: (i) => service.setDifficulty(context, i),
  259. );
  260. } else if (i is String) {
  261. return Text(i);
  262. }
  263. return Container();
  264. }).toList(),
  265. )
  266. ],
  267. ),
  268. Padding(
  269. padding: EdgeInsets.only(top: 10, bottom: 10),
  270. child: Stack(
  271. children: <Widget>[
  272. TextFormField(
  273. enabled: model.difficulty == 2,
  274. maxLines: model.difficulty == 2 ? 5 : 1,
  275. controller: model.troubleController,
  276. decoration: InputDecoration(
  277. border: OutlineInputBorder(),
  278. labelText: I18N.of("遇到的问题"),
  279. hintText: I18N.of("支持MarkDown"),
  280. ),
  281. ),
  282. Row(
  283. mainAxisAlignment: MainAxisAlignment.end,
  284. children: <Widget>[
  285. IconButton(
  286. icon: Icon(
  287. Icons.zoom_out_map,
  288. color: model.difficulty != 2
  289. ? null
  290. : Theme.of(context).colorScheme.secondary,
  291. ),
  292. onPressed: model.difficulty != 2
  293. ? null
  294. : () => service.preview(context),
  295. ),
  296. ],
  297. ),
  298. ],
  299. ),
  300. ),
  301. ElevatedButton(
  302. style: ButtonStyle(
  303. backgroundColor: MaterialStateProperty.all(
  304. Theme.of(context).colorScheme.secondary),
  305. foregroundColor:
  306. MaterialStateProperty.all(Theme.of(context).cardColor)),
  307. child: Text(I18N.of("记录")),
  308. onPressed: () => service.record(context),
  309. ),
  310. ],
  311. ),
  312. ),
  313. );
  314. }
  315. }