diff --git a/.DS_Store b/.DS_Store index 7b4ac0b..bacd1e4 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/flutter_leave_lc/android/.gitignore b/flutter_leave_lc/android/.gitignore index bc2100d..6f56801 100644 --- a/flutter_leave_lc/android/.gitignore +++ b/flutter_leave_lc/android/.gitignore @@ -5,3 +5,9 @@ gradle-wrapper.jar /gradlew.bat /local.properties GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties +**/*.keystore +**/*.jks diff --git a/flutter_leave_lc/android/app/build.gradle b/flutter_leave_lc/android/app/build.gradle index 128ceca..8e73e7f 100644 --- a/flutter_leave_lc/android/app/build.gradle +++ b/flutter_leave_lc/android/app/build.gradle @@ -22,49 +22,53 @@ if (flutterVersionName == null) { } apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" -def keystorePropertiesFile = rootProject.file("key.properties") -def keystoreProperties = new Properties() -keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) - android { - compileSdkVersion 28 - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } + compileSdkVersion flutter.compileSdkVersion - lintOptions { - disable 'InvalidPackage' + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "leancloud.flutterapp" - minSdkVersion 21 - targetSdkVersion 28 - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + applicationId "com.example.flutterapplc" + minSdkVersion flutter.minSdkVersion + targetSdkVersion flutter.targetSdkVersion + versionCode 1 + versionName "1.0.0" + multiDexEnabled true } + signingConfigs { release { - keyAlias keystoreProperties['keyAlias'] - keyPassword keystoreProperties['keyPassword'] - storeFile file(keystoreProperties['storeFile']) - storePassword keystoreProperties['storePassword'] + keyAlias 'flutter_rtm_demo_key' + keyPassword '123456' + storeFile file('/Users/xiaoxu/Documents/Flutter_WorkPlace/Keys/flutter_rtm_demo_key') + storePassword '123456' + } + debug { + keyAlias 'flutter_rtm_demo_key' + keyPassword '123456' + storeFile file('/Users/xiaoxu/Documents/Flutter_WorkPlace/Keys/flutter_rtm_demo_key') + storePassword '123456' } } buildTypes { + debug { + signingConfig signingConfigs.debug + } release { +// signingConfig signingConfigs.release +// minifyEnabled true +// useProguard true +// proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + minifyEnabled false + shrinkResources false + zipAlignEnabled false signingConfig signingConfigs.release - - minifyEnabled true - useProguard true - - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } @@ -74,8 +78,20 @@ flutter { } dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' + implementation fileTree(dir: 'libs', include: ['*.aar']) + implementation 'com.android.support:multidex:1.0.3' + //混合推送需要的包 + implementation('cn.leancloud:mixpush-vivo:8.2.4') + + //即时通信与推送需要的包 + implementation 'cn.leancloud:realtime-android:8.2.4' + implementation 'cn.leancloud:storage-android:8.2.4' + implementation 'io.reactivex.rxjava2:rxandroid:2.1.0' + + implementation 'androidx.appcompat:appcompat:1.0.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'com.google.android.material:material:1.5.0' } diff --git a/flutter_leave_lc/android/app/libs/vivo_pushSDK_v3.0.0.4_484.aar b/flutter_leave_lc/android/app/libs/vivo_pushSDK_v3.0.0.4_484.aar new file mode 100644 index 0000000..f278999 Binary files /dev/null and b/flutter_leave_lc/android/app/libs/vivo_pushSDK_v3.0.0.4_484.aar differ diff --git a/flutter_leave_lc/android/app/proguard-rules.pro b/flutter_leave_lc/android/app/proguard-rules.pro deleted file mode 100644 index babebba..0000000 --- a/flutter_leave_lc/android/app/proguard-rules.pro +++ /dev/null @@ -1,7 +0,0 @@ -#Flutter Wrapper --keep class io.flutter.app.** { *; } --keep class io.flutter.plugin.** { *; } --keep class io.flutter.util.** { *; } --keep class io.flutter.view.** { *; } --keep class io.flutter.** { *; } --keep class io.flutter.plugins.** { *; } \ No newline at end of file diff --git a/flutter_leave_lc/android/app/src/main/AndroidManifest.xml b/flutter_leave_lc/android/app/src/main/AndroidManifest.xml index dd53753..ebca25d 100644 --- a/flutter_leave_lc/android/app/src/main/AndroidManifest.xml +++ b/flutter_leave_lc/android/app/src/main/AndroidManifest.xml @@ -1,11 +1,11 @@ + + package="com.example.flutterapplc" + android:versionCode="1" + android:versionName="1.0.0"> - - - - - + + + android:allowBackup="true" + android:supportsRtl="true" + android:icon="@mipmap/ic_launcher" + > + android:windowSoftInputMode="adjustResize" + android:exported="true"> @@ -33,5 +36,34 @@ + + + + + + + + + + + + + + + diff --git a/flutter_leave_lc/android/app/src/main/java/com/example/flutterapplc/MainActivity.java b/flutter_leave_lc/android/app/src/main/java/com/example/flutterapplc/MainActivity.java new file mode 100644 index 0000000..4af5cc2 --- /dev/null +++ b/flutter_leave_lc/android/app/src/main/java/com/example/flutterapplc/MainActivity.java @@ -0,0 +1,20 @@ +package com.example.flutterapplc; + +import android.os.Bundle; +import android.os.PersistableBundle; +import android.util.Log; + +import androidx.annotation.Nullable; + +import com.vivo.push.PushClient; + +import io.flutter.embedding.android.FlutterActivity; + +public class MainActivity extends FlutterActivity { + @Override + public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { + super.onCreate(savedInstanceState, persistentState); + String regId = PushClient.getInstance(MainActivity.this).getRegId(); + Log.d("regid"," regId= " + regId); + } +} diff --git a/flutter_leave_lc/android/app/src/main/java/com/example/flutterapplc/MyApp.java b/flutter_leave_lc/android/app/src/main/java/com/example/flutterapplc/MyApp.java new file mode 100644 index 0000000..98bf4bf --- /dev/null +++ b/flutter_leave_lc/android/app/src/main/java/com/example/flutterapplc/MyApp.java @@ -0,0 +1,60 @@ +package com.example.flutterapplc; + +import cn.leancloud.LCException; +import cn.leancloud.LCInstallation; +import cn.leancloud.LCLogger; +import cn.leancloud.LCObject; +import cn.leancloud.LeanCloud; +import cn.leancloud.callback.LCCallback; +import cn.leancloud.vivo.LCMixPushManager; +import io.flutter.app.FlutterApplication; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; + +public class MyApp extends FlutterApplication { + private static final String LC_APP_ID = "eLAwFuK8k3eIYxh29VlbHu2N-gzGzoHsz"; + private static final String LC_APP_KEY = "G59fl4C1uLIQVR4BIiMjxnM3"; + private static final String LC_SERVER_URL = "https://elawfuk8.lc-cn-n1-shared.com"; + // private static final String LC_APP_ID = "Gvv2k8PugDTmYOCfuK8tiWd8-gzGzoHsz"; +// private static final String LC_APP_KEY = "dpwAo94n81jPsHVxaWwdxJVu"; +// private static final String LC_SERVER_URL = "https://gvv2k8pu.lc-cn-n1-shared.com"; + @Override + public void onCreate() { + super.onCreate(); + LeanCloud.setLogLevel(LCLogger.Level.DEBUG); + LeanCloud.initialize(this, LC_APP_ID, LC_APP_KEY, LC_SERVER_URL); + System.out.println("打印 initialize = :" + "initialize" ); + LCMixPushManager.registerVIVOPush(this); + LCMixPushManager.turnOnVIVOPush(new LCCallback() { + @Override + protected void internalDone0(Boolean aBoolean, LCException e) { + if (null != e) { + System.out.println("failed to turn on VIVO push. cause:"); + e.printStackTrace(); + } else { + System.out.println("succeed to turn on VIVO push."); + } + } + }); + LCInstallation.getCurrentInstallation().saveInBackground().subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + } + @Override + public void onNext(LCObject avObject) { + // 关联 installationId 到用户表等操作。 + String installationId = LCInstallation.getCurrentInstallation().getInstallationId(); + System.out.println("保存成功:" + installationId ); + } + @Override + public void onError(Throwable e) { + System.out.println("保存失败,错误信息:" + e.getMessage()); + } + @Override + public void onComplete() { + } + }); + String installationId = LCInstallation.getCurrentInstallation().getInstallationId(); + System.out.println("打印 installationId = :" + installationId ); + } +} diff --git a/flutter_leave_lc/android/app/src/main/java/com/example/flutterapplc/MyPushMessageReceiver.java b/flutter_leave_lc/android/app/src/main/java/com/example/flutterapplc/MyPushMessageReceiver.java new file mode 100644 index 0000000..dd96045 --- /dev/null +++ b/flutter_leave_lc/android/app/src/main/java/com/example/flutterapplc/MyPushMessageReceiver.java @@ -0,0 +1,24 @@ +package com.example.flutterapplc; + +import android.content.Context; +import android.util.Log; +import android.widget.Toast; + +import com.vivo.push.model.UnvarnishedMessage; + +import java.util.logging.Logger; + +import cn.leancloud.LCVIVOPushMessageReceiver; + +public class MyPushMessageReceiver extends LCVIVOPushMessageReceiver { + private static final Logger logger = Logger.getLogger(MyPushMessageReceiver.class.getSimpleName()); + + @Override + public void onTransmissionMessage(Context context, UnvarnishedMessage unvarnishedMessage) { + super.onTransmissionMessage(context, unvarnishedMessage); + Toast.makeText(context, " 收到透传通知: " + unvarnishedMessage.getMessage(), + Toast.LENGTH_LONG).show(); + Log.d("PushMessageReceiver", " onTransmissionMessage= " + + unvarnishedMessage.getMessage()); + } +} diff --git a/flutter_leave_lc/android/app/src/main/kotlin/com/example/flutterapplc/MainActivity.kt b/flutter_leave_lc/android/app/src/main/kotlin/com/example/flutterapplc/MainActivity.kt deleted file mode 100644 index d145e1b..0000000 --- a/flutter_leave_lc/android/app/src/main/kotlin/com/example/flutterapplc/MainActivity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.example.flutterapplc - -import androidx.annotation.NonNull; -import io.flutter.embedding.android.FlutterActivity -import io.flutter.embedding.engine.FlutterEngine -import io.flutter.plugins.GeneratedPluginRegistrant - -class MainActivity: FlutterActivity() { - override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { - GeneratedPluginRegistrant.registerWith(flutterEngine); - } -} diff --git a/flutter_leave_lc/android/app/src/main/res/drawable-v21/launch_background.xml b/flutter_leave_lc/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/flutter_leave_lc/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/flutter_leave_lc/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/flutter_leave_lc/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index 6fb390b..0b70095 100644 Binary files a/flutter_leave_lc/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/flutter_leave_lc/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/flutter_leave_lc/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/flutter_leave_lc/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index f74da84..ea8ba92 100644 Binary files a/flutter_leave_lc/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/flutter_leave_lc/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/flutter_leave_lc/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/flutter_leave_lc/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 2ca33c3..f4909ec 100644 Binary files a/flutter_leave_lc/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/flutter_leave_lc/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/flutter_leave_lc/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/flutter_leave_lc/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index daa614f..402e6db 100644 Binary files a/flutter_leave_lc/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/flutter_leave_lc/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/flutter_leave_lc/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/flutter_leave_lc/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 3311da4..0bd13d8 100644 Binary files a/flutter_leave_lc/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/flutter_leave_lc/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/flutter_leave_lc/android/app/src/main/res/values-night/styles.xml b/flutter_leave_lc/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..e0fc71c --- /dev/null +++ b/flutter_leave_lc/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/flutter_leave_lc/android/app/src/main/res/values/styles.xml b/flutter_leave_lc/android/app/src/main/res/values/styles.xml index 00fa441..46247bf 100644 --- a/flutter_leave_lc/android/app/src/main/res/values/styles.xml +++ b/flutter_leave_lc/android/app/src/main/res/values/styles.xml @@ -1,8 +1,18 @@ - + + diff --git a/flutter_leave_lc/android/build.gradle b/flutter_leave_lc/android/build.gradle index 3100ad2..36e820e 100644 --- a/flutter_leave_lc/android/build.gradle +++ b/flutter_leave_lc/android/build.gradle @@ -1,20 +1,18 @@ buildscript { - ext.kotlin_version = '1.3.50' repositories { google() - jcenter() + mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'com.android.tools.build:gradle:7.0.4' } } allprojects { repositories { google() - jcenter() + mavenCentral() } } diff --git a/flutter_leave_lc/android/gradle.properties b/flutter_leave_lc/android/gradle.properties index 38c8d45..94adc3a 100644 --- a/flutter_leave_lc/android/gradle.properties +++ b/flutter_leave_lc/android/gradle.properties @@ -1,4 +1,3 @@ org.gradle.jvmargs=-Xmx1536M -android.enableR8=true android.useAndroidX=true android.enableJetifier=true diff --git a/flutter_leave_lc/android/gradle/wrapper/gradle-wrapper.properties b/flutter_leave_lc/android/gradle/wrapper/gradle-wrapper.properties index 296b146..b8793d3 100644 --- a/flutter_leave_lc/android/gradle/wrapper/gradle-wrapper.properties +++ b/flutter_leave_lc/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip diff --git a/flutter_leave_lc/android/key.properties b/flutter_leave_lc/android/key.properties index 820bc40..4708fc1 100644 --- a/flutter_leave_lc/android/key.properties +++ b/flutter_leave_lc/android/key.properties @@ -1,4 +1,4 @@ storePassword=123456 keyPassword=123456 -keyAlias=key -storeFile=/Users/vivian/key.jks \ No newline at end of file +keyAlias=flutter_rtm_demo_key +storeFile=/Users/xiaoxu/Documents/Flutter_WorkPlace/Keys/flutter_rtm_demo_key diff --git a/flutter_leave_lc/android/settings.gradle b/flutter_leave_lc/android/settings.gradle index 5a2f14f..44e62bc 100644 --- a/flutter_leave_lc/android/settings.gradle +++ b/flutter_leave_lc/android/settings.gradle @@ -1,15 +1,11 @@ include ':app' -def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() -def plugins = new Properties() -def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') -if (pluginsFile.exists()) { - pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } -} +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } -plugins.each { name, path -> - def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() - include ":$name" - project(":$name").projectDir = pluginDirectory -} +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/flutter_leave_lc/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/flutter_leave_lc/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index c87d15a..6dd6010 100644 --- a/flutter_leave_lc/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/flutter_leave_lc/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ { LeaveTabPage(), WeeklyTabBarPage(), ContactsPage(), + SettingPage(), ]; @override @@ -110,6 +112,7 @@ class _HomeBottomBarPageState extends State { BottomNavigationBarItem( icon: Icon(Icons.event_note), title: Text('周报')), BottomNavigationBarItem(icon: Icon(Icons.phone), title: Text('联系人')), + BottomNavigationBarItem(icon: Icon(Icons.settings), title: Text('反馈')), ], currentIndex: this._currentIndex, fixedColor: Colors.blue, diff --git a/flutter_leave_lc/lib/LeavePage.dart b/flutter_leave_lc/lib/LeavePage.dart index 21aebd0..68baa7b 100644 --- a/flutter_leave_lc/lib/LeavePage.dart +++ b/flutter_leave_lc/lib/LeavePage.dart @@ -68,6 +68,7 @@ class _LeavePageState extends State { child: ListView( padding: EdgeInsets.symmetric(horizontal: 22.0), children: [ + Row( mainAxisAlignment: MainAxisAlignment.center, children: [ diff --git a/flutter_leave_lc/lib/Login.dart b/flutter_leave_lc/lib/Login.dart index 13ef49b..4d42d8a 100644 --- a/flutter_leave_lc/lib/Login.dart +++ b/flutter_leave_lc/lib/Login.dart @@ -1,9 +1,15 @@ import 'package:flutter/material.dart'; +import 'package:flutterapplc/Privacy.dart'; +import 'package:fluttertoast/fluttertoast.dart'; import 'HomeBottomBar.dart'; import 'SignUp.dart'; import 'Common/Global.dart'; import 'package:leancloud_storage/leancloud.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:flutter/services.dart'; +import 'package:leancloud_official_plugin/leancloud_plugin.dart'; + +import 'UserProtocol.dart'; //Todo 游客可以注册登录,LeanCloud 员工不必注册 @@ -21,6 +27,9 @@ class _LoginPageState extends State { String _userName, _password; bool _isObscure = true; Color _eyeColor; + bool _userProtocolSelected = false; + bool _privacySelected = false; + @override void initState() { @@ -92,6 +101,8 @@ class _LoginPageState extends State { buildPasswordTextField(context), buildForgetPasswordText(context), SizedBox(height: 60.0), + buildUserProtocol(context), + buildPrivacy(context), buildLoginButton(context), SizedBox(height: 30.0), buildRegisterText(context), @@ -151,7 +162,11 @@ class _LoginPageState extends State { if (_formKey.currentState.validate()) { //只有输入的内容符合要求通过才会到达此处 _formKey.currentState.save(); - userLogin(_userName, _password); + if (!_privacySelected || !_userProtocolSelected ) { + showToastRed('未同意用户使用协议或者隐私政策'); + } else { + userLogin(_userName, _password); + } } }, shape: StadiumBorder(side: BorderSide()), @@ -269,10 +284,85 @@ class _LoginPageState extends State { ), )); } - + Padding buildPrivacy(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(top: 1), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Checkbox( + value: _privacySelected, + activeColor: Colors.blue, //选中时的颜色 + onChanged: (value) { + setState(() { + _privacySelected = value; + }); + }, + ), + GestureDetector( + child: Text( + '我已阅读并同意隐私政策', + style: TextStyle( + color: Colors.blue, + decoration: TextDecoration.underline, + fontSize: 15.0, + ), + ), + onTap: () => showPrivacyPage(), + ) + ], + ), + ); + } + Padding buildUserProtocol(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(top: 1), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Checkbox( + value: _userProtocolSelected, + activeColor: Colors.blue, //选中时的颜色 + onChanged: (value) { + setState(() { + _userProtocolSelected = value; + }); + }, + ), + GestureDetector( + child: Text( + '我已阅读并同意用户使用协议', + style: TextStyle( + color: Colors.blue, + decoration: TextDecoration.underline, + fontSize: 15.0, + ), + ), + onTap: () => showUserProtocolPage(), + ) + ], + ), + ); + } Future login(String name, String password) async { LCUser user = await LCUser.login(name, password); } + showUserProtocolPage() { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => new UserProtocolPage(), + ), + ); + } + showPrivacyPage() { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => new PrivacyPage(), + ), + ); + } Future initLeanCloud() async { if (_userIfLeancloud == '游客登录') { diff --git a/flutter_leave_lc/lib/MyInformation.dart b/flutter_leave_lc/lib/MyInformation.dart index 7112306..7200b31 100644 --- a/flutter_leave_lc/lib/MyInformation.dart +++ b/flutter_leave_lc/lib/MyInformation.dart @@ -1,8 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:shared_preferences/shared_preferences.dart'; +import 'package:flutterapplc/Login.dart'; import 'package:leancloud_storage/leancloud.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import 'Common/Global.dart'; + + //TODO 手机号、邮箱、RealName class MyInformationPage extends StatefulWidget { MyInformationPage({Key key}) : super(key: key); @@ -12,7 +15,6 @@ class MyInformationPage extends StatefulWidget { class _MyInformationPageState extends State { final TextEditingController _controllerRealName = new TextEditingController(); final TextEditingController _controllerPhone = new TextEditingController(); - final TextEditingController _controllerPhone2 = new TextEditingController(); String _name = '暂无'; @@ -187,38 +189,174 @@ class _MyInformationPageState extends State { ], ), ), + new Container( + margin: const EdgeInsets.fromLTRB(0, 20, 10, 0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RaisedButton( + color: Colors.blue, + highlightColor: Colors.blue, + colorBrightness: Brightness.dark, + splashColor: Colors.grey, + child: Text("退出登录"), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0)), + onPressed: () { + showConfirmDialog(); + }, + ) + ], + ), + ), + new Container( + margin: const EdgeInsets.fromLTRB(0, 20, 10, 0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RaisedButton( + color: Colors.blue, + highlightColor: Colors.blue, + colorBrightness: Brightness.dark, + splashColor: Colors.grey, + child: Text("注销账号"), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0)), + onPressed: () { + showConfirmDialog_cancel(); + }, + ) + ], + ), + ), ], ), ), )); } -} + Future showConfirmDialog_cancel() async { + return showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text("提示"), + content: Text("确认注销账号吗"), + actions: [ + FlatButton( + child: Text("取消"), + onPressed: () => Navigator.of(context).pop(), // 关闭对话框 + ), + FlatButton( + child: Text("确认"), + onPressed: () { + //Client close; + //关闭对话框并返回true + clientCancel(); + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); + } + Future showConfirmDialog() async { + return showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text("提示"), + content: Text("确认退出登录"), + actions: [ + FlatButton( + child: Text("取消"), + onPressed: () => Navigator.of(context).pop(), // 关闭对话框 + ), + FlatButton( + child: Text("确认"), + onPressed: () { + //Client close; + //关闭对话框并返回true + clientClose(); + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); + } + //退出 + Future clientCancel() async { + CommonUtil.showLoadingDialog(context); //发起请求前弹出loading -Future updateProfile(String name, String phoneNumber) async { - LCUser user = await LCUser.getCurrent(); + cancel().then((value) { + Navigator.pop(context); //销毁 loading + Navigator.pushAndRemoveUntil( + context, + new MaterialPageRoute(builder: (context) => LoginPage()), + (_) => false); + }).catchError((error) { + showToastRed(error.message); + Navigator.pop(context); //销毁 loading + }); + } +//退出 + Future clientClose() async { + CommonUtil.showLoadingDialog(context); //发起请求前弹出loading + close().then((value) { + Navigator.pop(context); //销毁 loading + Navigator.pushAndRemoveUntil( + context, + new MaterialPageRoute(builder: (context) => LoginPage()), + (_) => false); + }).catchError((error) { + showToastRed(error.message); + Navigator.pop(context); //销毁 loading + }); + } + Future close() async { + LCUser user = await LCUser.getCurrent(); + if (user != null) { + await LCUser.logout(); + } else { + showToastRed('有 BUG,重启一下试试。。。'); + } + } + Future cancel() async { + LCUser user = await LCUser.getCurrent(); + if (user != null) { + await user.delete(); + } else { + showToastRed('有 BUG,重启一下试试。。。'); + } + } + Future updateProfile(String name, String phoneNumber) async { + LCUser user = await LCUser.getCurrent(); + user['mobilePhoneNumber'] = phoneNumber; + user['realName'] = name; + await user.save(); + } - user['mobilePhoneNumber'] = phoneNumber; - user['realName'] = name; + Future getUserData() async { - await user.save(); -} + LCUser user = await LCUser.getCurrent(); + dynamic currentUser; + try { + Map userMap = await LCCloud.run('queryUsers'); + List users = userMap['result']; -Future getUserData() async { - LCUser user = await LCUser.getCurrent(); - dynamic currentUser; - try { - Map userMap = await LCCloud.run('queryUsers'); - List users = userMap['result']; - - for (var obj in users) { - if (obj['objectId'] == user.objectId) { - currentUser = obj; - return currentUser; + for (var obj in users) { + if (obj['objectId'] == user.objectId) { + currentUser = obj; + return currentUser; + } } + } on LCException catch (e) { + showToastRed(e.message); } - } on LCException catch (e) { - showToastRed(e.message); + + return user; } - return user; } diff --git a/flutter_leave_lc/lib/MyWeekly.dart b/flutter_leave_lc/lib/MyWeekly.dart index 62cd842..04283c9 100644 --- a/flutter_leave_lc/lib/MyWeekly.dart +++ b/flutter_leave_lc/lib/MyWeekly.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:leancloud_storage/leancloud.dart'; -import 'package:date_format/date_format.dart'; import 'Common/Global.dart'; //TODO:管理员请假、delete 历史记录 diff --git a/flutter_leave_lc/lib/Privacy.dart b/flutter_leave_lc/lib/Privacy.dart new file mode 100644 index 0000000..90aed71 --- /dev/null +++ b/flutter_leave_lc/lib/Privacy.dart @@ -0,0 +1,48 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_webview_plugin/flutter_webview_plugin.dart'; +class PrivacyPage extends StatefulWidget { + @override + _UserProtocolPageState createState() => new _UserProtocolPageState(); +} + +class _UserProtocolPageState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { +// String str = ''' +// 本应用不收集任何用户信息。包括: +// +// 1. 不会收集设备 Mac 地址,也不会采集唯一设备识别码(如 IMEI / android ID / IDFA / OPENUDID / GUID、SIM 卡 IMSI 信息)对用户进行唯一标识。 +// +// 2.不会访问用户个人信息,也不会访问其他应用的数据信息。 +// +// 个人信息权限授予说明: +// +// 1.应用开启 INTERNET 权限,用于允许应用程序联网和发送请求数据的权限,以便保存用户数据。 +// +// 2.应用开启 ACCESS_NETWORK_STATE 权限, 用于检测联网方式,在网络异常状态下避免数据发送,节省流量和电量。 +// +// 除此之外,本应用不要求任何系统权限。 +// +// 公司主体:2021 美味书签(北京)信息技术有限公司 +// +// '''; + return new WebviewScaffold( + url:"https://leancn.goodluckin.top/", + appBar: AppBar( + //导航栏 + title: Text("用户隐私政策"), + centerTitle: true, + ), + withZoom: true, + // 允许网页缩放 + withLocalStorage: true, + // 允许LocalStorage + withJavascript: true, // 允许执行js代码 + ); + } +} \ No newline at end of file diff --git a/flutter_leave_lc/lib/Setting.dart b/flutter_leave_lc/lib/Setting.dart new file mode 100644 index 0000000..4b902e0 --- /dev/null +++ b/flutter_leave_lc/lib/Setting.dart @@ -0,0 +1,136 @@ +import 'package:flutter/material.dart'; +import 'package:leancloud_storage/leancloud.dart'; +import 'Common/Global.dart'; + +class SettingPage extends StatefulWidget { + SettingPage({Key key}) : super(key: key); + _SettingPageState createState() => _SettingPageState(); +} + +class _SettingPageState extends State { + final TextEditingController _controller = new TextEditingController(); +// 弹出对话框 + Future showDeleteConfirmDialog1() async { + return showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text("提示"), + content: Text("确认保存修改?"), + actions: [ + FlatButton( + child: Text("取消"), + onPressed: () => Navigator.of(context).pop(), // 关闭对话框 + ), + FlatButton( + child: Text("保存"), + onPressed: () { + saveWeekly(_controller.text) + .then((response) {}) + .catchError((error) { + showToastRed(error); + }); + //关闭对话框并返回true + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); + } + + @override + void initState() { + // TODO: implement initState + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: new Container( + padding: const EdgeInsets.all(10), + child: ListView( + // padding: EdgeInsets.symmetric(horizontal: 22.0), + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('意见反馈', + style: TextStyle( + fontSize: 23.0, + fontWeight: FontWeight.bold, + letterSpacing: 6.0, + )), + ], + ), + Row( + children: [ + new Expanded( + child: new Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + new Container( + padding: const EdgeInsets.only( + bottom: 8.0, right: 8, left: 10), + child: TextField( + controller: _controller, + textInputAction: TextInputAction.done, + keyboardType: TextInputType.multiline, + maxLines: 20, + minLines: 7, + decoration: const InputDecoration( + filled: true, + hintText: "反馈内容...", + fillColor: Colors.white, + contentPadding: const EdgeInsets.symmetric( + horizontal: 20, vertical: 10), + isDense: true, + border: const OutlineInputBorder( + gapPadding: 10, + borderRadius: + const BorderRadius.all(Radius.circular(4)), + borderSide: BorderSide( + width: 2, + style: BorderStyle.none, + ), + ), + ), + ), + ), + new Container( + padding: const EdgeInsets.only( + bottom: 8.0, right: 8, left: 10), + child: RaisedButton( + child: Text('保存'), + onPressed: () async { + //弹出对话框并等待其关闭 + bool delete = await showDeleteConfirmDialog1(); + if (delete == false) { + print("取消"); + } else { + print("保存"); + } + }, + )), + ], + ), + ), + ], + ), + ], + ), + )); + } +} + +Future saveWeekly(String text) async { + LCUser user = await LCUser.getCurrent(); + LCObject obj = LCObject('Feedback'); + obj['content'] = text; + obj['user'] = user; + LCObject object = await obj.save(); + showToastGreen('提交成功'); + return object; +} diff --git a/flutter_leave_lc/lib/UserProtocol.dart b/flutter_leave_lc/lib/UserProtocol.dart new file mode 100644 index 0000000..1fdfefd --- /dev/null +++ b/flutter_leave_lc/lib/UserProtocol.dart @@ -0,0 +1,62 @@ +import 'package:flutter/material.dart'; + +class UserProtocolPage extends StatefulWidget { + @override + _UserProtocolPageState createState() => new _UserProtocolPageState(); +} + +class _UserProtocolPageState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + String str = ''' + +LeanCN 是 LeanCloud 公司内部员工使用的工具类应用,用于请假、写周报、给同事打电话。用户使用本应用需接受本协议的全部条款。 + +1.您使用本应用的行为必须合法。 + +2.我们将保留基于我们的判断检查用户内容的权利。 + +3.您在应用内上传与发布的内容必须合法,否则您将承担全部法律责任。 + +4.一旦发现您上传的内容非法,我们会删除您账号下的全部数据,并禁止继续访问。 + +5. 禁止发布危害国家安全、泄露国家机密、破坏国家统一的内容。 + +6. 禁止发布煽动民族仇恨、民族歧视,破坏民族团结的内容。 + +7. 禁止发布破坏国家宗教政策,宣扬邪教和封建迷信的内容。 + +8. 禁止发布扰乱社会秩序,破坏社会稳定的谣言。 + +9. 禁止散步淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪的内容 + +10. 禁止发布侮辱或者诽谤他人,侵害他人合法权益的内容 + +11. 禁止发布含有法律、行政法规禁止的其他内容的。 + '''; + return Scaffold( + appBar: AppBar( + //导航栏 + title: Text("用户协议"), + centerTitle: true, + ), + body: Scrollbar( + // 显示进度条 + child: SingleChildScrollView( + padding: EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(str), + ], + + ), + )) + ); + } +} \ No newline at end of file diff --git a/flutter_leave_lc/pubspec.yaml b/flutter_leave_lc/pubspec.yaml index 877f218..324a384 100644 --- a/flutter_leave_lc/pubspec.yaml +++ b/flutter_leave_lc/pubspec.yaml @@ -11,7 +11,9 @@ description: A new Flutter application. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+4 +version: 1.0.0+1 + + environment: sdk: ">=2.1.0 <3.0.0" @@ -31,6 +33,8 @@ dependencies: flutter_markdown: ^0.6.9 url_launcher: ^6.0.17 get_it: ^7.2.0 + leancloud_official_plugin: ^1.0.1 + flutter_webview_plugin: ^0.4.0 dev_dependencies: