IOS打包和代码调整
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 165 KiB |
|
After Width: | Height: | Size: 272 KiB |
|
Before Width: | Height: | Size: 305 KiB After Width: | Height: | Size: 69 B |
|
Before Width: | Height: | Size: 305 KiB After Width: | Height: | Size: 69 B |
|
|
@ -6,6 +6,7 @@
|
|||
<item name="android:windowFullscreen">false</item>
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
|
||||
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
|
||||
<item name="android:windowSplashScreenBackground">#42a5f5</item>
|
||||
<item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
<item name="android:windowFullscreen">false</item>
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
|
||||
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
|
||||
<item name="android:windowSplashScreenBackground">#42a5f5</item>
|
||||
<item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ flutter_native_splash:
|
|||
# 如需恢复默认的白屏,执行如下命令
|
||||
# flutter pub run flutter_native_splash:remove
|
||||
# 设置闪屏页的默认态logo或背景图片路径
|
||||
background_image: assets/images/splash_native.png
|
||||
color: "#42a5f5"
|
||||
image_ios: assets/images/splash_native.png
|
||||
background_image_android: assets/images/splash_native.png
|
||||
android_12:
|
||||
image: assets/images/splash.png
|
||||
android: true
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@
|
|||
|
||||
/* Begin PBXFileReference section */
|
||||
02826AB13A0419EF6A6BEE4C /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0B2C69D12C734FA600ABD561 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
|
||||
0B2C69D22C743A7D00ABD561 /* RunnerRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerRelease.entitlements; sourceTree = "<group>"; };
|
||||
12C576EE23C708825E0F6031 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
|
|
@ -97,7 +99,6 @@
|
|||
20D60590541077F4B12F8462 /* Pods-RunnerTests.release.xcconfig */,
|
||||
168BD706454188B9AD4262F4 /* Pods-RunnerTests.profile.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
|
|
@ -144,6 +145,8 @@
|
|||
97C146F01CF9000F007C117D /* Runner */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0B2C69D22C743A7D00ABD561 /* RunnerRelease.entitlements */,
|
||||
0B2C69D12C734FA600ABD561 /* Runner.entitlements */,
|
||||
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
|
||||
|
|
@ -454,6 +457,7 @@
|
|||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
|
|
@ -488,17 +492,28 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = Z778GC45N8;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.yuanxuan.makingSchoolAsignmentApp;
|
||||
MARKETING_VERSION = 1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.yuanxuan.makingS--buneng--choolAsignmentApp";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Profile;
|
||||
|
|
@ -528,6 +543,7 @@
|
|||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = Z778GC45N8;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.yuanxuan.makingSchoolAsignmentApp.RunnerTests;
|
||||
|
|
@ -577,6 +593,7 @@
|
|||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
|
|
@ -634,6 +651,7 @@
|
|||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
|
|
@ -670,18 +688,26 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = Z778GC45N8;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.yuanxuan.makingSchoolAsignmentApp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Debug;
|
||||
|
|
@ -692,17 +718,25 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/RunnerRelease.entitlements;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = Z778GC45N8;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.yuanxuan.makingSchoolAsignmentApp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Release;
|
||||
|
|
|
|||
|
|
@ -1,122 +1,122 @@
|
|||
{
|
||||
"images" : [
|
||||
"images": [
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
"filename": "Icon-App-20x20@2x.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "2x",
|
||||
"size": "20x20"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@3x.png",
|
||||
"scale" : "3x"
|
||||
"filename": "Icon-App-20x20@3x.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "3x",
|
||||
"size": "20x20"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
"filename": "Icon-App-29x29@1x.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "1x",
|
||||
"size": "29x29"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
"filename": "Icon-App-29x29@2x.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "2x",
|
||||
"size": "29x29"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@3x.png",
|
||||
"scale" : "3x"
|
||||
"filename": "Icon-App-29x29@3x.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "3x",
|
||||
"size": "29x29"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
"filename": "Icon-App-40x40@2x.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "2x",
|
||||
"size": "40x40"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@3x.png",
|
||||
"scale" : "3x"
|
||||
"filename": "Icon-App-40x40@3x.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "3x",
|
||||
"size": "40x40"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@2x.png",
|
||||
"scale" : "2x"
|
||||
"filename": "Icon-App-60x60@2x.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "2x",
|
||||
"size": "60x60"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@3x.png",
|
||||
"scale" : "3x"
|
||||
"filename": "Icon-App-60x60@3x.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "3x",
|
||||
"size": "60x60"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@1x.png",
|
||||
"scale" : "1x"
|
||||
"filename": "Icon-App-20x20@1x.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "1x",
|
||||
"size": "20x20"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
"filename": "Icon-App-20x20@2x.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "2x",
|
||||
"size": "20x20"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
"filename": "Icon-App-29x29@1x.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "1x",
|
||||
"size": "29x29"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
"filename": "Icon-App-29x29@2x.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "2x",
|
||||
"size": "29x29"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@1x.png",
|
||||
"scale" : "1x"
|
||||
"filename": "Icon-App-40x40@1x.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "1x",
|
||||
"size": "40x40"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
"filename": "Icon-App-40x40@2x.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "2x",
|
||||
"size": "40x40"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@1x.png",
|
||||
"scale" : "1x"
|
||||
"filename": "Icon-App-76x76@1x.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "1x",
|
||||
"size": "76x76"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@2x.png",
|
||||
"scale" : "2x"
|
||||
"filename": "Icon-App-76x76@2x.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "2x",
|
||||
"size": "76x76"
|
||||
},
|
||||
{
|
||||
"size" : "83.5x83.5",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-83.5x83.5@2x.png",
|
||||
"scale" : "2x"
|
||||
"filename": "Icon-App-83.5x83.5@2x.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "2x",
|
||||
"size": "83.5x83.5"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "Icon-App-1024x1024@1x.png",
|
||||
"scale" : "1x"
|
||||
"filename": "Icon-App-1024x1024@1x.png",
|
||||
"idiom": "ios-marketing",
|
||||
"scale": "1x",
|
||||
"size": "1024x1024"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
"info": {
|
||||
"author": "icons_launcher",
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 238 KiB After Width: | Height: | Size: 249 KiB |
|
Before Width: | Height: | Size: 618 B After Width: | Height: | Size: 635 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 956 B After Width: | Height: | Size: 961 B |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 12 KiB |
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
21
making_school_asignment_app/ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "background.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
making_school_asignment_app/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png
vendored
Normal file
|
After Width: | Height: | Size: 69 B |
|
Before Width: | Height: | Size: 69 B After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 69 B After Width: | Height: | Size: 179 KiB |
|
Before Width: | Height: | Size: 69 B After Width: | Height: | Size: 258 KiB |
|
|
@ -1,5 +0,0 @@
|
|||
# Launch Screen Assets
|
||||
|
||||
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
|
||||
|
||||
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="LaunchImage" width="168" height="185"/>
|
||||
<image name="LaunchImage" width="750" height="1735"/>
|
||||
<image name="LaunchBackground" width="1" height="1"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
|
||||
<device id="retina6_12" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Flutter View Controller-->
|
||||
|
|
@ -14,13 +16,14 @@
|
|||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="55" y="-34"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Making School Asignment App</string>
|
||||
<string>点智学</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
|
|
@ -24,10 +26,19 @@
|
|||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict/>
|
||||
</dict>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIStatusBarHidden</key>
|
||||
<false/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
|
|
@ -41,12 +52,6 @@
|
|||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>UIStatusBarHidden</key>
|
||||
<false/>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
</dict>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.developer.associated-domains</key>
|
||||
<array/>
|
||||
<key>com.apple.developer.devicecheck.appattest-environment</key>
|
||||
<string>development</string>
|
||||
<key>com.apple.developer.networking.networkextension</key>
|
||||
<array/>
|
||||
<key>com.apple.developer.networking.slicing.appcategory</key>
|
||||
<array/>
|
||||
<key>com.apple.developer.networking.slicing.trafficcategory</key>
|
||||
<array/>
|
||||
<key>com.apple.developer.networking.wifi-info</key>
|
||||
<true/>
|
||||
<key>com.apple.developer.user-fonts</key>
|
||||
<array/>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.developer.associated-domains</key>
|
||||
<array/>
|
||||
<key>com.apple.developer.devicecheck.appattest-environment</key>
|
||||
<string>development</string>
|
||||
<key>com.apple.developer.networking.networkextension</key>
|
||||
<array/>
|
||||
<key>com.apple.developer.networking.slicing.appcategory</key>
|
||||
<array/>
|
||||
<key>com.apple.developer.networking.slicing.trafficcategory</key>
|
||||
<array/>
|
||||
<key>com.apple.developer.networking.wifi-info</key>
|
||||
<true/>
|
||||
<key>com.apple.developer.user-fonts</key>
|
||||
<array/>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -73,28 +73,31 @@ class DoPaperDetailsResult extends Object {
|
|||
@JsonKey(name: 'totalUnAnnotateCount')
|
||||
int totalUnAnnotateCount;
|
||||
|
||||
@JsonKey(name: 'needAnnotate', defaultValue: false) // 是否需要批阅
|
||||
bool needAnnotate;
|
||||
|
||||
DoPaperDetailsResult(
|
||||
this.totalUnAnnotateCount,
|
||||
this.templateIds,
|
||||
this.students,
|
||||
this.templateId,
|
||||
this.studentId,
|
||||
this.annotatedCount,
|
||||
this.submitCount,
|
||||
this.zgtAnswer,
|
||||
this.zgtAnnotate,
|
||||
this.lastAnswerTime,
|
||||
this.isFav,
|
||||
this.studentQuestions,
|
||||
this.unSubmitStudents,
|
||||
this.lastPage,
|
||||
this.nextPage,
|
||||
this.templateIdKeys,
|
||||
this.templateIdKeyMap,
|
||||
this.priority,
|
||||
this.annotateTime,
|
||||
this.showZgtAnnotate,
|
||||
) {
|
||||
this.totalUnAnnotateCount,
|
||||
this.templateIds,
|
||||
this.students,
|
||||
this.templateId,
|
||||
this.studentId,
|
||||
this.annotatedCount,
|
||||
this.submitCount,
|
||||
this.zgtAnswer,
|
||||
this.zgtAnnotate,
|
||||
this.lastAnswerTime,
|
||||
this.isFav,
|
||||
this.studentQuestions,
|
||||
this.unSubmitStudents,
|
||||
this.lastPage,
|
||||
this.nextPage,
|
||||
this.templateIdKeys,
|
||||
this.templateIdKeyMap,
|
||||
this.priority,
|
||||
this.annotateTime,
|
||||
this.showZgtAnnotate,
|
||||
{this.needAnnotate = false}) {
|
||||
if (templateIds.keys.isNotEmpty) {
|
||||
templateIdKeys = templateIds.keys.map((e) => int.parse(e)).toList();
|
||||
templateIdKeyMap = <int, int>{};
|
||||
|
|
@ -114,14 +117,21 @@ class DoPaperDetailsResult extends Object {
|
|||
|
||||
if (zgtAnnotate?.isNotEmpty ?? false) {
|
||||
showZgtAnnotate = RequestConfig.imgUrl + zgtAnnotate!; // 批注图片地址赋值
|
||||
if (annotateTime != null) showZgtAnnotate = '${showZgtAnnotate!}?$annotateTime';
|
||||
if (annotateTime != null)
|
||||
showZgtAnnotate = '${showZgtAnnotate!}?$annotateTime';
|
||||
}
|
||||
|
||||
// 判断当前试题是否需要批阅
|
||||
if (annotateTime == null ||
|
||||
studentQuestions.indexWhere((e) => e.studentScore == null) != -1) {
|
||||
needAnnotate = true;
|
||||
}
|
||||
// print('学生作答图片:${annotatedCount}');
|
||||
// print('老师批注图片提交数量:${submitCount}');
|
||||
}
|
||||
|
||||
factory DoPaperDetailsResult.fromJson(Map<String, dynamic> srcJson) => _$DoPaperDetailsResultFromJson(srcJson);
|
||||
factory DoPaperDetailsResult.fromJson(Map<String, dynamic> srcJson) =>
|
||||
_$DoPaperDetailsResultFromJson(srcJson);
|
||||
|
||||
Map<String, dynamic> toJson() => _$DoPaperDetailsResultToJson(this);
|
||||
}
|
||||
|
|
@ -144,7 +154,8 @@ class PaperStudents extends Object {
|
|||
this.isPriority,
|
||||
);
|
||||
|
||||
factory PaperStudents.fromJson(Map<String, dynamic> srcJson) => _$PaperStudentsFromJson(srcJson);
|
||||
factory PaperStudents.fromJson(Map<String, dynamic> srcJson) =>
|
||||
_$PaperStudentsFromJson(srcJson);
|
||||
|
||||
Map<String, dynamic> toJson() => _$PaperStudentsToJson(this);
|
||||
}
|
||||
|
|
@ -192,7 +203,8 @@ class StudentQuestions extends Object {
|
|||
this.isCorrect,
|
||||
});
|
||||
|
||||
factory StudentQuestions.fromJson(Map<String, dynamic> srcJson) => _$StudentQuestionsFromJson(srcJson);
|
||||
factory StudentQuestions.fromJson(Map<String, dynamic> srcJson) =>
|
||||
_$StudentQuestionsFromJson(srcJson);
|
||||
|
||||
Map<String, dynamic> toJson() => _$StudentQuestionsToJson(this);
|
||||
}
|
||||
|
|
@ -210,7 +222,8 @@ class LastPage extends Object {
|
|||
this.studentId,
|
||||
);
|
||||
|
||||
factory LastPage.fromJson(Map<String, dynamic> srcJson) => _$LastPageFromJson(srcJson);
|
||||
factory LastPage.fromJson(Map<String, dynamic> srcJson) =>
|
||||
_$LastPageFromJson(srcJson);
|
||||
|
||||
Map<String, dynamic> toJson() => _$LastPageToJson(this);
|
||||
}
|
||||
|
|
@ -228,7 +241,8 @@ class NextPage extends Object {
|
|||
this.studentId,
|
||||
);
|
||||
|
||||
factory NextPage.fromJson(Map<String, dynamic> srcJson) => _$NextPageFromJson(srcJson);
|
||||
factory NextPage.fromJson(Map<String, dynamic> srcJson) =>
|
||||
_$NextPageFromJson(srcJson);
|
||||
|
||||
Map<String, dynamic> toJson() => _$NextPageToJson(this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import 'annotate_class_logic.dart';
|
|||
import 'widget/completed_annotate_item.dart';
|
||||
|
||||
class AnnotateClassPage extends StatefulWidget {
|
||||
const AnnotateClassPage({Key? key}) : super(key: key);
|
||||
const AnnotateClassPage({super.key});
|
||||
|
||||
@override
|
||||
State<AnnotateClassPage> createState() => _AnnotateClassPageState();
|
||||
|
|
@ -25,109 +25,110 @@ class _AnnotateClassPageState extends State<AnnotateClassPage> {
|
|||
Widget build(BuildContext context) {
|
||||
String homeworkId = state.homeworkId.value;
|
||||
return OrientationBuilder(
|
||||
builder: (BuildContext context, Orientation orientation){
|
||||
return Scaffold(
|
||||
backgroundColor: const Color.fromRGBO(245, 245, 245, 1),
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
title: Obx(() {
|
||||
return Text(state.name.value, style: TextStyle(fontSize: 14.sp, color: const Color(0xFF333333)));
|
||||
}),
|
||||
centerTitle: true,
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back_ios, color: Colors.black),
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
builder: (BuildContext context, Orientation orientation) {
|
||||
return Scaffold(
|
||||
backgroundColor: const Color.fromRGBO(245, 245, 245, 1),
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
title: Obx(() {
|
||||
return Text(state.name.value,
|
||||
style:
|
||||
TextStyle(fontSize: 14.sp, color: const Color(0xFF333333)));
|
||||
}),
|
||||
centerTitle: true,
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back_ios, color: Colors.black),
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
),
|
||||
actions: const [
|
||||
ReturnToHomepage(),
|
||||
],
|
||||
),
|
||||
body: Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 14.r, horizontal: 14.r),
|
||||
child: Obx(() {
|
||||
return EasyRefresh(
|
||||
firstRefresh: false,
|
||||
taskIndependence: true,
|
||||
controller: logic.refreshController,
|
||||
header: MaterialHeader(),
|
||||
footer: TaurusFooter(),
|
||||
onRefresh: () async {
|
||||
return logic.getList();
|
||||
},
|
||||
),
|
||||
actions: const [
|
||||
ReturnToHomepage(),
|
||||
],
|
||||
),
|
||||
body: Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 14.r, horizontal: 14.r),
|
||||
child: Obx(() {
|
||||
return EasyRefresh(
|
||||
firstRefresh: false,
|
||||
taskIndependence: true,
|
||||
controller: logic.refreshController,
|
||||
header: MaterialHeader(),
|
||||
footer: TaurusFooter(),
|
||||
onRefresh: () async{
|
||||
return logic.getList();
|
||||
},
|
||||
child: state.completed.value
|
||||
? Utils.isPad()
|
||||
child: state.completed.value
|
||||
? Utils.isPad()
|
||||
? GridView(
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2, //横轴三个子widget
|
||||
mainAxisSpacing: 10.h,
|
||||
crossAxisSpacing: 6.w,
|
||||
childAspectRatio: 1.48 //宽高比为1时,子widget
|
||||
),
|
||||
children: state.classList.map((taskItem) {
|
||||
return CompletedAnnotateItem(
|
||||
taskItem: taskItem,
|
||||
logic: logic,
|
||||
name: state.name.value,
|
||||
);
|
||||
}).toList(),
|
||||
)
|
||||
gridDelegate:
|
||||
SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2, //横轴三个子widget
|
||||
mainAxisSpacing: 10.h,
|
||||
crossAxisSpacing: 6.w,
|
||||
childAspectRatio: 1.48 //宽高比为1时,子widget
|
||||
),
|
||||
children: state.classList.map((taskItem) {
|
||||
return CompletedAnnotateItem(
|
||||
taskItem: taskItem,
|
||||
logic: logic,
|
||||
name: state.name.value,
|
||||
);
|
||||
}).toList(),
|
||||
)
|
||||
: ListView.builder(
|
||||
itemCount: state.classList.length,
|
||||
itemBuilder: (context, index) {
|
||||
AnnotatedClass taskItem = state.classList[index];
|
||||
return CompletedAnnotateItem(
|
||||
taskItem: taskItem,
|
||||
logic: logic,
|
||||
name: state.name.value,
|
||||
);
|
||||
})
|
||||
: Utils.isPad()
|
||||
itemCount: state.classList.length,
|
||||
itemBuilder: (context, index) {
|
||||
AnnotatedClass taskItem = state.classList[index];
|
||||
return CompletedAnnotateItem(
|
||||
taskItem: taskItem,
|
||||
logic: logic,
|
||||
name: state.name.value,
|
||||
);
|
||||
})
|
||||
: Utils.isPad()
|
||||
? MasonryGridView.count(
|
||||
crossAxisCount: 2, //几列
|
||||
mainAxisSpacing: 4.w, // 间距
|
||||
crossAxisSpacing: 4.h, // 纵向间距?
|
||||
itemCount: state.classList.length,
|
||||
itemBuilder: (context, index) {
|
||||
AnnotatedClass item = state.classList[index];
|
||||
return AnnotateItem(
|
||||
homeworkId: homeworkId,
|
||||
item: item,
|
||||
font: 11.sp,
|
||||
name: state.name.value,
|
||||
logic: logic,
|
||||
);
|
||||
},
|
||||
)
|
||||
crossAxisCount: 2, //几列
|
||||
mainAxisSpacing: 4.w, // 间距
|
||||
crossAxisSpacing: 4.h, // 纵向间距?
|
||||
itemCount: state.classList.length,
|
||||
itemBuilder: (context, index) {
|
||||
AnnotatedClass item = state.classList[index];
|
||||
return AnnotateItem(
|
||||
homeworkId: homeworkId,
|
||||
item: item,
|
||||
font: 11.sp,
|
||||
name: state.name.value,
|
||||
logic: logic,
|
||||
);
|
||||
},
|
||||
)
|
||||
: ListView.builder(
|
||||
itemCount: state.classList.length,
|
||||
itemBuilder: (context, index) {
|
||||
AnnotatedClass item = state.classList[index];
|
||||
return AnnotateItem(
|
||||
homeworkId: homeworkId,
|
||||
item: item,
|
||||
font: 12.sp,
|
||||
name: state.name.value,
|
||||
logic: logic,
|
||||
);
|
||||
}));
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
);
|
||||
itemCount: state.classList.length,
|
||||
itemBuilder: (context, index) {
|
||||
AnnotatedClass item = state.classList[index];
|
||||
return AnnotateItem(
|
||||
homeworkId: homeworkId,
|
||||
item: item,
|
||||
font: 12.sp,
|
||||
name: state.name.value,
|
||||
logic: logic,
|
||||
);
|
||||
}));
|
||||
}),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
Get.delete<AnnotateClassLogic>();
|
||||
super.dispose();
|
||||
if(state.preIndex != 3){
|
||||
if (state.preIndex != 3) {
|
||||
// logic.readOverController.state.tabIndex.value = state.preIndex;
|
||||
}else{
|
||||
} else {
|
||||
// logic.homeController.getList();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
|
|
@ -32,13 +31,21 @@ class AnswerHandwriting extends Dialog {
|
|||
final String? questionNo;
|
||||
final Function closeCall;
|
||||
AnswerHandwriting(
|
||||
{super.key, required this.homeworkId, required this.studentId, required this.closeCall, this.templateId, this.pageNum, this.questionNo});
|
||||
{super.key,
|
||||
required this.homeworkId,
|
||||
required this.studentId,
|
||||
required this.closeCall,
|
||||
this.templateId,
|
||||
this.pageNum,
|
||||
this.questionNo});
|
||||
final _handwritingLogic = Get.find<HandwritingLogic>();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return OrientationBuilder(builder: (BuildContext context, Orientation orientation) {
|
||||
return OrientationBuilder(
|
||||
builder: (BuildContext context, Orientation orientation) {
|
||||
var boxHeight = ScreenUtil().screenHeight / 1.168; // 盒子高度
|
||||
var boxWidth = ScreenUtil().screenWidth - (ScreenUtil().scaleWidth < 1.5 ? 40.r : 40.r); // 盒子宽度
|
||||
var boxWidth = ScreenUtil().screenWidth -
|
||||
(ScreenUtil().scaleWidth < 1.5 ? 40.r : 40.r); // 盒子宽度
|
||||
|
||||
return Center(
|
||||
child: Container(
|
||||
|
|
@ -75,7 +82,8 @@ Future<void> showAnswerHandwriting(
|
|||
}
|
||||
|
||||
Get.put(HandwritingLogic(backCall));
|
||||
Get.find<HandwritingLogic>().params.value = OriginalManuscriptHandwritingParams(
|
||||
Get.find<HandwritingLogic>().params.value =
|
||||
OriginalManuscriptHandwritingParams(
|
||||
homeworkId: homeworkId,
|
||||
studentId: studentId,
|
||||
templateId: templateId,
|
||||
|
|
@ -123,10 +131,12 @@ class AnswerHandwritingMainBox extends HookWidget with EventBusMixin {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var _useStateModel = UseMainBoxState.use(homeworkId, studentId, pageNum, questionNo, templateId);
|
||||
var _useStateModel = UseMainBoxState.use(
|
||||
homeworkId, studentId, pageNum, questionNo, templateId);
|
||||
double barHeight = 62.h;
|
||||
double imageHeight = boxHeight - barHeight;
|
||||
useValueChanged<JobHandwriting?, void>(_useStateModel.handwritingData.value, (_, __) {
|
||||
useValueChanged<JobHandwriting?, void>(_useStateModel.handwritingData.value,
|
||||
(_, __) {
|
||||
var theData = _useStateModel.handwritingData.value;
|
||||
_useStateModel.pageNum.value = theData?.pageNum;
|
||||
_useStateModel.pageCount.value = theData?.pageCount ?? 0;
|
||||
|
|
@ -210,7 +220,8 @@ class UseMainBoxState with RequestToolMixin {
|
|||
});
|
||||
|
||||
// 工厂构造函数
|
||||
factory UseMainBoxState.use(String homeworkId, int studentId, [int? pageNum, String? questionNo, int? templateId]) {
|
||||
factory UseMainBoxState.use(String homeworkId, int studentId,
|
||||
[int? pageNum, String? questionNo, int? templateId]) {
|
||||
return UseMainBoxState._(
|
||||
homeworkId: homeworkId,
|
||||
templateId: templateId,
|
||||
|
|
@ -236,7 +247,8 @@ class PreviousNutton extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Obx(() {
|
||||
if (handwritingLogic.resultData.value?.pageNum != null && handwritingLogic.resultData.value!.pageNum > 1) {
|
||||
if (handwritingLogic.resultData.value?.pageNum != null &&
|
||||
handwritingLogic.resultData.value!.pageNum > 1) {
|
||||
return Positioned(
|
||||
left: 3.w,
|
||||
child: FloatingActionButton(
|
||||
|
|
@ -252,7 +264,8 @@ class PreviousNutton extends StatelessWidget {
|
|||
params.pageNum = resultData.pageNum - 1;
|
||||
params.templateId = null;
|
||||
params.questionNo = null;
|
||||
handwritingLogic.params.value = OriginalManuscriptHandwritingParams.fromJson(params.toJson());
|
||||
handwritingLogic.params.value =
|
||||
OriginalManuscriptHandwritingParams.fromJson(params.toJson());
|
||||
// handwritingLogic.params.value = params;
|
||||
}),
|
||||
child: Icon(Icons.arrow_back_ios, color: Colors.white, size: 22.sp),
|
||||
|
|
@ -275,7 +288,8 @@ class NextPageButton extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return Obx(() {
|
||||
if (handwritingLogic.resultData.value?.pageNum != null &&
|
||||
handwritingLogic.resultData.value!.pageNum < handwritingLogic.resultData.value!.pageCount) {
|
||||
handwritingLogic.resultData.value!.pageNum <
|
||||
handwritingLogic.resultData.value!.pageCount) {
|
||||
return Positioned(
|
||||
right: 3.w,
|
||||
child: FloatingActionButton(
|
||||
|
|
@ -290,9 +304,11 @@ class NextPageButton extends StatelessWidget {
|
|||
params.pageNum = resultData.pageNum + 1;
|
||||
params.templateId = null;
|
||||
params.questionNo = null;
|
||||
handwritingLogic.params.value = OriginalManuscriptHandwritingParams.fromJson(params.toJson());
|
||||
handwritingLogic.params.value =
|
||||
OriginalManuscriptHandwritingParams.fromJson(params.toJson());
|
||||
}),
|
||||
child: Icon(Icons.arrow_forward_ios, color: Colors.white, size: 22.sp),
|
||||
child:
|
||||
Icon(Icons.arrow_forward_ios, color: Colors.white, size: 22.sp),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -306,13 +322,15 @@ class NextPageButton extends StatelessWidget {
|
|||
class HandwritingDrawBox extends StatefulWidget {
|
||||
final double boxWidth;
|
||||
final double boxHeight;
|
||||
const HandwritingDrawBox({required this.boxWidth, required this.boxHeight, super.key});
|
||||
const HandwritingDrawBox(
|
||||
{required this.boxWidth, required this.boxHeight, super.key});
|
||||
|
||||
@override
|
||||
State<HandwritingDrawBox> createState() => _HandwritingDrawBoxState();
|
||||
}
|
||||
|
||||
class _HandwritingDrawBoxState extends State<HandwritingDrawBox> with EventBusMixin {
|
||||
class _HandwritingDrawBoxState extends State<HandwritingDrawBox>
|
||||
with EventBusMixin {
|
||||
HandwritingLogic handwritingLogic = Get.find<HandwritingLogic>(); // 学生答题笔迹逻辑层
|
||||
|
||||
ImageStream? imageStream; // 图片监听数据
|
||||
|
|
@ -351,13 +369,16 @@ class _HandwritingDrawBoxState extends State<HandwritingDrawBox> with EventBusMi
|
|||
});
|
||||
|
||||
_vnHandWritings = ValueNotifier<List<GestureHandwritingRecording>>([]);
|
||||
_vnPrimaryHandWritings = ValueNotifier<List<GestureHandwritingRecording>>(_packagedHandwritingDataAll);
|
||||
_vnPrimaryHandWritings = ValueNotifier<List<GestureHandwritingRecording>>(
|
||||
_packagedHandwritingDataAll);
|
||||
|
||||
handwritingLogic.toolbar.initialization.listen((e) {
|
||||
// 数据初始化完成赋值数据
|
||||
if (e) {
|
||||
_packagedHandwritingDatas = handwritingLogic.packagedHandwritingDatas.value;
|
||||
_packagedHandwritingDataAll = handwritingLogic.packagedHandwritingDataAll.value;
|
||||
_packagedHandwritingDatas =
|
||||
handwritingLogic.packagedHandwritingDatas.value;
|
||||
_packagedHandwritingDataAll =
|
||||
handwritingLogic.packagedHandwritingDataAll.value;
|
||||
} else {
|
||||
_packagedHandwritingDatas = [];
|
||||
_packagedHandwritingDataAll = [];
|
||||
|
|
@ -367,7 +388,9 @@ class _HandwritingDrawBoxState extends State<HandwritingDrawBox> with EventBusMi
|
|||
try {
|
||||
_vnPrimaryHandWritings.value = [..._packagedHandwritingDataAll]; // 总体数据
|
||||
} catch (e) {
|
||||
_vnPrimaryHandWritings = ValueNotifier<List<GestureHandwritingRecording>>(_packagedHandwritingDataAll);
|
||||
_vnPrimaryHandWritings =
|
||||
ValueNotifier<List<GestureHandwritingRecording>>(
|
||||
_packagedHandwritingDataAll);
|
||||
}
|
||||
// eventFire(model: JobHandwritingPlaybarBus);
|
||||
});
|
||||
|
|
@ -421,7 +444,8 @@ class _HandwritingDrawBoxState extends State<HandwritingDrawBox> with EventBusMi
|
|||
// 播放速度
|
||||
var _model = (e as PlaybackSpeedBus);
|
||||
speed = _model.speed;
|
||||
dragProgressBarInitData(handwritingDuration - handwritingTime, handwritingDuration);
|
||||
dragProgressBarInitData(
|
||||
handwritingDuration - handwritingTime, handwritingDuration);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
|
@ -446,14 +470,18 @@ class _HandwritingDrawBoxState extends State<HandwritingDrawBox> with EventBusMi
|
|||
});
|
||||
timers = [];
|
||||
// 总时间-剩余时间=已经执行时间
|
||||
if (recalculate && pendingData.isNotEmpty && handwritingTime > 0 && (handwritingDuration - handwritingTime > 0)) {
|
||||
if (recalculate &&
|
||||
pendingData.isNotEmpty &&
|
||||
handwritingTime > 0 &&
|
||||
(handwritingDuration - handwritingTime > 0)) {
|
||||
// 待执行的数据不等于空 每个数据都需要减去当前暂停已经执行的时间
|
||||
pendingData = pendingData.map((e) {
|
||||
return GestureHandwritingRecording(
|
||||
stroke: e.stroke,
|
||||
data: e.data,
|
||||
usageTime: e.usageTime,
|
||||
intervalTime: e.intervalTime - (handwritingDuration - handwritingTime) * 1000,
|
||||
intervalTime:
|
||||
e.intervalTime - (handwritingDuration - handwritingTime) * 1000,
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
|
|
@ -473,7 +501,8 @@ class _HandwritingDrawBoxState extends State<HandwritingDrawBox> with EventBusMi
|
|||
}
|
||||
handwritingLogic.toolbar.showManuscript.value = false;
|
||||
executableData.forEach((e) {
|
||||
var ter = Timer(Duration(milliseconds: e.intervalTime ~/ speed), () => zhixinCall(e));
|
||||
var ter = Timer(Duration(milliseconds: e.intervalTime ~/ speed),
|
||||
() => zhixinCall(e));
|
||||
timers.add(ter);
|
||||
});
|
||||
} catch (e) {
|
||||
|
|
@ -483,7 +512,8 @@ class _HandwritingDrawBoxState extends State<HandwritingDrawBox> with EventBusMi
|
|||
|
||||
Future<void> zhixinCall(GestureHandwritingRecording e) async {
|
||||
if (mounted) {
|
||||
List<GestureHandwritingRecording> trajectorys = handwritingLogic.toolbar.executionData.value..add(e);
|
||||
List<GestureHandwritingRecording> trajectorys =
|
||||
handwritingLogic.toolbar.executionData.value..add(e);
|
||||
handwritingLogic.toolbar.executionData.value = List.from(trajectorys);
|
||||
pendingData.remove(e); // 执行后删除容器中的当前动作
|
||||
}
|
||||
|
|
@ -539,20 +569,26 @@ class _HandwritingDrawBoxState extends State<HandwritingDrawBox> with EventBusMi
|
|||
var paperPicture = handwritingLogic.resultData.value?.paperPicture;
|
||||
if (paperPicture == null) return const SizedBox();
|
||||
|
||||
print('显示原稿:${handwritingLogic.toolbar.showManuscript.value} 数据:${_vnPrimaryHandWritings.value.length}');
|
||||
print(
|
||||
'显示原稿:${handwritingLogic.toolbar.showManuscript.value} 数据:${_vnPrimaryHandWritings.value.length}');
|
||||
return RepaintBoundary(
|
||||
child: CustomPaint(
|
||||
foregroundPainter: HandWritingDrawingPainter(
|
||||
ctrl: handwritingLogic.toolbar.showManuscript.value ? _vnPrimaryHandWritings : _vnHandWritings,
|
||||
ctrl: handwritingLogic.toolbar.showManuscript.value
|
||||
? _vnPrimaryHandWritings
|
||||
: _vnHandWritings,
|
||||
),
|
||||
child: $TheCachedNetworkImage(
|
||||
imageUrl: paperPicture,
|
||||
(context, imageProvider) {
|
||||
Image imageWidget = Image(image: imageProvider, fit: BoxFit.contain);
|
||||
Image imageWidget =
|
||||
Image(image: imageProvider, fit: BoxFit.contain);
|
||||
var imagInfoModel = handwritingLogic.imagInfoModel.value;
|
||||
if (imagInfoModel == null || imagInfoModel.boxWidth != widget.boxWidth) {
|
||||
if (imagInfoModel == null ||
|
||||
imagInfoModel.boxWidth != widget.boxWidth) {
|
||||
imageStream?.removeListener(theImageStreamListener);
|
||||
imageStream = imageWidget.image.resolve(const ImageConfiguration());
|
||||
imageStream =
|
||||
imageWidget.image.resolve(const ImageConfiguration());
|
||||
imageStream?.addListener(theImageStreamListener);
|
||||
}
|
||||
return imageWidget;
|
||||
|
|
@ -590,7 +626,8 @@ class HandWritingDrawingPainter extends CustomPainter {
|
|||
var _length = points.length;
|
||||
for (int i = 0; i < _length; i++) {
|
||||
GestureHandwritingRecording item = points[i];
|
||||
GestureHandwritingRecording? nextItem = i + 1 < _length ? points[i + 1] : null;
|
||||
GestureHandwritingRecording? nextItem =
|
||||
i + 1 < _length ? points[i + 1] : null;
|
||||
|
||||
Offset offsetData = item.data;
|
||||
Offset? nextOffsetData = nextItem?.data;
|
||||
|
|
@ -604,7 +641,8 @@ class HandWritingDrawingPainter extends CustomPainter {
|
|||
@override
|
||||
bool shouldRepaint(covariant CustomPainter oldDelegate) {
|
||||
if (oldDelegate is HandWritingDrawingPainter) {
|
||||
var repaint = ctrl.value.length != oldDelegate.ctrl.value.length || oldDelegate.ctrl.value != ctrl.value;
|
||||
var repaint = ctrl.value.length != oldDelegate.ctrl.value.length ||
|
||||
oldDelegate.ctrl.value != ctrl.value;
|
||||
print('调用是否绘制:$repaint');
|
||||
return repaint;
|
||||
}
|
||||
|
|
@ -616,7 +654,8 @@ class HandWritingDrawingPainter extends CustomPainter {
|
|||
class PageNumberBox extends StatelessWidget {
|
||||
PageNumberBox({super.key});
|
||||
|
||||
final HandwritingLogic handwritingLogic = Get.find<HandwritingLogic>(); // 学生答题笔迹逻辑层
|
||||
final HandwritingLogic handwritingLogic =
|
||||
Get.find<HandwritingLogic>(); // 学生答题笔迹逻辑层
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -634,11 +673,20 @@ class PageNumberBox extends StatelessWidget {
|
|||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Obx(() {
|
||||
return quickText('${handwritingLogic.resultData.value?.pageNum ?? 0}', color: Colors.white, size: 11.sp, align: TextAlign.end);
|
||||
return quickText(
|
||||
'${handwritingLogic.resultData.value?.pageNum ?? 0}',
|
||||
color: Colors.white,
|
||||
size: 11.sp,
|
||||
align: TextAlign.end);
|
||||
}),
|
||||
quickText('/', color: Colors.white, size: 10.sp, align: TextAlign.end),
|
||||
quickText('/',
|
||||
color: Colors.white, size: 10.sp, align: TextAlign.end),
|
||||
Obx(() {
|
||||
return quickText('${handwritingLogic.resultData.value?.pageCount ?? 0}', color: Colors.white, size: 8.sp, align: TextAlign.end);
|
||||
return quickText(
|
||||
'${handwritingLogic.resultData.value?.pageCount ?? 0}',
|
||||
color: Colors.white,
|
||||
size: 8.sp,
|
||||
align: TextAlign.end);
|
||||
}),
|
||||
],
|
||||
)),
|
||||
|
|
@ -647,7 +695,8 @@ class PageNumberBox extends StatelessWidget {
|
|||
}
|
||||
|
||||
@hwidget
|
||||
Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic handwritingLogic) {
|
||||
Widget $bottomPlaybar(
|
||||
BuildContext context, double barHeight, HandwritingLogic handwritingLogic) {
|
||||
var timeConsuming = useState(0);
|
||||
var handwritingInfo = useState<HandwritingInfo?>(null);
|
||||
|
||||
|
|
@ -665,8 +714,10 @@ Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic h
|
|||
usePlaybar.useTime.value = usePlaybar.handwritingDuration.value;
|
||||
});
|
||||
// 播放速度
|
||||
useValueChanged<PlaybackSpeed, void>(usePlaybar.constantFastSpeed.value, (_, __) {
|
||||
usePlaybar.eventFire(model: PlaybackSpeedBus(usePlaybar.constantFastSpeed.value.speed));
|
||||
useValueChanged<PlaybackSpeed, void>(usePlaybar.constantFastSpeed.value,
|
||||
(_, __) {
|
||||
usePlaybar.eventFire(
|
||||
model: PlaybackSpeedBus(usePlaybar.constantFastSpeed.value.speed));
|
||||
// 播放速度变化
|
||||
usePlaybar.playTimingSuspend();
|
||||
usePlaybar.playTimingStarts();
|
||||
|
|
@ -675,9 +726,12 @@ Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic h
|
|||
useValueChanged<int, void>(usePlaybar.useTime.value, (_, __) {
|
||||
var _runtime = usePlaybar.useTime.value;
|
||||
if (_runtime <= 0 || usePlaybar.handwritingDuration.value == _runtime) {
|
||||
Future.delayed(Duration.zero, () => (usePlaybar.playPause.value = false)); // 初始化播放按钮
|
||||
Future.delayed(
|
||||
Duration.zero, () => (usePlaybar.playPause.value = false)); // 初始化播放按钮
|
||||
}
|
||||
usePlaybar.eventFire(model: JobHandwritingRunTimeBus(_runtime, usePlaybar.handwritingDuration.value));
|
||||
usePlaybar.eventFire(
|
||||
model: JobHandwritingRunTimeBus(
|
||||
_runtime, usePlaybar.handwritingDuration.value));
|
||||
});
|
||||
|
||||
useEffect(() {
|
||||
|
|
@ -708,7 +762,8 @@ Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic h
|
|||
break;
|
||||
case JobHandwritingGetReadyBus:
|
||||
// 作业笔迹已经计算好坐标 可以开始播放
|
||||
Future.delayed(Duration.zero, () => (usePlaybar.handWritingReady.value = true));
|
||||
Future.delayed(
|
||||
Duration.zero, () => (usePlaybar.handWritingReady.value = true));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
|
@ -737,13 +792,17 @@ Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic h
|
|||
if (usePlaybar.handWritingReady.value)
|
||||
InkWell(
|
||||
onTap: () => easyThrottle('job_handwriting_play_pause', () {
|
||||
if (usePlaybar.handwritingDuration.value == 0) return ToastUtils.showInfo('没有笔迹');
|
||||
if (usePlaybar.handwritingDuration.value == 0)
|
||||
return ToastUtils.showInfo('没有笔迹');
|
||||
|
||||
usePlaybar.playPause.value = !usePlaybar.playPause.value;
|
||||
usePlaybar.eventFire(model: JobHandwritingPlaybarBus(usePlaybar.playPause.value));
|
||||
usePlaybar.eventFire(
|
||||
model: JobHandwritingPlaybarBus(usePlaybar.playPause.value));
|
||||
}),
|
||||
child: Icon(
|
||||
!usePlaybar.playPause.value ? Icons.play_circle_outline : Icons.pause_circle_outline,
|
||||
!usePlaybar.playPause.value
|
||||
? Icons.play_circle_outline
|
||||
: Icons.pause_circle_outline,
|
||||
color: Colors.white,
|
||||
size: 28.r,
|
||||
),
|
||||
|
|
@ -755,28 +814,36 @@ Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic h
|
|||
child: LayoutBuilder(builder: (context, constraints) {
|
||||
final double containerWidth = constraints.maxWidth; // 展示区域总宽度
|
||||
var unitScale = containerWidth / timeConsuming.value; // 单位刻度
|
||||
var pauseIntervalsLength = handwritingInfo.value?.pauseInterval.length ?? 0;
|
||||
var pauseIntervalsLength =
|
||||
handwritingInfo.value?.pauseInterval.length ?? 0;
|
||||
|
||||
List<Widget> pauseTickMarks = handwritingInfo.value?.pauseInterval.asMap().keys.map((e) {
|
||||
bool isLast = e == pauseIntervalsLength - 1;
|
||||
bool isFirst = e == 0;
|
||||
var item = handwritingInfo.value!.pauseInterval[e];
|
||||
return Positioned(
|
||||
top: 0,
|
||||
left: unitScale * item.startTime,
|
||||
child: Container(
|
||||
width: unitScale * (item.apart ?? 0),
|
||||
height: 10.h,
|
||||
decoration: BoxDecoration(
|
||||
color: Color.fromRGBO(202, 201, 201, 1),
|
||||
borderRadius: isFirst
|
||||
? BorderRadius.only(topLeft: Radius.circular(8.r), bottomLeft: Radius.circular(10.r))
|
||||
: (isLast ? BorderRadius.only(topRight: Radius.circular(8.r), bottomRight: Radius.circular(10.r)) : null),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList() ??
|
||||
[];
|
||||
List<Widget> pauseTickMarks =
|
||||
handwritingInfo.value?.pauseInterval.asMap().keys.map((e) {
|
||||
bool isLast = e == pauseIntervalsLength - 1;
|
||||
bool isFirst = e == 0;
|
||||
var item = handwritingInfo.value!.pauseInterval[e];
|
||||
return Positioned(
|
||||
top: 0,
|
||||
left: unitScale * item.startTime,
|
||||
child: Container(
|
||||
width: unitScale * (item.apart ?? 0),
|
||||
height: 10.h,
|
||||
decoration: BoxDecoration(
|
||||
color: Color.fromRGBO(202, 201, 201, 1),
|
||||
borderRadius: isFirst
|
||||
? BorderRadius.only(
|
||||
topLeft: Radius.circular(8.r),
|
||||
bottomLeft: Radius.circular(10.r))
|
||||
: (isLast
|
||||
? BorderRadius.only(
|
||||
topRight: Radius.circular(8.r),
|
||||
bottomRight: Radius.circular(10.r))
|
||||
: null),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList() ??
|
||||
[];
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
|
@ -800,29 +867,42 @@ Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic h
|
|||
child: SliderTheme(
|
||||
data: SliderTheme.of(context).copyWith(
|
||||
trackHeight: 10.h, // 轨道高度
|
||||
trackShape: RoundedRectSliderTrackShape(), // 轨道形状,可以自定义
|
||||
activeTrackColor: Theme.of(context).primaryColor, // 激活的轨道颜色
|
||||
trackShape:
|
||||
RoundedRectSliderTrackShape(), // 轨道形状,可以自定义
|
||||
activeTrackColor:
|
||||
Theme.of(context).primaryColor, // 激活的轨道颜色
|
||||
inactiveTrackColor: Colors.transparent, // 未激活的轨道颜色
|
||||
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 0, disabledThumbRadius: 0),
|
||||
thumbShape: RoundSliderThumbShape(
|
||||
enabledThumbRadius: 0, disabledThumbRadius: 0),
|
||||
thumbColor: Colors.white, // 滑块颜色
|
||||
overlayShape: RoundSliderOverlayShape(overlayRadius: 0),
|
||||
overlayShape:
|
||||
RoundSliderOverlayShape(overlayRadius: 0),
|
||||
overlayColor: Colors.black54, // 滑块外圈颜色
|
||||
// valueIndicatorShape: PaddleSliderValueIndicatorShape(), // 标签形状,可以自定义
|
||||
),
|
||||
child: Slider(
|
||||
value: (usePlaybar.handwritingDuration.value - usePlaybar.useTime.value).toDouble(),
|
||||
value: (usePlaybar.handwritingDuration.value -
|
||||
usePlaybar.useTime.value)
|
||||
.toDouble(),
|
||||
min: 0.0,
|
||||
max: usePlaybar.handwritingDuration.value.toDouble(),
|
||||
inactiveColor: Colors.transparent,
|
||||
onChangeEnd: (value) {
|
||||
if (!usePlaybar.handWritingReady.value) return;
|
||||
usePlaybar.playTimingSuspend(); // 暂停计时器得暂停
|
||||
usePlaybar.eventFire(model: JobHandwritingDragProgressBarBus(value.toInt(), usePlaybar.handwritingDuration.value));
|
||||
usePlaybar.useTime.value = usePlaybar.handwritingDuration.value - value.toInt();
|
||||
usePlaybar.eventFire(
|
||||
model: JobHandwritingDragProgressBarBus(
|
||||
value.toInt(),
|
||||
usePlaybar.handwritingDuration.value));
|
||||
usePlaybar.useTime.value =
|
||||
usePlaybar.handwritingDuration.value -
|
||||
value.toInt();
|
||||
},
|
||||
onChanged: (double value) {
|
||||
if (!usePlaybar.handWritingReady.value) return;
|
||||
usePlaybar.useTime.value = usePlaybar.handwritingDuration.value - value.toInt();
|
||||
usePlaybar.useTime.value =
|
||||
usePlaybar.handwritingDuration.value -
|
||||
value.toInt();
|
||||
},
|
||||
),
|
||||
),
|
||||
|
|
@ -835,8 +915,16 @@ Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic h
|
|||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
quickText('累计停顿:${handwritingInfo.value?.pauseCount ?? 0}次', color: Colors.white, size: 7.sp),
|
||||
quickText(convertSeconds(usePlaybar.useTime.value)?.toString() ?? '', color: Colors.white, size: 7.sp),
|
||||
quickText(
|
||||
'累计停顿:${handwritingInfo.value?.pauseCount ?? 0}次',
|
||||
color: Colors.white,
|
||||
size: 7.sp),
|
||||
quickText(
|
||||
convertSeconds(usePlaybar.useTime.value)
|
||||
?.toString() ??
|
||||
'',
|
||||
color: Colors.white,
|
||||
size: 7.sp),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
|
@ -851,16 +939,20 @@ Widget $bottomPlaybar(BuildContext context, double barHeight, HandwritingLogic h
|
|||
children: [
|
||||
InkWell(
|
||||
onTap: () => easyThrottle('job_handwriting_speed', () {
|
||||
var theIndex = PlaybackSpeed.values.indexOf(usePlaybar.constantFastSpeed.value);
|
||||
var theIndex = PlaybackSpeed.values
|
||||
.indexOf(usePlaybar.constantFastSpeed.value);
|
||||
if (theIndex == PlaybackSpeed.values.length - 1) {
|
||||
theIndex = -1;
|
||||
}
|
||||
usePlaybar.constantFastSpeed.value = PlaybackSpeed.values[theIndex + 1];
|
||||
usePlaybar.constantFastSpeed.value =
|
||||
PlaybackSpeed.values[theIndex + 1];
|
||||
}, duration: Duration(milliseconds: 500)),
|
||||
child: Container(
|
||||
// alignment: Alignment.,
|
||||
padding: EdgeInsets.symmetric(horizontal: 3.w, vertical: 1.5.h),
|
||||
decoration: BoxDecoration(color: Color.fromRGBO(182, 197, 250, 1), borderRadius: BorderRadius.circular(4.r)),
|
||||
decoration: BoxDecoration(
|
||||
color: Color.fromRGBO(182, 197, 250, 1),
|
||||
borderRadius: BorderRadius.circular(4.r)),
|
||||
child: quickText(
|
||||
'${usePlaybar.constantFastSpeed.value.name}',
|
||||
color: Color.fromRGBO(79, 114, 244, 1),
|
||||
|
|
@ -895,9 +987,12 @@ class StudentManuscriptBtn extends StatelessWidget {
|
|||
padding: EdgeInsets.symmetric(horizontal: 3.w, vertical: 1.5.h),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(4.r),
|
||||
color: handwritingLogic.toolbar.showManuscript.value ? Theme.of(context).primaryColor : Colors.grey,
|
||||
color: handwritingLogic.toolbar.showManuscript.value
|
||||
? Theme.of(context).primaryColor
|
||||
: Colors.grey,
|
||||
),
|
||||
child: quickText('学生原稿', color: Colors.white, size: 8.sp, align: TextAlign.center),
|
||||
child: quickText('学生原稿',
|
||||
color: Colors.white, size: 8.sp, align: TextAlign.center),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
|
@ -911,7 +1006,8 @@ class SysjTime extends StatefulWidget {
|
|||
State<SysjTime> createState() => _SysjTimeState();
|
||||
}
|
||||
|
||||
class _SysjTimeState extends State<SysjTime> with EventBusMixin<JobHandwritingRunTimeBus> {
|
||||
class _SysjTimeState extends State<SysjTime>
|
||||
with EventBusMixin<JobHandwritingRunTimeBus> {
|
||||
int useTime = 0;
|
||||
@override
|
||||
void initState() {
|
||||
|
|
@ -930,7 +1026,8 @@ class _SysjTimeState extends State<SysjTime> with EventBusMixin<JobHandwritingRu
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return quickText(convertSeconds(useTime)?.toString() ?? '', color: Colors.white, size: 7.sp);
|
||||
return quickText(convertSeconds(useTime)?.toString() ?? '',
|
||||
color: Colors.white, size: 7.sp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -971,7 +1068,9 @@ class UseBottomPlaybar with EventBusMixin {
|
|||
if (useTime.value > 0) {
|
||||
timer.value?.cancel();
|
||||
|
||||
timer.value = Timer.periodic(Duration(milliseconds: 1000 ~/ constantFastSpeed.value.speed), (theTime) {
|
||||
timer.value = Timer.periodic(
|
||||
Duration(milliseconds: 1000 ~/ constantFastSpeed.value.speed),
|
||||
(theTime) {
|
||||
useTime.value -= 1;
|
||||
if (useTime.value < 0) {
|
||||
theTime.cancel();
|
||||
|
|
|
|||
|
|
@ -41,13 +41,15 @@ class _QuestionPaperViewState extends State<QuestionPaperView> {
|
|||
// 试题图片视图
|
||||
Expanded(
|
||||
flex: 7,
|
||||
child: LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
|
||||
child: LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
var maxWidth = constraints.maxWidth;
|
||||
var maxHeight = constraints.maxHeight;
|
||||
return Stack(
|
||||
children: [
|
||||
// 主图
|
||||
QuestionImageView(maxWidth, maxHeight, sateData, annotationState, logic),
|
||||
QuestionImageView(
|
||||
maxWidth, maxHeight, sateData, annotationState, logic),
|
||||
// 继续批阅按钮
|
||||
// Positioned(right: 3.w, bottom: 4.h, child: const $ContinueToReview(isFloatingAction: true)),
|
||||
// 上一题按钮
|
||||
|
|
@ -61,15 +63,19 @@ class _QuestionPaperViewState extends State<QuestionPaperView> {
|
|||
heroTag: '点击前往上一题',
|
||||
tooltip: '点击前往上一题',
|
||||
focusColor: Theme.of(context).primaryColor,
|
||||
backgroundColor: const Color.fromRGBO(24, 32, 32, 0.05),
|
||||
backgroundColor:
|
||||
const Color.fromRGBO(24, 32, 32, 0.05),
|
||||
elevation: 10.r,
|
||||
onPressed: () => easyThrottle('TestQuestionSwitch', () {
|
||||
onPressed: () =>
|
||||
easyThrottle('TestQuestionSwitch', () {
|
||||
var param = sateData.param.value;
|
||||
param.studentId = lastPageVal.studentId;
|
||||
param.templateId = lastPageVal.templateId;
|
||||
sateData.param.value = DoPaperDetailsParam.fromJson(param.toJson());
|
||||
sateData.param.value =
|
||||
DoPaperDetailsParam.fromJson(param.toJson());
|
||||
}),
|
||||
child: Icon(Icons.arrow_back_ios, color: Colors.white, size: 22.sp),
|
||||
child: Icon(Icons.arrow_back_ios,
|
||||
color: Colors.white, size: 22.sp),
|
||||
);
|
||||
}),
|
||||
),
|
||||
|
|
@ -84,14 +90,18 @@ class _QuestionPaperViewState extends State<QuestionPaperView> {
|
|||
heroTag: '点击前往下一题',
|
||||
tooltip: '点击前往下一题',
|
||||
elevation: 10.r,
|
||||
backgroundColor: const Color.fromRGBO(24, 32, 32, 0.05),
|
||||
onPressed: () => easyThrottle('TestQuestionSwitch', () {
|
||||
backgroundColor:
|
||||
const Color.fromRGBO(24, 32, 32, 0.05),
|
||||
onPressed: () =>
|
||||
easyThrottle('TestQuestionSwitch', () {
|
||||
var param = sateData.param.value;
|
||||
param.studentId = nextPageVal.studentId;
|
||||
param.templateId = nextPageVal.templateId;
|
||||
sateData.param.value = DoPaperDetailsParam.fromJson(param.toJson());
|
||||
sateData.param.value =
|
||||
DoPaperDetailsParam.fromJson(param.toJson());
|
||||
}),
|
||||
child: Icon(Icons.arrow_forward_ios, color: Colors.white, size: 22.sp),
|
||||
child: Icon(Icons.arrow_forward_ios,
|
||||
color: Colors.white, size: 22.sp),
|
||||
);
|
||||
}),
|
||||
),
|
||||
|
|
@ -112,7 +122,8 @@ class _QuestionPaperViewState extends State<QuestionPaperView> {
|
|||
child: CupertinoButton(
|
||||
color: Colors.grey[300],
|
||||
onPressed: () => easyThrottle('home_work_reload_data', () {
|
||||
sateData.param.value = DoPaperDetailsParam.fromJson(sateData.param.value.toJson());
|
||||
sateData.param.value =
|
||||
DoPaperDetailsParam.fromJson(sateData.param.value.toJson());
|
||||
}),
|
||||
child: quickText('重新请求', color: Colors.black38),
|
||||
),
|
||||
|
|
@ -125,7 +136,8 @@ class _QuestionPaperViewState extends State<QuestionPaperView> {
|
|||
|
||||
// 底部已阅数量和待阅数量
|
||||
@swidget
|
||||
Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData) {
|
||||
Widget $totalSubmitCountView(
|
||||
BuildContext context, HomeworkReviewState sateData) {
|
||||
return Obx(() {
|
||||
var data = sateData.data.value;
|
||||
if (data == null) return Container();
|
||||
|
|
@ -140,7 +152,10 @@ Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData)
|
|||
context: context,
|
||||
elevation: 10,
|
||||
backgroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.only(topLeft: Radius.circular(10.r), topRight: Radius.circular(10.r))),
|
||||
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),
|
||||
|
|
@ -158,7 +173,8 @@ Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData)
|
|||
SizedBox(height: 10.h),
|
||||
Expanded(
|
||||
child: ListView(
|
||||
padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 4.w),
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 8.h, horizontal: 4.w),
|
||||
children: [
|
||||
Wrap(
|
||||
spacing: 7.2.w, // 主轴(水平)方向间距
|
||||
|
|
@ -169,27 +185,40 @@ Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData)
|
|||
alignment: const FractionalOffset(0.05, 0.09),
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 1.2.h, bottom: 1.5.h, left: 13.w, right: 5.w),
|
||||
padding: EdgeInsets.only(
|
||||
top: 1.2.h,
|
||||
bottom: 1.5.h,
|
||||
left: 13.w,
|
||||
right: 5.w),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(4.r),
|
||||
color: const Color.fromRGBO(239, 242, 255, 1),
|
||||
color: const Color.fromRGBO(
|
||||
239, 242, 255, 1),
|
||||
),
|
||||
child: quickText(
|
||||
e.name,
|
||||
size: 12.sp,
|
||||
wordSpacing: 2,
|
||||
color: const Color.fromRGBO(80, 94, 110, 1),
|
||||
color:
|
||||
const Color.fromRGBO(80, 94, 110, 1),
|
||||
),
|
||||
),
|
||||
Stack(
|
||||
alignment: const FractionalOffset(0.52, 0.24),
|
||||
alignment:
|
||||
const FractionalOffset(0.52, 0.24),
|
||||
children: [
|
||||
Icon(
|
||||
const IconData(0xe63d, fontFamily: "AlibabaIcon"),
|
||||
const IconData(0xe63d,
|
||||
fontFamily: "AlibabaIcon"),
|
||||
size: 12.sp,
|
||||
color: e.isPriority ? const Color.fromRGBO(76, 199, 147, 1) : const Color.fromRGBO(164, 164, 164, 1),
|
||||
color: e.isPriority
|
||||
? const Color.fromRGBO(
|
||||
76, 199, 147, 1)
|
||||
: const Color.fromRGBO(
|
||||
164, 164, 164, 1),
|
||||
),
|
||||
quickText('优先', size: 4.sp, color: Colors.white),
|
||||
quickText('优先',
|
||||
size: 4.sp, color: Colors.white),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
|
@ -211,11 +240,17 @@ Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData)
|
|||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 1.h),
|
||||
child: quickText('已阅', color: const Color.fromRGBO(117, 117, 117, 1), size: 10.sp),
|
||||
child: quickText('已阅',
|
||||
color: const Color.fromRGBO(117, 117, 117, 1), size: 10.sp),
|
||||
),
|
||||
quickText(data.annotatedCount, color: const Color.fromRGBO(76, 199, 147, 1), size: 12.sp, fontWeight: FontWeight.bold),
|
||||
quickText('/', color: const Color.fromRGBO(117, 117, 117, 1), size: 12.sp),
|
||||
quickText(data.submitCount - data.annotatedCount, color: const Color.fromRGBO(117, 117, 117, 1), size: 10.sp),
|
||||
quickText(data.annotatedCount,
|
||||
color: const Color.fromRGBO(76, 199, 147, 1),
|
||||
size: 12.sp,
|
||||
fontWeight: FontWeight.bold),
|
||||
quickText('/',
|
||||
color: const Color.fromRGBO(117, 117, 117, 1), size: 12.sp),
|
||||
quickText(data.submitCount - data.annotatedCount,
|
||||
color: const Color.fromRGBO(117, 117, 117, 1), size: 10.sp),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
@ -225,15 +260,18 @@ Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData)
|
|||
|
||||
// 试题题号视图
|
||||
@hwidget
|
||||
Widget $questionNumberView(BuildContext context, HomeworkReviewLogic logic, HomeworkReviewState sateData) {
|
||||
Widget $questionNumberView(BuildContext context, HomeworkReviewLogic logic,
|
||||
HomeworkReviewState sateData) {
|
||||
final scrollControllerNum = useScrollController(); // 试题题号区域
|
||||
|
||||
useEffect(() {
|
||||
scrollControllerNum.addListener(() {
|
||||
if (sateData.panQuestView == false) sateData.slide.value = scrollControllerNum.offset;
|
||||
if (sateData.panQuestView == false)
|
||||
sateData.slide.value = scrollControllerNum.offset;
|
||||
});
|
||||
var listenVal = sateData.slide.listen((e) {
|
||||
if (e != scrollControllerNum.offset && sateData.panQuestView == true) scrollControllerNum.jumpTo(e);
|
||||
if (e != scrollControllerNum.offset && sateData.panQuestView == true)
|
||||
scrollControllerNum.jumpTo(e);
|
||||
});
|
||||
|
||||
return () {
|
||||
|
|
@ -271,13 +309,20 @@ Widget $questionNumberView(BuildContext context, HomeworkReviewLogic logic, Home
|
|||
|
||||
return Container(
|
||||
height: boxHeight > actualImgHeight ? boxHeight : actualImgHeight,
|
||||
padding: EdgeInsets.only(top: imageVal.remainingHeight > 0 ? imageVal.remainingHeight / 2 : 0),
|
||||
padding: EdgeInsets.only(
|
||||
top: imageVal.remainingHeight > 0
|
||||
? imageVal.remainingHeight / 2
|
||||
: 0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: studentQuestions
|
||||
?.asMap()
|
||||
.keys
|
||||
.map((e) => $ScoringQuestionsView(logic, studentQuestions[e], imageVal.scaleRatio, studentQuestions))
|
||||
.map((e) => $ScoringQuestionsView(
|
||||
logic,
|
||||
studentQuestions[e],
|
||||
imageVal.scaleRatio,
|
||||
studentQuestions))
|
||||
.toList() ??
|
||||
[],
|
||||
),
|
||||
|
|
@ -290,7 +335,11 @@ Widget $questionNumberView(BuildContext context, HomeworkReviewLogic logic, Home
|
|||
// 单道题得分框
|
||||
@hwidget
|
||||
Widget $scoringQuestionsView(
|
||||
BuildContext context, HomeworkReviewLogic logic, StudentQuestions item, double scaleRatio, List<StudentQuestions>? studentQuestions) {
|
||||
BuildContext context,
|
||||
HomeworkReviewLogic logic,
|
||||
StudentQuestions item,
|
||||
double scaleRatio,
|
||||
List<StudentQuestions>? studentQuestions) {
|
||||
var studentScore = useState<int?>(item.studentScore);
|
||||
|
||||
useValueChanged<int?, void>(studentScore.value, (_, __) {
|
||||
|
|
@ -299,7 +348,8 @@ Widget $scoringQuestionsView(
|
|||
// 校验是否自动提交 对于已经批阅过的试题 不重复自动提交
|
||||
var annotateTime = logic.state.data.value?.annotateTime;
|
||||
if (annotateTime == null) {
|
||||
var noRatingGiven = studentQuestions!.firstWhereOrNull((e) => e.studentScore == null);
|
||||
var noRatingGiven =
|
||||
studentQuestions!.firstWhereOrNull((e) => e.studentScore == null);
|
||||
if (noRatingGiven == null) logic.submit(context);
|
||||
}
|
||||
});
|
||||
|
|
@ -312,7 +362,9 @@ Widget $scoringQuestionsView(
|
|||
return () {};
|
||||
}, []);
|
||||
|
||||
var padinVal = item.correctRate > 0 ? EdgeInsets.only(top: 6.4.h) : EdgeInsets.symmetric(vertical: 2.h);
|
||||
var padinVal = item.correctRate > 0
|
||||
? EdgeInsets.only(top: 6.4.h)
|
||||
: EdgeInsets.symmetric(vertical: 2.h);
|
||||
return Container(
|
||||
height: item.height * scaleRatio,
|
||||
padding: EdgeInsets.zero,
|
||||
|
|
@ -328,20 +380,24 @@ Widget $scoringQuestionsView(
|
|||
style: ElevatedButton.styleFrom(
|
||||
padding: EdgeInsets.zero,
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
backgroundColor: const Color.fromRGBO(237, 237, 237, 1), // 设置背景色
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero), // 去除圆角
|
||||
backgroundColor:
|
||||
const Color.fromRGBO(237, 237, 237, 1), // 设置背景色
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.zero), // 去除圆角
|
||||
),
|
||||
child: Padding(
|
||||
padding: padinVal,
|
||||
child: Icon(
|
||||
size: 22.sp,
|
||||
color: studentScore.value == 2 ? const Color.fromRGBO(255, 152, 0, 1) : const Color.fromRGBO(114, 114, 114, 1),
|
||||
color: studentScore.value == 2
|
||||
? const Color.fromRGBO(255, 152, 0, 1)
|
||||
: const Color.fromRGBO(114, 114, 114, 1),
|
||||
const IconData(0xe62b, fontFamily: "AlibabaIcon"),
|
||||
),
|
||||
),
|
||||
onPressed: () => easyThrottle('scoring_homework_questions', () {
|
||||
studentScore.value = studentScore.value == 2 ? null : 2;
|
||||
}),
|
||||
}, duration: const Duration(milliseconds: 222)),
|
||||
),
|
||||
),
|
||||
// 半
|
||||
|
|
@ -350,20 +406,24 @@ Widget $scoringQuestionsView(
|
|||
style: ElevatedButton.styleFrom(
|
||||
padding: EdgeInsets.zero,
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
backgroundColor: const Color.fromRGBO(237, 237, 237, 1), // 设置背景色
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero), // 去除圆角
|
||||
backgroundColor:
|
||||
const Color.fromRGBO(237, 237, 237, 1), // 设置背景色
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.zero), // 去除圆角
|
||||
),
|
||||
child: Padding(
|
||||
padding: padinVal,
|
||||
child: Icon(
|
||||
size: 22.sp,
|
||||
color: studentScore.value == 1 ? const Color.fromRGBO(255, 152, 0, 1) : const Color.fromRGBO(114, 114, 114, 1),
|
||||
color: studentScore.value == 1
|
||||
? const Color.fromRGBO(255, 152, 0, 1)
|
||||
: const Color.fromRGBO(114, 114, 114, 1),
|
||||
const IconData(0xe62c, fontFamily: "AlibabaIcon"),
|
||||
),
|
||||
),
|
||||
onPressed: () => easyThrottle('scoring_homework_questions', () {
|
||||
studentScore.value = studentScore.value == 1 ? null : 1;
|
||||
}),
|
||||
}, duration: const Duration(milliseconds: 222)),
|
||||
),
|
||||
),
|
||||
// 错
|
||||
|
|
@ -372,20 +432,24 @@ Widget $scoringQuestionsView(
|
|||
style: ElevatedButton.styleFrom(
|
||||
padding: EdgeInsets.zero,
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
backgroundColor: const Color.fromRGBO(237, 237, 237, 1), // 设置背景色
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero), // 去除圆角
|
||||
backgroundColor:
|
||||
const Color.fromRGBO(237, 237, 237, 1), // 设置背景色
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.zero), // 去除圆角
|
||||
),
|
||||
child: Padding(
|
||||
padding: padinVal,
|
||||
child: Icon(
|
||||
size: 22.sp,
|
||||
color: studentScore.value == 0 ? const Color.fromRGBO(255, 152, 0, 1) : const Color.fromRGBO(114, 114, 114, 1),
|
||||
color: studentScore.value == 0
|
||||
? const Color.fromRGBO(255, 152, 0, 1)
|
||||
: const Color.fromRGBO(114, 114, 114, 1),
|
||||
const IconData(0xe62a, fontFamily: "AlibabaIcon"),
|
||||
),
|
||||
),
|
||||
onPressed: () => easyThrottle('scoring_homework_questions', () {
|
||||
studentScore.value = studentScore.value == 0 ? null : 0;
|
||||
}),
|
||||
}, duration: const Duration(milliseconds: 222)),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
@ -396,8 +460,11 @@ Widget $scoringQuestionsView(
|
|||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(width: 1.1.w),
|
||||
quickText('${item.questionNo}', color: Theme.of(context).primaryColor.withOpacity(0.7), size: 8.sp),
|
||||
if (item.correctRate > 0) quickText(' 正确率', color: Colors.grey, size: 5.sp),
|
||||
quickText('${item.questionNo}',
|
||||
color: Theme.of(context).primaryColor.withOpacity(0.7),
|
||||
size: 8.sp),
|
||||
if (item.correctRate > 0)
|
||||
quickText(' 正确率', color: Colors.grey, size: 5.sp),
|
||||
if (item.correctRate > 0)
|
||||
Expanded(
|
||||
child: LinearPercentIndicator(
|
||||
|
|
@ -407,7 +474,10 @@ Widget $scoringQuestionsView(
|
|||
alignment: MainAxisAlignment.center,
|
||||
progressColor: const Color.fromRGBO(76, 199, 147, 0.6),
|
||||
backgroundColor: const Color(0xFFB8C7CB).withOpacity(0.35),
|
||||
center: quickText("${item.correctRate}%", size: 5.sp, align: TextAlign.center, color: Colors.white),
|
||||
center: quickText("${item.correctRate}%",
|
||||
size: 5.sp,
|
||||
align: TextAlign.center,
|
||||
color: Colors.white),
|
||||
),
|
||||
)
|
||||
],
|
||||
|
|
@ -419,13 +489,16 @@ Widget $scoringQuestionsView(
|
|||
}
|
||||
|
||||
// 试题图片视图
|
||||
class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar> {
|
||||
class QuestionImageView extends HookWidget
|
||||
with EventBusMixin<BottomOperationBar> {
|
||||
final double maxWidth;
|
||||
final double maxHeight;
|
||||
final HomeworkReviewLogic logic;
|
||||
final HomeworkReviewState sateData;
|
||||
final HomeworkReviewAnnotationsControlState annotationState;
|
||||
QuestionImageView(this.maxWidth, this.maxHeight, this.sateData, this.annotationState, this.logic, {super.key});
|
||||
QuestionImageView(this.maxWidth, this.maxHeight, this.sateData,
|
||||
this.annotationState, this.logic,
|
||||
{super.key});
|
||||
|
||||
/// 获取数组指定倒数具体值的下标
|
||||
int _findTargetIndex<T>(List<T> list, T target, [int reciprocal = 2]) {
|
||||
|
|
@ -456,7 +529,8 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
|
|||
}, []);
|
||||
|
||||
ImageStream? imageStream;
|
||||
var imageStreamListener = useState<ImageStreamListener>(ImageStreamListener((ImageInfo info, bool _) {
|
||||
var imageStreamListener = useState<ImageStreamListener>(
|
||||
ImageStreamListener((ImageInfo info, bool _) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
sateData.imageScale.value = TestQuestionsImageInfo(
|
||||
templateId: sateData.data.value?.templateId,
|
||||
|
|
@ -479,10 +553,17 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
|
|||
bool? res = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context1) {
|
||||
return AlertDialog(content: quickText("是否撤销全部批注痕迹?"), actions: <Widget>[
|
||||
TextButton(child: quickText("取消"), onPressed: () => Navigator.pop(context1, false)),
|
||||
TextButton(child: quickText("确定", color: Theme.of(context).primaryColor), onPressed: () => Navigator.pop(context1, true))
|
||||
]);
|
||||
return AlertDialog(
|
||||
content: quickText("是否撤销全部批注痕迹?"),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: quickText("取消"),
|
||||
onPressed: () => Navigator.pop(context1, false)),
|
||||
TextButton(
|
||||
child: quickText("确定",
|
||||
color: Theme.of(context).primaryColor),
|
||||
onPressed: () => Navigator.pop(context1, true))
|
||||
]);
|
||||
},
|
||||
);
|
||||
if (res == true) vnHandWritings.value = [];
|
||||
|
|
@ -492,17 +573,22 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
|
|||
await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context1) {
|
||||
return AlertDialog(content: quickText("是否撤销上次批阅批注痕迹?"), actions: <Widget>[
|
||||
TextButton(child: quickText("取消"), onPressed: () => Navigator.pop(context1, false)),
|
||||
TextButton(
|
||||
child: quickText("确定", color: Theme.of(context).primaryColor),
|
||||
onPressed: () {
|
||||
Navigator.pop(context1, true);
|
||||
sateData.data.value?.zgtAnnotate = null;
|
||||
sateData.data.value?.showZgtAnnotate = null;
|
||||
},
|
||||
)
|
||||
]);
|
||||
return AlertDialog(
|
||||
content: quickText("是否撤销上次批阅批注痕迹?"),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: quickText("取消"),
|
||||
onPressed: () => Navigator.pop(context1, false)),
|
||||
TextButton(
|
||||
child: quickText("确定",
|
||||
color: Theme.of(context).primaryColor),
|
||||
onPressed: () {
|
||||
Navigator.pop(context1, true);
|
||||
sateData.data.value?.zgtAnnotate = null;
|
||||
sateData.data.value?.showZgtAnnotate = null;
|
||||
},
|
||||
)
|
||||
]);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
@ -517,17 +603,22 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
|
|||
await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context1) {
|
||||
return AlertDialog(content: quickText("是否撤销上次批阅批注痕迹?"), actions: <Widget>[
|
||||
TextButton(child: quickText("取消"), onPressed: () => Navigator.pop(context1, false)),
|
||||
TextButton(
|
||||
child: quickText("确定", color: Theme.of(context).primaryColor),
|
||||
onPressed: () {
|
||||
Navigator.pop(context1, true);
|
||||
sateData.data.value?.zgtAnnotate = null;
|
||||
sateData.data.value?.showZgtAnnotate = null;
|
||||
},
|
||||
)
|
||||
]);
|
||||
return AlertDialog(
|
||||
content: quickText("是否撤销上次批阅批注痕迹?"),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: quickText("取消"),
|
||||
onPressed: () => Navigator.pop(context1, false)),
|
||||
TextButton(
|
||||
child: quickText("确定",
|
||||
color: Theme.of(context).primaryColor),
|
||||
onPressed: () {
|
||||
Navigator.pop(context1, true);
|
||||
sateData.data.value?.zgtAnnotate = null;
|
||||
sateData.data.value?.showZgtAnnotate = null;
|
||||
},
|
||||
)
|
||||
]);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
@ -548,7 +639,8 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
|
|||
}); // 执行滚动相关的逻辑,例如打印滚动位置
|
||||
|
||||
var listenVal = sateData.slide.listen((e) {
|
||||
if (e != scrollControllerQuestion.offset && sateData.panQuestView == false) scrollControllerQuestion.jumpTo(e);
|
||||
if (e != scrollControllerQuestion.offset &&
|
||||
sateData.panQuestView == false) scrollControllerQuestion.jumpTo(e);
|
||||
});
|
||||
|
||||
// 返回一个清理函数,在组件销毁时移除监听
|
||||
|
|
@ -572,12 +664,19 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
|
|||
onPanDown: (_) => sateData.panQuestView = true,
|
||||
child: SingleChildScrollView(
|
||||
controller: scrollControllerQuestion,
|
||||
physics: !annotationState.pen.value ? const BouncingScrollPhysics() : const NeverScrollableScrollPhysics(),
|
||||
physics: !annotationState.pen.value
|
||||
? const BouncingScrollPhysics()
|
||||
: const NeverScrollableScrollPhysics(),
|
||||
padding: EdgeInsets.zero,
|
||||
scrollDirection: Axis.vertical, // 设置垂直滚动
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: [BoxShadow(color: Colors.grey.withOpacity(0.2), offset: Offset(-6.r, 1.r), blurRadius: 10.r, spreadRadius: 8.r)]),
|
||||
decoration: BoxDecoration(boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.2),
|
||||
offset: Offset(-6.r, 1.r),
|
||||
blurRadius: 10.r,
|
||||
spreadRadius: 8.r)
|
||||
]),
|
||||
child: Listener(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onPointerDown: (PointerDownEvent event) {
|
||||
|
|
@ -604,9 +703,11 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
|
|||
if (imageScale == null || !annotationState.pen.value) return;
|
||||
Offset localPosition = event.localPosition;
|
||||
var dy = localPosition.dy;
|
||||
if (dy > imageScale.actualImgHeight || dy < 0) return; // 检查笔记是否超出图片范围
|
||||
if (dy > imageScale.actualImgHeight || dy < 0)
|
||||
return; // 检查笔记是否超出图片范围
|
||||
|
||||
vnHandWritings.value = List.from(vnHandWritings.value)..add(localPosition);
|
||||
vnHandWritings.value = List.from(vnHandWritings.value)
|
||||
..add(localPosition);
|
||||
sateData.handwritings = vnHandWritings.value;
|
||||
},
|
||||
child: Stack(
|
||||
|
|
@ -614,9 +715,12 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
|
|||
$TheCachedNetworkImage(
|
||||
imageUrl: imageUrl,
|
||||
(context, imageProvider) {
|
||||
Image imageWidget = Image(image: imageProvider, fit: BoxFit.fitWidth);
|
||||
Image imageWidget =
|
||||
Image(image: imageProvider, fit: BoxFit.fitWidth);
|
||||
imageStream?.removeListener(imageStreamListener.value);
|
||||
imageStream = imageWidget.image.resolve(const ImageConfiguration())..addListener(imageStreamListener.value);
|
||||
imageStream = imageWidget.image
|
||||
.resolve(const ImageConfiguration())
|
||||
..addListener(imageStreamListener.value);
|
||||
return imageWidget;
|
||||
},
|
||||
),
|
||||
|
|
@ -631,7 +735,8 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
|
|||
child: showZgtAnnotate != null
|
||||
? $TheCachedNetworkImage(
|
||||
imageUrl: showZgtAnnotate,
|
||||
(_, imageProvider) => Image(image: imageProvider, fit: BoxFit.fitWidth),
|
||||
(_, imageProvider) => Image(
|
||||
image: imageProvider, fit: BoxFit.fitWidth),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
|
|
@ -663,7 +768,8 @@ class DrawingPainter extends CustomPainter {
|
|||
for (int i = 0; i < pointsLength; i++) {
|
||||
Offset? offsetData = points[i];
|
||||
Offset? nextOffsetData = pointsLength - 1 == i ? null : points[i + 1];
|
||||
if (offsetData != null && nextOffsetData != null) canvas.drawLine(offsetData, nextOffsetData, paintBrush);
|
||||
if (offsetData != null && nextOffsetData != null)
|
||||
canvas.drawLine(offsetData, nextOffsetData, paintBrush);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
|
|
@ -16,7 +15,6 @@ import 'package:making_school_asignment_app/common/mixins/request_tool_mixin.dar
|
|||
import 'package:making_school_asignment_app/common/utils/toast_utils.dart';
|
||||
import 'package:making_school_asignment_app/common/utils/upload_oss_img_utils.dart';
|
||||
import 'package:making_school_asignment_app/page/global_widget/my_text.dart';
|
||||
import 'package:making_school_asignment_app/page/home_page/children/job_report/widget/personnel_data_overview.dart';
|
||||
|
||||
// 数据
|
||||
class HomeworkReviewState {
|
||||
|
|
@ -63,7 +61,8 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin {
|
|||
late StreamSubscription<DoPaperDetailsParam> _paramListen;
|
||||
late StreamSubscription<DoPaperDetailsResult?> _dataListen;
|
||||
final HomeworkReviewState state = HomeworkReviewState();
|
||||
final HomeworkReviewAnnotationsControlState annotationState = HomeworkReviewAnnotationsControlState();
|
||||
final HomeworkReviewAnnotationsControlState annotationState =
|
||||
HomeworkReviewAnnotationsControlState();
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
|
|
@ -93,9 +92,11 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin {
|
|||
}
|
||||
|
||||
void getData() async {
|
||||
var timerControl = Timer(const Duration(milliseconds: 300), () => ToastUtils.showLoading());
|
||||
var timerControl = Timer(
|
||||
const Duration(milliseconds: 300), () => ToastUtils.showLoading());
|
||||
try {
|
||||
DoPaperDetailsResult? data = await getClient().getDoPaperDetails(state.param.value);
|
||||
DoPaperDetailsResult? data =
|
||||
await getClient().getDoPaperDetails(state.param.value);
|
||||
// var studentQuestions = data.studentQuestions;
|
||||
// // 第0个的下标数据不需要处理
|
||||
// for (var i = 0; i < studentQuestions.length; i++) {
|
||||
|
|
@ -107,8 +108,6 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin {
|
|||
state.data.value = data;
|
||||
state.handwritings = [];
|
||||
state.studentQuestions.value = data.studentQuestions;
|
||||
|
||||
|
||||
} catch (e) {
|
||||
print('获取数据报错了:$e');
|
||||
ToastUtils.showError('获取试题数据出错,请重试');
|
||||
|
|
@ -118,7 +117,6 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin {
|
|||
|
||||
ToastUtils.dismiss();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 取消全部评分
|
||||
|
|
@ -170,12 +168,16 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin {
|
|||
if (data == null) return null;
|
||||
|
||||
// 获取OSS 图片url
|
||||
String imgKey = UploadOssImgUtils.getInstance().setImgKey(param.homeworkId, data.studentId.toString(), data.templateId.toString());
|
||||
String imgKey = UploadOssImgUtils.getInstance().setImgKey(
|
||||
param.homeworkId,
|
||||
data.studentId.toString(),
|
||||
data.templateId.toString());
|
||||
var resUrl = await getClient().getOssPresignedUri(imgKey);
|
||||
if (resUrl == null) return null;
|
||||
|
||||
// 没有图片就上传图片
|
||||
RenderRepaintBoundary? boundary = pictureOverviewKey.currentContext!.findRenderObject() as RenderRepaintBoundary?;
|
||||
RenderRepaintBoundary? boundary = pictureOverviewKey.currentContext!
|
||||
.findRenderObject() as RenderRepaintBoundary?;
|
||||
if (boundary == null) return null;
|
||||
// double dpr = MediaQuery.of(context).devicePixelRatio;
|
||||
|
||||
|
|
@ -187,16 +189,20 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin {
|
|||
}
|
||||
|
||||
ui.Image image = await boundary.toImage(pixelRatio: pixelRatio);
|
||||
ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
|
||||
ByteData? byteData =
|
||||
await image.toByteData(format: ui.ImageByteFormat.png);
|
||||
if (byteData == null) return null;
|
||||
|
||||
Dio dio = Dio();
|
||||
dio.options.contentType = null;
|
||||
List<int> bytes = byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes);
|
||||
List<int> bytes = byteData.buffer
|
||||
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes);
|
||||
await dio.put(
|
||||
resUrl,
|
||||
data: Stream.fromIterable(bytes.map((e) => [e])),
|
||||
options: Options(contentType: null, headers: {Headers.contentLengthHeader: bytes.length}),
|
||||
options: Options(
|
||||
contentType: null,
|
||||
headers: {Headers.contentLengthHeader: bytes.length}),
|
||||
);
|
||||
|
||||
return imgKey;
|
||||
|
|
@ -218,7 +224,8 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin {
|
|||
|
||||
if (state.data.value?.studentQuestions.isEmpty ?? true) return;
|
||||
var studentQuestions = state.data.value!.studentQuestions;
|
||||
var noRatingElement = studentQuestions.firstWhereOrNull((e) => e.studentScore == null);
|
||||
var noRatingElement =
|
||||
studentQuestions.firstWhereOrNull((e) => e.studentScore == null);
|
||||
if (noRatingElement != null) {
|
||||
ToastUtils.showInfo('${noRatingElement.questionNo}题请评分');
|
||||
return;
|
||||
|
|
@ -247,7 +254,7 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin {
|
|||
.then((e) async {
|
||||
state.needRefresh = true;
|
||||
var totalUnAnnotateCount = data.totalUnAnnotateCount;
|
||||
if (data.annotateTime == null) totalUnAnnotateCount -= 1;
|
||||
if (data.needAnnotate) totalUnAnnotateCount -= 1; // 是否需要批阅
|
||||
|
||||
if (totalUnAnnotateCount <= 0 && !state.lastQuestionPrompt) {
|
||||
// 批阅完成
|
||||
|
|
@ -256,7 +263,7 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin {
|
|||
builder: (BuildContext context1) {
|
||||
return AlertDialog(
|
||||
title: quickText('批阅已完成'),
|
||||
content: const Text('暂无更多待批阅项'),
|
||||
content: const Text('暂无更多批阅项'),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('继续'),
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:making_school_asignment_app/page/global_widget/ReturnToHomepage.dart';
|
||||
import 'package:making_school_asignment_app/page/global_widget/my_text.dart';
|
||||
import 'package:making_school_asignment_app/page/home_page/children/annotate_class/annotate_class_logic.dart';
|
||||
import 'package:making_school_asignment_app/page/home_page/home_logic.dart';
|
||||
|
||||
import 'components/bottom_operation_bar.dart';
|
||||
import 'components/button_floating_action.dart';
|
||||
import 'components/dropdown_switch_students_type.dart';
|
||||
import 'components/favorite_widget.dart';
|
||||
import 'components/question_paper_view.dart';
|
||||
|
|
@ -24,6 +23,7 @@ class _HomeworkReviewState extends State<HomeworkReview> {
|
|||
final logic = Get.find<HomeworkReviewLogic>();
|
||||
final sateData = Get.find<HomeworkReviewLogic>().state;
|
||||
final AnnotateClassLogic _controller = Get.find<AnnotateClassLogic>();
|
||||
final HomeLogic _homeLogicController = Get.find<HomeLogic>();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
|
@ -42,18 +42,27 @@ class _HomeworkReviewState extends State<HomeworkReview> {
|
|||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvoked: (e) {
|
||||
if (e && sateData.needRefresh) _controller.getList();
|
||||
if (e && sateData.needRefresh) {
|
||||
_controller.getList();
|
||||
_homeLogicController.getList();
|
||||
}
|
||||
},
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
// titleSpacing: 0,
|
||||
leading: IconButton(icon: const Icon(Icons.arrow_back_ios), onPressed: () => Get.back()),
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back_ios),
|
||||
onPressed: () => Get.back()),
|
||||
iconTheme: const IconThemeData(color: Colors.black),
|
||||
title: quickText(sateData.param.value.homeworkName),
|
||||
backgroundColor: Colors.white,
|
||||
elevation: 0,
|
||||
actions: [const FavoriteWidget(), SizedBox(width: 5.w), const ReturnToHomepage()],
|
||||
actions: [
|
||||
const FavoriteWidget(),
|
||||
SizedBox(width: 5.w),
|
||||
const ReturnToHomepage()
|
||||
],
|
||||
),
|
||||
body: SafeArea(
|
||||
child: Column(
|
||||
|
|
|
|||
|
|
@ -18,13 +18,14 @@ import 'home_logic.dart';
|
|||
part 'home_view.g.dart';
|
||||
|
||||
class HomePage extends StatefulWidget {
|
||||
const HomePage({Key? key}) : super(key: key);
|
||||
const HomePage({super.key});
|
||||
|
||||
@override
|
||||
State<HomePage> createState() => _HomePageState();
|
||||
}
|
||||
|
||||
class _HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin {
|
||||
class _HomePageState extends State<HomePage>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
final logic = Get.find<HomeLogic>();
|
||||
final state = Get.find<HomeLogic>().state;
|
||||
|
||||
|
|
@ -78,22 +79,31 @@ class _HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin
|
|||
),
|
||||
),
|
||||
),*/
|
||||
SizedBox(height: MediaQuery. of(context).padding.top / 2),
|
||||
SizedBox(height: MediaQuery.of(context).padding.top / 2),
|
||||
Obx(() {
|
||||
return $TermRow([
|
||||
EntranceModel(title: '作业批阅', image: 'assets/images/job_home_marking.png', navigationUrl: Routes.readOverPage),
|
||||
EntranceModel(
|
||||
title: '作业批阅',
|
||||
image: 'assets/images/job_home_marking.png',
|
||||
navigationUrl: Routes.readOverPage),
|
||||
EntranceModel(
|
||||
title: '学生历史作业',
|
||||
image: 'assets/images/job_home_history.png',
|
||||
navigationUrl: Routes.studentHistoryWorkPage,
|
||||
page: 'history',
|
||||
),
|
||||
EntranceModel(title: '知识点点掌握', image: 'assets/images/job_home_knowledge.png', navigationUrl: Routes.knowledgePointsGraspPage)
|
||||
EntranceModel(
|
||||
title: '知识点点掌握',
|
||||
image: 'assets/images/job_home_knowledge.png',
|
||||
navigationUrl: Routes.knowledgePointsGraspPage)
|
||||
], state.totalCount.value);
|
||||
}),
|
||||
spaceWidth,
|
||||
$TermRow([
|
||||
EntranceModel(title: '答题轨迹', image: 'assets/images/job_home_answer_record.png', navigationUrl: Routes.answerTrajectoryPage),
|
||||
EntranceModel(
|
||||
title: '答题轨迹',
|
||||
image: 'assets/images/job_home_answer_record.png',
|
||||
navigationUrl: Routes.answerTrajectoryPage),
|
||||
EntranceModel(
|
||||
title: '优先批阅设定',
|
||||
image: 'assets/images/job_home_youxian.png',
|
||||
|
|
@ -115,134 +125,210 @@ class _HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin
|
|||
Obx(() {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12.w),
|
||||
child: state.workList.isNotEmpty?Column(
|
||||
children: List.generate(state.workList.length, (index) {
|
||||
Items item = state.workList[index];
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
Get.toNamed(Routes.annotateClassPage, arguments: {
|
||||
'id': item.id,
|
||||
'name': item.name,
|
||||
'grade': item.grade,
|
||||
'subject': item.subject,
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(bottom: 15.h),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 4.h),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 15.h, horizontal: 10.w),
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(6.r),
|
||||
color: const Color.fromRGBO(255, 255, 255, 1),
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Color.fromRGBO(210, 216, 241, 1),
|
||||
offset: Offset.zero, //阴影y轴偏移量
|
||||
blurRadius: 5.8, //阴影模糊程度
|
||||
spreadRadius: 0, //阴影扩散程度
|
||||
)
|
||||
],
|
||||
),
|
||||
child: state.workList.isNotEmpty
|
||||
? Column(
|
||||
children:
|
||||
List.generate(state.workList.length, (index) {
|
||||
Items item = state.workList[index];
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
Get.toNamed(Routes.annotateClassPage,
|
||||
arguments: {
|
||||
'id': item.id,
|
||||
'name': item.name,
|
||||
'grade': item.grade,
|
||||
'subject': item.subject,
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(bottom: 15.h),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: Utils.isPad() ? 32.w : 38.w,
|
||||
height: 18.h,
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.only(left: Utils.isPad() ? 2.w : 3.w),
|
||||
decoration: BoxDecoration(
|
||||
color: state.type == 1 ? const Color(0xFF4CC793) : 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),
|
||||
),
|
||||
SizedBox(height: 4.h),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 15.h, horizontal: 10.w),
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(6.r),
|
||||
color: const Color.fromRGBO(
|
||||
255, 255, 255, 1),
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Color.fromRGBO(
|
||||
210, 216, 241, 1),
|
||||
offset: Offset.zero, //阴影y轴偏移量
|
||||
blurRadius: 5.8, //阴影模糊程度
|
||||
spreadRadius: 0, //阴影扩散程度
|
||||
)
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: Utils.isPad()
|
||||
? 32.w
|
||||
: 38.w,
|
||||
height: 18.h,
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.only(
|
||||
left: Utils.isPad()
|
||||
? 2.w
|
||||
: 3.w),
|
||||
decoration: BoxDecoration(
|
||||
color: state.type == 1
|
||||
? const Color(
|
||||
0xFF4CC793)
|
||||
: 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(
|
||||
top: 3.h, right: 4.w),
|
||||
child: quickText(
|
||||
state.type == 1
|
||||
? '作业'
|
||||
: '考试',
|
||||
color: Colors.white,
|
||||
size: 10.sp),
|
||||
),
|
||||
Expanded(
|
||||
child: quickText(
|
||||
item.name,
|
||||
maxLines: 2,
|
||||
size: Utils.isPad()
|
||||
? 14.sp
|
||||
: 16.sp,
|
||||
color: const Color.fromRGBO(
|
||||
70, 70, 70, 1),
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
margin: EdgeInsets.only(top:3.h,right: 4.w),
|
||||
child: quickText(state.type == 1 ? '作业' : '考试', color: Colors.white, size: 10.sp),
|
||||
),
|
||||
Expanded(
|
||||
child: quickText(
|
||||
item.name,
|
||||
maxLines: 2,
|
||||
size: Utils.isPad() ? 14.sp : 16.sp,
|
||||
color: const Color.fromRGBO(70, 70, 70, 1),
|
||||
fontWeight: FontWeight.bold,
|
||||
SizedBox(height: 10.h),
|
||||
Row(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.end,
|
||||
children: [
|
||||
quickText(
|
||||
EnumUtils.formatSubject(
|
||||
item.subject),
|
||||
color: const Color.fromRGBO(
|
||||
97, 97, 97, 1),
|
||||
size: 12.sp,
|
||||
),
|
||||
quickText(' / ',
|
||||
color: const Color.fromRGBO(
|
||||
130, 130, 130, 1),
|
||||
size: 11.sp,
|
||||
fontWeight:
|
||||
FontWeight.w500),
|
||||
Row(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.end,
|
||||
children: [
|
||||
quickText('题量:',
|
||||
color: const Color
|
||||
.fromRGBO(
|
||||
130, 130, 130, 1),
|
||||
size: 11.sp),
|
||||
quickText(
|
||||
'${item.questionCount! - item.annotateCount!}',
|
||||
color:
|
||||
const Color.fromRGBO(
|
||||
97, 97, 97, 1),
|
||||
size: 13.sp,
|
||||
),
|
||||
],
|
||||
),
|
||||
quickText(' / ',
|
||||
color: const Color.fromRGBO(
|
||||
130, 130, 130, 1),
|
||||
size: 11.sp,
|
||||
fontWeight:
|
||||
FontWeight.w500),
|
||||
quickText(
|
||||
DateTime.parse(
|
||||
item.publishTime)
|
||||
.toString()
|
||||
.substring(0, 10),
|
||||
color: const Color.fromRGBO(
|
||||
97, 97, 97, 1),
|
||||
size: 12.sp),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10.h),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
quickText(
|
||||
EnumUtils.formatSubject(item.subject),
|
||||
color: const Color.fromRGBO(97, 97, 97, 1),
|
||||
size: 12.sp,
|
||||
),
|
||||
quickText(' / ', color: const Color.fromRGBO(130, 130, 130, 1), size: 11.sp, fontWeight: FontWeight.w500),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
quickText('题量:', color: const Color.fromRGBO(130, 130, 130, 1), size: 11.sp),
|
||||
quickText(
|
||||
'${item.questionCount! - item.annotateCount!}',
|
||||
color: const Color.fromRGBO(97, 97, 97, 1),
|
||||
size: 13.sp,
|
||||
),
|
||||
],
|
||||
),
|
||||
quickText(' / ', color: const Color.fromRGBO(130, 130, 130, 1), size: 11.sp, fontWeight: FontWeight.w500),
|
||||
quickText(DateTime.parse(item.publishTime).toString().substring(0, 10),
|
||||
color: const Color.fromRGBO(97, 97, 97, 1), size: 12.sp),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10.h),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10.r),
|
||||
),
|
||||
child: LinearPercentIndicator(
|
||||
padding: EdgeInsets.zero,
|
||||
animation: true,
|
||||
lineHeight: 8.h,
|
||||
animationDuration: 2500,
|
||||
percent: item.annotateRate == null ? 0 : item.annotateRate! / 100,
|
||||
progressColor: const Color(0xFF4CC793),
|
||||
backgroundColor: const Color(0xFFE8E8E8),
|
||||
barRadius: Radius.circular(10.r),
|
||||
),
|
||||
SizedBox(height: 10.h),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
10.r),
|
||||
),
|
||||
child:
|
||||
LinearPercentIndicator(
|
||||
padding: EdgeInsets.zero,
|
||||
animation: true,
|
||||
lineHeight: 8.h,
|
||||
animationDuration: 2500,
|
||||
percent: item
|
||||
.annotateRate ==
|
||||
null
|
||||
? 0
|
||||
: item.annotateRate! /
|
||||
100,
|
||||
progressColor:
|
||||
const Color(
|
||||
0xFF4CC793),
|
||||
backgroundColor:
|
||||
const Color(
|
||||
0xFFE8E8E8),
|
||||
barRadius:
|
||||
Radius.circular(10.r),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 10.r,
|
||||
),
|
||||
quickText(
|
||||
'${item.annotateRate!.toStringAsFixed(0)}%',
|
||||
size: 10.sp,
|
||||
color: const Color(
|
||||
0xFF464646)),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 10.r,
|
||||
),
|
||||
quickText('${item.annotateRate!.toStringAsFixed(0)}%', size: 10.sp, color: const Color(0xFF464646)),
|
||||
],
|
||||
// FavoriteButton(jobTaskItem.id, jobTaskItem.title),
|
||||
],
|
||||
),
|
||||
),
|
||||
// FavoriteButton(jobTaskItem.id, jobTaskItem.title),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
):const MyEmptyWidget(),
|
||||
);
|
||||
}),
|
||||
)
|
||||
: const MyEmptyWidget(),
|
||||
);
|
||||
}),
|
||||
],
|
||||
|
|
@ -266,7 +352,11 @@ class EntranceModel extends Object {
|
|||
String navigationUrl;
|
||||
String? page;
|
||||
|
||||
EntranceModel({required this.title, required this.image, required this.navigationUrl, this.page});
|
||||
EntranceModel(
|
||||
{required this.title,
|
||||
required this.image,
|
||||
required this.navigationUrl,
|
||||
this.page});
|
||||
}
|
||||
|
||||
@swidget
|
||||
|
|
@ -275,7 +365,8 @@ Widget $termRow(BuildContext context, List<EntranceModel> items, int? data) {
|
|||
Widget childWidget;
|
||||
switch (leng) {
|
||||
case 1:
|
||||
childWidget = Row(children: [Expanded(child: $TermItem(items[0], data!))]);
|
||||
childWidget =
|
||||
Row(children: [Expanded(child: $TermItem(items[0], data!))]);
|
||||
break;
|
||||
case 2:
|
||||
childWidget = Row(children: [
|
||||
|
|
@ -310,11 +401,13 @@ Widget $termRow(BuildContext context, List<EntranceModel> items, int? data) {
|
|||
childWidget = Container();
|
||||
}
|
||||
|
||||
return Container(padding: EdgeInsets.symmetric(horizontal: 14.w), child: childWidget);
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 14.w), child: childWidget);
|
||||
}
|
||||
|
||||
@swidget
|
||||
Widget $termItem(BuildContext context, EntranceModel e, int data, {double? theHeight}) {
|
||||
Widget $termItem(BuildContext context, EntranceModel e, int data,
|
||||
{double? theHeight}) {
|
||||
bool isJob = e.title == '作业批阅';
|
||||
|
||||
return Material(
|
||||
|
|
@ -343,10 +436,14 @@ Widget $termItem(BuildContext context, EntranceModel e, int data, {double? theHe
|
|||
badgeStyle: badges.BadgeStyle(
|
||||
badgeColor: const Color.fromRGBO(255, 105, 105, 1),
|
||||
shape: badges.BadgeShape.square,
|
||||
borderRadius: BorderRadius.only(topLeft: Radius.circular(10.r), topRight: Radius.circular(8.5.r), bottomRight: Radius.circular(8.5.r)),
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(10.r),
|
||||
topRight: Radius.circular(8.5.r),
|
||||
bottomRight: Radius.circular(8.5.r)),
|
||||
// borderSide: BorderSide(color: Colors.white, width: 2),
|
||||
elevation: 1,
|
||||
padding: EdgeInsets.symmetric(horizontal: Utils.isPad() ? 11.w : 16.w, vertical: 2.h),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: Utils.isPad() ? 11.w : 16.w, vertical: 2.h),
|
||||
),
|
||||
position: badges.BadgePosition.topEnd(top: 10.r, end: 10.r),
|
||||
child: Container(
|
||||
|
|
@ -369,17 +466,25 @@ Widget $termItem(BuildContext context, EntranceModel e, int data, {double? theHe
|
|||
? Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset(e.image, height: 32.r, width: 32.r, fit: BoxFit.cover),
|
||||
Image.asset(e.image,
|
||||
height: 32.r, width: 32.r, fit: BoxFit.cover),
|
||||
SizedBox(height: 6.r),
|
||||
quickText(e.title, size: 12.sp, color: const Color.fromRGBO(79, 79, 79, 1), fontWeight: FontWeight.w500),
|
||||
quickText(e.title,
|
||||
size: 12.sp,
|
||||
color: const Color.fromRGBO(79, 79, 79, 1),
|
||||
fontWeight: FontWeight.w500),
|
||||
],
|
||||
)
|
||||
: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset(e.image, height: 32.r, width: 32.r, fit: BoxFit.cover),
|
||||
Image.asset(e.image,
|
||||
height: 32.r, width: 32.r, fit: BoxFit.cover),
|
||||
SizedBox(width: 6.r),
|
||||
quickText(e.title, size: 12.sp, color: const Color.fromRGBO(79, 79, 79, 1), fontWeight: FontWeight.w500),
|
||||
quickText(e.title,
|
||||
size: 12.sp,
|
||||
color: const Color.fromRGBO(79, 79, 79, 1),
|
||||
fontWeight: FontWeight.w500),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -94,6 +94,8 @@ dependencies:
|
|||
permission_handler: ^11.0.1
|
||||
flutter_distributor: ^0.4.5
|
||||
flutter_native_splash: ^2.4.1
|
||||
icons_launcher: ^2.1.7
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
@ -160,3 +162,11 @@ flutter:
|
|||
#
|
||||
# For details regarding fonts from package dependencies,
|
||||
# see https://flutter.dev/custom-fonts/#from-packages
|
||||
|
||||
icons_launcher:
|
||||
platforms:
|
||||
android:
|
||||
enable: false
|
||||
ios:
|
||||
enable: true
|
||||
image_path: "assets/images/logo_splash.png"
|
||||
|
|
@ -120,6 +120,33 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -149,9 +176,8 @@
|
|||
body {
|
||||
margin: 0;
|
||||
min-height: 100%;
|
||||
background-color: #ffffff;
|
||||
background-image: url("splash/img/light-background.png");
|
||||
background-size: 100% 100%;
|
||||
background-color: #42a5f5;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.center {
|
||||
|
|
@ -207,13 +233,18 @@
|
|||
document.body.style.background = "transparent";
|
||||
}
|
||||
</script>
|
||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="flutter_bootstrap.js" async=""></script>
|
||||
|
||||
|
||||
|
|
|
|||