xiaobai 2 years ago
parent
commit
05704a1fbb
80 changed files with 1322 additions and 720 deletions
  1. 3 3
      android/app/src/main/res/drawable-v21/launch_background.xml
  2. 3 6
      android/app/src/main/res/drawable/launch_background.xml
  3. BIN
      android/app/src/main/res/mipmap-hdpi/launch_image.png
  4. BIN
      android/app/src/main/res/mipmap-hdpi/splash.png
  5. BIN
      android/app/src/main/res/mipmap-mdpi/launch_image.png
  6. BIN
      android/app/src/main/res/mipmap-mdpi/splash.png
  7. BIN
      android/app/src/main/res/mipmap-xhdpi/launch_image.png
  8. BIN
      android/app/src/main/res/mipmap-xhdpi/splash.png
  9. BIN
      android/app/src/main/res/mipmap-xxhdpi/launch_image.png
  10. BIN
      android/app/src/main/res/mipmap-xxhdpi/splash.png
  11. BIN
      android/app/src/main/res/mipmap-xxxhdpi/launch_image.png
  12. BIN
      android/app/src/main/res/mipmap-xxxhdpi/splash.png
  13. 8 0
      android/app/src/main/res/values-night/styles.xml
  14. 8 0
      android/app/src/main/res/values/styles.xml
  15. BIN
      assets/images/2.0x/login_unselect.png
  16. BIN
      assets/images/2.0x/login_wechat.png
  17. BIN
      assets/images/2.0x/practice_edit_ic.png
  18. BIN
      assets/images/2.0x/practice_report_ic.png
  19. BIN
      assets/images/2.0x/practice_time_ic.png
  20. BIN
      assets/images/3.0x/login_unselect.png
  21. BIN
      assets/images/3.0x/login_wechat.png
  22. BIN
      assets/images/3.0x/practice_edit_ic.png
  23. BIN
      assets/images/3.0x/practice_report_ic.png
  24. BIN
      assets/images/3.0x/practice_time_ic.png
  25. BIN
      assets/images/login_unselect.png
  26. BIN
      assets/images/login_wechat.png
  27. BIN
      assets/images/practice_edit_ic.png
  28. BIN
      assets/images/practice_report_ic.png
  29. BIN
      assets/images/practice_time_ic.png
  30. 6 0
      ios/Runner/Assets.xcassets/Contents.json
  31. 5 5
      ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
  32. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
  33. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
  34. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
  35. 0 5
      ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
  36. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/launch_image.png
  37. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/launch_image@2x.png
  38. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/launch_image@3x.png
  39. 14 8
      ios/Runner/Base.lproj/LaunchScreen.storyboard
  40. 8 5
      ios/Runner/Base.lproj/Main.storyboard
  41. 77 73
      ios/Runner/Info.plist
  42. 2 1
      lib/component/mood_ring.dart
  43. 2 1
      lib/gen_a/A.dart
  44. 7 0
      lib/generated/json/favorite_model.g.dart
  45. 23 3
      lib/main.dart
  46. 2 0
      lib/net/http_url.dart
  47. 21 0
      lib/pages/explore/main/controller/discover_ctrl.dart
  48. 1 1
      lib/pages/explore/main/view/discover_all_view.dart
  49. 98 52
      lib/pages/main_ctrl.dart
  50. 14 1
      lib/pages/my/login/page/captcha_page.dart
  51. 140 66
      lib/pages/my/login/page/login_page.dart
  52. 5 124
      lib/pages/my/login/page/privacy_policy_page.dart
  53. 5 61
      lib/pages/my/login/page/user_agreement_page.dart
  54. 8 0
      lib/pages/my/main/controller/mine_ctrl.dart
  55. 1 0
      lib/pages/my/main/controller/personal_info_ctrl.dart
  56. 1 1
      lib/pages/my/main/model/user_model.dart
  57. 20 4
      lib/pages/my/main/page/personal_info_page.dart
  58. 53 53
      lib/pages/my/main/view/mine_info_view.dart
  59. 1 1
      lib/pages/my/mood_analysis/view/calendar_view.dart
  60. 11 2
      lib/pages/my/setting/page/order_manage_page.dart
  61. 14 4
      lib/pages/my/setting/page/setting_page.dart
  62. 168 1
      lib/pages/my/setting/page/subscription_manage_page.dart
  63. 40 4
      lib/pages/my/setting/view/order_manage_cell.dart
  64. 56 0
      lib/pages/my/vip/page/vip_agreement_page.dart
  65. 37 64
      lib/pages/my/vip/page/vip_buy_page.dart
  66. 1 0
      lib/pages/today/favorite/model/favorite_model.dart
  67. 9 0
      lib/pages/today/main/controller/home_ctrl.dart
  68. 106 2
      lib/pages/today/mood_record/controller/mood_text_ctrl.dart
  69. 1 1
      lib/pages/today/mood_record/page/mood_reason_page.dart
  70. 2 2
      lib/pages/today/mood_record/view/mood_reason_cell.dart
  71. 48 49
      lib/pages/today/practice/page/practice_detail_page.dart
  72. 139 77
      lib/pages/today/practice/page/segment_finish_page.dart
  73. 55 20
      lib/pages/today/practice/view/practice_info_view.dart
  74. 9 3
      lib/pages/today/practice_assess/page/exam_page.dart
  75. 3 3
      lib/pages/today/practice_assess/view/essay_view.dart
  76. 5 0
      lib/utils/app_event.dart
  77. 7 7
      pubspec.lock
  78. 2 0
      pubspec.yaml
  79. 73 7
      web/index.html
  80. BIN
      web/splash/img/light-background.png

+ 3 - 3
android/app/src/main/res/drawable-v21/launch_background.xml

@@ -1,9 +1,9 @@
-<?xml version="1.0" encoding="utf-8"?><!-- Modify this file to customize your launch splash screen -->
+<?xml version="1.0" encoding="utf-8"?>
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-
+    <item android:drawable="@android:color/white" />
     <item>
         <bitmap
             android:gravity="fill"
-            android:src="@mipmap/splash" />
+            android:src="@mipmap/launch_image" />
     </item>
 </layer-list>

+ 3 - 6
android/app/src/main/res/drawable/launch_background.xml

@@ -1,13 +1,10 @@
-<?xml version="1.0" encoding="utf-8"?><!-- Modify this file to customize your launch splash screen -->
+<?xml version="1.0" encoding="utf-8"?>
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:drawable="@android:color/white" />
-
-    <!-- You can insert your own image assets here -->
+<!--    <item android:drawable="?android:colorBackground" />-->
     <item>
         <bitmap
             android:gravity="fill"
-            android:src="@mipmap/splash" />
+            android:src="@mipmap/launch_image" />
     </item>
-
-
 </layer-list>

BIN
android/app/src/main/res/mipmap-hdpi/launch_image.png


BIN
android/app/src/main/res/mipmap-hdpi/splash.png


BIN
android/app/src/main/res/mipmap-mdpi/launch_image.png


BIN
android/app/src/main/res/mipmap-mdpi/splash.png


BIN
android/app/src/main/res/mipmap-xhdpi/launch_image.png


BIN
android/app/src/main/res/mipmap-xhdpi/splash.png


BIN
android/app/src/main/res/mipmap-xxhdpi/launch_image.png


BIN
android/app/src/main/res/mipmap-xxhdpi/splash.png


BIN
android/app/src/main/res/mipmap-xxxhdpi/launch_image.png


BIN
android/app/src/main/res/mipmap-xxxhdpi/splash.png


+ 8 - 0
android/app/src/main/res/values-night/styles.xml

@@ -5,6 +5,14 @@
         <!-- Show a splash screen on the activity. Automatically removed when
              the Flutter engine draws its first frame -->
         <item name="android:windowBackground">@drawable/launch_background</item>
+        <item name="android:forceDarkAllowed">false</item>
+        <item name="android:windowFullscreen">true</item>
+        <item name="android:windowDrawsSystemBarBackgrounds">false</item>
+        <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
+
+<!--        <item name="android:navigationBarColor">@android:color/transparent</item>-->
+<!--        <item name="android:statusBarColor">@android:color/transparent</item>-->
+
     </style>
     <!-- Theme applied to the Android Window as soon as the process has started.
          This theme determines the color of the Android Window while your

+ 8 - 0
android/app/src/main/res/values/styles.xml

@@ -5,6 +5,14 @@
         <!-- Show a splash screen on the activity. Automatically removed when
              the Flutter engine draws its first frame -->
         <item name="android:windowBackground">@drawable/launch_background</item>
+        <item name="android:forceDarkAllowed">false</item>
+        <item name="android:windowFullscreen">true</item>
+        <item name="android:windowDrawsSystemBarBackgrounds">false</item>
+        <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
+
+<!--        <item name="android:navigationBarColor">@android:color/transparent</item>-->
+<!--        <item name="android:statusBarColor">@android:color/transparent</item>-->
+
     </style>
     <!-- Theme applied to the Android Window as soon as the process has started.
          This theme determines the color of the Android Window while your

BIN
assets/images/2.0x/login_unselect.png


BIN
assets/images/2.0x/login_wechat.png


BIN
assets/images/2.0x/practice_edit_ic.png


BIN
assets/images/2.0x/practice_report_ic.png


BIN
assets/images/2.0x/practice_time_ic.png


BIN
assets/images/3.0x/login_unselect.png


BIN
assets/images/3.0x/login_wechat.png


BIN
assets/images/3.0x/practice_edit_ic.png


BIN
assets/images/3.0x/practice_report_ic.png


BIN
assets/images/3.0x/practice_time_ic.png


BIN
assets/images/login_unselect.png


BIN
assets/images/login_wechat.png


BIN
assets/images/practice_edit_ic.png


BIN
assets/images/practice_report_ic.png


BIN
assets/images/practice_time_ic.png


+ 6 - 0
ios/Runner/Assets.xcassets/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 5 - 5
ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json

@@ -1,23 +1,23 @@
 {
   "images" : [
     {
+      "filename" : "launch_image.png",
       "idiom" : "universal",
-      "filename" : "LaunchImage.png",
       "scale" : "1x"
     },
     {
+      "filename" : "launch_image@2x.png",
       "idiom" : "universal",
-      "filename" : "LaunchImage@2x.png",
       "scale" : "2x"
     },
     {
+      "filename" : "launch_image@3x.png",
       "idiom" : "universal",
-      "filename" : "LaunchImage@3x.png",
       "scale" : "3x"
     }
   ],
   "info" : {
-    "version" : 1,
-    "author" : "xcode"
+    "author" : "xcode",
+    "version" : 1
   }
 }

BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png


BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png


BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png


+ 0 - 5
ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md

@@ -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.

BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/launch_image.png


BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/launch_image@2x.png


BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/launch_image@3x.png


+ 14 - 8
ios/Runner/Base.lproj/LaunchScreen.storyboard

@@ -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="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <scenes>
         <!--View Controller-->
@@ -14,24 +16,28 @@
                         <viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
                     </layoutGuides>
                     <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
+                        <rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
-                            <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
+                            <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
+                                <rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
                             </imageView>
                         </subviews>
                         <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                         <constraints>
-                            <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
-                            <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
+                            <constraint firstItem="YRO-k0-Ey4" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="3T2-ad-Qdv"/>
+                            <constraint firstAttribute="trailing" secondItem="YRO-k0-Ey4" secondAttribute="trailing" id="TQA-XW-tRk"/>
+                            <constraint firstItem="YRO-k0-Ey4" firstAttribute="bottom" secondItem="Ze5-6b-2t3" secondAttribute="bottom" id="duK-uY-Gun"/>
+                            <constraint firstItem="YRO-k0-Ey4" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="xPn-NY-SIU"/>
                         </constraints>
                     </view>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
             </objects>
-            <point key="canvasLocation" x="53" y="375"/>
+            <point key="canvasLocation" x="80.916030534351137" y="264.08450704225356"/>
         </scene>
     </scenes>
     <resources>
-        <image name="LaunchImage" width="168" height="185"/>
+        <image name="LaunchImage" width="390" height="844"/>
     </resources>
 </document>

+ 8 - 5
ios/Runner/Base.lproj/Main.storyboard

@@ -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="22155" 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="22131"/>
+        <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="-16" y="-40"/>
         </scene>
     </scenes>
 </document>

+ 77 - 73
ios/Runner/Info.plist

@@ -1,81 +1,85 @@
 <?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>NSAppTransportSecurity</key>
 	<dict>
-		<key>NSAllowsArbitraryLoads</key>
+		<key>CADisableMinimumFrameDurationOnPhone</key>
 		<true/>
-	</dict>
-	<key>LSApplicationQueriesSchemes</key>
-	<array>
-		<string>wechat</string>
-		<string>weixin</string>
-		<string>weixinULAPI</string>
-	</array>
-	<key>CADisableMinimumFrameDurationOnPhone</key>
-	<true/>
-	<key>CFBundleDevelopmentRegion</key>
-	<string>$(DEVELOPMENT_LANGUAGE)</string>
-	<key>CFBundleDisplayName</key>
-	<string>心境奇旅</string>
-	<key>CFBundleExecutable</key>
-	<string>$(EXECUTABLE_NAME)</string>
-	<key>CFBundleIdentifier</key>
-	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
-	<key>CFBundleInfoDictionaryVersion</key>
-	<string>6.0</string>
-	<key>CFBundleName</key>
-	<string>$(PRODUCT_NAME)</string>
-	<key>CFBundlePackageType</key>
-	<string>APPL</string>
-	<key>CFBundleShortVersionString</key>
-	<string>$(FLUTTER_BUILD_NAME)</string>
-	<key>CFBundleSignature</key>
-	<string>????</string>
-	<key>CFBundleURLTypes</key>
-	<array>
-		<dict>
-			<key>CFBundleTypeRole</key>
-			<string>Editor</string>
-			<key>CFBundleURLName</key>
+		<key>CFBundleDevelopmentRegion</key>
+		<string>$(DEVELOPMENT_LANGUAGE)</string>
+		<key>CFBundleDisplayName</key>
+		<string>心境奇旅</string>
+		<key>CFBundleExecutable</key>
+		<string>$(EXECUTABLE_NAME)</string>
+		<key>CFBundleIdentifier</key>
+		<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+		<key>CFBundleInfoDictionaryVersion</key>
+		<string>6.0</string>
+		<key>CFBundleName</key>
+		<string>$(PRODUCT_NAME)</string>
+		<key>CFBundlePackageType</key>
+		<string>APPL</string>
+		<key>CFBundleShortVersionString</key>
+		<string>$(FLUTTER_BUILD_NAME)</string>
+		<key>CFBundleSignature</key>
+		<string>????</string>
+		<key>CFBundleURLTypes</key>
+		<array>
+			<dict>
+				<key>CFBundleTypeRole</key>
+				<string>Editor</string>
+				<key>CFBundleURLName</key>
+				<string>weixin</string>
+				<key>CFBundleURLSchemes</key>
+				<array>
+					<string>wx2c3133a32876fe1c</string>
+				</array>
+			</dict>
+		</array>
+		<key>CFBundleVersion</key>
+		<string>$(FLUTTER_BUILD_NUMBER)</string>
+		<key>LSApplicationQueriesSchemes</key>
+		<array>
+			<string>wechat</string>
 			<string>weixin</string>
-			<key>CFBundleURLSchemes</key>
-			<array>
-				<string>wx2c3133a32876fe1c</string>
-			</array>
+			<string>weixinULAPI</string>
+		</array>
+		<key>LSRequiresIPhoneOS</key>
+		<true/>
+		<key>NSAppTransportSecurity</key>
+		<dict>
+			<key>NSAllowsArbitraryLoads</key>
+			<true/>
 		</dict>
-	</array>
-	<key>CFBundleVersion</key>
-	<string>$(FLUTTER_BUILD_NUMBER)</string>
-	<key>LSRequiresIPhoneOS</key>
-	<true/>
-	<key>NSCameraUsageDescription</key>
-	<string>心境奇旅会在您拍摄头像时访问您的相机权限</string>
-	<key>NSPhotoLibraryAddUsageDescription</key>
-	<string>心境奇旅会在您拍摄头像时访问您的相机权限</string>
-	<key>NSPhotoLibraryUsageDescription</key>
-	<string>心境奇旅会在您上传头像时访问您的相册权限</string>
-	<key>UIApplicationSupportsIndirectInputEvents</key>
-	<true/>
-	<key>UILaunchStoryboardName</key>
-	<string>LaunchScreen</string>
-	<key>UIMainStoryboardFile</key>
-	<string>Main</string>
-	<key>UISupportedInterfaceOrientations</key>
-	<array>
-		<string>UIInterfaceOrientationPortrait</string>
-		<string>UIInterfaceOrientationLandscapeLeft</string>
-		<string>UIInterfaceOrientationLandscapeRight</string>
-	</array>
-	<key>UISupportedInterfaceOrientations~ipad</key>
-	<array>
-		<string>UIInterfaceOrientationPortrait</string>
-		<string>UIInterfaceOrientationPortraitUpsideDown</string>
-		<string>UIInterfaceOrientationLandscapeLeft</string>
-		<string>UIInterfaceOrientationLandscapeRight</string>
-	</array>
-	<key>UIViewControllerBasedStatusBarAppearance</key>
-	<false/>
-</dict>
+		<key>NSCameraUsageDescription</key>
+		<string>心境奇旅会在您拍摄头像时访问您的相机权限</string>
+		<key>NSPhotoLibraryAddUsageDescription</key>
+		<string>心境奇旅会在您拍摄头像时访问您的相机权限</string>
+		<key>NSPhotoLibraryUsageDescription</key>
+		<string>心境奇旅会在您上传头像时访问您的相册权限</string>
+		<key>UIApplicationSupportsIndirectInputEvents</key>
+		<true/>
+		<key>UILaunchStoryboardName</key>
+		<string>LaunchScreen</string>
+		<key>UIMainStoryboardFile</key>
+		<string>Main</string>
+		<key>UIRequiresFullScreen</key>
+		<true/>
+		<key>UISupportedInterfaceOrientations</key>
+		<array>
+			<string>UIInterfaceOrientationPortrait</string>
+			<string>UIInterfaceOrientationLandscapeLeft</string>
+			<string>UIInterfaceOrientationLandscapeRight</string>
+		</array>
+		<key>UISupportedInterfaceOrientations~ipad</key>
+		<array>
+			<string>UIInterfaceOrientationPortrait</string>
+			<string>UIInterfaceOrientationPortraitUpsideDown</string>
+			<string>UIInterfaceOrientationLandscapeLeft</string>
+			<string>UIInterfaceOrientationLandscapeRight</string>
+		</array>
+		<key>UIViewControllerBasedStatusBarAppearance</key>
+		<false/>
+		<key>UIStatusBarHidden</key>
+		<false/>
+	</dict>
 </plist>

+ 2 - 1
lib/component/mood_ring.dart

@@ -49,7 +49,8 @@ class MoodRing extends StatelessWidget {
                 content??"",
                 style: TextStyle(
                     color: contentColor??HexColor("#666666"),
-                    fontSize: 10.sp
+                    fontSize: 10.sp,
+                  fontWeight: FontWeight.w500
                 ),
               ),
             )

+ 2 - 1
lib/gen_a/A.dart

@@ -1,6 +1,6 @@
 class A{
  //auto gen ,do not edit! 
-  static  final String assets_images_mood_text_bg="assets/images/mood_text_bg.png";
+static  final String assets_images_mood_text_bg="assets/images/mood_text_bg.png";
 static  final String assets_images_home_back_all="assets/images/home_back_all.png";
 static  final String assets_images_mood_ic_music="assets/images/mood_ic_music.png";
 static  final String assets_images_mood_ic_custom="assets/images/mood_ic_custom.png";
@@ -41,6 +41,7 @@ static  final String assets_images_home_fill_space="assets/images/home_fill_spac
 static  final String assets_images_mood_list_more="assets/images/mood_list_more.png";
 static  final String assets_images_ic_lable_chapter="assets/images/ic_lable_chapter.png";
 static  final String assets_images_personal_info_edit_pic="assets/images/personal_info_edit_pic.png";
+static  final String assets_images_practice_report_ic="assets/images/practice_report_ic.png";
 static  final String assets_images_mood_ic_study="assets/images/mood_ic_study.png";
 static  final String assets_images_mood_ic_sleep="assets/images/mood_ic_sleep.png";
 static  final String assets_images_report_depressed="assets/images/report_depressed.png";

+ 7 - 0
lib/generated/json/favorite_model.g.dart

@@ -172,6 +172,10 @@ FavoriteRecords $FavoriteRecordsFromJson(Map<String, dynamic> json) {
   if (contentId != null) {
     favoriteRecords.contentId = contentId;
   }
+  final int? subType = jsonConvert.convert<int>(json['subType']);
+  if (subType != null) {
+    favoriteRecords.subType = subType;
+  }
   return favoriteRecords;
 }
 
@@ -196,6 +200,7 @@ Map<String, dynamic> $FavoriteRecordsToJson(FavoriteRecords entity) {
   data['price'] = entity.price;
   data['sourcePrice'] = entity.sourcePrice;
   data['contentId'] = entity.contentId;
+  data['subType'] = entity.subType;
   return data;
 }
 
@@ -220,6 +225,7 @@ extension FavoriteRecordsExtension on FavoriteRecords {
     double? price,
     double? sourcePrice,
     int? contentId,
+    int? subType,
     bool? isShowTime,
   }) {
     return FavoriteRecords()
@@ -242,6 +248,7 @@ extension FavoriteRecordsExtension on FavoriteRecords {
       ..price = price ?? this.price
       ..sourcePrice = sourcePrice ?? this.sourcePrice
       ..contentId = contentId ?? this.contentId
+      ..subType = subType ?? this.subType
       ..isShowTime = isShowTime ?? this.isShowTime;
   }
 }

+ 23 - 3
lib/main.dart

@@ -7,12 +7,11 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
 import 'package:get/get.dart';
 import 'package:poetry/pages/main_binding.dart';
 import 'package:poetry/pages/main_page.dart';
-import 'package:poetry/pages/my/main/bindings/mine_binding.dart';
 import 'package:poetry/routers/app_routers.dart';
 import 'package:poetry/utils/app_static.dart';
-import 'package:poetry/utils/hex_color.dart';
 import 'package:pull_to_refresh/pull_to_refresh.dart';
 import 'package:sp_util/sp_util.dart';
+import 'package:umeng_common_sdk/umeng_common_sdk.dart';
 
 void main() async {
   // Future.delayed(const Duration(milliseconds: 500), () {
@@ -20,7 +19,11 @@ void main() async {
   // });
   WidgetsFlutterBinding.ensureInitialized();
   await SpUtil.getInstance();
-  runApp(const MyApp());
+
+  Future.delayed(const Duration(milliseconds: 1500), () { //延长启动图展示时间
+    runApp(const MyApp());
+  });
+  // runApp(const MyApp());
 
   if (Platform.isAndroid) {
     // 以下两行 设置android状态栏为透明的沉浸。写在组件渲染之后,是为了在渲染后进行set赋值,覆盖状态栏,写在渲染之前MaterialApp组件会覆盖掉这个值。
@@ -87,6 +90,7 @@ class _MyAppState extends State<MyApp> {
                 getPages: AppRouters.routers,
                 title: "心境奇旅",
                 initialBinding: MainBinding(),
+                navigatorObservers: [GetObserver()],
                 //theme: ThemeData(primaryColor: Colors.white),
                 //debugShowCheckedModeBanner: false,
                 //darkTheme: ThemeData.light(),
@@ -128,6 +132,22 @@ class _MyAppState extends State<MyApp> {
   }
 }
 
+class GetObserver extends NavigatorObserver {
+  @override
+  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
+    super.didPush(route, previousRoute);
+    print('Route pushed: ${route.settings.name}');
+    UmengCommonSdk.onPageStart(route.settings.name??"");
+  }
+
+  @override
+  void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
+    super.didPop(route, previousRoute);
+    print('Route popped: ${route.settings.name}');
+    UmengCommonSdk.onPageEnd(route.settings.name??"");
+  }
+}
+
 /*
 
 ScreenUtil().setWidth(540)  (sdk>=2.6 : 540.w)   //根据屏幕宽度适配尺寸

+ 2 - 0
lib/net/http_url.dart

@@ -11,6 +11,7 @@ class HttpUrl {
   static const String verify_old_phone_URL = 'user/verifyCurrentPhone';  //验证老手机号
   static const String bind_new_phone_URL = 'user/bindPhone';  //绑定新手机号
   static const String app_config_URL = 'app/getConfig';  //app系统配置
+  static const String user_logoff_URL = 'user/delete';  //注销账号
 
   static const String mood_stat_URL = 'mood/rangeStat';  //心情统计
   static const String user_mood_stat_URL = 'user/getUserStat';  //用户心情统计
@@ -66,6 +67,7 @@ class HttpUrl {
   static const String buy_vip_wechat_URL = "order/wxBuyVip"; //购买vip,微信支付信息
   static const String buy_practice_wechat_URL = "order/wxBuyPractice"; //购买练习,微信支付信息
   static const String buy_assess_wechat_URL = "order/wxBuyTest"; //购买测评,微信支付信息
+  static const String vip_agreement_URL = "app/getVipAgreement"; //会员协议
 
   static const String apple_in_purchase_verify_URL = "order/applePayVerify"; //苹果内购提交订单
   static const String order_list_URL = "order/listOrder"; //订单列表

+ 21 - 0
lib/pages/explore/main/controller/discover_ctrl.dart

@@ -1,9 +1,12 @@
 
+import 'dart:async';
+
 import 'package:get/get.dart';
 import 'package:poetry/pages/explore/main/model/discover_model.dart';
 
 import '../../../../net/http_url.dart';
 import '../../../../net/http_utils.dart';
+import '../../../../utils/app_event.dart';
 import '../../../today/favorite/model/favorite_model.dart';
 
 class DiscoverCtrl extends GetxController {
@@ -12,6 +15,7 @@ class DiscoverCtrl extends GetxController {
   double APPBAR_SCROLL_OFFSET = 200;
   List<DiscoverModel> dataList = [];
   double offset = 0;
+  StreamSubscription? _firstInstallEvent;
 
   @override
   void onInit() {
@@ -19,6 +23,23 @@ class DiscoverCtrl extends GetxController {
     super.onInit();
 
     requestRecommend();
+    _initEvent();
+
+  }
+
+  @override
+  void dispose() {
+    // TODO: implement dispose
+    super.dispose();
+    _firstInstallEvent?.cancel();
+  }
+
+  void _initEvent() {
+
+    _firstInstallEvent =
+        AppEvent.getInstance()?.on<FirstInstallReloadDataEvent>().listen((event) {
+          requestRecommend();
+        });
   }
 
   void onScroll(offset) {

+ 1 - 1
lib/pages/explore/main/view/discover_all_view.dart

@@ -26,7 +26,7 @@ class DiscoverAllView extends StatelessWidget {
         height: 78.w,
         decoration: BoxDecoration(
           borderRadius: BorderRadius.circular(12.w),
-          border: Border.all(color: HexColor("#E6E5E5"), width: 0.5)
+          border: Border.all(color: HexColor("#000000").withOpacity(0.05), width: 1)
         ),
         child: Row(
           children: [

+ 98 - 52
lib/pages/main_ctrl.dart

@@ -11,6 +11,7 @@ import 'package:poetry/utils/hex_color.dart';
 import 'package:poetry/utils/rgb_color.dart';
 import 'package:sp_util/sp_util.dart';
 import 'package:umeng_common_sdk/umeng_common_sdk.dart';
+import 'package:universal_platform/universal_platform.dart';
 
 import '../config/env_config.dart';
 import '../constant/color_constant.dart';
@@ -18,6 +19,7 @@ import '../constant/um_constant.dart';
 import '../constant/wx_constant.dart';
 import '../module/app_service.dart';
 import '../routers/app_routers.dart';
+import '../utils/app_event.dart';
 
 class MainCtrl extends GetxController {
 
@@ -52,9 +54,7 @@ class MainCtrl extends GetxController {
         return;
       }
       else {
-        UmengCommonSdk.initCommon(UmConstant.androidAppKey,
-            UmConstant.iOSAppKey, EnvConfig.appChannel);
-        UmengCommonSdk.setPageCollectionModeAuto();
+        _initUmeng();
       }
     });
 
@@ -86,6 +86,16 @@ class MainCtrl extends GetxController {
     print("main on ready");
   }
 
+  void _initUmeng() {
+    UmengCommonSdk.initCommon(UmConstant.androidAppKey,
+        UmConstant.iOSAppKey, EnvConfig.appChannel);
+    // // 自动采集页面信息
+    // UmengCommonSdk.setPageCollectionModeAuto();
+
+    // 手动采集页面信息
+    UmengCommonSdk.setPageCollectionModeManual();
+  }
+
   void showHintDialog() async {
     var result = await showDialog(
         barrierDismissible: false,
@@ -96,7 +106,7 @@ class MainCtrl extends GetxController {
                 borderRadius: BorderRadius.all(Radius.circular(16.w))),
             child: Container(
               width: 314.w,
-              height: 280.w,
+              height: 270.w,
               decoration: BoxDecoration(
                 color: Colors.white,
                 borderRadius: BorderRadius.all(Radius.circular(16.w)),
@@ -109,7 +119,10 @@ class MainCtrl extends GetxController {
                   Text(
                     "提示",
                     style: TextStyle(
-                        fontSize: 18.w, color: ColorConstant.textMain),
+                        fontSize: 18.sp,
+                        fontWeight: FontWeight.w500,
+                        color: HexColor("#000000").withOpacity(0.87)
+                    ),
                   ),
                   SizedBox(
                     height: 16.w,
@@ -120,7 +133,11 @@ class MainCtrl extends GetxController {
                       TextSpan(
                           text: "我们非常重视您的个人信息和隐私保护。为了更好的保障您的个人权益,您在点击同意",
                           style: TextStyle(
-                              fontSize: 16.w, color: ColorConstant.textMain)),
+                              fontSize: 16.w,
+                              fontWeight: FontWeight.w400,
+                              color: HexColor("#808080")
+                          )
+                      ),
                       TextSpan(
                           recognizer: TapGestureRecognizer()
                             ..onTap = () {
@@ -129,11 +146,18 @@ class MainCtrl extends GetxController {
                           text: "《用户协议》",
                           style: TextStyle(
                               fontSize: 16.w,
-                              color: ColorConstant.primaryColor)),
+                              color: ColorConstant.primaryColor,
+                            fontWeight: FontWeight.w400,
+                          )
+                      ),
                       TextSpan(
                           text: "及",
                           style: TextStyle(
-                              fontSize: 16.w, color: ColorConstant.textMain)),
+                              fontSize: 16.w,
+                              fontWeight: FontWeight.w400,
+                              color: HexColor("#808080")
+                          )
+                      ),
                       TextSpan(
                           recognizer: TapGestureRecognizer()
                             ..onTap = () {
@@ -142,57 +166,79 @@ class MainCtrl extends GetxController {
                           text: "《隐私政策》",
                           style: TextStyle(
                               fontSize: 16.w,
-                              color: ColorConstant.primaryColor)),
+                              color: ColorConstant.primaryColor,
+                            fontWeight: FontWeight.w400,
+                          )
+                      ),
                       TextSpan(
                           text: "前,请务必审慎阅读,并充分理解协议条款内容。",
                           style: TextStyle(
-                              fontSize: 16.w, color: ColorConstant.textMain)),
+                              fontSize: 16.w,
+                              fontWeight: FontWeight.w400,
+                              color: HexColor("#808080")
+                          )
+                      ),
                     ])),
                   ),
-                  SizedBox(
-                    height: 24.w,
-                  ),
-                  Row(
-                    mainAxisAlignment: MainAxisAlignment.center,
-                    children: [
-                      MaterialButton(
-                        height: 48.w,
-                        minWidth: 125.w,
-                        onPressed: () {
-                          _doQuit();
-                        },
-                        shape: StadiumBorder(),
-                        color: Color(0xFFD7D7D7),
-                        textColor: Color(0xFF9E9E9E),
-                        disabledTextColor: Color(0xFFD7D7D7),
-                        child: Text(
-                          "拒绝",
-                          style: TextStyle(fontSize: 16.w),
+                  // SizedBox(
+                  //   height: 24.w,
+                  // ),
+                  Spacer(),
+                  Container(
+                    height: 48.w,
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.center,
+                      children: [
+                        InkWell(
+                          child: Container(
+                            width: 150.w,
+                            alignment: Alignment.center,
+                            child: Text(
+                              "拒绝",
+                              style: TextStyle(
+                                  fontSize: 16,
+                                  fontWeight: FontWeight.w400,
+                                  color: HexColor("#666666")
+                              ),
+                            ),
+                          ),
+                          onTap: (){
+                            _doQuit();
+                          },
                         ),
-                      ),
-                      SizedBox(
-                        width: 16.w,
-                      ),
-                      MaterialButton(
-                        height: 48.w,
-                        minWidth: 125.w,
-                        onPressed: () {
-                          Navigator.pop(context);
-                          AppService().setAgreeAgreement();
-                          UmengCommonSdk.initCommon(UmConstant.androidAppKey,
-                              UmConstant.iOSAppKey, EnvConfig.appChannel);
-                          UmengCommonSdk.setPageCollectionModeAuto();
-                        },
-                        shape: StadiumBorder(),
-                        color: ColorConstant.primaryColor,
-                        textColor: Colors.white,
-                        disabledTextColor: ColorConstant.primaryColor,
-                        child: Text(
-                          "同意",
-                          style: TextStyle(fontSize: 16.w),
+                        Container(
+                          margin: EdgeInsets.only(top: 9),
+                          width: 1,
+                          height: 24,
+                          color: HexColor("#EFEFEF"),
                         ),
-                      ),
-                    ],
+                        InkWell(
+                          child: Container(
+                            width: 150.w,
+                            alignment: Alignment.center,
+                            child: Text(
+                              "同意",
+                              style: TextStyle(
+                                  fontSize: 16,
+                                  fontWeight: FontWeight.w500,
+                                  color: HexColor("#FCA14C")
+                              ),
+                            ),
+                          ),
+                          onTap: (){
+                            Navigator.pop(context);
+                            AppService().setAgreeAgreement();
+                            if (UniversalPlatform.isIOS){
+                              AppEvent.getInstance()?.fire(FirstInstallReloadDataEvent());
+                            }
+                            _initUmeng();
+                          },
+                        )
+                      ],
+                    ),
+                  ),
+                  SizedBox(
+                    height: 10.w,
                   )
                 ],
               ),

+ 14 - 1
lib/pages/my/login/page/captcha_page.dart

@@ -45,6 +45,7 @@ class _CaptchaState extends State<CaptchaPage> {
   Timer? captchaTimer;
   String _captcha = "";
   bool _isLogin = false;
+  FocusNode focusNode = new FocusNode();
 
   @override
   void initState() {
@@ -73,6 +74,17 @@ class _CaptchaState extends State<CaptchaPage> {
     // });
 
     _sendCaptcha();
+
+    focusNode.addListener(() {
+      if (!focusNode.hasFocus) {
+        Future.delayed(Duration(milliseconds: 130), (){
+          setState(() {});
+        });
+      }
+      else {
+        setState(() {});
+      }
+    });
   }
 
   @override
@@ -189,6 +201,7 @@ class _CaptchaState extends State<CaptchaPage> {
                           keyboardType: TextInputType.number,
                           cursorColor: HexColor(HexColor.SLS_FCA14C),
                           cursorHeight: 24.w,
+                          focusNode: focusNode,
                           pinTheme: PinTheme(
                             shape: PinCodeFieldShape.box,
                             borderRadius: BorderRadius.circular(12.w),
@@ -283,7 +296,7 @@ class _CaptchaState extends State<CaptchaPage> {
                     },
                   ),
                   SizedBox(
-                    height: 64.h,
+                    height: focusNode.hasFocus?24:64,
                   )
                 ],
               ),

+ 140 - 66
lib/pages/my/login/page/login_page.dart

@@ -37,6 +37,7 @@ class _LoginPageState extends State<LoginPage> {
   final TextEditingController _mobileCtrl = TextEditingController();
   bool _isAgree = false;
   bool _isGetCaptcha = false;
+  FocusNode focusNode = new FocusNode();
 
   @override
   void initState() {
@@ -59,6 +60,17 @@ class _LoginPageState extends State<LoginPage> {
     //     ToastUtil.showMsg(event.msg!);
     //   }
     // });
+
+    focusNode.addListener(() {
+      if (!focusNode.hasFocus) {
+        Future.delayed(Duration(milliseconds: 130), (){
+          setState(() {});
+        });
+      }
+      else {
+        setState(() {});
+      }
+    });
   }
 
   @override
@@ -205,11 +217,12 @@ class _LoginPageState extends State<LoginPage> {
                               style: TextStyle(fontSize: 16.sp, color: RgbColor(32, 32, 31, 1), fontWeight: FontWeight.w500),
                               keyboardType: TextInputType.number,
                               cursorColor: HexColor(HexColor.SLS_FCA14C),
+                              focusNode: focusNode,
                               decoration: InputDecoration(
                                   border: InputBorder.none,
                                   hintText: "请输入手机号",
                                   hintStyle: TextStyle(
-                                    color: HexColor("#000000").withOpacity(0.5)
+                                    color: HexColor("#000000").withOpacity(0.1)
                                   )
                                   //contentPadding: EdgeInsets.only(left: 17.w, right: 15.w)
                               ),
@@ -259,70 +272,131 @@ class _LoginPageState extends State<LoginPage> {
                 Container(
                   alignment: Alignment.center,
                   height: 16.h,
-                  child: RichText(
-                      text: TextSpan(
-                          text: "",
-                          children: [
-                            WidgetSpan(
-                                alignment: PlaceholderAlignment.middle,
-                                child: GestureDetector(
-                                  child: Image.asset(
-                                    _isAgree?A.assets_images_login_select:A.assets_images_login_unselect,
-                                    width: 16.h,
-                                    height: 16.h,
-                                    fit: BoxFit.fill,
-                                  ),
-                                  onTap: (){
-                                    _isAgree = !_isAgree;
-                                    setState(() {});
-                                  },
-                                )
-                            ),
-                            TextSpan(
-                                text: " 登录代表您已同意",
-                                style: TextStyle(
-                                    fontSize: 10.sp,
-                                    color: RgbColor(153, 153, 153, 1),
-
-                                ),
-                                recognizer: TapGestureRecognizer()
-                                  ..onTap = (){
-                                    _isAgree = !_isAgree;
-                                    setState(() {});
-                                  }
-                            ),
-                            TextSpan(
-                              text: "《用户服务协议》",
-                              style: TextStyle(
-                                  fontSize: 10.sp,
-                                  color: RgbColor(252, 161, 76, 1)
-                              ),
-                              recognizer: TapGestureRecognizer()
-                                ..onTap = (){
-                                  Get.to(UserAgreementPage());
-                                },
-                            ),
-                            TextSpan(
-                                text: "与",
-                                style: TextStyle(
-                                    fontSize: 10.sp,
-                                    color: RgbColor(153, 153, 153, 1)
-                                )
-                            ),
-                            TextSpan(
-                              text: "《隐私政策》",
-                              style: TextStyle(
-                                  fontSize: 10.sp,
-                                  color: RgbColor(252, 161, 76, 1)
-                              ),
-                              recognizer: TapGestureRecognizer()
-                                ..onTap = (){
-                                  Get.to(PrivacyPolicyPage());
-                                },
-                            )
-                          ]
-                      )
-                  ),
+                  child: Row(
+                    mainAxisAlignment: MainAxisAlignment.center,
+                    children: [
+                      InkWell(
+                        child: Image.asset(
+                          _isAgree?A.assets_images_login_select:A.assets_images_login_unselect,
+                          width: 16.h,
+                          height: 16.h,
+                          fit: BoxFit.fill,
+                        ),
+                        onTap: (){
+                          _isAgree = !_isAgree;
+                          setState(() {});
+                        },
+                      ),
+                      InkWell(
+                        child: Text(
+                            " 登录代表您已同意",
+                          style: TextStyle(
+                            fontSize: 10.sp,
+                            color: RgbColor(153, 153, 153, 1),
+                          ),
+                        ),
+                        onTap: (){
+                          _isAgree = !_isAgree;
+                          setState(() {});
+                        },
+                      ),
+                      InkWell(
+                        child: Text(
+                          "《用户服务协议》",
+                          style: TextStyle(
+                            fontSize: 10.sp,
+                            color: RgbColor(252, 161, 76, 1),
+                          ),
+                        ),
+                        onTap: (){
+                          Get.to(UserAgreementPage());
+                        },
+                      ),
+                      Text(
+                        "与",
+                        style: TextStyle(
+                          fontSize: 10.sp,
+                          color: RgbColor(153, 153, 153, 1),
+                        ),
+                      ),
+                      InkWell(
+                        child: Text(
+                          "《隐私政策》",
+                          style: TextStyle(
+                            fontSize: 10.sp,
+                            color: RgbColor(252, 161, 76, 1),
+                          ),
+                        ),
+                        onTap: (){
+                          Get.to(PrivacyPolicyPage());
+                        },
+                      ),
+                    ],
+                  )
+                  // RichText(
+                  //     text: TextSpan(
+                  //         text: "",
+                  //         children: [
+                  //           WidgetSpan(
+                  //               alignment: PlaceholderAlignment.middle,
+                  //               child: GestureDetector(
+                  //                 child: Image.asset(
+                  //                   _isAgree?A.assets_images_login_select:A.assets_images_login_unselect,
+                  //                   width: 16.h,
+                  //                   height: 16.h,
+                  //                   fit: BoxFit.fill,
+                  //                 ),
+                  //                 onTap: (){
+                  //                   _isAgree = !_isAgree;
+                  //                   setState(() {});
+                  //                 },
+                  //               )
+                  //           ),
+                  //           TextSpan(
+                  //               text: " 登录代表您已同意",
+                  //               style: TextStyle(
+                  //                   fontSize: 10.sp,
+                  //                   color: RgbColor(153, 153, 153, 1),
+                  //
+                  //               ),
+                  //               recognizer: TapGestureRecognizer()
+                  //                 ..onTap = (){
+                  //                   _isAgree = !_isAgree;
+                  //                   setState(() {});
+                  //                 }
+                  //           ),
+                  //           TextSpan(
+                  //             text: "《用户服务协议》",
+                  //             style: TextStyle(
+                  //                 fontSize: 10.sp,
+                  //                 color: RgbColor(252, 161, 76, 1)
+                  //             ),
+                  //             recognizer: TapGestureRecognizer()
+                  //               ..onTap = (){
+                  //                 Get.to(UserAgreementPage());
+                  //               },
+                  //           ),
+                  //           TextSpan(
+                  //               text: "与",
+                  //               style: TextStyle(
+                  //                   fontSize: 10.sp,
+                  //                   color: RgbColor(153, 153, 153, 1)
+                  //               )
+                  //           ),
+                  //           TextSpan(
+                  //             text: "《隐私政策》",
+                  //             style: TextStyle(
+                  //                 fontSize: 10.sp,
+                  //                 color: RgbColor(252, 161, 76, 1)
+                  //             ),
+                  //             recognizer: TapGestureRecognizer()
+                  //               ..onTap = (){
+                  //                 Get.to(PrivacyPolicyPage());
+                  //               },
+                  //           )
+                  //         ]
+                  //     )
+                  // ),
                 ),
                 Spacer(),
                 if (AppService().isWeChatLogin())
@@ -341,7 +415,7 @@ class _LoginPageState extends State<LoginPage> {
                         ),
                         InkWell(
                           child: Container(
-                            margin: EdgeInsets.only(top: 16.h, bottom: 64.h),
+                            margin: EdgeInsets.only(top: 16.h, bottom: focusNode.hasFocus?24:64),
                             height: 48.h,
                             alignment: Alignment.center,
                             child: Image.asset(

+ 5 - 124
lib/pages/my/login/page/privacy_policy_page.dart

@@ -5,6 +5,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
 
 import '../../../../net/http_url.dart';
 import '../../../../net/http_utils.dart';
+import '../../../../utils/base_app_bar.dart';
 import '../../../../utils/toast_utils.dart';
 
 class PrivacyPolicyPage extends StatefulWidget {
@@ -12,110 +13,6 @@ class PrivacyPolicyPage extends StatefulWidget {
   _PrivacyPolicyPageState createState() => _PrivacyPolicyPageState();
 }
 
-// const htmlData = """
-//             <div>更新日期:<strong>2022/06/10</strong></div>
-//             <div>生效日期:<strong>2022/06/10</strong></div>
-//             <h2>导言</h2>
-//             <p>
-//                 <i>天天诗词</i> 是一款由 <i>北京美妙动听音乐有限公司</i> (以下简称”我们“)提供的产品。
-//                 您在使用我们的服务时,我们可能会收集和使用您的相关信息。我们希望通过本《隐私政策》向您说明,在使用我们的服务时,我们如何收集、使用、储存和分享这些信息,以及我们为您提供的访问、更新、控制和保护这些信息的方式。
-//                 本《隐私政策》与您所使用的 <i>天天诗词</i> 服务息息相关,希望您仔细阅读,在需要时,按照本《隐私政策》的指引,作出您认为适当的选择。本《隐私政策》中涉及的相关技术词汇,我们尽量以简明扼要的表述,并提供进一步说明的链接,以便您的理解。
-//             </p>
-//             <p><strong>您使用或继续使用我们的服务,即意味着同意我们按照本《隐私政策》收集、使用、储存和分享您的相关信息。</strong></p>
-//             <p>如对本《隐私政策》或相关事宜有任何问题,请通过 <strong>meimiaodongting@126.com</strong> 与我们联系。</p>
-//
-//             <h2>1. 我们收集的信息</h2>
-//             <p>我们或我们的第三方合作伙伴提供服务时,可能会收集、储存和使用下列与您有关的信息。如果您不提供相关信息,可能无法注册成为我们的用户或无法享受我们提供的某些服务,或者无法达到相关服务拟达到的效果。</p>
-//
-//             <ul>
-//                 <li><strong>位置信息</strong>,指您开启设备定位功能并使用我们基于位置提供的相关服务时,收集的有关您位置的信息,包括:<ul><li>您通过具有定位功能的移动设备使用我们的服务时,通过GPS或WiFi等方式收集的您的地理位置信息;</li><li>您可以通过关闭定位功能,停止对您的地理位置信息的收集。</li></ul></li>
-//             </ul>
-//
-//             <h2>2. 信息的存储</h2>
-//             <strong>2.1 信息存储的方式和期限</strong>
-//             <ul>
-//                 <li>我们会通过安全的方式存储您的信息,包括本地存储(例如利用APP进行数据缓存)、数据库和服务器日志。</li>
-//                 <li>一般情况下,我们只会在为实现服务目的所必需的时间内或法律法规规定的条件下存储您的个人信息。</li>
-//             </ul>
-//
-//             <strong>2.2 信息存储的地域</strong>
-//             <ul>
-//                 <li>我们会按照法律法规规定,将境内收集的用户个人信息存储于中国境内。</li>
-//                 <li>目前我们不会跨境传输或存储您的个人信息。将来如需跨境传输或存储的,我们会向您告知信息出境的目的、接收方、安全保证措施和安全风险,并征得您的同意。</li>
-//             </ul>
-//
-//             <strong>2.3 产品或服务停止运营时的通知</strong>
-//             <ul>
-//                 <li>当我们的产品或服务发生停止运营的情况时,我们将以推送通知、公告等形式通知您,并在合理期限内删除您的个人信息或进行匿名化处理,法律法规另有规定的除外。</li>
-//             </ul>
-//
-//             <h2>3. 信息安全</h2>
-//             <p>
-//                 我们使用各种安全技术和程序,以防信息的丢失、不当使用、未经授权阅览或披露。例如,在某些服务中,我们将利用加密技术(例如SSL)来保护您提供的个人信息。但请您理解,由于技术的限制以及可能存在的各种恶意手段,在互联网行业,即便竭尽所能加强安全措施,也不可能始终保证信息百分之百的安全。您需要了解,您接入我们的服务所用的系统和通讯网络,有可能因我们可控范围外的因素而出现问题。
-//             </p>
-//
-//             <h2>4. 我们如何使用信息</h2>
-//             <p>我们可能将在向您提供服务的过程之中所收集的信息用作下列用途:</p>
-//             <ul>
-//                 <li>向您提供服务;</li>
-//                 <li>在我们提供服务时,用于身份验证、客户服务、安全防范、诈骗监测、存档和备份用途,确保我们向您提供的产品和服务的安全性;</li>
-//                 <li>帮助我们设计新服务,改善我们现有服务;</li>
-//                 <li>使我们更加了解您如何接入和使用我们的服务,从而针对性地回应您的个性化需求,例如语言设定、位置设定、个性化的帮助服务和指示,或对您和其他用户作出其他方面的回应;</li>
-//                 <li>向您提供与您更加相关的广告以替代普遍投放的广告;</li>
-//                 <li>评估我们服务中的广告和其他促销及推广活动的效果,并加以改善;</li>
-//                 <li>软件认证或管理软件升级;</li>
-//                 <li>让您参与有关我们产品和服务的调查。</li>
-//             </ul>
-//
-//             <h2>5. 信息共享</h2>
-//             <p>
-//                 目前,我们不会主动共享或转让您的个人信息至第三方,如存在其他共享或转让您的个人信息或您需要我们将您的个人信息共享或转让至第三方情形时,我们会直接或确认第三方征得您对上述行为的明示同意。
-//             </p>
-//             <p>
-//                 为了投放广告,评估、优化广告投放效果等目的,我们需要向广告主及其代理商等第三方合作伙伴共享您的部分数据,要求其严格遵守我们关于数据隐私保护的措施与要求,包括但不限于根据数据保护协议、承诺书及相关数据处理政策进行处理,避免识别出个人身份,保障隐私安全。
-//             </p>
-//             <p>
-//                 我们不会向合作伙伴分享可用于识别您个人身份的信息(例如您的姓名或电子邮件地址),除非您明确授权。
-//             </p>
-//             <p>
-//                 我们不会对外公开披露所收集的个人信息,如必须公开披露时,我们会向您告知此次公开披露的目的、披露信息的类型及可能涉及的敏感信息,并征得您的明示同意。
-//             </p>
-//             <p>
-//                 随着我们业务的持续发展,我们有可能进行合并、收购、资产转让等交易,我们将告知您相关情形,按照法律法规及不低于本《隐私政策》所要求的标准继续保护或要求新的控制者继续保护您的个人信息。
-//             </p>
-//             <p>
-//                 另外,根据相关法律法规及国家标准,以下情形中,我们可能会共享、转让、公开披露个人信息无需事先征得您的授权同意:
-//             </p>
-//             <ul>
-//                 <li>与国家安全、国防安全直接相关的;</li>
-//                 <li>与公共安全、公共卫生、重大公共利益直接相关的;</li>
-//                 <li>犯罪侦查、起诉、审判和判决执行等直接相关的;</li>
-//                 <li>出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到本人同意的;</li>
-//                 <li>个人信息主体自行向社会公众公开个人信息的;</li>
-//                 <li>从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道。</li>
-//             </ul>
-//
-//             <h2>6. 您的权利</h2>
-//             <p>
-//                 在您使用我们的服务期间,我们可能会视产品具体情况为您提供相应的操作设置,以便您可以查询、删除、更正或撤回您的相关个人信息,您可参考相应的具体指引进行操作。此外,我们还设置了投诉举报渠道,您的意见将会得到及时的处理。如果您无法通过上述途径和方式行使您的个人信息主体权利,您可以通过本《隐私政策》中提供的联系方式提出您的请求,我们会按照法律法规的规定予以反馈。
-//             </p>
-//
-//
-//             <h2>7. 变更</h2>
-//             <p>
-//                 我们可能适时修订本《隐私政策》的条款。当变更发生时,我们会在版本更新时向您提示新的《隐私政策》,并向您说明生效日期。请您仔细阅读变更后的《隐私政策》内容,<strong>若您继续使用我们的服务,即表示您同意我们按照更新后的《隐私政策》处理您的个人信息。</strong>
-//             </p>
-//
-//             <h2>8. 未成年人保护</h2>
-//             <p>
-//                 我们鼓励父母或监护人指导未满十八岁的未成年人使用我们的服务。我们建议未成年人鼓励他们的父母或监护人阅读本《隐私政策》,并建议未成年人在提交的个人信息之前寻求父母或监护人的同意和指导。
-//             </p>
-//              <h2>9. 注销账户</h2>
-//              <p>
-//              您有权注销账号,具体流程如下:在主页面点击我的,点击设置,点击注销账号。您注销成功后,我们将根据法律法规的要求删除您的个人信息。
-//              </p>
-// """;
-
 class _PrivacyPolicyPageState extends State<PrivacyPolicyPage> {
 
   String _privacyPolicy = "";
@@ -134,11 +31,11 @@ class _PrivacyPolicyPageState extends State<PrivacyPolicyPage> {
     HttpUtils.get<String>(HttpUrl.privacy_policy_URL, queryParameters: {}).then((ret) {
       EasyLoading.dismiss();
       if (ret.isSuccess() && ret.data != null) {
-
         _privacyPolicy = ret.data??"";
         setState(() {});
       } else {
-        ToastUtil.showMsg(ret.msg??"");
+        //ToastUtil.showMsg(ret.msg??"");
+        _requestPrivacyPolicyData();
       }
     });
   }
@@ -146,24 +43,8 @@ class _PrivacyPolicyPageState extends State<PrivacyPolicyPage> {
   @override
   Widget build(BuildContext context) {
     return Scaffold(
-      appBar: AppBar(
-        centerTitle: true,
-        title: Text(
-          '隐私政策',
-          style: TextStyle(color: Colors.black, fontSize: 18.w),
-        ),
-        backgroundColor: Colors.white,
-        elevation: 0,
-        leading: GestureDetector(
-          onTap: () {
-            Navigator.of(context).pop();
-          },
-          child: Icon(
-            Icons.arrow_back_ios,
-            color: Colors.black,
-            size: 24.w,
-          ),
-        ),
+      appBar: BaseAppBar(
+        titleStr: "隐私政策",
       ),
       body: SingleChildScrollView(
         child: Html(

+ 5 - 61
lib/pages/my/login/page/user_agreement_page.dart

@@ -5,6 +5,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
 
 import '../../../../net/http_url.dart';
 import '../../../../net/http_utils.dart';
+import '../../../../utils/base_app_bar.dart';
 import '../../../../utils/toast_utils.dart';
 
 class UserAgreementPage extends StatefulWidget {
@@ -12,47 +13,6 @@ class UserAgreementPage extends StatefulWidget {
   _UserAgreementPageState createState() => _UserAgreementPageState();
 }
 
-// const htmlData = """
-// <p>欢迎使用北京美妙动听乐有限公司(以下简称“公司”)所提供的服务。为使用公司提供的服务,您应当阅读并遵守以下用户协议(以下简称“协议”)。</p>
-// <h4>一、定义</h4>
-// <p>1.1 本协议中,除非另有定义,下列词语具有如下含义:</p>
-// <p>(1)公司提供的服务:指公司通过其所有的产品和/或服务向用户提供的各项功能和服务。</p>
-// <p>(2)用户:指通过公司的产品和/或服务使用公司提供的服务的个人或组织。</p>
-// <h4>二、使用规则</h4>
-// <p>2.1 您在使用公司提供的服务时,应遵守中华人民共和国相关法律法规的规定,不得利用公司的服务从事任何违法活动,包括但不限于:</p>
-// <p>(1)发布、传送、传播、储存侵害他人知识产权、商业秘密等合法权利的内容;</p><p>(2)发布、传送、传播、储存淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪的内容;</p>
-// <p>(3)以任何方式危害国家安全、泄露国家秘密,颠覆国家政权,破坏国家统一的;</p>
-// <p>(4)以任何方式妨害他人合法权益的;</p>
-// <p>(5)发布、传送、传播广告信息及垃圾信息;</p>
-// <p>(6)其他违反中国法律、法规、规章、规范性文件的行为。</p>
-// <p>2.2 您理解并同意,公司有权对您使用公司提供的服务的情况进行审查和监督,如您违反上述规定,公司有权依据协议约定进行处理。</p>
-// <h4>三、服务内容</h4>
-// <p>3.1 公司提供的具体服务内容由公司根据实际情况提供,并随时变更、中断或终止部分或全部服务。</p>
-// <p>3.2 您理解并同意,公司并不保证提供的服务一定能满足您的要求,也不保证服务不会中断,对于因系统维护或升级的需要而需暂停服务的情况,公司将尽可能事先进行通告。</p>
-// <h4>四、隐私保护</h4>
-// <p>4.1 您同意并认可,为了向您提供更好的服务,公司有权在您使用服务时自动收集数据,并存储、使用该数据。</p>
-// <p>4.2 公司承诺不对外公开或向第三方提供您的个人数据,但下列情况除外:</p>
-// <p>(1)事先获得您的明确授权;</p>
-// <p>(2)根据有关法律法规、规章的要求;</p>
-// <p>(3)按照相关政府主管部门的要求;</p>
-// <p>(4)为维护公司的合法权益;</p>
-// <p>(5)为维护公共利益。</p>
-// <h4>五、责任范围</h4>
-// <p>5.1 您使用服务所存在的风险由您自行承担;因您使用服务产生的一切后果也由您自行承担,公司对您不承担任何责任。</p>
-// <p>5.2 公司不保证为向您提供便利而设置的外部链接的准确性和完整性,同时,对于该等外部链接指向的不由公司实际控制的任何网页上的内容,公司不承担任何责任。</p>
-// <p>5.3 对于因不可抗力或公司不能控制的原因造成的网络服务中断或其它缺陷,公司不承担任何责任,但将尽力减少因此而给您造成的损失和影响。</p>
-// <h4>六、法律适用和管辖</h4>
-// <p>6.1 本协议的订立、执行和解释及争议的解决均应适用中华人民共和国法律。</p>
-// <p>6.2 如双方就本协议内容或其执行发生任何争议,双方应尽力友好协商解决;协商不成时,任何一方均可向公司所在地的人民法院提起诉讼。</p>
-// <h4>七、其他</h4>
-// <p>7.1 本协议构成双方对本协议之约定事项及其他有关事宜的完整协议,除本协议规定的之外,未赋予本协议各方其他权利。</p>
-// <p>7.2 如本协议中的任何条款无论因何种原因完全或部分无效或不具有执行力,本协议的其余条款仍应有效并且有约束力。</p>
-// <p>7.3 本协议中的标题仅为方便而设,不具法律或契约效果。</p>
-// <p>7.4 本协议未尽事宜,由双方协商解决。</p>
-// <p>7.5 本协议中的任何条款无论因何种原因变更,变更后的协议条款对双方均有约束力。</p>
-// <p>该用户协议一旦发布即代表您与北京美妙动听乐有限公司已经达成协议,并同意接受本协议的所有内容。</p>
-// """;
-
 class _UserAgreementPageState extends State<UserAgreementPage> {
 
   String _userAgreement = "";
@@ -71,11 +31,11 @@ class _UserAgreementPageState extends State<UserAgreementPage> {
     HttpUtils.get<String>(HttpUrl.user_agreement_URL, queryParameters: {}).then((ret) {
       EasyLoading.dismiss();
       if (ret.isSuccess() && ret.data != null) {
-
         _userAgreement = ret.data??"";
         setState(() {});
       } else {
-        ToastUtil.showMsg(ret.msg??"");
+        //ToastUtil.showMsg(ret.msg??"");
+        _requestPrivacyPolicyData();
       }
     });
   }
@@ -84,24 +44,8 @@ class _UserAgreementPageState extends State<UserAgreementPage> {
   @override
   Widget build(BuildContext context) {
     return Scaffold(
-      appBar: AppBar(
-        centerTitle: true,
-        title: Text(
-          '用户协议',
-          style: TextStyle(color: Colors.black, fontSize: 18.w),
-        ),
-        backgroundColor: Colors.white,
-        elevation: 0,
-        leading: GestureDetector(
-          onTap: () {
-            Navigator.of(context).pop();
-          },
-          child: Icon(
-            Icons.arrow_back_ios,
-            color: Colors.black,
-            size: 24.w,
-          ),
-        ),
+      appBar: BaseAppBar(
+        titleStr: "用户协议",
       ),
       body: SingleChildScrollView(
         child: Html(

+ 8 - 0
lib/pages/my/main/controller/mine_ctrl.dart

@@ -31,6 +31,7 @@ class MineCtrl extends GetxController with GetTickerProviderStateMixin{
   StreamSubscription? _moodRecordSucceedEvent;
   StreamSubscription? _practiceOrAssessEvent;
   StreamSubscription? _appConfigEvent;
+  //StreamSubscription? _firstInstallEvent;
   UserStatModel? userStatModel;
   MoodStatModel moodStatModel = MoodStatModel();
   Color selectedColor = Colors.white;
@@ -94,6 +95,11 @@ class MineCtrl extends GetxController with GetTickerProviderStateMixin{
             update(["userInfo"]);
           }
         });
+
+    // _firstInstallEvent =
+    //     AppEvent.getInstance()?.on<FirstInstallReloadDataEvent>().listen((event) {
+    //       requestRecommend();
+    //     });
   }
 
   @override
@@ -104,6 +110,8 @@ class MineCtrl extends GetxController with GetTickerProviderStateMixin{
     _loginOrLogoutEvent?.cancel();
     _moodRecordSucceedEvent?.cancel();
     _practiceOrAssessEvent?.cancel();
+    _appConfigEvent?.cancel();
+    //_firstInstallEvent?.cancel();
   }
 
   void onScroll(offset) {

+ 1 - 0
lib/pages/my/main/controller/personal_info_ctrl.dart

@@ -38,6 +38,7 @@ class PersonalInfoCtrl extends GetxController {
   FocusNode captchaNode = new FocusNode();
   FocusNode newPhoneNode = new FocusNode();
   int nicknameLength = 0;
+  String maxNickName = "";
 
   @override
   void onInit() {

+ 1 - 1
lib/pages/my/main/model/user_model.dart

@@ -17,7 +17,7 @@ class UserModel {
 	String? desc;
 	String? token;
 	bool? firstRegister;
-	int? vipStatus; //-1过期,0没有订阅,1是会员不是自动续费,2是会员月度自动续费,3是会员年度自动续费
+	int? vipStatus; //-1过期,0没有订阅,1是会员不是自动续费月卡,2是会员不是自动续费年卡,3是会员月度自动续费,4是会员年度自动续费
 	String? vipStartTime;
 	String? vipEndTime;
 

+ 20 - 4
lib/pages/my/main/page/personal_info_page.dart

@@ -5,6 +5,7 @@ import 'package:adaptive_dialog/adaptive_dialog.dart';
 import 'package:cached_network_image/cached_network_image.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_easyloading/flutter_easyloading.dart';
 import 'package:flutter_screenutil/flutter_screenutil.dart';
 import 'package:get/get.dart';
 import 'package:poetry/pages/my/main/controller/personal_info_ctrl.dart';
@@ -203,8 +204,13 @@ class PersonalInfoPage extends GetView<PersonalInfoCtrl> {
                               ),
                               onTap: () {
                                 if (_.isSave) {
-                                  Get.back();
-                                  _.submitNickname();
+                                  if (_.nicknameLength > 24) {
+                                    EasyLoading.showError("昵称最大限制12个中文字");
+                                  }
+                                  else {
+                                    Get.back();
+                                    _.submitNickname();
+                                  }
                                 }
                               },
                             ),
@@ -229,10 +235,11 @@ class PersonalInfoPage extends GetView<PersonalInfoCtrl> {
                           child: Row(
                             children: [
                               Expanded(
-                                child: TextField(
+                                child: TextField (
                                   controller: _.nicknameTextCtrl,
                                   autofocus: true,
-                                  maxLength: 24,
+                                  //maxLength: 24,
+
                                   cursorColor: HexColor(HexColor.SLS_FCA14C),
                                   style: TextStyle(
                                     fontSize: 14.sp,
@@ -263,6 +270,15 @@ class PersonalInfoPage extends GetView<PersonalInfoCtrl> {
                                         _.nicknameLength += 2;
                                     }
                                   }
+
+                                    // if (_.nicknameLength == 24) {
+                                    //   _.maxNickName = _.nicknameTextCtrl.text;
+                                    // }
+                                    // else if (_.nicknameLength > 24) {
+                                    //   _.nicknameTextCtrl.text = _.maxNickName;
+                                    //   _.nicknameLength = 24;
+                                    // }
+
                                     _.update(["edit_nickname"]);
                                   },
                                 ),

+ 53 - 53
lib/pages/my/main/view/mine_info_view.dart

@@ -114,61 +114,61 @@ class MyInfoView extends GetView<MineCtrl> {
                             Get.to(()=>PersonalInfoPage(), binding: PersonalInfoBinding());
                           },
                         ),
-                        if (AppService().isWeChatPay())
-                          (userModel.vipStatus??0)>0?Container(
-                            margin: EdgeInsets.only(top: 4.w, bottom: 3.w+3),
-                            width: 32.w,
-                            height: 16.w,
-                            child: Image.asset(
-                              A.assets_images_mine_pro_ic2,
-                              fit: BoxFit.fill,
+                        // if (AppService().isWeChatPay())
+                        (userModel.vipStatus??0)>0?Container(
+                          margin: EdgeInsets.only(top: 4.w, bottom: 3.w+3),
+                          width: 32.w,
+                          height: 16.w,
+                          child: Image.asset(
+                            A.assets_images_mine_pro_ic2,
+                            fit: BoxFit.fill,
+                          ),
+                        ):InkWell(
+                          child: Container(
+                            margin: EdgeInsets.only(bottom: 3.w+3),
+                            height: 20.w,
+                            width: 102.w,
+                            alignment: Alignment.center,
+                            decoration: BoxDecoration(
+                                color: HexColor("#CCCCCC"),
+                                borderRadius: BorderRadius.circular(10.w)
                             ),
-                          ):InkWell(
-                            child: Container(
-                              margin: EdgeInsets.only(bottom: 3.w+3),
-                              height: 20.w,
-                              width: 102.w,
-                              alignment: Alignment.center,
-                              decoration: BoxDecoration(
-                                  color: HexColor("#CCCCCC"),
-                                  borderRadius: BorderRadius.circular(10.w)
-                              ),
-                              child: RichText(
-                                  text: TextSpan(
-                                      text: "",
-                                      children: [
-                                        TextSpan(
-                                          text: "升级至",
-                                          style: TextStyle(
-                                              fontSize: 10.sp,
-                                              color: HexColor("#FFFFFF"),
-                                              fontWeight: FontWeight.w500
-                                          ),
+                            child: RichText(
+                                text: TextSpan(
+                                    text: "",
+                                    children: [
+                                      TextSpan(
+                                        text: "升级至",
+                                        style: TextStyle(
+                                            fontSize: 10.sp,
+                                            color: HexColor("#FFFFFF"),
+                                            fontWeight: FontWeight.w500
                                         ),
-                                        WidgetSpan(
-                                          alignment: PlaceholderAlignment.middle,
-                                          child: Image.asset(
-                                            A.assets_images_mine_pro_ic,
-                                            width: 21.w,
-                                            height: 16.w,
-                                          ),
+                                      ),
+                                      WidgetSpan(
+                                        alignment: PlaceholderAlignment.middle,
+                                        child: Image.asset(
+                                          A.assets_images_mine_pro_ic,
+                                          width: 21.w,
+                                          height: 16.w,
                                         ),
-                                        TextSpan(
-                                          text: "专业版",
-                                          style: TextStyle(
-                                              fontSize: 10.sp,
-                                              color: HexColor("#FFFFFF"),
-                                              fontWeight: FontWeight.w500
-                                          ),
+                                      ),
+                                      TextSpan(
+                                        text: "专业版",
+                                        style: TextStyle(
+                                            fontSize: 10.sp,
+                                            color: HexColor("#FFFFFF"),
+                                            fontWeight: FontWeight.w500
                                         ),
-                                      ]
-                                  )
-                              ),
+                                      ),
+                                    ]
+                                )
                             ),
-                            onTap: (){
-                              Get.to(()=>VipBuyPage());
-                            },
-                          )
+                          ),
+                          onTap: (){
+                            Get.to(()=>VipBuyPage());
+                          },
+                        )
                       ],
                     ):InkWell(
                       child: Text(
@@ -211,7 +211,7 @@ class MyInfoView extends GetView<MineCtrl> {
                                 text: "",
                                 children: [
                                   TextSpan(
-                                    text: ((userStatModel.duration??0)/60).ceil().toString(),
+                                    text: isLogin?((userStatModel.duration??0)/60).ceil().toString():"-",
                                     style: TextStyle(
                                         fontSize: 20.sp,
                                         color: HexColor("#20201F"),
@@ -254,7 +254,7 @@ class MyInfoView extends GetView<MineCtrl> {
                                 text: "",
                                 children: [
                                   TextSpan(
-                                    text: (userStatModel.wordCount??0).toString(),
+                                    text: isLogin?(userStatModel.wordCount??0).toString():"-",
                                     style: TextStyle(
                                         fontSize: 20.sp,
                                         color: HexColor("#20201F"),
@@ -296,7 +296,7 @@ class MyInfoView extends GetView<MineCtrl> {
                                 text: "",
                                 children: [
                                   TextSpan(
-                                    text: (userStatModel.practiceCount??0).toString(),
+                                    text: isLogin?(userStatModel.practiceCount??0).toString():"-",
                                     style: TextStyle(
                                         fontSize: 20.sp,
                                         color: HexColor("#20201F"),

+ 1 - 1
lib/pages/my/mood_analysis/view/calendar_view.dart

@@ -100,7 +100,7 @@ class CalendarView extends StatelessWidget {
                 _titleList[index],
                 textAlign: TextAlign.center,
                 style: TextStyle(
-                    fontSize: 14.sp,
+                    fontSize: 12.sp,
                     color: RgbColor.rgb_999999
                 ),
               ),

+ 11 - 2
lib/pages/my/setting/page/order_manage_page.dart

@@ -5,6 +5,7 @@ import 'package:get/get.dart';
 import 'package:poetry/pages/my/setting/view/order_manage_cell.dart';
 import 'package:pull_to_refresh/pull_to_refresh.dart';
 
+import '../../../../common/empty_data_page.dart';
 import '../../../../net/http_url.dart';
 import '../../../../net/http_utils.dart';
 import '../../../../routers/app_routers.dart';
@@ -98,7 +99,10 @@ class _OrderManageState extends State<OrderManagePage> {
           canLoadingText: "松开开始加载数据",
           noDataText: "已展示全部内容啦",
         ),
-        child: ListView.builder(
+        child: (_orderList.isEmpty && !_isFirstRequest)?EmptyDataPage(
+          title: "暂时没有订单",
+          subTitle: "",
+        ):ListView.builder(
             physics: BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
             shrinkWrap: true,
             itemCount: _orderList.length,
@@ -107,7 +111,12 @@ class _OrderManageState extends State<OrderManagePage> {
               return InkWell(
                 child: OrderManageCell(favoriteRecords: favoriteRecords),
                 onTap: (){
-                  Get.toNamed(AppRouters.practiceDetailPage+"?practiceId="+favoriteRecords.contentId.toString()+"&type="+favoriteRecords.type.toString());
+                  if (favoriteRecords.type == 2){ //测评
+                    Get.toNamed(AppRouters.practiceDetailPage+"?practiceId="+favoriteRecords.contentId.toString()+"&type=3");
+                  }
+                  else if (favoriteRecords.type == 3) { //练习
+                    Get.toNamed(AppRouters.practiceDetailPage+"?practiceId="+favoriteRecords.contentId.toString()+"&type="+favoriteRecords.subType.toString());
+                  }
                 },
               );
             }

+ 14 - 4
lib/pages/my/setting/page/setting_page.dart

@@ -1,6 +1,7 @@
 
 import 'package:adaptive_dialog/adaptive_dialog.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_easyloading/flutter_easyloading.dart';
 import 'package:flutter_screenutil/flutter_screenutil.dart';
 import 'package:get/get.dart';
 import 'package:poetry/module/user_service.dart';
@@ -8,7 +9,10 @@ import 'package:poetry/routers/app_routers.dart';
 import 'package:poetry/utils/hex_color.dart';
 import 'package:poetry/utils/rgb_color.dart';
 import 'package:poetry/utils/time_util.dart';
+import 'package:poetry/utils/toast_utils.dart';
 
+import '../../../../net/http_url.dart';
+import '../../../../net/http_utils.dart';
 import '../../../../utils/base_app_bar.dart';
 import '../../../../utils/tips_dialog.dart';
 
@@ -46,9 +50,6 @@ class _SettingState extends State<SettingPage>
       ];
     }
 
-    // String timestamp = "1698998424";
-    // String time = TimeUtil.getTimeWithTimeStamp(timestamp, "yyyy-MM-dd HH:mm:ss");
-    // print("time = " + time);
   }
 
   @override
@@ -165,7 +166,16 @@ class _SettingState extends State<SettingPage>
   //提交注销账号
   void _submitLogoffAccount() {
 
-
+    EasyLoading.show();
+    HttpUtils.post(HttpUrl.user_logoff_URL, queryParameters: {}).then((ret) {
+      EasyLoading.dismiss();
+      if (ret.isSuccess() && ret.data != null) {
+        UserService().logout();
+        Get.back();
+      } else {
+        ToastUtil.showMsg(ret.msg??"");
+      }
+    });
   }
 
   @override

+ 168 - 1
lib/pages/my/setting/page/subscription_manage_page.dart

@@ -1,6 +1,16 @@
 
+import 'dart:async';
+
 import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/route_manager.dart';
+import 'package:poetry/module/user_service.dart';
+import 'package:poetry/pages/my/main/model/user_model.dart';
+import 'package:poetry/pages/my/vip/page/vip_buy_page.dart';
+import 'package:poetry/utils/hex_color.dart';
+import 'package:poetry/utils/time_util.dart';
 
+import '../../../../utils/app_event.dart';
 import '../../../../utils/base_app_bar.dart';
 
 class SubscriptionManagePage extends StatefulWidget {
@@ -10,13 +20,170 @@ class SubscriptionManagePage extends StatefulWidget {
 
 class _SubscriptionManageState extends State<SubscriptionManagePage> {
 
+  List<SubscriptionManageModel> _dataList = [];
+  UserModel _userModel = UserModel();
+  StreamSubscription? _reloadUserInfoEvent;
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+
+    initData();
+    _reloadUserInfoEvent =
+        AppEvent.getInstance()?.on<ReloadUserInfoEvent>().listen((event) {
+          initData();
+        });
+  }
+
+  @override
+  void dispose() {
+    // TODO: implement dispose
+    super.dispose();
+    _reloadUserInfoEvent?.cancel();
+  }
+
+  void initData() {
+
+    _userModel = UserService().getUserInfo();
+    _dataList.clear();
+    switch (_userModel.vipStatus){
+      case 1 :
+        _dataList.add(SubscriptionManageModel("订阅状态", "专业版月卡"));
+        _dataList.add(SubscriptionManageModel("专业版有效期至", TimeUtil.getTimeWithTimeStamp(_userModel.vipEndTime??"", "yyyy年MM月dd日")));
+        break;
+      case 2 :
+        _dataList.add(SubscriptionManageModel("订阅状态", "专业版年卡"));
+        _dataList.add(SubscriptionManageModel("专业版有效期至", TimeUtil.getTimeWithTimeStamp(_userModel.vipEndTime??"", "yyyy年MM月dd日")));
+        break;
+      case 3 :
+        _dataList.add(SubscriptionManageModel("订阅状态", "连续包月专业版"));
+        _dataList.add(SubscriptionManageModel("专业版有效期至", TimeUtil.getTimeWithTimeStamp(_userModel.vipEndTime??"", "yyyy年MM月dd日")));
+        break;
+      case 4 :
+        _dataList.add(SubscriptionManageModel("订阅状态", "连续包年专业版"));
+        _dataList.add(SubscriptionManageModel("专业版有效期至", TimeUtil.getTimeWithTimeStamp(_userModel.vipEndTime??"", "yyyy年MM月dd日")));
+        break;
+      default:
+        _dataList.add(SubscriptionManageModel("订阅状态", "未订阅"));
+        _dataList.add(SubscriptionManageModel("专业版有效期至", "未订阅"));
+        break;
+    }
+
+    setState(() {});
+  }
+
   @override
   Widget build(BuildContext context) {
     return Scaffold(
       appBar: BaseAppBar(
-        titleStr: "订阅管理",
+        titleStr: "专业版订阅管理",
         bgColor: Colors.white,
       ),
+      body: SafeArea(
+        child: Column(
+          //crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            Container(
+              child: ListView.builder(
+                  physics: BouncingScrollPhysics(parent: NeverScrollableScrollPhysics()),
+                  shrinkWrap: true,
+                  itemCount: _dataList.length,
+                  itemBuilder: (BuildContext context, int index) {
+                    SubscriptionManageModel model = _dataList[index];
+                    return Container(
+                      margin: EdgeInsets.only(left: 15.w, right: 15.w),
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.start,
+                        children: [
+                          Container(
+                            margin: EdgeInsets.only(top: 10.w),
+                            child: Text(
+                              model.title??"",
+                              style: TextStyle(
+                                  fontSize: 15.sp,
+                                  color: HexColor("#333333"),
+                                  fontWeight: FontWeight.w500
+                              ),
+                            ),
+                          ),
+                          Container(
+                            margin: EdgeInsets.only(top: 10.w),
+                            child: Text(
+                              model.subTitle??"",
+                              style: TextStyle(
+                                  fontSize: 13.sp,
+                                  color: HexColor("#999999"),
+                                  fontWeight: FontWeight.w400
+                              ),
+                            ),
+                          ),
+                          Container(
+                            margin: EdgeInsets.only(top: 10.w, bottom: 10.w),
+                            height: 1,
+                            color: HexColor("#DCDCDC"),
+                          )
+                        ],
+                      ),
+                    );
+                  }
+              ),
+            ),
+            if (_userModel.vipStatus == 3 || _userModel.vipStatus == 4)
+              Container(
+                margin: EdgeInsets.only(left: 15.w, right: 15.w, top: 10.w),
+                child: Text(
+                  "自动续费iTunes账户会在到期前24小时内扣费。在此之前,你可以手动在 iTunes/Apple ID 设置管理中关闭自动续费",
+                  style: TextStyle(
+                      fontSize: 13.sp,
+                      color: HexColor("#999999"),
+                      fontWeight: FontWeight.w400
+                  ),
+                ),
+              ),
+            Spacer(),
+            if (_userModel.vipStatus != 2 && _userModel.vipStatus != 4)
+              InkWell(
+                child: Container(
+                  alignment: Alignment.center,
+                  width: 342.w,
+                  height: 48.h,
+                  decoration: BoxDecoration(
+                      color: HexColor("#FCA14C"),
+                      borderRadius: BorderRadius.circular(24.h)
+                  ),
+                  child: Text(
+                    (_userModel.vipStatus == -1 || _userModel.vipStatus == 0)?"升级至专业版":"升级至专业版年卡",
+                    style: TextStyle(
+                        fontSize: 16.sp,
+                        color: HexColor("#FFFFFF"),
+                        fontWeight: FontWeight.w500
+                    ),
+                  ),
+                ),
+                onTap: () {
+                  if (_userModel.vipStatus == -1 || _userModel.vipStatus == 0){
+                    Get.to(()=>VipBuyPage());
+                  }
+                  else {
+                    Get.to(()=>VipBuyPage(hideMonth: true));
+                  }
+                },
+              ),
+            SizedBox(
+              height: 10,
+            )
+          ],
+        ),
+      ),
     );
   }
 }
+
+class SubscriptionManageModel {
+
+  String? title;
+  String? subTitle;
+
+  SubscriptionManageModel(this.title, this.subTitle);
+}

+ 40 - 4
lib/pages/my/setting/view/order_manage_cell.dart

@@ -8,7 +8,7 @@ import '../../../../gen_a/A.dart';
 import '../../../../utils/hex_color.dart';
 import '../../../../utils/rgb_color.dart';
 import '../../../today/favorite/model/favorite_model.dart';
-import '../../../today/main/view/home_recommend_cell.dart';
+
 
 class OrderManageCell extends StatelessWidget {
 
@@ -31,7 +31,14 @@ class OrderManageCell extends StatelessWidget {
               height: 72.w,
               child: ClipRRect(
                 borderRadius: BorderRadius.circular(9.w),
-                child: CachedNetworkImage(
+                child: (favoriteRecords.coverUrl??"").isEmpty?Container(
+                  padding: EdgeInsets.fromLTRB(10.w, 10.w, 10.w, 10.w),
+                  color: HexColor("#EFEFEF"),
+                  child: Image.asset(
+                    A.assets_images_vip_header_icon,
+                    fit: BoxFit.fill,
+                  ),
+                ):CachedNetworkImage(
                   imageUrl: (favoriteRecords.coverUrl??"")+"?x-oss-process=image/resize,m_lfit,w_216",
                   placeholder: (context, url) => Image.asset(A.assets_images_image_placeholder),
                   errorWidget: (context, url, error) => Image.asset(A.assets_images_image_placeholder),
@@ -70,7 +77,7 @@ class OrderManageCell extends StatelessWidget {
                                 borderRadius: BorderRadius.all(Radius.circular(6.w)),
                                 color: RgbColor.rgb_FAB16D_01
                             ),
-                            child: PracticeTypeView(
+                            child: OrderManageTypeView(
                               type: favoriteRecords.type??0,
                             )
                         ),
@@ -124,4 +131,33 @@ class OrderManageCell extends StatelessWidget {
   }
 }
 
-//
+class OrderManageTypeView extends Container {
+
+  OrderManageTypeView({
+    required int type //1会员,2练习,3测评
+  }):super(
+      height: 20.w,
+      child: Row(
+        children: [
+          SizedBox(
+            width: 5.w,
+          ),
+          Image.asset(type==1?A.assets_images_ic_lable_chapter:type==2?A.assets_images_ic_lable_series:A.assets_images_ic_lable_test,),
+          SizedBox(
+            width: 2.w,
+          ),
+          Text(
+            type==1?"会员":type==2?"测评":"练习",
+            style: TextStyle(
+                fontSize: 10.sp,
+                color: RgbColor.rgb_FCA14C,
+                fontWeight: FontWeight.w500
+            ),
+          ),
+          SizedBox(
+            width: 6.w,
+          )
+        ],
+      )
+  );
+}

+ 56 - 0
lib/pages/my/vip/page/vip_agreement_page.dart

@@ -0,0 +1,56 @@
+
+import 'package:flutter/material.dart';
+import 'package:flutter_easyloading/flutter_easyloading.dart';
+import 'package:flutter_html/flutter_html.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:poetry/utils/base_app_bar.dart';
+
+import '../../../../net/http_url.dart';
+import '../../../../net/http_utils.dart';
+import '../../../../utils/toast_utils.dart';
+
+class VipAgreementPage extends StatefulWidget {
+  @override
+  _VipAgreementState createState() => _VipAgreementState();
+}
+
+class _VipAgreementState extends State<VipAgreementPage> {
+
+  String _vipAgreement = "";
+
+  @override
+  void initState() {
+    // TODO: implement initState
+    super.initState();
+
+    _requestVipAgreementData();
+  }
+
+  void _requestVipAgreementData() {
+
+    EasyLoading.show();
+    HttpUtils.get<String>(HttpUrl.vip_agreement_URL, queryParameters: {}).then((ret) {
+      EasyLoading.dismiss();
+      if (ret.isSuccess() && ret.data != null) {
+        _vipAgreement = ret.data??"";
+        setState(() {});
+      } else {
+        ToastUtil.showMsg(ret.msg??"");
+      }
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: BaseAppBar(
+        titleStr: "会员协议",
+      ),
+      body: SingleChildScrollView(
+        child: Html(
+          data: _vipAgreement,
+        ),
+      ),
+    );
+  }
+}

+ 37 - 64
lib/pages/my/vip/page/vip_buy_page.dart

@@ -10,6 +10,7 @@ import 'package:in_app_purchase/in_app_purchase.dart';
 import 'package:in_app_purchase_storekit/in_app_purchase_storekit.dart';
 import 'package:in_app_purchase_storekit/store_kit_wrappers.dart';
 import 'package:poetry/pages/my/vip/model/vip_buy_model.dart';
+import 'package:poetry/pages/my/vip/page/vip_agreement_page.dart';
 import 'package:sp_util/sp_util.dart';
 import 'package:universal_platform/universal_platform.dart';
 
@@ -27,6 +28,12 @@ import '../../main/model/user_model.dart';
 
 class VipBuyPage extends StatefulWidget {
 
+  VipBuyPage({
+    this.hideMonth,
+  });
+
+  bool? hideMonth;
+
   @override
   _VipBuyState createState() => _VipBuyState();
 }
@@ -176,24 +183,25 @@ class _VipBuyState extends State<VipBuyPage>
                     });
                   },
                 ),
-                InkWell(
-                  child: _getMoneyWidget(
-                      "¥"+((_getVipModelByType(1).currentPrice??0)/100).toStringAsFixed(2),
-                      "/月",
-                      _getMoneyDesc(1),
-                      _selectedIndex==1?true:false,
-                      16.h
+                if (!(widget.hideMonth??false))
+                  InkWell(
+                    child: _getMoneyWidget(
+                        "¥"+((_getVipModelByType(1).currentPrice??0)/100).toStringAsFixed(2),
+                        "/月",
+                        _getMoneyDesc(1),
+                        _selectedIndex==1?true:false,
+                        16.h
+                    ),
+                    onTap: () {
+                      setState(() {
+                        _selectedIndex = 1;
+                      });
+                    },
                   ),
-                  onTap: () {
-                    setState(() {
-                      _selectedIndex = 1;
-                    });
-                  },
-                ),
                 Container(
                   margin: EdgeInsets.fromLTRB(20.w, 10.h, 20.w, 0),
                   child: Text(
-                    UniversalPlatform.isIOS?"开通即代表同意《会员协议》和《服务协议》。确认购买后,将向您的iTunes账户收款。自动续费iTunes账户会在到期前24小时内扣费。在此之前,您可以手动在 iTunes/Apple ID 设置管理中关闭自动续费":"开通即代表同意《会员协议》和《服务协议》。",
+                    UniversalPlatform.isIOS?"开通即代表同意《会员协议》。确认购买后,将向您的iTunes账户收款。自动续费iTunes账户会在到期前24小时内扣费。在此之前,您可以手动在 iTunes/Apple ID 设置管理中关闭自动续费":"开通即代表同意《会员协议》和《服务协议》。",
                     style: TextStyle(
                       fontSize: 10.sp,
                       color: HexColor("#666666"),
@@ -229,58 +237,23 @@ class _VipBuyState extends State<VipBuyPage>
                     }
                   },
                 ),
-                Container(
-                  margin: EdgeInsets.fromLTRB(102.w, 12.h, 0, 12.h),
-                  height: 14.h,
-                  child: Row(
-                    children: [
-                      InkWell(
-                        child: Text(
-                          "会员协议",
-                          style: TextStyle(
-                              fontSize: 10.sp,
-                              color: HexColor("#999999"),
-                              fontWeight: FontWeight.w400
-                          ),
-                        ),
-                        onTap: () {
-
-                        },
-                      ),
-                      SizedBox(
-                        width: 32.w,
-                      ),
-                      InkWell(
-                        child: Text(
-                          "服务协议",
-                          style: TextStyle(
-                              fontSize: 10.sp,
-                              color: HexColor("#999999"),
-                              fontWeight: FontWeight.w400
-                          ),
-                        ),
-                        onTap: () {
-
-                        },
-                      ),
-                      SizedBox(
-                        width: 32.w,
+                InkWell(
+                  child: Container(
+                    margin: EdgeInsets.fromLTRB(0, 12.h, 0, 12.h),
+                    height: 19.h,
+                    alignment: Alignment.center,
+                    child: Text(
+                      "会员协议",
+                      style: TextStyle(
+                          fontSize: 10.sp,
+                          color: HexColor("#999999"),
+                          fontWeight: FontWeight.w400
                       ),
-                      InkWell(
-                        child: Text(
-                          "常见问题",
-                          style: TextStyle(
-                              fontSize: 10.sp,
-                              color: HexColor("#999999"),
-                              fontWeight: FontWeight.w400
-                          ),
-                        ),
-                        onTap: () {
-
-                        },
-                      )
-                    ],
+                    ),
                   ),
+                  onTap: (){
+                    Get.to(()=>VipAgreementPage());
+                  },
                 ),
                 SizedBox(
                   height: ScreenUtil().bottomBarHeight,

+ 1 - 0
lib/pages/today/favorite/model/favorite_model.dart

@@ -48,6 +48,7 @@ class FavoriteRecords {
 	double? price;
 	double? sourcePrice;
 	int? contentId;
+	int? subType;
 
 	@JSONField(deserialize: false, serialize: false)
 	bool isShowTime = false;

+ 9 - 0
lib/pages/today/main/controller/home_ctrl.dart

@@ -35,6 +35,7 @@ class HomeCtrl extends GetxController {
   StreamSubscription? _moodRecordSucceedEvent;
   StreamSubscription? _reloadContinueEvent;
   StreamSubscription? _practiceFinishEvent;
+  StreamSubscription? _firstInstallEvent;
   double offset = 0;
   List<String> moodTextList = ["观察情绪,会有别样收获", "记录心情,提升心理调节能力", "与自己相处,释放情绪力量"];
   String moodDescText = "";
@@ -64,6 +65,7 @@ class HomeCtrl extends GetxController {
     _moodRecordSucceedEvent?.cancel();
     _reloadContinueEvent?.cancel();
     _practiceFinishEvent?.cancel();
+    _firstInstallEvent?.cancel();
   }
 
   void _initEvent() {
@@ -76,6 +78,7 @@ class HomeCtrl extends GetxController {
           _initUserInfo();
           _requestTodayMoodStat();
           _requestContinuePracticeList();
+          _requestEnergyChargeHouse();
           _requestTodayRecommend();
         });
     _moodRecordSucceedEvent =
@@ -92,6 +95,12 @@ class HomeCtrl extends GetxController {
             _requestContinuePracticeList();
           }
         });
+    _firstInstallEvent =
+        AppEvent.getInstance()?.on<FirstInstallReloadDataEvent>().listen((event) {
+          _requestAppConfig();
+          _requestEnergyChargeHouse();
+          _requestTodayRecommend();
+        });
   }
 
   void onScroll(offset) {

+ 106 - 2
lib/pages/today/mood_record/controller/mood_text_ctrl.dart

@@ -1,6 +1,7 @@
 
 
 import 'dart:async';
+import 'dart:convert';
 
 import 'package:flutter/material.dart';
 import 'package:flutter_easyloading/flutter_easyloading.dart';
@@ -22,6 +23,7 @@ import '../../../../utils/app_event.dart';
 import '../../../../utils/toast_utils.dart';
 import '../model/mood_type_model.dart';
 
+
 class MoodTextCtrl extends GetxController with GetSingleTickerProviderStateMixin{
 
   FocusNode focusNode = new FocusNode();
@@ -167,9 +169,52 @@ class MoodTextCtrl extends GetxController with GetSingleTickerProviderStateMixin
       }
     }
 
+    //计算长度
+    int count = 0;
+    for (int i=0; i<recordTextCtrl.text.length; i++) {
+      String chart = recordTextCtrl.text[i];
+      if (isSpace(chart)){
+        continue;
+      }
+      if (i < recordTextCtrl.text.length-1) { //不是最后一个字符
+        String nextChart = recordTextCtrl.text[i+1];
+        if (isChinese(chart)) {
+          count++;
+        }
+        else if (isLetter(chart)) {
+          if (!isLetter(nextChart)) {
+            count++;
+          }
+          else {
+            continue;
+          }
+        }
+        else if (isNumber(chart)) {
+          if (!isNumber(nextChart)) {
+            count++;
+          }
+          else {
+            continue;
+          }
+        }
+        else {
+          count++;
+        }
+      }
+      else { //最后一个字符
+        count++;
+      }
+    }
+
+    int emojiCount = countEmoji(recordTextCtrl.text);
+    print("emojiCount = " + emojiCount.toString());
+    if (emojiCount > 0) {
+      count = count - emojiCount;
+    }
+
     params["reasonId"] = reasonIds;
     params["typeId"] = typeIds;
-    params["wordCount"] = recordTextCtrl.text.length;
+    params["wordCount"] = count;
     params["duration"] = chooseCtrl.seconds;
     params["recordTime"] = chooseCtrl.recordTime;
     params["isHistory"] = chooseCtrl.isHistory?1:0;
@@ -184,7 +229,7 @@ class MoodTextCtrl extends GetxController with GetSingleTickerProviderStateMixin
         Get.to(()=>SegmentFinishPage(
           type: 2,
           useTime: chooseCtrl.seconds,
-          wordCount: recordTextCtrl.text.length,
+          wordCount: count,
           mood: chooseCtrl.getMoodString(),
         ));
       } else {
@@ -194,6 +239,65 @@ class MoodTextCtrl extends GetxController with GetSingleTickerProviderStateMixin
     });
   }
 
+  bool isChinese(String chart) {
+    final reg = RegExp(r'^[\u4e00-\u9fa5]+$');
+    return reg.hasMatch(chart);
+  }
+
+  bool isLetter(String chart) {
+    return chart.isAlphabetOnly;
+  }
+
+  bool isNumber(String chart) {
+    final reg = RegExp(r'^-?[0-9.]+$');
+    return reg.hasMatch(chart);
+  }
+
+  bool isSpace(String chart) {
+    return chart == " ";
+  }
+
+  // int countWords(String text) {
+  //   if (text == null || text.isEmpty) {
+  //     return 0;
+  //   }
+  //
+  //   // 使用正则表达式匹配中文、英文单词、标点符号和表情
+  //   RegExp regExp = RegExp(r'[\u4e00-\u9fa5]|[\w]|[\s,.!?\x{1F600}-\x{1F64F}\x{1F300}-\x{1F5FF}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F800}-\x{1F8FF}\x{1F900}-\x{1F9FF}\x{1FA00}-\x{1FA6F}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2B50}]');
+  //   Iterable<Match> matches = regExp.allMatches(text);
+  //
+  //   // 统计匹配到的字符数
+  //   int count = matches.length;
+  //   return count;
+  // }
+
+  // int countWords(String text) {
+  //   if (text == null || text.isEmpty) {
+  //     return 0;
+  //   }
+  //
+  //   // 使用正则表达式匹配中文、英文、标点符号和表情
+  //   RegExp regExp = RegExp(r"[\u4e00-\u9fa5]|[a-zA-Z]|[^\x00-\xff]");
+  //
+  //   Iterable<Match> matches = regExp.allMatches(text);
+  //
+  //   return matches.length;
+  // }
+
+  int countEmoji(String text) {
+    if (text == null || text.isEmpty) {
+      return 0;
+    }
+
+    //表情符号
+    RegExp regExp = RegExp(
+        r'(?:[\u00A9\u00AE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9-\u21AA\u231A-\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA-\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614-\u2615\u2618\u261D\u2620\u2622-\u2623\u2626\u262A\u262E-\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u2660\u2663\u2665-\u2666\u2668\u267B\u267F\u2692-\u2697\u2699\u269B-\u269C\u26A0-\u26A1\u26AA-\u26AB\u26B0-\u26B1\u26BD-\u26BE\u26C4-\u26C5\u26C8\u26CE-\u26CF\u26D1\u26D3-\u26D4\u26E9-\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733-\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763-\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934-\u2935\u2B05-\u2B07\u2B1B-\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|(?:\uD83C[\uDC04\uDCCF\uDD70-\uDD71\uDD7E-\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01-\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50-\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96-\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F-\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95-\uDD96\uDDA4-\uDDA5\uDDA8\uDDB1-\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDEE0-\uDEE5\uDEE9\uDEEB-\uDEEC\uDEF0\uDEF3-\uDEF6]|\uD83E[\uDD10-\uDD1E\uDD20-\uDD27\uDD30\uDD33-\uDD3A\uDD3C-\uDD3E\uDD40-\uDD45\uDD47-\uDD4B\uDD50-\uDD5E\uDD80-\uDD91\uDDC0]))');
+
+    Iterable<Match> matches = regExp.allMatches(text);
+
+    return matches.length;
+  }
+
   // @override
   // // TODO: implement wantKeepAlive
   // bool get wantKeepAlive => true;

+ 1 - 1
lib/pages/today/mood_record/page/mood_reason_page.dart

@@ -109,7 +109,7 @@ class MoodReasonPage extends GetView<MoodReasonCtrl>{
                             child: MoodReasonCell(reasonModel: reasonModel, showType: 1,),
                             onTap: (){
                               if (reasonModel.isCustom) {
-                                if ((controller.userModel.vipStatus??0) > 0 || !AppService().isWeChatPay()) {
+                                if ((controller.userModel.vipStatus??0) > 0) {
                                   _showCustomReasonDialog();
                                 }
                                 else {

+ 2 - 2
lib/pages/today/mood_record/view/mood_reason_cell.dart

@@ -34,7 +34,7 @@ class MoodReasonCell extends GetView<MoodReasonCtrl> {
         ),
         child: (reasonModel.isCustom && showType==1)?Column(
           children: [
-            if ((controller.userModel.vipStatus??0) < 1 && AppService().isWeChatPay())
+            if ((controller.userModel.vipStatus??0) < 1)
               Container(
                 alignment: Alignment.topLeft,
                 child: Image.asset(
@@ -42,7 +42,7 @@ class MoodReasonCell extends GetView<MoodReasonCtrl> {
                 ),
               ),
             Container(
-              margin: EdgeInsets.only(top: ((controller.userModel.vipStatus??0) < 1 && AppService().isWeChatPay())?21.w:37.w),
+              margin: EdgeInsets.only(top: ((controller.userModel.vipStatus??0) < 1)?21.w:37.w),
               height: 24.w,
               alignment: Alignment.center,
               child: Row(

+ 48 - 49
lib/pages/today/practice/page/practice_detail_page.dart

@@ -202,7 +202,7 @@ class _MyFavoriteTabState extends State<PracticeDetailPage> with SingleTickerPro
     for (int i = 0; i < _tabValues.length; i++) {
       Container container = new Container(
         //width: 60.w,
-        height: 20.w,
+        height: 22.w,
         alignment: Alignment.centerLeft,
         child: Text(
             _tabValues[i],
@@ -239,8 +239,7 @@ class _MyFavoriteTabState extends State<PracticeDetailPage> with SingleTickerPro
               child: Container(
                 width: 1.sw,
                 height: ScreenUtil().statusBarHeight+AppStatic.navBarHeight+188.w,
-                child:
-                ImageFiltered(
+                child: ImageFiltered(
                   imageFilter: ImageFilter.blur(sigmaX: 50, sigmaY: 50, tileMode: TileMode.decal),
                   child: Container(
                     width: double.infinity,
@@ -296,14 +295,14 @@ class _MyFavoriteTabState extends State<PracticeDetailPage> with SingleTickerPro
                         children: [
                           Container(
                             margin: EdgeInsets.only(top: 24.w),
-                            height: 20.w,
+                            height: 22.w,
                             alignment: Alignment.centerLeft,
                             child: TabBar(
                               isScrollable: true,
                               labelColor: Color.fromRGBO(0, 0, 0, 1),
                               unselectedLabelColor: Color.fromRGBO(0, 0, 0, 0.4),
-                              labelStyle: TextStyle(fontSize: 14.sp, fontWeight: FontWeight.w500, fontFamily: AppStatic.fontFamily),
-                              unselectedLabelStyle: TextStyle(fontSize: 14.sp, fontWeight: FontWeight.w500, fontFamily: AppStatic.fontFamily),
+                              labelStyle: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w500, fontFamily: AppStatic.fontFamily),
+                              unselectedLabelStyle: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w500, fontFamily: AppStatic.fontFamily),
                               indicatorSize: TabBarIndicatorSize.tab,
                               controller: _tabController,
                               tabs: _tabList,
@@ -316,7 +315,7 @@ class _MyFavoriteTabState extends State<PracticeDetailPage> with SingleTickerPro
                             ),
                           ),
                           SizedBox(
-                            height: 12.w,
+                            height: 16.w,
                           ),
                           Expanded(
                               child: TabBarView(
@@ -332,27 +331,30 @@ class _MyFavoriteTabState extends State<PracticeDetailPage> with SingleTickerPro
                               mainAxisAlignment: MainAxisAlignment.spaceBetween,
                               children: [
                                 if (_bottomBtnStatus == 3)
-                                  RichText(
-                                      text: TextSpan(
-                                          children: [
-                                            TextSpan(
-                                                text: "¥",
-                                                style: TextStyle(
-                                                    fontSize: 16.sp,
-                                                    color: HexColor("#FF4B4B"),
-                                                    fontWeight: FontWeight.w600
-                                                )
-                                            ),
-                                            TextSpan(
-                                              text: ((_detailModel.price??0)/100).toStringAsFixed(2),
-                                              style: TextStyle(
-                                                  fontSize: 24.sp,
-                                                  color: HexColor("#FF4B4B"),
-                                                  fontWeight: FontWeight.w600
-                                              )
-                                            ),
-                                          ]
-                                      )
+                                  Container(
+                                    alignment: Alignment.centerLeft,
+                                    child: RichText(
+                                        text: TextSpan(
+                                            children: [
+                                              TextSpan(
+                                                  text: "¥",
+                                                  style: TextStyle(
+                                                      fontSize: 16.sp,
+                                                      color: HexColor("#FF4B4B"),
+                                                      fontWeight: FontWeight.w600
+                                                  )
+                                              ),
+                                              TextSpan(
+                                                  text: ((_detailModel.price??0)/100).toStringAsFixed(2),
+                                                  style: TextStyle(
+                                                      fontSize: 24.sp,
+                                                      color: HexColor("#FF4B4B"),
+                                                      fontWeight: FontWeight.w600
+                                                  )
+                                              ),
+                                            ]
+                                        )
+                                    ),
                                   ),
                                 InkWell(
                                   child: Container(
@@ -508,31 +510,25 @@ class _MyFavoriteTabState extends State<PracticeDetailPage> with SingleTickerPro
   void _initBottomButtonStatus() {
 
     String commonText = _type==3?(_detailModel.hasTested??0)>0?"再测一次":"开始测评":"开始第 "+((_detailModel.usageTimes??0)+1).toString()+" 次练习";
-    if (AppService().isWeChatPay()) {
-      if (_detailModel.isVip??false) {
-        if ((_userModel.vipStatus??0)>0) {
-          _bottomBtnStatus = 1;
-          _bottomBtnText = commonText;
-        }
-        else {
-          _bottomBtnStatus = 2;
-          _bottomBtnText = "升级至 Pro 专业版";
-        }
-      }
-      else if (_detailModel.isPay??false) {
-        if (_detailModel.hasPayed==1) {
-          _bottomBtnStatus = 1;
-          _bottomBtnText = commonText;
-        }
-        else {
-          _bottomBtnStatus = 3;
-          _bottomBtnText = "立即购买";
-        }
+    if (_detailModel.isVip??false) {
+      if ((_userModel.vipStatus??0)>0) {
+        _bottomBtnStatus = 1;
+        _bottomBtnText = commonText;
       }
       else {
+        _bottomBtnStatus = 2;
+        _bottomBtnText = "升级至 Pro 专业版";
+      }
+    }
+    else if (_detailModel.isPay??false) {
+      if (_detailModel.hasPayed==1) {
         _bottomBtnStatus = 1;
         _bottomBtnText = commonText;
       }
+      else {
+        _bottomBtnStatus = 3;
+        _bottomBtnText = "立即购买";
+      }
     }
     else {
       _bottomBtnStatus = 1;
@@ -1040,7 +1036,10 @@ class _MyFavoriteTabState extends State<PracticeDetailPage> with SingleTickerPro
         else {
           _requestPracticeDetail(false);
         }
-      } else {
+      }
+      else if (ret.code == 7007){
+      }
+      else {
         ToastUtil.showMsg(ret.msg??"");
       }
     });

+ 139 - 77
lib/pages/today/practice/page/segment_finish_page.dart

@@ -329,47 +329,59 @@ class _MyFavoriteTabState extends State<SegmentFinishPage> with SingleTickerProv
                             Container(
                               margin: EdgeInsets.only(top: 15.h),
                               height: 24.h,
-                              alignment: Alignment.centerLeft,
-                              child: RichText(
-                                  text: TextSpan(
-                                      style: DefaultTextStyle.of(context).style,
-                                      text: "",
-                                      children: [
-                                        WidgetSpan(
-                                          alignment: PlaceholderAlignment.middle,
-                                            child: Image.asset(
-                                              A.assets_images_finish_time,
-                                              width: 24.h,
-                                              height: 24.h,
-                                              fit: BoxFit.fill,
-                                              alignment: Alignment.topLeft,
-                                            ),
-                                        ),
-                                        WidgetSpan(
-                                          alignment: PlaceholderAlignment.middle,
-                                          child: Text(
-                                            " "+(widget.useTime/60).ceil().toString(),
-                                            style: TextStyle(
-                                                fontSize: 20.sp,
-                                                color: HexColor("#20201F"),
-                                                fontWeight: FontWeight.w600
-                                            ),
-                                          )
-                                        ),
-                                        WidgetSpan(
-                                          alignment: PlaceholderAlignment.top,
-                                          child: Text(
-                                            " 分钟",
-                                            style: TextStyle(
-                                                fontSize: 12.sp,
-                                                color: HexColor("#20201F"),
-                                                fontWeight: FontWeight.w500
-                                            ),
-                                          ),
-                                        ),
-                                      ]
+                              child: Row(
+                                children: [
+                                  Container(
+                                    //color: Colors.cyan,
+                                    child: Image.asset(
+                                      A.assets_images_finish_time,
+                                      width: 24.h,
+                                      height: 24.h,
+                                      fit: BoxFit.fill,
+                                    ),
+                                  ),
+                                  Container(
+                                    margin: EdgeInsets.only(left: 8.w),
+                                    height: 24.h,
+                                    alignment: Alignment.topCenter,
+                                    //color: Colors.blue,
+                                    child: Text(
+                                      (widget.useTime/60).ceil().toString(),
+                                      style: TextStyle(
+                                          fontSize: 20.sp,
+                                          color: HexColor("#20201F"),
+                                          fontWeight: FontWeight.w600
+                                      ),
+                                      strutStyle: StrutStyle(
+                                        fontSize: 20.sp,
+                                        leading: 0,
+                                        height: 1.2,
+                                        forceStrutHeight: true, // 关键属性 强制改为文字高度
+                                      ),
+                                    ),
+                                  ),
+                                  Container(
+                                    margin: EdgeInsets.only(left: 2.w),
+                                    height: 24.h,
+                                    alignment: Alignment.center,
+                                    //color: Colors.red,
+                                    child: Text(
+                                      "分钟",
+                                      style: TextStyle(
+                                          fontSize: 12.sp,
+                                          color: HexColor("#20201F"),
+                                          fontWeight: FontWeight.w500
+                                      ),
+                                      strutStyle: StrutStyle(
+                                        fontSize: 20.sp,
+                                        leading: 0,
+                                        height: 1.0,
+                                        forceStrutHeight: true, // 关键属性 强制改为文字高度
+                                      ),
+                                    ),
                                   )
-                              ),
+                                ],
+                              )
                             )
                           ],
                         )
@@ -399,44 +411,94 @@ class _MyFavoriteTabState extends State<SegmentFinishPage> with SingleTickerProv
                                 margin: EdgeInsets.only(top: 15.h),
                                 height: 24.h,
                                 alignment: Alignment.centerLeft,
-                                child: RichText(
-                                    text: TextSpan(
-                                        text: "",
-                                        children: [
-                                          WidgetSpan(
-                                            alignment: PlaceholderAlignment.middle,
-                                            child: Image.asset(
-                                              A.assets_images_finish_word_count,
-                                              width: 24.h,
-                                              height: 24.h,
-                                              fit: BoxFit.fill,
-                                            ),
-                                          ),
-                                          WidgetSpan(
-                                            alignment: PlaceholderAlignment.middle,
-                                            child: Text(
-                                              " "+widget.wordCount.toString(),
-                                              style: TextStyle(
-                                                fontSize: 20.sp,
-                                                color: HexColor("#20201F"),
-                                                fontWeight: FontWeight.w600,
-                                              ),
-                                            ),
-                                          ),
-                                          WidgetSpan(
-                                            alignment: PlaceholderAlignment.top,
-                                            child: Text(
-                                              " 字",
-                                              style: TextStyle(
-                                                  fontSize: 12.sp,
-                                                  color: HexColor("#20201F"),
-                                                  fontWeight: FontWeight.w500
-                                              ),
-                                            ),
-                                          ),
-                                        ]
+                                child: Row(
+                                  children: [
+                                    Container(
+                                      child: Image.asset(
+                                        A.assets_images_finish_word_count,
+                                        width: 24.h,
+                                        height: 24.h,
+                                        fit: BoxFit.fill,
+                                      ),
+                                    ),
+                                    Container(
+                                      margin: EdgeInsets.only(left: 8.w),
+                                      height: 24.h,
+                                      alignment: Alignment.topCenter,
+                                      child: Text(
+                                        widget.wordCount.toString(),
+                                        style: TextStyle(
+                                            fontSize: 20.sp,
+                                            color: HexColor("#20201F"),
+                                            fontWeight: FontWeight.w600
+                                        ),
+                                        strutStyle: StrutStyle(
+                                          fontSize: 20.sp,
+                                          leading: 0,
+                                          height: 1.2,
+                                          forceStrutHeight: true, // 关键属性 强制改为文字高度
+                                        ),
+                                      ),
+                                    ),
+                                    Container(
+                                      margin: EdgeInsets.only(left: 2.w),
+                                      height: 24.h,
+                                      alignment: Alignment.center,
+                                      child: Text(
+                                        "字",
+                                        style: TextStyle(
+                                            fontSize: 12.sp,
+                                            color: HexColor("#20201F"),
+                                            fontWeight: FontWeight.w500
+                                        ),
+                                        strutStyle: StrutStyle(
+                                          fontSize: 20.sp,
+                                          leading: 0,
+                                          height: 1.0,
+                                          forceStrutHeight: true, // 关键属性 强制改为文字高度
+                                        ),
+                                      ),
                                     )
-                                ),
+                                  ],
+                                )
+                                // RichText(
+                                //     text: TextSpan(
+                                //         text: "",
+                                //         children: [
+                                //           WidgetSpan(
+                                //             alignment: PlaceholderAlignment.middle,
+                                //             child: Image.asset(
+                                //               A.assets_images_finish_word_count,
+                                //               width: 24.h,
+                                //               height: 24.h,
+                                //               fit: BoxFit.fill,
+                                //             ),
+                                //           ),
+                                //           WidgetSpan(
+                                //             alignment: PlaceholderAlignment.middle,
+                                //             child: Text(
+                                //               " "+widget.wordCount.toString(),
+                                //               style: TextStyle(
+                                //                 fontSize: 20.sp,
+                                //                 color: HexColor("#20201F"),
+                                //                 fontWeight: FontWeight.w600,
+                                //               ),
+                                //             ),
+                                //           ),
+                                //           WidgetSpan(
+                                //             alignment: PlaceholderAlignment.top,
+                                //             child: Text(
+                                //               " 字",
+                                //               style: TextStyle(
+                                //                   fontSize: 12.sp,
+                                //                   color: HexColor("#20201F"),
+                                //                   fontWeight: FontWeight.w500
+                                //               ),
+                                //             ),
+                                //           ),
+                                //         ]
+                                //     )
+                                // ),
                               )
                             ],
                           )

+ 55 - 20
lib/pages/today/practice/view/practice_info_view.dart

@@ -1,4 +1,5 @@
 
+import 'package:cached_network_image/cached_network_image.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_screenutil/flutter_screenutil.dart';
 import 'package:poetry/module/app_service.dart';
@@ -31,18 +32,39 @@ class PracticeInfoView extends StatelessWidget {
               child: Container(
                 width: 72.w,
                 height: 72.w,
-                decoration: BoxDecoration(
-                  image: DecorationImage(
-                      image: NetworkImage(detailModel.coverUrl??""),
-                      fit: BoxFit.fill
-                  ),
-                ),
-                child: ((detailModel.isVip??false)&&AppService().isWeChatPay())?Container(
-                  alignment: Alignment.topLeft,
-                  child: Image.asset(
-                    A.assets_images_mark_pro,
-                  ),
-                ):Container()
+                // decoration: BoxDecoration(
+                //   image: DecorationImage(
+                //       image: NetworkImage(detailModel.coverUrl??""),
+                //       fit: BoxFit.fill
+                //   ),
+                // ),
+                child: Stack(
+                  children: [
+                    Positioned.fill(
+                      child: CachedNetworkImage(
+                        imageUrl: detailModel.coverUrl??"",
+                        fit: BoxFit.fill,
+                      ),
+                    ),
+                    if (detailModel.isVip??false)
+                      Positioned(
+                        left: 0,
+                        top: 0,
+                        child: Container(
+                          alignment: Alignment.topLeft,
+                          child: Image.asset(
+                            A.assets_images_mark_pro,
+                          ),
+                        ),
+                      )
+                  ],
+                )
+                // ((detailModel.isVip??false)&&AppService().isWeChatPay())?Container(
+                //   alignment: Alignment.topLeft,
+                //   child: Image.asset(
+                //     A.assets_images_mark_pro,
+                //   ),
+                // ):Container()
               ),
             ),
             SizedBox(
@@ -108,14 +130,14 @@ class PracticeInfoView extends StatelessWidget {
                                   opacity: 0.4,
                                   child: Image.asset(
                                     A.assets_images_practice_time_ic,
-                                    width: 12.w,
-                                    height: 12.w,
+                                    width: 14.w,
+                                    height: 14.w,
                                     fit: BoxFit.fill,
                                   ),
                                 ),
                               if (type != 3)
                                 Container(
-                                  margin: EdgeInsets.only(left: 2.w, right: 14.w),
+                                  margin: EdgeInsets.only(left: 1.w, right: 12.w),
                                   child: Text(
                                     (detailModel.duration!/60).round().toString()+"分钟",
                                     style: TextStyle(
@@ -129,25 +151,38 @@ class PracticeInfoView extends StatelessWidget {
                                 opacity: 0.4,
                                 child: Image.asset(
                                   A.assets_images_practice_edit_ic,
-                                  width: 10.w,
-                                  height: 10.w,
+                                  width: 14.w,
+                                  height: 14.w,
                                   fit: BoxFit.fill,
                                 ),
                               ),
                               SizedBox(
-                                width: 2.w,
+                                width: 1.w,
                               ),
                               Text(
-                                detailModel.segmentCount.toString()+"书写页",
+                                detailModel.segmentCount.toString()+(type==3?"题目":"书写页"),
                                 style: TextStyle(
                                     fontSize: 10.sp,
                                     color: HexColor("#000000").withOpacity(0.4),
                                     fontWeight: FontWeight.w500
                                 ),
                               ),
+                              if (type == 3)
+                                Padding(
+                                  padding: EdgeInsets.only(left: 12.w),
+                                  child: Opacity(
+                                    opacity: 0.4,
+                                    child: Image.asset(
+                                      A.assets_images_practice_report_ic,
+                                      width: 14.w,
+                                      height: 14.w,
+                                      fit: BoxFit.fill,
+                                    ),
+                                  ),
+                                ),
                               if (type == 3)
                                Padding(
-                                 padding: EdgeInsets.only(left: 25.w),
+                                 padding: EdgeInsets.only(left: 1.w),
                                  child: Text(
                                    detailModel.reportWordCount.toString()+"字报告",
                                    style: TextStyle(

+ 9 - 3
lib/pages/today/practice_assess/page/exam_page.dart

@@ -81,7 +81,7 @@ class ExamPage extends GetView<ExamCtrl> {
                             title: "是否添加到继续练习",
                             content: "添加至继续练习后,当前进度及输入内容将会保存",
                             cancelText: "否,退出练习",
-                            sureText: "添加到继续习",
+                            sureText: "添加到继续习",
                               height: 185,
                             cancelHandle: (){
                               Get.back();
@@ -244,7 +244,13 @@ class ExamPage extends GetView<ExamCtrl> {
                                                   height: 40.w,
                                                   decoration: BoxDecoration(
                                                       color: HexColor("#FFFFFF"),
-                                                      borderRadius: BorderRadius.circular(20.w)
+                                                      borderRadius: BorderRadius.circular(20.w),
+                                                    boxShadow: [BoxShadow(
+                                                        color: HexColor("#000000").withOpacity(0.04),
+                                                        offset: Offset(0, 4), //阴影xy轴偏移量
+                                                        blurRadius: 8, //阴影模糊程度
+                                                        spreadRadius: 0 //阴影扩散程度
+                                                    )],
                                                   ),
                                                   child: Text(
                                                     guide,
@@ -271,7 +277,7 @@ class ExamPage extends GetView<ExamCtrl> {
                                       )
                                   ),
                                   SizedBox(
-                                    width: 10.w,
+                                    width: 16.w,
                                   ),
                                   _.index==_.segmentList.length-1&&!_.getNextButtonStatus()?Text(""):
                                   _.index==_.segmentList.length-1&&_.getNextButtonStatus()?MoodNextButton(

+ 3 - 3
lib/pages/today/practice_assess/view/essay_view.dart

@@ -36,7 +36,7 @@ class EssayView extends GetView<ExamCtrl> {
             ),
           ),
           SizedBox(
-            height: 33.w,
+            height: 16.w,
           ),
           Expanded(
             child: TextField(
@@ -48,9 +48,9 @@ class EssayView extends GetView<ExamCtrl> {
               cursorHeight: 20,
               maxLines: null,
               style: TextStyle(
-                fontSize: 16.sp,
+                fontSize: 14.sp,
                 color: HexColor("#222222"),
-                height: 1.5,
+                height: 1.7,
               ),
               // strutStyle: StrutStyle(
               //   leading:  0.7, //行间距

+ 5 - 0
lib/utils/app_event.dart

@@ -79,3 +79,8 @@ class ExploreUpdateSearchKeywordEvent {
 class MoodAnalysisShareEvent {
   MoodAnalysisShareEvent();
 }
+
+//首次安装同意使用网络后刷新数据
+class FirstInstallReloadDataEvent {
+  FirstInstallReloadDataEvent();
+}

+ 7 - 7
pubspec.lock

@@ -692,10 +692,10 @@ packages:
     dependency: transitive
     description:
       name: js
-      sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
+      sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
       url: "https://pub.dev"
     source: hosted
-    version: "0.6.5"
+    version: "0.6.7"
   json_annotation:
     dependency: transitive
     description:
@@ -964,10 +964,10 @@ packages:
     dependency: transitive
     description:
       name: petitparser
-      sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4"
+      sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
       url: "https://pub.dev"
     source: hosted
-    version: "5.1.0"
+    version: "6.0.2"
   pin_code_fields:
     dependency: "direct main"
     description:
@@ -1417,10 +1417,10 @@ packages:
     dependency: transitive
     description:
       name: xml
-      sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5"
+      sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
       url: "https://pub.dev"
     source: hosted
-    version: "6.2.2"
+    version: "6.5.0"
 sdks:
-  dart: ">=3.2.0-194.0.dev <4.0.0"
+  dart: ">=3.2.0 <4.0.0"
   flutter: ">=3.13.0"

+ 2 - 0
pubspec.yaml

@@ -125,6 +125,8 @@ dev_dependencies:
   # rules and activating additional ones.
   flutter_lints: ^2.0.0
 
+#  flutter_native_splash: ^2.3.8
+
 # For information on the generic Dart part of this file, see the
 # following page: https://dart.dev/tools/pub/pubspec
 

+ 73 - 7
web/index.html

@@ -1,6 +1,4 @@
-<!DOCTYPE html>
-<html>
-<head>
+<!DOCTYPE html><html><head>
   <!--
     If you are serving your web app in a path other than the root, change the
     href value below to reflect the base path you are serving from.
@@ -27,7 +25,7 @@
   <link rel="apple-touch-icon" href="icons/Icon-192.png">
 
   <!-- Favicon -->
-  <link rel="icon" type="image/png" href="favicon.png"/>
+  <link rel="icon" type="image/png" href="favicon.png">
 
   <title>心境奇旅</title>
   <link rel="manifest" href="manifest.json">
@@ -37,7 +35,7 @@
     var serviceWorkerVersion = null;
   </script>
   <!-- This script adds the flutter initialization JS code -->
-  <script src="flutter.js" defer></script>
+  <script src="flutter.js" defer=""></script>
 
   <style>
     .loading {
@@ -84,6 +82,73 @@
       }
     }
   </style>
+  <style id="splash-screen-style">
+    html {
+      height: 100%
+    }
+
+    body {
+      margin: 0;
+      min-height: 100%;
+      background-color: #ffffff;
+      background-image: url("splash/img/light-background.png");
+      background-size: 100% 100%;
+    }
+
+    .center {
+      margin: 0;
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      -ms-transform: translate(-50%, -50%);
+      transform: translate(-50%, -50%);
+    }
+
+    .contain {
+      display:block;
+      width:100%; height:100%;
+      object-fit: contain;
+    }
+
+    .stretch {
+      display:block;
+      width:100%; height:100%;
+    }
+
+    .cover {
+      display:block;
+      width:100%; height:100%;
+      object-fit: cover;
+    }
+
+    .bottom {
+      position: absolute;
+      bottom: 0;
+      left: 50%;
+      -ms-transform: translate(-50%, 0);
+      transform: translate(-50%, 0);
+    }
+
+    .bottomLeft {
+      position: absolute;
+      bottom: 0;
+      left: 0;
+    }
+
+    .bottomRight {
+      position: absolute;
+      bottom: 0;
+      right: 0;
+    }
+  </style>
+  <script id="splash-screen-script">
+    function removeSplashFromWeb() {
+      document.getElementById("splash")?.remove();
+      document.getElementById("splash-branding")?.remove();
+      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>
   <div class="loading">
@@ -104,5 +169,6 @@
       });
     });
   </script>
-</body>
-</html>
+
+
+</body></html>

BIN
web/splash/img/light-background.png