Compare commits
72 Commits
39d0686b91
...
d7ad4912eb
| Author | SHA1 | Date |
|---|---|---|
|
|
d7ad4912eb | |
|
|
e4c00bf8d8 | |
|
|
76b15038c6 | |
|
|
25e95b44e0 | |
|
|
955d3254af | |
|
|
96203b02ae | |
|
|
aeb318f9d5 | |
|
|
9c66503154 | |
|
|
85a80c364a | |
|
|
ffc9fdd9c1 | |
|
|
bf3e2eb9e2 | |
|
|
2bf8ae88f6 | |
|
|
ad655b7cca | |
|
|
b2f50b10a6 | |
|
|
047965aede | |
|
|
6a963c20e2 | |
|
|
ee487e63bd | |
|
|
2ad03b6b20 | |
|
|
6d7857ccef | |
|
|
d793161d67 | |
|
|
7bb6072a75 | |
|
|
705945c270 | |
|
|
4dfab0f4c3 | |
|
|
fa9e9912d5 | |
|
|
be2c1e1e6b | |
|
|
9174e69bb0 | |
|
|
98b42e053c | |
|
|
84ece07e29 | |
|
|
78791e84da | |
|
|
a9a9b03deb | |
|
|
290d4efddf | |
|
|
e0814ba901 | |
|
|
1c159dbda3 | |
|
|
52321c54d0 | |
|
|
8e95d8791c | |
|
|
8e0522bc6b | |
|
|
c12976ded8 | |
|
|
dd8ae7724a | |
|
|
5d3d4b17a2 | |
|
|
e84eca79d2 | |
|
|
cea53d3544 | |
|
|
c653b10515 | |
|
|
4d7c48941f | |
|
|
9b96db5bca | |
|
|
001ac3a21b | |
|
|
c22e4f95bf | |
|
|
57642af805 | |
|
|
8130e8250a | |
|
|
e4c889fc6d | |
|
|
314638a3ae | |
|
|
72a04ceb10 | |
|
|
3293de1814 | |
|
|
8ef26ca793 | |
|
|
ea5a73d9a1 | |
|
|
199397ac3b | |
|
|
0143dc0da7 | |
|
|
68e3ed45f8 | |
|
|
195b6ba2b5 | |
|
|
9878d22822 | |
|
|
0fad2da7f6 | |
|
|
b8eceb80bb | |
|
|
7e1ce0ef72 | |
|
|
02a7b748e1 | |
|
|
046f8cda4d | |
|
|
1de02f27e2 | |
|
|
35eaa570d1 | |
|
|
cf76e6aa44 | |
|
|
2ca30595d9 | |
|
|
ff1b70d39d | |
|
|
624fb083df | |
|
|
e1db8ae9b9 | |
|
|
82befc0088 |
|
|
@ -200,3 +200,14 @@ marking_app/lib/common/model/job/job_report_knowledge_model.g.dart
|
||||||
marking_app/lib/common/model/job/job_report_question_deatil_model.g.dart
|
marking_app/lib/common/model/job/job_report_question_deatil_model.g.dart
|
||||||
marking_app/lib/common/model/job/job_do_marking_status_info.g.dart
|
marking_app/lib/common/model/job/job_do_marking_status_info.g.dart
|
||||||
marking_app/lib/common/model/report/small_question.g.dart
|
marking_app/lib/common/model/report/small_question.g.dart
|
||||||
|
marking_app/lib/pages/homework_correction/pages/job_list_participate_in_class.g.dart
|
||||||
|
marking_app/lib/common/model/job/job_favorite_model.g.dart
|
||||||
|
marking_app/lib/common/model/job/job_level_set_params.g.dart
|
||||||
|
marking_app/lib/common/model/job/job_student_goups.g.dart
|
||||||
|
marking_app/lib/common/model/job/job_student_level.g.dart
|
||||||
|
marking_app/lib/common/model/job/job_favorite_item_model.g.dart
|
||||||
|
marking_app/lib/pages/homework_correction/pages/job_favorite.g.dart
|
||||||
|
marking_app/lib/common/model/job/job_fav_student.g.dart
|
||||||
|
marking_app/lib/common/model/job/job_data_report.g.dart
|
||||||
|
marking_app/lib/common/model/job/job_student_history.g.dart
|
||||||
|
marking_app/lib/pages/homework_correction/job_personal_detail.g.dart
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,12 @@
|
||||||
<div class="content unicode" style="display: block;">
|
<div class="content unicode" style="display: block;">
|
||||||
<ul class="icon_lists dib-box">
|
<ul class="icon_lists dib-box">
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">Frame</div>
|
||||||
|
<div class="code-name">&#xe63e;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="dib">
|
<li class="dib">
|
||||||
<span class="icon iconfont"></span>
|
<span class="icon iconfont"></span>
|
||||||
<div class="name">Frame</div>
|
<div class="name">Frame</div>
|
||||||
|
|
@ -408,9 +414,9 @@
|
||||||
<pre><code class="language-css"
|
<pre><code class="language-css"
|
||||||
>@font-face {
|
>@font-face {
|
||||||
font-family: 'iconfont';
|
font-family: 'iconfont';
|
||||||
src: url('iconfont.woff2?t=1706671294868') format('woff2'),
|
src: url('iconfont.woff2?t=1710142362036') format('woff2'),
|
||||||
url('iconfont.woff?t=1706671294868') format('woff'),
|
url('iconfont.woff?t=1710142362036') format('woff'),
|
||||||
url('iconfont.ttf?t=1706671294868') format('truetype');
|
url('iconfont.ttf?t=1710142362036') format('truetype');
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
||||||
|
|
@ -436,6 +442,15 @@
|
||||||
<div class="content font-class">
|
<div class="content font-class">
|
||||||
<ul class="icon_lists dib-box">
|
<ul class="icon_lists dib-box">
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-Frame14"></span>
|
||||||
|
<div class="name">
|
||||||
|
Frame
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-Frame14
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="dib">
|
<li class="dib">
|
||||||
<span class="icon iconfont icon-Frame13"></span>
|
<span class="icon iconfont icon-Frame13"></span>
|
||||||
<div class="name">
|
<div class="name">
|
||||||
|
|
@ -967,6 +982,14 @@
|
||||||
<div class="content symbol">
|
<div class="content symbol">
|
||||||
<ul class="icon_lists dib-box">
|
<ul class="icon_lists dib-box">
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-Frame14"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">Frame</div>
|
||||||
|
<div class="code-name">#icon-Frame14</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="dib">
|
<li class="dib">
|
||||||
<svg class="icon svg-icon" aria-hidden="true">
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
<use xlink:href="#icon-Frame13"></use>
|
<use xlink:href="#icon-Frame13"></use>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "iconfont"; /* Project id 3423846 */
|
font-family: "iconfont"; /* Project id 3423846 */
|
||||||
src: url('iconfont.woff2?t=1706671294868') format('woff2'),
|
src: url('iconfont.woff2?t=1710142362036') format('woff2'),
|
||||||
url('iconfont.woff?t=1706671294868') format('woff'),
|
url('iconfont.woff?t=1710142362036') format('woff'),
|
||||||
url('iconfont.ttf?t=1706671294868') format('truetype');
|
url('iconfont.ttf?t=1710142362036') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
|
|
@ -13,6 +13,10 @@
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-Frame14:before {
|
||||||
|
content: "\e63e";
|
||||||
|
}
|
||||||
|
|
||||||
.icon-Frame13:before {
|
.icon-Frame13:before {
|
||||||
content: "\e63d";
|
content: "\e63d";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,13 @@
|
||||||
"css_prefix_text": "icon-",
|
"css_prefix_text": "icon-",
|
||||||
"description": "",
|
"description": "",
|
||||||
"glyphs": [
|
"glyphs": [
|
||||||
|
{
|
||||||
|
"icon_id": "39483566",
|
||||||
|
"name": "Frame",
|
||||||
|
"font_class": "Frame14",
|
||||||
|
"unicode": "e63e",
|
||||||
|
"unicode_decimal": 58942
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"icon_id": "39175701",
|
"icon_id": "39175701",
|
||||||
"name": "Frame",
|
"name": "Frame",
|
||||||
|
|
|
||||||
|
After Width: | Height: | Size: 790 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 273 B |
|
After Width: | Height: | Size: 537 B |
|
After Width: | Height: | Size: 371 B |
|
After Width: | Height: | Size: 326 B |
|
After Width: | Height: | Size: 465 B |
|
After Width: | Height: | Size: 290 B |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 833 B |
|
Before Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 983 B |
|
After Width: | Height: | Size: 997 B |
|
After Width: | Height: | Size: 443 B |
|
|
@ -1,6 +1,6 @@
|
||||||
# Uncomment this line to define a global platform for your project
|
# Uncomment this line to define a global platform for your project
|
||||||
# source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'
|
# source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'
|
||||||
platform :ios, '11.0'
|
platform :ios, '12.0'
|
||||||
|
|
||||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,6 @@ PODS:
|
||||||
- fluttertoast (0.0.2):
|
- fluttertoast (0.0.2):
|
||||||
- Flutter
|
- Flutter
|
||||||
- Toast
|
- Toast
|
||||||
- FMDB (2.7.5):
|
|
||||||
- FMDB/standard (= 2.7.5)
|
|
||||||
- FMDB/standard (2.7.5)
|
|
||||||
- image_picker_ios (0.0.1):
|
- image_picker_ios (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- install_plugin (2.0.0):
|
- install_plugin (2.0.0):
|
||||||
|
|
@ -30,7 +27,7 @@ PODS:
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- sqflite (0.0.3):
|
- sqflite (0.0.3):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FMDB (>= 2.7.5)
|
- FlutterMacOS
|
||||||
- Toast (4.0.0)
|
- Toast (4.0.0)
|
||||||
- url_launcher_ios (0.0.1):
|
- url_launcher_ios (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
|
@ -51,14 +48,13 @@ DEPENDENCIES:
|
||||||
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||||
- rive_common (from `.symlinks/plugins/rive_common/ios`)
|
- rive_common (from `.symlinks/plugins/rive_common/ios`)
|
||||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
- sqflite (from `.symlinks/plugins/sqflite/darwin`)
|
||||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||||
- wakelock (from `.symlinks/plugins/wakelock/ios`)
|
- wakelock (from `.symlinks/plugins/wakelock/ios`)
|
||||||
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`)
|
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- FMDB
|
|
||||||
- ReachabilitySwift
|
- ReachabilitySwift
|
||||||
- Toast
|
- Toast
|
||||||
|
|
||||||
|
|
@ -86,7 +82,7 @@ EXTERNAL SOURCES:
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
||||||
sqflite:
|
sqflite:
|
||||||
:path: ".symlinks/plugins/sqflite/ios"
|
:path: ".symlinks/plugins/sqflite/darwin"
|
||||||
url_launcher_ios:
|
url_launcher_ios:
|
||||||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||||
wakelock:
|
wakelock:
|
||||||
|
|
@ -99,21 +95,20 @@ SPEC CHECKSUMS:
|
||||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||||
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
|
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
|
||||||
fluttertoast: fafc4fa4d01a6a9e4f772ecd190ffa525e9e2d9c
|
fluttertoast: fafc4fa4d01a6a9e4f772ecd190ffa525e9e2d9c
|
||||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
image_picker_ios: 99dfe1854b4fa34d0364e74a78448a0151025425
|
||||||
image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5
|
|
||||||
install_plugin: b52f81470a1f37b006607bdf7ffc6031df43fe76
|
install_plugin: b52f81470a1f37b006607bdf7ffc6031df43fe76
|
||||||
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
|
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
|
||||||
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
|
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
|
||||||
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
|
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
|
||||||
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
||||||
rive_common: 8a159d68033a8b073e5853acc50f03aa486a2888
|
rive_common: 3a4c254c6e4db7e4b9e05daeb3d1f47ae4f7bf76
|
||||||
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
|
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
|
||||||
sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a
|
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
|
||||||
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
||||||
url_launcher_ios: bf5ce03e0e2088bad9cc378ea97fa0ed5b49673b
|
url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812
|
||||||
wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f
|
wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f
|
||||||
webview_flutter_wkwebview: 2e2d318f21a5e036e2c3f26171342e95908bd60a
|
webview_flutter_wkwebview: 4f3e50f7273d31e5500066ed267e3ae4309c5ae4
|
||||||
|
|
||||||
PODFILE CHECKSUM: 441579d1897b785684860026b910c66dadea2938
|
PODFILE CHECKSUM: 64629b724b9886c2d78e6972ff5ef90e370df047
|
||||||
|
|
||||||
COCOAPODS: 1.11.3
|
COCOAPODS: 1.11.3
|
||||||
|
|
|
||||||
|
|
@ -316,6 +316,7 @@
|
||||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
|
@ -334,7 +335,7 @@
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
|
|
@ -351,7 +352,7 @@
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
||||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "";
|
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "";
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 15;
|
CURRENT_PROJECT_VERSION = 20;
|
||||||
DEVELOPMENT_TEAM = CYDU583KN6;
|
DEVELOPMENT_TEAM = CYDU583KN6;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
|
@ -359,7 +360,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.93;
|
MARKETING_VERSION = 1.0.102;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.markingApp;
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.markingApp;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
|
|
@ -395,6 +396,7 @@
|
||||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
|
@ -419,7 +421,7 @@
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
|
@ -450,6 +452,7 @@
|
||||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
|
@ -468,7 +471,7 @@
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
|
|
@ -487,7 +490,7 @@
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
||||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "";
|
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "";
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 15;
|
CURRENT_PROJECT_VERSION = 20;
|
||||||
DEVELOPMENT_TEAM = CYDU583KN6;
|
DEVELOPMENT_TEAM = CYDU583KN6;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
|
@ -495,7 +498,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.93;
|
MARKETING_VERSION = 1.0.102;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.markingApp;
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.markingApp;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
|
|
@ -517,7 +520,7 @@
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
||||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "";
|
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "";
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 15;
|
CURRENT_PROJECT_VERSION = 20;
|
||||||
DEVELOPMENT_TEAM = CYDU583KN6;
|
DEVELOPMENT_TEAM = CYDU583KN6;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
|
@ -525,7 +528,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.93;
|
MARKETING_VERSION = 1.0.102;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.markingApp;
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.markingApp;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,10 @@ class RequestConfig {
|
||||||
static const devLoginBaseUrl = "http://192.168.2.9:6400"; // 基本请求接口
|
static const devLoginBaseUrl = "http://192.168.2.9:6400"; // 基本请求接口
|
||||||
static const devBaseUrlOfReport = "http://192.168.2.9:4000"; // 获取报告接口*/
|
static const devBaseUrlOfReport = "http://192.168.2.9:4000"; // 获取报告接口*/
|
||||||
|
|
||||||
static const devBaseUrl = "https://mk-hw.23544.com"; // 基本请求
|
static const devBaseUrl = "https://mhw.qwit.top"; // 基本请求
|
||||||
static const devLoginBaseUrl = "https://mk-hw.23544.com"; // 登录接口
|
static const devLoginBaseUrl = "https://mhw.qwit.top"; // 登录接口
|
||||||
static const devBaseUrlOfReport = "https://dc-api.23544.com"; // 获取报告接口
|
static const devBaseUrlOfReport = "https://mhw.qwit.top"; // 获取报告接口
|
||||||
|
// static const proBaseUrlOfHomework = "https://mhw.qwit.top/hw"; // 获取作业接口
|
||||||
|
|
||||||
/* 正式地址 */
|
/* 正式地址 */
|
||||||
static const proBaseUrl = "https://mk-hw.23544.com"; // 基本请求
|
static const proBaseUrl = "https://mk-hw.23544.com"; // 基本请求
|
||||||
|
|
@ -46,7 +47,10 @@ class RequestConfig {
|
||||||
|
|
||||||
// 私有化构造函数,防止外部直接实例化
|
// 私有化构造函数,防止外部直接实例化
|
||||||
// 私有化构造函数,防止外部直接实例化
|
// 私有化构造函数,防止外部直接实例化
|
||||||
RequestConfig._({required this.baseUrl, required this.baseUrlOfReport, required this.loginBaseUrl});
|
RequestConfig._(
|
||||||
|
{required this.baseUrl,
|
||||||
|
required this.baseUrlOfReport,
|
||||||
|
required this.loginBaseUrl});
|
||||||
|
|
||||||
factory RequestConfig() {
|
factory RequestConfig() {
|
||||||
if (_instance == null) {
|
if (_instance == null) {
|
||||||
|
|
@ -66,8 +70,10 @@ class RequestConfig {
|
||||||
newBaseUrlOfReport = devBaseUrlOfReport;
|
newBaseUrlOfReport = devBaseUrlOfReport;
|
||||||
newLoginBaseUrl = devLoginBaseUrl;
|
newLoginBaseUrl = devLoginBaseUrl;
|
||||||
}
|
}
|
||||||
_instance =
|
_instance = RequestConfig._(
|
||||||
RequestConfig._(baseUrl: newBaseUrl, baseUrlOfReport: newBaseUrlOfReport, loginBaseUrl: newLoginBaseUrl);
|
baseUrl: newBaseUrl,
|
||||||
|
baseUrlOfReport: newBaseUrlOfReport,
|
||||||
|
loginBaseUrl: newLoginBaseUrl);
|
||||||
}
|
}
|
||||||
return _instance!;
|
return _instance!;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
// 作业类型枚举
|
||||||
|
enum JobMarkingTypeEnum {
|
||||||
|
UNUSED(name: '未使用废弃', indexValue: 0),
|
||||||
|
JOB(name: '作业', indexValue: 1),
|
||||||
|
EXAMINATION(name: '考试', indexValue: 2);
|
||||||
|
|
||||||
|
const JobMarkingTypeEnum({required this.name, required this.indexValue});
|
||||||
|
final String name;
|
||||||
|
final int indexValue;
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,8 @@ class JobDoPapersStudentBus extends Object {
|
||||||
@JsonKey(name: 'studentName')
|
@JsonKey(name: 'studentName')
|
||||||
String studentName;
|
String studentName;
|
||||||
|
|
||||||
|
bool isFinish;
|
||||||
|
|
||||||
int pageIndex;
|
int pageIndex;
|
||||||
|
|
||||||
bool isFirst;
|
bool isFirst;
|
||||||
|
|
@ -19,6 +21,7 @@ class JobDoPapersStudentBus extends Object {
|
||||||
this.studentName,
|
this.studentName,
|
||||||
this.pageIndex,
|
this.pageIndex,
|
||||||
this.isFirst,
|
this.isFirst,
|
||||||
|
this.isFinish,
|
||||||
);
|
);
|
||||||
|
|
||||||
factory JobDoPapersStudentBus.fromJson(Map<String, dynamic> srcJson) => _$JobDoPapersStudentBusFromJson(srcJson);
|
factory JobDoPapersStudentBus.fromJson(Map<String, dynamic> srcJson) => _$JobDoPapersStudentBusFromJson(srcJson);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@ part 'job_collect_params.g.dart';
|
||||||
|
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class JobCollectParams extends Object {
|
class JobCollectParams extends Object {
|
||||||
|
@JsonKey(name: 'paperId')
|
||||||
|
int paperId;
|
||||||
|
|
||||||
@JsonKey(name: 'taskId')
|
@JsonKey(name: 'taskId')
|
||||||
int taskId;
|
int taskId;
|
||||||
|
|
||||||
|
|
@ -14,6 +17,7 @@ class JobCollectParams extends Object {
|
||||||
bool isCollect;
|
bool isCollect;
|
||||||
|
|
||||||
JobCollectParams(
|
JobCollectParams(
|
||||||
|
this.paperId,
|
||||||
this.taskId,
|
this.taskId,
|
||||||
this.studentId,
|
this.studentId,
|
||||||
this.isCollect,
|
this.isCollect,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,178 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_report_model.dart';
|
||||||
|
|
||||||
|
part 'job_data_report.g.dart';
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class JobDataReport extends Object {
|
||||||
|
@JsonKey(name: 'jobId')
|
||||||
|
int jobId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'jobName')
|
||||||
|
String jobName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'gradeName')
|
||||||
|
String gradeName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'className')
|
||||||
|
String? className;
|
||||||
|
|
||||||
|
@JsonKey(name: 'validCount')
|
||||||
|
int validCount;
|
||||||
|
|
||||||
|
@JsonKey(name: 'noAnswerCount')
|
||||||
|
int noAnswerCount;
|
||||||
|
|
||||||
|
@JsonKey(name: 'kgValidRate')
|
||||||
|
double kgValidRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'kgQuestionCount')
|
||||||
|
int kgQuestionCount;
|
||||||
|
|
||||||
|
@JsonKey(name: 'zgValidRate')
|
||||||
|
double zgValidRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'zgQuestionCount')
|
||||||
|
int zgQuestionCount;
|
||||||
|
|
||||||
|
bool sortType; // true 默认排序 ; false 未提交置顶
|
||||||
|
bool sortLevel;
|
||||||
|
bool hasUnrated;//有未批阅
|
||||||
|
|
||||||
|
@JsonKey(name: 'studentDetails')
|
||||||
|
List<StudentDetails> studentDetails;
|
||||||
|
|
||||||
|
@JsonKey(name: 'kgReport')
|
||||||
|
KgReport kgReport;
|
||||||
|
|
||||||
|
@JsonKey(name: 'zgReport')
|
||||||
|
ZgReport zgReport;
|
||||||
|
|
||||||
|
JobDataReport(this.jobId, this.jobName, this.gradeName, this.className, this.validCount, this.noAnswerCount,
|
||||||
|
this.kgValidRate, this.kgQuestionCount, this.zgValidRate, this.zgQuestionCount, this.studentDetails, this.kgReport,
|
||||||
|
this.zgReport,
|
||||||
|
[this.sortType = true,this.sortLevel = false,this.hasUnrated = false]) {
|
||||||
|
|
||||||
|
this.studentDetails.sort((a, b) {
|
||||||
|
int num1 = a.kgValidRate + a.zgValidRate;
|
||||||
|
int num2 = b.kgValidRate + b.zgValidRate;
|
||||||
|
return num2.compareTo(num1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
factory JobDataReport.fromJson(Map<String, dynamic> srcJson) => _$JobDataReportFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$JobDataReportToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class StudentDetails extends Object {
|
||||||
|
@JsonKey(name: 'studentId')
|
||||||
|
int? studentId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'studentName')
|
||||||
|
String? studentName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'kgValidCount')
|
||||||
|
int kgValidCount;
|
||||||
|
|
||||||
|
@JsonKey(name: 'kgValidRate')
|
||||||
|
int kgValidRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'zgValidCount')
|
||||||
|
int zgValidCount;
|
||||||
|
|
||||||
|
@JsonKey(name: 'zgValidRate')
|
||||||
|
int zgValidRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'kgDetails')
|
||||||
|
List<KgDetails> kgDetails;
|
||||||
|
|
||||||
|
@JsonKey(name: 'zgDetails')
|
||||||
|
List<KgDetails> zgDetails;
|
||||||
|
|
||||||
|
@JsonKey(name: 'readLevel')
|
||||||
|
int? readLevel;
|
||||||
|
|
||||||
|
@JsonKey(name: 'kgError')
|
||||||
|
int kgError;
|
||||||
|
|
||||||
|
@JsonKey(name: 'zgError')
|
||||||
|
int zgError;
|
||||||
|
|
||||||
|
@JsonKey(name: 'kgCorrect')
|
||||||
|
int kgCorrect;
|
||||||
|
|
||||||
|
@JsonKey(name: 'zgCorrect')
|
||||||
|
int zgCorrect;
|
||||||
|
|
||||||
|
@JsonKey(name: 'unrated')
|
||||||
|
int unrated;
|
||||||
|
|
||||||
|
//全部未做
|
||||||
|
@JsonKey(name: 'allNotDone')
|
||||||
|
bool allNotDone;
|
||||||
|
|
||||||
|
StudentDetails(
|
||||||
|
this.studentId,
|
||||||
|
this.studentName,
|
||||||
|
this.kgValidCount,
|
||||||
|
this.kgValidRate,
|
||||||
|
this.zgValidCount,
|
||||||
|
this.zgValidRate,
|
||||||
|
this.kgDetails,
|
||||||
|
this.zgDetails,
|
||||||
|
this.readLevel,
|
||||||
|
[this.kgError = 0,this.kgCorrect = 0,this.zgCorrect = 0,this.zgError = 0,this.unrated = 0,this.allNotDone = false]
|
||||||
|
);
|
||||||
|
|
||||||
|
factory StudentDetails.fromJson(Map<String, dynamic> srcJson) => _$StudentDetailsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$StudentDetailsToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class KgDetails extends Object {
|
||||||
|
@JsonKey(name: 'questionNo')
|
||||||
|
String questionNo;
|
||||||
|
|
||||||
|
@JsonKey(name: 'questionId')
|
||||||
|
int questionId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'partName')
|
||||||
|
String partName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'state')
|
||||||
|
int state;
|
||||||
|
|
||||||
|
@JsonKey(name: 'studentAnswer')
|
||||||
|
String? studentAnswer;
|
||||||
|
|
||||||
|
@JsonKey(name: 'questionAnswer')
|
||||||
|
String? questionAnswer;
|
||||||
|
|
||||||
|
@JsonKey(name: 'useTime')
|
||||||
|
int? useTime;
|
||||||
|
|
||||||
|
@JsonKey(name: 'annotateAnswers')
|
||||||
|
String? annotateAnswers;
|
||||||
|
|
||||||
|
@JsonKey(name: 'score')
|
||||||
|
double? score;
|
||||||
|
|
||||||
|
KgDetails(
|
||||||
|
this.questionNo,
|
||||||
|
this.questionId,
|
||||||
|
this.partName,
|
||||||
|
this.state,
|
||||||
|
this.studentAnswer,
|
||||||
|
this.questionAnswer,
|
||||||
|
this.useTime,
|
||||||
|
this.annotateAnswers,
|
||||||
|
this.score,
|
||||||
|
);
|
||||||
|
|
||||||
|
factory KgDetails.fromJson(Map<String, dynamic> srcJson) => _$KgDetailsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$KgDetailsToJson(this);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'job_fav_student.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class JobFavStudent extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'page')
|
||||||
|
int page;
|
||||||
|
|
||||||
|
@JsonKey(name: 'pageSize')
|
||||||
|
int pageSize;
|
||||||
|
|
||||||
|
@JsonKey(name: 'total')
|
||||||
|
int total;
|
||||||
|
|
||||||
|
@JsonKey(name: 'totalPages')
|
||||||
|
int totalPages;
|
||||||
|
|
||||||
|
@JsonKey(name: 'items')
|
||||||
|
List<Items> items;
|
||||||
|
|
||||||
|
@JsonKey(name: 'hasPrevPage')
|
||||||
|
bool hasPrevPage;
|
||||||
|
|
||||||
|
@JsonKey(name: 'hasNextPage')
|
||||||
|
bool hasNextPage;
|
||||||
|
|
||||||
|
JobFavStudent(this.page,this.pageSize,this.total,this.totalPages,this.items,this.hasPrevPage,this.hasNextPage,);
|
||||||
|
|
||||||
|
factory JobFavStudent.fromJson(Map<String, dynamic> srcJson) => _$JobFavStudentFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$JobFavStudentToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class Items extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'id')
|
||||||
|
String id;
|
||||||
|
|
||||||
|
@JsonKey(name: 'teacherId')
|
||||||
|
int teacherId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'teacherAccount')
|
||||||
|
String? teacherAccount;
|
||||||
|
|
||||||
|
@JsonKey(name: 'folderName')
|
||||||
|
String folderName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'jobId')
|
||||||
|
int jobId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'jobName')
|
||||||
|
String jobName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'studentId')
|
||||||
|
int studentId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'studentName')
|
||||||
|
String studentName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'className')
|
||||||
|
String className;
|
||||||
|
|
||||||
|
@JsonKey(name: 'questionPage')
|
||||||
|
int? questionPage;
|
||||||
|
|
||||||
|
@JsonKey(name: 'questionPicture')
|
||||||
|
String? questionPicture;
|
||||||
|
|
||||||
|
@JsonKey(name: 'createTime')
|
||||||
|
String createTime;
|
||||||
|
|
||||||
|
@JsonKey(name: 'schoolName')
|
||||||
|
String schoolName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'gradeName')
|
||||||
|
String gradeName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'studentClassName')
|
||||||
|
String studentClassName;
|
||||||
|
|
||||||
|
Items(this.id,this.teacherId,this.teacherAccount,this.folderName,this.jobId,this.jobName,this.studentId,this.studentName,this.className,this.questionPage,this.questionPicture,this.createTime,this.schoolName,this.gradeName,this.studentClassName,);
|
||||||
|
|
||||||
|
factory Items.fromJson(Map<String, dynamic> srcJson) => _$ItemsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$ItemsToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'job_favorite_item_model.g.dart';
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class JobFavoriteItemModel extends Object {
|
||||||
|
@JsonKey(name: 'studentId')
|
||||||
|
int studentId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'studentName')
|
||||||
|
String studentName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'createTime')
|
||||||
|
String createTime;
|
||||||
|
|
||||||
|
JobFavoriteItemModel(
|
||||||
|
this.studentId,
|
||||||
|
this.studentName,
|
||||||
|
this.createTime,
|
||||||
|
);
|
||||||
|
|
||||||
|
factory JobFavoriteItemModel.fromJson(Map<String, dynamic> srcJson) => _$JobFavoriteItemModelFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$JobFavoriteItemModelToJson(this);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'job_favorite_model.g.dart';
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class JobFavoriteModel extends Object {
|
||||||
|
@JsonKey(name: 'schoolId')
|
||||||
|
int schoolId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'gradeId')
|
||||||
|
int gradeId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'graduationYear')
|
||||||
|
String graduationYear;
|
||||||
|
|
||||||
|
@JsonKey(name: 'className')
|
||||||
|
String className;
|
||||||
|
|
||||||
|
@JsonKey(name: 'count')
|
||||||
|
int count;
|
||||||
|
|
||||||
|
JobFavoriteModel(
|
||||||
|
this.schoolId,
|
||||||
|
this.gradeId,
|
||||||
|
this.graduationYear,
|
||||||
|
this.className,
|
||||||
|
this.count,
|
||||||
|
);
|
||||||
|
|
||||||
|
factory JobFavoriteModel.fromJson(Map<String, dynamic> srcJson) => _$JobFavoriteModelFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$JobFavoriteModelToJson(this);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'job_level_set_params.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class JobLevelSetParams extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'studentGroupDetailId')
|
||||||
|
int studentGroupDetailId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'readLevel')
|
||||||
|
int readLevel;
|
||||||
|
|
||||||
|
JobLevelSetParams(this.studentGroupDetailId,this.readLevel,);
|
||||||
|
|
||||||
|
factory JobLevelSetParams.fromJson(Map<String, dynamic> srcJson) => _$JobLevelSetParamsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$JobLevelSetParamsToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -48,9 +48,36 @@ class JobReportModel extends Object {
|
||||||
@JsonKey(name: 'studentAnswerInfos')
|
@JsonKey(name: 'studentAnswerInfos')
|
||||||
List<StudentAnswerInfos> studentAnswerInfos;
|
List<StudentAnswerInfos> studentAnswerInfos;
|
||||||
|
|
||||||
|
@JsonKey(name: 'overallInfos')
|
||||||
|
Map<String,overallInfo> overallInfos;
|
||||||
|
|
||||||
@JsonKey(name: 'overallTitles')
|
@JsonKey(name: 'overallTitles')
|
||||||
List<OverallTitles> overallTitles;
|
List<OverallTitles> overallTitles;
|
||||||
|
|
||||||
|
@JsonKey(name: 'kgReport')
|
||||||
|
KgReport kgReport;
|
||||||
|
|
||||||
|
@JsonKey(name: 'zgReport')
|
||||||
|
ZgReport zgReport;
|
||||||
|
|
||||||
|
@JsonKey(name: 'noAnswerStudentNames')
|
||||||
|
List<String> noAnswerStudentNames;
|
||||||
|
|
||||||
|
@JsonKey(name: 'allCorrectStudentNames')
|
||||||
|
List<String> allCorrectStudentNames;
|
||||||
|
|
||||||
|
@JsonKey(name: 'validStudentNames')
|
||||||
|
List<String> validStudentNames;
|
||||||
|
|
||||||
|
@JsonKey(name: 'noAnswerStudents')
|
||||||
|
List<AnswerOkStudents>? noAnswerStudents;
|
||||||
|
|
||||||
|
@JsonKey(name: 'allCorrectStudents')
|
||||||
|
List<AnswerOkStudents>? allCorrectStudents;
|
||||||
|
|
||||||
|
@JsonKey(name: 'validStudents')
|
||||||
|
List<AnswerOkStudents>? validStudents;
|
||||||
|
|
||||||
// 前端自定义 -- 全对学生
|
// 前端自定义 -- 全对学生
|
||||||
@JsonKey(name: 'allpairsStudents')
|
@JsonKey(name: 'allpairsStudents')
|
||||||
List<StudentAnswerInfos>? allpairsStudents;
|
List<StudentAnswerInfos>? allpairsStudents;
|
||||||
|
|
@ -82,7 +109,17 @@ class JobReportModel extends Object {
|
||||||
this.knowledgeInfos,
|
this.knowledgeInfos,
|
||||||
this.questionAnswerInfos,
|
this.questionAnswerInfos,
|
||||||
this.studentAnswerInfos,
|
this.studentAnswerInfos,
|
||||||
this.overallTitles, [
|
this.overallInfos,
|
||||||
|
this.overallTitles,
|
||||||
|
this.kgReport,
|
||||||
|
this.zgReport,
|
||||||
|
this.noAnswerStudentNames,
|
||||||
|
this.allCorrectStudentNames,
|
||||||
|
this.validStudentNames,
|
||||||
|
this.noAnswerStudents,
|
||||||
|
this.allCorrectStudents,
|
||||||
|
this.validStudents,
|
||||||
|
[
|
||||||
this.allpairsStudents,
|
this.allpairsStudents,
|
||||||
this.passStudents,
|
this.passStudents,
|
||||||
this.disqualifiedStudents,
|
this.disqualifiedStudents,
|
||||||
|
|
@ -265,12 +302,157 @@ class OverallTitles extends Object {
|
||||||
@JsonKey(name: 'count')
|
@JsonKey(name: 'count')
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
|
@JsonKey(name: 'studentNames')
|
||||||
|
List<String> studentNames;
|
||||||
|
|
||||||
|
|
||||||
OverallTitles(
|
OverallTitles(
|
||||||
this.title,
|
this.title,
|
||||||
this.count,
|
this.count,
|
||||||
|
this.studentNames,
|
||||||
);
|
);
|
||||||
|
|
||||||
factory OverallTitles.fromJson(Map<String, dynamic> srcJson) => _$OverallTitlesFromJson(srcJson);
|
factory OverallTitles.fromJson(Map<String, dynamic> srcJson) => _$OverallTitlesFromJson(srcJson);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => _$OverallTitlesToJson(this);
|
Map<String, dynamic> toJson() => _$OverallTitlesToJson(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class KgReport extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'correctRate')
|
||||||
|
int correctRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'details')
|
||||||
|
List<Details> details;
|
||||||
|
|
||||||
|
KgReport(this.correctRate,this.details,);
|
||||||
|
|
||||||
|
factory KgReport.fromJson(Map<String, dynamic> srcJson) => _$KgReportFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$KgReportToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class ZgReport extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'correctRate')
|
||||||
|
int correctRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'details')
|
||||||
|
List<Details> details;
|
||||||
|
|
||||||
|
ZgReport(this.correctRate,this.details,);
|
||||||
|
|
||||||
|
factory ZgReport.fromJson(Map<String, dynamic> srcJson) => _$ZgReportFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$ZgReportToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class Details extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'questionNo')
|
||||||
|
String questionNo;
|
||||||
|
|
||||||
|
@JsonKey(name: 'questionId')
|
||||||
|
int questionId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'partName')
|
||||||
|
String partName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'questionType')
|
||||||
|
int questionType;
|
||||||
|
|
||||||
|
@JsonKey(name: 'validRate')
|
||||||
|
int validRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'validCount')
|
||||||
|
String validCount;
|
||||||
|
|
||||||
|
/* @JsonKey(name: 'validStudentNames')
|
||||||
|
List<String> validStudentNames;*/
|
||||||
|
|
||||||
|
@JsonKey(name: 'correctRate')
|
||||||
|
int correctRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'questionAnswer')
|
||||||
|
String questionAnswer;
|
||||||
|
|
||||||
|
@JsonKey(name: 'questionPicture')
|
||||||
|
String? questionPicture;
|
||||||
|
|
||||||
|
@JsonKey(name: 'priorityGeneral')
|
||||||
|
String priorityGeneral;
|
||||||
|
|
||||||
|
@JsonKey(name: 'priorityStudentNames')
|
||||||
|
List<String> priorityStudentNames;
|
||||||
|
|
||||||
|
@JsonKey(name: 'answerNgStudentNames')
|
||||||
|
List<String> answerNgStudentNames;
|
||||||
|
|
||||||
|
@JsonKey(name: 'noAnswerStudentNames')
|
||||||
|
List<String> noAnswerStudentNames;
|
||||||
|
|
||||||
|
@JsonKey(name: 'answerOkStudentNames')
|
||||||
|
List<String> answerOkStudentNames;
|
||||||
|
|
||||||
|
@JsonKey(name: 'noAnswerStudents')
|
||||||
|
List<AnswerOkStudents>? noAnswerStudents;
|
||||||
|
|
||||||
|
@JsonKey(name: 'answerOkStudents')
|
||||||
|
List<AnswerOkStudents>? answerOkStudents;
|
||||||
|
|
||||||
|
@JsonKey(name: 'answerNgStudents')
|
||||||
|
List<AnswerOkStudents>? answerNgStudents;
|
||||||
|
|
||||||
|
@JsonKey(name: 'priorityStudents')
|
||||||
|
List<AnswerOkStudents>? priorityStudents;
|
||||||
|
|
||||||
|
Details(this.questionNo,this.questionId,this.partName,this.questionType,this.validRate, this.noAnswerStudents,
|
||||||
|
this.answerOkStudents,this.answerNgStudents,this.priorityStudents,
|
||||||
|
this.validCount,this.correctRate,this.questionAnswer,this.questionPicture,this.priorityGeneral,
|
||||||
|
this.priorityStudentNames,this.answerNgStudentNames,this.noAnswerStudentNames,this.answerOkStudentNames);
|
||||||
|
|
||||||
|
factory Details.fromJson(Map<String, dynamic> srcJson) => _$DetailsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$DetailsToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class overallInfo extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'count')
|
||||||
|
int count;
|
||||||
|
|
||||||
|
@JsonKey(name: 'students')
|
||||||
|
List<AnswerOkStudents> students;
|
||||||
|
|
||||||
|
overallInfo(this.count,this.students,);
|
||||||
|
|
||||||
|
factory overallInfo.fromJson(Map<String, dynamic> srcJson) => _$overallInfoFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$overallInfoToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class AnswerOkStudents extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'id')
|
||||||
|
int id;
|
||||||
|
|
||||||
|
@JsonKey(name: 'name')
|
||||||
|
String name;
|
||||||
|
|
||||||
|
AnswerOkStudents(this.id,this.name,);
|
||||||
|
|
||||||
|
factory AnswerOkStudents.fromJson(Map<String, dynamic> srcJson) => _$AnswerOkStudentsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$AnswerOkStudentsToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part "job_student_goups.g.dart";
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class JobStudentGroups extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'groupId')
|
||||||
|
int groupId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'groupName')
|
||||||
|
String groupName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'classNames')
|
||||||
|
List<String> classNames;
|
||||||
|
|
||||||
|
JobStudentGroups(this.groupId,this.groupName,this.classNames,);
|
||||||
|
|
||||||
|
factory JobStudentGroups.fromJson(Map<String, dynamic> srcJson) => _$JobStudentGroupsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$JobStudentGroupsToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,154 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'job_student_history.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class JobStudentHistory extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'correctRate')
|
||||||
|
int correctRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'objectiveCorrectRate')
|
||||||
|
int objectiveCorrectRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'subjectiveCorrectRate')
|
||||||
|
int subjectiveCorrectRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'pagedList')
|
||||||
|
PagedList pagedList;
|
||||||
|
|
||||||
|
JobStudentHistory(this.correctRate,this.objectiveCorrectRate,this.subjectiveCorrectRate,this.pagedList,);
|
||||||
|
|
||||||
|
factory JobStudentHistory.fromJson(Map<String, dynamic> srcJson) => _$JobStudentHistoryFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$JobStudentHistoryToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class PagedList extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'page')
|
||||||
|
int page;
|
||||||
|
|
||||||
|
@JsonKey(name: 'pageSize')
|
||||||
|
int pageSize;
|
||||||
|
|
||||||
|
@JsonKey(name: 'total')
|
||||||
|
int total;
|
||||||
|
|
||||||
|
@JsonKey(name: 'totalPages')
|
||||||
|
int totalPages;
|
||||||
|
|
||||||
|
@JsonKey(name: 'items')
|
||||||
|
List<Items> items;
|
||||||
|
|
||||||
|
@JsonKey(name: 'hasPrevPage')
|
||||||
|
bool hasPrevPage;
|
||||||
|
|
||||||
|
@JsonKey(name: 'hasNextPage')
|
||||||
|
bool hasNextPage;
|
||||||
|
|
||||||
|
PagedList(this.page,this.pageSize,this.total,this.totalPages,this.items,this.hasPrevPage,this.hasNextPage,);
|
||||||
|
|
||||||
|
factory PagedList.fromJson(Map<String, dynamic> srcJson) => _$PagedListFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$PagedListToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class Items extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'id')
|
||||||
|
int id;
|
||||||
|
|
||||||
|
@JsonKey(name: 'name')
|
||||||
|
String name;
|
||||||
|
|
||||||
|
@JsonKey(name: 'subject')
|
||||||
|
int subject;
|
||||||
|
|
||||||
|
@JsonKey(name: 'subjectName')
|
||||||
|
String subjectName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'publishTime')
|
||||||
|
String publishTime;
|
||||||
|
|
||||||
|
@JsonKey(name: 'isPaper')
|
||||||
|
bool isPaper;
|
||||||
|
|
||||||
|
@JsonKey(name: 'studentJobId')
|
||||||
|
int studentJobId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'correctRate')
|
||||||
|
int correctRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'objectiveCorrectRate')
|
||||||
|
int objectiveCorrectRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'objectiveDtls')
|
||||||
|
List<SubjectiveDtls> objectiveDtls;
|
||||||
|
|
||||||
|
@JsonKey(name: 'subjectiveCorrectRate')
|
||||||
|
int subjectiveCorrectRate;
|
||||||
|
|
||||||
|
@JsonKey(name: 'subjectiveDtls')
|
||||||
|
List<SubjectiveDtls> subjectiveDtls;
|
||||||
|
|
||||||
|
@JsonKey(name: 'gradeName')
|
||||||
|
String gradeName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'className')
|
||||||
|
String className;
|
||||||
|
|
||||||
|
//全部未做
|
||||||
|
@JsonKey(name: 'allNotDone')
|
||||||
|
bool allNotDone;
|
||||||
|
|
||||||
|
Items(this.id,this.name,this.subject,this.subjectName,this.publishTime,this.gradeName,this.className,this.isPaper,this.studentJobId,this.correctRate,this.objectiveCorrectRate,this.objectiveDtls,this.subjectiveCorrectRate,this.subjectiveDtls,[this.allNotDone = false,]);
|
||||||
|
|
||||||
|
factory Items.fromJson(Map<String, dynamic> srcJson) => _$ItemsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$ItemsToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class SubjectiveDtls extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'studentJobId')
|
||||||
|
int studentJobId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'questionId')
|
||||||
|
int questionId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'questionNo')
|
||||||
|
String questionNo;
|
||||||
|
|
||||||
|
@JsonKey(name: 'questionType')
|
||||||
|
int questionType;
|
||||||
|
|
||||||
|
@JsonKey(name: 'useTime')
|
||||||
|
int useTime;
|
||||||
|
|
||||||
|
@JsonKey(name: 'score')
|
||||||
|
double score;
|
||||||
|
|
||||||
|
@JsonKey(name: 'annotateTime')
|
||||||
|
String? annotateTime;
|
||||||
|
|
||||||
|
@JsonKey(name: 'state')
|
||||||
|
int state;
|
||||||
|
|
||||||
|
SubjectiveDtls(this.studentJobId,this.questionId,this.questionNo,this.questionType,this.useTime,this.score,this.annotateTime,this.state,);
|
||||||
|
|
||||||
|
factory SubjectiveDtls.fromJson(Map<String, dynamic> srcJson) => _$SubjectiveDtlsFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$SubjectiveDtlsToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'job_student_level.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class JobStudentLevel extends Object {
|
||||||
|
|
||||||
|
@JsonKey(name: 'studentGroupDetailId')
|
||||||
|
int studentGroupDetailId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'studentId')
|
||||||
|
int studentId;
|
||||||
|
|
||||||
|
@JsonKey(name: 'studentName')
|
||||||
|
String studentName;
|
||||||
|
|
||||||
|
@JsonKey(name: 'createTime')
|
||||||
|
String createTime;
|
||||||
|
|
||||||
|
@JsonKey(name: 'readLevel')
|
||||||
|
int readLevel;
|
||||||
|
|
||||||
|
JobStudentLevel(this.studentGroupDetailId,this.studentId,this.studentName,this.createTime,this.readLevel,);
|
||||||
|
|
||||||
|
factory JobStudentLevel.fromJson(Map<String, dynamic> srcJson) => _$JobStudentLevelFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$JobStudentLevelToJson(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:marking_app/common/model/enum/job_marking_type_enum.dart';
|
||||||
|
|
||||||
part 'job_task_item.g.dart';
|
part 'job_task_item.g.dart';
|
||||||
|
|
||||||
|
|
@ -40,8 +41,8 @@ class JobTaskItem extends Object {
|
||||||
@JsonKey(name: 'precision')
|
@JsonKey(name: 'precision')
|
||||||
double precision;
|
double precision;
|
||||||
|
|
||||||
@JsonKey(name: 'markingTasks')
|
// @JsonKey(name: 'markingTasks')
|
||||||
List<MarkingTasks> markingTasks;
|
// List<MarkingTasks> markingTasks;
|
||||||
|
|
||||||
@JsonKey(name: 'createTime')
|
@JsonKey(name: 'createTime')
|
||||||
String createTime;
|
String createTime;
|
||||||
|
|
@ -49,6 +50,14 @@ class JobTaskItem extends Object {
|
||||||
@JsonKey(name: 'progressPercentage')
|
@JsonKey(name: 'progressPercentage')
|
||||||
double progressPercentage; // 进度百分比
|
double progressPercentage; // 进度百分比
|
||||||
|
|
||||||
|
@JsonKey(name: 'markingType')
|
||||||
|
int markingType; // 考试类型
|
||||||
|
|
||||||
|
@JsonKey(name: 'markingTypeEnum')
|
||||||
|
JobMarkingTypeEnum markingTypeEnum; // 考试类型
|
||||||
|
|
||||||
|
int taskCount; // 参与班级数量
|
||||||
|
|
||||||
JobTaskItem(
|
JobTaskItem(
|
||||||
this.id,
|
this.id,
|
||||||
this.title,
|
this.title,
|
||||||
|
|
@ -62,10 +71,12 @@ class JobTaskItem extends Object {
|
||||||
this.objectivePrecision,
|
this.objectivePrecision,
|
||||||
this.subjectivePrecision,
|
this.subjectivePrecision,
|
||||||
this.precision,
|
this.precision,
|
||||||
this.markingTasks,
|
// this.markingTasks,
|
||||||
this.createTime, {
|
this.createTime,
|
||||||
this.progressPercentage = 0,
|
this.markingType,
|
||||||
}) {
|
this.taskCount,
|
||||||
|
{this.progressPercentage = 0,
|
||||||
|
this.markingTypeEnum = JobMarkingTypeEnum.UNUSED}) {
|
||||||
try {
|
try {
|
||||||
progressPercentage = (finishCount / totalCount) * 100;
|
progressPercentage = (finishCount / totalCount) * 100;
|
||||||
if (progressPercentage.isNaN) {
|
if (progressPercentage.isNaN) {
|
||||||
|
|
@ -76,6 +87,11 @@ class JobTaskItem extends Object {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
progressPercentage = 0;
|
progressPercentage = 0;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
markingTypeEnum = JobMarkingTypeEnum.values[this.markingType];
|
||||||
|
} catch (e) {
|
||||||
|
markingTypeEnum = JobMarkingTypeEnum.UNUSED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
factory JobTaskItem.fromJson(Map<String, dynamic> srcJson) => _$JobTaskItemFromJson(srcJson);
|
factory JobTaskItem.fromJson(Map<String, dynamic> srcJson) => _$JobTaskItemFromJson(srcJson);
|
||||||
|
|
@ -91,6 +107,10 @@ class MarkingTasks extends Object {
|
||||||
@JsonKey(name: 'className')
|
@JsonKey(name: 'className')
|
||||||
String className;
|
String className;
|
||||||
|
|
||||||
|
int dpcSchoolId;
|
||||||
|
|
||||||
|
int dpcGradeId;
|
||||||
|
|
||||||
@JsonKey(name: 'teacherName')
|
@JsonKey(name: 'teacherName')
|
||||||
String teacherName;
|
String teacherName;
|
||||||
|
|
||||||
|
|
@ -132,8 +152,14 @@ class MarkingTasks extends Object {
|
||||||
@JsonKey(name: 'canGoReview')
|
@JsonKey(name: 'canGoReview')
|
||||||
bool canGoReview; // 是否能批阅
|
bool canGoReview; // 是否能批阅
|
||||||
|
|
||||||
|
/** 前端自定义字段 */
|
||||||
|
@JsonKey(name: 'collectNumber')
|
||||||
|
int collectNumber; // 是否能批阅
|
||||||
|
|
||||||
MarkingTasks(
|
MarkingTasks(
|
||||||
this.id,
|
this.id,
|
||||||
|
this.dpcSchoolId,
|
||||||
|
this.dpcGradeId,
|
||||||
this.className,
|
this.className,
|
||||||
this.teacherName,
|
this.teacherName,
|
||||||
this.isFinish,
|
this.isFinish,
|
||||||
|
|
@ -141,13 +167,14 @@ class MarkingTasks extends Object {
|
||||||
this.commitStudentCount,
|
this.commitStudentCount,
|
||||||
this.totalCount,
|
this.totalCount,
|
||||||
this.finishCount,
|
this.finishCount,
|
||||||
|
this.precision,
|
||||||
this.objectivePrecision,
|
this.objectivePrecision,
|
||||||
this.subjectivePrecision,
|
this.subjectivePrecision,
|
||||||
this.precision,
|
|
||||||
this.canMarking, {
|
this.canMarking, {
|
||||||
this.progressPercentage = 0,
|
this.progressPercentage = 0,
|
||||||
this.canGoReview = true,
|
this.canGoReview = true,
|
||||||
this.finishTime,
|
this.finishTime,
|
||||||
|
this.collectNumber = 0,
|
||||||
}) {
|
}) {
|
||||||
try {
|
try {
|
||||||
progressPercentage = (finishCount / totalCount) * 100;
|
progressPercentage = (finishCount / totalCount) * 100;
|
||||||
|
|
@ -158,6 +185,11 @@ class MarkingTasks extends Object {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
progressPercentage = 0;
|
progressPercentage = 0;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
precision = precision / 100;
|
||||||
|
objectivePrecision = objectivePrecision / 100;
|
||||||
|
subjectivePrecision = subjectivePrecision / 100;
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
canGoReview = totalCount > 0 && canMarking && !isFinish;
|
canGoReview = totalCount > 0 && canMarking && !isFinish;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,9 @@ class Questions extends Object {
|
||||||
@JsonKey(name: 'score')
|
@JsonKey(name: 'score')
|
||||||
double? score;
|
double? score;
|
||||||
|
|
||||||
Questions(this.questionNo, this.answer, [this.score]);
|
double accuracy; // 当前题正确率
|
||||||
|
|
||||||
|
Questions(this.questionNo, this.answer, this.accuracy, [this.score]);
|
||||||
|
|
||||||
factory Questions.fromJson(Map<String, dynamic> srcJson) => _$QuestionsFromJson(srcJson);
|
factory Questions.fromJson(Map<String, dynamic> srcJson) => _$QuestionsFromJson(srcJson);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,22 @@ class MarkingListParams extends BasePage {
|
||||||
@JsonKey(name: 'PageType')
|
@JsonKey(name: 'PageType')
|
||||||
int pageType;
|
int pageType;
|
||||||
|
|
||||||
|
String? startTime;
|
||||||
|
String? endTime;
|
||||||
|
|
||||||
|
int? markingType; // 1 作业 2考试
|
||||||
|
|
||||||
MarkingListParams({
|
MarkingListParams({
|
||||||
required this.isFinish,
|
required this.isFinish,
|
||||||
required this.pageType,
|
required this.pageType,
|
||||||
required page,
|
required page,
|
||||||
required limit,
|
required limit,
|
||||||
}) : super(page, limit);
|
this.markingType,
|
||||||
|
this.startTime,
|
||||||
|
this.endTime,
|
||||||
|
}) : super(page, limit) {
|
||||||
|
this.markingType ??= 1;
|
||||||
|
}
|
||||||
|
|
||||||
factory MarkingListParams.fromJson(Map<String, dynamic> srcJson) => _$MarkingListParamsFromJson(srcJson);
|
factory MarkingListParams.fromJson(Map<String, dynamic> srcJson) => _$MarkingListParamsFromJson(srcJson);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:marking_app/routes/RouterManager.dart';
|
||||||
|
import 'package:marking_app/utils/anti_shake_throttling.dart';
|
||||||
|
|
||||||
|
// 返回首页
|
||||||
|
class ReturnToHomepage extends StatelessWidget {
|
||||||
|
final Color? bgColor;
|
||||||
|
const ReturnToHomepage({super.key,this.bgColor = const Color.fromRGBO(135, 135, 135, 1)});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () => easyThrottle('RETURN_TO_HOMEPAGE', () {
|
||||||
|
Navigator.of(context).popUntil(ModalRoute.withName(RouterManager.root));
|
||||||
|
}),
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.only(right: 4.5.w),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Icon(Icons.home_rounded, size: 22.sp, color: bgColor),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,7 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
@ -83,6 +84,28 @@ class _MyAppState extends State<MyApp> {
|
||||||
title: '远轩阅卷系统',
|
title: '远轩阅卷系统',
|
||||||
navigatorKey: TheGlobal.navigatorKey,
|
navigatorKey: TheGlobal.navigatorKey,
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
|
// locale: const Locale('zh', 'CN'), // 中文简体 ,
|
||||||
|
// supportedLocales: [
|
||||||
|
// const Locale('zh', 'CN'), // 中文简体
|
||||||
|
// // 其他支持的locale可以在这里添加
|
||||||
|
// ],
|
||||||
|
// 这里是国际化支持,确保添加flutter_localizations依赖
|
||||||
|
supportedLocales: [
|
||||||
|
const Locale('zh', 'CN'), // 中文简体
|
||||||
|
// 其他支持的locale可以在这里添加
|
||||||
|
],
|
||||||
|
localizationsDelegates: [
|
||||||
|
// ...其他delegates
|
||||||
|
GlobalMaterialLocalizations.delegate,
|
||||||
|
GlobalWidgetsLocalizations.delegate,
|
||||||
|
GlobalCupertinoLocalizations.delegate, // 如果你使用了Cupertino风格的组件
|
||||||
|
// ...添加其他必要的delegates
|
||||||
|
],
|
||||||
|
localeResolutionCallback: (locale, supportedLocales) {
|
||||||
|
// 在这里可以实现自定义的locale解析逻辑
|
||||||
|
// 如果需要,返回你想要的Locale对象
|
||||||
|
return locale;
|
||||||
|
},
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
primarySwatch: createMaterialColor(const Color.fromRGBO(46, 91, 255, 1)),
|
primarySwatch: createMaterialColor(const Color.fromRGBO(46, 91, 255, 1)),
|
||||||
// textTheme: Typography.englishLike2018.apply(fontSizeFactor: 1.sp,),
|
// textTheme: Typography.englishLike2018.apply(fontSizeFactor: 1.sp,),
|
||||||
|
|
|
||||||
|
|
@ -357,29 +357,6 @@ Widget $theTabBar({required TabController controller, ValueChanged<int>? onTap})
|
||||||
isScrollable: true,
|
isScrollable: true,
|
||||||
labelColor: const Color.fromRGBO(45, 56, 76, 1),
|
labelColor: const Color.fromRGBO(45, 56, 76, 1),
|
||||||
indicatorSize: TabBarIndicatorSize.label, // 设置指示器高度和标签一样高
|
indicatorSize: TabBarIndicatorSize.label, // 设置指示器高度和标签一样高
|
||||||
// labelPadding: EdgeInsets.symmetric(vertical: 0), // 设置标签的内边距
|
|
||||||
// background: linear-gradient(270deg, #2E5BFF 30.23%, rgba(46, 91, 255, 0.00) 96.59%);
|
|
||||||
// indicatorColor: RectangleIndicator(),
|
|
||||||
// indicator: BoxDecoration(
|
|
||||||
// gradient: LinearGradient(
|
|
||||||
// begin: Alignment.centerLeft,
|
|
||||||
// end: Alignment.centerRight,
|
|
||||||
// colors: [
|
|
||||||
// Color.fromRGBO(46, 91, 255, 0.00),
|
|
||||||
// Color(0xFF2E5BFF),
|
|
||||||
// ],
|
|
||||||
// stops: [0.3023, 0.9659],
|
|
||||||
// // transform: GradientRotation(3.14 / 2), //将270度转换为弧度
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// indicator: BoxDecoration(
|
|
||||||
// // 设置指示器样式
|
|
||||||
// gradient: LinearGradient(
|
|
||||||
// colors: [Colors.yellow, Colors.green], // 设置渐变色
|
|
||||||
// begin: Alignment.centerLeft,
|
|
||||||
// end: Alignment.centerRight,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
tabs: const <Widget>[Tab(text: '阅卷'), Tab(text: '作业')],
|
tabs: const <Widget>[Tab(text: '阅卷'), Tab(text: '作业')],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ import 'package:marking_app/utils/request/rest_client.dart';
|
||||||
/// isFavorite 默认是否收藏
|
/// isFavorite 默认是否收藏
|
||||||
/// favoriteNum 默认收藏次数
|
/// favoriteNum 默认收藏次数
|
||||||
class FavoriteWidget extends StatefulWidget {
|
class FavoriteWidget extends StatefulWidget {
|
||||||
FavoriteWidget({Key? key}) : super(key: key);
|
final Function call;
|
||||||
|
FavoriteWidget(this.call, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_FavoriteState createState() => _FavoriteState();
|
_FavoriteState createState() => _FavoriteState();
|
||||||
|
|
@ -19,12 +20,13 @@ class FavoriteWidget extends StatefulWidget {
|
||||||
|
|
||||||
class _FavoriteState extends State<FavoriteWidget> with EventBusMixin<JobQuestionsSwitch>, CommonMixin {
|
class _FavoriteState extends State<FavoriteWidget> with EventBusMixin<JobQuestionsSwitch>, CommonMixin {
|
||||||
Future<JobCollectParams?>? _future; // 考试试卷
|
Future<JobCollectParams?>? _future; // 考试试卷
|
||||||
|
JobQuestionsSwitch? _eventModel;
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
eventOn(callback: (JobQuestionsSwitch eventModel) {
|
eventOn(callback: (JobQuestionsSwitch eventModel) {
|
||||||
_future = getData(eventModel.taskId, eventModel.studentId);
|
_eventModel = eventModel;
|
||||||
|
_future = getData(eventModel.taskId, eventModel.studentId, eventModel.paperId);
|
||||||
toUpState(setState, () {}, mounted);
|
toUpState(setState, () {}, mounted);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -35,11 +37,11 @@ class _FavoriteState extends State<FavoriteWidget> with EventBusMixin<JobQuestio
|
||||||
eventCancel();
|
eventCancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<JobCollectParams?> getData(int taskId, int studentId) async {
|
Future<JobCollectParams?> getData(int taskId, int studentId, int paperId) async {
|
||||||
try {
|
try {
|
||||||
RestClient _client = await getClient();
|
RestClient _client = await getClient();
|
||||||
BaseStructureResult<bool> res = await _client.getJobCollect(taskId, studentId);
|
BaseStructureResult<bool> res = await _client.getJobCollect(taskId, studentId, paperId);
|
||||||
if (res.success) return JobCollectParams(taskId, studentId, res.data ?? false);
|
if (res.success) return JobCollectParams(paperId, taskId, studentId, res.data ?? false);
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -47,12 +49,15 @@ class _FavoriteState extends State<FavoriteWidget> with EventBusMixin<JobQuestio
|
||||||
|
|
||||||
Future<void> toFavorite(JobCollectParams favoriteVal) async {
|
Future<void> toFavorite(JobCollectParams favoriteVal) async {
|
||||||
try {
|
try {
|
||||||
|
if (_eventModel?.paperId == null) return;
|
||||||
ToastUtils.showLoading();
|
ToastUtils.showLoading();
|
||||||
RestClient _client = await getClient();
|
RestClient _client = await getClient();
|
||||||
favoriteVal.isCollect = !favoriteVal.isCollect;
|
favoriteVal.isCollect = !favoriteVal.isCollect;
|
||||||
|
favoriteVal.paperId = _eventModel!.paperId;
|
||||||
BaseStructureResult<bool> res = await _client.toJobFavoriteCancel(favoriteVal);
|
BaseStructureResult<bool> res = await _client.toJobFavoriteCancel(favoriteVal);
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
_future = getData(favoriteVal.taskId, favoriteVal.studentId);
|
_future = getData(favoriteVal.taskId, favoriteVal.studentId, _eventModel!.paperId);
|
||||||
|
widget.call();
|
||||||
toUpState(setState, () {}, mounted);
|
toUpState(setState, () {}, mounted);
|
||||||
} else {
|
} else {
|
||||||
ToastUtils.showError(res.message ?? '操作失败,请重试');
|
ToastUtils.showError(res.message ?? '操作失败,请重试');
|
||||||
|
|
@ -97,6 +102,7 @@ class _FavoriteState extends State<FavoriteWidget> with EventBusMixin<JobQuestio
|
||||||
class JobQuestionsSwitch extends Object {
|
class JobQuestionsSwitch extends Object {
|
||||||
final int taskId;
|
final int taskId;
|
||||||
final int studentId;
|
final int studentId;
|
||||||
|
final int paperId;
|
||||||
|
|
||||||
JobQuestionsSwitch(this.taskId, this.studentId);
|
JobQuestionsSwitch(this.taskId, this.studentId, this.paperId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,13 @@ import 'package:marking_app/common/mixin/common.dart';
|
||||||
import 'package:marking_app/common/model/common/base_structure_result.dart';
|
import 'package:marking_app/common/model/common/base_structure_result.dart';
|
||||||
import 'package:marking_app/common/model/event_bus/jobs/job_do_papers_student_bus.dart';
|
import 'package:marking_app/common/model/event_bus/jobs/job_do_papers_student_bus.dart';
|
||||||
import 'package:marking_app/common/model/job/job_concerned_with_student.dart';
|
import 'package:marking_app/common/model/job/job_concerned_with_student.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_concerned_with_student_params.dart';
|
||||||
import 'package:marking_app/common/model/job/job_do_marking_status_info.dart';
|
import 'package:marking_app/common/model/job/job_do_marking_status_info.dart';
|
||||||
import 'package:marking_app/common/model/job/job_page_tab.dart';
|
import 'package:marking_app/common/model/job/job_page_tab.dart';
|
||||||
import 'package:marking_app/common/model/job/job_review_submission.dart';
|
import 'package:marking_app/common/model/job/job_review_submission.dart';
|
||||||
import 'package:marking_app/common/model/job/marking_text_question_job.dart';
|
import 'package:marking_app/common/model/job/marking_text_question_job.dart';
|
||||||
import 'package:marking_app/common/model/job/marking_text_question_job_tab_params.dart';
|
import 'package:marking_app/common/model/job/marking_text_question_job_tab_params.dart';
|
||||||
|
import 'package:marking_app/components/ReturnToHomepage.dart';
|
||||||
import 'package:marking_app/pages/common/event_bus_mixin.dart';
|
import 'package:marking_app/pages/common/event_bus_mixin.dart';
|
||||||
import 'package:marking_app/pages/homework_correction/components/new_version_of_homework/bottom_annotation_switch_job.dart';
|
import 'package:marking_app/pages/homework_correction/components/new_version_of_homework/bottom_annotation_switch_job.dart';
|
||||||
import 'package:marking_app/pages/homework_correction/eventBus/marking_text_question_job_tab_params_bus.dart';
|
import 'package:marking_app/pages/homework_correction/eventBus/marking_text_question_job_tab_params_bus.dart';
|
||||||
|
|
@ -72,15 +74,9 @@ class DoPapersJob extends HookWidget with EventBusMixin<DoPapersJobRefreshBus> {
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
actions: [
|
actions: [
|
||||||
FavoriteWidget(),
|
FavoriteWidget(() => refresh = true),
|
||||||
// Container(
|
SizedBox(width: 5.w),
|
||||||
// padding: EdgeInsets.only(right: 4.w),
|
ReturnToHomepage(),
|
||||||
// alignment: Alignment.center,
|
|
||||||
// child: Row(
|
|
||||||
// crossAxisAlignment: CrossAxisAlignment.end,
|
|
||||||
// children: [Icon(Icons.lightbulb_outline, size: 12.sp), SizedBox(width: 1.w), quickText('查看原卷')],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
|
|
@ -93,7 +89,7 @@ class DoPapersJob extends HookWidget with EventBusMixin<DoPapersJobRefreshBus> {
|
||||||
exitCallback: () => Navigator.of(context).pop(refresh),
|
exitCallback: () => Navigator.of(context).pop(refresh),
|
||||||
),
|
),
|
||||||
SizedBox(height: 1.h),
|
SizedBox(height: 1.h),
|
||||||
Expanded(child: ExamPaperAndScoringView(taskId: taskId)),
|
Expanded(child: ExamPaperAndScoringView(taskId: taskId, className: className)),
|
||||||
$BottomOperationBar()
|
$BottomOperationBar()
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -108,7 +104,17 @@ class DoPapersJob extends HookWidget with EventBusMixin<DoPapersJobRefreshBus> {
|
||||||
class ReviewStatusInfo extends HookWidget with CommonMixin {
|
class ReviewStatusInfo extends HookWidget with CommonMixin {
|
||||||
final int taskId;
|
final int taskId;
|
||||||
final int pageIndex;
|
final int pageIndex;
|
||||||
const ReviewStatusInfo({required this.taskId, required this.pageIndex, super.key});
|
// final int schoolId;
|
||||||
|
// final int gradeId;
|
||||||
|
final String className;
|
||||||
|
const ReviewStatusInfo({
|
||||||
|
required this.taskId,
|
||||||
|
required this.pageIndex,
|
||||||
|
// required this.schoolId,
|
||||||
|
// required this.gradeId,
|
||||||
|
required this.className,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
Future<JobDoMarkingStatusInfo?> getData() async {
|
Future<JobDoMarkingStatusInfo?> getData() async {
|
||||||
var _client = await getClient();
|
var _client = await getClient();
|
||||||
|
|
@ -116,6 +122,20 @@ class ReviewStatusInfo extends HookWidget with CommonMixin {
|
||||||
return result.data;
|
return result.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 获取未提交
|
||||||
|
Future<List<JobConcernedWithStudent>?> getStudents() async {
|
||||||
|
try {
|
||||||
|
ToastUtils.showLoading();
|
||||||
|
var _client = await getClient();
|
||||||
|
var _result = await _client.getJobWithStudents(JobConcernedWithStudentParams([taskId], isCommit: false, pageIndex: pageIndex));
|
||||||
|
if (_result.success) return _result.data;
|
||||||
|
} catch (e) {
|
||||||
|
ToastUtils.showError('获取数据失败,请重试');
|
||||||
|
} finally {
|
||||||
|
ToastUtils.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var doMarkingInfo = useState<JobDoMarkingStatusInfo?>(null);
|
var doMarkingInfo = useState<JobDoMarkingStatusInfo?>(null);
|
||||||
|
|
@ -125,26 +145,86 @@ class ReviewStatusInfo extends HookWidget with CommonMixin {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (doMarkingInfo.value == null) return Container();
|
if (doMarkingInfo.value == null) return Container();
|
||||||
return Container(
|
return InkWell(
|
||||||
|
onTap: () async {
|
||||||
|
print('点击了...');
|
||||||
|
List<JobConcernedWithStudent>? students = await getStudents();
|
||||||
|
if (students == null) return;
|
||||||
|
students = students..sort((e, e1) => e.studentName.compareTo(e1.studentName));
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
elevation: 10,
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(10.r),
|
||||||
|
topRight: Radius.circular(10.r),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 2.w),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.only(top: 14.h),
|
||||||
|
child: quickText(
|
||||||
|
'当前页未提交学生名单',
|
||||||
|
size: 15.sp,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Color.fromRGBO(60, 60, 60, 1),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 10.h),
|
||||||
|
Expanded(
|
||||||
|
child: ListView(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 4.w),
|
||||||
|
children: [
|
||||||
|
Wrap(
|
||||||
|
spacing: 6.0, // 主轴(水平)方向间距
|
||||||
|
runSpacing: 4.0, // 纵轴(垂直)方向间距
|
||||||
|
alignment: WrapAlignment.spaceAround, //沿主轴方向居中
|
||||||
|
children: students!.map((e) {
|
||||||
|
return Chip(
|
||||||
|
labelPadding: EdgeInsets.symmetric(vertical: 1.5.h, horizontal: 5.w),
|
||||||
|
backgroundColor: Color.fromRGBO(239, 242, 255, 1),
|
||||||
|
// avatar: CircleAvatar(
|
||||||
|
// backgroundColor: Colors.white,
|
||||||
|
// child: quickText(e.studentName.substring(0, 1),
|
||||||
|
// size: 12.sp, color: Theme.of(context).primaryColor),
|
||||||
|
// ),
|
||||||
|
label: quickText(e.studentName, color: Color.fromRGBO(80, 94, 110, 1), size: 12.sp),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
quickText('已阅', color: Color.fromRGBO(117, 117, 117, 1), size: 10.sp),
|
quickText('已阅', color: Color.fromRGBO(117, 117, 117, 1), size: 10.sp),
|
||||||
quickText(doMarkingInfo.value!.finishCount,
|
quickText(doMarkingInfo.value!.finishCount, color: Color.fromRGBO(76, 199, 147, 1), size: 12.sp, fontWeight: FontWeight.bold),
|
||||||
color: Color.fromRGBO(76, 199, 147, 1), size: 12.sp, fontWeight: FontWeight.bold),
|
|
||||||
quickText('/', color: Color.fromRGBO(117, 117, 117, 1), size: 12.sp),
|
quickText('/', color: Color.fromRGBO(117, 117, 117, 1), size: 12.sp),
|
||||||
quickText(doMarkingInfo.value!.surplusNo, color: Color.fromRGBO(117, 117, 117, 1), size: 10.sp),
|
quickText(doMarkingInfo.value!.surplusNo, color: Color.fromRGBO(117, 117, 117, 1), size: 10.sp),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 切换下拉框 (学生和试卷状态)
|
// 切换下拉框 (学生和试卷状态)
|
||||||
@hwidget
|
@hwidget
|
||||||
Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context,
|
Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context, {required Function() exitCallback, required int taskId, required int jobId}) {
|
||||||
{required Function() exitCallback, required int taskId, required int jobId}) {
|
|
||||||
UseSwitchStudentAndType _useSwitchStudentAndType = UseSwitchStudentAndType.use(); // 学生和试卷状态
|
UseSwitchStudentAndType _useSwitchStudentAndType = UseSwitchStudentAndType.use(); // 学生和试卷状态
|
||||||
|
|
||||||
// 当前tab改变时
|
// 当前tab改变时
|
||||||
|
|
@ -187,23 +267,18 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context,
|
||||||
case JobDoPapersStudentBus:
|
case JobDoPapersStudentBus:
|
||||||
var studentInfo = val as JobDoPapersStudentBus;
|
var studentInfo = val as JobDoPapersStudentBus;
|
||||||
_useSwitchStudentAndType.studentBusInfo.value = studentInfo; // 赋值历史记录
|
_useSwitchStudentAndType.studentBusInfo.value = studentInfo; // 赋值历史记录
|
||||||
var selectedStudent = _useSwitchStudentAndType.studentData.value
|
var selectedStudent =
|
||||||
.firstWhereOrNull((element) => element.studentId == studentInfo.studentId);
|
_useSwitchStudentAndType.studentData.value.firstWhereOrNull((element) => element.studentId == studentInfo.studentId);
|
||||||
if (selectedStudent == null) {
|
if (selectedStudent == null) {
|
||||||
// 当前学生集合中没有此学生
|
// 当前学生集合中没有此学生
|
||||||
selectedStudent = JobConcernedWithStudent.fromJson(studentInfo.toJson());
|
selectedStudent = JobConcernedWithStudent.fromJson(studentInfo.toJson());
|
||||||
_useSwitchStudentAndType.studentData.value = [
|
_useSwitchStudentAndType.studentData.value = [..._useSwitchStudentAndType.studentData.value, selectedStudent];
|
||||||
..._useSwitchStudentAndType.studentData.value,
|
|
||||||
selectedStudent
|
|
||||||
];
|
|
||||||
_useSwitchStudentAndType.getDataForStudents(taskId: taskId);
|
_useSwitchStudentAndType.getDataForStudents(taskId: taskId);
|
||||||
}
|
}
|
||||||
_useSwitchStudentAndType.currentStudent.value = selectedStudent;
|
_useSwitchStudentAndType.currentStudent.value = selectedStudent;
|
||||||
print('是否是优先批阅:${studentInfo.isFirst}');
|
_useSwitchStudentAndType.isFinish.value = studentInfo.isFinish;
|
||||||
_useSwitchStudentAndType.isFirst.value = studentInfo.isFirst;
|
_useSwitchStudentAndType.isFirst.value = studentInfo.isFirst;
|
||||||
_useSwitchStudentAndType.currentTab.value =
|
_useSwitchStudentAndType.currentTab.value = _useSwitchStudentAndType.tabs.value.firstWhere((e) => e.pageIndex == studentInfo.pageIndex);
|
||||||
_useSwitchStudentAndType.tabs.value.firstWhere((e) => e.pageIndex == studentInfo.pageIndex);
|
|
||||||
print('是否是优先批阅1111:${_useSwitchStudentAndType.isFirst}');
|
|
||||||
break;
|
break;
|
||||||
case JobCheckSwitchingQuestionTabBus:
|
case JobCheckSwitchingQuestionTabBus:
|
||||||
// 检查切换试题体型
|
// 检查切换试题体型
|
||||||
|
|
@ -223,7 +298,8 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context,
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
print('加载的是否优先批阅:${_useSwitchStudentAndType.isFirst}');
|
var _currentTab = _useSwitchStudentAndType.currentTab.value;
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
padding: EdgeInsets.only(bottom: 2.r, left: 12.r, right: 12.r),
|
padding: EdgeInsets.only(bottom: 2.r, left: 12.r, right: 12.r),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
|
@ -240,7 +316,7 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 7,
|
flex: 3,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.only(left: 10.w),
|
padding: EdgeInsets.only(left: 10.w),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
|
@ -265,15 +341,14 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context,
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
_useSwitchStudentAndType.currentTab.value =
|
_useSwitchStudentAndType.currentTab.value = _useSwitchStudentAndType.tabs.value.firstWhere((element) => element.pageIndex == value);
|
||||||
_useSwitchStudentAndType.tabs.value.firstWhere((element) => element.pageIndex == value);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(flex: 1, child: SizedBox()),
|
Expanded(flex: 1, child: SizedBox()),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 7,
|
flex: 5,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.only(left: 10.w),
|
padding: EdgeInsets.only(left: 10.w),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
|
@ -301,28 +376,55 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context,
|
||||||
JobConcernedWithStudent? currentStudent = _useSwitchStudentAndType.currentStudent.value;
|
JobConcernedWithStudent? currentStudent = _useSwitchStudentAndType.currentStudent.value;
|
||||||
if (currentStudent?.studentId == value) return;
|
if (currentStudent?.studentId == value) return;
|
||||||
_useSwitchStudentAndType.studentBusInfo.value = null; // 置空BUS通知记录
|
_useSwitchStudentAndType.studentBusInfo.value = null; // 置空BUS通知记录
|
||||||
_useSwitchStudentAndType.currentStudent.value = _useSwitchStudentAndType.studentData.value
|
_useSwitchStudentAndType.currentStudent.value =
|
||||||
.firstWhereOrNull((element) => element.studentId == value);
|
_useSwitchStudentAndType.studentData.value.firstWhereOrNull((element) => element.studentId == value);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(flex: 1, child: SizedBox()),
|
Expanded(flex: 1, child: SizedBox()),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 3,
|
flex: 4,
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
|
if (_useSwitchStudentAndType.isFinish.value && _currentTab?.finishCount != _currentTab?.total)
|
||||||
|
Expanded(
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.flip_camera_android_outlined, size: 10.sp, color: Theme.of(context).primaryColor.withOpacity(0.8)),
|
||||||
|
SizedBox(width: 1.w),
|
||||||
|
InkWell(
|
||||||
|
onTap: () => easyThrottle(
|
||||||
|
'DO_PAPERS_JOB_CONTINUE_TO_REVIEW',
|
||||||
|
() {
|
||||||
|
var _pageIndex = _useSwitchStudentAndType.currentTab.value?.pageIndex;
|
||||||
|
if (_pageIndex == null) return;
|
||||||
|
|
||||||
|
_useSwitchStudentAndType.eventFire(model: MarkingTextQuestionJobTabParamsBus(taskId, _pageIndex));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
child: quickText(
|
||||||
|
'继续批阅',
|
||||||
|
size: 10.sp,
|
||||||
|
decoration: TextDecoration.underline,
|
||||||
|
color: Theme.of(context).primaryColor.withOpacity(0.9),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 2.w),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
Stack(
|
Stack(
|
||||||
alignment: const FractionalOffset(0.52, 0.24),
|
alignment: const FractionalOffset(0.52, 0.24),
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
Icon(
|
||||||
const IconData(0xe63d, fontFamily: "AlibabaIcon"),
|
const IconData(0xe63d, fontFamily: "AlibabaIcon"),
|
||||||
size: 12.sp,
|
size: 12.sp,
|
||||||
color: _useSwitchStudentAndType.isFirst.value
|
color: _useSwitchStudentAndType.isFirst.value ? Color.fromRGBO(76, 199, 147, 1) : Color.fromRGBO(164, 164, 164, 1),
|
||||||
? Color.fromRGBO(76, 199, 147, 1)
|
|
||||||
: Color.fromRGBO(164, 164, 164, 1),
|
|
||||||
),
|
),
|
||||||
quickText('优先', size: 4.sp, color: Colors.white),
|
quickText('优先', size: 4.sp, color: Colors.white),
|
||||||
],
|
],
|
||||||
|
|
@ -331,9 +433,7 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context,
|
||||||
quickText(
|
quickText(
|
||||||
'优先批阅',
|
'优先批阅',
|
||||||
size: 10.sp,
|
size: 10.sp,
|
||||||
color: _useSwitchStudentAndType.isFirst.value
|
color: _useSwitchStudentAndType.isFirst.value ? Color.fromRGBO(76, 199, 147, 1) : Color.fromRGBO(164, 164, 164, 1),
|
||||||
? Color.fromRGBO(76, 199, 147, 1)
|
|
||||||
: Color.fromRGBO(164, 164, 164, 1),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -381,7 +481,8 @@ Widget $dropdownBoxSwitchStudentsOrTypeView(BuildContext context,
|
||||||
// 试卷和打分键盘栏
|
// 试卷和打分键盘栏
|
||||||
class ExamPaperAndScoringView extends StatefulHookConsumerWidget {
|
class ExamPaperAndScoringView extends StatefulHookConsumerWidget {
|
||||||
final int taskId;
|
final int taskId;
|
||||||
const ExamPaperAndScoringView({required this.taskId, super.key});
|
final String className;
|
||||||
|
const ExamPaperAndScoringView({required this.taskId, required this.className, super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_EexamPaperAndScoringViewState createState() => _EexamPaperAndScoringViewState();
|
_EexamPaperAndScoringViewState createState() => _EexamPaperAndScoringViewState();
|
||||||
|
|
@ -444,10 +545,16 @@ class _EexamPaperAndScoringViewState extends ConsumerState<ExamPaperAndScoringVi
|
||||||
ref.read(jobHomeWorkProvider.notifier).setVal([]);
|
ref.read(jobHomeWorkProvider.notifier).setVal([]);
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
eventFire(model: JobQuestionsSwitch(jobDetails.taskId, jobDetails.studentId));
|
eventFire(model: JobQuestionsSwitch(jobDetails.taskId, jobDetails.studentId, jobDetails.paperId));
|
||||||
eventFire(
|
eventFire(
|
||||||
model: JobDoPapersStudentBus(
|
model: JobDoPapersStudentBus(
|
||||||
jobDetails.studentId, jobDetails.studentName, jobDetails.pageIndex, jobDetails.isFirst));
|
jobDetails.studentId,
|
||||||
|
jobDetails.studentName,
|
||||||
|
jobDetails.pageIndex,
|
||||||
|
jobDetails.isFirst,
|
||||||
|
jobDetails.isFinish,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return jobDetails;
|
return jobDetails;
|
||||||
}
|
}
|
||||||
|
|
@ -502,8 +609,7 @@ class _EexamPaperAndScoringViewState extends ConsumerState<ExamPaperAndScoringVi
|
||||||
return MyFutureBuilder.buildFutureBuilderOfSingleInstance<MarkingTextQuestionJob>(context, _future!, (jobData) {
|
return MyFutureBuilder.buildFutureBuilderOfSingleInstance<MarkingTextQuestionJob>(context, _future!, (jobData) {
|
||||||
List<Questions> questions = jobData?.questions ?? [];
|
List<Questions> questions = jobData?.questions ?? [];
|
||||||
|
|
||||||
bool canNormalPrevious =
|
bool canNormalPrevious = jobData != null && (jobData.prevId != 0 || jobData.previousPageIndex != null); //是否可以正常点击切换上一题
|
||||||
jobData != null && (jobData.prevId != 0 || jobData.previousPageIndex != null); //是否可以正常点击切换上一题
|
|
||||||
bool canNormalNext = jobData != null && (jobData.nextId != 0 || jobData.nextPageIndex != null); //是否可以正常点击切换下一题
|
bool canNormalNext = jobData != null && (jobData.nextId != 0 || jobData.nextPageIndex != null); //是否可以正常点击切换下一题
|
||||||
|
|
||||||
return Stack(
|
return Stack(
|
||||||
|
|
@ -522,7 +628,7 @@ class _EexamPaperAndScoringViewState extends ConsumerState<ExamPaperAndScoringVi
|
||||||
|
|
||||||
if (jobData == null) return Container(); // 没有试题展示缩略图
|
if (jobData == null) return Container(); // 没有试题展示缩略图
|
||||||
|
|
||||||
print('容器宽度:${containerWidth};容器高度:${containerHeight}');
|
// print('容器宽度:${containerWidth};容器高度:${containerHeight}');
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
JobPictureOverview(
|
JobPictureOverview(
|
||||||
|
|
@ -541,8 +647,8 @@ class _EexamPaperAndScoringViewState extends ConsumerState<ExamPaperAndScoringVi
|
||||||
focusColor: Theme.of(context).primaryColor,
|
focusColor: Theme.of(context).primaryColor,
|
||||||
backgroundColor: const Color.fromRGBO(24, 32, 32, 0.1),
|
backgroundColor: const Color.fromRGBO(24, 32, 32, 0.1),
|
||||||
elevation: 6.r,
|
elevation: 6.r,
|
||||||
onPressed: () => easyThrottle('TestQuestionSwitch',
|
onPressed: () =>
|
||||||
() => switchTestQuestions(jobData: jobData, toNextQuestion: false)),
|
easyThrottle('TestQuestionSwitch', () => switchTestQuestions(jobData: jobData, toNextQuestion: false)),
|
||||||
child: Icon(Icons.arrow_back_ios, color: Colors.white, size: 22.sp),
|
child: Icon(Icons.arrow_back_ios, color: Colors.white, size: 22.sp),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -556,8 +662,7 @@ class _EexamPaperAndScoringViewState extends ConsumerState<ExamPaperAndScoringVi
|
||||||
tooltip: '点击前往下一题',
|
tooltip: '点击前往下一题',
|
||||||
elevation: 6.r,
|
elevation: 6.r,
|
||||||
backgroundColor: const Color.fromRGBO(24, 32, 32, 0.1),
|
backgroundColor: const Color.fromRGBO(24, 32, 32, 0.1),
|
||||||
onPressed: () =>
|
onPressed: () => easyThrottle('TestQuestionSwitch', () => switchTestQuestions(jobData: jobData)),
|
||||||
easyThrottle('TestQuestionSwitch', () => switchTestQuestions(jobData: jobData)),
|
|
||||||
child: Icon(Icons.arrow_forward_ios, color: Colors.white, size: 22.sp),
|
child: Icon(Icons.arrow_forward_ios, color: Colors.white, size: 22.sp),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -567,14 +672,20 @@ class _EexamPaperAndScoringViewState extends ConsumerState<ExamPaperAndScoringVi
|
||||||
),
|
),
|
||||||
|
|
||||||
/// 批阅进度详情
|
/// 批阅进度详情
|
||||||
ReviewStatusInfo(taskId: widget.taskId, pageIndex: jobData!.pageIndex)
|
ReviewStatusInfo(
|
||||||
|
taskId: widget.taskId,
|
||||||
|
pageIndex: jobData!.pageIndex,
|
||||||
|
className: widget.className,
|
||||||
|
// gradeId: null,
|
||||||
|
// schoolId: null,
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 2,
|
flex: 2,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.symmetric(vertical: 14.h),
|
padding: EdgeInsets.only(bottom: 14.h, top: 6.h),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Color.fromRGBO(159, 159, 159, 0.97),
|
color: Color.fromRGBO(159, 159, 159, 0.97),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
|
|
@ -596,10 +707,8 @@ class _EexamPaperAndScoringViewState extends ConsumerState<ExamPaperAndScoringVi
|
||||||
eventFire(model: JobCheckSwitchingQuestionTabBus(jobData.pageIndex));
|
eventFire(model: JobCheckSwitchingQuestionTabBus(jobData.pageIndex));
|
||||||
},
|
},
|
||||||
viewHomeworkNotes: (JobReviewQuestions subJobQuestion) {
|
viewHomeworkNotes: (JobReviewQuestions subJobQuestion) {
|
||||||
var _theBusModel = JobNotesViewBus(
|
var _theBusModel =
|
||||||
taskId: jobData.taskId,
|
JobNotesViewBus(taskId: jobData.taskId, paperId: jobData.paperId, questionNo: subJobQuestion.questionNo);
|
||||||
paperId: jobData.paperId,
|
|
||||||
questionNo: subJobQuestion.questionNo);
|
|
||||||
eventFire(model: _theBusModel);
|
eventFire(model: _theBusModel);
|
||||||
},
|
},
|
||||||
scaffoldKeyPictureOverview: scaffoldKeyPictureOverview,
|
scaffoldKeyPictureOverview: scaffoldKeyPictureOverview,
|
||||||
|
|
@ -694,9 +803,12 @@ Widget $examPaperAndScoringKeyboardView(
|
||||||
child: Container(
|
child: Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
padding: EdgeInsets.symmetric(vertical: 8.h),
|
padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 4.w),
|
||||||
decoration:
|
decoration: BoxDecoration(border: Border(bottom: BorderSide(width: 0.2.r, color: Colors.white))),
|
||||||
BoxDecoration(border: Border(bottom: BorderSide(width: 0.2.r, color: Colors.white))),
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
|
@ -707,7 +819,16 @@ Widget $examPaperAndScoringKeyboardView(
|
||||||
child: quickText('题', size: 11.sp, color: textColor),
|
child: quickText('题', size: 11.sp, color: textColor),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)),
|
),
|
||||||
|
),
|
||||||
|
if (question.accuracy > 0)
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: 1.5.h),
|
||||||
|
child: quickText('正确率:${question.accuracy}%', size: 8.sp, color: Colors.white, align: TextAlign.end),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
child: Row(
|
child: Row(
|
||||||
|
|
@ -715,18 +836,20 @@ Widget $examPaperAndScoringKeyboardView(
|
||||||
Expanded(
|
Expanded(
|
||||||
child: $MaterialBtn(
|
child: $MaterialBtn(
|
||||||
bgc: Color.fromRGBO(237, 237, 237, 1),
|
bgc: Color.fromRGBO(237, 237, 237, 1),
|
||||||
onTap: () => _useDoScoring.goToScoringShortcut(
|
onTap: () {
|
||||||
|
_useDoScoring.goToScoringShortcut(
|
||||||
scoring: ScoringMethodEnum.CORRECT,
|
scoring: ScoringMethodEnum.CORRECT,
|
||||||
questionNo: question.questionNo,
|
questionNo: question.questionNo,
|
||||||
),
|
);
|
||||||
|
var noAnswerQuestion = _useDoScoring.submittedData.value.questions.firstWhereOrNull((e) => e.score == null);
|
||||||
|
if (noAnswerQuestion == null) toSubmit();
|
||||||
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.symmetric(vertical: 12.r),
|
padding: EdgeInsets.symmetric(vertical: 12.r),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: quickText(
|
child: quickText(
|
||||||
'对',
|
'对',
|
||||||
color: subJobQuestion.score == 2
|
color: subJobQuestion.score == 2 ? Color.fromRGBO(255, 152, 0, 1) : Color.fromRGBO(114, 114, 114, 1),
|
||||||
? Color.fromRGBO(255, 152, 0, 1)
|
|
||||||
: Color.fromRGBO(114, 114, 114, 1),
|
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
size: 12.sp,
|
size: 12.sp,
|
||||||
),
|
),
|
||||||
|
|
@ -736,19 +859,21 @@ Widget $examPaperAndScoringKeyboardView(
|
||||||
SizedBox(width: 0.2.w),
|
SizedBox(width: 0.2.w),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: $MaterialBtn(
|
child: $MaterialBtn(
|
||||||
onTap: () => _useDoScoring.goToScoringShortcut(
|
onTap: () {
|
||||||
|
_useDoScoring.goToScoringShortcut(
|
||||||
scoring: ScoringMethodEnum.CORRECT_HALF,
|
scoring: ScoringMethodEnum.CORRECT_HALF,
|
||||||
questionNo: question.questionNo,
|
questionNo: question.questionNo,
|
||||||
),
|
);
|
||||||
|
var noAnswerQuestion = _useDoScoring.submittedData.value.questions.firstWhereOrNull((e) => e.score == null);
|
||||||
|
if (noAnswerQuestion == null) toSubmit();
|
||||||
|
},
|
||||||
bgc: Color.fromRGBO(237, 237, 237, 1),
|
bgc: Color.fromRGBO(237, 237, 237, 1),
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.symmetric(vertical: 12.r),
|
padding: EdgeInsets.symmetric(vertical: 12.r),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: quickText(
|
child: quickText(
|
||||||
'半',
|
'半',
|
||||||
color: subJobQuestion.score == 1
|
color: subJobQuestion.score == 1 ? Color.fromRGBO(255, 152, 0, 1) : Color.fromRGBO(114, 114, 114, 1),
|
||||||
? Color.fromRGBO(255, 152, 0, 1)
|
|
||||||
: Color.fromRGBO(114, 114, 114, 1),
|
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
size: 12.sp,
|
size: 12.sp,
|
||||||
),
|
),
|
||||||
|
|
@ -758,19 +883,21 @@ Widget $examPaperAndScoringKeyboardView(
|
||||||
SizedBox(width: 0.2.w),
|
SizedBox(width: 0.2.w),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: $MaterialBtn(
|
child: $MaterialBtn(
|
||||||
onTap: () => _useDoScoring.goToScoringShortcut(
|
onTap: () {
|
||||||
|
_useDoScoring.goToScoringShortcut(
|
||||||
scoring: ScoringMethodEnum.WRONG,
|
scoring: ScoringMethodEnum.WRONG,
|
||||||
questionNo: question.questionNo,
|
questionNo: question.questionNo,
|
||||||
),
|
);
|
||||||
|
var noAnswerQuestion = _useDoScoring.submittedData.value.questions.firstWhereOrNull((e) => e.score == null);
|
||||||
|
if (noAnswerQuestion == null) toSubmit();
|
||||||
|
},
|
||||||
bgc: Color.fromRGBO(237, 237, 237, 1),
|
bgc: Color.fromRGBO(237, 237, 237, 1),
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.symmetric(vertical: 12.r),
|
padding: EdgeInsets.symmetric(vertical: 12.r),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: quickText(
|
child: quickText(
|
||||||
'错',
|
'错',
|
||||||
color: subJobQuestion.score == 0
|
color: subJobQuestion.score == 0 ? Color.fromRGBO(255, 152, 0, 1) : Color.fromRGBO(114, 114, 114, 1),
|
||||||
? Color.fromRGBO(255, 152, 0, 1)
|
|
||||||
: Color.fromRGBO(114, 114, 114, 1),
|
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
size: 12.sp,
|
size: 12.sp,
|
||||||
),
|
),
|
||||||
|
|
@ -787,6 +914,7 @@ Widget $examPaperAndScoringKeyboardView(
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
SizedBox(height: 3.h),
|
||||||
Container(
|
Container(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
|
@ -865,7 +993,7 @@ Widget $examPaperAndScoringKeyboardView(
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 36.h),
|
SizedBox(height: 26.h),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -876,8 +1004,7 @@ Widget $examPaperAndScoringKeyboardView(
|
||||||
bgc: Colors.white,
|
bgc: Colors.white,
|
||||||
splashColor: Theme.of(context).primaryColor.withOpacity(0.8),
|
splashColor: Theme.of(context).primaryColor.withOpacity(0.8),
|
||||||
borderRadius: BorderRadius.circular(2.r),
|
borderRadius: BorderRadius.circular(2.r),
|
||||||
onTap: () => easyThrottle('homework_review_submission_main_callback', () => toSubmit(),
|
onTap: () => easyThrottle('homework_review_submission_main_callback', () => toSubmit(), duration: Duration(seconds: 1)),
|
||||||
duration: Duration(seconds: 1)),
|
|
||||||
child: Container(
|
child: Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
|
|
@ -900,8 +1027,7 @@ Widget $examPaperAndScoringKeyboardView(
|
||||||
}
|
}
|
||||||
|
|
||||||
@swidget
|
@swidget
|
||||||
Widget $materialBtn(
|
Widget $materialBtn({required Widget child, Color? bgc, Color? splashColor, GestureTapCallback? onTap, BorderRadius? borderRadius}) {
|
||||||
{required Widget child, Color? bgc, Color? splashColor, GestureTapCallback? onTap, BorderRadius? borderRadius}) {
|
|
||||||
return Material(
|
return Material(
|
||||||
color: bgc,
|
color: bgc,
|
||||||
borderRadius: borderRadius,
|
borderRadius: borderRadius,
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ import 'package:marking_app/utils/request/rest_client.dart';
|
||||||
class UseSwitchStudentAndType with CommonMixin, EventBusMixin {
|
class UseSwitchStudentAndType with CommonMixin, EventBusMixin {
|
||||||
ValueNotifier<bool> exitPromptFlag; // 退出提示
|
ValueNotifier<bool> exitPromptFlag; // 退出提示
|
||||||
ValueNotifier<bool> isFirst;
|
ValueNotifier<bool> isFirst;
|
||||||
|
ValueNotifier<bool> isFinish;
|
||||||
|
|
||||||
ValueNotifier<List<JobConcernedWithStudent>> studentData; // 学生集合数据
|
ValueNotifier<List<JobConcernedWithStudent>> studentData; // 学生集合数据
|
||||||
ValueNotifier<List<JobPageTab>> tabs; // 学生集合数据
|
ValueNotifier<List<JobPageTab>> tabs; // 学生集合数据
|
||||||
|
|
||||||
|
|
@ -36,6 +38,7 @@ class UseSwitchStudentAndType with CommonMixin, EventBusMixin {
|
||||||
required this.studentBusInfo,
|
required this.studentBusInfo,
|
||||||
required this.exitPromptFlag,
|
required this.exitPromptFlag,
|
||||||
required this.isFirst,
|
required this.isFirst,
|
||||||
|
required this.isFinish,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 工厂构造函数
|
// 工厂构造函数
|
||||||
|
|
@ -60,6 +63,7 @@ class UseSwitchStudentAndType with CommonMixin, EventBusMixin {
|
||||||
studentBusInfo: theStudentBus,
|
studentBusInfo: theStudentBus,
|
||||||
exitPromptFlag: useState<bool>(false),
|
exitPromptFlag: useState<bool>(false),
|
||||||
isFirst: useState<bool>(false),
|
isFirst: useState<bool>(false),
|
||||||
|
isFinish: useState<bool>(false),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,8 +99,7 @@ class UseSwitchStudentAndType with CommonMixin, EventBusMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 属性tab类型数据
|
/// 属性tab类型数据
|
||||||
Future<JobPageTab?> refreshQuestionTypeData(BuildContext context,
|
Future<JobPageTab?> refreshQuestionTypeData(BuildContext context, {required int taskId, required Function() exitCallback}) async {
|
||||||
{required int taskId, required Function() exitCallback}) async {
|
|
||||||
List<JobPageTab>? tabDatas = await getDataForTestpaper(taskId: taskId, synchronization: false);
|
List<JobPageTab>? tabDatas = await getDataForTestpaper(taskId: taskId, synchronization: false);
|
||||||
if (tabDatas?.isNotEmpty ?? false) {
|
if (tabDatas?.isNotEmpty ?? false) {
|
||||||
JobPageTab? tabJob = tabDatas!.firstWhereOrNull((e) => e.finishCount < e.total);
|
JobPageTab? tabJob = tabDatas!.firstWhereOrNull((e) => e.finishCount < e.total);
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:functional_widget_annotation/functional_widget_annotation.dart';
|
import 'package:functional_widget_annotation/functional_widget_annotation.dart';
|
||||||
import 'package:marking_app/common/mixin/common.dart';
|
import 'package:marking_app/common/mixin/common.dart';
|
||||||
import 'package:flutter_easyrefresh/easy_refresh.dart';
|
import 'package:flutter_easyrefresh/easy_refresh.dart';
|
||||||
|
|
@ -18,6 +19,7 @@ import 'package:marking_app/common/config/request_config.dart';
|
||||||
import 'package:marking_app/common/model/job/job_task_item.dart';
|
import 'package:marking_app/common/model/job/job_task_item.dart';
|
||||||
import 'package:marking_app/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart';
|
import 'package:marking_app/pages/homework_correction/components/new_version_of_homework/homework_tasks_view_item.dart';
|
||||||
import 'package:marking_app/provider/review_provider.dart';
|
import 'package:marking_app/provider/review_provider.dart';
|
||||||
|
import 'package:marking_app/routes/RouterManager.dart';
|
||||||
import 'package:marking_app/utils/index.dart';
|
import 'package:marking_app/utils/index.dart';
|
||||||
import 'package:marking_app/utils/my_text.dart';
|
import 'package:marking_app/utils/my_text.dart';
|
||||||
import 'package:marking_app/utils/request/rest_client.dart';
|
import 'package:marking_app/utils/request/rest_client.dart';
|
||||||
|
|
@ -25,6 +27,7 @@ import 'package:marking_app/common/model/common/base_page_data.dart';
|
||||||
import 'package:marking_app/common/model/marking/marking_list_params.dart';
|
import 'package:marking_app/common/model/marking/marking_list_params.dart';
|
||||||
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
|
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
|
||||||
import 'package:marking_app/utils/easy_refresh/mixin/refresh_data_handle.dart';
|
import 'package:marking_app/utils/easy_refresh/mixin/refresh_data_handle.dart';
|
||||||
|
import 'package:syncfusion_flutter_datepicker/datepicker.dart';
|
||||||
|
|
||||||
part 'index.g.dart';
|
part 'index.g.dart';
|
||||||
|
|
||||||
|
|
@ -39,7 +42,7 @@ class HomeworkCorrection extends StatefulHookConsumerWidget {
|
||||||
class _HomeworkCorrectionState extends ConsumerState<HomeworkCorrection>
|
class _HomeworkCorrectionState extends ConsumerState<HomeworkCorrection>
|
||||||
with
|
with
|
||||||
CommonMixin,
|
CommonMixin,
|
||||||
SingleTickerProviderStateMixin,
|
TickerProviderStateMixin,
|
||||||
RefreshDataHandle<JobTaskItem, MarkingListParams>,
|
RefreshDataHandle<JobTaskItem, MarkingListParams>,
|
||||||
AutomaticKeepAliveClientMixin {
|
AutomaticKeepAliveClientMixin {
|
||||||
@override
|
@override
|
||||||
|
|
@ -47,6 +50,8 @@ class _HomeworkCorrectionState extends ConsumerState<HomeworkCorrection>
|
||||||
|
|
||||||
/* Tab控制器 */
|
/* Tab控制器 */
|
||||||
late TabController _tabController;
|
late TabController _tabController;
|
||||||
|
late TabController _tabController2;
|
||||||
|
|
||||||
int _tabIndex = 0;
|
int _tabIndex = 0;
|
||||||
bool completedToRefresh = true;
|
bool completedToRefresh = true;
|
||||||
|
|
||||||
|
|
@ -95,6 +100,7 @@ class _HomeworkCorrectionState extends ConsumerState<HomeworkCorrection>
|
||||||
length: 2,
|
length: 2,
|
||||||
vsync: this,
|
vsync: this,
|
||||||
);
|
);
|
||||||
|
_tabController2 = TabController(length: 4, vsync: this);
|
||||||
_refreshController1 = EasyRefreshController();
|
_refreshController1 = EasyRefreshController();
|
||||||
_refreshController2 = EasyRefreshController();
|
_refreshController2 = EasyRefreshController();
|
||||||
|
|
||||||
|
|
@ -117,6 +123,7 @@ class _HomeworkCorrectionState extends ConsumerState<HomeworkCorrection>
|
||||||
if (_currentTaskIdListener != null) {
|
if (_currentTaskIdListener != null) {
|
||||||
_currentTaskIdListener!();
|
_currentTaskIdListener!();
|
||||||
}
|
}
|
||||||
|
_tabController2.dispose();
|
||||||
_tabController.dispose();
|
_tabController.dispose();
|
||||||
_refreshController1.dispose();
|
_refreshController1.dispose();
|
||||||
_refreshController2.dispose();
|
_refreshController2.dispose();
|
||||||
|
|
@ -167,11 +174,9 @@ class _HomeworkCorrectionState extends ConsumerState<HomeworkCorrection>
|
||||||
margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
|
margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
|
||||||
padding: EdgeInsets.only(bottom: 9.h, top: 4.h),
|
padding: EdgeInsets.only(bottom: 9.h, top: 4.h),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(flex: 1, child: SizedBox()),
|
||||||
flex: 1,
|
|
||||||
child: SizedBox(),
|
|
||||||
),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 4,
|
flex: 4,
|
||||||
child: Container(
|
child: Container(
|
||||||
|
|
@ -254,11 +259,41 @@ class _HomeworkCorrectionState extends ConsumerState<HomeworkCorrection>
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 1,
|
flex: 1,
|
||||||
child: SizedBox(),
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
RouterManager.router
|
||||||
|
.navigateTo(context, RouterManager.jobStudentGroupPath, transition: getTransition());
|
||||||
|
},
|
||||||
|
child: Icon(IconData(0xe63e, fontFamily: "AlibabaIcon"),
|
||||||
|
color: Color.fromRGBO(44, 48, 63, 1), size: 24.sp),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (_tabIndex == 1)
|
||||||
|
$CompletedJobConditionFilter(
|
||||||
|
controller: _tabController2,
|
||||||
|
jobType: params2.markingType ?? 1,
|
||||||
|
customTime: _tabController2.index != 3 || (params2.startTime == null && params2.endTime == null)
|
||||||
|
? null
|
||||||
|
: PickerDateRange(
|
||||||
|
params2.startTime == null ? null : DateTime.parse(params2.startTime!),
|
||||||
|
params2.endTime == null ? null : DateTime.parse(params2.endTime!),
|
||||||
|
),
|
||||||
|
onJobTypeTap: (int jobTypeVal) {
|
||||||
|
params2.markingType = jobTypeVal;
|
||||||
|
_refreshController2.callRefresh();
|
||||||
|
},
|
||||||
|
onTimeFilter: (String? startTime, String? endTime) {
|
||||||
|
if (startTime == null && endTime == null && _tabController2.index == 3) {
|
||||||
|
_tabController2.animateTo(0);
|
||||||
|
}
|
||||||
|
params2.endTime = endTime;
|
||||||
|
params2.startTime = startTime;
|
||||||
|
_refreshController2.callRefresh();
|
||||||
|
},
|
||||||
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: IndexedStack(
|
child: IndexedStack(
|
||||||
index: _tabIndex,
|
index: _tabIndex,
|
||||||
|
|
@ -304,6 +339,7 @@ Widget $easyRefresh({
|
||||||
required int tab,
|
required int tab,
|
||||||
}) {
|
}) {
|
||||||
bool completed = tab == 2; // 是否是待批阅
|
bool completed = tab == 2; // 是否是待批阅
|
||||||
|
bool isPadFlag = isPad();
|
||||||
return EasyRefresh(
|
return EasyRefresh(
|
||||||
firstRefresh: true,
|
firstRefresh: true,
|
||||||
taskIndependence: true,
|
taskIndependence: true,
|
||||||
|
|
@ -313,8 +349,19 @@ Widget $easyRefresh({
|
||||||
controller: controller,
|
controller: controller,
|
||||||
header: MaterialHeader(),
|
header: MaterialHeader(),
|
||||||
footer: TaurusFooter(),
|
footer: TaurusFooter(),
|
||||||
child: ListView.builder(
|
child: completed && isPadFlag
|
||||||
padding: EdgeInsets.only(top: 11.h, bottom: 10.h, left: 16.w, right: 16.w),
|
? GridView(
|
||||||
|
padding: EdgeInsets.only(top: 11.h, bottom: 10.h, left: 12.w, right: 12.w),
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: 2, //横轴三个子widget
|
||||||
|
mainAxisSpacing: 10.h,
|
||||||
|
crossAxisSpacing: 6.w,
|
||||||
|
childAspectRatio: 1.81 //宽高比为1时,子widget
|
||||||
|
),
|
||||||
|
children: data.map((e) => $ReviewedItem(jobTaskItem: e)).toList(),
|
||||||
|
)
|
||||||
|
: ListView.builder(
|
||||||
|
padding: EdgeInsets.only(top: 11.h, bottom: 10.h, left: 12.w, right: 12.w),
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
return HomeworkTasksViewItem(
|
return HomeworkTasksViewItem(
|
||||||
completed: completed,
|
completed: completed,
|
||||||
|
|
@ -328,3 +375,355 @@ Widget $easyRefresh({
|
||||||
onLoad: () => onLoad(controller, params, tab),
|
onLoad: () => onLoad(controller, params, tab),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@swidget
|
||||||
|
Widget $reviewedItem(BuildContext context, {required JobTaskItem jobTaskItem}) {
|
||||||
|
EdgeInsets padEdg = EdgeInsets.symmetric(horizontal: 10.w);
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
String url =
|
||||||
|
'${RouterManager.jobListParticipateInClassPath}?&jobId=${jobTaskItem.id}&genderName=${Uri.encodeComponent(jobTaskItem.genderName)}&jobName=${Uri.encodeComponent(jobTaskItem.title)}&completed=${true}';
|
||||||
|
RouterManager.router.navigateTo(context, url, transition: getTransition());
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.only(top: 10.h),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(6.r),
|
||||||
|
color: Colors.white,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: const Color.fromRGBO(210, 216, 241, 1),
|
||||||
|
offset: Offset.zero, //阴影y轴偏移量
|
||||||
|
blurRadius: 5.8, //阴影模糊程度
|
||||||
|
spreadRadius: 0, //阴影扩散程度
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
// 顶部任务名称
|
||||||
|
Padding(
|
||||||
|
padding: padEdg,
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 32.w,
|
||||||
|
height: 18.h,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
padding: EdgeInsets.only(left: 2.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: jobTaskItem.markingTypeEnum.name == '作业'
|
||||||
|
? const Color.fromRGBO(104, 136, 253, 1)
|
||||||
|
: const Color.fromRGBO(255, 175, 56, 1),
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(14.r),
|
||||||
|
topRight: Radius.circular(3.r),
|
||||||
|
bottomLeft: Radius.circular(4.r),
|
||||||
|
bottomRight: Radius.circular(4.r),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
margin: EdgeInsets.only(right: 4.w),
|
||||||
|
child: quickText(jobTaskItem.markingTypeEnum.name, color: Colors.white, size: 10.sp),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: quickText(jobTaskItem.title, size: 14.sp, color: Color.fromRGBO(70, 70, 70, 1), maxLines: 2),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Padding(
|
||||||
|
padding: padEdg,
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
quickText(
|
||||||
|
jobTaskItem.createTime.substring(0, 10),
|
||||||
|
color: Color.fromRGBO(97, 97, 97, 1),
|
||||||
|
size: 10.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
quickText(' / ', color: Color.fromRGBO(76, 199, 147, 1), size: 10.sp, fontWeight: FontWeight.w500),
|
||||||
|
quickText(
|
||||||
|
'参与班级:',
|
||||||
|
color: Color.fromRGBO(76, 199, 147, 1),
|
||||||
|
size: 9.sp,
|
||||||
|
),
|
||||||
|
quickText(
|
||||||
|
'${jobTaskItem.taskCount}',
|
||||||
|
color: Color.fromRGBO(76, 199, 147, 1),
|
||||||
|
size: 10.sp,
|
||||||
|
),
|
||||||
|
quickText(' / ', color: Color.fromRGBO(116, 145, 253, 1), size: 10.sp, fontWeight: FontWeight.w500),
|
||||||
|
quickText(
|
||||||
|
'科目:' + jobTaskItem.subjectName,
|
||||||
|
color: Color.fromRGBO(116, 145, 253, 1),
|
||||||
|
size: 9.sp,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10.w),
|
||||||
|
child: FavoriteButton(
|
||||||
|
jobTaskItem.id,
|
||||||
|
jobTaskItem.title,
|
||||||
|
margin: EdgeInsets.only(top: 4.h, bottom: 6.h),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => easyThrottle('go_to_homework_report', () {
|
||||||
|
RouterManager.router.navigateTo(
|
||||||
|
context,
|
||||||
|
RouterManager.jobReportPagePath +
|
||||||
|
'?title=${Uri.encodeComponent(jobTaskItem.title)}&id=${jobTaskItem.id}',
|
||||||
|
transition: getTransition(),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 6.h),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(6.r), bottomRight: Radius.circular(6.r)),
|
||||||
|
color: Colors.white,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: const Color.fromRGBO(0, 0, 0, 0.15),
|
||||||
|
offset: Offset(0, -0.0001), //阴影y轴偏移量
|
||||||
|
blurRadius: 4, //阴影模糊程度
|
||||||
|
spreadRadius: 0, //阴影扩散程度
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Row(children: [
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: quickText('查看报告', color: Color.fromRGBO(118, 118, 118, 1), size: 11.sp),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 筛选时间
|
||||||
|
@swidget
|
||||||
|
Widget $theTabBar({required TabController controller, ValueChanged<int>? onTap, PickerDateRange? customTime}) {
|
||||||
|
var customTimeStr = '自定义';
|
||||||
|
if (customTime != null) {
|
||||||
|
customTimeStr = customTime.startDate?.toString().substring(0, 10) ?? '';
|
||||||
|
if (customTime.endDate != null) {
|
||||||
|
// print(customTime.startDate!.year == customTime.endDate!.year);
|
||||||
|
if (!isPad() && customTime.startDate!.year == customTime.endDate!.year) {
|
||||||
|
customTimeStr =
|
||||||
|
customTime.startDate.toString().substring(5, 10) + '~${customTime.endDate.toString().substring(5, 10)}';
|
||||||
|
} else {
|
||||||
|
customTimeStr += '~${customTime.endDate?.toString().substring(0, 10)}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Container(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: TabBar(
|
||||||
|
controller: controller,
|
||||||
|
unselectedLabelStyle: TextStyle(fontSize: 12.sp, color: const Color.fromRGBO(102, 102, 102, 1)),
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Color.fromRGBO(116, 145, 253, 1),
|
||||||
|
),
|
||||||
|
isScrollable: true,
|
||||||
|
labelColor: const Color.fromRGBO(45, 56, 76, 1),
|
||||||
|
indicatorSize: TabBarIndicatorSize.label, // 设置指示器高度和标签一样高
|
||||||
|
onTap: onTap,
|
||||||
|
tabs: <Widget>[
|
||||||
|
const Tab(text: '全部'),
|
||||||
|
const Tab(text: '近一周'),
|
||||||
|
const Tab(text: '近一月'),
|
||||||
|
Tab(text: customTimeStr),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 已完成作业条件筛选栏
|
||||||
|
@hwidget
|
||||||
|
Widget $completedJobConditionFilter(BuildContext context,
|
||||||
|
{required TabController controller,
|
||||||
|
required int jobType,
|
||||||
|
PickerDateRange? customTime,
|
||||||
|
required ValueChanged<int> onJobTypeTap,
|
||||||
|
required Function(String? startTime, String? endTime) onTimeFilter}) {
|
||||||
|
List<Map<String, dynamic>> jobTypes = [
|
||||||
|
{'type': 1, 'name': '作业'},
|
||||||
|
{'type': 2, 'name': '考试'}
|
||||||
|
];
|
||||||
|
var jobTypeState = useState(0);
|
||||||
|
var customTimeState = useState<PickerDateRange?>(null);
|
||||||
|
|
||||||
|
useEffect(() {
|
||||||
|
if (jobTypeState.value != jobType) jobTypeState.value = jobType;
|
||||||
|
if (customTimeState.value != customTime) customTimeState.value = customTime;
|
||||||
|
|
||||||
|
return () {};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
DateTime getWeekStartDate() {
|
||||||
|
DateTime now = DateTime.now();
|
||||||
|
int dayOfWeek = now.weekday; // 获取今天是周几(1代表周一,7代表周日)
|
||||||
|
int diff = dayOfWeek - 1; // 计算今天距离周一的天数差
|
||||||
|
if (diff < 0) {
|
||||||
|
diff += 7; // 如果是周日,则需要加上一周的天数
|
||||||
|
}
|
||||||
|
return now.subtract(Duration(days: diff)); // 减去天数差,得到本周一的时间
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime getWeekEndDate() {
|
||||||
|
DateTime now = DateTime.now();
|
||||||
|
int dayOfWeek = now.weekday; // 获取今天是周几
|
||||||
|
int diff = 7 - dayOfWeek; // 计算今天距离周日的天数差
|
||||||
|
if (diff == 0) {
|
||||||
|
diff = 7; // 如果是周日,则加上一周的天数
|
||||||
|
}
|
||||||
|
return now.add(Duration(days: diff)); // 加上天数差减一,得到本周日的时间
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime getMonthStartDate() {
|
||||||
|
DateTime now = DateTime.now();
|
||||||
|
return DateTime(now.year, now.month, 1); // 获取当前月份的第一天
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime getMonthEndDate() {
|
||||||
|
DateTime now = DateTime.now();
|
||||||
|
int nextMonth = now.month + 1;
|
||||||
|
if (nextMonth > 12) {
|
||||||
|
nextMonth = 1;
|
||||||
|
now = now.add(Duration(days: 31 - now.day)); // 跨年了,所以加到当前月的最后一天
|
||||||
|
} else {
|
||||||
|
now = now.add(Duration(days: DateTime(now.year, nextMonth, 0).day - now.day)); // 加到下个月的第一天的前一天,即本月最后一天
|
||||||
|
}
|
||||||
|
return now;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
height: 39.h,
|
||||||
|
padding: EdgeInsets.only(left: 4.w, right: 12.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color.fromRGBO(244, 244, 244, 1),
|
||||||
|
border: Border(bottom: BorderSide(color: Color.fromRGBO(204, 204, 204, 1), width: 1)),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
$TheTabBar(
|
||||||
|
controller: controller,
|
||||||
|
customTime: customTimeState.value,
|
||||||
|
onTap: (int val) async {
|
||||||
|
switch (val) {
|
||||||
|
case 0: // 全部
|
||||||
|
onTimeFilter(null, null);
|
||||||
|
break;
|
||||||
|
case 1: // 近一周
|
||||||
|
onTimeFilter(
|
||||||
|
getWeekStartDate().toString().substring(0, 10),
|
||||||
|
getWeekEndDate().toString().substring(0, 10),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 2: // 近一个月
|
||||||
|
onTimeFilter(
|
||||||
|
getMonthStartDate().toString().substring(0, 10),
|
||||||
|
getMonthEndDate().toString().substring(0, 10),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default: // 自定义
|
||||||
|
// DateTimeRange? range = await showDateRangePicker(
|
||||||
|
// // locale: const Locale('zh', 'CN'),
|
||||||
|
// locale: const Locale('zh', 'CN'),
|
||||||
|
// context: context,
|
||||||
|
// confirmText: '搜索',
|
||||||
|
// initialEntryMode: DatePickerEntryMode.calendarOnly,
|
||||||
|
// currentDate: DateTime.now(),
|
||||||
|
// firstDate: DateTime.now().subtract(const Duration(days: 4)),
|
||||||
|
// lastDate: DateTime.now().add(const Duration(days: 3)),
|
||||||
|
// );
|
||||||
|
|
||||||
|
var dialogData = await showDialog<PickerDateRange?>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context1) {
|
||||||
|
return Center(
|
||||||
|
child: Container(
|
||||||
|
color: Colors.white,
|
||||||
|
width: isPad() ? ScreenUtil().screenWidth / 2 : ScreenUtil().screenWidth / 1.3,
|
||||||
|
height: ScreenUtil().screenHeight / 2,
|
||||||
|
child: SfDateRangePicker(
|
||||||
|
showActionButtons: true,
|
||||||
|
confirmText: '确定',
|
||||||
|
cancelText: '取消',
|
||||||
|
onSubmit: (p0) {
|
||||||
|
print(p0);
|
||||||
|
Navigator.of(context1).pop(p0);
|
||||||
|
},
|
||||||
|
onCancel: () {
|
||||||
|
Navigator.of(context1).pop();
|
||||||
|
},
|
||||||
|
selectionMode: DateRangePickerSelectionMode.range,
|
||||||
|
initialSelectedRange: customTimeState.value,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
// startDate: 2024-03-04 18:47:00.117958, endDate: 2024-03-11 18:47:00.117986
|
||||||
|
// if (dialogData != null && (dialogData.startDate != null || dialogData.endDate != null)) {}
|
||||||
|
onTimeFilter(
|
||||||
|
dialogData?.startDate?.toString().substring(0, 10),
|
||||||
|
dialogData?.endDate?.toString().substring(0, 10),
|
||||||
|
);
|
||||||
|
customTimeState.value = dialogData;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expanded(child: SizedBox()),
|
||||||
|
Container(
|
||||||
|
width: 74.r,
|
||||||
|
margin: EdgeInsets.symmetric(vertical: 5.h),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.vertical(
|
||||||
|
top: Radius.elliptical(6, 6),
|
||||||
|
bottom: Radius.elliptical(6, 6),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: DropdownButton(
|
||||||
|
icon: Icon(Icons.expand_more_outlined),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
// value: params2.jobType ?? 1,
|
||||||
|
value: jobType,
|
||||||
|
style: TextStyle(color: Color.fromRGBO(89, 89, 89, 1), fontSize: 12.sp),
|
||||||
|
underline: Container(),
|
||||||
|
isExpanded: true,
|
||||||
|
items: jobTypes.map((e) {
|
||||||
|
return DropdownMenuItem(
|
||||||
|
value: e['type'],
|
||||||
|
child: quickText(e['name'], size: 12.sp, color: Colors.black),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
onChanged: (dynamic value) {
|
||||||
|
if (value != null) {
|
||||||
|
jobTypeState.value = value;
|
||||||
|
onJobTypeTap(value as int);
|
||||||
|
}
|
||||||
|
// jobTypeState
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,798 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
|
import 'package:flutter_easyrefresh/easy_refresh.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:functional_widget_annotation/functional_widget_annotation.dart';
|
||||||
|
import 'package:marking_app/common/mixin/common.dart';
|
||||||
|
import 'package:marking_app/common/model/common/base_structure_result.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_student_history.dart';
|
||||||
|
import 'package:marking_app/components/ReturnToHomepage.dart';
|
||||||
|
import 'package:marking_app/pages/homework_correction/widget/personal_detail_topbar.dart';
|
||||||
|
import 'package:marking_app/routes/RouterManager.dart';
|
||||||
|
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
|
||||||
|
import 'package:marking_app/utils/index.dart';
|
||||||
|
import 'package:marking_app/utils/my_text.dart';
|
||||||
|
import 'package:marking_app/utils/request/rest_client.dart';
|
||||||
|
import 'package:marking_app/utils/right_home_icon.dart';
|
||||||
|
import 'package:percent_indicator/percent_indicator.dart';
|
||||||
|
import 'package:syncfusion_flutter_datepicker/datepicker.dart';
|
||||||
|
|
||||||
|
part 'job_personal_detail.g.dart';
|
||||||
|
|
||||||
|
class JobPersonalDetail extends StatefulWidget {
|
||||||
|
final String studentName;
|
||||||
|
final int studentId;
|
||||||
|
|
||||||
|
const JobPersonalDetail({Key? key, required this.studentName, required this.studentId}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_JobPersonalDetailState createState() => _JobPersonalDetailState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _JobPersonalDetailState extends State<JobPersonalDetail> with CommonMixin, TickerProviderStateMixin {
|
||||||
|
@override
|
||||||
|
int page = 1;
|
||||||
|
int pageSize = 10;
|
||||||
|
int totalPages = 0;
|
||||||
|
JobStudentHistory? studentData;
|
||||||
|
bool isJob = true;
|
||||||
|
late TabController tabController;
|
||||||
|
String startDataTime = '';
|
||||||
|
String endDataTime = '';
|
||||||
|
String customTimeStr = '自定义';
|
||||||
|
List<Items> dataList = [];
|
||||||
|
late final EasyRefreshController refreshController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
refreshController = EasyRefreshController();
|
||||||
|
tabController = TabController(length: 4, vsync: this);
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
tabController.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void getList() async {
|
||||||
|
RestClient _client = await getClient();
|
||||||
|
BaseStructureResult<JobStudentHistory> res =
|
||||||
|
await _client.getStudentJobHistory(widget.studentId, !isJob, startDataTime, endDataTime, page, pageSize);
|
||||||
|
if (res.success) {
|
||||||
|
res.data!.pagedList.items.forEach((element) {
|
||||||
|
int num = 0;
|
||||||
|
element.objectiveDtls.forEach((item) {
|
||||||
|
if (item.state == 0) {
|
||||||
|
num = num + 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
element.subjectiveDtls.forEach((subject) {
|
||||||
|
if (subject.state == 0) {
|
||||||
|
num = num + 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (num == (element.objectiveDtls.length + element.subjectiveDtls.length)) {
|
||||||
|
element.allNotDone = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
studentData = res.data!;
|
||||||
|
if (page == 1) {
|
||||||
|
dataList = studentData!.pagedList.items;
|
||||||
|
} else {
|
||||||
|
dataList = [...dataList, ...studentData!.pagedList.items];
|
||||||
|
}
|
||||||
|
|
||||||
|
totalPages = res.data!.pagedList.totalPages;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
EasyLoading.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
bool isPadFlag = isPad();
|
||||||
|
if (studentData == null) return Container();
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: Color.fromRGBO(245, 245, 245, 1),
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
title: Text('${widget.studentName}作业详情', style: TextStyle(fontSize: 14.sp, color: Color(0xFF333333))),
|
||||||
|
centerTitle: true,
|
||||||
|
leading: IconButton(
|
||||||
|
icon: Icon(Icons.arrow_back_ios, color: Colors.black),
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
ReturnToHomepage(),
|
||||||
|
],
|
||||||
|
elevation: 0,
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: 1.r,
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
color: Color.fromRGBO(179, 179, 179, 0.3),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
color: Colors.white,
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 2.r),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
setState(() {
|
||||||
|
isJob = true;
|
||||||
|
page = 1;
|
||||||
|
totalPages = 0;
|
||||||
|
});
|
||||||
|
getList();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: (MediaQuery.of(context).size.width - 1.r) / 2,
|
||||||
|
height: 40.r,
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'作业',
|
||||||
|
style: TextStyle(fontSize: 14.sp, color: isJob ? Color(0xFF7491FD) : Color(0xFF505E6E)),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
height: 40.r,
|
||||||
|
width: 1.r,
|
||||||
|
color: Color.fromRGBO(179, 179, 179, 0.3),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
setState(() {
|
||||||
|
isJob = false;
|
||||||
|
page = 1;
|
||||||
|
totalPages = 0;
|
||||||
|
});
|
||||||
|
getList();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: (MediaQuery.of(context).size.width - 1.r) / 2,
|
||||||
|
height: 40.r,
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'考试',
|
||||||
|
style: TextStyle(fontSize: 14.sp, color: !isJob ? Color(0xFF7491FD) : Color(0xFF505E6E)),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.symmetric(vertical: 10.r, horizontal: 14.r),
|
||||||
|
padding: EdgeInsets.only(top: 10.r, left: 10.r, right: 10.r, bottom: 10.r),
|
||||||
|
decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(10.r)), color: Colors.white),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'总览:',
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF7491FD), fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
progressBar(context,
|
||||||
|
title: '客观题正确率:',
|
||||||
|
color: Color(0xFFB8C7FF),
|
||||||
|
percent: studentData!.objectiveCorrectRate / 100,
|
||||||
|
padingEdg: EdgeInsets.zero,
|
||||||
|
marginEdg: EdgeInsets.only(top: 8.h)),
|
||||||
|
progressBar(context,
|
||||||
|
title: '主观题正确率:',
|
||||||
|
color: Color(0xFFB8C7FF),
|
||||||
|
percent: studentData!.subjectiveCorrectRate / 100,
|
||||||
|
padingEdg: EdgeInsets.zero,
|
||||||
|
marginEdg: EdgeInsets.only(top: 8.h)),
|
||||||
|
progressBar(context,
|
||||||
|
title: '总正确率:',
|
||||||
|
color: Color(0xFFB8C7FF),
|
||||||
|
percent: studentData!.correctRate / 100,
|
||||||
|
padingEdg: EdgeInsets.zero,
|
||||||
|
marginEdg: EdgeInsets.only(top: 8.h)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
/* SizedBox(
|
||||||
|
height: 5.r,
|
||||||
|
),*/
|
||||||
|
jobConditionFilter(context,
|
||||||
|
controller: tabController,
|
||||||
|
jobType: isJob ? 1 : 2,
|
||||||
|
customTimeStr: customTimeStr,
|
||||||
|
customTime: tabController.index != 3 ||
|
||||||
|
((endDataTime == null || endDataTime == '') && (startDataTime == null || startDataTime == ''))
|
||||||
|
? null
|
||||||
|
: PickerDateRange(
|
||||||
|
startDataTime == null || startDataTime == '' ? null : DateTime.parse(startDataTime!),
|
||||||
|
endDataTime == null || endDataTime == '' ? null : DateTime.parse(endDataTime!),
|
||||||
|
), onTimeFilter: (String? startTime, String? endTime) {
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
if (startTime == null && endTime == null) {
|
||||||
|
if (tabController.index == 3) {
|
||||||
|
tabController.animateTo(0);
|
||||||
|
}
|
||||||
|
startDataTime = '';
|
||||||
|
endDataTime = '';
|
||||||
|
customTimeStr = '自定义';
|
||||||
|
} else {
|
||||||
|
print('startTime=$startTime');
|
||||||
|
print('endDataTime=$endTime');
|
||||||
|
startDataTime = startTime != null ? startTime : '';
|
||||||
|
endDataTime = endTime != null ? endTime : '';
|
||||||
|
}
|
||||||
|
page = 1;
|
||||||
|
setState(() {});
|
||||||
|
getList();
|
||||||
|
// _refreshController2.callRefresh();
|
||||||
|
}, refreshTime: (value) {
|
||||||
|
if (value != null && value.startDate != null) {
|
||||||
|
customTimeStr = value.startDate?.toString().substring(0, 10) ?? '';
|
||||||
|
setState(() {});
|
||||||
|
if (value.endDate != null) {
|
||||||
|
if (!isPad() && value.startDate!.year == value.endDate!.year) {
|
||||||
|
customTimeStr =
|
||||||
|
value.startDate.toString().substring(5, 10) + '~${value.endDate.toString().substring(5, 10)}';
|
||||||
|
setState(() {});
|
||||||
|
} else {
|
||||||
|
customTimeStr = '$customTimeStr~${value.endDate?.toString().substring(0, 10)}';
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(top: 14.r, right: 14.r),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'注:',
|
||||||
|
style: TextStyle(fontSize: 8.sp, color: Color(0xFF8B8B8B)),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 10.r,
|
||||||
|
height: 10.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(5.r)),
|
||||||
|
// color: Color(0xFF4CC793),
|
||||||
|
border: Border.all(width: 1.r, color: Color(0xFF4CC793)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 2.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'正确',
|
||||||
|
style: TextStyle(fontSize: 8.sp, color: Color(0xFF8B8B8B)),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 15.r,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 10.r,
|
||||||
|
height: 10.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(5.r)),
|
||||||
|
// color: Color(0xFFFF7474),
|
||||||
|
border: Border.all(width: 1.r, color: Color(0xFFFF7474)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 2.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'错误',
|
||||||
|
style: TextStyle(fontSize: 8.sp, color: Color(0xFF8B8B8B)),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 15.r,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 10.r,
|
||||||
|
height: 10.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(5.r)),
|
||||||
|
// color: Color(0xFF666666),
|
||||||
|
border: Border.all(width: 1.r, color: Color(0xFF666666)),
|
||||||
|
// border: Border.all(width: 1.r,color: Colors.grey),
|
||||||
|
/* boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey,
|
||||||
|
offset: Offset(1.w, 1.h), //阴影y轴偏移量
|
||||||
|
blurRadius: 4, //阴影模糊程度
|
||||||
|
spreadRadius: 0.1, //阴影扩散程度
|
||||||
|
)
|
||||||
|
],*/
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 2.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'已作答未批阅',
|
||||||
|
style: TextStyle(fontSize: 8.sp, color: Color(0xFF8B8B8B)),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 15.r,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 10.r,
|
||||||
|
height: 10.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(5.r)),
|
||||||
|
border: Border.all(width: 1.r, color: Color(0xFFDDDDDD)),
|
||||||
|
// color: Color(0xFFDDDDDD),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 2.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'未做',
|
||||||
|
style: TextStyle(fontSize: 8.sp, color: Color(0xFF8B8B8B)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.r),
|
||||||
|
child: EasyRefresh(
|
||||||
|
firstRefresh: false,
|
||||||
|
taskIndependence: true,
|
||||||
|
controller: refreshController,
|
||||||
|
header: MaterialHeader(),
|
||||||
|
footer: TaurusFooter(),
|
||||||
|
onRefresh: () async {
|
||||||
|
setState(() {
|
||||||
|
page = 1;
|
||||||
|
});
|
||||||
|
getList();
|
||||||
|
},
|
||||||
|
onLoad: () async {
|
||||||
|
if (page < totalPages) {
|
||||||
|
setState(() {
|
||||||
|
page += 1;
|
||||||
|
});
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: dataList.length > 0
|
||||||
|
? ListView.builder(
|
||||||
|
itemCount: dataList.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
Items item = dataList[index];
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
/* RouterManager.router.navigateTo(
|
||||||
|
context,
|
||||||
|
RouterManager.quickDataCheckPath +
|
||||||
|
'?gradeName=${Uri.encodeComponent(item.gradeName)}&className=${Uri.encodeComponent(item.className)}&jobId=${item.id}',
|
||||||
|
transition: getTransition(),
|
||||||
|
);*/
|
||||||
|
RouterManager.router.navigateTo(
|
||||||
|
context,
|
||||||
|
RouterManager.quickCheckPersonalPath +
|
||||||
|
'?jobId=${item.id}&studentId=${widget.studentId}',
|
||||||
|
transition: getTransition(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.symmetric(vertical: 5.r, horizontal: 14.r),
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 14.r, horizontal: 10.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(10.r)),
|
||||||
|
color: item.allNotDone ? Color(0xFFFFEDD3) : Colors.white),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 32.w,
|
||||||
|
height: 18.h,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
padding: EdgeInsets.only(left: 2.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: isJob ? const Color.fromRGBO(104, 136, 253, 1) : Color(0xFFFFA116),
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(14.r),
|
||||||
|
topRight: Radius.circular(3.r),
|
||||||
|
bottomLeft: Radius.circular(4.r),
|
||||||
|
bottomRight: Radius.circular(4.r),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
margin: EdgeInsets.only(right: 4.w),
|
||||||
|
child: Text(
|
||||||
|
isJob ? '作业' : '考试',
|
||||||
|
style: TextStyle(fontSize: 10.sp, color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
item.name,
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF464646)),
|
||||||
|
)),
|
||||||
|
// SizedBox(width: 5.r,),
|
||||||
|
// Text('2024.1',style: TextStyle(fontSize: 12.sp,color: Color(0xFF5B5B5B)),),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
width: 40.r,
|
||||||
|
height: 20.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(4.r)),
|
||||||
|
border: Border.all(width: 1.r, color: Color(0xFF4CC793)),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
item.subjectName,
|
||||||
|
style: TextStyle(fontSize: 10.sp, color: Color(0xFF4CC793)),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.r,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'客:',
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF5B5B5B)),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 5.r,
|
||||||
|
),
|
||||||
|
item.objectiveDtls.length > 0
|
||||||
|
? Expanded(
|
||||||
|
child: Wrap(
|
||||||
|
direction: Axis.horizontal,
|
||||||
|
alignment: WrapAlignment.start,
|
||||||
|
spacing: 8,
|
||||||
|
runSpacing: 5,
|
||||||
|
children: List.generate(item.objectiveDtls.length, (i) {
|
||||||
|
SubjectiveDtls subjective = item.objectiveDtls[i];
|
||||||
|
return Container(
|
||||||
|
width: 20.r,
|
||||||
|
height: 20.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.transparent,
|
||||||
|
border: Border.all(
|
||||||
|
width: 1.r,
|
||||||
|
color: subjective.state == 0
|
||||||
|
? Color(0xFFDDDDDD)
|
||||||
|
: subjective.state == 3
|
||||||
|
? Color(0xFF666666)
|
||||||
|
: subjective.state == 1
|
||||||
|
? Color(0xFFFF7474)
|
||||||
|
: Color(0xFF4CC793)),
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(10.r))),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
subjective.questionNo,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.r,
|
||||||
|
color: subjective.state == 0
|
||||||
|
? Color(0xFFDDDDDD)
|
||||||
|
: subjective.state == 3
|
||||||
|
? Color(0xFF666666)
|
||||||
|
: subjective.state == 1
|
||||||
|
? Color(0xFFFF7474)
|
||||||
|
: Color(0xFF4CC793)),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Text(
|
||||||
|
'无',
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF5B5B5B)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.r,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'主:',
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF5B5B5B)),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 5.r,
|
||||||
|
),
|
||||||
|
item.subjectiveDtls.length > 0
|
||||||
|
? Expanded(
|
||||||
|
child: Wrap(
|
||||||
|
direction: Axis.horizontal,
|
||||||
|
alignment: WrapAlignment.start,
|
||||||
|
spacing: 8,
|
||||||
|
runSpacing: 5,
|
||||||
|
children: List.generate(item.subjectiveDtls.length, (i) {
|
||||||
|
SubjectiveDtls subjective = item.subjectiveDtls[i];
|
||||||
|
return Container(
|
||||||
|
width: 20.r,
|
||||||
|
height: 20.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.transparent,
|
||||||
|
border: Border.all(
|
||||||
|
width: 1.r,
|
||||||
|
color: subjective.state == 0
|
||||||
|
? Color(0xFFDDDDDD)
|
||||||
|
: subjective.state == 3
|
||||||
|
? Color(0xFF666666)
|
||||||
|
: subjective.state == 1
|
||||||
|
? Color(0xFFFF7474)
|
||||||
|
: Color(0xFF4CC793)),
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(10.r))),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
subjective.questionNo,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.r,
|
||||||
|
color: subjective.state == 0
|
||||||
|
? Color(0xFFDDDDDD)
|
||||||
|
: subjective.state == 3
|
||||||
|
? Color(0xFF666666)
|
||||||
|
: subjective.state == 1
|
||||||
|
? Color(0xFFFF7474)
|
||||||
|
: Color(0xFF4CC793)),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Text(
|
||||||
|
'无',
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF5B5B5B)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
progressBar(context,
|
||||||
|
title: '客观题正确率:',
|
||||||
|
color: Color(0xFF90E0BE),
|
||||||
|
percent: item.objectiveCorrectRate / 100,
|
||||||
|
padingEdg: EdgeInsets.zero,
|
||||||
|
marginEdg: EdgeInsets.only(top: 8.h)),
|
||||||
|
progressBar(context,
|
||||||
|
title: '主观题正确率:',
|
||||||
|
color: Color(0xFF90E0BE),
|
||||||
|
percent: item.subjectiveCorrectRate / 100,
|
||||||
|
padingEdg: EdgeInsets.zero,
|
||||||
|
marginEdg: EdgeInsets.only(top: 8.h)),
|
||||||
|
progressBar(context,
|
||||||
|
title: '总正确率:',
|
||||||
|
color: Color(0xFF90E0BE),
|
||||||
|
percent: item.correctRate / 100,
|
||||||
|
padingEdg: EdgeInsets.zero,
|
||||||
|
marginEdg: EdgeInsets.only(top: 8.h)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
})
|
||||||
|
: MyEmptyWidget(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@swidget
|
||||||
|
Widget progressBar(
|
||||||
|
BuildContext context, {
|
||||||
|
double? fontSize,
|
||||||
|
double? lineHeight,
|
||||||
|
required String title,
|
||||||
|
required Color color,
|
||||||
|
required double percent,
|
||||||
|
required EdgeInsets padingEdg,
|
||||||
|
required EdgeInsets marginEdg,
|
||||||
|
}) {
|
||||||
|
var percentStr = '${doubleToStringAsFixed(percent * 100)}%';
|
||||||
|
fontSize ??= 10.sp;
|
||||||
|
lineHeight ??= 8.h;
|
||||||
|
return Container(
|
||||||
|
margin: marginEdg,
|
||||||
|
padding: padingEdg,
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
if (title == '总正确率:') quickText('确率', color: Colors.transparent, size: fontSize),
|
||||||
|
quickText(title, color: Color(0xFF8B8B8B), size: fontSize),
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: Container(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(10.r),
|
||||||
|
/* boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: color,
|
||||||
|
spreadRadius: 0.6,
|
||||||
|
blurRadius: 3,
|
||||||
|
offset: Offset(0, 0),
|
||||||
|
),
|
||||||
|
],*/
|
||||||
|
),
|
||||||
|
child: LinearPercentIndicator(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
animation: true,
|
||||||
|
lineHeight: lineHeight,
|
||||||
|
animationDuration: 2500,
|
||||||
|
percent: percent,
|
||||||
|
/* center: Text(
|
||||||
|
percentStr,
|
||||||
|
style: TextStyle(color: Colors.white, fontSize: 4.5.sp),
|
||||||
|
),*/
|
||||||
|
// linearStrokeCap: LinearStrokeCap.butt,
|
||||||
|
progressColor: color,
|
||||||
|
backgroundColor: Color(0xFFE8E8E8),
|
||||||
|
barRadius: Radius.circular(10.r),
|
||||||
|
// linearGradient: LinearGradient(
|
||||||
|
// tileMode: TileMode.mirror,
|
||||||
|
// stops: [0.0, 1.0],
|
||||||
|
// colors: [color.withOpacity(0.1), color],
|
||||||
|
// ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
quickText(percentStr, size: fontSize, color: Color(0xFF464646))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 已完成作业条件筛选栏
|
||||||
|
@hwidget
|
||||||
|
Widget jobConditionFilter(BuildContext context,
|
||||||
|
{required TabController controller,
|
||||||
|
required int jobType,
|
||||||
|
PickerDateRange? customTime,
|
||||||
|
required Function refreshTime,
|
||||||
|
required String customTimeStr,
|
||||||
|
required Function(String? startTime, String? endTime) onTimeFilter}) {
|
||||||
|
var customTimeState = PickerDateRange(null, null);
|
||||||
|
print('customTime=${customTime}');
|
||||||
|
if (customTime != null) {
|
||||||
|
customTimeState = PickerDateRange(customTime!.startDate != null ? customTime!.startDate : null,
|
||||||
|
customTime!.endDate != null ? customTime!.endDate : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime getWeekStartDate() {
|
||||||
|
DateTime now = DateTime.now();
|
||||||
|
int dayOfWeek = now.weekday; // 获取今天是周几(1代表周一,7代表周日)
|
||||||
|
int diff = dayOfWeek - 1; // 计算今天距离周一的天数差
|
||||||
|
if (diff < 0) {
|
||||||
|
diff += 7; // 如果是周日,则需要加上一周的天数
|
||||||
|
}
|
||||||
|
return now.subtract(Duration(days: diff)); // 减去天数差,得到本周一的时间
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime getWeekEndDate() {
|
||||||
|
DateTime now = DateTime.now();
|
||||||
|
int dayOfWeek = now.weekday; // 获取今天是周几
|
||||||
|
int diff = 7 - dayOfWeek; // 计算今天距离周日的天数差
|
||||||
|
if (diff == 0) {
|
||||||
|
diff = 7; // 如果是周日,则加上一周的天数
|
||||||
|
}
|
||||||
|
return now.add(Duration(days: diff)); // 加上天数差减一,得到本周日的时间
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime getMonthStartDate() {
|
||||||
|
DateTime now = DateTime.now();
|
||||||
|
return DateTime(now.year, now.month, 1); // 获取当前月份的第一天
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime getMonthEndDate() {
|
||||||
|
DateTime now = DateTime.now();
|
||||||
|
int nextMonth = now.month + 1;
|
||||||
|
if (nextMonth > 12) {
|
||||||
|
nextMonth = 1;
|
||||||
|
now = now.add(Duration(days: 31 - now.day)); // 跨年了,所以加到当前月的最后一天
|
||||||
|
} else {
|
||||||
|
now = now.add(Duration(days: DateTime(now.year, nextMonth, 0).day - now.day)); // 加到下个月的第一天的前一天,即本月最后一天
|
||||||
|
}
|
||||||
|
return now;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
// height: 39.h,
|
||||||
|
// padding: EdgeInsets.only(left: 4.w, right: 12.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color.fromRGBO(244, 244, 244, 1),
|
||||||
|
// border: Border(bottom: BorderSide(color: Color.fromRGBO(204, 204, 204, 1), width: 1)),
|
||||||
|
),
|
||||||
|
child: PersonalDetailTopBar(
|
||||||
|
controller: controller,
|
||||||
|
customTimeStr: customTimeStr,
|
||||||
|
onTap: (int val) async {
|
||||||
|
switch (val) {
|
||||||
|
case 0: // 全部
|
||||||
|
onTimeFilter(null, null);
|
||||||
|
break;
|
||||||
|
case 1: // 近一周
|
||||||
|
onTimeFilter(
|
||||||
|
getWeekStartDate().toString().substring(0, 10),
|
||||||
|
getWeekEndDate().toString().substring(0, 10),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 2: // 近一个月
|
||||||
|
onTimeFilter(
|
||||||
|
getMonthStartDate().toString().substring(0, 10),
|
||||||
|
getMonthEndDate().toString().substring(0, 10),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default: // 自定义
|
||||||
|
var dialogData = await showDialog<PickerDateRange?>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context1) {
|
||||||
|
return Center(
|
||||||
|
child: Container(
|
||||||
|
color: Colors.white,
|
||||||
|
width: isPad() ? ScreenUtil().screenWidth / 2 : ScreenUtil().screenWidth / 1.3,
|
||||||
|
height: ScreenUtil().screenHeight / 2,
|
||||||
|
child: SfDateRangePicker(
|
||||||
|
showActionButtons: true,
|
||||||
|
confirmText: '确定',
|
||||||
|
cancelText: '取消',
|
||||||
|
onSubmit: (p0) {
|
||||||
|
print(p0);
|
||||||
|
Navigator.of(context1).pop(p0);
|
||||||
|
refreshTime(p0);
|
||||||
|
},
|
||||||
|
onCancel: () {
|
||||||
|
Navigator.of(context1).pop();
|
||||||
|
},
|
||||||
|
selectionMode: DateRangePickerSelectionMode.range,
|
||||||
|
initialSelectedRange: customTimeState,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
// startDate: 2024-03-04 18:47:00.117958, endDate: 2024-03-11 18:47:00.117986
|
||||||
|
// if (dialogData != null && (dialogData.startDate != null || dialogData.endDate != null)) {}
|
||||||
|
onTimeFilter(
|
||||||
|
dialogData?.startDate?.toString().substring(0, 10),
|
||||||
|
dialogData?.endDate?.toString().substring(0, 10),
|
||||||
|
);
|
||||||
|
customTimeState = dialogData!;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,312 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
|
import 'package:flutter_easyrefresh/easy_refresh.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:marking_app/common/mixin/common.dart';
|
||||||
|
import 'package:marking_app/common/model/common/base_structure_result.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_level_set_params.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_review_submission.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_student_level.dart';
|
||||||
|
import 'package:marking_app/components/ReturnToHomepage.dart';
|
||||||
|
import 'package:marking_app/routes/RouterManager.dart';
|
||||||
|
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
|
||||||
|
import 'package:marking_app/utils/index.dart';
|
||||||
|
import 'package:marking_app/utils/request/rest_client.dart';
|
||||||
|
|
||||||
|
class JobPriorityReviewSet extends StatefulWidget {
|
||||||
|
final String groupId;
|
||||||
|
const JobPriorityReviewSet({Key? key,required this.groupId}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<JobPriorityReviewSet> createState() => _JobPriorityReviewSetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _JobPriorityReviewSetState extends State<JobPriorityReviewSet>
|
||||||
|
with CommonMixin,SingleTickerProviderStateMixin {
|
||||||
|
late final EasyRefreshController refreshController;
|
||||||
|
late TabController tabController;
|
||||||
|
int tabIndex = 0;
|
||||||
|
List levelList = [];
|
||||||
|
bool isClicking = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
refreshController = EasyRefreshController();
|
||||||
|
tabController =
|
||||||
|
TabController(initialIndex: tabIndex, length: 2, vsync: this);
|
||||||
|
getReadLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void getReadLevel() async{
|
||||||
|
RestClient _client = await getClient();
|
||||||
|
BaseStructureResult<List<JobStudentLevel>> res = await _client.getJobReadLevel(widget.groupId,tabIndex == 0?1:0);
|
||||||
|
setState(() {
|
||||||
|
if(res.success){
|
||||||
|
levelList = res.data!;
|
||||||
|
isClicking = false;
|
||||||
|
}else{
|
||||||
|
levelList = [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
EasyLoading.dismiss();
|
||||||
|
refreshController.finishRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setJobReadLevel(int studentId,int level) async{
|
||||||
|
RestClient _client = await getClient();
|
||||||
|
JobLevelSetParams params = JobLevelSetParams(studentId, level);
|
||||||
|
BaseStructureResult res = await _client.getSetJobReadLevel(params);
|
||||||
|
if(res.code == 200){
|
||||||
|
getReadLevel();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
refreshController.dispose();
|
||||||
|
tabController.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
bool isPadFlag = isPad();
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: Color.fromRGBO(245, 245, 245, 1),
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
title: Text(
|
||||||
|
'优先批阅人配置',
|
||||||
|
style: TextStyle(fontSize: 14.sp, color: Color(0xFF333333)),
|
||||||
|
),
|
||||||
|
centerTitle: true,
|
||||||
|
leading: IconButton(
|
||||||
|
icon: Icon(Icons.arrow_back_ios, color: Colors.black),
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
ReturnToHomepage(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 10.r,),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 14.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border(bottom: BorderSide(width: 1.r,color: Color(0xFFCCCCCC)))
|
||||||
|
),
|
||||||
|
child: TabBar(
|
||||||
|
onTap: (int val) {
|
||||||
|
print(val);
|
||||||
|
setState(() {
|
||||||
|
tabIndex = val;
|
||||||
|
});
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
getReadLevel();
|
||||||
|
},
|
||||||
|
tabs: [
|
||||||
|
SizedBox(
|
||||||
|
width: (MediaQuery.of(context).size.width - 28.r) /2,
|
||||||
|
child: Tab(
|
||||||
|
text: '优先批阅',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: (MediaQuery.of(context).size.width - 28.r) /2,
|
||||||
|
child: Tab(
|
||||||
|
text: '默认批阅',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
controller: tabController,
|
||||||
|
unselectedLabelStyle: TextStyle(
|
||||||
|
fontSize: 14.sp, color:Color(0xFF666666)),
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Color(0xFF6888FD),
|
||||||
|
),
|
||||||
|
isScrollable: true,
|
||||||
|
labelColor: Color(0xFF6888FD),
|
||||||
|
unselectedLabelColor: Color(0xFF666666),
|
||||||
|
indicatorSize: TabBarIndicatorSize.label,
|
||||||
|
labelPadding: const EdgeInsets.all(0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Expanded(
|
||||||
|
child:Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical:14.r,horizontal: 14.r),
|
||||||
|
child: EasyRefresh(
|
||||||
|
firstRefresh: true,
|
||||||
|
taskIndependence: true,
|
||||||
|
controller: refreshController,
|
||||||
|
header: MaterialHeader(),
|
||||||
|
footer: TaurusFooter(),
|
||||||
|
onRefresh: () async{
|
||||||
|
getReadLevel();
|
||||||
|
},
|
||||||
|
child: levelList.length>0?isPadFlag?GridView(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: 2,
|
||||||
|
mainAxisSpacing: 10.r,
|
||||||
|
crossAxisSpacing: 10.r,
|
||||||
|
childAspectRatio: 556 / 112,
|
||||||
|
),children: List.generate(levelList.length, (index) {
|
||||||
|
JobStudentLevel item = levelList[index];
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(10.r)),
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(child: Text(item.studentName,style: TextStyle(fontSize: 12.sp,color: Color(0xFF6888FD)),)),
|
||||||
|
|
||||||
|
tabIndex == 0?InkWell(
|
||||||
|
onTap: (){
|
||||||
|
setState(() {
|
||||||
|
isClicking = true;
|
||||||
|
});
|
||||||
|
setJobReadLevel(item.studentGroupDetailId,0);
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
height: 20.r,
|
||||||
|
width: 70.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(20.r)),
|
||||||
|
color: isClicking?Color(0xFFDCE3FF):Color(0xFF6888FD),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child:Text('取消优先',style: TextStyle(fontSize: 10.sp,color: Colors.white),),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
):InkWell(
|
||||||
|
onTap: (){
|
||||||
|
setState(() {
|
||||||
|
isClicking = true;
|
||||||
|
});
|
||||||
|
setJobReadLevel(item.studentGroupDetailId,1);
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
height: 20.r,
|
||||||
|
width: 70.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(20.r)),
|
||||||
|
color: isClicking?Color(0xFF6888FD):Color(0xFFFFFFFF),
|
||||||
|
border: Border.all(width: 1.r,color: isClicking?Color(0xFFFFFFFF):Color(0xFF6888FD)),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child:Text('设为优先',style: TextStyle(fontSize: 10.sp,color: isClicking?Color(0xFFFFFFFF):Color(0xFF6888FD)),),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 5.r,),
|
||||||
|
InkWell(
|
||||||
|
onTap: (){
|
||||||
|
RouterManager.router.navigateTo(context, '${RouterManager.jobPersonalDetailPath}?studentId=${item.studentId}&studentName=${Uri.encodeComponent(item.studentName)}');
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
height: 20.r,
|
||||||
|
width: 70.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(20.r)),
|
||||||
|
color: Colors.white,
|
||||||
|
border: Border.all(width: 1.r,color: Color(0xFFFCA017))
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text('详情',style: TextStyle(fontSize: 10.sp,color: Color(0xFFFCA017)),),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),):ListView.builder(itemBuilder: (context,index){
|
||||||
|
JobStudentLevel item = levelList[index];
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical:20.r,horizontal: 15.r),
|
||||||
|
margin: EdgeInsets.only(bottom: 15.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(10.r)),
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(child: Text(item.studentName,style: TextStyle(fontSize: 12.sp,color: Color(0xFF6888FD)),)),
|
||||||
|
tabIndex == 0?InkWell(
|
||||||
|
onTap: (){
|
||||||
|
setState(() {
|
||||||
|
isClicking = true;
|
||||||
|
});
|
||||||
|
setJobReadLevel(item.studentGroupDetailId,0);
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
height: 24.r,
|
||||||
|
width: 82.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(20.r)),
|
||||||
|
color: isClicking?Color(0xFFDCE3FF):Color(0xFF6888FD),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child:Text('取消优先',style: TextStyle(fontSize: 10.sp,color: Colors.white),),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
):InkWell(
|
||||||
|
onTap: (){
|
||||||
|
setJobReadLevel(item.studentGroupDetailId,1);
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
height: 24.r,
|
||||||
|
width: 82.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(20.r)),
|
||||||
|
color: Color(0xFFFFFFFF),
|
||||||
|
border: Border.all(width: 1.r,color: Color(0xFF6888FD)),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child:Text('设为优先',style: TextStyle(fontSize: 10.sp,color: Color(0xFF6888FD)),),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 5.r,),
|
||||||
|
InkWell(
|
||||||
|
onTap: (){
|
||||||
|
RouterManager.router.navigateTo(context, '${RouterManager.jobPersonalDetailPath}?studentId=${item.studentId}&studentName=${Uri.encodeComponent(item.studentName)}');
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
height: 20.r,
|
||||||
|
width: 70.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(20.r)),
|
||||||
|
color: Colors.white,
|
||||||
|
border: Border.all(width: 1.r,color: Color(0xFFFCA017))
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text('详情',style: TextStyle(fontSize: 10.sp,color: Color(0xFFFCA017)),),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},itemCount: levelList.length,):MyEmptyWidget(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:fl_chart/fl_chart.dart';
|
import 'package:fl_chart/fl_chart.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_echart/flutter_echart.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:functional_widget_annotation/functional_widget_annotation.dart';
|
import 'package:functional_widget_annotation/functional_widget_annotation.dart';
|
||||||
import 'package:marking_app/common/mixin/common.dart';
|
import 'package:marking_app/common/mixin/common.dart';
|
||||||
|
|
@ -7,9 +8,15 @@ import 'package:marking_app/common/model/common/base_structure_result.dart';
|
||||||
import 'package:marking_app/common/model/job/job_report_join_class.dart';
|
import 'package:marking_app/common/model/job/job_report_join_class.dart';
|
||||||
import 'package:marking_app/common/model/job/job_report_knowledge_model.dart';
|
import 'package:marking_app/common/model/job/job_report_knowledge_model.dart';
|
||||||
import 'package:marking_app/common/model/job/job_report_model.dart';
|
import 'package:marking_app/common/model/job/job_report_model.dart';
|
||||||
|
import 'package:marking_app/components/ReturnToHomepage.dart';
|
||||||
|
import 'package:marking_app/pages/homework_correction/widget/report_table.dart';
|
||||||
|
import 'package:marking_app/pages/homework_correction/widget/top_count.dart';
|
||||||
|
import 'package:marking_app/pages/mainPage.dart';
|
||||||
|
import 'package:marking_app/routes/RouterManager.dart';
|
||||||
import 'package:marking_app/utils/index.dart';
|
import 'package:marking_app/utils/index.dart';
|
||||||
import 'package:marking_app/utils/my_text.dart';
|
import 'package:marking_app/utils/my_text.dart';
|
||||||
import 'package:marking_app/utils/request/rest_client.dart';
|
import 'package:marking_app/utils/request/rest_client.dart';
|
||||||
|
import 'package:marking_app/utils/right_home_icon.dart';
|
||||||
import 'package:percent_indicator/linear_percent_indicator.dart';
|
import 'package:percent_indicator/linear_percent_indicator.dart';
|
||||||
import 'package:photo_view/photo_view.dart';
|
import 'package:photo_view/photo_view.dart';
|
||||||
|
|
||||||
|
|
@ -20,8 +27,12 @@ part 'job_report.g.dart';
|
||||||
/// 作业报告
|
/// 作业报告
|
||||||
class JobReport extends StatefulWidget {
|
class JobReport extends StatefulWidget {
|
||||||
final int id;
|
final int id;
|
||||||
|
final int? schoolId;
|
||||||
|
final int? gradeId;
|
||||||
|
final String? className;
|
||||||
final String title;
|
final String title;
|
||||||
const JobReport({required this.id, required this.title, super.key});
|
|
||||||
|
const JobReport({required this.id, required this.title, this.schoolId, this.gradeId, this.className, super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<JobReport> createState() => _JobReportState();
|
State<JobReport> createState() => _JobReportState();
|
||||||
|
|
@ -48,8 +59,16 @@ class _JobReportState extends State<JobReport> with CommonMixin {
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
toUpState(setState, () {
|
toUpState(setState, () {
|
||||||
involveClasses = [JobReportJoinClass(-1, '全部', -1, '全部', '全部', '全部', -1, -1, '-1'), ...(result.data ?? [])];
|
involveClasses = [JobReportJoinClass(-1, '全部', -1, '全部', '全部', '全部', -1, -1, '-1'), ...(result.data ?? [])];
|
||||||
|
involveClasses?.forEach((element) {
|
||||||
|
if (element.className == widget.className &&
|
||||||
|
element.gradeId == widget.gradeId &&
|
||||||
|
element.schoolId == widget.schoolId) {
|
||||||
|
classData = element;
|
||||||
|
}
|
||||||
|
});
|
||||||
}, mounted);
|
}, mounted);
|
||||||
}
|
}
|
||||||
|
_future = getReport();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
}
|
}
|
||||||
|
|
@ -220,16 +239,26 @@ class _JobReportState extends State<JobReport> with CommonMixin {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
bool isPadFlag = isPad();
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: Color.fromRGBO(245, 245, 245, 1),
|
backgroundColor: Color.fromRGBO(245, 245, 245, 1),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
title: quickText(widget.title, size: 16.sp, color: Color.fromRGBO(51, 51, 51, 1)),
|
centerTitle: true,
|
||||||
|
title: Center(
|
||||||
|
child: quickText(
|
||||||
|
widget.title + '作业报告',
|
||||||
|
size: 14.sp,
|
||||||
|
color: Color.fromRGBO(51, 51, 51, 1),
|
||||||
|
)),
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
icon: Icon(Icons.arrow_back_ios, color: Colors.black),
|
icon: Icon(Icons.arrow_back_ios, color: Colors.black),
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
|
ReturnToHomepage(),
|
||||||
|
],
|
||||||
|
/*actions: [
|
||||||
// 下拉框
|
// 下拉框
|
||||||
$DropdownSelection(involveClasses, classData, call: (JobReportJoinClass _classData) {
|
$DropdownSelection(involveClasses, classData, call: (JobReportJoinClass _classData) {
|
||||||
classData = _classData;
|
classData = _classData;
|
||||||
|
|
@ -237,7 +266,7 @@ class _JobReportState extends State<JobReport> with CommonMixin {
|
||||||
_future = getReport();
|
_future = getReport();
|
||||||
toUpState(setState, () {}, mounted);
|
toUpState(setState, () {}, mounted);
|
||||||
}),
|
}),
|
||||||
],
|
],*/
|
||||||
),
|
),
|
||||||
body: MyFutureBuilder.buildFutureBuilderOfSingleInstance<JobReportModel>(context, _future, (data) {
|
body: MyFutureBuilder.buildFutureBuilderOfSingleInstance<JobReportModel>(context, _future, (data) {
|
||||||
if (data == null)
|
if (data == null)
|
||||||
|
|
@ -252,18 +281,143 @@ class _JobReportState extends State<JobReport> with CommonMixin {
|
||||||
);
|
);
|
||||||
|
|
||||||
return ListView(
|
return ListView(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10.w),
|
padding: EdgeInsets.symmetric(horizontal: 0.w),
|
||||||
children: [
|
children: [
|
||||||
|
// 下拉框
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.h, horizontal: 10.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
$DropdownSelection(involveClasses, classData, call: (JobReportJoinClass _classData) {
|
||||||
|
classData = _classData;
|
||||||
|
if (_classData.gradeId == -1) classData = null;
|
||||||
|
_future = getReport();
|
||||||
|
toUpState(setState, () {}, mounted);
|
||||||
|
}),
|
||||||
|
// Expanded(child: Text('')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
//完成率、正确率
|
||||||
|
TopCount(data,classData == null?'':classData!.className,widget.id),
|
||||||
|
/* InkWell(
|
||||||
|
onTap: (){
|
||||||
|
RouterManager.router.navigateTo(
|
||||||
|
context,
|
||||||
|
RouterManager.quickDataCheckPath +
|
||||||
|
'?jobId=${1}&className=',
|
||||||
|
transition: getTransition(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Text('数据快查'),
|
||||||
|
),*/
|
||||||
|
//客观题
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.r, horizontal: 14.r),
|
||||||
|
margin: EdgeInsets.symmetric(vertical: 10.r, horizontal: 10.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(6.r)),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'客观题',
|
||||||
|
style: TextStyle(fontSize: 14.sp, color: Color(0xFF5C5C5C), fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 10.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'${data.kgReport.correctRate}%',
|
||||||
|
style: TextStyle(fontSize: 14.sp, color: Color(0xFF6888FD), fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 6.r,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: data.kgReport.details.length > 10 ? 300.r : data.kgReport.details.length * 40.r + (isPadFlag == true ?40.r:65.r),
|
||||||
|
child: ReportTable(
|
||||||
|
headList: ['题', '作答率', '作答人数', '正确率', '标准答案', '优先批阅概况'],
|
||||||
|
bodyList: data.kgReport.details,
|
||||||
|
fixedCols: 1,
|
||||||
|
fixedRows: 1,
|
||||||
|
jobId: widget.id,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
//主观题
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.r, horizontal: 14.r),
|
||||||
|
margin: EdgeInsets.symmetric(vertical: 10.r, horizontal: 10.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(6.r)),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'主观题',
|
||||||
|
style: TextStyle(fontSize: 14.sp, color: Color(0xFF5C5C5C), fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 6.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'${data.zgReport.correctRate}%',
|
||||||
|
style: TextStyle(fontSize: 14.sp, color: Color(0xFF6888FD), fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.r,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: data.zgReport.details.length > 10 ? 300.r : data.zgReport.details.length * 40.r +(isPad() == true ?40.r:65.r),
|
||||||
|
child: ReportTable(
|
||||||
|
headList: ['题', '作答率', '作答人数', '正确率', '查看原题', '优先批阅概况'],
|
||||||
|
bodyList: data.zgReport.details,
|
||||||
|
fixedCols: 1,
|
||||||
|
fixedRows: 1,
|
||||||
|
isKG: true,
|
||||||
|
jobId: widget.id,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
// 顶部图形数据
|
// 顶部图形数据
|
||||||
$TopGraphic(data),
|
/* $TopGraphic(data),*/
|
||||||
// 掌握知识点的情况
|
// 掌握知识点的情况
|
||||||
$MasterKnowledgePoint(data.knowledgeInfos, detailKnowledgeCall),
|
Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 10.r),
|
||||||
|
child: $MasterKnowledgePoint(data.knowledgeInfos, detailKnowledgeCall)),
|
||||||
// 掌握知识点的情况
|
// 掌握知识点的情况
|
||||||
$OverallPerformance(data.studentCount, data.overallTitles),
|
/* Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 10.r),
|
||||||
|
child: $OverallPerformance(data.studentCount, data.overallTitles)),
|
||||||
// 单位时间答题情况
|
// 单位时间答题情况
|
||||||
$UnitTimeAnsweringSituation(widget.id, data.questionAnswerInfos),
|
Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 10.r),
|
||||||
|
child: $UnitTimeAnsweringSituation(widget.id, data.questionAnswerInfos)),*/
|
||||||
// 人员数据概况
|
// 人员数据概况
|
||||||
$PersonnelDataOverview(data.studentAnswerInfos),
|
Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 10.r), child: $PersonnelDataOverview(data.studentAnswerInfos)),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
|
@ -276,19 +430,35 @@ class _JobReportState extends State<JobReport> with CommonMixin {
|
||||||
Widget $dropdownSelection(List<JobReportJoinClass>? involveClasses, JobReportJoinClass? classData,
|
Widget $dropdownSelection(List<JobReportJoinClass>? involveClasses, JobReportJoinClass? classData,
|
||||||
{required Function(JobReportJoinClass) call}) {
|
{required Function(JobReportJoinClass) call}) {
|
||||||
if (involveClasses == null) return Container(child: quickText('点击重试')); // 点击重试
|
if (involveClasses == null) return Container(child: quickText('点击重试')); // 点击重试
|
||||||
return DropdownButton(
|
return Container(
|
||||||
|
// width: 200.r,
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFFF5F5F5),
|
||||||
|
borderRadius: BorderRadius.vertical(
|
||||||
|
top: Radius.elliptical(10, 10),
|
||||||
|
bottom: Radius.elliptical(10, 10),
|
||||||
|
)),
|
||||||
|
child: DropdownButton(
|
||||||
value: classData?.uniqueId ?? '-1',
|
value: classData?.uniqueId ?? '-1',
|
||||||
style: TextStyle(color: Color.fromRGBO(89, 89, 89, 1), fontSize: 12.sp),
|
style: TextStyle(color: Color.fromRGBO(89, 89, 89, 1), fontSize: 12.sp),
|
||||||
|
underline: Container(),
|
||||||
|
// isExpanded:true,
|
||||||
items: involveClasses.map((e) {
|
items: involveClasses.map((e) {
|
||||||
return DropdownMenuItem(
|
return DropdownMenuItem(
|
||||||
value: e.uniqueId!,
|
value: e.uniqueId!,
|
||||||
child: quickText(e.graduationYear + e.className, size: 12.sp, color: Colors.black),
|
child: quickText(
|
||||||
|
e.uniqueId == '-1'
|
||||||
|
? e.graduationYear
|
||||||
|
:
|
||||||
|
e.gradeName + e.className, size: 12.sp, color: Colors.black),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
onChanged: (String? value) {
|
onChanged: (String? value) {
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
call(involveClasses.firstWhere((element) => element.uniqueId == value));
|
call(involveClasses.firstWhere((element) => element.uniqueId == value));
|
||||||
},
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -582,11 +752,16 @@ Widget $topGraphic(BuildContext context, JobReportModel data) {
|
||||||
color: Color.fromRGBO(241, 241, 241, 1),
|
color: Color.fromRGBO(241, 241, 241, 1),
|
||||||
),
|
),
|
||||||
child: FlutterWaveLoading(
|
child: FlutterWaveLoading(
|
||||||
width: 140.w, //宽
|
width: 140.w,
|
||||||
height: 170.h, //高
|
//宽
|
||||||
isOval: false, // 是否椭圆裁切
|
height: 170.h,
|
||||||
progress: data.allCorrect / data.studentCount, // 进度
|
//高
|
||||||
waveHeight: 8, //波浪高
|
isOval: false,
|
||||||
|
// 是否椭圆裁切
|
||||||
|
progress: data.allCorrect / data.studentCount,
|
||||||
|
// 进度
|
||||||
|
waveHeight: 8,
|
||||||
|
//波浪高
|
||||||
milliseconds: 5000,
|
milliseconds: 5000,
|
||||||
color: Color.fromRGBO(0, 179, 134, 1), //颜色
|
color: Color.fromRGBO(0, 179, 134, 1), //颜色
|
||||||
),
|
),
|
||||||
|
|
@ -670,11 +845,16 @@ Widget $topGraphic(BuildContext context, JobReportModel data) {
|
||||||
color: Color.fromRGBO(241, 241, 241, 1),
|
color: Color.fromRGBO(241, 241, 241, 1),
|
||||||
),
|
),
|
||||||
child: FlutterWaveLoading(
|
child: FlutterWaveLoading(
|
||||||
width: 140.w, //宽
|
width: 140.w,
|
||||||
height: 170.h, //高
|
//宽
|
||||||
isOval: false, // 是否椭圆裁切
|
height: 170.h,
|
||||||
progress: data.passCount / data.studentCount, // 进度
|
//高
|
||||||
waveHeight: 8, //波浪高
|
isOval: false,
|
||||||
|
// 是否椭圆裁切
|
||||||
|
progress: data.passCount / data.studentCount,
|
||||||
|
// 进度
|
||||||
|
waveHeight: 8,
|
||||||
|
//波浪高
|
||||||
milliseconds: 8000,
|
milliseconds: 8000,
|
||||||
color: Color.fromRGBO(255, 134, 0, 0.84), //颜色
|
color: Color.fromRGBO(255, 134, 0, 0.84), //颜色
|
||||||
),
|
),
|
||||||
|
|
@ -758,11 +938,16 @@ Widget $topGraphic(BuildContext context, JobReportModel data) {
|
||||||
color: Color.fromRGBO(241, 241, 241, 1),
|
color: Color.fromRGBO(241, 241, 241, 1),
|
||||||
),
|
),
|
||||||
child: FlutterWaveLoading(
|
child: FlutterWaveLoading(
|
||||||
width: 140.w, //宽
|
width: 140.w,
|
||||||
height: 170.h, //高
|
//宽
|
||||||
isOval: false, // 是否椭圆裁切
|
height: 170.h,
|
||||||
progress: data.failCount / data.studentCount, // 进度
|
//高
|
||||||
waveHeight: 8, //波浪高
|
isOval: false,
|
||||||
|
// 是否椭圆裁切
|
||||||
|
progress: data.failCount / data.studentCount,
|
||||||
|
// 进度
|
||||||
|
waveHeight: 8,
|
||||||
|
//波浪高
|
||||||
milliseconds: 7000,
|
milliseconds: 7000,
|
||||||
color: Color.fromRGBO(255, 106, 106, 1), //颜色
|
color: Color.fromRGBO(255, 106, 106, 1), //颜色
|
||||||
),
|
),
|
||||||
|
|
@ -846,11 +1031,16 @@ Widget $topGraphic(BuildContext context, JobReportModel data) {
|
||||||
color: Color.fromRGBO(241, 241, 241, 1),
|
color: Color.fromRGBO(241, 241, 241, 1),
|
||||||
),
|
),
|
||||||
child: FlutterWaveLoading(
|
child: FlutterWaveLoading(
|
||||||
width: 140.w, //宽
|
width: 140.w,
|
||||||
height: 170.h, //高
|
//宽
|
||||||
isOval: false, // 是否椭圆裁切
|
height: 170.h,
|
||||||
progress: data.noAnswerCount / data.studentCount, // 进度
|
//高
|
||||||
waveHeight: 8, //波浪高
|
isOval: false,
|
||||||
|
// 是否椭圆裁切
|
||||||
|
progress: data.noAnswerCount / data.studentCount,
|
||||||
|
// 进度
|
||||||
|
waveHeight: 8,
|
||||||
|
//波浪高
|
||||||
milliseconds: 6000,
|
milliseconds: 6000,
|
||||||
color: Color.fromRGBO(96, 96, 96, 1), //颜色
|
color: Color.fromRGBO(96, 96, 96, 1), //颜色
|
||||||
),
|
),
|
||||||
|
|
@ -933,7 +1123,7 @@ Widget $topGraphic(BuildContext context, JobReportModel data) {
|
||||||
Widget $masterKnowledgePoint(BuildContext context, List<KnowledgeInfos> knowledgeInfos,
|
Widget $masterKnowledgePoint(BuildContext context, List<KnowledgeInfos> knowledgeInfos,
|
||||||
Future<void> Function(KnowledgeInfos knowledge) detailCall) {
|
Future<void> Function(KnowledgeInfos knowledge) detailCall) {
|
||||||
Widget childItem(int serialNumber, KnowledgeInfos knowItem) => Container(
|
Widget childItem(int serialNumber, KnowledgeInfos knowItem) => Container(
|
||||||
margin: EdgeInsets.only(bottom: 20.h),
|
margin: EdgeInsets.only(bottom: 15.h, left: 15.r, right: 15.r),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
|
@ -949,7 +1139,7 @@ Widget $masterKnowledgePoint(BuildContext context, List<KnowledgeInfos> knowledg
|
||||||
quickText('${(serialNumber + 1).toString() + '.' + knowItem.knowledgeName}',
|
quickText('${(serialNumber + 1).toString() + '.' + knowItem.knowledgeName}',
|
||||||
size: 12.sp, color: Color.fromRGBO(152, 152, 152, 1)),
|
size: 12.sp, color: Color.fromRGBO(152, 152, 152, 1)),
|
||||||
quickText('${doubleToStringAsFixed(knowItem.rate)}%',
|
quickText('${doubleToStringAsFixed(knowItem.rate)}%',
|
||||||
size: 14.sp, color: Color.fromRGBO(64, 64, 64, 1), fontWeight: FontWeight.bold),
|
size: 12.sp, color: Color.fromRGBO(64, 64, 64, 1)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -957,7 +1147,7 @@ Widget $masterKnowledgePoint(BuildContext context, List<KnowledgeInfos> knowledg
|
||||||
Expanded(flex: 1, child: SizedBox()),
|
Expanded(flex: 1, child: SizedBox()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(height: 6.h),
|
SizedBox(height: 3.h),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -966,13 +1156,14 @@ Widget $masterKnowledgePoint(BuildContext context, List<KnowledgeInfos> knowledg
|
||||||
child: LinearPercentIndicator(
|
child: LinearPercentIndicator(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
animation: true,
|
animation: true,
|
||||||
lineHeight: 15.h,
|
lineHeight: 10.h,
|
||||||
animationDuration: 2500,
|
animationDuration: 2500,
|
||||||
percent: 0.1,
|
percent: 0.1,
|
||||||
center: Text(
|
/* center:
|
||||||
|
Text(
|
||||||
'${doubleToStringAsFixed(knowItem.rate)}%',
|
'${doubleToStringAsFixed(knowItem.rate)}%',
|
||||||
style: TextStyle(color: Colors.white, fontSize: 10.sp),
|
style: TextStyle(color: Colors.white, fontSize: 10.sp),
|
||||||
),
|
),*/
|
||||||
progressColor: Theme.of(context).primaryColor,
|
progressColor: Theme.of(context).primaryColor,
|
||||||
backgroundColor: const Color.fromRGBO(219, 224, 243, 1),
|
backgroundColor: const Color.fromRGBO(219, 224, 243, 1),
|
||||||
barRadius: Radius.circular(10.r),
|
barRadius: Radius.circular(10.r),
|
||||||
|
|
@ -983,7 +1174,7 @@ Widget $masterKnowledgePoint(BuildContext context, List<KnowledgeInfos> knowledg
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
quickText('查看', size: 14.sp, color: Color.fromRGBO(239, 135, 20, 1)),
|
quickText('查看', size: 12.sp, color: Color.fromRGBO(239, 135, 20, 1)),
|
||||||
Icon(Icons.arrow_forward_ios, size: 11.sp, color: Color.fromRGBO(239, 135, 20, 1)),
|
Icon(Icons.arrow_forward_ios, size: 11.sp, color: Color.fromRGBO(239, 135, 20, 1)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -1015,13 +1206,13 @@ Widget $masterKnowledgePoint(BuildContext context, List<KnowledgeInfos> knowledg
|
||||||
/// 整体表现
|
/// 整体表现
|
||||||
@swidget
|
@swidget
|
||||||
Widget $overallPerformance(int totalNumber, List<OverallTitles> overallTitles) {
|
Widget $overallPerformance(int totalNumber, List<OverallTitles> overallTitles) {
|
||||||
Map<String, Color> colorMap = {
|
List colorMap = [
|
||||||
'优秀': Color.fromRGBO(104, 136, 253, 1),
|
Color.fromRGBO(104, 136, 253, 1),
|
||||||
'良好': Color.fromRGBO(255, 186, 33, 1),
|
Color.fromRGBO(255, 186, 33, 1),
|
||||||
'一般': Color.fromRGBO(243, 163, 44, 1),
|
Color.fromRGBO(243, 163, 44, 1),
|
||||||
'较差': Color.fromRGBO(211, 211, 211, 1).withOpacity(0.5),
|
Color.fromRGBO(201, 201, 201, 1),
|
||||||
'很差': Color.fromRGBO(211, 211, 211, 1),
|
Color.fromRGBO(211, 211, 211, 1),
|
||||||
};
|
];
|
||||||
return Container(
|
return Container(
|
||||||
margin: EdgeInsets.only(top: 20.h),
|
margin: EdgeInsets.only(top: 20.h),
|
||||||
padding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 16.w),
|
padding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 16.w),
|
||||||
|
|
@ -1039,22 +1230,52 @@ Widget $overallPerformance(int totalNumber, List<OverallTitles> overallTitles) {
|
||||||
margin: EdgeInsets.only(bottom: 20.h),
|
margin: EdgeInsets.only(bottom: 20.h),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: PieChart(
|
child: PieChatWidget(
|
||||||
|
dataList: overallTitles.asMap().keys.map((index) {
|
||||||
|
var e = overallTitles[index];
|
||||||
|
return EChartPieBean(
|
||||||
|
title: e.title,
|
||||||
|
|
||||||
|
number: e.count,
|
||||||
|
color: colorMap[index]);
|
||||||
|
}).toList(),
|
||||||
|
//是否需要背景
|
||||||
|
isBackground: true,
|
||||||
|
//是否画直线
|
||||||
|
isLineText: true,
|
||||||
|
//背景
|
||||||
|
bgColor: Colors.white,
|
||||||
|
//是否显示最前面的内容
|
||||||
|
isFrontgText: false,
|
||||||
|
//默认选择放大的块
|
||||||
|
initSelect: 1,
|
||||||
|
//初次显示以动画方式展开
|
||||||
|
openType: OpenType.ANI,
|
||||||
|
//旋转类型
|
||||||
|
loopType: LoopType.DOWN_LOOP,
|
||||||
|
//点击回调
|
||||||
|
clickCallBack: (int value) {
|
||||||
|
print("当前点击显示 $value");
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
/* PieChart(
|
||||||
PieChartData(
|
PieChartData(
|
||||||
borderData: FlBorderData(show: false),
|
borderData: FlBorderData(show: false),
|
||||||
sectionsSpace: 2,
|
sectionsSpace: 0,
|
||||||
centerSpaceRadius: 0,
|
centerSpaceRadius: 0,
|
||||||
sections: overallTitles.map((e) {
|
sections: overallTitles.asMap().keys.map((index) {
|
||||||
|
var e = overallTitles[index];
|
||||||
return PieChartSectionData(
|
return PieChartSectionData(
|
||||||
color: colorMap[e.title],
|
color: colorMap[index],
|
||||||
value: e.count / totalNumber * 100,
|
value: e.count / totalNumber * 100,
|
||||||
radius: 110,
|
radius: 110,
|
||||||
title: e.title + (doubleToStringAsFixed(e.count / totalNumber * 100) + '%'),
|
title: e.title + (doubleToStringAsFixed(e.count / totalNumber * 100) + '%'),
|
||||||
titleStyle: TextStyle(fontSize: 14.sp, color: Colors.white, fontWeight: FontWeight.bold),
|
titleStyle: TextStyle(fontSize: 12.sp, color: Color(0xFF999999)),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
),
|
),
|
||||||
),
|
),*/
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -1131,10 +1352,9 @@ Widget $unitTimeAnsweringSituation(BuildContext context, int jobid, List<Questio
|
||||||
|
|
||||||
return false; // 没有找到中文字符
|
return false; // 没有找到中文字符
|
||||||
}
|
}
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: 520.h,
|
// height: isPad() ? 520.h : 460.h,
|
||||||
margin: EdgeInsets.only(top: 20.h),
|
margin: EdgeInsets.only(top: 20.h),
|
||||||
padding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 12.w),
|
padding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 12.w),
|
||||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(10.r)),
|
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(10.r)),
|
||||||
|
|
@ -1145,7 +1365,11 @@ Widget $unitTimeAnsweringSituation(BuildContext context, int jobid, List<Questio
|
||||||
child: quickText('整体表现', color: Color.fromRGBO(92, 92, 92, 1), size: 14.sp, fontWeight: FontWeight.bold),
|
child: quickText('整体表现', color: Color.fromRGBO(92, 92, 92, 1), size: 14.sp, fontWeight: FontWeight.bold),
|
||||||
margin: EdgeInsets.only(bottom: 20.h),
|
margin: EdgeInsets.only(bottom: 20.h),
|
||||||
),
|
),
|
||||||
Expanded(
|
Scrollbar(
|
||||||
|
thickness: 8.w,
|
||||||
|
thumbVisibility: true,
|
||||||
|
trackVisibility: true,
|
||||||
|
radius: Radius.circular(10.r),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|
@ -1310,7 +1534,7 @@ Widget $personnelDataOverview(BuildContext context, List<StudentAnswerInfos> stu
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: 290.h,
|
// height: isPad() ? 290.h : 264.h,
|
||||||
margin: EdgeInsets.only(top: 20.h),
|
margin: EdgeInsets.only(top: 20.h),
|
||||||
padding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 12.w),
|
padding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 12.w),
|
||||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(10.r)),
|
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(10.r)),
|
||||||
|
|
@ -1321,7 +1545,11 @@ Widget $personnelDataOverview(BuildContext context, List<StudentAnswerInfos> stu
|
||||||
child: quickText('人员数据概况', color: Color.fromRGBO(92, 92, 92, 1), size: 14.sp, fontWeight: FontWeight.bold),
|
child: quickText('人员数据概况', color: Color.fromRGBO(92, 92, 92, 1), size: 14.sp, fontWeight: FontWeight.bold),
|
||||||
margin: EdgeInsets.only(bottom: 20.h),
|
margin: EdgeInsets.only(bottom: 20.h),
|
||||||
),
|
),
|
||||||
Expanded(
|
Scrollbar(
|
||||||
|
thickness: 8.w,
|
||||||
|
thumbVisibility: true,
|
||||||
|
trackVisibility: true,
|
||||||
|
radius: Radius.circular(10.r),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|
@ -1398,5 +1626,6 @@ class QuestionPictureModel extends Object {
|
||||||
String questionNo;
|
String questionNo;
|
||||||
int questionid;
|
int questionid;
|
||||||
int jobid;
|
int jobid;
|
||||||
|
|
||||||
QuestionPictureModel({required this.jobid, required this.questionid, required this.questionNo, this.questionPicture});
|
QuestionPictureModel({required this.jobid, required this.questionid, required this.questionNo, this.questionPicture});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,231 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_easyrefresh/easy_refresh.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:marking_app/common/mixin/common.dart';
|
||||||
|
import 'package:marking_app/common/model/common/base_structure_result.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_student_goups.dart';
|
||||||
|
import 'package:marking_app/common/model/user/user_info.dart';
|
||||||
|
import 'package:marking_app/components/ReturnToHomepage.dart';
|
||||||
|
import 'package:marking_app/routes/RouterManager.dart';
|
||||||
|
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
|
||||||
|
import 'package:marking_app/utils/fast_data.dart';
|
||||||
|
import 'package:marking_app/utils/index.dart';
|
||||||
|
import 'package:marking_app/utils/request/rest_client.dart';
|
||||||
|
|
||||||
|
class JobStudentGroup extends StatefulWidget {
|
||||||
|
const JobStudentGroup({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<JobStudentGroup> createState() => _JobStudentGroupState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _JobStudentGroupState extends State<JobStudentGroup> with CommonMixin {
|
||||||
|
late final EasyRefreshController refreshController;
|
||||||
|
late String loginName;
|
||||||
|
List studentGroups = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
refreshController = EasyRefreshController();
|
||||||
|
FastData fastData = FastData.getInstance();
|
||||||
|
fastData.getUser().then((value) {
|
||||||
|
if (value == null || value == '') return;
|
||||||
|
Map<String, dynamic> userInfo = json.decode(value);
|
||||||
|
setState(() {
|
||||||
|
loginName = userInfo['loginName'];
|
||||||
|
});
|
||||||
|
getStudentGroups();
|
||||||
|
print(userInfo);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void getStudentGroups() async {
|
||||||
|
RestClient _client = await getClient();
|
||||||
|
BaseStructureResult<List<JobStudentGroups>> res =
|
||||||
|
await _client.getJobLevelStudentGroups(loginName);
|
||||||
|
setState(() {
|
||||||
|
if(res.code == 200){
|
||||||
|
studentGroups = res.data!;
|
||||||
|
}else{
|
||||||
|
studentGroups = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
refreshController.finishRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
refreshController.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
bool isPadFlag = isPad();
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: Color.fromRGBO(245, 245, 245, 1),
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
title: Text(
|
||||||
|
'我的学生分组',
|
||||||
|
style: TextStyle(fontSize: 16.sp, color: Color(0xFF333333)),
|
||||||
|
),
|
||||||
|
centerTitle: true,
|
||||||
|
leading: IconButton(
|
||||||
|
icon: Icon(Icons.arrow_back_ios, color: Colors.black),
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
ReturnToHomepage(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: Padding(
|
||||||
|
padding: EdgeInsets.only(top: 15.r, left: 14.r, right: 14.r),
|
||||||
|
child: EasyRefresh(
|
||||||
|
firstRefresh: false,
|
||||||
|
taskIndependence: true,
|
||||||
|
controller: refreshController,
|
||||||
|
header: MaterialHeader(),
|
||||||
|
footer: TaurusFooter(),
|
||||||
|
onRefresh: () async{
|
||||||
|
getStudentGroups();
|
||||||
|
},
|
||||||
|
child: studentGroups != null && studentGroups.length > 0
|
||||||
|
? isPadFlag?GridView(
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: 2,
|
||||||
|
mainAxisSpacing: 10.r,
|
||||||
|
crossAxisSpacing: 10.r,
|
||||||
|
childAspectRatio: 556 / 112,
|
||||||
|
),
|
||||||
|
children: List.generate(studentGroups.length, (index) {
|
||||||
|
JobStudentGroups item = studentGroups[index];
|
||||||
|
String classNames = item.classNames.join(" ");
|
||||||
|
return InkWell(
|
||||||
|
onTap: (){
|
||||||
|
RouterManager.router.navigateTo(context, '${RouterManager.jobPriorityReviewSetPath}?&groupId=${item.groupId}',transition: getTransition());
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(10.r)),
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(right: 8.r),
|
||||||
|
child: Text(
|
||||||
|
item.groupName,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.sp, color: Color(0xFF6888FD)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
classNames,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.sp,
|
||||||
|
color: Color(0xFF999999),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.end,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.only(left: 5.r),
|
||||||
|
height: 20.r,
|
||||||
|
width: 55.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.all(Radius.circular(20.r)),
|
||||||
|
color: Color(0xFF6888FD),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'设置',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.sp, color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
):ListView.builder(
|
||||||
|
itemBuilder: (context,index){
|
||||||
|
JobStudentGroups item = studentGroups[index];
|
||||||
|
String classNames = item.classNames.join(" ");
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical:15.r,horizontal: 10.r),
|
||||||
|
margin: EdgeInsets.only(bottom: 10.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(10.r)),
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(right: 8.r),
|
||||||
|
child: Text(
|
||||||
|
item.groupName,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp, color: Color(0xFF6888FD)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
classNames,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF999999),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.end,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: (){
|
||||||
|
RouterManager.router.navigateTo(context, '${RouterManager.jobPriorityReviewSetPath}?&groupId=${item.groupId}',transition: getTransition());
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.only(left: 5.r),
|
||||||
|
height: 24.r,
|
||||||
|
width: 55.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.all(Radius.circular(20.r)),
|
||||||
|
color: Color(0xFF6888FD),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'设置',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.sp, color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: studentGroups.length,
|
||||||
|
)
|
||||||
|
: Padding(
|
||||||
|
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height/2 - 200.r),
|
||||||
|
child: MyEmptyWidget(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,224 @@
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_fav_student.dart';
|
||||||
|
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
|
||||||
|
import 'package:photo_view/photo_view.dart';
|
||||||
|
import 'package:photo_view/photo_view_gallery.dart';
|
||||||
|
|
||||||
|
class FavoriteStudentDialog extends StatefulWidget {
|
||||||
|
final Items item;
|
||||||
|
final List group;
|
||||||
|
final Function deleteFav;
|
||||||
|
final Future<bool> Function() confirmDialog;
|
||||||
|
|
||||||
|
const FavoriteStudentDialog(
|
||||||
|
{Key? key,
|
||||||
|
required this.item,
|
||||||
|
required this.group,
|
||||||
|
required this.deleteFav,
|
||||||
|
required this.confirmDialog})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<FavoriteStudentDialog> createState() => _FavoriteStudentDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FavoriteStudentDialogState extends State<FavoriteStudentDialog> {
|
||||||
|
int defaultIndex = 0;
|
||||||
|
List<Items> imageList = [];
|
||||||
|
late PageController pageController;
|
||||||
|
late Items currentStudent;
|
||||||
|
|
||||||
|
void initState() {
|
||||||
|
currentStudent = widget.item;
|
||||||
|
List<Items> list = [];
|
||||||
|
widget.group.forEach((element) {
|
||||||
|
for (var item in element['list']) {
|
||||||
|
list.add(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setState(() {
|
||||||
|
imageList = list;
|
||||||
|
defaultIndex = list.indexWhere((element) => element.id == widget.item.id);
|
||||||
|
});
|
||||||
|
pageController = PageController(initialPage: defaultIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
pageController.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
height: MediaQuery.of(context).size.height,
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.r, horizontal: 14.r),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'${currentStudent.className} ${currentStudent.studentName}',
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF4E73FD)),
|
||||||
|
),
|
||||||
|
Expanded(child: Container()),
|
||||||
|
Text(
|
||||||
|
'第${currentStudent.questionPage}页',
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF868686)),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () async {
|
||||||
|
bool confim = await widget.confirmDialog();
|
||||||
|
if (confim) {
|
||||||
|
widget.deleteFav(currentStudent);
|
||||||
|
imageList.removeAt(defaultIndex);
|
||||||
|
setState(() {
|
||||||
|
if (imageList.length > 0) {
|
||||||
|
if (defaultIndex < imageList.length) {
|
||||||
|
currentStudent = imageList[defaultIndex];
|
||||||
|
} else {
|
||||||
|
currentStudent = imageList[defaultIndex - 1];
|
||||||
|
defaultIndex = defaultIndex - 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currentStudent.className = '';
|
||||||
|
currentStudent.studentName = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 8.r),
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/favorite_delete_icon.png',
|
||||||
|
width: 22.r,
|
||||||
|
height: 22.r,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/favorite_dialog_close.png',
|
||||||
|
width: 22.r,
|
||||||
|
height: 22.r,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.r,
|
||||||
|
),
|
||||||
|
imageList.length > 0
|
||||||
|
? Expanded(
|
||||||
|
child: Container(
|
||||||
|
color: Colors.white,
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
child: PhotoViewGallery.builder(
|
||||||
|
scrollPhysics: const BouncingScrollPhysics(),
|
||||||
|
builder: (BuildContext context, int index) {
|
||||||
|
final Items item = imageList[index];
|
||||||
|
return PhotoViewGalleryPageOptions(
|
||||||
|
imageProvider: NetworkImage(item.questionPicture!),
|
||||||
|
heroAttributes: PhotoViewHeroAttributes(tag: item.id),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: imageList.length,
|
||||||
|
pageController: pageController,
|
||||||
|
onPageChanged: (index) {
|
||||||
|
setState(() {
|
||||||
|
defaultIndex = index;
|
||||||
|
currentStudent = imageList[index];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
top: MediaQuery.of(context).size.height / 2 - 200.r),
|
||||||
|
child: MyEmptyWidget(),
|
||||||
|
),
|
||||||
|
if (imageList.length > 0)
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 15.r),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if (defaultIndex > 0) {
|
||||||
|
setState(() {
|
||||||
|
defaultIndex = defaultIndex - 1;
|
||||||
|
pageController.jumpToPage(defaultIndex);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width:
|
||||||
|
(MediaQuery.of(context).size.width - 78.r) / 2 - 10.r,
|
||||||
|
height: 28.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(6.r)),
|
||||||
|
border: Border.all(
|
||||||
|
width: 1.r,
|
||||||
|
color: Color(0xFFCACACA),
|
||||||
|
style: BorderStyle.solid),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'上一页',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.r,
|
||||||
|
color: defaultIndex == 0
|
||||||
|
? Color(0xFFCACACA)
|
||||||
|
: Color(0xFF505E6E)),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if (defaultIndex < imageList.length - 1) {
|
||||||
|
setState(() {
|
||||||
|
defaultIndex = defaultIndex + 1;
|
||||||
|
pageController.jumpToPage(defaultIndex);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width:
|
||||||
|
(MediaQuery.of(context).size.width - 78.r) / 2 - 10.r,
|
||||||
|
height: 28.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(6.r)),
|
||||||
|
border: Border.all(
|
||||||
|
width: 1.r,
|
||||||
|
color: Color(0xFFCACACA),
|
||||||
|
style: BorderStyle.solid),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'下一页',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.r,
|
||||||
|
color: defaultIndex == imageList.length - 1
|
||||||
|
? Color(0xFFCACACA)
|
||||||
|
: Color(0xFF505E6E)),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,530 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:functional_widget_annotation/functional_widget_annotation.dart';
|
||||||
|
import 'package:marking_app/common/mixin/common.dart';
|
||||||
|
import 'package:marking_app/common/model/common/base_structure_result.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_fav_student.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_favorite_item_model.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_report_join_class.dart';
|
||||||
|
import 'package:marking_app/components/ReturnToHomepage.dart';
|
||||||
|
import 'package:marking_app/pages/homework_correction/pages/favorite_student_dialog.dart';
|
||||||
|
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
|
||||||
|
import 'package:marking_app/utils/index.dart';
|
||||||
|
import 'package:marking_app/utils/my_text.dart';
|
||||||
|
import 'package:marking_app/utils/request/rest_client.dart';
|
||||||
|
|
||||||
|
part 'job_favorite.g.dart';
|
||||||
|
|
||||||
|
/// 作业收藏学生名单列表
|
||||||
|
class JobFavorite extends StatefulWidget {
|
||||||
|
final int jobId;
|
||||||
|
final int? schoolId;
|
||||||
|
final int? gradeId;
|
||||||
|
final String? className;
|
||||||
|
final String jobName;
|
||||||
|
|
||||||
|
const JobFavorite({
|
||||||
|
required this.jobId,
|
||||||
|
this.schoolId,
|
||||||
|
this.gradeId,
|
||||||
|
this.className,
|
||||||
|
required this.jobName,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<JobFavorite> createState() => _JobFavoriteState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _JobFavoriteState extends State<JobFavorite> with CommonMixin {
|
||||||
|
late Future<List<Items>?> _future;
|
||||||
|
List<JobReportJoinClass>? involveClasses = [];
|
||||||
|
JobReportJoinClass? classData;
|
||||||
|
late String loginName;
|
||||||
|
final int pageSize = 100;
|
||||||
|
String className = '全部';
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
/* FastData fastData = FastData.getInstance();
|
||||||
|
fastData.getUser().then((value) {
|
||||||
|
if (value == null || value == '') return;
|
||||||
|
Map<String, dynamic> userInfo = json.decode(value);
|
||||||
|
setState(() {
|
||||||
|
loginName = userInfo['loginName'];
|
||||||
|
});
|
||||||
|
});*/
|
||||||
|
if (widget.className != null) {
|
||||||
|
className = widget.className!;
|
||||||
|
}
|
||||||
|
|
||||||
|
getInvolveClasses();
|
||||||
|
_future = getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<Items>> getData() async {
|
||||||
|
var _client = await getClient();
|
||||||
|
var result = await _client.getListOfJobFavorites(widget.jobId,
|
||||||
|
widget.jobName, className == '全部' ? '' : className, pageSize);
|
||||||
|
return result.data!.items;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> toGoCancelFavorite(int jobId, int studentId) async {
|
||||||
|
var _client = await getClient();
|
||||||
|
var result = await _client.toJobCancelFavorite(jobId, studentId);
|
||||||
|
if (result.success && (result.data ?? false)) {
|
||||||
|
_future = getData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> getInvolveClasses() async {
|
||||||
|
try {
|
||||||
|
RestClient _client = await getClient();
|
||||||
|
BaseStructureResult<List<JobReportJoinClass>> result =
|
||||||
|
await _client.getJobReportJoinClasses(widget.jobId);
|
||||||
|
if (result.success) {
|
||||||
|
toUpState(setState, () {
|
||||||
|
involveClasses = [
|
||||||
|
JobReportJoinClass(-1, '全部', -1, '全部', '全部', '全部', -1, -1, '-1'),
|
||||||
|
...(result.data ?? [])
|
||||||
|
];
|
||||||
|
involveClasses?.forEach((element) {
|
||||||
|
if (element.className == widget.className &&
|
||||||
|
element.gradeId == widget.gradeId &&
|
||||||
|
element.schoolId == widget.schoolId) {
|
||||||
|
classData = element;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, mounted);
|
||||||
|
}
|
||||||
|
_future = getData();
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> confirmDialog() async {
|
||||||
|
return await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
actionsPadding: EdgeInsets.symmetric(vertical: 10.r, horizontal: 10.r),
|
||||||
|
content: Text(
|
||||||
|
'确定删除吗?',
|
||||||
|
style: TextStyle(fontSize: 14.sp, color: Color(0xFF505E6E)),
|
||||||
|
),
|
||||||
|
actionsAlignment: MainAxisAlignment.center,
|
||||||
|
actions: <Widget>[
|
||||||
|
InkWell(
|
||||||
|
child: Container(
|
||||||
|
width: 97.r,
|
||||||
|
height: 27.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(20.r)),
|
||||||
|
color: Color(0xFF6888FD),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'确定',
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
))),
|
||||||
|
onTap: () {
|
||||||
|
// 执行操作
|
||||||
|
Navigator.of(context).pop(true);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).pop(false);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 97.r,
|
||||||
|
height: 27.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(20.r)),
|
||||||
|
color: Color(0xFFF4F4F4),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'取消',
|
||||||
|
style: TextStyle(color: Color(0xFF666666)),
|
||||||
|
))),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDelete(Items student) async {
|
||||||
|
RestClient _client = await getClient();
|
||||||
|
BaseStructureResult res = await _client.getJobDeFavorites(
|
||||||
|
widget.jobId, student.studentId, student.questionPage!);
|
||||||
|
if (res.success) {
|
||||||
|
_future = getData();
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void showStudentDialog(BuildContext context, Items item, List groups) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
insetPadding: EdgeInsets.all(25.r),
|
||||||
|
content: FavoriteStudentDialog(
|
||||||
|
item: item,
|
||||||
|
group: groups,
|
||||||
|
deleteFav: getDelete,
|
||||||
|
confirmDialog: confirmDialog),
|
||||||
|
contentPadding: EdgeInsets.all(0),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(15.r))));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
bool isPadFlag = isPad();
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: Color.fromRGBO(245, 245, 245, 1),
|
||||||
|
appBar: AppBar(
|
||||||
|
// titleSpacing: 0,
|
||||||
|
elevation: 0.0,
|
||||||
|
leading: IconButton(
|
||||||
|
icon: Icon(Icons.arrow_back_ios),
|
||||||
|
onPressed: () => Navigator.of(context).pop()),
|
||||||
|
iconTheme: IconThemeData(color: Colors.black),
|
||||||
|
title: quickText('收藏夹'),
|
||||||
|
centerTitle: true,
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
actions: [
|
||||||
|
ReturnToHomepage(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: MyFutureBuilder.buildFutureBuilderOfSingleInstance<List<Items>>(
|
||||||
|
context,
|
||||||
|
_future,
|
||||||
|
(List<Items>? datas) {
|
||||||
|
if (datas == null)
|
||||||
|
return Container(
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
toUpState(setState, () => _future = getData(), mounted);
|
||||||
|
},
|
||||||
|
child: Center(
|
||||||
|
child: quickText('请求错误,点击再次发起请求'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
List pageList = [];
|
||||||
|
List groupList = [];
|
||||||
|
if (datas!.length > 0) {
|
||||||
|
for (var item in datas) {
|
||||||
|
pageList.add(item.questionPage);
|
||||||
|
}
|
||||||
|
pageList = pageList.toSet().toList();
|
||||||
|
|
||||||
|
for (var page in pageList) {
|
||||||
|
var printList = datas
|
||||||
|
.where((element) => element.questionPage == page)
|
||||||
|
.toList();
|
||||||
|
groupList.add({"questionPage": page, "list": printList});
|
||||||
|
}
|
||||||
|
groupList
|
||||||
|
.sort((a, b) => a['questionPage'].compareTo(b['questionPage']));
|
||||||
|
}
|
||||||
|
return Container(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 0.r, horizontal: 14.r),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
widget.jobName,
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 14.sp, color: Color(0xFF3C3C3C)),
|
||||||
|
),
|
||||||
|
// 下拉框
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 10.h, horizontal: 10.w),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
$classSelection(involveClasses, classData,
|
||||||
|
call: (JobReportJoinClass _classData) {
|
||||||
|
classData = _classData;
|
||||||
|
if (_classData.gradeId == -1) classData = null;
|
||||||
|
className = _classData.className;
|
||||||
|
_future = getData();
|
||||||
|
toUpState(setState, () {}, mounted);
|
||||||
|
}),
|
||||||
|
// Expanded(child: Text('')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
height: 1.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFFCCCCCC),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
groupList.length > 0
|
||||||
|
? Expanded(
|
||||||
|
child: isPadFlag
|
||||||
|
? Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
top: 10.r,
|
||||||
|
bottom: 8.r,
|
||||||
|
left: 14.r,
|
||||||
|
right: 14.r),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children:
|
||||||
|
List.generate(groupList.length, (index) {
|
||||||
|
var item = groupList[index];
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: 8.r),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding:
|
||||||
|
EdgeInsets.only(bottom: 5.r),
|
||||||
|
child: Text(
|
||||||
|
'第${item['questionPage']}页',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF2E5BFF)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GridView(
|
||||||
|
gridDelegate:
|
||||||
|
SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: 2,
|
||||||
|
mainAxisSpacing: 8.r,
|
||||||
|
crossAxisSpacing: 10.r,
|
||||||
|
childAspectRatio: 556 / 112,
|
||||||
|
),
|
||||||
|
shrinkWrap: true,
|
||||||
|
children: List.generate(
|
||||||
|
item['list'].length, (i) {
|
||||||
|
Items student = item['list'][i];
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 5.r,
|
||||||
|
horizontal: 10.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.all(
|
||||||
|
Radius.circular(
|
||||||
|
6.r)),
|
||||||
|
),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
showStudentDialog(context,
|
||||||
|
student, groupList);
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment
|
||||||
|
.spaceBetween,
|
||||||
|
children: [
|
||||||
|
quickText(
|
||||||
|
student.studentName,
|
||||||
|
color: Color(
|
||||||
|
0xFF333333),
|
||||||
|
size: 12.sp),
|
||||||
|
Expanded(
|
||||||
|
child: Container()),
|
||||||
|
Padding(
|
||||||
|
padding:
|
||||||
|
EdgeInsets.only(
|
||||||
|
right: 8.r),
|
||||||
|
child: Text(
|
||||||
|
student.className,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(
|
||||||
|
0xFF666666)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () async {
|
||||||
|
var confim =
|
||||||
|
await confirmDialog();
|
||||||
|
if (confim) {
|
||||||
|
getDelete(
|
||||||
|
student);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/favorite_delete_icon.png',
|
||||||
|
width: 24.r,
|
||||||
|
height: 24.r,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
})),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
: ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
var item = groupList[index];
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
top: 10.r,
|
||||||
|
bottom: 8.r,
|
||||||
|
left: 14.r,
|
||||||
|
right: 14.r),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: 5.r),
|
||||||
|
child: Text(
|
||||||
|
'第${item['questionPage']}页',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Color(0xFF2E5BFF)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ListView.builder(
|
||||||
|
itemBuilder: (context, i) {
|
||||||
|
Items student = item['list'][i];
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
showStudentDialog(
|
||||||
|
context, student, groupList);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 5.r,
|
||||||
|
horizontal: 10.r),
|
||||||
|
margin: EdgeInsets.only(top: 5.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(6.r)),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment
|
||||||
|
.spaceBetween,
|
||||||
|
children: [
|
||||||
|
quickText(student.studentName,
|
||||||
|
color: Color(0xFF333333),
|
||||||
|
size: 14.sp),
|
||||||
|
Expanded(child: Container()),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
right: 8.r),
|
||||||
|
child: Text(
|
||||||
|
student.className,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Color(
|
||||||
|
0xFF666666)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () async {
|
||||||
|
var confim =
|
||||||
|
await confirmDialog();
|
||||||
|
if (confim) {
|
||||||
|
getDelete(student);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/favorite_delete_icon.png',
|
||||||
|
width: 32.r,
|
||||||
|
height: 32.r,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: item['list'].length,
|
||||||
|
shrinkWrap: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: groupList.length,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
top: MediaQuery.of(context).size.height / 2 - 200.r),
|
||||||
|
child: MyEmptyWidget(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 下拉选择框
|
||||||
|
@swidget
|
||||||
|
Widget $classSelection(
|
||||||
|
List<JobReportJoinClass>? involveClasses, JobReportJoinClass? classData,
|
||||||
|
{required Function(JobReportJoinClass) call}) {
|
||||||
|
if (involveClasses == null)
|
||||||
|
return Container(child: quickText('点击重试')); // 点击重试
|
||||||
|
return Container(
|
||||||
|
// width: 200.r,
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.vertical(
|
||||||
|
top: Radius.elliptical(10, 10),
|
||||||
|
bottom: Radius.elliptical(10, 10),
|
||||||
|
)),
|
||||||
|
child: DropdownButton(
|
||||||
|
value: classData?.uniqueId ?? '-1',
|
||||||
|
|
||||||
|
style: TextStyle(color: Color.fromRGBO(89, 89, 89, 1), fontSize: 12.sp),
|
||||||
|
underline: Container(),
|
||||||
|
// isExpanded:true,
|
||||||
|
items: involveClasses.map((e) {
|
||||||
|
return DropdownMenuItem(
|
||||||
|
value: e.uniqueId!,
|
||||||
|
child: quickText(
|
||||||
|
e.uniqueId == '-1'
|
||||||
|
? e.graduationYear
|
||||||
|
: e.graduationYear + e.className,
|
||||||
|
size: 10.sp,
|
||||||
|
color: Colors.black),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
onChanged: (String? value) {
|
||||||
|
if (value == null) return;
|
||||||
|
call(involveClasses.firstWhere((element) => element.uniqueId == value));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,220 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:marking_app/common/mixin/common.dart';
|
||||||
|
import 'package:marking_app/common/model/common/base_structure_result.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_data_report.dart';
|
||||||
|
import 'package:marking_app/components/ReturnToHomepage.dart';
|
||||||
|
import 'package:marking_app/pages/homework_correction/widget/student_kg_table.dart';
|
||||||
|
import 'package:marking_app/pages/homework_correction/widget/student_zg_table.dart';
|
||||||
|
import 'package:marking_app/routes/RouterManager.dart';
|
||||||
|
import 'package:marking_app/utils/common_utils.dart';
|
||||||
|
import 'package:marking_app/utils/request/rest_client.dart';
|
||||||
|
import 'package:marking_app/utils/toast_utils.dart';
|
||||||
|
|
||||||
|
class QuickCheckPersonal extends StatefulWidget {
|
||||||
|
final int jobId;
|
||||||
|
final int studentId;
|
||||||
|
|
||||||
|
const QuickCheckPersonal(
|
||||||
|
{Key? key, required this.jobId, required this.studentId})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<QuickCheckPersonal> createState() => _QuickCheckPersonalState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _QuickCheckPersonalState extends State<QuickCheckPersonal>
|
||||||
|
with CommonMixin {
|
||||||
|
StudentDetails? studentInfo;
|
||||||
|
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
getJobPersonal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void getJobPersonal() async {
|
||||||
|
RestClient _client = await getClient();
|
||||||
|
Map<String, dynamic> params = {};
|
||||||
|
params['jobid'] = widget.jobId;
|
||||||
|
// params['jobid'] = '521646983660101';
|
||||||
|
params['studentId'] = widget.studentId;
|
||||||
|
BaseStructureResult<StudentDetails?> data =
|
||||||
|
await _client.getJobPersonalReport(params);
|
||||||
|
if(data.data!.studentId != null){
|
||||||
|
setState(() {
|
||||||
|
studentInfo = data.data;
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
Navigator.pop(context);
|
||||||
|
ToastUtils.showError('暂无数据');
|
||||||
|
}
|
||||||
|
EasyLoading.dismiss();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (studentInfo == null) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: Color.fromRGBO(245, 245, 245, 1),
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
title: Text(
|
||||||
|
studentInfo!.studentName!,
|
||||||
|
style: TextStyle(fontSize: 14.sp, color: Color(0xFF000000)),
|
||||||
|
),
|
||||||
|
centerTitle: true,
|
||||||
|
leading: IconButton(
|
||||||
|
icon: Icon(Icons.arrow_back_ios, color: Colors.black),
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
ReturnToHomepage(),
|
||||||
|
/* Title(
|
||||||
|
color: Color(0xFF6888FD),
|
||||||
|
child: Container(
|
||||||
|
child: InkWell(
|
||||||
|
onTap: (){
|
||||||
|
RouterManager.router.navigateTo(context, '${RouterManager.jobPersonalDetailPath}?studentId=${widget.studentId}&studentName=${Uri.encodeComponent(studentInfo!.studentName!)}');
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(right: 16.r),
|
||||||
|
child: Text('历史作业',style: TextStyle(fontSize: 12.sp,color: Color(0xFF6888FD)),),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
),
|
||||||
|
),*/
|
||||||
|
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(top: 14.r,left: 14.r),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: (){
|
||||||
|
RouterManager.router.navigateTo(context, '${RouterManager.jobPersonalDetailPath}?studentId=${widget.studentId}&studentName=${Uri.encodeComponent(studentInfo!.studentName!)}');
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 93.r,
|
||||||
|
height: 28.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFFEAF3FF),
|
||||||
|
borderRadius: BorderRadius.circular(4.r),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text('历史查询',style: TextStyle(fontSize: 10.r,color: Color(0xFF2080F7)),),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 10.r,),
|
||||||
|
Container(
|
||||||
|
width: 93.r,
|
||||||
|
height: 28.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFFEDFFF7),
|
||||||
|
borderRadius: BorderRadius.circular(4.r),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text('查看原稿',style: TextStyle(fontSize: 10.r,color: Color(0xFF4CC793)),),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
//客观题
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 14.r, horizontal: 10.r),
|
||||||
|
margin: EdgeInsets.symmetric(vertical: 14.r, horizontal: 14.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(6.r)),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'客观题',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp, color: Color(0xFF5C5C5C),fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 10.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'${studentInfo!.kgValidRate}%',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp, color: Color(0xFF6888FD),fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 10.r,),
|
||||||
|
SizedBox(
|
||||||
|
height: studentInfo!.kgDetails.length>8?300.r:studentInfo!.kgDetails.length * 40.r + 40.r,
|
||||||
|
child: StudentKgTable(
|
||||||
|
headList: ['题号', '学生答案', '标准答案'],
|
||||||
|
bodyList: studentInfo!.kgDetails,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 15.r,),
|
||||||
|
//主观题
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 14.r, horizontal: 10.r),
|
||||||
|
margin: EdgeInsets.symmetric(vertical: 14.r, horizontal: 14.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(6.r)),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'主观题',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp, color: Color(0xFF5C5C5C),fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 10.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'${studentInfo!.zgValidRate}%',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp, color: Color(0xFF6888FD),fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 10.r,),
|
||||||
|
SizedBox(
|
||||||
|
height: studentInfo!.zgDetails.length>8?300.r:studentInfo!.zgDetails.length * 40.r + 40.r,
|
||||||
|
child: StudentZgTable(
|
||||||
|
headList: ['题号', '用时', '学生答案','批注结果','批注'],
|
||||||
|
bodyList: studentInfo!.zgDetails,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,472 @@
|
||||||
|
import 'package:fl_chart/fl_chart.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:marking_app/common/mixin/common.dart';
|
||||||
|
import 'package:marking_app/common/model/common/base_structure_result.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_data_report.dart';
|
||||||
|
import 'package:marking_app/components/ReturnToHomepage.dart';
|
||||||
|
import 'package:marking_app/pages/homework_correction/widget/quick_data_check_bottom.dart';
|
||||||
|
import 'package:marking_app/pages/homework_correction/widget/quick_student_data_table.dart';
|
||||||
|
import 'package:marking_app/pages/homework_correction/widget/report_table.dart';
|
||||||
|
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
|
||||||
|
import 'package:marking_app/utils/index.dart';
|
||||||
|
import 'package:marking_app/utils/request/rest_client.dart';
|
||||||
|
import 'package:marking_app/utils/right_home_icon.dart';
|
||||||
|
import 'package:percent_indicator/linear_percent_indicator.dart';
|
||||||
|
|
||||||
|
class QuickDataCheckPage extends StatefulWidget {
|
||||||
|
final int jobId;
|
||||||
|
final String className;
|
||||||
|
final String gradeName;
|
||||||
|
final int? schoolId;
|
||||||
|
final int? gradeId;
|
||||||
|
|
||||||
|
const QuickDataCheckPage(
|
||||||
|
{Key? key,
|
||||||
|
required this.jobId,
|
||||||
|
required this.className,
|
||||||
|
required this.gradeName,
|
||||||
|
this.schoolId,
|
||||||
|
this.gradeId})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<QuickDataCheckPage> createState() => _QuickDataCheckPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _QuickDataCheckPageState extends State<QuickDataCheckPage>
|
||||||
|
with CommonMixin {
|
||||||
|
JobDataReport? jobData;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
EasyLoading.show(status: 'loading...');
|
||||||
|
getJobDataReport();
|
||||||
|
}
|
||||||
|
|
||||||
|
void getJobDataReport() async {
|
||||||
|
RestClient _client = await getClient();
|
||||||
|
Map<String, dynamic> params = {};
|
||||||
|
params['jobid'] = widget.jobId;
|
||||||
|
params['className'] = widget.className;
|
||||||
|
if (widget.schoolId != null) {
|
||||||
|
params['schoolId'] = widget.schoolId;
|
||||||
|
}
|
||||||
|
if (widget.gradeId != null) {
|
||||||
|
params['gradeId'] = widget.gradeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseStructureResult<JobDataReport?> data =
|
||||||
|
await _client.getJobDataCenterReport(params);
|
||||||
|
EasyLoading.dismiss();
|
||||||
|
if (data.code == 200) {
|
||||||
|
int totalUnrated = 0;
|
||||||
|
|
||||||
|
data.data!.studentDetails.forEach((element) {
|
||||||
|
element.kgError = 0;
|
||||||
|
element.kgCorrect = 0;
|
||||||
|
element.zgError = 0;
|
||||||
|
element.zgCorrect = 0;
|
||||||
|
int num = 0;
|
||||||
|
element.kgDetails.forEach((item) {
|
||||||
|
if (item.state == 0) {
|
||||||
|
num = num + 1;
|
||||||
|
}else if (item.state == 1) {
|
||||||
|
element.kgError = element.kgError + 1;
|
||||||
|
}else if (item.state == 2) {
|
||||||
|
element.kgCorrect = element.kgCorrect + 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
element.zgDetails.forEach((item) {
|
||||||
|
if (item.state == 0) {
|
||||||
|
num = num + 1;
|
||||||
|
}else if (item.state == 1) {
|
||||||
|
element.zgError = element.zgError + 1;
|
||||||
|
}else if (item.state == 2) {
|
||||||
|
element.zgCorrect = element.zgCorrect + 1;
|
||||||
|
}else if (item.state == 3) {
|
||||||
|
element.unrated = element.unrated + 1;
|
||||||
|
totalUnrated = element.unrated;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(num == (element.kgDetails.length+ element.zgDetails.length)){
|
||||||
|
element.allNotDone = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (totalUnrated > 0) {
|
||||||
|
data.data!.hasUnrated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
jobData = data.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AnnotatedRegion(
|
||||||
|
value: const SystemUiOverlayStyle(
|
||||||
|
statusBarColor: Colors.transparent,
|
||||||
|
systemNavigationBarIconBrightness: Brightness.light,
|
||||||
|
statusBarIconBrightness: Brightness.light,
|
||||||
|
statusBarBrightness: Brightness.dark,
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
|
||||||
|
height: MediaQuery.of(context).size.height,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment.topCenter,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
colors: [
|
||||||
|
Color(0xFF6889FD),
|
||||||
|
Color(0xFFF5F5F5),
|
||||||
|
],
|
||||||
|
stops: [
|
||||||
|
0.09,
|
||||||
|
0.3
|
||||||
|
])),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(Icons.arrow_back_ios, color: Colors.white),
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(right: 8.r),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'数据快查',
|
||||||
|
style: TextStyle(fontSize: 14.sp, color: Colors.white),
|
||||||
|
)),
|
||||||
|
)),
|
||||||
|
ReturnToHomepage(bgColor: Colors.white,),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 10.r),
|
||||||
|
jobData != null
|
||||||
|
? Expanded(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 14.r, top: 2.r),
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
'assets/images/job_report_class_icon.png',
|
||||||
|
width: 22.r,
|
||||||
|
height: 22.r,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 6.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
widget.gradeName + widget.className,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.r, color: Colors.white),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 15.r, horizontal: 15.r),
|
||||||
|
margin: EdgeInsets.symmetric(
|
||||||
|
vertical: 10.r, horizontal: 14.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.all(Radius.circular(6.r))),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 2.r,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 12.r,
|
||||||
|
height: 12.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFF4CC793),
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(7.r))),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 6.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'已提交',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF333333)),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 35.r,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 12.r,
|
||||||
|
height: 12.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFF6888FD),
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(7.r))),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 6.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'未提交',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF333333)),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 2.r,
|
||||||
|
),
|
||||||
|
//环形图
|
||||||
|
SizedBox(
|
||||||
|
height: MediaQuery.of(context).size.width * 0.3,
|
||||||
|
child: PieChart(
|
||||||
|
PieChartData(
|
||||||
|
borderData: FlBorderData(show: false),
|
||||||
|
sectionsSpace: 0,
|
||||||
|
centerSpaceRadius:
|
||||||
|
MediaQuery.of(context).size.width * 0.06,
|
||||||
|
sections: [
|
||||||
|
PieChartSectionData(
|
||||||
|
color: Color(0xFF4CC793),
|
||||||
|
value: jobData!.validCount /
|
||||||
|
(jobData!.validCount +
|
||||||
|
jobData!.noAnswerCount) *
|
||||||
|
100,
|
||||||
|
radius:
|
||||||
|
MediaQuery.of(context).size.width *
|
||||||
|
0.07 +
|
||||||
|
5,
|
||||||
|
title: '${jobData!.validCount}人',
|
||||||
|
titleStyle: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PieChartSectionData(
|
||||||
|
color: Color(0xFF6888FD),
|
||||||
|
value: jobData!.noAnswerCount /
|
||||||
|
(jobData!.validCount +
|
||||||
|
jobData!.noAnswerCount) *
|
||||||
|
100,
|
||||||
|
radius:
|
||||||
|
MediaQuery.of(context).size.width *
|
||||||
|
0.07,
|
||||||
|
title: '${jobData!.noAnswerCount}人',
|
||||||
|
titleStyle: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// 客观进度条
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'客观题答题进度',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.sp,
|
||||||
|
color: Color(0xFF8B8B8B)),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'${doubleToStringAsFixed(jobData!.kgValidRate)}%',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.sp,
|
||||||
|
color: Color(0xFF333333)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 6.r),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 10,
|
||||||
|
child: LinearPercentIndicator(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
animation: true,
|
||||||
|
lineHeight: 9.h,
|
||||||
|
animationDuration: 2500,
|
||||||
|
percent: jobData!.kgValidRate / 100,
|
||||||
|
progressColor: Color(0xFFFF7F22),
|
||||||
|
backgroundColor: Color(0xFFEAEAEA),
|
||||||
|
barRadius: Radius.circular(10.r),
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 20.r),
|
||||||
|
// 主观进度条
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'主观题答题进度',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.sp,
|
||||||
|
color: Color(0xFF8B8B8B)),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'${doubleToStringAsFixed(jobData!.zgValidRate)}%',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.sp,
|
||||||
|
color: Color(0xFF333333)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 6.r),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 10,
|
||||||
|
child: LinearPercentIndicator(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
animation: true,
|
||||||
|
lineHeight: 9.h,
|
||||||
|
animationDuration: 2500,
|
||||||
|
percent: jobData!.zgValidRate / 100,
|
||||||
|
progressColor: Color(0xFFFF7F22),
|
||||||
|
backgroundColor: Color(0xFFEAEAEA),
|
||||||
|
barRadius: Radius.circular(10.r),
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
QuickDataCheckBottom(jobData:jobData,jobId: widget.jobId,),
|
||||||
|
//客观题
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.r, horizontal: 10.r),
|
||||||
|
margin: EdgeInsets.symmetric(vertical: 10.r, horizontal: 14.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(6.r)),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'客观题',
|
||||||
|
style: TextStyle(fontSize: 14.sp, color: Color(0xFF5C5C5C), fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 10.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'${jobData!.kgReport.correctRate}%',
|
||||||
|
style: TextStyle(fontSize: 14.sp, color: Color(0xFF6888FD), fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 6.r,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: jobData!.kgReport.details.length > 10 ? 300.r : jobData!.kgReport.details.length * 40.r + (isPad() == true ?40.r:65.r),
|
||||||
|
child: ReportTable(
|
||||||
|
headList: ['题', '作答率', '作答人数', '正确率', '标准答案', '优先批阅概况'],
|
||||||
|
bodyList: jobData!.kgReport.details,
|
||||||
|
fixedCols: 1,
|
||||||
|
fixedRows: 1,
|
||||||
|
jobId: widget.jobId,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
//主观题
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.r, horizontal: 14.r),
|
||||||
|
margin: EdgeInsets.symmetric(vertical: 10.r, horizontal: 10.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(6.r)),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'主观题',
|
||||||
|
style: TextStyle(fontSize: 14.sp, color: Color(0xFF5C5C5C), fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 6.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'${jobData!.zgReport.correctRate}%',
|
||||||
|
style: TextStyle(fontSize: 14.sp, color: Color(0xFF6888FD), fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.r,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: jobData!.zgReport.details.length > 10 ? 300.r : jobData!.zgReport.details.length * 40.r +(isPad() == true ?40.r:65.r),
|
||||||
|
child: ReportTable(
|
||||||
|
headList: ['题', '作答率', '作答人数', '正确率', '查看原题', '优先批阅概况'],
|
||||||
|
bodyList: jobData!.zgReport.details,
|
||||||
|
fixedCols: 1,
|
||||||
|
fixedRows: 1,
|
||||||
|
isKG: true,
|
||||||
|
jobId: widget.jobId,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
))
|
||||||
|
: Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
top: MediaQuery.of(context).size.height / 2 - 200.r),
|
||||||
|
child: MyEmptyWidget(),
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
|
||||||
|
class PersonalDetailTopBar extends StatefulWidget {
|
||||||
|
final TabController controller;
|
||||||
|
final ValueChanged<int>? onTap;
|
||||||
|
final String customTimeStr;
|
||||||
|
const PersonalDetailTopBar({Key? key,required this.controller, this.onTap, required this.customTimeStr}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<PersonalDetailTopBar> createState() => _PersonalDetailTopBarState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PersonalDetailTopBarState extends State<PersonalDetailTopBar> {
|
||||||
|
@override
|
||||||
|
void initState(){
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border(bottom: BorderSide(width: 1.r,color: Color(0xFFCCCCCC)))
|
||||||
|
),
|
||||||
|
child: TabBar(
|
||||||
|
controller: widget.controller,
|
||||||
|
unselectedLabelStyle: TextStyle(fontSize: 12.sp, color: const Color.fromRGBO(102, 102, 102, 1)),
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Color.fromRGBO(116, 145, 253, 1),
|
||||||
|
),
|
||||||
|
isScrollable: true,
|
||||||
|
labelColor: Color(0xFF6888FD),
|
||||||
|
unselectedLabelColor: Color(0xFF666666),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 14.r),
|
||||||
|
// indicatorSize: TabBarIndicatorSize.label, // 设置指示器高度和标签一样高
|
||||||
|
onTap: widget.onTap,
|
||||||
|
tabs: <Widget>[
|
||||||
|
const Tab(text: '全部'),
|
||||||
|
const Tab(text: '近一周'),
|
||||||
|
const Tab(text: '近一月'),
|
||||||
|
Tab(text: widget.customTimeStr),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,266 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_data_report.dart';
|
||||||
|
import 'package:marking_app/pages/homework_correction/widget/quick_student_data_table.dart';
|
||||||
|
|
||||||
|
class QuickDataCheckBottom extends StatefulWidget {
|
||||||
|
final int jobId;
|
||||||
|
final JobDataReport? jobData;
|
||||||
|
const QuickDataCheckBottom({Key? key,required this.jobId,required this.jobData}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<QuickDataCheckBottom> createState() => _QuickDataCheckBottomState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _QuickDataCheckBottomState extends State<QuickDataCheckBottom> {
|
||||||
|
List<StudentDetails> showList = [];
|
||||||
|
List<StudentDetails> followList = [];
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
showList =widget.jobData!.studentDetails;
|
||||||
|
widget.jobData!.studentDetails.forEach((e) {
|
||||||
|
if(e.readLevel == 1){
|
||||||
|
followList.add(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 10.r, horizontal: 10.r),
|
||||||
|
margin: EdgeInsets.symmetric(
|
||||||
|
vertical: 10.r, horizontal: 14.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.all(Radius.circular(6.r))),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: (){
|
||||||
|
if (widget.jobData == null) return;
|
||||||
|
if (!widget.jobData!.sortType) {
|
||||||
|
widget.jobData!.studentDetails.sort((a, b) {
|
||||||
|
int num1 =
|
||||||
|
a.kgValidRate + a.zgValidRate;
|
||||||
|
int num2 =
|
||||||
|
b.kgValidRate + b.zgValidRate;
|
||||||
|
return num2.compareTo(num1);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
widget.jobData!.studentDetails.sort((a, b) {
|
||||||
|
int num1 =
|
||||||
|
a.kgValidRate + a.zgValidRate;
|
||||||
|
int num2 =
|
||||||
|
b.kgValidRate + b.zgValidRate;
|
||||||
|
return num1.compareTo(num2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
widget.jobData!.sortType = !widget.jobData!.sortType;
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
widget.jobData!.sortLevel = false;
|
||||||
|
showList = widget.jobData!.studentDetails;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
if(!widget.jobData!.sortType)
|
||||||
|
Image.asset(
|
||||||
|
'assets/images/no_check_icon.png',
|
||||||
|
width: 16.r,
|
||||||
|
height: 16.r,
|
||||||
|
),
|
||||||
|
if(widget.jobData!.sortType)
|
||||||
|
Image.asset(
|
||||||
|
'assets/images/check_icon.png',
|
||||||
|
width: 16.r,
|
||||||
|
height: 16.r,
|
||||||
|
),
|
||||||
|
SizedBox(width: 5.r,),
|
||||||
|
Text(
|
||||||
|
widget.jobData!.sortType?'已提交排序':'未提交排序',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF707070)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(
|
||||||
|
width: 20.r,
|
||||||
|
),
|
||||||
|
|
||||||
|
InkWell(
|
||||||
|
onTap: (){
|
||||||
|
if (widget.jobData == null) return;
|
||||||
|
if (!widget.jobData!.sortLevel) {
|
||||||
|
showList = followList;
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
widget.jobData!.studentDetails.sort((a, b) {
|
||||||
|
int num1 =
|
||||||
|
a.kgValidRate + a.zgValidRate;
|
||||||
|
int num2 =
|
||||||
|
b.kgValidRate + b.zgValidRate;
|
||||||
|
return num1.compareTo(num2);
|
||||||
|
});
|
||||||
|
showList = widget.jobData!.studentDetails;
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
widget.jobData!.sortLevel =
|
||||||
|
!widget.jobData!.sortLevel;
|
||||||
|
setState(() {
|
||||||
|
widget.jobData!.sortType = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
if(!widget.jobData!.sortLevel)
|
||||||
|
Image.asset(
|
||||||
|
'assets/images/no_check_icon.png',
|
||||||
|
width: 16.r,
|
||||||
|
height: 16.r,
|
||||||
|
),
|
||||||
|
if(widget.jobData!.sortLevel)
|
||||||
|
Image.asset(
|
||||||
|
'assets/images/check_icon.png',
|
||||||
|
width: 16.r,
|
||||||
|
height: 16.r,
|
||||||
|
),
|
||||||
|
SizedBox(width: 5.r,),
|
||||||
|
Text(
|
||||||
|
'看关注学生',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF707070)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.r,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'注:',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 8.sp, color: Color(0xFF717171)),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width:10.r,
|
||||||
|
height: 10.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(5.r)),
|
||||||
|
color: Color(0xFF4CC793),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 2.r,),
|
||||||
|
Text(
|
||||||
|
'正确',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 8.sp, color: Color(0xFF717171)),
|
||||||
|
),
|
||||||
|
SizedBox(width: 15.r,),
|
||||||
|
Container(
|
||||||
|
width:10.r,
|
||||||
|
height: 10.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(5.r)),
|
||||||
|
color: Color(0xFFFF7474),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 2.r,),
|
||||||
|
Text(
|
||||||
|
'错误',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 8.sp, color: Color(0xFF717171)),
|
||||||
|
),
|
||||||
|
SizedBox(width: 15.r,),
|
||||||
|
Container(
|
||||||
|
width:10.r,
|
||||||
|
height: 10.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(5.r)),
|
||||||
|
color: Colors.white,
|
||||||
|
// border: Border.all(width: 1.r,color: Colors.grey),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey,
|
||||||
|
offset: Offset(1.w, 1.h), //阴影y轴偏移量
|
||||||
|
blurRadius: 4, //阴影模糊程度
|
||||||
|
spreadRadius: 0.1, //阴影扩散程度
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 2.r,),
|
||||||
|
Text(
|
||||||
|
'已作答未批阅',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 8.sp, color: Color(0xFF717171)),
|
||||||
|
),
|
||||||
|
SizedBox(width: 15.r,),
|
||||||
|
Container(
|
||||||
|
width:10.r,
|
||||||
|
height: 10.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(5.r)),
|
||||||
|
color: Color(0xFFD3D3D3),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 2.r,),
|
||||||
|
Text(
|
||||||
|
'未做',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 8.sp, color: Color(0xFF717171)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 5.r,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: showList.length > 5
|
||||||
|
? 350.r
|
||||||
|
: showList.length * 50.r +
|
||||||
|
40.r,
|
||||||
|
child: QuickStudentDataTable(
|
||||||
|
headList: [
|
||||||
|
'学生姓名',
|
||||||
|
'客观题',
|
||||||
|
'主观题',
|
||||||
|
'客观题状态',
|
||||||
|
'主观题状态',
|
||||||
|
'未批阅'
|
||||||
|
],
|
||||||
|
bodyList: showList,
|
||||||
|
jobId: widget.jobId,
|
||||||
|
fixedRows: 1,
|
||||||
|
fixedCols: 0,
|
||||||
|
// hasUnrated: widget.jobData!.hasUnrated,
|
||||||
|
hasUnrated: false,
|
||||||
|
kgCount: widget.jobData!.kgQuestionCount,
|
||||||
|
zgCount: widget.jobData!.zgQuestionCount,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,287 @@
|
||||||
|
import 'package:data_table_2/data_table_2.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_data_report.dart';
|
||||||
|
import 'package:marking_app/routes/RouterManager.dart';
|
||||||
|
import 'package:marking_app/utils/index.dart';
|
||||||
|
|
||||||
|
class QuickStudentDataTable extends StatefulWidget {
|
||||||
|
final List headList;
|
||||||
|
final List bodyList;
|
||||||
|
final int? fixedRows;
|
||||||
|
final int? fixedCols;
|
||||||
|
final int jobId;
|
||||||
|
final bool hasUnrated;
|
||||||
|
final int kgCount;
|
||||||
|
final int zgCount;
|
||||||
|
|
||||||
|
const QuickStudentDataTable({
|
||||||
|
Key? key,
|
||||||
|
required this.headList,
|
||||||
|
required this.bodyList,
|
||||||
|
required this.jobId,
|
||||||
|
required this.hasUnrated,
|
||||||
|
required this.kgCount,
|
||||||
|
required this.zgCount,
|
||||||
|
this.fixedCols = 0,
|
||||||
|
this.fixedRows = 0,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<QuickStudentDataTable> createState() => _QuickStudentDataTableState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _QuickStudentDataTableState extends State<QuickStudentDataTable> {
|
||||||
|
final ScrollController _controller = ScrollController();
|
||||||
|
int? _sortColumnIndex;
|
||||||
|
bool _sortAscending = true;
|
||||||
|
|
||||||
|
DataRow _getRow(int index, [Color? color]) {
|
||||||
|
assert(index >= 0);
|
||||||
|
StudentDetails item = widget.bodyList[index];
|
||||||
|
/* int num = 0;
|
||||||
|
int total = 0;
|
||||||
|
item.kgDetails.forEach((element) {
|
||||||
|
if (element.state == 0) {
|
||||||
|
num = num + 1;
|
||||||
|
}
|
||||||
|
total = total + 1;
|
||||||
|
});
|
||||||
|
item.zgDetails.forEach((element) {
|
||||||
|
if (element.state == 0) {
|
||||||
|
num = num + 1;
|
||||||
|
}
|
||||||
|
total = total + 1;
|
||||||
|
});*/
|
||||||
|
return DataRow2.byIndex(
|
||||||
|
index: index,
|
||||||
|
color: color != null
|
||||||
|
? item.allNotDone
|
||||||
|
? MaterialStateProperty.all(Color(0xFFFFD79C))
|
||||||
|
: MaterialStateProperty.all(color)
|
||||||
|
: null,
|
||||||
|
cells: [
|
||||||
|
DataCell(InkWell(
|
||||||
|
onTap: () {
|
||||||
|
RouterManager.router.navigateTo(
|
||||||
|
context,
|
||||||
|
RouterManager.quickCheckPersonalPath +
|
||||||
|
'?jobId=${widget.jobId}&studentId=${item.studentId}',
|
||||||
|
transition: getTransition(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(item.studentName!,
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))),
|
||||||
|
SizedBox(
|
||||||
|
width: 5.r,
|
||||||
|
),
|
||||||
|
Image.asset(
|
||||||
|
'assets/images/job_data_right_icon.png',
|
||||||
|
width: 10.r,
|
||||||
|
height: 10.r,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
DataCell(Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'${item.kgCorrect}',
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF4CC793))),
|
||||||
|
Text(
|
||||||
|
'/',
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))),
|
||||||
|
Text(
|
||||||
|
'${item.kgError}',
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFFFF7474))),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
DataCell(Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'${item.zgCorrect}',
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF4CC793))),
|
||||||
|
Text(
|
||||||
|
'/',
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))),
|
||||||
|
Text(
|
||||||
|
'${item.zgError}',
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFFFF7474))),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
DataCell(
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 2.r, horizontal: 5.r),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Wrap(
|
||||||
|
direction: Axis.horizontal,
|
||||||
|
alignment: WrapAlignment.start,
|
||||||
|
spacing: 2,
|
||||||
|
runSpacing: 2,
|
||||||
|
children: List.generate(item.kgDetails.length, (index) {
|
||||||
|
KgDetails kgInfo = item.kgDetails[index];
|
||||||
|
return Container(
|
||||||
|
width: 14.r,
|
||||||
|
height: 14.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: kgInfo.state == 0
|
||||||
|
? Color(0xFFD3D3D3)
|
||||||
|
: kgInfo.state == 3?Colors.white:kgInfo.state == 1
|
||||||
|
? Color(0xFFFF7474)
|
||||||
|
: Color(0xFF4CC793),
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(7.r))),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
kgInfo.questionNo,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.sp,
|
||||||
|
color: kgInfo.state == 3
|
||||||
|
? Color(0xFF525252)
|
||||||
|
: Colors.white),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
DataCell(
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 2.r, horizontal: 5.r),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Wrap(
|
||||||
|
direction: Axis.horizontal,
|
||||||
|
alignment: WrapAlignment.start,
|
||||||
|
spacing: 2,
|
||||||
|
runSpacing: 2,
|
||||||
|
children: List.generate(item.zgDetails.length, (index) {
|
||||||
|
KgDetails kgInfo = item.zgDetails[index];
|
||||||
|
return Container(
|
||||||
|
width: 14.r,
|
||||||
|
height: 14.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: kgInfo.state == 0
|
||||||
|
? Color(0xFFD3D3D3)
|
||||||
|
: kgInfo.state == 3?Colors.white:kgInfo.state == 1
|
||||||
|
? Color(0xFFFF7474)
|
||||||
|
: Color(0xFF4CC793),
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(7.r))),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
kgInfo.questionNo,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.sp,
|
||||||
|
color: kgInfo.state == 3
|
||||||
|
? Color(0xFF525252)
|
||||||
|
: Colors.white),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if(widget.hasUnrated)
|
||||||
|
DataCell(Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: Text('${item.unrated}',
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if(!widget.hasUnrated){
|
||||||
|
widget.headList.removeLast();
|
||||||
|
}
|
||||||
|
return DataTable2(
|
||||||
|
dividerThickness: 0,
|
||||||
|
scrollController: _controller,
|
||||||
|
columnSpacing: 0,
|
||||||
|
horizontalMargin: 0,
|
||||||
|
bottomMargin: 0,
|
||||||
|
dataRowHeight: 50.r,
|
||||||
|
border: TableBorder(
|
||||||
|
horizontalInside: BorderSide(
|
||||||
|
width: 1, color: Colors.white, style: BorderStyle.solid),
|
||||||
|
bottom: BorderSide(
|
||||||
|
width: 1, color: Colors.white, style: BorderStyle.solid),
|
||||||
|
verticalInside: BorderSide(
|
||||||
|
width: 1, color: Colors.white, style: BorderStyle.solid)),
|
||||||
|
headingRowColor: MaterialStateProperty.resolveWith((states) =>
|
||||||
|
widget.fixedCols! > 0 ? Colors.white : Colors.transparent),
|
||||||
|
headingRowDecoration: BoxDecoration(color: Color(0xFFE6E6E6)),
|
||||||
|
fixedColumnsColor: Color(0xFFE6E6E6),
|
||||||
|
fixedCornerColor: Colors.grey[400],
|
||||||
|
minWidth: MediaQuery.of(context).size.width,
|
||||||
|
fixedTopRows: widget.fixedRows!,
|
||||||
|
fixedLeftColumns: widget.fixedCols!,
|
||||||
|
sortColumnIndex: _sortColumnIndex,
|
||||||
|
sortAscending: _sortAscending,
|
||||||
|
// onSelectAll: (val) => setState(() => selectAll(val)),
|
||||||
|
columns: List.generate(widget.headList.length, (index) {
|
||||||
|
var item = widget.headList[index];
|
||||||
|
return index == 1?DataColumn2(
|
||||||
|
label: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(item,
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF505767))),
|
||||||
|
Text('(${widget.kgCount})',
|
||||||
|
style: TextStyle(fontSize: 10.sp, color: Color(0xFF505767))),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
// size: ColumnSize.S,
|
||||||
|
fixedWidth: (MediaQuery.of(context).size.width - 20.r - 28.r) / widget.headList.length,
|
||||||
|
):index == 2?DataColumn2(
|
||||||
|
label: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(item,
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF505767))),
|
||||||
|
Text('(${widget.zgCount})',
|
||||||
|
style: TextStyle(fontSize: 10.sp, color: Color(0xFF505767))),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
// size: ColumnSize.S,
|
||||||
|
fixedWidth: (MediaQuery.of(context).size.width - 20.r - 28.r) / widget.headList.length,
|
||||||
|
):DataColumn2(
|
||||||
|
label: Center(
|
||||||
|
child: Text(item,
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF505767))),
|
||||||
|
),
|
||||||
|
// size: ColumnSize.S,
|
||||||
|
fixedWidth: (MediaQuery.of(context).size.width - 20.r - 28.r) / widget.headList.length,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
rows: List<DataRow>.generate(widget.bodyList.length,
|
||||||
|
(index) => _getRow(index, Color(0xFFF5F5F5))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,481 @@
|
||||||
|
import 'package:data_table_2/data_table_2.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_report_model.dart';
|
||||||
|
import 'package:marking_app/routes/RouterManager.dart';
|
||||||
|
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
|
||||||
|
import 'package:marking_app/utils/index.dart';
|
||||||
|
import 'package:marking_app/utils/toast_utils.dart';
|
||||||
|
import 'package:photo_view/photo_view.dart';
|
||||||
|
|
||||||
|
class ReportTable extends StatefulWidget {
|
||||||
|
final List headList;
|
||||||
|
final List bodyList;
|
||||||
|
final int? fixedRows;
|
||||||
|
final int? fixedCols;
|
||||||
|
final bool? isKG;
|
||||||
|
final int jobId;
|
||||||
|
|
||||||
|
const ReportTable({
|
||||||
|
Key? key,
|
||||||
|
required this.headList,
|
||||||
|
required this.bodyList,
|
||||||
|
required this.jobId,
|
||||||
|
this.fixedCols = 0,
|
||||||
|
this.fixedRows = 0,
|
||||||
|
this.isKG = false,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ReportTable> createState() => _ReportTableState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ReportTableState extends State<ReportTable> {
|
||||||
|
final ScrollController _controller = ScrollController();
|
||||||
|
int? _sortColumnIndex;
|
||||||
|
bool _sortAscending = true;
|
||||||
|
|
||||||
|
void showPeopleListDialog(
|
||||||
|
{required BuildContext context,
|
||||||
|
required String title,
|
||||||
|
required String questionNo,
|
||||||
|
required List arr,
|
||||||
|
List? dcList}) {
|
||||||
|
print(dcList);
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
// insetPadding: EdgeInsets.symmetric(vertical: 20.r,horizontal: 20.r),
|
||||||
|
contentPadding: EdgeInsets.all(20.r),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(15.r))),
|
||||||
|
content: SizedBox(
|
||||||
|
width: MediaQuery.of(context).size.width * 0.7,
|
||||||
|
height: MediaQuery.of(context).size.height * 0.7,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Text(
|
||||||
|
title,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 15.sp,
|
||||||
|
color: Color(0xFF3C3C3C),
|
||||||
|
fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 5.r,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
widget.isKG == true ? '主观题' : '客观题',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp, color: Color(0xFF436CFF)),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'―',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp, color: Color(0xFF436CFF)),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'第$questionNo题',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp, color: Color(0xFF436CFF)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 15.r,
|
||||||
|
),
|
||||||
|
dcList != null
|
||||||
|
? Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'未作答人',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF6A6A6A)),
|
||||||
|
))),
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'答对人数',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF6A6A6A)),
|
||||||
|
))),
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'答错人',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF6A6A6A)),
|
||||||
|
))),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: Padding(
|
||||||
|
padding: EdgeInsets.only(left: 15.r),
|
||||||
|
child: Text(
|
||||||
|
title,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp, color: Color(0xFF6A6A6A)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 5.r,
|
||||||
|
),
|
||||||
|
if (dcList != null)
|
||||||
|
Expanded(
|
||||||
|
child: ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
var item = arr[index];
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 5.r),
|
||||||
|
color:
|
||||||
|
index.isOdd ? Colors.white : Color(0xFFF0F0F0),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
goQuickCheckPersonalPath(
|
||||||
|
item['noAnswerStudents'].id);
|
||||||
|
},
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
item['noAnswerStudents'].name,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF323232)),
|
||||||
|
)))),
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
goQuickCheckPersonalPath(
|
||||||
|
item['answerOkStudents'].id);
|
||||||
|
},
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
item['answerOkStudents'].name,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF323232)),
|
||||||
|
)))),
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
goQuickCheckPersonalPath(
|
||||||
|
item['answerNgStudents'].id);
|
||||||
|
},
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
item['answerNgStudents'].name,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF323232)),
|
||||||
|
)))),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: arr.length,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
arr.length > 0
|
||||||
|
? Expanded(
|
||||||
|
child: ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
AnswerOkStudents item = arr[index];
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
goQuickCheckPersonalPath(item.id);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 5.r, horizontal: 15.r),
|
||||||
|
color: index.isOdd
|
||||||
|
? Colors.white
|
||||||
|
: Color(0xFFF0F0F0),
|
||||||
|
child: Text(
|
||||||
|
item.name,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF323232)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: arr.length,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: MyEmptyWidget()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void goQuickCheckPersonalPath(id) {
|
||||||
|
if (id != -1) {
|
||||||
|
RouterManager.router.navigateTo(
|
||||||
|
context,
|
||||||
|
RouterManager.quickCheckPersonalPath +
|
||||||
|
'?jobId=${widget.jobId}&studentId=$id',
|
||||||
|
transition: getTransition(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void zdHandle(BuildContext context, String title, String questionNo,
|
||||||
|
List noAnswerStudents, List answerNgStudents, List answerOkStudents) {
|
||||||
|
List list = [];
|
||||||
|
AnswerOkStudents student = AnswerOkStudents(-1, '-');
|
||||||
|
if (noAnswerStudents.length > answerNgStudents.length &&
|
||||||
|
noAnswerStudents.length > answerOkStudents.length) {
|
||||||
|
for (int i = 0; i < noAnswerStudents.length; i++) {
|
||||||
|
var obj = {
|
||||||
|
'noAnswerStudents': noAnswerStudents[i],
|
||||||
|
'answerNgStudents':
|
||||||
|
answerNgStudents.length > i ? answerNgStudents[i] : student,
|
||||||
|
'answerOkStudents':
|
||||||
|
answerOkStudents.length > i ? answerOkStudents[i] : student
|
||||||
|
};
|
||||||
|
list.add(obj);
|
||||||
|
}
|
||||||
|
} else if (answerNgStudents.length > noAnswerStudents.length &&
|
||||||
|
answerNgStudents.length > answerOkStudents.length) {
|
||||||
|
for (int i = 0; i < answerNgStudents.length; i++) {
|
||||||
|
var obj = {
|
||||||
|
'noAnswerStudents':
|
||||||
|
noAnswerStudents.length > i ? noAnswerStudents[i] : student,
|
||||||
|
'answerNgStudents': answerNgStudents[i],
|
||||||
|
'answerOkStudents':
|
||||||
|
answerOkStudents.length > i ? answerOkStudents[i] : student
|
||||||
|
};
|
||||||
|
list.add(obj);
|
||||||
|
}
|
||||||
|
} else if (answerOkStudents.length > noAnswerStudents.length &&
|
||||||
|
answerOkStudents.length > answerNgStudents.length) {
|
||||||
|
for (int i = 0; i < answerOkStudents.length; i++) {
|
||||||
|
var obj = {
|
||||||
|
'noAnswerStudents':
|
||||||
|
noAnswerStudents.length > i ? noAnswerStudents[i] : student,
|
||||||
|
'answerNgStudents':
|
||||||
|
answerNgStudents.length > i ? answerNgStudents[i] : student,
|
||||||
|
'answerOkStudents': answerOkStudents[i]
|
||||||
|
};
|
||||||
|
list.add(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showPeopleListDialog(
|
||||||
|
context: context,
|
||||||
|
title: title,
|
||||||
|
questionNo: questionNo,
|
||||||
|
arr: list,
|
||||||
|
dcList: []);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dcHandle(
|
||||||
|
BuildContext context, String title, String questionNo, List arr) {
|
||||||
|
showPeopleListDialog(
|
||||||
|
context: context, title: title, questionNo: questionNo, arr: arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataRow _getRow(int index, [Color? color]) {
|
||||||
|
assert(index >= 0);
|
||||||
|
var item = widget.bodyList[index];
|
||||||
|
return DataRow2.byIndex(
|
||||||
|
index: index,
|
||||||
|
color: color != null ? MaterialStateProperty.all(color) : null,
|
||||||
|
cells: [
|
||||||
|
DataCell(Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: Text(item.questionNo,
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
DataCell(Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: Text('${item.validRate}%',
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
DataCell(InkWell(
|
||||||
|
onTap: () {
|
||||||
|
zdHandle(context, '作答人数', item.questionNo, item.noAnswerStudents,
|
||||||
|
item.answerNgStudents, item.answerOkStudents);
|
||||||
|
},
|
||||||
|
child: Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(item.validCount,
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 12.sp, color: Color(0xFF4CC793))),
|
||||||
|
Image.asset(
|
||||||
|
'assets/images/green_right_icon.png',
|
||||||
|
width: 12.r,
|
||||||
|
height: 12.r,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
DataCell(Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: Text('${item.correctRate}%',
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
DataCell(Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: widget.isKG == true
|
||||||
|
? InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if (item.questionPicture == null)
|
||||||
|
return ToastUtils.showInfo('当前试题没有原题');
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (_) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(),
|
||||||
|
body: PhotoView(
|
||||||
|
imageProvider:
|
||||||
|
NetworkImage(item.questionPicture!)),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Text('原题',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: widget.isKG == true
|
||||||
|
? Color(0xFFFF8A00)
|
||||||
|
: Color(0xFF4CC793))),
|
||||||
|
)
|
||||||
|
: Text(item.questionAnswer,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: widget.isKG == true
|
||||||
|
? Color(0xFFFF8A00)
|
||||||
|
: Color(0xFF4CC793))),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
DataCell(InkWell(
|
||||||
|
onTap: () {
|
||||||
|
List<String> parts = item.priorityGeneral.split('人');
|
||||||
|
dcHandle(context, '${parts[1]}人', item.questionNo,
|
||||||
|
item.priorityStudents);
|
||||||
|
},
|
||||||
|
child: Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(item.priorityGeneral,
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))),
|
||||||
|
Image.asset(
|
||||||
|
'assets/images/job_data_right_icon.png',
|
||||||
|
width: 10.r,
|
||||||
|
height: 10.r,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
bool isPadFlag = isPad();
|
||||||
|
return DataTable2(
|
||||||
|
dividerThickness: 0,
|
||||||
|
scrollController: _controller,
|
||||||
|
columnSpacing: 0,
|
||||||
|
horizontalMargin: 0,
|
||||||
|
dataRowHeight: 40.r,
|
||||||
|
bottomMargin: 0,
|
||||||
|
border: TableBorder(
|
||||||
|
horizontalInside: BorderSide(
|
||||||
|
width: 1, color: Colors.white, style: BorderStyle.solid),
|
||||||
|
bottom: BorderSide(
|
||||||
|
width: 1, color: Colors.white, style: BorderStyle.solid),
|
||||||
|
verticalInside: BorderSide(
|
||||||
|
width: 1, color: Colors.white, style: BorderStyle.solid)),
|
||||||
|
headingRowColor: MaterialStateProperty.resolveWith((states) =>
|
||||||
|
widget.fixedCols! > 0 ? Colors.white : Colors.transparent),
|
||||||
|
/* headingRowDecoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
Colors.grey[400]!,
|
||||||
|
Colors.grey[200]!,
|
||||||
|
],
|
||||||
|
begin: Alignment.topCenter,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
),
|
||||||
|
),*/
|
||||||
|
headingRowDecoration: BoxDecoration(color: Color(0xFFE6E6E6)),
|
||||||
|
fixedColumnsColor: Color(0xFFE6E6E6),
|
||||||
|
fixedCornerColor: Colors.grey[400],
|
||||||
|
minWidth: widget.headList.length > 6
|
||||||
|
? 80.r * widget.headList.length
|
||||||
|
: isPadFlag
|
||||||
|
? MediaQuery.of(context).size.width
|
||||||
|
: 85.r * widget.headList.length,
|
||||||
|
fixedTopRows: widget.fixedRows!,
|
||||||
|
fixedLeftColumns: widget.fixedCols!,
|
||||||
|
sortColumnIndex: _sortColumnIndex,
|
||||||
|
sortAscending: _sortAscending,
|
||||||
|
// onSelectAll: (val) => setState(() => selectAll(val)),
|
||||||
|
columns: List.generate(widget.headList.length, (index) {
|
||||||
|
var item = widget.headList[index];
|
||||||
|
return DataColumn2(
|
||||||
|
label: Center(
|
||||||
|
child: Text(item,
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF505767))),
|
||||||
|
),
|
||||||
|
// size: ColumnSize.S,
|
||||||
|
fixedWidth: index == 0
|
||||||
|
? 40.r
|
||||||
|
: widget.headList.length > 6
|
||||||
|
? 80.r
|
||||||
|
: isPadFlag
|
||||||
|
? (MediaQuery.of(context).size.width - 8.r) /
|
||||||
|
widget.headList.length
|
||||||
|
: 85.r,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
rows: List<DataRow>.generate(widget.bodyList.length,
|
||||||
|
(index) => _getRow(index, Color(0xFFF5F5F5))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
import 'package:data_table_2/data_table_2.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_data_report.dart';
|
||||||
|
|
||||||
|
class StudentKgTable extends StatefulWidget {
|
||||||
|
final List headList;
|
||||||
|
final List bodyList;
|
||||||
|
final int? fixedRows;
|
||||||
|
final int? fixedCols;
|
||||||
|
|
||||||
|
const StudentKgTable({
|
||||||
|
Key? key,
|
||||||
|
required this.headList,
|
||||||
|
required this.bodyList,
|
||||||
|
this.fixedCols = 0,
|
||||||
|
this.fixedRows = 0,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StudentKgTable> createState() => _StudentKgTableState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _StudentKgTableState extends State<StudentKgTable> {
|
||||||
|
final ScrollController _controller = ScrollController();
|
||||||
|
int? _sortColumnIndex;
|
||||||
|
bool _sortAscending = true;
|
||||||
|
|
||||||
|
String sortString(String str) {
|
||||||
|
return String.fromCharCodes(str.codeUnits.toList()..sort());
|
||||||
|
}
|
||||||
|
DataRow _getRow(int index, [Color? color]) {
|
||||||
|
assert(index >= 0);
|
||||||
|
KgDetails item = widget.bodyList[index];
|
||||||
|
return DataRow2.byIndex(
|
||||||
|
index: index,
|
||||||
|
color: color != null ? MaterialStateProperty.all(color): null,
|
||||||
|
cells: [
|
||||||
|
DataCell(Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: Text(item.questionNo,
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
DataCell(Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: Text(item.studentAnswer == null?'未作答':item.studentAnswer!,
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: item.studentAnswer == null?Color(0xFF525252):
|
||||||
|
item.state == 2?Color(0xFF4CC793):
|
||||||
|
item.state == 1?Color(0xFFFF7474):item.state == 0?Color(0xFFD3D3D3):Colors.white),
|
||||||
|
),
|
||||||
|
))),
|
||||||
|
DataCell(Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: Text(item.questionAnswer == null ?'无':item.questionAnswer!,
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DataTable2(
|
||||||
|
dividerThickness: 0,
|
||||||
|
scrollController: _controller,
|
||||||
|
columnSpacing: 0,
|
||||||
|
horizontalMargin: 0,
|
||||||
|
bottomMargin: 0,
|
||||||
|
dataRowHeight: 40.r,
|
||||||
|
headingRowHeight: 40.r,
|
||||||
|
border: TableBorder(
|
||||||
|
horizontalInside: BorderSide(
|
||||||
|
width: 1, color: Colors.white, style: BorderStyle.solid),
|
||||||
|
bottom: BorderSide(
|
||||||
|
width: 1, color: Colors.white, style: BorderStyle.solid),
|
||||||
|
verticalInside: BorderSide(
|
||||||
|
width: 1, color: Colors.white, style: BorderStyle.solid)),
|
||||||
|
headingRowColor: MaterialStateProperty.resolveWith((states) =>
|
||||||
|
widget.fixedCols! > 0 ? Colors.white : Colors.transparent),
|
||||||
|
headingRowDecoration: BoxDecoration(color: Color(0xFFE6E6E6)),
|
||||||
|
fixedColumnsColor: Color(0xFFE6E6E6),
|
||||||
|
fixedCornerColor: Colors.grey[400],
|
||||||
|
minWidth: MediaQuery.of(context).size.width,
|
||||||
|
fixedTopRows: widget.fixedRows!,
|
||||||
|
fixedLeftColumns: widget.fixedCols!,
|
||||||
|
sortColumnIndex: _sortColumnIndex,
|
||||||
|
sortAscending: _sortAscending,
|
||||||
|
// onSelectAll: (val) => setState(() => selectAll(val)),
|
||||||
|
columns: List.generate(widget.headList.length, (index) {
|
||||||
|
var item = widget.headList[index];
|
||||||
|
return DataColumn2(
|
||||||
|
label: Center(
|
||||||
|
child: Text(item,
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF505767))),
|
||||||
|
),
|
||||||
|
// size: ColumnSize.S,
|
||||||
|
fixedWidth: (MediaQuery.of(context).size.width - 20.r - 28.r)/3,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
rows: List<DataRow>.generate(widget.bodyList.length,
|
||||||
|
(index) => _getRow(index, Color(0xFFF5F5F5))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,172 @@
|
||||||
|
import 'package:data_table_2/data_table_2.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_data_report.dart';
|
||||||
|
import 'package:marking_app/utils/common_utils.dart';
|
||||||
|
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
|
||||||
|
import 'package:photo_view/photo_view.dart';
|
||||||
|
|
||||||
|
class StudentZgTable extends StatefulWidget {
|
||||||
|
final List headList;
|
||||||
|
final List bodyList;
|
||||||
|
final int? fixedRows;
|
||||||
|
final int? fixedCols;
|
||||||
|
|
||||||
|
const StudentZgTable({
|
||||||
|
Key? key,
|
||||||
|
required this.headList,
|
||||||
|
required this.bodyList,
|
||||||
|
this.fixedCols = 0,
|
||||||
|
this.fixedRows = 0,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StudentZgTable> createState() => _StudentZgTableState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _StudentZgTableState extends State<StudentZgTable> {
|
||||||
|
final ScrollController _controller = ScrollController();
|
||||||
|
int? _sortColumnIndex;
|
||||||
|
bool _sortAscending = true;
|
||||||
|
|
||||||
|
void showImgDialog(BuildContext context,String imgUrl){
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (_) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(),
|
||||||
|
body: SizedBox(
|
||||||
|
/* width: MediaQuery.of(context).size.width * 0.6,
|
||||||
|
height: MediaQuery.of(context).size.height * 0.6,*/
|
||||||
|
child: PhotoView(
|
||||||
|
imageProvider:
|
||||||
|
NetworkImage(imgUrl)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
/* showDialog(context: context, builder: (BuildContext context){
|
||||||
|
return AlertDialog(
|
||||||
|
// insetPadding: EdgeInsets.symmetric(vertical: 20.r,horizontal: 20.r),
|
||||||
|
backgroundColor:Colors.transparent,
|
||||||
|
contentPadding: EdgeInsets.all(20.r),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(15.r))),
|
||||||
|
content: Container(
|
||||||
|
color: Colors.transparent,
|
||||||
|
width: MediaQuery.of(context).size.width * 0.6,
|
||||||
|
height: MediaQuery.of(context).size.height * 0.6,
|
||||||
|
child: PhotoView(
|
||||||
|
imageProvider:
|
||||||
|
NetworkImage(imgUrl)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});*/
|
||||||
|
}
|
||||||
|
|
||||||
|
DataRow _getRow(int index, [Color? color]) {
|
||||||
|
assert(index >= 0);
|
||||||
|
KgDetails item = widget.bodyList[index];
|
||||||
|
return DataRow2.byIndex(
|
||||||
|
index: index,
|
||||||
|
color: color != null ? MaterialStateProperty.all(color): null,
|
||||||
|
cells: [
|
||||||
|
DataCell(Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: Text(item.questionNo,
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF6888FD))),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
DataCell(Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: Text(CommonUtils.second2HMS(item.useTime!),
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
DataCell(InkWell(
|
||||||
|
onTap: (){
|
||||||
|
if(item.state != 0){
|
||||||
|
showImgDialog(context,item.studentAnswer!);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
child: Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: Text(item.state!=0 ?'查看':'--',
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF3661FE))),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
DataCell(Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: item.state == 2?
|
||||||
|
Image.asset('assets/images/job_personal_correct_icon.png',width: 18.r,height: 18.r,):item.state == 1?
|
||||||
|
Image.asset('assets/images/job_personal_error_icon.png',width: 10.r,height: 10.r,):Text('', style: TextStyle(fontSize: 12.sp, color: Color(0xFF525252))),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
DataCell(InkWell(
|
||||||
|
onTap: (){
|
||||||
|
if(item.state==1 || item.state==2){
|
||||||
|
showImgDialog(context,item.annotateAnswers!);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
child: Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 5.r),
|
||||||
|
child: Text(item.state==1 || item.state==2?'查看':'--',
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF3661FE))),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DataTable2(
|
||||||
|
dividerThickness: 0,
|
||||||
|
scrollController: _controller,
|
||||||
|
columnSpacing: 0,
|
||||||
|
horizontalMargin: 0,
|
||||||
|
bottomMargin: 0,
|
||||||
|
headingRowHeight: 40.r,
|
||||||
|
dataRowHeight: 40.r,
|
||||||
|
border: TableBorder(
|
||||||
|
horizontalInside: BorderSide(
|
||||||
|
width: 1, color: Colors.white, style: BorderStyle.solid),
|
||||||
|
bottom: BorderSide(
|
||||||
|
width: 1, color: Colors.white, style: BorderStyle.solid),
|
||||||
|
verticalInside: BorderSide(
|
||||||
|
width: 1, color: Colors.white, style: BorderStyle.solid)),
|
||||||
|
headingRowColor: MaterialStateProperty.resolveWith((states) =>
|
||||||
|
widget.fixedCols! > 0 ? Colors.white : Colors.transparent),
|
||||||
|
headingRowDecoration: BoxDecoration(color: Color(0xFFE6E6E6)),
|
||||||
|
fixedColumnsColor: Color(0xFFE6E6E6),
|
||||||
|
fixedCornerColor: Colors.grey[400],
|
||||||
|
minWidth: MediaQuery.of(context).size.width,
|
||||||
|
fixedTopRows: widget.fixedRows!,
|
||||||
|
fixedLeftColumns: widget.fixedCols!,
|
||||||
|
sortColumnIndex: _sortColumnIndex,
|
||||||
|
sortAscending: _sortAscending,
|
||||||
|
// onSelectAll: (val) => setState(() => selectAll(val)),
|
||||||
|
columns: List.generate(widget.headList.length, (index) {
|
||||||
|
var item = widget.headList[index];
|
||||||
|
return DataColumn2(
|
||||||
|
label: Center(
|
||||||
|
child: Text(item,
|
||||||
|
style: TextStyle(fontSize: 12.sp, color: Color(0xFF505767))),
|
||||||
|
),
|
||||||
|
// size: ColumnSize.S,
|
||||||
|
fixedWidth: (MediaQuery.of(context).size.width - 20.r - 28.r)/5,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
rows: List<DataRow>.generate(widget.bodyList.length,
|
||||||
|
(index) => _getRow(index, Color(0xFFF5F5F5))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,550 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:functional_widget_annotation/functional_widget_annotation.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_report_model.dart';
|
||||||
|
import 'package:marking_app/routes/RouterManager.dart';
|
||||||
|
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
|
||||||
|
import 'package:marking_app/utils/index.dart';
|
||||||
|
|
||||||
|
class TopCount extends StatelessWidget {
|
||||||
|
final JobReportModel data;
|
||||||
|
final String className;
|
||||||
|
final int jobId;
|
||||||
|
|
||||||
|
const TopCount(this.data, this.className, this.jobId,{Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
void showStudentListDialog(
|
||||||
|
{required BuildContext context,
|
||||||
|
required String title,
|
||||||
|
required List arr}) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
// insetPadding: EdgeInsets.symmetric(vertical: 20.r,horizontal: 20.r),
|
||||||
|
contentPadding: EdgeInsets.all(20.r),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(15.r))),
|
||||||
|
content: SizedBox(
|
||||||
|
width: MediaQuery.of(context).size.width * 0.7,
|
||||||
|
height: MediaQuery.of(context).size.height * 0.7,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Text(
|
||||||
|
className + title,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 15.sp,
|
||||||
|
color: Color(0xFF3C3C3C),
|
||||||
|
fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 5.r,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 15.r,
|
||||||
|
),
|
||||||
|
arr.length > 0
|
||||||
|
? Expanded(
|
||||||
|
child: ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
AnswerOkStudents item = arr[index];
|
||||||
|
return InkWell(
|
||||||
|
onTap: (){
|
||||||
|
RouterManager.router.navigateTo(
|
||||||
|
context,
|
||||||
|
RouterManager.quickCheckPersonalPath +
|
||||||
|
'?jobId=$jobId&studentId=${item.id}',
|
||||||
|
transition: getTransition(),);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 5.r, horizontal: 15.r),
|
||||||
|
color: index.isOdd
|
||||||
|
? Colors.white
|
||||||
|
: Color(0xFFF0F0F0),
|
||||||
|
child: Text(
|
||||||
|
item.name,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFF323232)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: arr.length,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: MyEmptyWidget()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
double leftWidth = (MediaQuery.of(context).size.width-40.r) * 0.7/3;
|
||||||
|
double rightWidth = (MediaQuery.of(context).size.width-40.r) * 0.3/2;
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.r, horizontal: 10.r),
|
||||||
|
margin: EdgeInsets.symmetric(vertical: 10.r, horizontal: 10.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(6.r)),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
showStudentListDialog(
|
||||||
|
context: context,
|
||||||
|
title: '未提交作业学生',
|
||||||
|
arr: data.noAnswerStudents!);
|
||||||
|
},
|
||||||
|
child:leftContainer(context,count: data.noAnswerCount,name: '未提交',nameColor: Color(0xFFD92F2F),bgColor: Color(0xFFEEEEEE)),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
showStudentListDialog(
|
||||||
|
context: context,
|
||||||
|
title: '已提交作业学生',
|
||||||
|
arr: data.validStudents!);
|
||||||
|
},
|
||||||
|
child: leftContainer(context,count: data.validCount,name: '已提交',nameColor: Color(0xFF4CC793),bgColor: Color(0xFFF5F5F5)),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
showStudentListDialog(
|
||||||
|
context: context,
|
||||||
|
title: '全对作业学生',
|
||||||
|
arr: data.allCorrectStudents!);
|
||||||
|
},
|
||||||
|
child:leftContainer(context,count: data.allCorrect,name: '全对',nameColor: Color(0xFFFF9800),bgColor: Color(0xFFEEEEEE)),
|
||||||
|
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
height: 92.r,
|
||||||
|
width: rightWidth,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: InkWell(
|
||||||
|
onTap: (){
|
||||||
|
showStudentListDialog(
|
||||||
|
context: context,
|
||||||
|
title: '优等作业学生',
|
||||||
|
arr: data.overallInfos['优']!.students);
|
||||||
|
},
|
||||||
|
child: rightContainer(count: data.overallInfos['优']!.count,bgColor: Color(0xFF56FFB8),nameColor: Color(0xFF009254),name: '优',),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: InkWell(
|
||||||
|
onTap: (){
|
||||||
|
showStudentListDialog(
|
||||||
|
context: context,
|
||||||
|
title: '中等作业学生',
|
||||||
|
arr: data.overallInfos['中']!.students);
|
||||||
|
},
|
||||||
|
child: rightContainer(count: data.overallInfos['中']!.count,bgColor: Color(0xFFD3FF93),nameColor: Color(0xFF3F6605),name: '中'),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
height: 92.r,
|
||||||
|
width:rightWidth,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: InkWell(
|
||||||
|
onTap: (){
|
||||||
|
showStudentListDialog(
|
||||||
|
context: context,
|
||||||
|
title: '良等作业学生',
|
||||||
|
arr: data.overallInfos['良']!.students);
|
||||||
|
},
|
||||||
|
child: rightContainer(count: data.overallInfos['良']!.count,bgColor: Color(0xFFFFC38C),nameColor: Color(0xFFD36500),name: '良' ),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: InkWell(
|
||||||
|
onTap: (){
|
||||||
|
showStudentListDialog(
|
||||||
|
context: context,
|
||||||
|
title: '差等作业学生',
|
||||||
|
arr: data.overallInfos['差']!.students);
|
||||||
|
},
|
||||||
|
child: rightContainer(count: data.overallInfos['差']!.count,bgColor: Color(0xFFFF9D94),nameColor: Color(0xFFD12616),name: '差' ),
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
/* Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
showStudentListDialog(
|
||||||
|
context: context,
|
||||||
|
title: '未提交作业学生',
|
||||||
|
arr: data.noAnswerStudentNames);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 81.r,
|
||||||
|
padding:
|
||||||
|
EdgeInsets.symmetric(vertical: 10.r, horizontal: 6.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
width: 1.r,
|
||||||
|
color: Color(0xFF4CC793),
|
||||||
|
style: BorderStyle.solid),
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(6.r)),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 5.r,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
data.noAnswerCount.toString(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 24.sp,
|
||||||
|
color: Color(0xFF4CC793),
|
||||||
|
fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'人',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Color(0xFF4CC793),
|
||||||
|
fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 20.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'未提交',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp, color: Color(0xFF818181)),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
showStudentListDialog(
|
||||||
|
context: context,
|
||||||
|
title: '已提交作业学生',
|
||||||
|
arr: data.validStudentNames);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 81.r,
|
||||||
|
padding:
|
||||||
|
EdgeInsets.symmetric(vertical: 10.r, horizontal: 6.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
width: 1.r,
|
||||||
|
color: Color(0xFF4CC793),
|
||||||
|
style: BorderStyle.solid),
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(6.r)),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 5.r,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
data.validCount.toString(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 24.sp,
|
||||||
|
color: Color(0xFF4CC793),
|
||||||
|
fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'人',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Color(0xFF4CC793),
|
||||||
|
fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 20.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'已提交',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp, color: Color(0xFF818181)),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
showStudentListDialog(
|
||||||
|
context: context,
|
||||||
|
title: '全对作业学生',
|
||||||
|
arr: data.allCorrectStudentNames);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 81.r,
|
||||||
|
padding:
|
||||||
|
EdgeInsets.symmetric(vertical: 10.r, horizontal: 6.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
width: 1.r,
|
||||||
|
color: Color(0xFF4CC793),
|
||||||
|
style: BorderStyle.solid),
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(6.r)),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 5.r,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
data.allCorrect.toString(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 24.sp,
|
||||||
|
color: Color(0xFF4CC793),
|
||||||
|
fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'人',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Color(0xFF4CC793),
|
||||||
|
fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 20.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'全对',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp, color: Color(0xFF818181)),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 15.r,
|
||||||
|
),*/
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 15.r),
|
||||||
|
child: GridView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
childAspectRatio: 150 / 46,
|
||||||
|
crossAxisSpacing: 2.r, //水平子 Widget 之间间距
|
||||||
|
mainAxisSpacing: 2.r, //垂直子 Widget 之间间距
|
||||||
|
crossAxisCount: 2, //一行的 Widget 数量
|
||||||
|
),
|
||||||
|
itemCount: data.overallTitles.length,
|
||||||
|
itemBuilder: (BuildContext context, index) {
|
||||||
|
var item = data.overallTitles[index];
|
||||||
|
Color bgColor = Color(0xFF4CC793);
|
||||||
|
if (item.title == '优') {
|
||||||
|
bgColor = Color(0xFF4CC793);
|
||||||
|
} else if (item.title == '良') {
|
||||||
|
bgColor = Color(0xFFF8700D);
|
||||||
|
} else if (item.title == '中') {
|
||||||
|
bgColor = Color(0xFF4CC7B8);
|
||||||
|
} else if (item.title == '差') {
|
||||||
|
bgColor = Color(0xFFFF6F6F);
|
||||||
|
}
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
showStudentListDialog(
|
||||||
|
context: context,
|
||||||
|
title: item.title + '等作业学生',
|
||||||
|
arr: item.studentNames);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.r),
|
||||||
|
width: (MediaQuery.of(context).size.width - 55.r) / 2,
|
||||||
|
color: Color(0xFFF5F5F5),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: (MediaQuery.of(context).size.width - 55.r) / 4,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 28.r,
|
||||||
|
height: 28.r,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
border: Border.all(
|
||||||
|
color: bgColor,
|
||||||
|
width: 1.r,
|
||||||
|
style: BorderStyle.solid),
|
||||||
|
borderRadius: BorderRadius.circular(14.r)),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
item.title,
|
||||||
|
style:
|
||||||
|
TextStyle(color: bgColor, fontSize: 12.r),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 10.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
item.count.toString(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20.sp, color: Color(0xFF595959)),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'人',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp, color: Color(0xFF595959)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@swidget
|
||||||
|
Widget leftContainer(context,{required int count,required String name,required Color nameColor,required Color bgColor}){
|
||||||
|
double leftWidth = (MediaQuery.of(context).size.width-40.r) * 0.7/3;
|
||||||
|
return Container(
|
||||||
|
width: leftWidth,
|
||||||
|
height: 92.r,
|
||||||
|
padding:
|
||||||
|
EdgeInsets.symmetric(vertical: 10.r, horizontal: 6.r),
|
||||||
|
color: bgColor,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 5.r,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
count.toString(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18.sp,
|
||||||
|
color: Color(0xFF595959),
|
||||||
|
fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'人',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.sp,
|
||||||
|
color: Color(0xFF595959),
|
||||||
|
fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 20.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
name,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: nameColor,
|
||||||
|
fontWeight: FontWeight.w500),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@swidget
|
||||||
|
Widget rightContainer({required int count,required Color bgColor,required Color nameColor,required String name}){
|
||||||
|
return Container(
|
||||||
|
color:bgColor,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 5.r,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
count.toString(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: nameColor,
|
||||||
|
fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'人',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 8.sp,
|
||||||
|
color: nameColor,
|
||||||
|
fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 5.r,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
name,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: nameColor,
|
||||||
|
fontWeight: FontWeight.w500),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -10,7 +10,6 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_easyrefresh/easy_refresh.dart';
|
import 'package:flutter_easyrefresh/easy_refresh.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:marking_app/common/config/request_config.dart';
|
import 'package:marking_app/common/config/request_config.dart';
|
||||||
|
|
@ -21,8 +20,6 @@ import 'package:marking_app/common/model/event_bus/marking_statistics_bus.dart';
|
||||||
import 'package:marking_app/common/model/marking/marking_statistics.dart';
|
import 'package:marking_app/common/model/marking/marking_statistics.dart';
|
||||||
import 'package:marking_app/pages/common/event_bus_mixin.dart';
|
import 'package:marking_app/pages/common/event_bus_mixin.dart';
|
||||||
import 'package:marking_app/provider/review_provider.dart';
|
import 'package:marking_app/provider/review_provider.dart';
|
||||||
import 'package:marking_app/utils/anti_shake_throttling.dart';
|
|
||||||
import 'package:marking_app/utils/index.dart';
|
|
||||||
import 'package:marking_app/utils/request/rest_client.dart';
|
import 'package:marking_app/utils/request/rest_client.dart';
|
||||||
import 'package:marking_app/common/model/common/base_page_data.dart';
|
import 'package:marking_app/common/model/common/base_page_data.dart';
|
||||||
import 'package:marking_app/common/model/marking/marking_item.dart';
|
import 'package:marking_app/common/model/marking/marking_item.dart';
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
|
||||||
|
class ReportHistory extends StatefulWidget {
|
||||||
|
const ReportHistory({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ReportHistory> createState() => _ReportHistoryState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ReportHistoryState extends State<ReportHistory> {
|
||||||
|
bool isWork = true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: Color(0xFFEDF0FF),
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
title: Text(
|
||||||
|
'已完成报告',
|
||||||
|
style: TextStyle(fontSize: 14.r, color: Color(0xFF000000)),
|
||||||
|
),
|
||||||
|
centerTitle: true,
|
||||||
|
leading: IconButton(
|
||||||
|
icon: Icon(Icons.arrow_back_ios, color: Colors.black),
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: MediaQuery.of(context).size.width * 0.8,
|
||||||
|
height: 40.r,
|
||||||
|
margin: EdgeInsets.only(
|
||||||
|
top: 10.r, left: MediaQuery.of(context).size.width * 0.2 / 2),
|
||||||
|
padding: EdgeInsets.all(2.r),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: InkWell(
|
||||||
|
onTap: (){
|
||||||
|
isWork = true;
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: isWork ? Color(0xFF6988FD) : Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'作业',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.r,
|
||||||
|
color: isWork ? Colors.white : Color(0xFF505E6E)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
Expanded(
|
||||||
|
child: InkWell(
|
||||||
|
onTap: (){
|
||||||
|
isWork = false;
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: !isWork ? Color(0xFF6988FD) : Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'考试',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.r,
|
||||||
|
color: !isWork ? Colors.white : Color(0xFF505E6E)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,7 +11,7 @@ class TopUserInfo extends ConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final userState = ref.watch(userProvider);
|
final userState = ref.read(userProvider);
|
||||||
|
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,15 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:marking_app/common/model/enum/marking_list_type.dart';
|
import 'package:marking_app/common/model/enum/marking_list_type.dart';
|
||||||
import 'package:marking_app/pages/common/startUpPage.dart';
|
import 'package:marking_app/pages/common/startUpPage.dart';
|
||||||
import 'package:marking_app/pages/homework_correction/do_papers_job_exam.dart';
|
import 'package:marking_app/pages/homework_correction/do_papers_job_exam.dart';
|
||||||
|
import 'package:marking_app/pages/homework_correction/job_personal_detail.dart';
|
||||||
|
import 'package:marking_app/pages/homework_correction/job_priority_review_set.dart';
|
||||||
import 'package:marking_app/pages/homework_correction/job_report.dart';
|
import 'package:marking_app/pages/homework_correction/job_report.dart';
|
||||||
|
import 'package:marking_app/pages/homework_correction/job_student_group.dart';
|
||||||
|
import 'package:marking_app/pages/homework_correction/pages/job_favorite.dart';
|
||||||
|
import 'package:marking_app/pages/homework_correction/pages/job_list_participate_in_class.dart';
|
||||||
import 'package:marking_app/pages/homework_correction/review_job.dart';
|
import 'package:marking_app/pages/homework_correction/review_job.dart';
|
||||||
|
import 'package:marking_app/pages/homework_correction/quick_check_personal.dart';
|
||||||
|
import 'package:marking_app/pages/homework_correction/quick_data_check.dart';
|
||||||
import 'package:marking_app/pages/login/index.dart';
|
import 'package:marking_app/pages/login/index.dart';
|
||||||
import 'package:marking_app/pages/mainPage.dart';
|
import 'package:marking_app/pages/mainPage.dart';
|
||||||
import 'package:marking_app/pages/marking/do_papers.dart';
|
import 'package:marking_app/pages/marking/do_papers.dart';
|
||||||
|
|
@ -28,6 +34,7 @@ import 'package:marking_app/pages/mine/index.dart';
|
||||||
import 'package:marking_app/pages/mine/other_pages/index.dart';
|
import 'package:marking_app/pages/mine/other_pages/index.dart';
|
||||||
import 'package:marking_app/pages/other/agreement_page.dart';
|
import 'package:marking_app/pages/other/agreement_page.dart';
|
||||||
import 'package:marking_app/pages/report_detail/index.dart';
|
import 'package:marking_app/pages/report_detail/index.dart';
|
||||||
|
import 'package:marking_app/pages/report_detail/report_history.dart';
|
||||||
import 'package:marking_app/pages/reports/report_class_teacher.dart';
|
import 'package:marking_app/pages/reports/report_class_teacher.dart';
|
||||||
import 'package:marking_app/pages/reports/report_personal_subject.dart';
|
import 'package:marking_app/pages/reports/report_personal_subject.dart';
|
||||||
import 'package:marking_app/pages/reports/report_subject_teacher.dart';
|
import 'package:marking_app/pages/reports/report_subject_teacher.dart';
|
||||||
|
|
@ -53,12 +60,24 @@ class RouterManager {
|
||||||
static const String jobReportPagePath = '/job/report/index';
|
static const String jobReportPagePath = '/job/report/index';
|
||||||
// 作业 ==> 横屏考试
|
// 作业 ==> 横屏考试
|
||||||
static const String jobExamPagePath = '/job/exam/index';
|
static const String jobExamPagePath = '/job/exam/index';
|
||||||
|
// 作业 ==> 列表 ==> 参与班级
|
||||||
|
static const String jobListParticipateInClassPath = '/job/list/participateInClass';
|
||||||
|
// 作业 ==> 收藏页面
|
||||||
|
static const String jobFavoritePagePath = '/job/favorite/index';
|
||||||
|
|
||||||
static const String reportClassTeacherPath = 'report/details/reportClassTeacher';
|
static const String reportClassTeacherPath = 'report/details/reportClassTeacher';
|
||||||
static const String reportSubjectTeacherPath = 'report/details/reportSubjectTeacher';
|
static const String reportSubjectTeacherPath = 'report/details/reportSubjectTeacher';
|
||||||
static const String reportPersonalSubjectPath = 'report/details/reportPersonalSubject';
|
static const String reportPersonalSubjectPath = 'report/details/reportPersonalSubject';
|
||||||
static const String userMinePath = 'user/mine/index';
|
static const String userMinePath = 'user/mine/index';
|
||||||
static const String reportDetailPath = '/report_detail/index';
|
static const String reportDetailPath = '/report_detail/index';
|
||||||
|
static const String quickDataCheckPath = '/homework_correction/quick_data_check';
|
||||||
|
static const String quickCheckPersonalPath = '/homework_correction/quick_check_personal';
|
||||||
|
static const String jobPriorityReviewSetPath = '/homework_correction/job_priority_review_set';
|
||||||
|
static const String jobStudentGroupPath = '/homework_correction/job_student_group';
|
||||||
|
static const String jobPersonalDetailPath = '/homework_correction/job_personal_detail';
|
||||||
|
static const String reportCardDialogPath = '/report_detail/widgets/report_card_dialog';
|
||||||
|
static const String reportHistoryPath = '/report_detail/report_history';
|
||||||
|
|
||||||
// TheMine
|
// TheMine
|
||||||
|
|
||||||
static final FluroRouter router = FluroRouter();
|
static final FluroRouter router = FluroRouter();
|
||||||
|
|
@ -173,7 +192,16 @@ class RouterManager {
|
||||||
static final _jobReportPageHandler = Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
|
static final _jobReportPageHandler = Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
|
||||||
int id = int.parse(params['id']![0]);
|
int id = int.parse(params['id']![0]);
|
||||||
String title = params['title']![0];
|
String title = params['title']![0];
|
||||||
return JobReport(id: id, title: title);
|
int? schoolId;
|
||||||
|
if (params['schoolId'] != null && params['schoolId']?[0] != null && params['schoolId']![0] != 'null') {
|
||||||
|
schoolId = int.parse(params['schoolId']![0]);
|
||||||
|
}
|
||||||
|
int? gradeId;
|
||||||
|
if (params['gradeId'] != null && params['gradeId']?[0] != null && params['gradeId']![0] != 'null') {
|
||||||
|
gradeId = int.parse(params['gradeId']![0]);
|
||||||
|
}
|
||||||
|
String? className = params['className']?[0];
|
||||||
|
return JobReport(id: id, title: title, schoolId: schoolId, gradeId: gradeId, className: className);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 作业报告页面
|
// 作业报告页面
|
||||||
|
|
@ -239,6 +267,101 @@ class RouterManager {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static final _jobListParticipateInClassHandler = Handler(
|
||||||
|
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
|
||||||
|
int jobId = int.parse(params['jobId']![0]);
|
||||||
|
String jobName = params['jobName']![0];
|
||||||
|
String genderName = params['genderName']![0];
|
||||||
|
// ignore: sdk_version_since
|
||||||
|
bool completed = bool.parse(params['completed']?[0] ?? 'false');
|
||||||
|
return JobListParticipateInClass(jobId: jobId, jobName: jobName, genderName: genderName, completed: completed);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// 数据快查
|
||||||
|
static final _quickDataCheckPageHandler = Handler(
|
||||||
|
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
|
||||||
|
int jobId = int.parse(params['jobId']![0]);
|
||||||
|
String className = params['className']![0];
|
||||||
|
String gradeName = params['gradeName']![0];
|
||||||
|
int? schoolId;
|
||||||
|
if (params['schoolId'] != null && params['schoolId']?[0] != null && params['schoolId']![0] != 'null') {
|
||||||
|
schoolId = int.parse(params['schoolId']![0]);
|
||||||
|
}
|
||||||
|
int? gradeId;
|
||||||
|
if (params['gradeId'] != null && params['gradeId']?[0] != null && params['gradeId']![0] != 'null') {
|
||||||
|
gradeId = int.parse(params['gradeId']![0]);
|
||||||
|
}
|
||||||
|
return QuickDataCheckPage(jobId: jobId, className: className,gradeName:gradeName,schoolId:schoolId,gradeId:gradeId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// 数据快查-个人信息
|
||||||
|
static final _quickCheckPersonalPageHandler = Handler(
|
||||||
|
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
|
||||||
|
int jobId = int.parse(params['jobId']![0]);
|
||||||
|
int studentId = int.parse(params['studentId']![0]);
|
||||||
|
return QuickCheckPersonal(jobId: jobId, studentId: studentId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
//优先配置
|
||||||
|
static final _jobPriorityReviewSetPageHandler = Handler(
|
||||||
|
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
|
||||||
|
String groupId = params['groupId']![0];
|
||||||
|
return JobPriorityReviewSet(groupId: groupId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
//学生分组
|
||||||
|
static final _jobStudentGroupPageHandler = Handler(
|
||||||
|
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
|
||||||
|
return JobStudentGroup();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
//作业收藏页面
|
||||||
|
static final _jobFavoritePagePathHandler = Handler(
|
||||||
|
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
|
||||||
|
int jobId = int.parse(params['jobId']![0]);
|
||||||
|
String jobName = params['jobName']![0];
|
||||||
|
String? className = params['className']?[0];
|
||||||
|
int? schoolId;
|
||||||
|
if (params['schoolId'] != null && params['schoolId']?[0] != null && params['schoolId']![0] != 'null') {
|
||||||
|
schoolId = int.parse(params['schoolId']![0]);
|
||||||
|
}
|
||||||
|
int? gradeId;
|
||||||
|
if (params['gradeId'] != null && params['gradeId']?[0] != null && params['gradeId']![0] != 'null') {
|
||||||
|
gradeId = int.parse(params['gradeId']![0]);
|
||||||
|
}
|
||||||
|
return JobFavorite(jobId: jobId, gradeId: gradeId, schoolId: schoolId, className: className,jobName:jobName);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// 优先配置个人详情
|
||||||
|
static final _jobPersonalDetailPathHandler = Handler(
|
||||||
|
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
|
||||||
|
String studentName = params['studentName']![0];
|
||||||
|
int studentId = int.parse(params['studentId']![0]);
|
||||||
|
return JobPersonalDetail(studentId: studentId,studentName:studentName);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// 学生报告详情
|
||||||
|
static final _reportCardDialogPathHandler = Handler(
|
||||||
|
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
|
||||||
|
/* String studentName = params['studentName']![0];
|
||||||
|
int studentId = int.parse(params['studentId']![0]);
|
||||||
|
return ReportCardDialog(studentId: studentId,studentName:studentName);*/
|
||||||
|
},
|
||||||
|
);
|
||||||
|
// 学生历史报告
|
||||||
|
static final _reportHistoryPathHandler = Handler(
|
||||||
|
handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
|
||||||
|
/* String studentName = params['studentName']![0];
|
||||||
|
int studentId = int.parse(params['studentId']![0]);*/
|
||||||
|
return ReportHistory();
|
||||||
|
},
|
||||||
|
);
|
||||||
// 开始阅卷页面
|
// 开始阅卷页面
|
||||||
// static final _doMarkingPapers = Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) => MarkingPapers());
|
// static final _doMarkingPapers = Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) => MarkingPapers());
|
||||||
|
|
||||||
|
|
@ -273,6 +396,18 @@ class RouterManager {
|
||||||
router.define(reportDetailPath, handler: _reportDetailPath, transitionType: TransitionType.material);
|
router.define(reportDetailPath, handler: _reportDetailPath, transitionType: TransitionType.material);
|
||||||
router.define(jobReportPagePath, handler: _jobReportPageHandler, transitionType: TransitionType.material);
|
router.define(jobReportPagePath, handler: _jobReportPageHandler, transitionType: TransitionType.material);
|
||||||
router.define(jobExamPagePath, handler: _jobExamPageHandler, transitionType: TransitionType.material);
|
router.define(jobExamPagePath, handler: _jobExamPageHandler, transitionType: TransitionType.material);
|
||||||
|
router.define(jobListParticipateInClassPath,
|
||||||
|
handler: _jobListParticipateInClassHandler, transitionType: TransitionType.material);
|
||||||
|
router.define(quickDataCheckPath, handler: _quickDataCheckPageHandler, transitionType: TransitionType.material);
|
||||||
|
router.define(quickCheckPersonalPath,
|
||||||
|
handler: _quickCheckPersonalPageHandler, transitionType: TransitionType.material);
|
||||||
|
router.define(jobPriorityReviewSetPath,
|
||||||
|
handler: _jobPriorityReviewSetPageHandler, transitionType: TransitionType.material);
|
||||||
|
router.define(jobStudentGroupPath, handler: _jobStudentGroupPageHandler, transitionType: TransitionType.material);
|
||||||
|
router.define(jobFavoritePagePath, handler: _jobFavoritePagePathHandler, transitionType: TransitionType.material);
|
||||||
|
router.define(jobPersonalDetailPath, handler: _jobPersonalDetailPathHandler, transitionType: TransitionType.material);
|
||||||
|
router.define(reportCardDialogPath, handler: _reportCardDialogPathHandler, transitionType: TransitionType.material);
|
||||||
|
router.define(reportHistoryPath, handler: _reportHistoryPathHandler, transitionType: TransitionType.material);
|
||||||
|
|
||||||
// getTransition()
|
// getTransition()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,4 +18,31 @@ class CommonUtils {
|
||||||
// 这里其实就是 digest.toString()
|
// 这里其实就是 digest.toString()
|
||||||
return hex.encode(digest.bytes);
|
return hex.encode(digest.bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///补零
|
||||||
|
static String zeroFill(int i) {
|
||||||
|
return i >= 10 ? "$i" : "0$i";
|
||||||
|
}
|
||||||
|
/// 秒转时分秒
|
||||||
|
static String second2HMS(int sec, {bool isEasy = false}) {
|
||||||
|
String hms = "00:00:00";
|
||||||
|
if (!isEasy) hms = "00时00分00秒";
|
||||||
|
if (sec > 0) {
|
||||||
|
int h = sec ~/ 3600;
|
||||||
|
int m = (sec % 3600) ~/ 60;
|
||||||
|
int s = sec % 60;
|
||||||
|
/* hms = "${zeroFill(h)}:${zeroFill(m)}:${zeroFill(s)}";
|
||||||
|
if (!isEasy) hms = "${zeroFill(h)}时${zeroFill(m)}分${zeroFill(s)}秒";*/
|
||||||
|
if(h>0){
|
||||||
|
hms = "$h时$m分$s秒";
|
||||||
|
}else{
|
||||||
|
if(m>0){
|
||||||
|
hms = "$m分$s秒";
|
||||||
|
}else{
|
||||||
|
hms = "$s秒";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hms;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class AutoDrawer extends StatefulWidget {
|
class AutoDrawer extends StatefulWidget {
|
||||||
|
|
||||||
final double elevation;
|
final double elevation;
|
||||||
final Widget child;
|
final Widget child;
|
||||||
final String? semanticLabel;
|
final String? semanticLabel;
|
||||||
|
|
@ -22,7 +21,6 @@ import 'package:flutter/material.dart';
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AutoDrawerState extends State<AutoDrawer> {
|
class _AutoDrawerState extends State<AutoDrawer> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
if (widget.callback != null) {
|
if (widget.callback != null) {
|
||||||
|
|
@ -31,6 +29,7 @@ import 'package:flutter/material.dart';
|
||||||
}
|
}
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
if (widget.callback != null) {
|
if (widget.callback != null) {
|
||||||
|
|
@ -43,15 +42,7 @@ import 'package:flutter/material.dart';
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
assert(debugCheckHasMaterialLocalizations(context));
|
assert(debugCheckHasMaterialLocalizations(context));
|
||||||
String? label = widget.semanticLabel;
|
String? label = widget.semanticLabel ?? MaterialLocalizations.of(context).drawerLabel;
|
||||||
switch (defaultTargetPlatform) {
|
|
||||||
case TargetPlatform.iOS:
|
|
||||||
label = widget.semanticLabel;
|
|
||||||
break;
|
|
||||||
case TargetPlatform.android:
|
|
||||||
case TargetPlatform.fuchsia:
|
|
||||||
label = widget.semanticLabel ?? MaterialLocalizations.of(context)?.drawerLabel;
|
|
||||||
}
|
|
||||||
final double _width = MediaQuery.of(context).size.width * widget.widthPercent;
|
final double _width = MediaQuery.of(context).size.width * widget.widthPercent;
|
||||||
return Semantics(
|
return Semantics(
|
||||||
scopesRoute: true,
|
scopesRoute: true,
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
|
||||||
class MyEmptyWidget extends StatelessWidget {
|
class MyEmptyWidget extends StatelessWidget {
|
||||||
static const String defText = "抱歉,暂无内容";
|
static const String defText = "抱歉,暂无内容";
|
||||||
static const String defimg = "assets/images/not_data_bgm.png";
|
static const String defimg = "assets/images/not_data_bgm2.png";
|
||||||
final String? textVal;
|
final String? textVal;
|
||||||
final String? imgAssetPath;
|
final String? imgAssetPath;
|
||||||
final AlignmentGeometry alignment;
|
final AlignmentGeometry alignment;
|
||||||
|
|
@ -32,22 +32,25 @@ class MyEmptyWidget extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
padding: padding,
|
padding: padding != null?padding:EdgeInsets.only(bottom: 40.r),
|
||||||
alignment: alignment,
|
alignment: alignment,
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Image.asset(
|
Opacity(
|
||||||
|
opacity: 0.6,
|
||||||
|
child: Image.asset(
|
||||||
imgAssetPath ?? defimg,
|
imgAssetPath ?? defimg,
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
width: imgWidth ?? 130.w,
|
width: imgWidth ?? 150.w,
|
||||||
height: imgHeight ?? 130.w,
|
height: imgHeight ?? 150.w,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: 15.h),
|
padding: EdgeInsets.only(top: 5.h),
|
||||||
child: Text(
|
child: Text(
|
||||||
textVal ?? defText,
|
textVal ?? defText,
|
||||||
style: TextStyle(fontSize: 16.sp, color: Colors.grey),
|
style: TextStyle(fontSize: 12.sp, color: Color(0xB2898B8D)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import 'dart:math';
|
||||||
|
|
||||||
import 'package:fluro/fluro.dart';
|
import 'package:fluro/fluro.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:marking_app/common/config/request_config.dart';
|
import 'package:marking_app/common/config/request_config.dart';
|
||||||
|
|
||||||
export "./colorUtils.dart";
|
export "./colorUtils.dart";
|
||||||
|
|
@ -105,6 +106,11 @@ void toPrint({required dynamic val, bool toPrintJson = false}) {
|
||||||
if (printSwitch && val != null) toPrintJson ? printJson(val) : print(val);
|
if (printSwitch && val != null) toPrintJson ? printJson(val) : print(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 是否是平板
|
||||||
|
bool isPad([double mobilePhoneScale = 1.2]) {
|
||||||
|
return ScreenUtil().scaleWidth > mobilePhoneScale;
|
||||||
|
}
|
||||||
|
|
||||||
class EUMNoScrollBehavior extends ScrollBehavior {
|
class EUMNoScrollBehavior extends ScrollBehavior {
|
||||||
@override
|
@override
|
||||||
Widget buildViewportChrome(BuildContext context, Widget child, AxisDirection axisDirection) {
|
Widget buildViewportChrome(BuildContext context, Widget child, AxisDirection axisDirection) {
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,12 @@ import 'package:marking_app/common/model/common/upload_img_secret_key.dart';
|
||||||
import 'package:marking_app/common/model/job/job_collect_params.dart';
|
import 'package:marking_app/common/model/job/job_collect_params.dart';
|
||||||
import 'package:marking_app/common/model/job/job_concerned_with_student.dart';
|
import 'package:marking_app/common/model/job/job_concerned_with_student.dart';
|
||||||
import 'package:marking_app/common/model/job/job_concerned_with_student_params.dart';
|
import 'package:marking_app/common/model/job/job_concerned_with_student_params.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_data_report.dart';
|
||||||
import 'package:marking_app/common/model/job/job_do_marking_status_info.dart';
|
import 'package:marking_app/common/model/job/job_do_marking_status_info.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_fav_student.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_favorite_item_model.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_favorite_model.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_level_set_params.dart';
|
||||||
import 'package:marking_app/common/model/job/job_note_taking_trajectory.dart';
|
import 'package:marking_app/common/model/job/job_note_taking_trajectory.dart';
|
||||||
import 'package:marking_app/common/model/job/job_page_tab.dart';
|
import 'package:marking_app/common/model/job/job_page_tab.dart';
|
||||||
import 'package:marking_app/common/model/job/job_report_join_class.dart';
|
import 'package:marking_app/common/model/job/job_report_join_class.dart';
|
||||||
|
|
@ -23,6 +28,9 @@ import 'package:marking_app/common/model/job/job_report_knowledge_model.dart';
|
||||||
import 'package:marking_app/common/model/job/job_report_model.dart';
|
import 'package:marking_app/common/model/job/job_report_model.dart';
|
||||||
import 'package:marking_app/common/model/job/job_report_question_deatil_model.dart';
|
import 'package:marking_app/common/model/job/job_report_question_deatil_model.dart';
|
||||||
import 'package:marking_app/common/model/job/job_review_submission.dart';
|
import 'package:marking_app/common/model/job/job_review_submission.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_student_goups.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_student_history.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_student_level.dart';
|
||||||
import 'package:marking_app/common/model/job/job_task_item.dart';
|
import 'package:marking_app/common/model/job/job_task_item.dart';
|
||||||
import 'package:marking_app/common/model/job/marking_text_question_job.dart';
|
import 'package:marking_app/common/model/job/marking_text_question_job.dart';
|
||||||
import 'package:marking_app/common/model/job/marking_text_question_job_params.dart';
|
import 'package:marking_app/common/model/job/marking_text_question_job_params.dart';
|
||||||
|
|
@ -242,8 +250,8 @@ abstract class RestClient {
|
||||||
|
|
||||||
// 作业 => 查询作业是否收藏
|
// 作业 => 查询作业是否收藏
|
||||||
@the_retrofit.GET("${RequestConfig.hwProxyKeywords}/api/Dpc/collect")
|
@the_retrofit.GET("${RequestConfig.hwProxyKeywords}/api/Dpc/collect")
|
||||||
Future<BaseStructureResult<bool>> getJobCollect(
|
Future<BaseStructureResult<bool>> getJobCollect(@the_retrofit.Query("taskId") int taskId,
|
||||||
@the_retrofit.Query("taskId") int taskId, @the_retrofit.Query("studentId") int studentId);
|
@the_retrofit.Query("studentId") int studentId, @the_retrofit.Query("paperId") int paperId);
|
||||||
|
|
||||||
// 作业 => 作业优先批阅取消
|
// 作业 => 作业优先批阅取消
|
||||||
@the_retrofit.POST("/api/read/cancel-job-read-level")
|
@the_retrofit.POST("/api/read/cancel-job-read-level")
|
||||||
|
|
@ -267,7 +275,7 @@ abstract class RestClient {
|
||||||
@the_retrofit.GET("/api/jobs/job-report")
|
@the_retrofit.GET("/api/jobs/job-report")
|
||||||
Future<BaseStructureResult<JobReportModel>> getJobReport(@the_retrofit.Queries() Map<String, dynamic> params);
|
Future<BaseStructureResult<JobReportModel>> getJobReport(@the_retrofit.Queries() Map<String, dynamic> params);
|
||||||
|
|
||||||
// 作业 => 获取作业报告
|
// 作业 => 获取作业班级列表(参与班级)
|
||||||
@the_retrofit.GET("/api/jobs/student-job-for-class")
|
@the_retrofit.GET("/api/jobs/student-job-for-class")
|
||||||
Future<BaseStructureResult<List<JobReportJoinClass>>> getJobReportJoinClasses(@the_retrofit.Query("jobId") int jobId);
|
Future<BaseStructureResult<List<JobReportJoinClass>>> getJobReportJoinClasses(@the_retrofit.Query("jobId") int jobId);
|
||||||
|
|
||||||
|
|
@ -285,4 +293,69 @@ abstract class RestClient {
|
||||||
@the_retrofit.GET("/api/jobs/job-report-question-detail")
|
@the_retrofit.GET("/api/jobs/job-report-question-detail")
|
||||||
Future<BaseStructureResult<List<JobReportQuestionDeatilModel>>> getJobReportQuestionDetail(
|
Future<BaseStructureResult<List<JobReportQuestionDeatilModel>>> getJobReportQuestionDetail(
|
||||||
@the_retrofit.Query("jobid") int jobId, @the_retrofit.Query("questionid") int questionid);
|
@the_retrofit.Query("jobid") int jobId, @the_retrofit.Query("questionid") int questionid);
|
||||||
|
|
||||||
|
// 作业 => 列表 ==> 参与班级列表
|
||||||
|
@the_retrofit.GET("${RequestConfig.hwProxyKeywords}/api/Task/tasks")
|
||||||
|
Future<BaseStructureResult<List<MarkingTasks>>> getJobListParticipateInClass(
|
||||||
|
@the_retrofit.Query("markingId") int jobId);
|
||||||
|
|
||||||
|
// 作业 => 作业收藏数量
|
||||||
|
@the_retrofit.GET("/dpc-api/api/read/job-favorite-count-by-class")
|
||||||
|
Future<BaseStructureResult<List<JobFavoriteModel>>> getListOfJobFavoriteNumber(
|
||||||
|
@the_retrofit.Query("jobid") int jobId);
|
||||||
|
|
||||||
|
// 作业 => 作业收藏列表
|
||||||
|
@the_retrofit.GET("/api/jobs/fav-student-jobs")
|
||||||
|
Future<BaseStructureResult<JobFavStudent>> getListOfJobFavorites(
|
||||||
|
@the_retrofit.Query("JobId") int jobId,
|
||||||
|
@the_retrofit.Query("JobName") String jobName,
|
||||||
|
@the_retrofit.Query("className") String? className,
|
||||||
|
@the_retrofit.Query("PageSize") int pageSize,
|
||||||
|
);
|
||||||
|
|
||||||
|
// 作业 => 作业收藏列表
|
||||||
|
@the_retrofit.POST("${RequestConfig.hwProxyKeywords}/dpc-api/api/read/cancel-favorite")
|
||||||
|
Future<BaseStructureResult<bool>> toJobCancelFavorite(
|
||||||
|
@the_retrofit.Field() int jobId, @the_retrofit.Field() int studentId);
|
||||||
|
|
||||||
|
// 作业 => 数据快查
|
||||||
|
@the_retrofit.GET("/api/read/job-data-center-report")
|
||||||
|
Future<BaseStructureResult<JobDataReport>> getJobDataCenterReport(
|
||||||
|
@the_retrofit.Queries() Map<String, dynamic> params);
|
||||||
|
|
||||||
|
// 作业 => 数据快查--个人
|
||||||
|
@the_retrofit.GET("/api/read/job-data-center-student-report")
|
||||||
|
Future<BaseStructureResult<StudentDetails>> getJobPersonalReport(@the_retrofit.Queries() Map<String, dynamic> params);
|
||||||
|
|
||||||
|
// 作业 => 优先批阅,学生分组列表
|
||||||
|
@the_retrofit.GET("/api/read/job-read-level-student-groups")
|
||||||
|
Future<BaseStructureResult<List<JobStudentGroups>>> getJobLevelStudentGroups(
|
||||||
|
@the_retrofit.Query("account") String account);
|
||||||
|
|
||||||
|
// 作业 => 优先批阅,优先批阅列表
|
||||||
|
@the_retrofit.GET("/api/read/job-read-level")
|
||||||
|
Future<BaseStructureResult<List<JobStudentLevel>>> getJobReadLevel(
|
||||||
|
@the_retrofit.Query("GroupId") String groupId, @the_retrofit.Query("ReadLevel") int readLevel);
|
||||||
|
|
||||||
|
// 作业 => 取消/设置优先
|
||||||
|
@the_retrofit.POST("/api/read/jc-job-read-level")
|
||||||
|
Future<BaseStructureResult> getSetJobReadLevel(@the_retrofit.Body() JobLevelSetParams params);
|
||||||
|
|
||||||
|
// 作业 => 取消收藏
|
||||||
|
@the_retrofit.POST("/api/jobs/de-fav-student-job")
|
||||||
|
Future<BaseStructureResult> getJobDeFavorites(@the_retrofit.Field("jobId") int jobId,
|
||||||
|
@the_retrofit.Field("studentId") int studentId, @the_retrofit.Field("questionPage") int questionPage);
|
||||||
|
|
||||||
|
// 作业 => 学生作业详情历史
|
||||||
|
@the_retrofit.GET("/api/read/student-job-history")
|
||||||
|
Future<BaseStructureResult<JobStudentHistory>> getStudentJobHistory(
|
||||||
|
@the_retrofit.Query("StudentId") int studentId,
|
||||||
|
@the_retrofit.Query("IsPaper") bool isPaper,
|
||||||
|
@the_retrofit.Query("DateStart") String? dateStart,
|
||||||
|
@the_retrofit.Query("DateEnd") String? dateEnd,
|
||||||
|
@the_retrofit.Query("Page") int page,
|
||||||
|
@the_retrofit.Query("PageSize") int pageSize,
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
|
||||||
|
Padding homeIcon({double? top = 5,double? right = 8,String? color = 'black'}){
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.only(top:top!.r,right: right!.r),
|
||||||
|
child: Image.asset('assets/images/home_icon_$color.png',width: 18.r,height: 18.r,),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 1.0.95
|
version: 1.0.102
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.17.1 <3.0.0"
|
sdk: ">=2.17.1 <3.0.0"
|
||||||
|
|
@ -29,6 +29,8 @@ environment:
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
flutter_localizations:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
|
|
@ -108,6 +110,11 @@ dependencies:
|
||||||
badges: ^3.1.2
|
badges: ^3.1.2
|
||||||
horizontal_data_table: ^4.1.1
|
horizontal_data_table: ^4.1.1
|
||||||
data_table_2: ^2.5.10
|
data_table_2: ^2.5.10
|
||||||
|
syncfusion_flutter_datepicker: ^21.2.10
|
||||||
|
flutter_staggered_grid_view: ^0.6.2
|
||||||
|
# 饼图
|
||||||
|
flutter_echart: ^2.0.0
|
||||||
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
||||||