commit f41919ba5a0a3ea0d797bda54c8dd88b63b06eaf
Author: 18631081161 <2088094923@qq.com>
Date: Mon Jun 3 15:30:15 2024 +0800
首次提交
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..489faea
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,45 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+migrate_working_dir/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+**/ios/Flutter/.last_build_id
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.packages
+.pub-cache/
+.pub/
+/build/
+
+# Symbolication related
+app.*.symbols
+
+# Obfuscation related
+app.*.map.json
+
+# Android Studio will place build artifacts here
+/android/app/debug
+/android/app/profile
+/android/app/release
+/pubspec.lock
diff --git a/.metadata b/.metadata
new file mode 100644
index 0000000..1b95e72
--- /dev/null
+++ b/.metadata
@@ -0,0 +1,30 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled.
+
+version:
+ revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
+ channel: stable
+
+project_type: app
+
+# Tracks metadata for the flutter migrate command
+migration:
+ platforms:
+ - platform: root
+ create_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
+ base_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
+ - platform: android
+ create_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
+ base_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
+
+ # User provided section
+
+ # List of Local paths (relative to this file) that should be
+ # ignored by the migrate tool.
+ #
+ # Files that are not part of the templates will be ignored by default.
+ unmanaged_files:
+ - 'lib/main.dart'
+ - 'ios/Runner.xcodeproj/project.pbxproj'
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..ed55099
--- /dev/null
+++ b/README.md
@@ -0,0 +1,92 @@
+# Ai_drawing
+
+AI绘图包
+
+## Getting started
+
+To make it easy for you to get started with GitLab, here's a list of recommended next steps.
+
+Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
+
+## Add your files
+
+- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
+- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
+
+```
+cd existing_repo
+git remote add origin http://192.168.1.33/mogu_flutter/ai_drawing.git
+git branch -M main
+git push -uf origin main
+```
+
+## Integrate with your tools
+
+- [ ] [Set up project integrations](http://192.168.1.33/mogu_flutter/ai_drawing/-/settings/integrations)
+
+## Collaborate with your team
+
+- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
+- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
+- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
+- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
+- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
+
+## Test and Deploy
+
+Use the built-in continuous integration in GitLab.
+
+- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
+- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
+- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
+- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
+- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
+
+***
+
+# Editing this README
+
+When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template.
+
+## Suggestions for a good README
+Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
+
+## Name
+Choose a self-explaining name for your project.
+
+## Description
+Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
+
+## Badges
+On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
+
+## Visuals
+Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
+
+## Installation
+Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
+
+## Usage
+Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
+
+## Support
+Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
+
+## Roadmap
+If you have ideas for releases in the future, it is a good idea to list them in the README.
+
+## Contributing
+State if you are open to contributions and what your requirements are for accepting them.
+
+For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
+
+You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
+
+## Authors and acknowledgment
+Show your appreciation to those who have contributed to the project.
+
+## License
+For open source projects, say how it is licensed.
+
+## Project status
+If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
diff --git a/analysis_options.yaml b/analysis_options.yaml
new file mode 100644
index 0000000..61b6c4d
--- /dev/null
+++ b/analysis_options.yaml
@@ -0,0 +1,29 @@
+# This file configures the analyzer, which statically analyzes Dart code to
+# check for errors, warnings, and lints.
+#
+# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
+# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
+# invoked from the command line by running `flutter analyze`.
+
+# The following line activates a set of recommended lints for Flutter apps,
+# packages, and plugins designed to encourage good coding practices.
+include: package:flutter_lints/flutter.yaml
+
+linter:
+ # The lint rules applied to this project can be customized in the
+ # section below to disable rules from the `package:flutter_lints/flutter.yaml`
+ # included above or to enable additional rules. A list of all available lints
+ # and their documentation is published at
+ # https://dart-lang.github.io/linter/lints/index.html.
+ #
+ # Instead of disabling a lint rule for the entire project in the
+ # section below, it can also be suppressed for a single line of code
+ # or a specific dart file by using the `// ignore: name_of_lint` and
+ # `// ignore_for_file: name_of_lint` syntax on the line or in the file
+ # producing the lint.
+ rules:
+ # avoid_print: false # Uncomment to disable the `avoid_print` rule
+ # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options
diff --git a/android/.gitignore b/android/.gitignore
new file mode 100644
index 0000000..6f56801
--- /dev/null
+++ b/android/.gitignore
@@ -0,0 +1,13 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/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/android/app/build.gradle b/android/app/build.gradle
new file mode 100644
index 0000000..41e1d54
--- /dev/null
+++ b/android/app/build.gradle
@@ -0,0 +1,85 @@
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+ localPropertiesFile.withReader('UTF-8') { reader ->
+ localProperties.load(reader)
+ }
+}
+
+def flutterRoot = localProperties.getProperty('flutter.sdk')
+if (flutterRoot == null) {
+ throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
+}
+
+def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
+if (flutterVersionCode == null) {
+ flutterVersionCode = '1'
+}
+
+def flutterVersionName = localProperties.getProperty('flutter.versionName')
+if (flutterVersionName == null) {
+ flutterVersionName = '1.0'
+}
+
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
+android {
+ compileSdkVersion 33
+ ndkVersion flutter.ndkVersion
+
+
+ signingConfigs {
+ //签名的配置
+ signConfig {
+ storeFile file("aiDraw.jks")
+ storePassword '123456'
+ keyAlias 'aiDraw'
+ keyPassword '123456'
+ }
+ }
+
+ lintOptions {
+ //如打包出现Failed to transform libs.jar to match attributes
+ checkReleaseBuilds false
+ }
+
+ 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 "com.hissai.draw"
+ minSdkVersion 19
+ targetSdkVersion 33
+ versionCode flutterVersionCode.toInteger()
+ versionName flutterVersionName
+
+ multiDexEnabled true
+ }
+
+ buildTypes {
+ release {
+ // TODO: Add your own signing config for the release build.
+ signingConfig signingConfigs.signConfig //打包命令行:gradlew assembleRelease
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ //关闭混淆
+ minifyEnabled false //删除无用代码
+ shrinkResources false //删除无用资源
+ }
+ debug {
+ signingConfig signingConfigs.signConfig
+ }
+ }
+
+ dependencies {
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ }
+}
+
+flutter {
+ source '../..'
+}
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..04f4627
--- /dev/null
+++ b/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/assets/holybladeCloud.properties b/android/app/src/main/assets/holybladeCloud.properties
new file mode 100644
index 0000000..9100c19
--- /dev/null
+++ b/android/app/src/main/assets/holybladeCloud.properties
@@ -0,0 +1,2 @@
+BossId=27014
+AppId=1001
\ No newline at end of file
diff --git a/android/app/src/main/java/com/hissai/draw/App.java b/android/app/src/main/java/com/hissai/draw/App.java
new file mode 100644
index 0000000..3ee8bea
--- /dev/null
+++ b/android/app/src/main/java/com/hissai/draw/App.java
@@ -0,0 +1,30 @@
+package com.hissai.draw;
+
+import android.content.Context;
+
+import io.flutter.app.FlutterApplication;
+
+public class App extends FlutterApplication {
+
+
+ private static App instance;
+
+ @Override
+ protected void attachBaseContext(Context base) {
+ super.attachBaseContext(base);
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ instance = this;
+
+ }
+
+
+ public static App getInstance() {
+ return instance;
+ }
+
+
+}
diff --git a/android/app/src/main/java/com/hissai/draw/MainActivity.java b/android/app/src/main/java/com/hissai/draw/MainActivity.java
new file mode 100644
index 0000000..570774b
--- /dev/null
+++ b/android/app/src/main/java/com/hissai/draw/MainActivity.java
@@ -0,0 +1,82 @@
+package com.hissai.draw;
+
+import android.os.Bundle;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.hissai.draw.utils.AppUtil;
+import com.hissai.draw.utils.Configs;
+import com.hissai.draw.utils.MacInfo;
+import com.hissai.draw.utils.NetWork;
+import com.hissai.draw.utils.ThreadUtil;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import io.flutter.embedding.android.FlutterActivity;
+import io.flutter.embedding.engine.FlutterEngine;
+import io.flutter.plugin.common.MethodChannel;
+import io.flutter.plugin.common.StandardMethodCodec;
+
+public class MainActivity extends FlutterActivity {
+ private static final String CHANNEL = "samples.flutter.dev/battery";
+ private MethodChannel nativeChannel;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ ThreadUtil.INST.excute(() -> NetWork.getConfigs(MainActivity.this));
+
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ }
+
+
+ //flutter 通道
+ @Override
+ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
+ super.configureFlutterEngine(flutterEngine);
+ Log.d("TAG", "configureFlutterEngine: flutterEngine");
+ nativeChannel = new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL, StandardMethodCodec.INSTANCE);
+ nativeChannel.setMethodCallHandler((call, result) -> {
+ switch (call.method) {
+ case "getRequestHeaders":
+ Map map = new HashMap<>();
+ map.put("AppId", Configs.appId);
+ map.put("BossId", Configs.bossId);
+ map.put("Version", Configs.versionName);
+ map.put("CPU", Configs.cpu);
+ MacInfo.imsi = MacInfo.getSubscriptionOperatorType();
+ map.put("imsi", MacInfo.imsi != null ? MacInfo.imsi : "");
+ map.put("ip", Configs.ip);
+ map.put("timeZone", AppUtil.getTimeZone());
+ map.put("statusHeight", AppUtil.px2dip(App.getInstance(), AppUtil.getStatusBarHeight(App.getInstance())));//状态栏高度
+ result.success(map);
+ break;
+
+ case "initAPI"://同意隐私初始化信息
+ ThreadUtil.INST.excute(() -> {
+ NetWork.getInit(MainActivity.this);
+ });
+ break;
+ }
+
+ });
+ }
+}
diff --git a/android/app/src/main/java/com/hissai/draw/utils/AppUtil.java b/android/app/src/main/java/com/hissai/draw/utils/AppUtil.java
new file mode 100644
index 0000000..7b7a08e
--- /dev/null
+++ b/android/app/src/main/java/com/hissai/draw/utils/AppUtil.java
@@ -0,0 +1,807 @@
+package com.hissai.draw.utils;
+
+import android.Manifest;
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.AppOpsManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.media.AudioManager;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.os.Build;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.WindowManager;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import androidx.annotation.RequiresApi;
+import androidx.core.app.ActivityCompat;
+import androidx.core.app.NotificationManagerCompat;
+
+import com.hissai.draw.App;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * App工具类
+ */
+public class AppUtil {
+
+ public static boolean checkURL(String url) {
+ boolean value = false;
+ try {
+ HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
+ int code = conn.getResponseCode();
+ if (code != 200) {
+ value = false;
+ } else {
+ value = true;
+ }
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return value;
+ }
+
+ /**
+ * 获得屏幕宽度
+ *
+ * @param context
+ * @return
+ */
+ public static int getScreenWidth(Context context) {
+ WindowManager wm = (WindowManager) context
+ .getSystemService(Context.WINDOW_SERVICE);
+ DisplayMetrics outMetrics = new DisplayMetrics();
+ wm.getDefaultDisplay().getMetrics(outMetrics);
+ return outMetrics.widthPixels;
+ }
+
+ /**
+ * 获得屏幕高度
+ * 小于android4.4去掉状态栏高度
+ *
+ * @param context
+ * @return
+ */
+ public static int getScreenHeight(Context context) {
+ WindowManager wm = (WindowManager) context
+ .getSystemService(Context.WINDOW_SERVICE);
+ DisplayMetrics outMetrics = new DisplayMetrics();
+ wm.getDefaultDisplay().getMetrics(outMetrics);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ return outMetrics.heightPixels;
+ } else {
+ return outMetrics.heightPixels - getStatusBarHeight(context);
+ }
+
+ }
+
+ /**
+ * 获取状态栏高度
+ *
+ * @param context
+ * @return
+ */
+ public static int getStatusBarHeight(Context context) {
+ int result = 0;
+ try {
+ int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
+ if (resourceId > 0) {
+ result = context.getResources().getDimensionPixelSize(resourceId);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ // 根据手机的分辨率从 px(像素) 的单位 转成为 dp
+ public static int px2dip(Context context, float pxValue) {
+ // 获取当前手机的像素密度(1个dp对应几个px)
+ float scale = context.getResources().getDisplayMetrics().density;
+ return (int) (pxValue / scale + 0.5f); // 四舍五入取整
+ }
+
+ /**
+ * 获取屏幕宽度
+ *
+ * @param context
+ * @return
+ */
+ public static int getWindowWidth(Context context) {
+ // 获取屏幕分辨率
+ WindowManager wm = (WindowManager) (context
+ .getSystemService(Context.WINDOW_SERVICE));
+ DisplayMetrics dm = new DisplayMetrics();
+ wm.getDefaultDisplay().getMetrics(dm);
+ int mScreenWidth = dm.widthPixels;
+ return mScreenWidth;
+ }
+
+ /**
+ * 获取屏幕高度
+ *
+ * @param context
+ * @return
+ */
+ public static int getWindowHight(Context context) {
+ // 获取屏幕分辨率
+ WindowManager wm = (WindowManager) (context.getSystemService(Context.WINDOW_SERVICE));
+ DisplayMetrics dm = new DisplayMetrics();
+ wm.getDefaultDisplay().getMetrics(dm);
+ int mScreenHight = dm.heightPixels;
+ return mScreenHight;
+ }
+
+ /**
+ * 检测耳机是否接入
+ * 0:无插入,1:耳机和话筒均插入,2:仅插入话筒
+ *
+ * @return
+ */
+ public static boolean isHeadsetExists(Context context) {
+ AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ return audioManager.isWiredHeadsetOn();
+ }
+
+ public static boolean isBlueTooth(Context context) {
+
+ AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ return audioManager.isBluetoothA2dpOn();
+ }
+
+
+ /**
+ * 获取唯一设备号
+ *
+ * @param context
+ * @return
+ */
+ public static String getDeviceId(Context context) {
+ String android_id = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
+ Log.d("TAG", "getDeviceId: android_id==" + android_id);
+ return android_id;
+ }
+
+ /**
+ * 隐藏软键盘
+ *
+ * @param context
+ * @param editText
+ * @return
+ */
+ public static void hideInputMethod(Context context, EditText editText) {
+ InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
+ }
+
+ /**
+ * 隐藏软键盘
+ *
+ * @param activity
+ * @return
+ */
+ public static boolean hideInputMethod(Activity activity) {
+ InputMethodManager imm = (InputMethodManager) activity
+ .getSystemService(Context.INPUT_METHOD_SERVICE);
+ if (activity.getCurrentFocus() == null)
+ return false;
+ return imm.hideSoftInputFromWindow(activity.getCurrentFocus()
+ .getApplicationWindowToken(),
+ InputMethodManager.HIDE_NOT_ALWAYS);
+ }
+
+ /**
+ * 显示或者隐藏状态栏;true隐藏,false显示
+ *
+ * @param @param context
+ * @param @param enable
+ * @return void
+ * @description
+ * @author yanqin
+ */
+ public static void full(Context context, boolean enable) {
+ if (enable) {
+ ((Activity) context).getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//隐藏状态栏
+ } else {
+ ((Activity) context).getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); //显示状态栏
+ }
+ }
+
+
+ //打开扬声器
+ public static void OpenSpeaker(Context mContext) {
+ try {
+ //判断扬声器是否在打开
+ AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ audioManager.setMode(AudioManager.ROUTE_SPEAKER);
+ //获取当前通话音量
+ audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
+ if (!audioManager.isSpeakerphoneOn()) {
+ audioManager.setSpeakerphoneOn(true);
+ audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,
+ audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL),
+ AudioManager.STREAM_VOICE_CALL);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+
+ //关闭扬声器
+ public static void CloseSpeaker(Context mContext) {
+ try {
+ AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ if (audioManager != null) {
+ if (audioManager.isSpeakerphoneOn()) {
+ audioManager.setSpeakerphoneOn(false);
+ audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, 50,
+ AudioManager.STREAM_VOICE_CALL);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static String getUserAgent(Context context) {
+ String userAgent = "";
+ if (context != null) {
+ PackageManager pm = context.getPackageManager();
+
+ if (pm != null) {
+ String appName = context.getApplicationInfo().loadLabel(pm).toString();
+ String packageName = context.getPackageName();
+ userAgent = packageName.substring(packageName.lastIndexOf(".") + 1, packageName.length());
+ userAgent = userAgent + "/" + getVersionName(context);
+ userAgent = userAgent + "(" + Build.MODEL + ";" + getAndroidSDKVersionString() + ")";
+ }
+ }
+
+ if (userAgent != null) {
+ if (isChinese(userAgent)) {
+ userAgent = chinaToUnicode(userAgent);
+ }
+ }
+ return userAgent;
+ }
+
+ // 判断一个字符是否是中文
+ public static boolean isChinese(char c) {
+ return c >= 0x4E00 && c <= 0x9FA5;// 根据字节码判断
+ }
+
+ // 判断一个字符串是否含有中文
+ public static boolean isChinese(String str) {
+ if (str == null)
+ return false;
+ for (char c : str.toCharArray()) {
+ if (isChinese(c))
+ return true;// 有一个中文字符就返回
+ }
+ return false;
+ }
+
+ public static String chinaToUnicode(String str) {
+ String result = null;
+ for (int i = 0; i < str.length(); i++) {
+ int chr1 = (char) str.charAt(i);
+ result += "\\u" + Integer.toHexString(chr1);
+ }
+ return result;
+ }
+
+
+ /**
+ * 描述:判断网络是否有效.
+ *
+ * @param context the context
+ * @return true, if is network available
+ */
+ public static boolean isNetworkAvailable(Context context) {
+ try {
+ ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ if (connectivity != null) {
+ NetworkInfo info = connectivity.getActiveNetworkInfo();
+ if (info != null && info.isConnected()) {
+ if (info.getState() == NetworkInfo.State.CONNECTED) {
+ return true;
+ }
+ }
+ }
+ } catch (Exception e) {
+ return false;
+ }
+ return false;
+ }
+
+
+ /**
+ * 描述:判断网络是否有效.没有网络时进行提示
+ *
+ * @param context the context
+ * @return true, if is network available
+ */
+ public static boolean isNetworkAvailableMsg(Context context, int msgId) {
+ try {
+ ConnectivityManager connectivity = (ConnectivityManager) context
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ if (connectivity != null) {
+ NetworkInfo info = connectivity.getActiveNetworkInfo();
+ if (info != null && info.isConnected()) {
+ if (info.getState() == NetworkInfo.State.CONNECTED) {
+ return true;
+ } else {
+ Toast.makeText(context, msgId, Toast.LENGTH_SHORT).show();
+ }
+ } else {
+ Toast.makeText(context, msgId, Toast.LENGTH_SHORT).show();
+ }
+ }
+ } catch (Exception e) {
+ return false;
+ }
+ return false;
+ }
+
+ /**
+ * 判断当前网络是否是wifi网络.
+ *
+ * @param context the context
+ * @return boolean
+ */
+ public static boolean isWifi(Context context) {
+ ConnectivityManager connectivityManager = (ConnectivityManager) context
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
+ if (activeNetInfo != null
+ && activeNetInfo.getType() == ConnectivityManager.TYPE_WIFI) {
+ return true;
+ }
+ return false;
+ }
+
+ //版本号
+ public static int getVersionCode(Context context) {
+ return getPackageInfo(context).versionCode;
+ }
+
+ private static PackageInfo getPackageInfo(Context context) {
+ PackageInfo pi = null;
+
+ try {
+ PackageManager pm = context.getPackageManager();
+ pi = pm.getPackageInfo(context.getPackageName(),
+ PackageManager.GET_CONFIGURATIONS);
+
+
+ return pi;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return pi;
+ }
+
+
+ /**
+ * 获取当前应用的版本名
+ *
+ * @return
+ */
+ public static String getVersionName(Context context) {
+ // 获取packagemanager的实例
+ if (context == null) {
+ return "";
+ }
+ PackageManager packageManager = context.getPackageManager();
+ if (packageManager == null)
+ return "";
+ // getPackageName()是你当前类的包名,0代表是获取版本信息
+ PackageInfo packInfo;
+ String version = "";
+ try {
+ packInfo = packageManager.getPackageInfo(context.getPackageName(),
+ 0);
+ version = packInfo.versionName;
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return version;
+ }
+
+
+ /**
+ * 初始化手机屏幕的宽高
+ *
+ * @param activity
+ */
+ public static DisplayMetrics getScreenSize(Activity activity) {
+ DisplayMetrics dm = new DisplayMetrics();
+ activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
+ return dm;
+ }
+
+ /**
+ * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
+ */
+ public static int dip2px(Context context, double dpValue) {
+ Context mContext = context;//防止获取的上下文为空
+ final float scale = mContext.getResources().getDisplayMetrics().density;
+ return (int) (dpValue * scale + 0.5f);
+ }
+
+ /**
+ * 判断是否有sim卡
+ *
+ * @param context
+ * @return
+ */
+ public static boolean hasSimCard(Context context) {
+ TelephonyManager telMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ int simState = telMgr.getSimState();
+ boolean result = true;
+ switch (simState) {
+ case TelephonyManager.SIM_STATE_ABSENT:
+ result = false; // 没有SIM卡
+ break;
+ case TelephonyManager.SIM_STATE_UNKNOWN:
+ result = false;
+ break;
+ }
+ return result;
+ }
+
+ /**
+ * 判断是否是通话设备
+ *
+ * @param context
+ * @return
+ */
+ public static boolean isPhoneDevice(Context context) {
+ TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ int type = telephony.getPhoneType();
+ if (type == TelephonyManager.PHONE_TYPE_NONE) {
+ //是通话设备
+ return false;
+ } else {
+ //不是通话设备
+ return true;
+ }
+
+ }
+
+
+ /**
+ * 获取手机系统版本
+ *
+ * @param @return
+ * @return String
+ * @description
+ * @author yanqin
+ */
+ public static String getAndroidSDKVersionString() {
+
+ return "Android " + Build.VERSION.RELEASE;
+ }
+
+
+ /**
+ * 获取外网的IP(要访问Url,要放到后台线程里处理)
+ *
+ * @param @return
+ * @return String
+ * @throws
+ * @Title: GetNetIp
+ * @Description:
+ */
+ public static String getNetIp() {
+ URL infoUrl = null;
+ InputStream inStream = null;
+ String ipLine = "";
+ HttpURLConnection httpConnection = null;
+ try {
+ infoUrl = new URL("http://pv.sohu.com/cityjson?ie=utf-8");//必须要用这个网址,因为这个网址返回了我们的ip地址。
+ URLConnection connection = infoUrl.openConnection();
+ httpConnection = (HttpURLConnection) connection;
+ int responseCode = httpConnection.getResponseCode();
+ if (responseCode == HttpURLConnection.HTTP_OK) {
+ inStream = httpConnection.getInputStream();
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(inStream, "utf-8"));
+ StringBuilder strber = new StringBuilder();
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ strber.append(line + "\n");
+ }
+
+ Pattern pattern = Pattern
+ .compile("((?:(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d)))\\.){3}(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d))))");
+ Matcher matcher = pattern.matcher(strber.toString());
+ if (matcher.find()) {
+ ipLine = matcher.group();
+ }
+ //释放资源
+ reader.close();
+ }
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ inStream.close();
+ httpConnection.disconnect();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ return ipLine;
+ }
+
+ /**
+ * 判断android activity是否运行(可见)
+ *
+ * @param mContext
+ * @param activityClassName
+ * @return
+ */
+ public static boolean isActivityRunning(Context mContext, String activityClassName) {
+ ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+ List info = activityManager.getRunningTasks(1);
+ if (info != null && info.size() > 0) {
+ ComponentName component = info.get(0).topActivity;
+ if (activityClassName.equals(component.getClassName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 获取手机型号
+ *
+ * @return 手机型号
+ */
+ public static String getSystemModel() {
+ return Build.MODEL;
+ }
+
+ /**
+ * 获取手机厂商
+ *
+ * @return 手机厂商
+ */
+ public static String getDeviceBrand() {
+ return Build.BRAND;
+ }
+
+ /**
+ * 获取手机IMEI(需要“android.permission.READ_PHONE_STATE”权限)
+ *
+ * @return 手机IMEI
+ */
+ public static String getIMEI(Context ctx) {
+ TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Activity.TELEPHONY_SERVICE);
+ if (tm != null) {
+ if (ActivityCompat.checkSelfPermission(ctx, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
+ return "";
+ }
+ return tm.getDeviceId();
+ }
+ return null;
+ }
+
+ /**
+ * 获取手机mac地址
+ * 注:并不是所有机型都适配
+ *
+ * @param ctx
+ * @return
+ */
+ public static String getWifiMac(Context ctx) {
+ WifiManager wifi = (WifiManager) ctx.getSystemService(Context.WIFI_SERVICE);
+ WifiInfo info = wifi.getConnectionInfo();
+ String str = info.getMacAddress();
+ if (str == null) str = "";
+ return str;
+ }
+
+ /**
+ * 这是使用adb shell命令来获取mac地址的方式
+ *
+ * @return
+ */
+ public static String getMac(Context ctx) {
+ String macSerial = null;
+ String str = "";
+
+ try {
+ Process pp = Runtime.getRuntime().exec("cat /sys/class/net/wlan0/address ");
+ InputStreamReader ir = new InputStreamReader(pp.getInputStream());
+ LineNumberReader input = new LineNumberReader(ir);
+
+ for (; null != str; ) {
+ str = input.readLine();
+ if (str != null) {
+ macSerial = str.trim();// 去空格
+ break;
+ }
+ }
+ //释放资源
+ ir.close();
+ input.close();
+ } catch (IOException ex) {
+ // 赋予默认值
+ ex.printStackTrace();
+ }
+ if ("".equals(str)) {
+ return getWifiMac(ctx);
+ }
+
+
+ return macSerial;
+ }
+
+ /**
+ * 获取系统音量
+ *
+ * @return
+ */
+ public static int getMediaVolume(Context context) {
+ AudioManager audioMgr = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ return audioMgr.getStreamVolume(AudioManager.STREAM_MUSIC);
+ }
+
+ /**
+ * 获取系统最大音量
+ *
+ * @param streamType AudioManager.STREAM_MUSIC 声道
+ * @return
+ */
+ public static int getMediaMaxVolume(Context context, int streamType) {
+ AudioManager audioMgr = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ return audioMgr.getStreamMaxVolume(streamType);
+ }
+
+ /**
+ * 设置音量
+ *
+ * @param volume
+ */
+ public static void setMediaVolume(int volume, Context context) {
+ AudioManager audioMgr = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ audioMgr.setStreamVolume(AudioManager.STREAM_MUSIC, volume, AudioManager.FLAG_PLAY_SOUND);
+ }
+
+ /**
+ * 设置音量
+ *
+ * @param volume
+ */
+ public static void setMediaVolumeNoSound(int volume, Context context) {
+ AudioManager audioMgr = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ audioMgr.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
+ }
+
+ /**
+ * 获取是否存在NavigationBar(虚拟按键)
+ *
+ * @param @param context
+ * @param @return
+ * @return boolean
+ * @description
+ * @author yanqin
+ */
+ private static boolean checkDeviceHasNavigationBar(Context context) {
+ boolean hasNavigationBar = false;
+ Resources rs = context.getResources();
+ int id = rs
+ .getIdentifier("config_showNavigationBar", "bool", "android");
+ if (id > 0) {
+ hasNavigationBar = rs.getBoolean(id);
+ }
+ try {
+ Class systemPropertiesClass = Class
+ .forName("android.os.SystemProperties");
+ Method m = systemPropertiesClass.getMethod("get", String.class);
+ String navBarOverride = (String) m.invoke(systemPropertiesClass,
+ "qemu.hw.mainkeys");
+ if ("1".equals(navBarOverride)) {
+ hasNavigationBar = false;
+ } else if ("0".equals(navBarOverride)) {
+ hasNavigationBar = true;
+ }
+ } catch (Exception e) {
+
+ }
+ return hasNavigationBar;
+ }
+
+
+ /**
+ * 获取NavigationBar(虚拟按键)的高度:
+ *
+ * @param @param context
+ * @param @return
+ * @return int
+ * @description
+ * @author yangqin
+ */
+ public static int getNavigationBarHeight(Context context) {
+ int navigationBarHeight = 0;
+ Resources rs = context.getResources();
+ int id = rs.getIdentifier("navigation_bar_height", "dimen", "android");
+ if (id > 0 && checkDeviceHasNavigationBar(context)) {
+ navigationBarHeight = rs.getDimensionPixelSize(id);
+ }
+ return navigationBarHeight;
+ }
+
+
+
+ //获取系统语言
+ public static String getSystemLan() {
+ Locale locale = App.getInstance().getResources().getConfiguration().locale;
+
+ String language = locale.getLanguage();
+
+ String local = Locale.getDefault().toString();
+
+ String country = App.getInstance().getResources().getConfiguration().locale.getCountry();
+
+ Log.e("HJL", "tjCountry: language:" + language + ",local:" + local + ",country:" + country);
+ return language;
+ }
+
+ //获取系统时区
+ public static String getTimeZone() {
+ TimeZone timeZone = TimeZone.getDefault();
+ String id = timeZone.getID(); //获取时区id,如“Asia/Shanghai”
+ String name = timeZone.getDisplayName(); //获取名字,如“”
+ String shotName = timeZone.getDisplayName(false, TimeZone.SHORT); //获取名字,如“GMT+08:00”
+ int time = timeZone.getRawOffset(); //获取时差,返回值毫秒
+
+ /*Log.d("TAG", "getTimeZone: id==" + id);
+ Log.d("TAG", "getTimeZone: name==" + name);
+ Log.d("TAG", "getTimeZone: shotName==" + shotName);
+ Log.d("TAG", "getTimeZone: time==" + time);*/
+ return shotName;
+ }
+
+
+}
diff --git a/android/app/src/main/java/com/hissai/draw/utils/Configs.java b/android/app/src/main/java/com/hissai/draw/utils/Configs.java
new file mode 100644
index 0000000..fec21bf
--- /dev/null
+++ b/android/app/src/main/java/com/hissai/draw/utils/Configs.java
@@ -0,0 +1,14 @@
+package com.hissai.draw.utils;
+
+public class Configs {
+
+ public static String bossId = "24001";
+ public static String serverURL = "https://ecdnjyouapihw.cnrplay.com/phone300_Api/";
+ public static String ip = "";//本机ip地址
+ public static String deviceId = "";//设备ID
+ public static String appId = "1";
+ public static String versionName = "";//版本号
+ public static String deviceModel = "";//设备的硬件厂商和型号
+ public static String systemVersion = "";//操作系统版本号
+ public static String cpu = "";//
+}
diff --git a/android/app/src/main/java/com/hissai/draw/utils/MacInfo.java b/android/app/src/main/java/com/hissai/draw/utils/MacInfo.java
new file mode 100644
index 0000000..f4268cc
--- /dev/null
+++ b/android/app/src/main/java/com/hissai/draw/utils/MacInfo.java
@@ -0,0 +1,365 @@
+package com.hissai.draw.utils;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.content.Context;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.os.Build;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import com.hissai.draw.App;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.InputStreamReader;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.UUID;
+
+public class MacInfo {
+
+ public static String getMac(Activity activity) {
+ return md5s(getDeviceUDID(activity));
+ }
+
+ private static String md5s(String plainText) {
+
+ String str = "";
+ try {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ md.update(plainText.getBytes());
+ byte b[] = md.digest();
+
+ int i;
+
+ StringBuffer buf = new StringBuffer("");
+ for (int offset = 0; offset < b.length; offset++) {
+ i = b[offset];
+ if (i < 0)
+ i += 256;
+ if (i < 16)
+ buf.append("0");
+ buf.append(Integer.toHexString(i));
+ }
+ str = buf.toString();
+ str = str.toUpperCase();
+ } catch (NoSuchAlgorithmException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+
+ }
+ return str;
+ }
+
+ public static String android_id = "";
+ public static String imei = "";
+ public static String imei2 = "";
+ public static String imsi = "";
+ public static String imsi2 = "";
+ public static String sn = "";
+ public static String mac = "";
+ public static String device_id = "";
+ public static String oaId = "";
+
+ @SuppressLint("MissingPermission")
+ private static String getDeviceUDID(Activity activity) {
+
+ android_id = Configs.deviceId;
+
+ try {
+ TelephonyManager tm = (TelephonyManager) activity.getSystemService(Context.TELEPHONY_SERVICE);
+ if (tm != null) {
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
+ if (tm.hasCarrierPrivileges()) {
+ imei = tm.getImei(0);
+ imei2 = tm.getImei(1);
+ } else {
+ System.out.println("Can not get IMEI info.");
+ }
+ } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ imei = tm.getImei(0);
+ imei2 = tm.getImei(1);
+ } else {
+ imei = tm.getDeviceId();
+
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ try {
+ device_id = getUUID();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ if (device_id == null) {
+ device_id = "";
+ }
+ if (imei == null) {
+ imei = "";
+ }
+ try {
+ // sn
+ sn = Build.SERIAL;
+ if (sn == null)
+ sn = "";
+ } catch (Exception e) {
+ sn = "";
+ }
+
+ try {
+ // mac address
+ WifiManager wifi = (WifiManager) activity.getApplicationContext()
+ .getSystemService(Context.WIFI_SERVICE);
+ WifiInfo info = wifi.getConnectionInfo();
+ mac = info.getMacAddress();
+
+ if (mac == null || mac.equals("")
+ || mac.equals("00:00:00:00:00:00") || mac.equals("02:00:00:00:00:00")) {
+ mac = getLocalMacAddressFromIp();
+ }
+
+ if (mac == null || mac.equals("")
+ || mac.equals("00:00:00:00:00:00") || mac.equals("02:00:00:00:00:00")) {
+ mac = getNewMac();
+ }
+
+ if (mac == null || mac.equals("")
+ || mac.equals("00:00:00:00:00:00") || mac.equals("02:00:00:00:00:00")) {
+ mac = "";
+ }
+ } catch (Exception e) {
+ mac = "";
+ }
+
+ return android_id + ":" + imei + ":" + sn + ":" + mac;
+ }
+
+ public static String getOAID(Activity activity) {
+ try {
+ oaId = "";
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return oaId;
+ }
+
+
+ @SuppressLint("MissingPermission")
+ public static String getUUID() {
+
+ String serial = null;
+
+ String m_szDevIDShort = "35" +
+ Build.BOARD.length() % 10 + Build.BRAND.length() % 10 +
+
+ Build.CPU_ABI.length() % 10 + Build.DEVICE.length() % 10 +
+
+ Build.DISPLAY.length() % 10 + Build.HOST.length() % 10 +
+
+ Build.ID.length() % 10 + Build.MANUFACTURER.length() % 10 +
+
+ Build.MODEL.length() % 10 + Build.PRODUCT.length() % 10 +
+
+ Build.TAGS.length() % 10 + Build.TYPE.length() % 10 +
+
+ Build.USER.length() % 10; //13 位
+
+ try {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ serial = Build.getSerial();
+ } else {
+ serial = Build.SERIAL;
+ }
+ //API>=9 使用serial号
+ return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
+ } catch (Exception exception) {
+ //serial需要一个初始化
+ serial = "serial"; // 随便一个初始化
+ }
+ //使用硬件信息拼凑出来的15位号码
+ return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
+ }
+
+
+ /**
+ * 通过网络接口取
+ *
+ * @return
+ */
+ private static String getNewMac() {
+ try {
+ List all = Collections.list(NetworkInterface.getNetworkInterfaces());
+ for (NetworkInterface nif : all) {
+ if (!nif.getName().equalsIgnoreCase("wlan0")) continue;
+ byte[] macBytes = nif.getHardwareAddress();
+ if (macBytes == null) {
+ return null;
+ }
+ StringBuilder res1 = new StringBuilder();
+ for (byte b : macBytes) {
+ res1.append(String.format("%02X:", b));
+ }
+ if (res1.length() > 0) {
+ res1.deleteCharAt(res1.length() - 1);
+ }
+ return res1.toString();
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * * 根据IP地址获取MAC地址
+ * * @return
+ *
+ */
+ private static String getLocalMacAddressFromIp() {
+ String strMacAddr = null;
+ try {
+ //获得IpD地址
+ InetAddress ip = getLocalInetAddress();
+ byte[] b = NetworkInterface.getByInetAddress(ip).getHardwareAddress();
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 0; i < b.length; i++) {
+ if (i != 0) {
+ buffer.append(':');
+ }
+ String str = Integer.toHexString(b[i] & 0xFF);
+ buffer.append(str.length() == 1 ? 0 + str : str);
+ }
+ strMacAddr = buffer.toString().toUpperCase();
+ } catch (Exception e) {
+ }
+ return strMacAddr;
+ }
+
+ /**
+ * * 获取移动设备本地IP
+ * * @return
+ *
+ */
+ private static InetAddress getLocalInetAddress() {
+ InetAddress ip = null;
+ try {
+ //列举
+ Enumeration en_netInterface = NetworkInterface.getNetworkInterfaces();
+ while (en_netInterface.hasMoreElements()) {//是否还有元素
+ NetworkInterface ni = (NetworkInterface) en_netInterface.nextElement();//得到下一个元素
+ Enumeration en_ip = ni.getInetAddresses();//得到一个ip地址的列举
+ while (en_ip.hasMoreElements()) {
+ ip = en_ip.nextElement();
+ if (!ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1)
+ break;
+ else
+ ip = null;
+ }
+ if (ip != null) {
+ break;
+ }
+ }
+ } catch (SocketException e) {
+ e.printStackTrace();
+ }
+ return ip;
+ }
+
+ private static String callCmd(String cmd, String filter) {
+ String result = "";
+ String line = "";
+ try {
+ Process proc = Runtime.getRuntime().exec(cmd);
+ InputStreamReader is = new InputStreamReader(proc.getInputStream());
+ BufferedReader br = new BufferedReader(is);
+
+ // ִ������cmd��ֻȡ����к���filter����һ��
+ while ((line = br.readLine()) != null
+ && line.contains(filter) == false) {
+ // result += line;
+ Log.i("test", "line: " + line);
+ }
+
+ result = line;
+ Log.i("test", "result: " + result);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+
+ private static String getMacForHisense() {
+ String path = "/sys/class/net/eth0/address";
+ File file = new File(path);
+ if (file.exists()) {
+ BufferedReader buf;
+ try {
+ buf = new BufferedReader(new FileReader(file));
+ String mac = buf.readLine();
+ if (mac != null) {
+ return mac;
+ }
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ return "";
+ }
+
+ /**
+ * 获取设备拨号运营商
+ *
+ * @return ["中国电信CTCC":3]["中国联通CUCC:2]["中国移动CMCC":1]["other":0]["无sim卡":-1]
+ */
+ public static String getSubscriptionOperatorType() {
+ //int opeType = -1;
+ // No sim
+ if (!hasSim()) {
+ return null;
+ }
+
+ TelephonyManager tm = (TelephonyManager) App.getInstance().getSystemService(Context.TELEPHONY_SERVICE);
+ String operator = tm.getSimOperator();
+ String operator2 = tm.getSimOperatorName();
+ /* // 中国联通
+ if ("46001".equals(operator) || "46006".equals(operator) || "46009".equals(operator)) {
+ opeType = 2;
+ // 中国移动
+ } else if ("46000".equals(operator) || "46002".equals(operator) || "46004".equals(operator) || "46007".equals(operator)) {
+ opeType = 1;
+ // 中国电信
+ } else if ("46003".equals(operator) || "46005".equals(operator) || "46011".equals(operator)) {
+ opeType = 3;
+ } else {
+ opeType = 0;
+ }*/
+ return operator;
+ }
+
+ /**
+ * 判断是否有Sim卡
+ *
+ * @return
+ */
+ public static boolean hasSim() {
+ TelephonyManager tm = (TelephonyManager) App.getInstance().getSystemService(Context.TELEPHONY_SERVICE);
+ if (tm.getSimState() == TelephonyManager.SIM_STATE_READY) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/android/app/src/main/java/com/hissai/draw/utils/NetWork.java b/android/app/src/main/java/com/hissai/draw/utils/NetWork.java
new file mode 100644
index 0000000..2b0142e
--- /dev/null
+++ b/android/app/src/main/java/com/hissai/draw/utils/NetWork.java
@@ -0,0 +1,89 @@
+package com.hissai.draw.utils;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+public class NetWork {
+
+
+ //读取文件
+ public static Properties getNetConfigProperties(Context activity) {
+ Properties props = new Properties();
+ InputStream in;
+ try {
+ in = activity.getAssets().open("holybladeCloud.properties");
+ props.load(in);
+ } catch (IOException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
+ return props;
+ }
+
+ //获取配置
+ public static void getConfigs(Context context) {
+ Properties con = getNetConfigProperties(context);
+ if (Configs.serverURL.equals("")) {
+ Configs.serverURL = con.getProperty("ServerURL");
+ }
+ Configs.bossId = con.getProperty("BossId");
+ Configs.appId = con.getProperty("AppId");
+
+ // 获取版本号
+ PackageManager packageManager = context.getPackageManager();
+ // getPackageName()是你当前类的包名,0代表是获取版本信息
+ PackageInfo packInfo = null;
+ try {
+ packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
+ Configs.versionName = packInfo.versionName;
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ //同意协议 初始化 获取设备信息
+ public static void getInit(Context context) {
+ Configs.deviceId = AppUtil.getDeviceId(context);
+ String brand = android.os.Build.BRAND;
+ String model = android.os.Build.MODEL;
+ Configs.deviceModel = brand + ":" + model;
+ Configs.systemVersion = "android:" + android.os.Build.VERSION.RELEASE;
+ Configs.cpu = getCpuName();
+
+ }
+
+
+ //获取cpu名称
+ public static String getCpuName() {
+ String cpuName = "";
+ try {
+ FileReader fr = new FileReader("/proc/cpuinfo");
+ BufferedReader br = new BufferedReader(fr);
+ String text;
+ while ((text = br.readLine()) != null) {
+ String[] array = text.split(":\\s+", 2);
+ for (int i = 0; i < array.length; i++) {
+ //LogUtil.d("cpuName = "+ i + "="+array[i]);
+ cpuName = array[i];
+ }
+ if (array[0].contains("Hardware") || array[0].contains("hardware"))
+ break;
+ }
+ return cpuName;
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return "";
+ }
+
+}
diff --git a/android/app/src/main/java/com/hissai/draw/utils/ThreadUtil.java b/android/app/src/main/java/com/hissai/draw/utils/ThreadUtil.java
new file mode 100644
index 0000000..40d4b1f
--- /dev/null
+++ b/android/app/src/main/java/com/hissai/draw/utils/ThreadUtil.java
@@ -0,0 +1,61 @@
+package com.hissai.draw.utils;
+
+import android.os.Handler;
+import android.os.Looper;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * 线程工具,用于执行线程等
+ */
+public final class ThreadUtil {
+ public static final ThreadUtil INST = new ThreadUtil();
+
+ private ExecutorService executors;
+
+ private ThreadUtil() {
+ }
+
+ /**
+ * 在线程中执行
+ *
+ * @param runnable 要执行的runnable
+ */
+ public void excute(Runnable runnable) {
+ ExecutorService executorService = getExecutorService();
+ if (executorService != null) {
+ // 优先使用线程池,提高效率
+ executorService.execute(runnable);
+ } else {
+ // 线程池获取失败,则直接使用线程
+ new Thread(runnable).start();
+ }
+ }
+
+ /**
+ * 在主线程中执行
+ *
+ * @param runnable 要执行的runnable
+ */
+ public void excuteInMainThread(Runnable runnable) {
+ new Handler(Looper.getMainLooper()).post(runnable);
+ }
+
+ /**
+ * 获取缓存线程池
+ *
+ * @return 缓存线程池服务
+ */
+ private ExecutorService getExecutorService() {
+ if (executors == null) {
+ try {
+ executors = Executors.newCachedThreadPool();
+ } catch (Exception e) {
+
+ }
+ }
+
+ return executors;
+ }
+}
diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml
new file mode 100644
index 0000000..5076a6f
--- /dev/null
+++ b/android/app/src/main/res/drawable/launch_background.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..ba5bcf8
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..ba5bcf8
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..ba5bcf8
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..ba5bcf8
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/kpy.png b/android/app/src/main/res/mipmap-xxhdpi/kpy.png
new file mode 100644
index 0000000..dbe32f1
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/kpy.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..ba5bcf8
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..dd49500
--- /dev/null
+++ b/android/app/src/main/res/values/colors.xml
@@ -0,0 +1,4 @@
+
+
+ #C4C4C4
+
diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..cb1ef88
--- /dev/null
+++ b/android/app/src/main/res/values/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml
new file mode 100644
index 0000000..6ab9a2d
--- /dev/null
+++ b/android/app/src/profile/AndroidManifest.xml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/android/build.gradle b/android/build.gradle
new file mode 100644
index 0000000..5f2ad63
--- /dev/null
+++ b/android/build.gradle
@@ -0,0 +1,33 @@
+buildscript {
+ ext.kotlin_version = '1.6.10'
+ repositories {
+ google()
+ mavenCentral()
+ maven { url "https://jitpack.io" }
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:7.2.2'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ maven { url "https://jitpack.io" }
+ }
+}
+
+rootProject.buildDir = '../build'
+subprojects {
+ project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
+ project.evaluationDependsOn(':app')
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/android/gradle.properties b/android/gradle.properties
new file mode 100644
index 0000000..94adc3a
--- /dev/null
+++ b/android/gradle.properties
@@ -0,0 +1,3 @@
+org.gradle.jvmargs=-Xmx1536M
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..cb24abd
--- /dev/null
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
diff --git a/android/settings.gradle b/android/settings.gradle
new file mode 100644
index 0000000..44e62bc
--- /dev/null
+++ b/android/settings.gradle
@@ -0,0 +1,11 @@
+include ':app'
+
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
+
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
+
+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/assets/images/ad_free_bg.png b/assets/images/ad_free_bg.png
new file mode 100644
index 0000000..4ec4097
Binary files /dev/null and b/assets/images/ad_free_bg.png differ
diff --git a/assets/images/btn_cirilibao.webp b/assets/images/btn_cirilibao.webp
new file mode 100644
index 0000000..95386e2
Binary files /dev/null and b/assets/images/btn_cirilibao.webp differ
diff --git a/assets/images/create.png b/assets/images/create.png
new file mode 100644
index 0000000..d08d584
Binary files /dev/null and b/assets/images/create.png differ
diff --git a/assets/images/create_r.png b/assets/images/create_r.png
new file mode 100644
index 0000000..ca9a535
Binary files /dev/null and b/assets/images/create_r.png differ
diff --git a/assets/images/cuo.png b/assets/images/cuo.png
new file mode 100644
index 0000000..7906b2c
Binary files /dev/null and b/assets/images/cuo.png differ
diff --git a/assets/images/cuo2.png b/assets/images/cuo2.png
new file mode 100644
index 0000000..5c41cfb
Binary files /dev/null and b/assets/images/cuo2.png differ
diff --git a/assets/images/gallery.png b/assets/images/gallery.png
new file mode 100644
index 0000000..98cb35c
Binary files /dev/null and b/assets/images/gallery.png differ
diff --git a/assets/images/gallery_r.png b/assets/images/gallery_r.png
new file mode 100644
index 0000000..8507ee9
Binary files /dev/null and b/assets/images/gallery_r.png differ
diff --git a/assets/images/google_login.png b/assets/images/google_login.png
new file mode 100644
index 0000000..78b8539
Binary files /dev/null and b/assets/images/google_login.png differ
diff --git a/assets/images/google_logo.png b/assets/images/google_logo.png
new file mode 100644
index 0000000..5d13bb8
Binary files /dev/null and b/assets/images/google_logo.png differ
diff --git a/assets/images/head.png b/assets/images/head.png
new file mode 100644
index 0000000..5d3b5fc
Binary files /dev/null and b/assets/images/head.png differ
diff --git a/assets/images/ic_ad.png b/assets/images/ic_ad.png
new file mode 100644
index 0000000..13d75ea
Binary files /dev/null and b/assets/images/ic_ad.png differ
diff --git a/assets/images/ic_bg.png b/assets/images/ic_bg.png
new file mode 100644
index 0000000..2dfdda1
Binary files /dev/null and b/assets/images/ic_bg.png differ
diff --git a/assets/images/ic_check.png b/assets/images/ic_check.png
new file mode 100644
index 0000000..0c32e33
Binary files /dev/null and b/assets/images/ic_check.png differ
diff --git a/assets/images/ic_close.png b/assets/images/ic_close.png
new file mode 100644
index 0000000..a829905
Binary files /dev/null and b/assets/images/ic_close.png differ
diff --git a/assets/images/ic_collect.png b/assets/images/ic_collect.png
new file mode 100644
index 0000000..bde1221
Binary files /dev/null and b/assets/images/ic_collect.png differ
diff --git a/assets/images/ic_collect_s.png b/assets/images/ic_collect_s.png
new file mode 100644
index 0000000..39b156c
Binary files /dev/null and b/assets/images/ic_collect_s.png differ
diff --git a/assets/images/ic_count.png b/assets/images/ic_count.png
new file mode 100644
index 0000000..8111cce
Binary files /dev/null and b/assets/images/ic_count.png differ
diff --git a/assets/images/ic_download.png b/assets/images/ic_download.png
new file mode 100644
index 0000000..be8fcb5
Binary files /dev/null and b/assets/images/ic_download.png differ
diff --git a/assets/images/ic_follow.png b/assets/images/ic_follow.png
new file mode 100644
index 0000000..629171f
Binary files /dev/null and b/assets/images/ic_follow.png differ
diff --git a/assets/images/ic_jump.png b/assets/images/ic_jump.png
new file mode 100644
index 0000000..cdbb959
Binary files /dev/null and b/assets/images/ic_jump.png differ
diff --git a/assets/images/ic_like.png b/assets/images/ic_like.png
new file mode 100644
index 0000000..ac00064
Binary files /dev/null and b/assets/images/ic_like.png differ
diff --git a/assets/images/ic_like_in.png b/assets/images/ic_like_in.png
new file mode 100644
index 0000000..1e575d1
Binary files /dev/null and b/assets/images/ic_like_in.png differ
diff --git a/assets/images/ic_loading.webp b/assets/images/ic_loading.webp
new file mode 100644
index 0000000..7a822eb
Binary files /dev/null and b/assets/images/ic_loading.webp differ
diff --git a/assets/images/ic_mall.png b/assets/images/ic_mall.png
new file mode 100644
index 0000000..b40243c
Binary files /dev/null and b/assets/images/ic_mall.png differ
diff --git a/assets/images/ic_message.png b/assets/images/ic_message.png
new file mode 100644
index 0000000..33c78f4
Binary files /dev/null and b/assets/images/ic_message.png differ
diff --git a/assets/images/ic_message_collect.png b/assets/images/ic_message_collect.png
new file mode 100644
index 0000000..d4a1a22
Binary files /dev/null and b/assets/images/ic_message_collect.png differ
diff --git a/assets/images/ic_message_notice.png b/assets/images/ic_message_notice.png
new file mode 100644
index 0000000..c2b7bca
Binary files /dev/null and b/assets/images/ic_message_notice.png differ
diff --git a/assets/images/ic_no_collect.png b/assets/images/ic_no_collect.png
new file mode 100644
index 0000000..18acdbb
Binary files /dev/null and b/assets/images/ic_no_collect.png differ
diff --git a/assets/images/ic_no_content.png b/assets/images/ic_no_content.png
new file mode 100644
index 0000000..b88d84b
Binary files /dev/null and b/assets/images/ic_no_content.png differ
diff --git a/assets/images/ic_open.png b/assets/images/ic_open.png
new file mode 100644
index 0000000..6188836
Binary files /dev/null and b/assets/images/ic_open.png differ
diff --git a/assets/images/ic_portfolio.webp b/assets/images/ic_portfolio.webp
new file mode 100644
index 0000000..7c9f231
Binary files /dev/null and b/assets/images/ic_portfolio.webp differ
diff --git a/assets/images/ic_random.png b/assets/images/ic_random.png
new file mode 100644
index 0000000..4b09e4f
Binary files /dev/null and b/assets/images/ic_random.png differ
diff --git a/assets/images/ic_return.png b/assets/images/ic_return.png
new file mode 100644
index 0000000..5fd089d
Binary files /dev/null and b/assets/images/ic_return.png differ
diff --git a/assets/images/ic_same_style.png b/assets/images/ic_same_style.png
new file mode 100644
index 0000000..ca2248b
Binary files /dev/null and b/assets/images/ic_same_style.png differ
diff --git a/assets/images/ic_search.png b/assets/images/ic_search.png
new file mode 100644
index 0000000..b3eafc4
Binary files /dev/null and b/assets/images/ic_search.png differ
diff --git a/assets/images/ic_setting.png b/assets/images/ic_setting.png
new file mode 100644
index 0000000..dee8f49
Binary files /dev/null and b/assets/images/ic_setting.png differ
diff --git a/assets/images/ic_share.png b/assets/images/ic_share.png
new file mode 100644
index 0000000..7c5277f
Binary files /dev/null and b/assets/images/ic_share.png differ
diff --git a/assets/images/ic_size_select.png b/assets/images/ic_size_select.png
new file mode 100644
index 0000000..1aa373c
Binary files /dev/null and b/assets/images/ic_size_select.png differ
diff --git a/assets/images/ic_sort.png b/assets/images/ic_sort.png
new file mode 100644
index 0000000..85e0d13
Binary files /dev/null and b/assets/images/ic_sort.png differ
diff --git a/assets/images/ic_style_s.png b/assets/images/ic_style_s.png
new file mode 100644
index 0000000..c520f51
Binary files /dev/null and b/assets/images/ic_style_s.png differ
diff --git a/assets/images/ic_tip.png b/assets/images/ic_tip.png
new file mode 100644
index 0000000..0478f90
Binary files /dev/null and b/assets/images/ic_tip.png differ
diff --git a/assets/images/ic_title.png b/assets/images/ic_title.png
new file mode 100644
index 0000000..7a056e5
Binary files /dev/null and b/assets/images/ic_title.png differ
diff --git a/assets/images/ic_topping.png b/assets/images/ic_topping.png
new file mode 100644
index 0000000..4c2fb0c
Binary files /dev/null and b/assets/images/ic_topping.png differ
diff --git a/assets/images/ic_upload.png b/assets/images/ic_upload.png
new file mode 100644
index 0000000..6253505
Binary files /dev/null and b/assets/images/ic_upload.png differ
diff --git a/assets/images/ic_works.png b/assets/images/ic_works.png
new file mode 100644
index 0000000..91cc56f
Binary files /dev/null and b/assets/images/ic_works.png differ
diff --git a/assets/images/ic_works_f.png b/assets/images/ic_works_f.png
new file mode 100644
index 0000000..e89618f
Binary files /dev/null and b/assets/images/ic_works_f.png differ
diff --git a/assets/images/icon.png b/assets/images/icon.png
new file mode 100644
index 0000000..6350e4a
Binary files /dev/null and b/assets/images/icon.png differ
diff --git a/assets/images/img_11.png b/assets/images/img_11.png
new file mode 100644
index 0000000..d09616b
Binary files /dev/null and b/assets/images/img_11.png differ
diff --git a/assets/images/img_11_no.png b/assets/images/img_11_no.png
new file mode 100644
index 0000000..d0c02e4
Binary files /dev/null and b/assets/images/img_11_no.png differ
diff --git a/assets/images/img_169.png b/assets/images/img_169.png
new file mode 100644
index 0000000..04303a6
Binary files /dev/null and b/assets/images/img_169.png differ
diff --git a/assets/images/img_169_no.png b/assets/images/img_169_no.png
new file mode 100644
index 0000000..ebb9803
Binary files /dev/null and b/assets/images/img_169_no.png differ
diff --git a/assets/images/img_34.png b/assets/images/img_34.png
new file mode 100644
index 0000000..6a8d524
Binary files /dev/null and b/assets/images/img_34.png differ
diff --git a/assets/images/img_34_no.png b/assets/images/img_34_no.png
new file mode 100644
index 0000000..6205fd2
Binary files /dev/null and b/assets/images/img_34_no.png differ
diff --git a/assets/images/img_43.png b/assets/images/img_43.png
new file mode 100644
index 0000000..44ec09c
Binary files /dev/null and b/assets/images/img_43.png differ
diff --git a/assets/images/img_43_no.png b/assets/images/img_43_no.png
new file mode 100644
index 0000000..fbd5aa8
Binary files /dev/null and b/assets/images/img_43_no.png differ
diff --git a/assets/images/img_916.png b/assets/images/img_916.png
new file mode 100644
index 0000000..d45cbf4
Binary files /dev/null and b/assets/images/img_916.png differ
diff --git a/assets/images/img_916_no.png b/assets/images/img_916_no.png
new file mode 100644
index 0000000..0d626e9
Binary files /dev/null and b/assets/images/img_916_no.png differ
diff --git a/assets/images/img_delete.png b/assets/images/img_delete.png
new file mode 100644
index 0000000..9c51523
Binary files /dev/null and b/assets/images/img_delete.png differ
diff --git a/assets/images/jia.png b/assets/images/jia.png
new file mode 100644
index 0000000..0f00559
Binary files /dev/null and b/assets/images/jia.png differ
diff --git a/assets/images/jia_w.png b/assets/images/jia_w.png
new file mode 100644
index 0000000..dd4c14c
Binary files /dev/null and b/assets/images/jia_w.png differ
diff --git a/assets/images/kpy.png b/assets/images/kpy.png
new file mode 100644
index 0000000..dbe32f1
Binary files /dev/null and b/assets/images/kpy.png differ
diff --git a/assets/images/kuang.png b/assets/images/kuang.png
new file mode 100644
index 0000000..8279ad4
Binary files /dev/null and b/assets/images/kuang.png differ
diff --git a/assets/images/login_bg.png b/assets/images/login_bg.png
new file mode 100644
index 0000000..29fc05b
Binary files /dev/null and b/assets/images/login_bg.png differ
diff --git a/assets/images/login_logo.png b/assets/images/login_logo.png
new file mode 100644
index 0000000..67a37d9
Binary files /dev/null and b/assets/images/login_logo.png differ
diff --git a/assets/images/login_phone.png b/assets/images/login_phone.png
new file mode 100644
index 0000000..a20857b
Binary files /dev/null and b/assets/images/login_phone.png differ
diff --git a/assets/images/me.png b/assets/images/me.png
new file mode 100644
index 0000000..0d76c73
Binary files /dev/null and b/assets/images/me.png differ
diff --git a/assets/images/me_r.png b/assets/images/me_r.png
new file mode 100644
index 0000000..c0b8a0d
Binary files /dev/null and b/assets/images/me_r.png differ
diff --git a/assets/images/share_logo.png b/assets/images/share_logo.png
new file mode 100644
index 0000000..ff45355
Binary files /dev/null and b/assets/images/share_logo.png differ
diff --git a/assets/images/shop_bg.png b/assets/images/shop_bg.png
new file mode 100644
index 0000000..969d99d
Binary files /dev/null and b/assets/images/shop_bg.png differ
diff --git a/assets/images/shop_logo.png b/assets/images/shop_logo.png
new file mode 100644
index 0000000..45cd3ea
Binary files /dev/null and b/assets/images/shop_logo.png differ
diff --git a/assets/images/shop_star.png b/assets/images/shop_star.png
new file mode 100644
index 0000000..7acb939
Binary files /dev/null and b/assets/images/shop_star.png differ
diff --git a/assets/images/upbg.webp b/assets/images/upbg.webp
new file mode 100644
index 0000000..6cdc28a
Binary files /dev/null and b/assets/images/upbg.webp differ
diff --git a/assets/images/view_ad.png b/assets/images/view_ad.png
new file mode 100644
index 0000000..409c15f
Binary files /dev/null and b/assets/images/view_ad.png differ
diff --git a/assets/images/zhankai.png b/assets/images/zhankai.png
new file mode 100644
index 0000000..eaf18de
Binary files /dev/null and b/assets/images/zhankai.png differ
diff --git a/ios/.symlinks/plugins/device_info b/ios/.symlinks/plugins/device_info
new file mode 100644
index 0000000..bae2e42
--- /dev/null
+++ b/ios/.symlinks/plugins/device_info
@@ -0,0 +1 @@
+/Users/wuyangguan/Desktop/Flutter-Development/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.3/
\ No newline at end of file
diff --git a/ios/.symlinks/plugins/flutter_native_image b/ios/.symlinks/plugins/flutter_native_image
new file mode 100644
index 0000000..1792d31
--- /dev/null
+++ b/ios/.symlinks/plugins/flutter_native_image
@@ -0,0 +1 @@
+/Users/wuyangguan/Desktop/Flutter-Development/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_native_image-0.0.6+1/
\ No newline at end of file
diff --git a/ios/.symlinks/plugins/fluttertoast b/ios/.symlinks/plugins/fluttertoast
new file mode 100644
index 0000000..60dcb4e
--- /dev/null
+++ b/ios/.symlinks/plugins/fluttertoast
@@ -0,0 +1 @@
+/Users/wuyangguan/Desktop/Flutter-Development/flutter/.pub-cache/hosted/pub.dartlang.org/fluttertoast-8.2.1/
\ No newline at end of file
diff --git a/ios/.symlinks/plugins/image_cropper b/ios/.symlinks/plugins/image_cropper
new file mode 100644
index 0000000..99eb7d9
--- /dev/null
+++ b/ios/.symlinks/plugins/image_cropper
@@ -0,0 +1 @@
+/Users/wuyangguan/Desktop/Flutter-Development/flutter/.pub-cache/hosted/pub.dartlang.org/image_cropper-3.0.3/
\ No newline at end of file
diff --git a/ios/.symlinks/plugins/image_gallery_saver b/ios/.symlinks/plugins/image_gallery_saver
new file mode 100644
index 0000000..9805c0e
--- /dev/null
+++ b/ios/.symlinks/plugins/image_gallery_saver
@@ -0,0 +1 @@
+/Users/wuyangguan/Desktop/Flutter-Development/flutter/.pub-cache/hosted/pub.dartlang.org/image_gallery_saver-1.7.1/
\ No newline at end of file
diff --git a/ios/.symlinks/plugins/image_picker_ios b/ios/.symlinks/plugins/image_picker_ios
new file mode 100644
index 0000000..a74813e
--- /dev/null
+++ b/ios/.symlinks/plugins/image_picker_ios
@@ -0,0 +1 @@
+/Users/wuyangguan/Desktop/Flutter-Development/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_ios-0.8.7+3/
\ No newline at end of file
diff --git a/ios/.symlinks/plugins/path_provider_foundation b/ios/.symlinks/plugins/path_provider_foundation
new file mode 100644
index 0000000..6cce734
--- /dev/null
+++ b/ios/.symlinks/plugins/path_provider_foundation
@@ -0,0 +1 @@
+/Users/wuyangguan/Desktop/Flutter-Development/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_foundation-2.2.2/
\ No newline at end of file
diff --git a/ios/.symlinks/plugins/permission_handler_apple b/ios/.symlinks/plugins/permission_handler_apple
new file mode 100644
index 0000000..d0d8808
--- /dev/null
+++ b/ios/.symlinks/plugins/permission_handler_apple
@@ -0,0 +1 @@
+/Users/wuyangguan/Desktop/Flutter-Development/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler_apple-9.0.8/
\ No newline at end of file
diff --git a/ios/.symlinks/plugins/shared_preferences_foundation b/ios/.symlinks/plugins/shared_preferences_foundation
new file mode 100644
index 0000000..ecb10a8
--- /dev/null
+++ b/ios/.symlinks/plugins/shared_preferences_foundation
@@ -0,0 +1 @@
+/Users/wuyangguan/Desktop/Flutter-Development/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_foundation-2.2.1/
\ No newline at end of file
diff --git a/ios/.symlinks/plugins/sign_in_with_apple b/ios/.symlinks/plugins/sign_in_with_apple
new file mode 100644
index 0000000..6251f93
--- /dev/null
+++ b/ios/.symlinks/plugins/sign_in_with_apple
@@ -0,0 +1 @@
+/Users/wuyangguan/Desktop/Flutter-Development/flutter/.pub-cache/hosted/pub.dartlang.org/sign_in_with_apple-4.3.0/
\ No newline at end of file
diff --git a/ios/.symlinks/plugins/sqflite b/ios/.symlinks/plugins/sqflite
new file mode 100644
index 0000000..9f718e9
--- /dev/null
+++ b/ios/.symlinks/plugins/sqflite
@@ -0,0 +1 @@
+/Users/wuyangguan/Desktop/Flutter-Development/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-2.2.7/
\ No newline at end of file
diff --git a/ios/.symlinks/plugins/url_launcher_ios b/ios/.symlinks/plugins/url_launcher_ios
new file mode 100644
index 0000000..2258bdb
--- /dev/null
+++ b/ios/.symlinks/plugins/url_launcher_ios
@@ -0,0 +1 @@
+/Users/wuyangguan/Desktop/Flutter-Development/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_ios-6.1.4/
\ No newline at end of file
diff --git a/ios/.symlinks/plugins/webview_flutter_wkwebview b/ios/.symlinks/plugins/webview_flutter_wkwebview
new file mode 100644
index 0000000..8b4278f
--- /dev/null
+++ b/ios/.symlinks/plugins/webview_flutter_wkwebview
@@ -0,0 +1 @@
+/Users/wuyangguan/Desktop/Flutter-Development/flutter/.pub-cache/hosted/pub.dartlang.org/webview_flutter_wkwebview-2.9.5/
\ No newline at end of file
diff --git a/ios/Flutter/Generated.xcconfig b/ios/Flutter/Generated.xcconfig
new file mode 100644
index 0000000..5785570
--- /dev/null
+++ b/ios/Flutter/Generated.xcconfig
@@ -0,0 +1,14 @@
+// This is a generated file; do not edit or check into version control.
+FLUTTER_ROOT=D:\flutter_windows_3.3.1-stable\flutter
+FLUTTER_APPLICATION_PATH=D:\git_code\ai_drawing
+COCOAPODS_PARALLEL_CODE_SIGN=true
+FLUTTER_TARGET=lib\main.dart
+FLUTTER_BUILD_DIR=build
+FLUTTER_BUILD_NAME=1.1.0
+FLUTTER_BUILD_NUMBER=1
+EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386
+EXCLUDED_ARCHS[sdk=iphoneos*]=armv7
+DART_OBFUSCATION=false
+TRACK_WIDGET_CREATION=true
+TREE_SHAKE_ICONS=false
+PACKAGE_CONFIG=.dart_tool/package_config.json
diff --git a/ios/Flutter/flutter_export_environment.sh b/ios/Flutter/flutter_export_environment.sh
new file mode 100644
index 0000000..4970922
--- /dev/null
+++ b/ios/Flutter/flutter_export_environment.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+# This is a generated file; do not edit or check into version control.
+export "FLUTTER_ROOT=D:\flutter_windows_3.3.1-stable\flutter"
+export "FLUTTER_APPLICATION_PATH=D:\git_code\ai_drawing"
+export "COCOAPODS_PARALLEL_CODE_SIGN=true"
+export "FLUTTER_TARGET=lib\main.dart"
+export "FLUTTER_BUILD_DIR=build"
+export "FLUTTER_BUILD_NAME=1.1.0"
+export "FLUTTER_BUILD_NUMBER=1"
+export "DART_OBFUSCATION=false"
+export "TRACK_WIDGET_CREATION=true"
+export "TREE_SHAKE_ICONS=false"
+export "PACKAGE_CONFIG=.dart_tool/package_config.json"
diff --git a/ios/Podfile b/ios/Podfile
new file mode 100644
index 0000000..d207307
--- /dev/null
+++ b/ios/Podfile
@@ -0,0 +1,38 @@
+# Uncomment this line to define a global platform for your project
+# platform :ios, '11.0'
+
+# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
+ENV['COCOAPODS_DISABLE_STATS'] = 'true'
+
+project 'Runner', {
+ 'Debug' => :debug,
+ 'Profile' => :release,
+ 'Release' => :release,
+}
+
+def flutter_root
+ generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
+ unless File.exist?(generated_xcode_build_settings_path)
+ raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
+ end
+
+ File.foreach(generated_xcode_build_settings_path) do |line|
+ matches = line.match(/FLUTTER_ROOT\=(.*)/)
+ return matches[1].strip if matches
+ end
+ raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
+end
+
+require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
+
+flutter_ios_podfile_setup
+
+target 'Runner' do
+ flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
+end
+
+post_install do |installer|
+ installer.pods_project.targets.each do |target|
+ flutter_additional_ios_build_settings(target)
+ end
+end
diff --git a/ios/Runner/GeneratedPluginRegistrant.h b/ios/Runner/GeneratedPluginRegistrant.h
new file mode 100644
index 0000000..7a89092
--- /dev/null
+++ b/ios/Runner/GeneratedPluginRegistrant.h
@@ -0,0 +1,19 @@
+//
+// Generated file. Do not edit.
+//
+
+// clang-format off
+
+#ifndef GeneratedPluginRegistrant_h
+#define GeneratedPluginRegistrant_h
+
+#import
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface GeneratedPluginRegistrant : NSObject
++ (void)registerWithRegistry:(NSObject*)registry;
+@end
+
+NS_ASSUME_NONNULL_END
+#endif /* GeneratedPluginRegistrant_h */
diff --git a/ios/Runner/GeneratedPluginRegistrant.m b/ios/Runner/GeneratedPluginRegistrant.m
new file mode 100644
index 0000000..1b6d6d4
--- /dev/null
+++ b/ios/Runner/GeneratedPluginRegistrant.m
@@ -0,0 +1,126 @@
+//
+// Generated file. Do not edit.
+//
+
+// clang-format off
+
+#import "GeneratedPluginRegistrant.h"
+
+#if __has_include()
+#import
+#else
+@import connectivity_plus;
+#endif
+
+#if __has_include()
+#import
+#else
+@import device_info;
+#endif
+
+#if __has_include()
+#import
+#else
+@import flutter_native_image;
+#endif
+
+#if __has_include()
+#import
+#else
+@import fluttertoast;
+#endif
+
+#if __has_include()
+#import
+#else
+@import image_cropper;
+#endif
+
+#if __has_include()
+#import
+#else
+@import image_gallery_saver;
+#endif
+
+#if __has_include()
+#import
+#else
+@import image_picker_ios;
+#endif
+
+#if __has_include()
+#import
+#else
+@import ironsource_mediation;
+#endif
+
+#if __has_include()
+#import
+#else
+@import path_provider_foundation;
+#endif
+
+#if __has_include()
+#import
+#else
+@import permission_handler_apple;
+#endif
+
+#if __has_include()
+#import
+#else
+@import sensors_analytics_flutter_plugin;
+#endif
+
+#if __has_include()
+#import
+#else
+@import share_plus;
+#endif
+
+#if __has_include()
+#import
+#else
+@import shared_preferences_foundation;
+#endif
+
+#if __has_include()
+#import
+#else
+@import sqflite;
+#endif
+
+#if __has_include()
+#import
+#else
+@import url_launcher_ios;
+#endif
+
+#if __has_include()
+#import
+#else
+@import webview_flutter_wkwebview;
+#endif
+
+@implementation GeneratedPluginRegistrant
+
++ (void)registerWithRegistry:(NSObject*)registry {
+ [ConnectivityPlusPlugin registerWithRegistrar:[registry registrarForPlugin:@"ConnectivityPlusPlugin"]];
+ [FLTDeviceInfoPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTDeviceInfoPlugin"]];
+ [FlutterNativeImagePlugin registerWithRegistrar:[registry registrarForPlugin:@"FlutterNativeImagePlugin"]];
+ [FluttertoastPlugin registerWithRegistrar:[registry registrarForPlugin:@"FluttertoastPlugin"]];
+ [FLTImageCropperPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTImageCropperPlugin"]];
+ [ImageGallerySaverPlugin registerWithRegistrar:[registry registrarForPlugin:@"ImageGallerySaverPlugin"]];
+ [FLTImagePickerPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTImagePickerPlugin"]];
+ [IronSourceMediationPlugin registerWithRegistrar:[registry registrarForPlugin:@"IronSourceMediationPlugin"]];
+ [PathProviderPlugin registerWithRegistrar:[registry registrarForPlugin:@"PathProviderPlugin"]];
+ [PermissionHandlerPlugin registerWithRegistrar:[registry registrarForPlugin:@"PermissionHandlerPlugin"]];
+ [SensorsAnalyticsFlutterPlugin registerWithRegistrar:[registry registrarForPlugin:@"SensorsAnalyticsFlutterPlugin"]];
+ [FLTSharePlusPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTSharePlusPlugin"]];
+ [SharedPreferencesPlugin registerWithRegistrar:[registry registrarForPlugin:@"SharedPreferencesPlugin"]];
+ [SqflitePlugin registerWithRegistrar:[registry registrarForPlugin:@"SqflitePlugin"]];
+ [FLTURLLauncherPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTURLLauncherPlugin"]];
+ [FLTWebViewFlutterPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTWebViewFlutterPlugin"]];
+}
+
+@end
diff --git a/lib/bean/ad_free_bean.dart b/lib/bean/ad_free_bean.dart
new file mode 100644
index 0000000..cf4db83
--- /dev/null
+++ b/lib/bean/ad_free_bean.dart
@@ -0,0 +1,16 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'ad_free_bean.g.dart';
+
+@JsonSerializable()
+class AdFreeBean {
+ String? BackgroundImage;
+ String? BtnImage;
+ String? BtnAction;
+
+ AdFreeBean(this.BackgroundImage, this.BtnImage, this.BtnAction);
+
+ factory AdFreeBean.fromJson(Map json) => _$AdFreeBeanFromJson(json);
+
+ Map toJson() => _$AdFreeBeanToJson(this);
+}
diff --git a/lib/bean/ad_free_bean.g.dart b/lib/bean/ad_free_bean.g.dart
new file mode 100644
index 0000000..958e19c
--- /dev/null
+++ b/lib/bean/ad_free_bean.g.dart
@@ -0,0 +1,22 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'ad_free_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+AdFreeBean _$AdFreeBeanFromJson(Map json) {
+ return AdFreeBean(
+ json['BackgroundImage'] as String?,
+ json['BtnImage'] as String?,
+ json['BtnAction'] as String?,
+ );
+}
+
+Map _$AdFreeBeanToJson(AdFreeBean instance) =>
+ {
+ 'BackgroundImage': instance.BackgroundImage,
+ 'BtnImage': instance.BtnImage,
+ 'BtnAction': instance.BtnAction,
+ };
diff --git a/lib/bean/app_config_bean.dart b/lib/bean/app_config_bean.dart
new file mode 100644
index 0000000..4b331eb
--- /dev/null
+++ b/lib/bean/app_config_bean.dart
@@ -0,0 +1,26 @@
+import 'package:json_annotation/json_annotation.dart';
+
+import 'ad_free_bean.dart';
+
+part 'app_config_bean.g.dart';
+
+@JsonSerializable()
+class AppConfigBean {
+ int? SharingRewards;
+ AdFreeBean? AdFree;
+ String? MallInletImage;
+ int? InvitationCodeNumber;
+ int? InviteeNumber;
+ bool? UserPageAd;
+ bool? UserPageShoppingMall;
+ bool? UserPageOfficialAccount;
+ bool? IsCheckRemark;
+ bool? IsShowUserPageEquityBtn;
+
+ AppConfigBean(this.SharingRewards, this.AdFree, this.MallInletImage, this.InvitationCodeNumber, this.InviteeNumber, this.UserPageAd,
+ this.UserPageShoppingMall, this.UserPageOfficialAccount, this.IsCheckRemark, this.IsShowUserPageEquityBtn);
+
+ factory AppConfigBean.fromJson(Map json) => _$AppConfigBeanFromJson(json);
+
+ Map toJson() => _$AppConfigBeanToJson(this);
+}
diff --git a/lib/bean/app_config_bean.g.dart b/lib/bean/app_config_bean.g.dart
new file mode 100644
index 0000000..00a8024
--- /dev/null
+++ b/lib/bean/app_config_bean.g.dart
@@ -0,0 +1,38 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'app_config_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+AppConfigBean _$AppConfigBeanFromJson(Map json) {
+ return AppConfigBean(
+ json['SharingRewards'] as int?,
+ json['AdFree'] == null
+ ? null
+ : AdFreeBean.fromJson(json['AdFree'] as Map),
+ json['MallInletImage'] as String?,
+ json['InvitationCodeNumber'] as int?,
+ json['InviteeNumber'] as int?,
+ json['UserPageAd'] as bool?,
+ json['UserPageShoppingMall'] as bool?,
+ json['UserPageOfficialAccount'] as bool?,
+ json['IsCheckRemark'] as bool?,
+ json['IsShowUserPageEquityBtn'] as bool?,
+ );
+}
+
+Map _$AppConfigBeanToJson(AppConfigBean instance) =>
+ {
+ 'SharingRewards': instance.SharingRewards,
+ 'AdFree': instance.AdFree,
+ 'MallInletImage': instance.MallInletImage,
+ 'InvitationCodeNumber': instance.InvitationCodeNumber,
+ 'InviteeNumber': instance.InviteeNumber,
+ 'UserPageAd': instance.UserPageAd,
+ 'UserPageShoppingMall': instance.UserPageShoppingMall,
+ 'UserPageOfficialAccount': instance.UserPageOfficialAccount,
+ 'IsCheckRemark': instance.IsCheckRemark,
+ 'IsShowUserPageEquityBtn': instance.IsShowUserPageEquityBtn,
+ };
diff --git a/lib/bean/art_detail_bean.dart b/lib/bean/art_detail_bean.dart
new file mode 100644
index 0000000..f13c50a
--- /dev/null
+++ b/lib/bean/art_detail_bean.dart
@@ -0,0 +1,30 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'art_detail_bean.g.dart';
+
+@JsonSerializable()
+class ArtDetailBean {
+ int? Id;
+ int? UserId;
+ String? TaskId;
+ int? TaskLevel;
+ String? TaskResult;
+ String? Title;
+ int? TemplateId;
+ String? CreateTime;
+ int? Status;
+ String? Prompt;
+ String? UserNickName;
+ String? UserIocn;
+ bool? IsUserDrawGallery;
+ bool? IsMyCollect;
+ int? SizeTemplateId;
+ int? DrawState;
+
+ ArtDetailBean(this.Id, this.UserId, this.TaskId, this.TaskLevel, this.TaskResult, this.Title, this.TemplateId, this.CreateTime, this.Status,
+ this.Prompt, this.UserNickName, this.UserIocn, this.IsUserDrawGallery, this.IsMyCollect, this.SizeTemplateId, this.DrawState);
+
+ factory ArtDetailBean.fromJson(Map json) => _$ArtDetailBeanFromJson(json);
+
+ Map toJson() => _$ArtDetailBeanToJson(this);
+}
diff --git a/lib/bean/art_detail_bean.g.dart b/lib/bean/art_detail_bean.g.dart
new file mode 100644
index 0000000..1c94e1f
--- /dev/null
+++ b/lib/bean/art_detail_bean.g.dart
@@ -0,0 +1,48 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'art_detail_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+ArtDetailBean _$ArtDetailBeanFromJson(Map json) {
+ return ArtDetailBean(
+ json['Id'] as int?,
+ json['UserId'] as int?,
+ json['TaskId'] as String?,
+ json['TaskLevel'] as int?,
+ json['TaskResult'] as String?,
+ json['Title'] as String?,
+ json['TemplateId'] as int?,
+ json['CreateTime'] as String?,
+ json['Status'] as int?,
+ json['Prompt'] as String?,
+ json['UserNickName'] as String?,
+ json['UserIocn'] as String?,
+ json['IsUserDrawGallery'] as bool?,
+ json['IsMyCollect'] as bool?,
+ json['SizeTemplateId'] as int?,
+ json['DrawState'] as int?,
+ );
+}
+
+Map _$ArtDetailBeanToJson(ArtDetailBean instance) =>
+ {
+ 'Id': instance.Id,
+ 'UserId': instance.UserId,
+ 'TaskId': instance.TaskId,
+ 'TaskLevel': instance.TaskLevel,
+ 'TaskResult': instance.TaskResult,
+ 'Title': instance.Title,
+ 'TemplateId': instance.TemplateId,
+ 'CreateTime': instance.CreateTime,
+ 'Status': instance.Status,
+ 'Prompt': instance.Prompt,
+ 'UserNickName': instance.UserNickName,
+ 'UserIocn': instance.UserIocn,
+ 'IsUserDrawGallery': instance.IsUserDrawGallery,
+ 'IsMyCollect': instance.IsMyCollect,
+ 'SizeTemplateId': instance.SizeTemplateId,
+ 'DrawState': instance.DrawState,
+ };
diff --git a/lib/bean/create_order_bean.dart b/lib/bean/create_order_bean.dart
new file mode 100644
index 0000000..feb2ccd
--- /dev/null
+++ b/lib/bean/create_order_bean.dart
@@ -0,0 +1,15 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'create_order_bean.g.dart';
+
+@JsonSerializable()
+class CreateOrderBean {
+ String? OrderCode;
+ String? OldToken;
+
+ CreateOrderBean(this.OrderCode, this.OldToken);
+
+ factory CreateOrderBean.fromJson(Map json) => _$CreateOrderBeanFromJson(json);
+
+ Map toJson() => _$CreateOrderBeanToJson(this);
+}
diff --git a/lib/bean/create_order_bean.g.dart b/lib/bean/create_order_bean.g.dart
new file mode 100644
index 0000000..df5cab1
--- /dev/null
+++ b/lib/bean/create_order_bean.g.dart
@@ -0,0 +1,20 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'create_order_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+CreateOrderBean _$CreateOrderBeanFromJson(Map json) {
+ return CreateOrderBean(
+ json['OrderCode'] as String?,
+ json['OldToken'] as String?,
+ );
+}
+
+Map _$CreateOrderBeanToJson(CreateOrderBean instance) =>
+ {
+ 'OrderCode': instance.OrderCode,
+ 'OldToken': instance.OldToken,
+ };
diff --git a/lib/bean/draw_template_bean.dart b/lib/bean/draw_template_bean.dart
new file mode 100644
index 0000000..d9382f2
--- /dev/null
+++ b/lib/bean/draw_template_bean.dart
@@ -0,0 +1,18 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'draw_template_bean.g.dart';
+
+@JsonSerializable()
+class DrawTemplateBean {
+ int? Id;
+ String? Title;
+ String? ImageSmall;
+ int? Type;
+ double? Charging;
+
+ DrawTemplateBean(this.Id, this.Title, this.ImageSmall, this.Type, this.Charging);
+
+ factory DrawTemplateBean.fromJson(Map json) => _$DrawTemplateBeanFromJson(json);
+
+ Map toJson() => _$DrawTemplateBeanToJson(this);
+}
diff --git a/lib/bean/draw_template_bean.g.dart b/lib/bean/draw_template_bean.g.dart
new file mode 100644
index 0000000..b48431e
--- /dev/null
+++ b/lib/bean/draw_template_bean.g.dart
@@ -0,0 +1,26 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'draw_template_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+DrawTemplateBean _$DrawTemplateBeanFromJson(Map json) {
+ return DrawTemplateBean(
+ json['Id'] as int?,
+ json['Title'] as String?,
+ json['ImageSmall'] as String?,
+ json['Type'] as int?,
+ (json['Charging'] as num?)?.toDouble(),
+ );
+}
+
+Map _$DrawTemplateBeanToJson(DrawTemplateBean instance) =>
+ {
+ 'Id': instance.Id,
+ 'Title': instance.Title,
+ 'ImageSmall': instance.ImageSmall,
+ 'Type': instance.Type,
+ 'Charging': instance.Charging,
+ };
diff --git a/lib/bean/equity_advert_bean.dart b/lib/bean/equity_advert_bean.dart
new file mode 100644
index 0000000..40a0fc6
--- /dev/null
+++ b/lib/bean/equity_advert_bean.dart
@@ -0,0 +1,17 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'equity_advert_bean.g.dart';
+
+@JsonSerializable()
+class EquityAdvertBean {
+ bool? IsDisplay;
+ int? WatchNum;
+ int? TotalNum;
+
+
+ EquityAdvertBean(this.IsDisplay, this.WatchNum, this.TotalNum);
+
+ factory EquityAdvertBean.fromJson(Map json) => _$EquityAdvertBeanFromJson(json);
+
+ Map toJson() => _$EquityAdvertBeanToJson(this);
+}
diff --git a/lib/bean/equity_advert_bean.g.dart b/lib/bean/equity_advert_bean.g.dart
new file mode 100644
index 0000000..3f81719
--- /dev/null
+++ b/lib/bean/equity_advert_bean.g.dart
@@ -0,0 +1,22 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'equity_advert_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+EquityAdvertBean _$EquityAdvertBeanFromJson(Map json) {
+ return EquityAdvertBean(
+ json['IsDisplay'] as bool?,
+ json['WatchNum'] as int?,
+ json['TotalNum'] as int?,
+ );
+}
+
+Map _$EquityAdvertBeanToJson(EquityAdvertBean instance) =>
+ {
+ 'IsDisplay': instance.IsDisplay,
+ 'WatchNum': instance.WatchNum,
+ 'TotalNum': instance.TotalNum,
+ };
diff --git a/lib/bean/equity_bean.dart b/lib/bean/equity_bean.dart
new file mode 100644
index 0000000..5c2762d
--- /dev/null
+++ b/lib/bean/equity_bean.dart
@@ -0,0 +1,20 @@
+import 'package:json_annotation/json_annotation.dart';
+
+import 'equity_advert_bean.dart';
+import 'equity_product_bean.dart';
+
+part 'equity_bean.g.dart';
+
+@JsonSerializable()
+class EquityBean {
+
+ EquityAdvertBean? ObjAdvert;
+ EquityProductBean? ObjProduct;
+
+
+ EquityBean(this.ObjAdvert, this.ObjProduct);
+
+ factory EquityBean.fromJson(Map json) => _$EquityBeanFromJson(json);
+
+ Map toJson() => _$EquityBeanToJson(this);
+}
diff --git a/lib/bean/equity_bean.g.dart b/lib/bean/equity_bean.g.dart
new file mode 100644
index 0000000..30d6ec6
--- /dev/null
+++ b/lib/bean/equity_bean.g.dart
@@ -0,0 +1,25 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'equity_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+EquityBean _$EquityBeanFromJson(Map json) {
+ return EquityBean(
+ json['ObjAdvert'] == null
+ ? null
+ : EquityAdvertBean.fromJson(json['ObjAdvert'] as Map),
+ json['ObjProduct'] == null
+ ? null
+ : EquityProductBean.fromJson(
+ json['ObjProduct'] as Map),
+ );
+}
+
+Map _$EquityBeanToJson(EquityBean instance) =>
+ {
+ 'ObjAdvert': instance.ObjAdvert,
+ 'ObjProduct': instance.ObjProduct,
+ };
diff --git a/lib/bean/equity_product_bean.dart b/lib/bean/equity_product_bean.dart
new file mode 100644
index 0000000..43ebca7
--- /dev/null
+++ b/lib/bean/equity_product_bean.dart
@@ -0,0 +1,20 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'equity_product_bean.g.dart';
+
+@JsonSerializable()
+class EquityProductBean {
+ String? ProductId;
+ String? ProductName;
+ int? ProductNum;
+ int? ContinuedDay;
+ double? Price;
+ double? OriginalPrice;
+ String? ImageUrl;
+
+ EquityProductBean(this.ProductId, this.ProductName, this.ProductNum, this.ContinuedDay, this.Price, this.OriginalPrice, this.ImageUrl);
+
+ factory EquityProductBean.fromJson(Map json) => _$EquityProductBeanFromJson(json);
+
+ Map toJson() => _$EquityProductBeanToJson(this);
+}
diff --git a/lib/bean/equity_product_bean.g.dart b/lib/bean/equity_product_bean.g.dart
new file mode 100644
index 0000000..cc19b08
--- /dev/null
+++ b/lib/bean/equity_product_bean.g.dart
@@ -0,0 +1,30 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'equity_product_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+EquityProductBean _$EquityProductBeanFromJson(Map json) {
+ return EquityProductBean(
+ json['ProductId'] as String?,
+ json['ProductName'] as String?,
+ json['ProductNum'] as int?,
+ json['ContinuedDay'] as int?,
+ (json['Price'] as num?)?.toDouble(),
+ (json['OriginalPrice'] as num?)?.toDouble(),
+ json['ImageUrl'] as String?,
+ );
+}
+
+Map _$EquityProductBeanToJson(EquityProductBean instance) =>
+ {
+ 'ProductId': instance.ProductId,
+ 'ProductName': instance.ProductName,
+ 'ProductNum': instance.ProductNum,
+ 'ContinuedDay': instance.ContinuedDay,
+ 'Price': instance.Price,
+ 'OriginalPrice': instance.OriginalPrice,
+ 'ImageUrl': instance.ImageUrl,
+ };
diff --git a/lib/bean/gallery_label_bean.dart b/lib/bean/gallery_label_bean.dart
new file mode 100644
index 0000000..5cbf630
--- /dev/null
+++ b/lib/bean/gallery_label_bean.dart
@@ -0,0 +1,16 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'gallery_label_bean.g.dart';
+
+@JsonSerializable()
+class GalleryLabelBean {
+ int? LabelId;
+ String? LabelName;
+ bool? IsDefault;
+
+ GalleryLabelBean(this.LabelId, this.LabelName, this.IsDefault);
+
+ factory GalleryLabelBean.fromJson(Map json) => _$GalleryLabelBeanFromJson(json);
+
+ Map toJson() => _$GalleryLabelBeanToJson(this);
+}
diff --git a/lib/bean/gallery_label_bean.g.dart b/lib/bean/gallery_label_bean.g.dart
new file mode 100644
index 0000000..fdd003c
--- /dev/null
+++ b/lib/bean/gallery_label_bean.g.dart
@@ -0,0 +1,22 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'gallery_label_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+GalleryLabelBean _$GalleryLabelBeanFromJson(Map json) {
+ return GalleryLabelBean(
+ json['LabelId'] as int?,
+ json['LabelName'] as String?,
+ json['IsDefault'] as bool?,
+ );
+}
+
+Map _$GalleryLabelBeanToJson(GalleryLabelBean instance) =>
+ {
+ 'LabelId': instance.LabelId,
+ 'LabelName': instance.LabelName,
+ 'IsDefault': instance.IsDefault,
+ };
diff --git a/lib/bean/gallery_work_label_bean.dart b/lib/bean/gallery_work_label_bean.dart
new file mode 100644
index 0000000..aaed102
--- /dev/null
+++ b/lib/bean/gallery_work_label_bean.dart
@@ -0,0 +1,16 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'gallery_work_label_bean.g.dart';
+
+@JsonSerializable()
+class GalleryWorkLabelBean {
+ int? LabelId;
+ String? LabelName;
+ int? LabelOrderId;
+
+ GalleryWorkLabelBean(this.LabelId, this.LabelName, this.LabelOrderId);
+
+ factory GalleryWorkLabelBean.fromJson(Map json) => _$GalleryWorkLabelBeanFromJson(json);
+
+ Map toJson() => _$GalleryWorkLabelBeanToJson(this);
+}
diff --git a/lib/bean/gallery_work_label_bean.g.dart b/lib/bean/gallery_work_label_bean.g.dart
new file mode 100644
index 0000000..32af8f9
--- /dev/null
+++ b/lib/bean/gallery_work_label_bean.g.dart
@@ -0,0 +1,23 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'gallery_work_label_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+GalleryWorkLabelBean _$GalleryWorkLabelBeanFromJson(Map json) {
+ return GalleryWorkLabelBean(
+ json['LabelId'] as int?,
+ json['LabelName'] as String?,
+ json['LabelOrderId'] as int?,
+ );
+}
+
+Map _$GalleryWorkLabelBeanToJson(
+ GalleryWorkLabelBean instance) =>
+ {
+ 'LabelId': instance.LabelId,
+ 'LabelName': instance.LabelName,
+ 'LabelOrderId': instance.LabelOrderId,
+ };
diff --git a/lib/bean/gallery_work_list_bean.dart b/lib/bean/gallery_work_list_bean.dart
new file mode 100644
index 0000000..403c871
--- /dev/null
+++ b/lib/bean/gallery_work_list_bean.dart
@@ -0,0 +1,28 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'gallery_work_list_bean.g.dart';
+
+@JsonSerializable()
+class GalleryWorkListBean {
+ String? TaskId;
+ int? DrawId;
+ String? ImageUrl;
+ String? Title;
+ int? WorksID;
+ String? UserNickName;
+ int? UserId;
+ String? UserIocn;
+ bool? IsCollect;
+ int? LikeNum;
+ String? FavoriteDateTime;
+ int? Status;
+ int? IsWorks;
+ int? IsTalent;
+
+ GalleryWorkListBean(this.TaskId, this.DrawId, this.ImageUrl, this.Title, this.WorksID, this.UserNickName, this.UserId, this.UserIocn,
+ this.IsCollect, this.LikeNum, this.FavoriteDateTime, this.Status, this.IsWorks, this.IsTalent);
+
+ factory GalleryWorkListBean.fromJson(Map json) => _$GalleryWorkListBeanFromJson(json);
+
+ Map toJson() => _$GalleryWorkListBeanToJson(this);
+}
diff --git a/lib/bean/gallery_work_list_bean.g.dart b/lib/bean/gallery_work_list_bean.g.dart
new file mode 100644
index 0000000..a5380bf
--- /dev/null
+++ b/lib/bean/gallery_work_list_bean.g.dart
@@ -0,0 +1,45 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'gallery_work_list_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+GalleryWorkListBean _$GalleryWorkListBeanFromJson(Map json) {
+ return GalleryWorkListBean(
+ json['TaskId'] as String?,
+ json['DrawId'] as int?,
+ json['ImageUrl'] as String?,
+ json['Title'] as String?,
+ json['WorksID'] as int?,
+ json['UserNickName'] as String?,
+ json['UserId'] as int?,
+ json['UserIocn'] as String?,
+ json['IsCollect'] as bool?,
+ json['LikeNum'] as int?,
+ json['FavoriteDateTime'] as String?,
+ json['Status'] as int?,
+ json['IsWorks'] as int?,
+ json['IsTalent'] as int?,
+ );
+}
+
+Map _$GalleryWorkListBeanToJson(
+ GalleryWorkListBean instance) =>
+ {
+ 'TaskId': instance.TaskId,
+ 'DrawId': instance.DrawId,
+ 'ImageUrl': instance.ImageUrl,
+ 'Title': instance.Title,
+ 'WorksID': instance.WorksID,
+ 'UserNickName': instance.UserNickName,
+ 'UserId': instance.UserId,
+ 'UserIocn': instance.UserIocn,
+ 'IsCollect': instance.IsCollect,
+ 'LikeNum': instance.LikeNum,
+ 'FavoriteDateTime': instance.FavoriteDateTime,
+ 'Status': instance.Status,
+ 'IsWorks': instance.IsWorks,
+ 'IsTalent': instance.IsTalent,
+ };
diff --git a/lib/bean/levitating_ball_bean.dart b/lib/bean/levitating_ball_bean.dart
new file mode 100644
index 0000000..62903fc
--- /dev/null
+++ b/lib/bean/levitating_ball_bean.dart
@@ -0,0 +1,20 @@
+import 'package:json_annotation/json_annotation.dart';
+
+import 'levitating_ball_pop_bean.dart';
+
+part 'levitating_ball_bean.g.dart';
+
+@JsonSerializable()
+class LevitatingBallBean {
+ String? name;
+ int? ResType;
+ String? ResId;
+ String? ImageUrl;
+ LevitatingBallPopBean? Popup;
+
+ LevitatingBallBean(this.name, this.ResType, this.ResId, this.ImageUrl, this.Popup);
+
+ factory LevitatingBallBean.fromJson(Map json) => _$LevitatingBallBeanFromJson(json);
+
+ Map toJson() => _$LevitatingBallBeanToJson(this);
+}
diff --git a/lib/bean/levitating_ball_bean.g.dart b/lib/bean/levitating_ball_bean.g.dart
new file mode 100644
index 0000000..99d97be
--- /dev/null
+++ b/lib/bean/levitating_ball_bean.g.dart
@@ -0,0 +1,28 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'levitating_ball_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+LevitatingBallBean _$LevitatingBallBeanFromJson(Map json) {
+ return LevitatingBallBean(
+ json['name'] as String?,
+ json['ResType'] as int?,
+ json['ResId'] as String?,
+ json['ImageUrl'] as String?,
+ json['Popup'] == null
+ ? null
+ : LevitatingBallPopBean.fromJson(json['Popup'] as Map),
+ );
+}
+
+Map _$LevitatingBallBeanToJson(LevitatingBallBean instance) =>
+ {
+ 'name': instance.name,
+ 'ResType': instance.ResType,
+ 'ResId': instance.ResId,
+ 'ImageUrl': instance.ImageUrl,
+ 'Popup': instance.Popup,
+ };
diff --git a/lib/bean/levitating_ball_pop_bean.dart b/lib/bean/levitating_ball_pop_bean.dart
new file mode 100644
index 0000000..7728ca4
--- /dev/null
+++ b/lib/bean/levitating_ball_pop_bean.dart
@@ -0,0 +1,21 @@
+import 'package:aiplot/bean/pic_info_bean.dart';
+import 'package:json_annotation/json_annotation.dart';
+
+part 'levitating_ball_pop_bean.g.dart';
+
+@JsonSerializable()
+class LevitatingBallPopBean {
+ String? Image;
+ int? PopoutType;
+ String? Text;
+ PicInfoBean? BgPicInfo;
+ PicInfoBean? BtOKInfo;
+ PicInfoBean? BtCloseInfo;
+ PicInfoBean? ContentInfo;
+
+ LevitatingBallPopBean(this.Image, this.PopoutType, this.Text, this.BgPicInfo, this.BtOKInfo, this.BtCloseInfo, this.ContentInfo);
+
+ factory LevitatingBallPopBean.fromJson(Map json) => _$LevitatingBallPopBeanFromJson(json);
+
+ Map toJson() => _$LevitatingBallPopBeanToJson(this);
+}
diff --git a/lib/bean/levitating_ball_pop_bean.g.dart b/lib/bean/levitating_ball_pop_bean.g.dart
new file mode 100644
index 0000000..735bd61
--- /dev/null
+++ b/lib/bean/levitating_ball_pop_bean.g.dart
@@ -0,0 +1,40 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'levitating_ball_pop_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+LevitatingBallPopBean _$LevitatingBallPopBeanFromJson(
+ Map json) {
+ return LevitatingBallPopBean(
+ json['Image'] as String?,
+ json['PopoutType'] as int?,
+ json['Text'] as String?,
+ json['BgPicInfo'] == null
+ ? null
+ : PicInfoBean.fromJson(json['BgPicInfo'] as Map),
+ json['BtOKInfo'] == null
+ ? null
+ : PicInfoBean.fromJson(json['BtOKInfo'] as Map),
+ json['BtCloseInfo'] == null
+ ? null
+ : PicInfoBean.fromJson(json['BtCloseInfo'] as Map),
+ json['ContentInfo'] == null
+ ? null
+ : PicInfoBean.fromJson(json['ContentInfo'] as Map),
+ );
+}
+
+Map _$LevitatingBallPopBeanToJson(
+ LevitatingBallPopBean instance) =>
+ {
+ 'Image': instance.Image,
+ 'PopoutType': instance.PopoutType,
+ 'Text': instance.Text,
+ 'BgPicInfo': instance.BgPicInfo,
+ 'BtOKInfo': instance.BtOKInfo,
+ 'BtCloseInfo': instance.BtCloseInfo,
+ 'ContentInfo': instance.ContentInfo,
+ };
diff --git a/lib/bean/login_bean.dart b/lib/bean/login_bean.dart
new file mode 100644
index 0000000..ebf6b6f
--- /dev/null
+++ b/lib/bean/login_bean.dart
@@ -0,0 +1,17 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'login_bean.g.dart';
+
+@JsonSerializable()
+class LoginBean {
+ int? UserId;
+ String? UserName;
+ String? Token;
+
+
+ LoginBean(this.UserId, this.UserName, this.Token);
+
+ factory LoginBean.fromJson(Map json) => _$LoginBeanFromJson(json);
+
+ Map toJson() => _$LoginBeanToJson(this);
+}
diff --git a/lib/bean/login_bean.g.dart b/lib/bean/login_bean.g.dart
new file mode 100644
index 0000000..320859a
--- /dev/null
+++ b/lib/bean/login_bean.g.dart
@@ -0,0 +1,21 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'login_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+LoginBean _$LoginBeanFromJson(Map json) {
+ return LoginBean(
+ json['UserId'] as int?,
+ json['UserName'] as String?,
+ json['Token'] as String?,
+ );
+}
+
+Map _$LoginBeanToJson(LoginBean instance) => {
+ 'UserId': instance.UserId,
+ 'UserName': instance.UserName,
+ 'Token': instance.Token,
+ };
diff --git a/lib/bean/me_bean.dart b/lib/bean/me_bean.dart
new file mode 100644
index 0000000..eac0709
--- /dev/null
+++ b/lib/bean/me_bean.dart
@@ -0,0 +1,21 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'me_bean.g.dart';
+
+@JsonSerializable()
+class MeBean {
+ int? Id;
+ String? TaskId;
+ String? OutputUri;
+ String? CreatTime;
+ String? UpdateTime;
+ String? InputParams;
+ String? Title;
+ bool? IsCheck;
+
+ MeBean(this.Id, this.TaskId, this.OutputUri, this.CreatTime, this.UpdateTime, this.InputParams, this.Title, this.IsCheck);
+
+ factory MeBean.fromJson(Map json) => _$MeBeanFromJson(json);
+
+ Map toJson() => _$MeBeanToJson(this);
+}
diff --git a/lib/bean/me_bean.g.dart b/lib/bean/me_bean.g.dart
new file mode 100644
index 0000000..144a6fa
--- /dev/null
+++ b/lib/bean/me_bean.g.dart
@@ -0,0 +1,31 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'me_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+MeBean _$MeBeanFromJson(Map json) {
+ return MeBean(
+ json['Id'] as int?,
+ json['TaskId'] as String?,
+ json['OutputUri'] as String?,
+ json['CreatTime'] as String?,
+ json['UpdateTime'] as String?,
+ json['InputParams'] as String?,
+ json['Title'] as String?,
+ json['IsCheck'] as bool?,
+ );
+}
+
+Map _$MeBeanToJson(MeBean instance) => {
+ 'Id': instance.Id,
+ 'TaskId': instance.TaskId,
+ 'OutputUri': instance.OutputUri,
+ 'CreatTime': instance.CreatTime,
+ 'UpdateTime': instance.UpdateTime,
+ 'InputParams': instance.InputParams,
+ 'Title': instance.Title,
+ 'IsCheck': instance.IsCheck,
+ };
diff --git a/lib/bean/pic_info_bean.dart b/lib/bean/pic_info_bean.dart
new file mode 100644
index 0000000..df6b713
--- /dev/null
+++ b/lib/bean/pic_info_bean.dart
@@ -0,0 +1,18 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'pic_info_bean.g.dart';
+
+@JsonSerializable()
+class PicInfoBean {
+ String? Pic;
+ dynamic PosX;
+ dynamic PosY;
+ dynamic W;
+ dynamic H;
+
+ PicInfoBean(this.Pic, this.PosX, this.PosY, this.W, this.H);
+
+ factory PicInfoBean.fromJson(Map json) => _$PicInfoBeanFromJson(json);
+
+ Map toJson() => _$PicInfoBeanToJson(this);
+}
diff --git a/lib/bean/pic_info_bean.g.dart b/lib/bean/pic_info_bean.g.dart
new file mode 100644
index 0000000..7111648
--- /dev/null
+++ b/lib/bean/pic_info_bean.g.dart
@@ -0,0 +1,26 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'pic_info_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+PicInfoBean _$PicInfoBeanFromJson(Map json) {
+ return PicInfoBean(
+ json['Pic'] as String?,
+ json['PosX'],
+ json['PosY'],
+ json['W'],
+ json['H'],
+ );
+}
+
+Map _$PicInfoBeanToJson(PicInfoBean instance) =>
+ {
+ 'Pic': instance.Pic,
+ 'PosX': instance.PosX,
+ 'PosY': instance.PosY,
+ 'W': instance.W,
+ 'H': instance.H,
+ };
diff --git a/lib/bean/popout_bean.dart b/lib/bean/popout_bean.dart
new file mode 100644
index 0000000..f242e5f
--- /dev/null
+++ b/lib/bean/popout_bean.dart
@@ -0,0 +1,23 @@
+import 'package:aiplot/bean/pic_info_bean.dart';
+import 'package:json_annotation/json_annotation.dart';
+
+part 'popout_bean.g.dart';
+
+@JsonSerializable()
+class PopoutBean {
+ int? PopoutType;
+ String? PopoutId;
+ String? Image;
+ String? Text;
+ int? AdId;
+ PicInfoBean? BgPicInfo;
+ PicInfoBean? BtOKInfo;
+ PicInfoBean? BtCloseInfo;
+ PicInfoBean? ContentInfo;
+
+ PopoutBean(this.PopoutType, this.PopoutId, this.Image, this.Text, this.AdId, this.BgPicInfo, this.BtOKInfo, this.BtCloseInfo, this.ContentInfo);
+
+ factory PopoutBean.fromJson(Map json) => _$PopoutBeanFromJson(json);
+
+ Map toJson() => _$PopoutBeanToJson(this);
+}
diff --git a/lib/bean/popout_bean.g.dart b/lib/bean/popout_bean.g.dart
new file mode 100644
index 0000000..7a8bfdd
--- /dev/null
+++ b/lib/bean/popout_bean.g.dart
@@ -0,0 +1,42 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'popout_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+PopoutBean _$PopoutBeanFromJson(Map json) {
+ return PopoutBean(
+ json['PopoutType'] as int?,
+ json['PopoutId'] as String?,
+ json['Image'] as String?,
+ json['Text'] as String?,
+ json['AdId'] as int?,
+ json['BgPicInfo'] == null
+ ? null
+ : PicInfoBean.fromJson(json['BgPicInfo'] as Map),
+ json['BtOKInfo'] == null
+ ? null
+ : PicInfoBean.fromJson(json['BtOKInfo'] as Map),
+ json['BtCloseInfo'] == null
+ ? null
+ : PicInfoBean.fromJson(json['BtCloseInfo'] as Map),
+ json['ContentInfo'] == null
+ ? null
+ : PicInfoBean.fromJson(json['ContentInfo'] as Map),
+ );
+}
+
+Map _$PopoutBeanToJson(PopoutBean instance) =>
+ {
+ 'PopoutType': instance.PopoutType,
+ 'PopoutId': instance.PopoutId,
+ 'Image': instance.Image,
+ 'Text': instance.Text,
+ 'AdId': instance.AdId,
+ 'BgPicInfo': instance.BgPicInfo,
+ 'BtOKInfo': instance.BtOKInfo,
+ 'BtCloseInfo': instance.BtCloseInfo,
+ 'ContentInfo': instance.ContentInfo,
+ };
diff --git a/lib/bean/product_bean.dart b/lib/bean/product_bean.dart
new file mode 100644
index 0000000..b8e3eca
--- /dev/null
+++ b/lib/bean/product_bean.dart
@@ -0,0 +1,20 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'product_bean.g.dart';
+
+@JsonSerializable()
+class ProductBean {
+ String? ProductId;
+ String? ProductName;
+ int? ProductNum;
+ int? ContinuedDay;
+ double? Price;
+ double? OriginalPrice;
+ String? ImageUrl;
+
+ ProductBean(this.ProductId, this.ProductName, this.ProductNum, this.ContinuedDay, this.Price, this.OriginalPrice, this.ImageUrl);
+
+ factory ProductBean.fromJson(Map json) => _$ProductBeanFromJson(json);
+
+ Map toJson() => _$ProductBeanToJson(this);
+}
diff --git a/lib/bean/product_bean.g.dart b/lib/bean/product_bean.g.dart
new file mode 100644
index 0000000..740594f
--- /dev/null
+++ b/lib/bean/product_bean.g.dart
@@ -0,0 +1,30 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'product_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+ProductBean _$ProductBeanFromJson(Map json) {
+ return ProductBean(
+ json['ProductId'] as String?,
+ json['ProductName'] as String?,
+ json['ProductNum'] as int?,
+ json['ContinuedDay'] as int?,
+ (json['Price'] as num?)?.toDouble(),
+ (json['OriginalPrice'] as num?)?.toDouble(),
+ json['ImageUrl'] as String?,
+ );
+}
+
+Map _$ProductBeanToJson(ProductBean instance) =>
+ {
+ 'ProductId': instance.ProductId,
+ 'ProductName': instance.ProductName,
+ 'ProductNum': instance.ProductNum,
+ 'ContinuedDay': instance.ContinuedDay,
+ 'Price': instance.Price,
+ 'OriginalPrice': instance.OriginalPrice,
+ 'ImageUrl': instance.ImageUrl,
+ };
diff --git a/lib/bean/progress_bean.dart b/lib/bean/progress_bean.dart
new file mode 100644
index 0000000..6879bce
--- /dev/null
+++ b/lib/bean/progress_bean.dart
@@ -0,0 +1,19 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'progress_bean.g.dart';
+
+@JsonSerializable()
+class ProgressBean {
+ String? TaskId;
+ String? CreateTime;
+ String? UpdateTime;
+ String? ServerUri;
+ int? TaskPercent;
+ String? TaskResponse;
+
+ ProgressBean(this.TaskId, this.CreateTime, this.UpdateTime, this.ServerUri, this.TaskPercent, this.TaskResponse);
+
+ factory ProgressBean.fromJson(Map json) => _$ProgressBeanFromJson(json);
+
+ Map toJson() => _$ProgressBeanToJson(this);
+}
diff --git a/lib/bean/progress_bean.g.dart b/lib/bean/progress_bean.g.dart
new file mode 100644
index 0000000..8d3620d
--- /dev/null
+++ b/lib/bean/progress_bean.g.dart
@@ -0,0 +1,28 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'progress_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+ProgressBean _$ProgressBeanFromJson(Map json) {
+ return ProgressBean(
+ json['TaskId'] as String?,
+ json['CreateTime'] as String?,
+ json['UpdateTime'] as String?,
+ json['ServerUri'] as String?,
+ json['TaskPercent'] as int?,
+ json['TaskResponse'] as String?,
+ );
+}
+
+Map _$ProgressBeanToJson(ProgressBean instance) =>
+ {
+ 'TaskId': instance.TaskId,
+ 'CreateTime': instance.CreateTime,
+ 'UpdateTime': instance.UpdateTime,
+ 'ServerUri': instance.ServerUri,
+ 'TaskPercent': instance.TaskPercent,
+ 'TaskResponse': instance.TaskResponse,
+ };
diff --git a/lib/bean/recommender_bean.dart b/lib/bean/recommender_bean.dart
new file mode 100644
index 0000000..49eb846
--- /dev/null
+++ b/lib/bean/recommender_bean.dart
@@ -0,0 +1,18 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'recommender_bean.g.dart';
+
+@JsonSerializable()
+class RecommenderBean {
+ int? UserId;
+ String? NickName;
+ String? UserIconUrl;
+ int? UserFollow;
+ String? CreateTime;
+
+ RecommenderBean(this.UserId, this.NickName, this.UserIconUrl, this.UserFollow, this.CreateTime);
+
+ factory RecommenderBean.fromJson(Map json) => _$RecommenderBeanFromJson(json);
+
+ Map toJson() => _$RecommenderBeanToJson(this);
+}
diff --git a/lib/bean/recommender_bean.g.dart b/lib/bean/recommender_bean.g.dart
new file mode 100644
index 0000000..17ac4c0
--- /dev/null
+++ b/lib/bean/recommender_bean.g.dart
@@ -0,0 +1,26 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'recommender_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+RecommenderBean _$RecommenderBeanFromJson(Map json) {
+ return RecommenderBean(
+ json['UserId'] as int?,
+ json['NickName'] as String?,
+ json['UserIconUrl'] as String?,
+ json['UserFollow'] as int?,
+ json['CreateTime'] as String?,
+ );
+}
+
+Map _$RecommenderBeanToJson(RecommenderBean instance) =>
+ {
+ 'UserId': instance.UserId,
+ 'NickName': instance.NickName,
+ 'UserIconUrl': instance.UserIconUrl,
+ 'UserFollow': instance.UserFollow,
+ 'CreateTime': instance.CreateTime,
+ };
diff --git a/lib/bean/server_bean.dart b/lib/bean/server_bean.dart
new file mode 100644
index 0000000..10dc95d
--- /dev/null
+++ b/lib/bean/server_bean.dart
@@ -0,0 +1,15 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'server_bean.g.dart';
+
+@JsonSerializable()
+class ServerBean {
+ String? HissAiApiUrl;
+ String? HissAiPayUrl;
+
+ ServerBean(this.HissAiApiUrl,this.HissAiPayUrl);
+
+ factory ServerBean.fromJson(Map json) => _$ServerBeanFromJson(json);
+
+ Map toJson() => _$ServerBeanToJson(this);
+}
diff --git a/lib/bean/server_bean.g.dart b/lib/bean/server_bean.g.dart
new file mode 100644
index 0000000..b7848a6
--- /dev/null
+++ b/lib/bean/server_bean.g.dart
@@ -0,0 +1,20 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'server_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+ServerBean _$ServerBeanFromJson(Map json) {
+ return ServerBean(
+ json['HissAiApiUrl'] as String?,
+ json['HissAiPayUrl'] as String?,
+ );
+}
+
+Map _$ServerBeanToJson(ServerBean instance) =>
+ {
+ 'HissAiApiUrl': instance.HissAiApiUrl,
+ 'HissAiPayUrl': instance.HissAiPayUrl,
+ };
diff --git a/lib/bean/text_to_image_bean.dart b/lib/bean/text_to_image_bean.dart
new file mode 100644
index 0000000..be9dee8
--- /dev/null
+++ b/lib/bean/text_to_image_bean.dart
@@ -0,0 +1,19 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'text_to_image_bean.g.dart';
+
+@JsonSerializable()
+class TextToImageBean {
+ int? SeqId;
+ String? TaskId;
+ int? TaskLevel;
+ int? Status;
+ int? TaskPercent;
+ String? TaskResult;
+
+ TextToImageBean(this.SeqId, this.TaskId, this.TaskLevel, this.Status, this.TaskPercent, this.TaskResult);
+
+ factory TextToImageBean.fromJson(Map json) => _$TextToImageBeanFromJson(json);
+
+ Map toJson() => _$TextToImageBeanToJson(this);
+}
diff --git a/lib/bean/text_to_image_bean.g.dart b/lib/bean/text_to_image_bean.g.dart
new file mode 100644
index 0000000..e45374c
--- /dev/null
+++ b/lib/bean/text_to_image_bean.g.dart
@@ -0,0 +1,28 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'text_to_image_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+TextToImageBean _$TextToImageBeanFromJson(Map json) {
+ return TextToImageBean(
+ json['SeqId'] as int?,
+ json['TaskId'] as String?,
+ json['TaskLevel'] as int?,
+ json['Status'] as int?,
+ json['TaskPercent'] as int?,
+ json['TaskResult'] as String?,
+ );
+}
+
+Map _$TextToImageBeanToJson(TextToImageBean instance) =>
+ {
+ 'SeqId': instance.SeqId,
+ 'TaskId': instance.TaskId,
+ 'TaskLevel': instance.TaskLevel,
+ 'Status': instance.Status,
+ 'TaskPercent': instance.TaskPercent,
+ 'TaskResult': instance.TaskResult,
+ };
diff --git a/lib/bean/user_ad_num_bean.dart b/lib/bean/user_ad_num_bean.dart
new file mode 100644
index 0000000..efdebf3
--- /dev/null
+++ b/lib/bean/user_ad_num_bean.dart
@@ -0,0 +1,17 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'user_ad_num_bean.g.dart';
+
+@JsonSerializable()
+class UserAdNumBean {
+ int? UsedRewardCount;
+ int? TotalRewardCount;
+ String? BackgroundImage;
+
+
+ UserAdNumBean(this.UsedRewardCount, this.TotalRewardCount, this.BackgroundImage);
+
+ factory UserAdNumBean.fromJson(Map json) => _$UserAdNumBeanFromJson(json);
+
+ Map toJson() => _$UserAdNumBeanToJson(this);
+}
diff --git a/lib/bean/user_ad_num_bean.g.dart b/lib/bean/user_ad_num_bean.g.dart
new file mode 100644
index 0000000..66de49f
--- /dev/null
+++ b/lib/bean/user_ad_num_bean.g.dart
@@ -0,0 +1,22 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'user_ad_num_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+UserAdNumBean _$UserAdNumBeanFromJson(Map json) {
+ return UserAdNumBean(
+ json['UsedRewardCount'] as int?,
+ json['TotalRewardCount'] as int?,
+ json['BackgroundImage'] as String?,
+ );
+}
+
+Map _$UserAdNumBeanToJson(UserAdNumBean instance) =>
+ {
+ 'UsedRewardCount': instance.UsedRewardCount,
+ 'TotalRewardCount': instance.TotalRewardCount,
+ 'BackgroundImage': instance.BackgroundImage,
+ };
diff --git a/lib/bean/user_bean.dart b/lib/bean/user_bean.dart
new file mode 100644
index 0000000..cd3e501
--- /dev/null
+++ b/lib/bean/user_bean.dart
@@ -0,0 +1,16 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'user_bean.g.dart';
+
+@JsonSerializable()
+class UserBean {
+ String? userId;
+ String? token;
+ String? userToken;
+
+ UserBean(this.userId, this.token, this.userToken);
+
+ factory UserBean.fromJson(Map json) => _$UserBeanFromJson(json);
+
+ Map toJson() => _$UserBeanToJson(this);
+}
diff --git a/lib/bean/user_bean.g.dart b/lib/bean/user_bean.g.dart
new file mode 100644
index 0000000..d4811fb
--- /dev/null
+++ b/lib/bean/user_bean.g.dart
@@ -0,0 +1,21 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'user_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+UserBean _$UserBeanFromJson(Map json) {
+ return UserBean(
+ json['userId'] as String?,
+ json['token'] as String?,
+ json['userToken'] as String?,
+ );
+}
+
+Map _$UserBeanToJson(UserBean instance) => {
+ 'userId': instance.userId,
+ 'token': instance.token,
+ 'userToken': instance.userToken,
+ };
diff --git a/lib/bean/user_center_bean.dart b/lib/bean/user_center_bean.dart
new file mode 100644
index 0000000..6c34a08
--- /dev/null
+++ b/lib/bean/user_center_bean.dart
@@ -0,0 +1,24 @@
+import 'package:aiplot/bean/works_list_bean.dart';
+import 'package:json_annotation/json_annotation.dart';
+
+part 'user_center_bean.g.dart';
+
+@JsonSerializable()
+class UserCenterBean {
+ String? UserIconUrl;
+ int? UserId;
+ String? NickName;
+ int? LikeNum;
+ int? TalentId;
+ List? WorksList;
+ int? IsTalentUser;
+ bool? IsFollow;
+ int? FansNum;
+
+ UserCenterBean(
+ this.UserIconUrl, this.UserId, this.NickName, this.LikeNum, this.TalentId, this.WorksList, this.IsTalentUser, this.IsFollow, this.FansNum);
+
+ factory UserCenterBean.fromJson(Map json) => _$UserCenterBeanFromJson(json);
+
+ Map toJson() => _$UserCenterBeanToJson(this);
+}
diff --git a/lib/bean/user_center_bean.g.dart b/lib/bean/user_center_bean.g.dart
new file mode 100644
index 0000000..0d73937
--- /dev/null
+++ b/lib/bean/user_center_bean.g.dart
@@ -0,0 +1,36 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'user_center_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+UserCenterBean _$UserCenterBeanFromJson(Map json) {
+ return UserCenterBean(
+ json['UserIconUrl'] as String?,
+ json['UserId'] as int?,
+ json['NickName'] as String?,
+ json['LikeNum'] as int?,
+ json['TalentId'] as int?,
+ (json['WorksList'] as List?)
+ ?.map((e) => WorksListBean.fromJson(e as Map))
+ .toList(),
+ json['IsTalentUser'] as int?,
+ json['IsFollow'] as bool?,
+ json['FansNum'] as int?,
+ );
+}
+
+Map _$UserCenterBeanToJson(UserCenterBean instance) =>
+ {
+ 'UserIconUrl': instance.UserIconUrl,
+ 'UserId': instance.UserId,
+ 'NickName': instance.NickName,
+ 'LikeNum': instance.LikeNum,
+ 'TalentId': instance.TalentId,
+ 'WorksList': instance.WorksList,
+ 'IsTalentUser': instance.IsTalentUser,
+ 'IsFollow': instance.IsFollow,
+ 'FansNum': instance.FansNum,
+ };
diff --git a/lib/bean/user_draw_bean.dart b/lib/bean/user_draw_bean.dart
new file mode 100644
index 0000000..ba3f35f
--- /dev/null
+++ b/lib/bean/user_draw_bean.dart
@@ -0,0 +1,25 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'user_draw_bean.g.dart';
+
+@JsonSerializable()
+class UserDrawBean {
+ String? TaskId;
+ int? DrawId;
+ String? ImageUrl;
+ String? Title;
+ String? UserNickName;
+ String? UserIocn;
+ bool? IsCollect;
+ int? CollectNumber;
+ String? FavoriteDateTime;
+ int? Status;
+ bool? IsCheck;
+
+ UserDrawBean(this.TaskId, this.DrawId, this.ImageUrl, this.Title, this.UserNickName, this.UserIocn, this.IsCollect, this.CollectNumber,
+ this.FavoriteDateTime,this.Status,this.IsCheck);
+
+ factory UserDrawBean.fromJson(Map json) => _$UserDrawBeanFromJson(json);
+
+ Map toJson() => _$UserDrawBeanToJson(this);
+}
diff --git a/lib/bean/user_draw_bean.g.dart b/lib/bean/user_draw_bean.g.dart
new file mode 100644
index 0000000..514ebb7
--- /dev/null
+++ b/lib/bean/user_draw_bean.g.dart
@@ -0,0 +1,38 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'user_draw_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+UserDrawBean _$UserDrawBeanFromJson(Map json) {
+ return UserDrawBean(
+ json['TaskId'] as String?,
+ json['DrawId'] as int?,
+ json['ImageUrl'] as String?,
+ json['Title'] as String?,
+ json['UserNickName'] as String?,
+ json['UserIocn'] as String?,
+ json['IsCollect'] as bool?,
+ json['CollectNumber'] as int?,
+ json['FavoriteDateTime'] as String?,
+ json['Status'] as int?,
+ json['IsCheck'] as bool?,
+ );
+}
+
+Map _$UserDrawBeanToJson(UserDrawBean instance) =>
+ {
+ 'TaskId': instance.TaskId,
+ 'DrawId': instance.DrawId,
+ 'ImageUrl': instance.ImageUrl,
+ 'Title': instance.Title,
+ 'UserNickName': instance.UserNickName,
+ 'UserIocn': instance.UserIocn,
+ 'IsCollect': instance.IsCollect,
+ 'CollectNumber': instance.CollectNumber,
+ 'FavoriteDateTime': instance.FavoriteDateTime,
+ 'Status': instance.Status,
+ 'IsCheck': instance.IsCheck,
+ };
diff --git a/lib/bean/user_info_bean.dart b/lib/bean/user_info_bean.dart
new file mode 100644
index 0000000..31f8922
--- /dev/null
+++ b/lib/bean/user_info_bean.dart
@@ -0,0 +1,27 @@
+import 'package:aiplot/bean/user_ad_num_bean.dart';
+import 'package:json_annotation/json_annotation.dart';
+
+part 'user_info_bean.g.dart';
+
+@JsonSerializable()
+class UserInfoBean {
+ int? UserId;
+ String? NickName;
+ String? UserIconUrl;
+ double? Currency;
+ double? TemporaryCurrency;
+ double? AllCurrency;
+ int? VipType;
+ int? CollectNumber;
+ int? SaveImageNumber;
+ UserAdNumBean? UserAdLog;
+ String? InvitationCode;
+ String? InvitationCodeImageUrl;
+
+ UserInfoBean(this.UserId, this.NickName, this.UserIconUrl, this.Currency, this.TemporaryCurrency, this.AllCurrency, this.VipType,
+ this.CollectNumber, this.SaveImageNumber, this.UserAdLog, this.InvitationCode, this.InvitationCodeImageUrl);
+
+ factory UserInfoBean.fromJson(Map json) => _$UserInfoBeanFromJson(json);
+
+ Map toJson() => _$UserInfoBeanToJson(this);
+}
diff --git a/lib/bean/user_info_bean.g.dart b/lib/bean/user_info_bean.g.dart
new file mode 100644
index 0000000..2669605
--- /dev/null
+++ b/lib/bean/user_info_bean.g.dart
@@ -0,0 +1,42 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'user_info_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+UserInfoBean _$UserInfoBeanFromJson(Map json) {
+ return UserInfoBean(
+ json['UserId'] as int?,
+ json['NickName'] as String?,
+ json['UserIconUrl'] as String?,
+ (json['Currency'] as num?)?.toDouble(),
+ (json['TemporaryCurrency'] as num?)?.toDouble(),
+ (json['AllCurrency'] as num?)?.toDouble(),
+ json['VipType'] as int?,
+ json['CollectNumber'] as int?,
+ json['SaveImageNumber'] as int?,
+ json['UserAdLog'] == null
+ ? null
+ : UserAdNumBean.fromJson(json['UserAdLog'] as Map),
+ json['InvitationCode'] as String?,
+ json['InvitationCodeImageUrl'] as String?,
+ );
+}
+
+Map _$UserInfoBeanToJson(UserInfoBean instance) =>
+ {
+ 'UserId': instance.UserId,
+ 'NickName': instance.NickName,
+ 'UserIconUrl': instance.UserIconUrl,
+ 'Currency': instance.Currency,
+ 'TemporaryCurrency': instance.TemporaryCurrency,
+ 'AllCurrency': instance.AllCurrency,
+ 'VipType': instance.VipType,
+ 'CollectNumber': instance.CollectNumber,
+ 'SaveImageNumber': instance.SaveImageNumber,
+ 'UserAdLog': instance.UserAdLog,
+ 'InvitationCode': instance.InvitationCode,
+ 'InvitationCodeImageUrl': instance.InvitationCodeImageUrl,
+ };
diff --git a/lib/bean/works_detail_bean.dart b/lib/bean/works_detail_bean.dart
new file mode 100644
index 0000000..b71eb0c
--- /dev/null
+++ b/lib/bean/works_detail_bean.dart
@@ -0,0 +1,71 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'works_detail_bean.g.dart';
+
+@JsonSerializable()
+class WorksDetailBean {
+ int? DrawId;
+ int? Id;
+ int? UserId;
+ int? AppId;
+ String? TaskId;
+ int? TaskLevel;
+ String? TaskResult;
+ String? TaskResultWatermark;
+ String? TaskResultResize;
+ String? Title;
+ int? TemplateId;
+ int? TemplateLabelId;
+ int? FollowDrawId;
+ String? CreateTime;
+ int? Status;
+ String? Prompt;
+ String? UserNickName;
+ String? UserIocn;
+ bool? IsUserDrawGallery;
+ bool? IsMyCollect;
+ int? SizeTemplateId;
+ int? DrawState;
+ int? LikeNum;
+ bool? IsMyLike;
+ bool? IsFollow;
+ bool? IsTalentWork;
+ bool? IsCurrentImgDetails;
+ int? ConsumeCurrency;
+ String? DrawLabel;
+
+ WorksDetailBean(
+ this.DrawId,
+ this.Id,
+ this.UserId,
+ this.AppId,
+ this.TaskId,
+ this.TaskLevel,
+ this.TaskResult,
+ this.TaskResultWatermark,
+ this.TaskResultResize,
+ this.Title,
+ this.TemplateId,
+ this.TemplateLabelId,
+ this.FollowDrawId,
+ this.CreateTime,
+ this.Status,
+ this.Prompt,
+ this.UserNickName,
+ this.UserIocn,
+ this.IsUserDrawGallery,
+ this.IsMyCollect,
+ this.SizeTemplateId,
+ this.DrawState,
+ this.LikeNum,
+ this.IsMyLike,
+ this.IsFollow,
+ this.IsTalentWork,
+ this.IsCurrentImgDetails,
+ this.ConsumeCurrency,
+ this.DrawLabel);
+
+ factory WorksDetailBean.fromJson(Map json) => _$WorksDetailBeanFromJson(json);
+
+ Map toJson() => _$WorksDetailBeanToJson(this);
+}
diff --git a/lib/bean/works_detail_bean.g.dart b/lib/bean/works_detail_bean.g.dart
new file mode 100644
index 0000000..ea779e8
--- /dev/null
+++ b/lib/bean/works_detail_bean.g.dart
@@ -0,0 +1,74 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'works_detail_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+WorksDetailBean _$WorksDetailBeanFromJson(Map json) {
+ return WorksDetailBean(
+ json['DrawId'] as int?,
+ json['Id'] as int?,
+ json['UserId'] as int?,
+ json['AppId'] as int?,
+ json['TaskId'] as String?,
+ json['TaskLevel'] as int?,
+ json['TaskResult'] as String?,
+ json['TaskResultWatermark'] as String?,
+ json['TaskResultResize'] as String?,
+ json['Title'] as String?,
+ json['TemplateId'] as int?,
+ json['TemplateLabelId'] as int?,
+ json['FollowDrawId'] as int?,
+ json['CreateTime'] as String?,
+ json['Status'] as int?,
+ json['Prompt'] as String?,
+ json['UserNickName'] as String?,
+ json['UserIocn'] as String?,
+ json['IsUserDrawGallery'] as bool?,
+ json['IsMyCollect'] as bool?,
+ json['SizeTemplateId'] as int?,
+ json['DrawState'] as int?,
+ json['LikeNum'] as int?,
+ json['IsMyLike'] as bool?,
+ json['IsFollow'] as bool?,
+ json['IsTalentWork'] as bool?,
+ json['IsCurrentImgDetails'] as bool?,
+ json['ConsumeCurrency'] as int?,
+ json['DrawLabel'] as String?,
+ );
+}
+
+Map _$WorksDetailBeanToJson(WorksDetailBean instance) =>
+ {
+ 'DrawId': instance.DrawId,
+ 'Id': instance.Id,
+ 'UserId': instance.UserId,
+ 'AppId': instance.AppId,
+ 'TaskId': instance.TaskId,
+ 'TaskLevel': instance.TaskLevel,
+ 'TaskResult': instance.TaskResult,
+ 'TaskResultWatermark': instance.TaskResultWatermark,
+ 'TaskResultResize': instance.TaskResultResize,
+ 'Title': instance.Title,
+ 'TemplateId': instance.TemplateId,
+ 'TemplateLabelId': instance.TemplateLabelId,
+ 'FollowDrawId': instance.FollowDrawId,
+ 'CreateTime': instance.CreateTime,
+ 'Status': instance.Status,
+ 'Prompt': instance.Prompt,
+ 'UserNickName': instance.UserNickName,
+ 'UserIocn': instance.UserIocn,
+ 'IsUserDrawGallery': instance.IsUserDrawGallery,
+ 'IsMyCollect': instance.IsMyCollect,
+ 'SizeTemplateId': instance.SizeTemplateId,
+ 'DrawState': instance.DrawState,
+ 'LikeNum': instance.LikeNum,
+ 'IsMyLike': instance.IsMyLike,
+ 'IsFollow': instance.IsFollow,
+ 'IsTalentWork': instance.IsTalentWork,
+ 'IsCurrentImgDetails': instance.IsCurrentImgDetails,
+ 'ConsumeCurrency': instance.ConsumeCurrency,
+ 'DrawLabel': instance.DrawLabel,
+ };
diff --git a/lib/bean/works_info_bean.dart b/lib/bean/works_info_bean.dart
new file mode 100644
index 0000000..250a2a3
--- /dev/null
+++ b/lib/bean/works_info_bean.dart
@@ -0,0 +1,61 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'works_info_bean.g.dart';
+
+@JsonSerializable()
+class WorksInfoBean {
+ int Id;
+ int DrawId;
+ int WorksId;
+ int UserId;
+ int AppId;
+ String BossId;
+ String TaskId;
+ String TaskResult;
+ String TaskResultWatermark;
+ String TaskResultResize;
+ String Title;
+ int TemplateId;
+ int TemplateLabelId;
+ String CreateTime;
+ int Status;
+ String Prompt;
+ String UserNickName;
+ String UserIocn;
+ bool IsMyLike;
+ int SizeTemplateId;
+ int LikeNum;
+ bool IsGalleyWork;
+ bool IsTalentWork;
+ bool IsFollow;
+
+ WorksInfoBean(
+ this.Id,
+ this.DrawId,
+ this.WorksId,
+ this.UserId,
+ this.AppId,
+ this.BossId,
+ this.TaskId,
+ this.TaskResult,
+ this.TaskResultWatermark,
+ this.TaskResultResize,
+ this.Title,
+ this.TemplateId,
+ this.TemplateLabelId,
+ this.CreateTime,
+ this.Status,
+ this.Prompt,
+ this.UserNickName,
+ this.UserIocn,
+ this.IsMyLike,
+ this.SizeTemplateId,
+ this.LikeNum,
+ this.IsGalleyWork,
+ this.IsTalentWork,
+ this.IsFollow);
+
+ factory WorksInfoBean.fromJson(Map json) => _$WorksInfoBeanFromJson(json);
+
+ Map toJson() => _$WorksInfoBeanToJson(this);
+}
diff --git a/lib/bean/works_info_bean.g.dart b/lib/bean/works_info_bean.g.dart
new file mode 100644
index 0000000..ee8d0e3
--- /dev/null
+++ b/lib/bean/works_info_bean.g.dart
@@ -0,0 +1,64 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'works_info_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+WorksInfoBean _$WorksInfoBeanFromJson(Map json) {
+ return WorksInfoBean(
+ json['Id'] as int,
+ json['DrawId'] as int,
+ json['WorksId'] as int,
+ json['UserId'] as int,
+ json['AppId'] as int,
+ json['BossId'] as String,
+ json['TaskId'] as String,
+ json['TaskResult'] as String,
+ json['TaskResultWatermark'] as String,
+ json['TaskResultResize'] as String,
+ json['Title'] as String,
+ json['TemplateId'] as int,
+ json['TemplateLabelId'] as int,
+ json['CreateTime'] as String,
+ json['Status'] as int,
+ json['Prompt'] as String,
+ json['UserNickName'] as String,
+ json['UserIocn'] as String,
+ json['IsMyLike'] as bool,
+ json['SizeTemplateId'] as int,
+ json['LikeNum'] as int,
+ json['IsGalleyWork'] as bool,
+ json['IsTalentWork'] as bool,
+ json['IsFollow'] as bool,
+ );
+}
+
+Map _$WorksInfoBeanToJson(WorksInfoBean instance) =>
+ {
+ 'Id': instance.Id,
+ 'DrawId': instance.DrawId,
+ 'WorksId': instance.WorksId,
+ 'UserId': instance.UserId,
+ 'AppId': instance.AppId,
+ 'BossId': instance.BossId,
+ 'TaskId': instance.TaskId,
+ 'TaskResult': instance.TaskResult,
+ 'TaskResultWatermark': instance.TaskResultWatermark,
+ 'TaskResultResize': instance.TaskResultResize,
+ 'Title': instance.Title,
+ 'TemplateId': instance.TemplateId,
+ 'TemplateLabelId': instance.TemplateLabelId,
+ 'CreateTime': instance.CreateTime,
+ 'Status': instance.Status,
+ 'Prompt': instance.Prompt,
+ 'UserNickName': instance.UserNickName,
+ 'UserIocn': instance.UserIocn,
+ 'IsMyLike': instance.IsMyLike,
+ 'SizeTemplateId': instance.SizeTemplateId,
+ 'LikeNum': instance.LikeNum,
+ 'IsGalleyWork': instance.IsGalleyWork,
+ 'IsTalentWork': instance.IsTalentWork,
+ 'IsFollow': instance.IsFollow,
+ };
diff --git a/lib/bean/works_list_bean.dart b/lib/bean/works_list_bean.dart
new file mode 100644
index 0000000..ebea46e
--- /dev/null
+++ b/lib/bean/works_list_bean.dart
@@ -0,0 +1,16 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'works_list_bean.g.dart';
+
+@JsonSerializable()
+class WorksListBean {
+ int? WorkId;
+ String? WorkName;
+ bool? IsSelect;
+
+ WorksListBean(this.WorkId, this.WorkName, this.IsSelect);
+
+ factory WorksListBean.fromJson(Map json) => _$WorksListBeanFromJson(json);
+
+ Map toJson() => _$WorksListBeanToJson(this);
+}
diff --git a/lib/bean/works_list_bean.g.dart b/lib/bean/works_list_bean.g.dart
new file mode 100644
index 0000000..59c175f
--- /dev/null
+++ b/lib/bean/works_list_bean.g.dart
@@ -0,0 +1,22 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'works_list_bean.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+WorksListBean _$WorksListBeanFromJson(Map json) {
+ return WorksListBean(
+ json['WorkId'] as int?,
+ json['WorkName'] as String?,
+ json['IsSelect'] as bool?,
+ );
+}
+
+Map _$WorksListBeanToJson(WorksListBean instance) =>
+ {
+ 'WorkId': instance.WorkId,
+ 'WorkName': instance.WorkName,
+ 'IsSelect': instance.IsSelect,
+ };
diff --git a/lib/common/EventBusUtil.dart b/lib/common/EventBusUtil.dart
new file mode 100644
index 0000000..b3e6311
--- /dev/null
+++ b/lib/common/EventBusUtil.dart
@@ -0,0 +1,73 @@
+import 'dart:async';
+
+import 'package:event_bus/event_bus.dart';
+
+class EventBusUtil {
+ static EventBus? _eventBus;
+
+ //获取单例
+ static EventBus getInstance() {
+ _eventBus ??= EventBus();
+ return _eventBus!;
+ }
+
+ //返回某事件的订阅者
+ static StreamSubscription listen(Function(T event) onData) {
+ _eventBus ??= EventBus();
+ //内部流属于广播模式,可以有多个订阅者
+ return _eventBus!.on().listen(onData);
+ }
+
+ //发送事件
+ static void fire(T e) {
+ _eventBus ??= EventBus();
+ _eventBus!.fire(e);
+ }
+}
+
+abstract class Event {}
+
+class LoginEvent extends Event {
+ static int eventIn = 1;
+ static int eventOut = 0;
+ final int status;
+
+ LoginEvent(this.status);
+}
+
+class OrderStatusEvent extends Event {}
+
+class PushStatusEvent extends Event {}
+
+//导航切换
+class TabBarEvent extends Event {
+ final int Tab;
+
+ TabBarEvent(this.Tab);
+}
+
+class PhoneLoginBackEvent extends Event {
+ PhoneLoginBackEvent();
+}
+
+//导航跳转
+class TabBarJumpEvent extends Event {
+ int index;
+
+ TabBarJumpEvent(this.index);
+}
+
+//画同款
+class CopyDrawingEvent extends Event {
+ CopyDrawingEvent();
+}
+
+//登录完成
+class LoginSuccess extends Event {
+ LoginSuccess();
+}
+
+//刷新用户信息
+class RefreshUserdata extends Event {
+ RefreshUserdata();
+}
diff --git a/lib/common/Global.dart b/lib/common/Global.dart
new file mode 100644
index 0000000..b379b61
--- /dev/null
+++ b/lib/common/Global.dart
@@ -0,0 +1,55 @@
+
+import 'dart:io';
+
+import 'package:flutter/services.dart';
+import 'package:flutter/widgets.dart';
+
+import '../network/NetworkConfig.dart';
+
+const int Environment_Dev = 1;
+const int Environment_Pre = 2;
+const int Environment_Online = 3;
+
+class Global {
+ factory Global() => _getInstance();
+
+ static Global get instance => _getInstance();
+ static Global? _instance;
+
+ Global._internal() {
+ // 初始化
+ }
+
+ static Global _getInstance() {
+ if (_instance == null) {
+ _instance = new Global._internal();
+ }
+ return _instance!;
+ }
+
+ static const method = MethodChannel('samples.flutter.dev/battery');
+
+ static bool get isRelease => bool.fromEnvironment("dart.vm.product");
+ static String? flatform_name;
+
+ static Future initialize() async {
+ if (!NetworkConfig.isTest) {
+ NetworkConfig.BASE_URLS = NetworkConfig.BASE_URLS_AI;
+ }
+
+ if (Platform.isIOS) {
+ //ios相关代码
+ flatform_name = 'iOS';
+ } else if (Platform.isAndroid) {
+ //android相关代码
+ flatform_name = 'Android';
+ }
+ WidgetsFlutterBinding.ensureInitialized(); //不加这个强制横/竖屏会报错
+ SystemChrome.setPreferredOrientations([
+ // 强制竖屏
+ DeviceOrientation.portraitUp,
+ DeviceOrientation.portraitDown
+ ]);
+ Global a = Global.instance;
+ }
+}
diff --git a/lib/common/TabUnderLine.dart b/lib/common/TabUnderLine.dart
new file mode 100644
index 0000000..cc5c074
--- /dev/null
+++ b/lib/common/TabUnderLine.dart
@@ -0,0 +1,179 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/foundation.dart';
+// 默认高度从46改为40
+const double _kTabHeight = 50.0;
+const double _kTextAndIconTabHeight = 72.0;
+
+class RoundUnderlineTabIndicator extends Decoration {
+ /// Create an underline style selected tab indicator.
+ ///
+ /// The [borderSide] and [insets] arguments must not be null.
+ const RoundUnderlineTabIndicator({
+ this.borderSide = const BorderSide(width: 2.0, color: Colors.white),
+ this.insets = EdgeInsets.zero,
+ }) : assert(borderSide != null),
+ assert(insets != null);
+
+ /// The color and weight of the horizontal line drawn below the selected tab.
+ final BorderSide borderSide;
+
+ /// Locates the selected tab's underline relative to the tab's boundary.
+ ///
+ /// The [TabBar.indicatorSize] property can be used to define the
+ /// tab indicator's bounds in terms of its (centered) tab widget with
+ /// [TabIndicatorSize.label], or the entire tab with [TabIndicatorSize.tab].
+ final EdgeInsetsGeometry insets;
+
+ @override
+ Decoration? lerpFrom(Decoration? a, double t) {
+ if (a is UnderlineTabIndicator) {
+ return UnderlineTabIndicator(
+ borderSide: BorderSide.lerp(a.borderSide, borderSide, t),
+ insets: EdgeInsetsGeometry.lerp(a.insets, insets, t)!,
+ );
+ }
+ return super.lerpFrom(a, t);
+ }
+
+ @override
+ Decoration? lerpTo(Decoration? b, double t) {
+ if (b is UnderlineTabIndicator) {
+ return UnderlineTabIndicator(
+ borderSide: BorderSide.lerp(borderSide, b.borderSide, t),
+ insets: EdgeInsetsGeometry.lerp(insets, b.insets, t)!,
+ );
+ }
+ return super.lerpTo(b, t);
+ }
+
+ @override
+ _UnderlinePainter createBoxPainter([ VoidCallback? onChanged ]) {
+ return _UnderlinePainter(this, onChanged!);
+ }
+}
+
+class _UnderlinePainter extends BoxPainter {
+ _UnderlinePainter(this.decoration, VoidCallback onChanged)
+ : assert(decoration != null),
+ super(onChanged);
+
+ final RoundUnderlineTabIndicator decoration;
+
+ BorderSide get borderSide => decoration.borderSide;
+ EdgeInsetsGeometry get insets => decoration.insets;
+
+ Rect _indicatorRectFor(Rect rect, TextDirection textDirection) {
+ assert(rect != null);
+ assert(textDirection != null);
+ final Rect indicator = insets.resolve(textDirection).deflateRect(rect);
+// return Rect.fromLTWH(
+// indicator.left,
+// indicator.bottom - borderSide.width,
+// indicator.width,
+// borderSide.width,
+// );
+ //希望的宽度
+ double wantWidth = 17;
+ //取中间坐标
+ double cw = (indicator.left + indicator.right) / 2;
+ return Rect.fromLTWH(cw - wantWidth / 2,
+ indicator.bottom - borderSide.width, wantWidth, borderSide.width);
+ }
+
+ @override
+ void paint(Canvas canvas, Offset offset, ImageConfiguration? configuration) {
+ assert(configuration != null);
+ assert(configuration!.size != null);
+ final Rect rect = offset & configuration!.size!;
+ final TextDirection? textDirection = configuration.textDirection;
+ final Rect indicator = _indicatorRectFor(rect!, textDirection!).deflate(borderSide.width / 2.0);
+// final Paint paint = borderSide.toPaint()..strokeCap = StrokeCap.square;
+ // 改为圆角
+ final Paint paint = borderSide.toPaint()..strokeCap = StrokeCap.round;
+ canvas.drawLine(indicator.bottomLeft, indicator.bottomRight, paint);
+ }
+}
+
+
+
+
+
+
+class VgTab extends StatelessWidget {
+ /// Creates a material design [TabBar] tab.
+ ///
+ /// At least one of [text], [icon], and [child] must be non-null. The [text]
+ /// and [child] arguments must not be used at the same time.
+ const VgTab({
+ Key? key,
+ this.text,
+ this.icon,
+ this.child,
+ }) : assert(text != null || child != null || icon != null),
+ assert(!(text != null && null != child)), // TODO(goderbauer): https://github.com/dart-lang/sdk/issues/34180
+ super(key: key);
+
+ /// The text to display as the tab's label.
+ ///
+ /// Must not be used in combination with [child].
+ final String? text;
+
+ /// The widget to be used as the tab's label.
+ ///
+ /// Usually a [Text] widget, possibly wrapped in a [Semantics] widget.
+ ///
+ /// Must not be used in combination with [text].
+ final Widget? child;
+
+ /// An icon to display as the tab's label.
+ final Widget? icon;
+
+ Widget _buildLabelText() {
+ return child ?? Text(text!, softWrap: false, overflow: TextOverflow.fade);
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ assert(debugCheckHasMaterial(context));
+
+ double height;
+ Widget? label;
+ if (icon == null) {
+ height = _kTabHeight;
+ label = _buildLabelText();
+ } else if (text == null && child == null) {
+ height = _kTabHeight;
+ label = icon;
+ } else {
+ height = _kTextAndIconTabHeight;
+ label = Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Container(
+ child: icon,
+ margin: const EdgeInsets.only(bottom: 10.0),
+ ),
+ _buildLabelText(),
+ ],
+ );
+ }
+
+ return SizedBox(
+ height: height,
+ width: 30,
+ child: Center(
+ child: label,
+ widthFactor: 1.0,
+ ),
+ );
+ }
+
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ properties.add(StringProperty('text', text, defaultValue: null));
+ properties.add(DiagnosticsProperty('icon', icon, defaultValue: null));
+ }
+}
\ No newline at end of file
diff --git a/lib/common/app_util.dart b/lib/common/app_util.dart
new file mode 100644
index 0000000..071bf45
--- /dev/null
+++ b/lib/common/app_util.dart
@@ -0,0 +1,218 @@
+import 'dart:convert';
+import 'dart:io';
+import 'dart:math';
+
+import 'package:aiplot/network/NetworkConfig.dart';
+import 'package:cached_network_image/cached_network_image.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_cache_manager/flutter_cache_manager.dart';
+import 'package:flutter_easyloading/flutter_easyloading.dart';
+import 'package:http/http.dart' as http;
+import 'package:image_cropper/image_cropper.dart';
+import 'package:image_gallery_saver/image_gallery_saver.dart';
+import 'package:image_picker/image_picker.dart';
+import 'package:mime/mime.dart';
+import 'package:permission_handler/permission_handler.dart';
+
+class AppUtil {
+ /// 默认为下载网络图片,如需下载资源图片,需要指定 [isAsset] 为 `true`。
+ static Future saveImage(String imageUrl, {bool isAsset = false}) async {
+ try {
+ if (imageUrl == null) throw '保存失败,图片不存在!';
+
+ print(NetworkConfig.systemVersion);
+
+ /// 权限检测
+ PermissionStatus storageStatus;
+
+ ///android13及以上版本 "storage" 已废除 图片 视频 音频权限需要分别申请
+ if (int.parse(NetworkConfig.systemVersion) >= 13) {
+ storageStatus = await Permission.photos.status;
+ } else {
+ storageStatus = await Permission.storage.status;
+ }
+
+ if (storageStatus != PermissionStatus.granted) {
+ if (int.parse(NetworkConfig.systemVersion) >= 13) {
+ storageStatus = await Permission.photos.request();
+ } else {
+ storageStatus = await Permission.storage.request();
+ }
+ if (storageStatus != PermissionStatus.granted) {
+ throw '无法存储图片,请先授权!';
+ }
+ }
+
+ /// 保存的图片数据
+ Uint8List imageBytes;
+
+ if (isAsset == true) {
+ /// 保存资源图片
+ ByteData bytes = await rootBundle.load(imageUrl);
+ imageBytes = bytes.buffer.asUint8List();
+ } else {
+ Map map = {};
+
+ /// 保存网络图片
+ CachedNetworkImage image = CachedNetworkImage(imageUrl: imageUrl);
+ BaseCacheManager manager = image.cacheManager ?? DefaultCacheManager();
+ Map headers = image.httpHeaders != null ? image.httpHeaders! : map;
+ File file = await manager.getSingleFile(
+ image.imageUrl,
+ headers: headers,
+ );
+ imageBytes = await file.readAsBytes();
+ }
+
+ /// 保存图片
+ final result = await ImageGallerySaver.saveImage(imageBytes, quality: 100);
+
+ if (result == null || result == '') throw '图片保存失败';
+
+ EasyLoading.showToast("Successfully saved");
+ } catch (e) {
+ print(e.toString());
+ }
+ }
+
+ ///保存Widget图片
+ static Future saveWidgetImage(ByteData bytes) async {
+ try {
+ if (bytes == null) throw '保存失败,图片不存在!';
+
+ /// 权限检测
+ PermissionStatus storageStatus;
+
+ ///android13及以上版本 "storage" 已废除 图片 视频 音频权限需要分别申请
+ if (int.parse(NetworkConfig.systemVersion) >= 13) {
+ storageStatus = await Permission.photos.status;
+ } else {
+ storageStatus = await Permission.storage.status;
+ }
+
+ if (storageStatus != PermissionStatus.granted) {
+ if (int.parse(NetworkConfig.systemVersion) >= 13) {
+ storageStatus = await Permission.photos.request();
+ } else {
+ storageStatus = await Permission.storage.request();
+ }
+
+ if (storageStatus != PermissionStatus.granted) {
+ throw '无法存储图片,请先授权!';
+ }
+ }
+
+ Uint8List imageBytes = bytes.buffer.asUint8List();
+
+ /// 保存图片
+ final result = await ImageGallerySaver.saveImage(imageBytes, quality: 100);
+
+ if (result == null || result == '') throw '图片保存失败';
+
+ EasyLoading.showToast("Successfully saved");
+ } catch (e) {
+ print(e.toString());
+ }
+ }
+
+ //获取图片
+ static Future getImages() async {
+ final pkImage = await ImagePicker().pickImage(
+ source: ImageSource.gallery,
+ );
+ return pkImage!;
+ }
+
+ //裁剪
+ static cropImage(String path, int index) async {
+ double x = 1.0;
+ double y = 1.0;
+ switch (index) {
+ case 0:
+ x = 1.0;
+ y = 1.0;
+ break;
+ case 1:
+ x = 3.0;
+ y = 4.0;
+ break;
+ case 2:
+ x = 4.0;
+ y = 3.0;
+ break;
+ case 3:
+ x = 9.0;
+ y = 16.0;
+ break;
+ case 4:
+ x = 16.0;
+ y = 9.0;
+ break;
+ }
+ CroppedFile? croppedFile = await ImageCropper().cropImage(
+ sourcePath: path,
+ aspectRatioPresets: [
+ CropAspectRatioPreset.square, //1:1
+ ],
+ aspectRatio: CropAspectRatio(ratioX: x, ratioY: y),
+ uiSettings: [
+ IOSUiSettings(
+ title: 'Cropper',
+ aspectRatioLockEnabled: true,
+ resetAspectRatioEnabled: false,
+ ),
+ AndroidUiSettings(
+ toolbarTitle: 'Cropper',
+ toolbarColor: Color(0xFFBE6FDF),
+ toolbarWidgetColor: Colors.white,
+ activeControlsWidgetColor: Color(0xFFBE6FDF),
+ initAspectRatio: CropAspectRatioPreset.square,
+ lockAspectRatio: true,
+ ),
+ ],
+ );
+ return croppedFile;
+ }
+
+ //解析图片转base64
+ static uploadImage(XFile pickedFile) async {
+ var file = File(pickedFile.path);
+ String? type = lookupMimeType(pickedFile.path); //读取格式
+ Uint8List imageBytes = await file.readAsBytes();
+ String base64 = base64Encode(imageBytes);
+ return "data:$type;base64,$base64";
+ }
+
+ //解析图片转base64
+ static uploadImage2(File pickedFile) async {
+ String? type = lookupMimeType(pickedFile.path); //读取格式
+ Uint8List imageBytes = await pickedFile.readAsBytes();
+ String base64 = base64Encode(imageBytes);
+ return "data:$type;base64,$base64";
+ }
+
+ // 获取文件大小
+ static String getFileSizeString({int? bytes, int decimals = 0}) {
+ if (bytes! <= 0) return "0 Bytes";
+ const suffixes = [" Bytes", "KB", "MB", "GB", "TB"];
+ var i = (log(bytes) / log(1024)).floor();
+ return ((bytes / pow(1024, i)).toStringAsFixed(decimals)) + suffixes[i];
+ }
+
+ // 获取文件大小(mb)
+ static double getFileSizeDouble({int? bytes, int decimals = 0}) {
+ final kb = bytes! / 1024;
+ final mb = kb / 1024;
+ print("object===$mb");
+ return mb;
+ }
+
+ ///网络图片转base64
+ static Future networkImageToBase64(String imageUrl) async {
+ http.Response response = await http.get(Uri.parse(imageUrl));
+ final bytes = response.bodyBytes;
+ print("bytes===$bytes");
+ return bytes != null ? base64Encode(bytes) : null;
+ }
+}
diff --git a/lib/common/dialog_bean.dart b/lib/common/dialog_bean.dart
new file mode 100644
index 0000000..cbcdc5c
--- /dev/null
+++ b/lib/common/dialog_bean.dart
@@ -0,0 +1,105 @@
+
+
+import 'package:flutter/cupertino.dart';
+
+typedef CreateDialogWidget = Widget Function();
+
+/// @desc 弹窗数据类
+class DialogBean {
+ ///dialog唯一标识,通过 DialogBean 数据内容生成 Md5生成
+ late String dialogId;
+
+ ///当前 dialog,显示的视图。如果为空,则在顶层页面
+ String? pageRouter;
+
+ ///当前 pageRouter 对应的子页面
+ List? innerPageRouters;
+
+ ///优先级、用于显示弹窗前排序,
+ ///但对于加入的弹窗,已经显示的情况
+ ///[highClear] 清除已显示的弹窗,直接显示当前弹窗,该属性慎用
+ ///[high] 回收当前已显示的弹窗,再显示高优先级弹窗,该属性慎用
+ DialogPriority dialogPriority;
+
+ ///用于排序
+ late int priority;
+
+ ///弹窗内部业务 widget,每次show 时动态创建。不能直接传创建好的 widget,因为在 high回收时,调用 pop 再 show 会出现 The following NoSuchMethodError was thrown building Builder(dirty):
+ CreateDialogWidget? createDialogWidget;
+
+ ///弹窗类型
+ DialogType? dialogType;
+
+ DialogBean({
+ this.pageRouter,
+ this.innerPageRouters,
+ this.dialogPriority = DialogPriority.normal,
+ this.dialogType = DialogType.dialog,
+ @required this.createDialogWidget,
+ }) : super() {
+ assert(createDialogWidget!().key != null);
+ dialogId = (createDialogWidget!().key as ValueKey).value;
+ switch (dialogPriority) {
+ case DialogPriority.highClearAll:
+ priority = 30;
+ pageRouter = null;
+ break;
+ case DialogPriority.highClear:
+ priority = 20;
+ pageRouter = null;
+ break;
+ case DialogPriority.high:
+ priority = 10;
+ break;
+ case DialogPriority.normal:
+ priority = 1;
+ break;
+ case DialogPriority.low:
+ priority = 0;
+ break;
+ }
+ //如果内页不空,则 pageRouter不能为空
+ if (innerPageRouters != null) {
+ assert(pageRouter != null);
+ }
+ }
+
+ ///是否为高优先级,带清除功能的
+ bool isHighClear() {
+ return dialogPriority == DialogPriority.highClear ||
+ dialogPriority == DialogPriority.highClearAll;
+ }
+
+ @override
+ String toString() {
+ return 'DialogBean{dialogId: $dialogId, pageRouter: $pageRouter, innerPageRouters: $innerPageRouters, priority: $priority, dialogType: $dialogType}';
+ }
+}
+
+enum DialogType {
+ ///弹窗
+ dialog,
+
+ ///底部弹窗
+ bottomSheet,
+
+ ///底部可滑动弹窗
+ bottomScrollSheet,
+}
+
+enum DialogPriority {
+ ///最高优先级,清除其它----所有弹窗(例如强制升级弹窗)
+ highClearAll,
+
+ ///高优先级弹窗,清除其它弹窗不包括highClearAll(登录超时、多终端登录)
+ highClear,
+
+ ///高优先级弹窗,回收normal弹窗,优先显示(指纹引导弹窗、提交请求弹窗)
+ high,
+
+ ///默认弹窗,按顺序弹出
+ normal,
+
+ ///低优先级弹窗,按顺序弹出
+ low,
+}
diff --git a/lib/common/dialog_manager.dart b/lib/common/dialog_manager.dart
new file mode 100644
index 0000000..d3afde5
--- /dev/null
+++ b/lib/common/dialog_manager.dart
@@ -0,0 +1,309 @@
+
+import 'package:flutter/material.dart';
+
+import 'dialog_bean.dart';
+import 'navigator_manager.dart';
+
+/// @desc 统一弹窗(包含 showDialog、showModalBottomSheet)
+class DialogManager {
+ // 工厂模式 : 单例公开访问点
+ factory DialogManager() => _getInstance()!;
+
+// static DialogManager get instance => _getInstance();
+
+ // 静态私有成员,没有初始化
+ static DialogManager? _instance;
+
+ ///弹窗数据(待显示)
+ late List _dialogList;
+
+// ///当前正在显示的弹窗
+// DialogBean showDialogBean;
+
+ ///已显示过或正在显示的弹窗数据,还未被回调清除
+ ///已经显示过的弹窗,不能用一个DialogBean
+ ///(因为showDialogBean在对话 pop 是会赋为空,一个正要显示,一个取消的回调过来又重新给设为空了。)
+ late List _hasShowDialogList;
+
+ ///是否有系统弹窗正在显示,例如系统权限申请弹窗
+ late bool isSystemDialogShowing;
+
+ // 私有构造函数
+ DialogManager._internal() {
+ // 初始化
+ _dialogList = [];
+ _hasShowDialogList = [];
+ isSystemDialogShowing = false;
+ }
+
+ // 静态、同步、私有访问点
+ static DialogManager? _getInstance() {
+ if (_instance == null) {
+ _instance = DialogManager._internal();
+ }
+ return _instance;
+ }
+
+ ///高优先级,回收取消正在显示的弹窗
+ static const String popRecycle = "popRecycle";
+
+ ///其它地方触发取消正在显示的调窗,且不自动显示下一个
+ static const String popRecycleAndNotNext = "popRecycleAndNotNext";
+
+ ///取消弹窗,但不自动显示下一个
+ static const String popNotNext = "popNotNext";
+
+ ///增加弹窗
+ void add(DialogBean bean) {
+ print("dialog add ${bean.dialogId}");
+ //对于 highClear 和 highClearAll则加入时要清掉其它低优先级弹窗,必须放在 show 前。假如在 add中,可能低优先级的在后台添加的
+ switch (bean.dialogPriority) {
+ case DialogPriority.highClear:
+ case DialogPriority.highClearAll:
+ //移除其它低优先级弹窗数据,(不清除正显示的。在 show 里面再清除&& !hasShow(item.dialogId),也可以在后台处理)
+ _dialogList.removeWhere((item) => item.priority < bean.priority);
+ break;
+ default:
+ break;
+ }
+ //去掉重复弹窗(待显示的与顶层正在显示的弹窗)
+
+ bool hasDialog = _getAllDialogBean().any((dialogBean) => bean.dialogId == dialogBean.dialogId);
+
+ //没有重复的,且栈中没有 highClear 等优先级的弹窗,或者 clearBean小于等于bean.priority
+ if (!hasDialog) {
+ DialogBean? clearBean = _getHighClearDialogBean();
+ if (clearBean == null || bean.priority >= clearBean.priority) {
+ _dialogList.add(bean);
+ }
+ }
+ //根据优先级进行排序:降序
+ _dialogList.sort((a, b) => b.priority.compareTo(a.priority));
+ }
+
+ ///显示弹窗,不能返回 Future,不然在同时 show两次时重叠 DialogManager()..add()..show;DialogManager()..add()..show;
+ void show(BuildContext context) {
+ print("dialog show $_dialogList");
+ //如果有系统弹窗正在显示,则不显示
+ if (isSystemDialogShowing) {
+ return;
+ }
+
+ //如果待显示数组为空
+ if (_dialogList.isEmpty) {
+ return;
+ }
+
+ //对于 highClean 和 highCleanAll则加入时要清掉其它低优先级弹窗,必须放在 show 前。假如在 add中,可能低优先级的在后台添加的
+// if (bean != null) {
+// //移除其它低优先级弹窗数据
+// _dialogList.removeWhere((item) => item.priority < bean.priority);
+// }
+
+ //已经有正在显示的弹窗且是在栈顶层显示(showDialogBean != null && 不能加入此判断,在显示强升时碰到的,因为showDialogBean在对话 pop 是会赋为空。所以导致这里不准,一个正在显示,一个取消的回调过来又重新给设为空了。)
+ if (NavigatorManager().isTopDialog() && _hasShowDialogList.isNotEmpty) {
+ DialogBean? hasShowDialogBean = getShowingDialog();
+ print("当前有正在显示的弹窗$hasShowDialogBean");
+ DialogBean? bean;
+ //已有显示的弹窗,且high 弹窗在当前页显示,且已显示的弹窗优先级低于high级弹窗
+ //highClear 和 highClearAll 不用管显示页面 所以不要这个判断,这里_getHighClearDialogBean取所有的(包括正在显示的)
+ if ((bean = _getHighClearDialogBean(beans: _dialogList)) != null && _canShow(bean) && (hasShowDialogBean!.priority < bean!.priority)) {
+ //如果当前加入的弹窗是 highClear,则清掉所有弹窗(包括当前正在显示的,以及未显示的)
+ print("清除正在显示的弹窗${bean.dialogPriority}");
+ Navigator.pop(context);
+ } else if (((bean = _getDialogBeanByPriority(DialogPriority.high, beans: _dialogList)) != null ||
+ (bean = _getDialogBeanByPriority(DialogPriority.normal, beans: _dialogList)) != null) && //已有显示的弹窗,且high 弹窗在当前页显示,且已显示的弹窗优先级低于high级弹窗
+ _canShow(bean) &&
+ hasShowDialogBean!.priority < bean!.priority) {
+ //如果当前加入的弹窗是 high,则回收当前正在显示的弹窗。
+ print("回收正在显示的弹窗${bean.dialogPriority}");
+ Navigator.pop(context, popRecycle);
+ //不能在这里把弹窗直接回收,因为在使用 pop 会调用whenComplete会清掉当前显示的弹窗。所以要到whenComplete 中去处理
+ }
+ return;
+ }
+ //查找当前页面可显示的弹窗数据
+ DialogBean showDialogBean;
+ try {
+ showDialogBean = _dialogList.firstWhere((bean) => _canShow(bean));
+ _hasShowDialogList.add(showDialogBean);
+ //新从数组中移动,因为回调中再移动可能会出现提交成功后显示一个提示框,导致一直显示提交框,不会消失
+ _dialogList.remove(showDialogBean);
+ print("显示的dialog =$showDialogBean");
+ switch (showDialogBean.dialogType!) {
+ case DialogType.dialog:
+ showDialog(
+ context: context,
+ barrierDismissible: false,
+ builder: (BuildContext context) {
+ return showDialogBean.createDialogWidget!();
+ },
+ ).then((obj) {
+ _handlePopResult(context, obj);
+ });
+ break;
+ case DialogType.bottomSheet:
+ showModalBottomSheet(
+ backgroundColor: Color(0x00FFFFFF),
+ context: context,
+ isDismissible: false,
+ enableDrag: false,
+ isScrollControlled: true,
+ builder: (BuildContext context) {
+ return showDialogBean.createDialogWidget!();
+ },
+ ).then((obj) {
+ _handlePopResult(context, obj);
+ });
+ break;
+ case DialogType.bottomScrollSheet:
+ showModalBottomSheet(
+ backgroundColor: Color(0x00FFFFFF),
+ context: context,
+ isScrollControlled: true,
+ builder: (BuildContext context) {
+ return showDialogBean.createDialogWidget!();
+ },
+ ).then((obj) {
+ _handlePopResult(context, obj);
+ });
+ break;
+ }
+ } catch (e) {
+ //没有找到可显示的弹窗
+ }
+
+ }
+
+ void _handlePopResult(BuildContext context, dynamic obj) {
+ //取消第一个
+ DialogBean dismissBean = _hasShowDialogList[0];
+ print("消失的dialog =$dismissBean,接收回调结果:$obj");
+ //取消第一个
+ _hasShowDialogList.remove(dismissBean);
+ //如果是从 high 弹窗回收或外部手动 pop的话,则重新添加回数组
+ if (obj == popRecycle || obj == popRecycleAndNotNext) {
+ _dialogList.add(dismissBean);
+ }
+ // widget 中可能会先 pop ,再 push,这里显示下一个时,通过顶层路由来判断,不能通过当前显示的页面来判断。
+ if (obj != popRecycleAndNotNext && obj != popNotNext) {
+ show(context);
+ }
+ }
+
+ ///弹窗是否正在显示
+ bool isShowing(String? dialogId) {
+ DialogBean? dialogBean = getShowingDialog();
+ if (dialogBean != null && dialogId == dialogBean.dialogId) {
+ return true;
+ }
+ return false;
+ }
+
+ ///取得在正显示的弹窗
+ DialogBean? getShowingDialog() {
+ if (_hasShowDialogList.isNotEmpty && NavigatorManager().isTopDialog()) {
+ return _hasShowDialogList[_hasShowDialogList.length - 1];
+ }
+ return null;
+ }
+
+ ///显示系统弹窗,必须与 dismiss 成对使用
+ void showSystemDialog(BuildContext context) {
+ //回收正在显示的弹窗
+ pop(context, result: popRecycleAndNotNext);
+ //正在显示系统弹窗
+ isSystemDialogShowing = true;
+ }
+
+ ///隐藏系统弹窗,必须与 show 成对使用
+ void dismissSystemDialog(BuildContext context) {
+ //正在显示系统弹窗
+ isSystemDialogShowing = false;
+ //系统弹窗消失,续续显示其它弹窗
+ show(context);
+ }
+
+ ///弹窗栈中是否此弹窗
+ bool hasShow(String dialogId) {
+ return _dialogList.any((bean) => dialogId == bean.dialogId);
+ }
+
+ ///清除已经显示的弹窗,系统权限弹窗时回收到其它弹窗
+ ///[result] 默认回收弹窗,不显示下一个
+ void pop(BuildContext context, {String? result}) {
+ if (_hasShowDialogList.isNotEmpty && NavigatorManager().isTopDialog()) {
+ Navigator.pop(context, result);
+ }
+ }
+
+ ///清除已经显示的弹窗,系统权限弹窗时回收到其它弹窗
+ ///[result] 默认回收弹窗,不显示下一个
+ void popByDialogId(BuildContext context, String dialogId, {String? result}) {
+ if (isShowing(dialogId)) {
+ Navigator.pop(context, result);
+ }
+ }
+
+ ///清除已经显示的弹窗或待显示的弹窗,例如登录超时打开登录时、或者退出登录
+ void popAndClear(BuildContext context) {
+ //如果没有 highClear或 highClearAll.
+ DialogBean? dialogBean = _getHighClearDialogBean();
+ if (dialogBean == null) {
+ _dialogList.clear();
+ pop(context, result: popNotNext);
+ }
+ }
+
+ ///是否可显示,未指定页面,或者指定的页面在顶层
+ bool _canShow(DialogBean? dialogBean) {
+ if (dialogBean == null) {
+ return false;
+ }
+ String? pageRouter = dialogBean.pageRouter;
+ //指定的页面在顶层
+ return isEmpty(pageRouter) || NavigatorManager().isTopRouter(pageRouter!);
+ }
+
+ ///按取得 clear 其它弹窗优先级的弹窗 bean
+ DialogBean? _getHighClearDialogBean({List? beans}) {
+ DialogBean? bean = _getDialogBeanByPriority(DialogPriority.highClearAll, beans: beans);
+ if (bean != null) {
+ return bean;
+ }
+ bean = _getDialogBeanByPriority(DialogPriority.highClear, beans: beans);
+ if (bean != null) {
+ return bean;
+ }
+ return null;
+ }
+
+ ///按弹窗优先级获取弹窗(默认包括待显示的及正在显示的)
+ DialogBean? _getDialogBeanByPriority(DialogPriority priority, {List? beans}) {
+ try {
+ return (beans ?? _getAllDialogBean()).firstWhere(
+ (bean) => priority == bean.dialogPriority,
+ );
+ } catch (e) {
+ return null;
+ }
+ /*return (beans ?? _getAllDialogBean()).firstWhereOrNull(
+ (bean) => priority == bean.dialogPriority,
+ );*/
+ }
+
+ ///取得所有弹窗,包括待显示及正在显示的弹窗
+ List _getAllDialogBean() {
+ List all = [];
+ DialogBean? showingDialogBean = getShowingDialog();
+ if (getShowingDialog() != null) {
+ all.add(showingDialogBean!);
+ }
+ all.addAll(_dialogList);
+ return all;
+ }
+
+ bool isEmpty(String? s) {
+ return s == null || s.isEmpty;
+ }
+}
diff --git a/lib/common/dialog_util.dart b/lib/common/dialog_util.dart
new file mode 100644
index 0000000..a83fbc9
--- /dev/null
+++ b/lib/common/dialog_util.dart
@@ -0,0 +1,34 @@
+import 'dart:convert';
+
+import 'package:convert/convert.dart';
+import 'package:crypto/crypto.dart';
+import 'package:flutter/material.dart';
+
+/// @desc 弹窗 widget 统一创建类
+/// @time 2019-11-06 09:42
+/// @author Cheney
+class DialogUtil {
+ ///对话框提示显示
+ ///[id] 同一对话框唯一标识
+ static Widget createTipWidget(BuildContext context, Widget dialog, String message,
+ {String? id, bool hasTips = true, bool canceled = true, String? cancelText, String? confirmText, final Function? onTap
+ /* OnCancelListener onCancelListener,
+ OnConfirmListener onConfirmListener,*/
+ }) {
+ return WillPopScope(key: ValueKey(id ?? generateId("createTipWidget$message")), child: dialog, onWillPop: () async => canceled);
+ }
+
+ ///生成对话框 id
+ static String generateId(String txt) {
+ assert(txt != null);
+ return generateMd5(txt);
+ }
+
+ /// md5 加密
+ static String generateMd5(String data) {
+ var content = Utf8Encoder().convert(data);
+ var digest = md5.convert(content);
+ // 这里其实就是 digest.toString()
+ return hex.encode(digest.bytes);
+ }
+}
diff --git a/lib/common/func.dart b/lib/common/func.dart
new file mode 100644
index 0000000..c993f40
--- /dev/null
+++ b/lib/common/func.dart
@@ -0,0 +1,59 @@
+import 'package:flutter/material.dart';
+
+class FunctionUtil {
+ static BuildContext? dialogContext;
+
+ //显示中间弹窗
+ static void popDialog(BuildContext context, Widget widget) {
+ showDialog(
+ context: context,
+ barrierDismissible: true,
+ builder: (BuildContext context) {
+ dialogContext = context;
+ return widget;
+ });
+ }
+
+ //显示底部弹窗
+ static void bottomSheetDialog(BuildContext context, Widget widget) {
+ showModalBottomSheet(
+ backgroundColor: const Color(0x00FFFFFF),
+ context: context,
+ /* isDismissible: false,*/
+ isScrollControlled: true,
+ builder: (BuildContext context) {
+ dialogContext = context;
+ return widget;
+ },
+ );
+ }
+
+ //显示底部弹窗
+ static void bottomNoSheetDialog(BuildContext context, Widget widget) {
+ showModalBottomSheet(
+ backgroundColor: Color(0x00FFFFFF),
+ context: context,
+ isDismissible: false,
+ isScrollControlled: true,
+ enableDrag: false,
+ builder: (BuildContext context) {
+ dialogContext = context;
+ return WillPopScope(onWillPop: () async => false, child: widget);
+ });
+ }
+
+ //返回上一级
+ static void pop() {
+ Navigator.pop(dialogContext!);
+ }
+
+ //push到下一级
+ static Future push(BuildContext context, Widget widget) {
+ return Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => widget,
+ ),
+ );
+ }
+}
diff --git a/lib/common/my_navigator_observers.dart b/lib/common/my_navigator_observers.dart
new file mode 100644
index 0000000..b7eba2c
--- /dev/null
+++ b/lib/common/my_navigator_observers.dart
@@ -0,0 +1,39 @@
+import 'package:common_utils/common_utils.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+
+import 'navigator_manager.dart';
+
+/// @desc: 导航监听
+
+class MyNavigatorObserver extends NavigatorObserver {
+ @override
+ void didPush(Route route, Route? previousRoute) {
+ LogUtil.v("didPush router : $route | previousRoute: $previousRoute");
+ NavigatorManager().addRouter(route);
+ }
+
+ @override
+ void didPop(Route route, Route? previousRoute) {
+ LogUtil.v("didPop router : $route | previousRoute: $previousRoute");
+
+ NavigatorManager().removeRouter(route);
+
+ }
+
+ @override
+ void didRemove(Route route, Route? previousRoute) {
+ LogUtil.v("didRemove router : $route | previousRoute: $previousRoute");
+
+ NavigatorManager().removeRouter(route);
+
+ }
+
+ @override
+ void didReplace({Route? newRoute, Route? oldRoute}) {
+ LogUtil.v("didReplace router : $newRoute | previousRoute: $oldRoute");
+
+ NavigatorManager().replaceRouter(newRoute!, oldRoute!);
+
+ }
+}
diff --git a/lib/common/navigator_manager.dart b/lib/common/navigator_manager.dart
new file mode 100644
index 0000000..d9efd3f
--- /dev/null
+++ b/lib/common/navigator_manager.dart
@@ -0,0 +1,61 @@
+import 'package:flutter/material.dart';
+
+typedef OnInterceptor = Function(bool isInterceptor);
+
+/// 导航管理
+class NavigatorManager {
+ ///所有路由栈,包括弹窗与页面
+ List? _history;
+
+ static final NavigatorManager _instance = NavigatorManager._internal();
+
+ factory NavigatorManager() => _instance;
+
+ NavigatorManager? _bus;
+
+ NavigatorManager._internal() {
+ if (_bus == null) {
+ _history = [];
+ }
+ }
+
+ ///通过拦截器增加 push router
+ void addRouter(Route route) {
+ _history?.add(route);
+ }
+
+ ///通过拦截器移动 push router
+ void removeRouter(Route route) {
+ _history?.remove(route);
+ }
+
+ ///通过拦截器移动 push router
+ void replaceRouter(Route newRoute, Route oldRoute) {
+ _history?.remove(oldRoute);
+ _history?.add(newRoute);
+ }
+
+ List? get history => _history;
+
+ ///是否顶层路由为页面,或者还未显示,正在压入栈
+ bool isTopRouter(String routerName) {
+ if (_history!.isEmpty) {
+ return false;
+ }
+ int i = _history!.length - 1;
+ Route route = _history![i];
+ while (route.settings == null && i >= 0) {
+ i--;
+ route = _history![i];
+ }
+ return route.settings.name != null && route.settings.name == routerName;
+ }
+
+ ///是否顶层路由为弹窗(包括showBottomSheet),或者还未显示,正在压入栈
+ bool isTopDialog() {
+ if (_history!.isEmpty) {
+ return false;
+ }
+ return _history![_history!.length - 1].settings.name == null;
+ }
+}
diff --git a/lib/dialog/ad_free_dialog.dart b/lib/dialog/ad_free_dialog.dart
new file mode 100644
index 0000000..53aedb2
--- /dev/null
+++ b/lib/dialog/ad_free_dialog.dart
@@ -0,0 +1,136 @@
+import 'package:aiplot/network/NetworkConfig.dart';
+import 'package:cached_network_image/cached_network_image.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_easyloading/flutter_easyloading.dart';
+import 'package:ironsource_mediation/ironsource_mediation.dart';
+
+import '../generated/l10n.dart';
+
+///删除图片提示
+class AdFreeDialog extends StatefulWidget {
+ Function onTap;
+
+ AdFreeDialog({required this.onTap});
+
+ @override
+ State createState() => _AdFreeDialogState();
+}
+
+class _AdFreeDialogState extends State {
+ @override
+ Widget build(BuildContext context) {
+ final size = MediaQuery.of(context).size;
+ final w314 = size.width / 1.1464968152866;
+ final h343 = size.width / 1.0495626822157;
+ final h75 = size.width / 4.8;
+ final t40 = size.width / 9;
+ final w85 = size.width / 4.235294117647;
+ final h45 = size.width / 8;
+ final t143 = size.width / 2.5174825174825;
+ final w283 = size.width / 1.2720848056537;
+ final t235 = size.width / 1.531914893617;
+ return Material(
+ type: MaterialType.transparency, //透明类型
+ color: const Color(0x00000000),
+ child: Center(
+ child: Stack(
+ alignment: Alignment.center,
+ children: [
+ CachedNetworkImage(
+ fit: BoxFit.fitHeight,
+ width: w314,
+ height: h343,
+ imageUrl: NetworkConfig.appConfigBean!.AdFree!.BackgroundImage!,
+ errorWidget: (context, url, error) => Image(
+ fit: BoxFit.fitWidth,
+ width: w314,
+ height: h343,
+ image: AssetImage('assets/images/ad_free_bg.png'),
+ ),
+ ),
+ Positioned(
+ top: t143,
+ child: GestureDetector(
+ onTap: () {
+ Navigator.pop(context);
+ if (NetworkConfig.appConfigBean!.AdFree!.BtnAction == "mall") {
+ Navigator.pushNamed(context, "/ShopPage");
+ }
+ },
+ child: CachedNetworkImage(
+ fit: BoxFit.fitHeight,
+ width: w283,
+ imageUrl: NetworkConfig.appConfigBean!.AdFree!.BtnImage!,
+ errorWidget: (context, url, error) => const Icon(Icons.error),
+ ),
+ ),
+ ),
+
+ ///看广告
+ Positioned(
+ top: t235,
+ child: GestureDetector(
+ onTap: () {
+ if (NetworkConfig.usedRewardCount != NetworkConfig.totalRewardCount) {
+ if (NetworkConfig.isAdAvailable) {
+ Navigator.pop(context);
+ IronSource.showRewardedVideo();
+ } else {
+ EasyLoading.showToast(S.of(context).no_advertisements);
+ }
+ } else {
+ EasyLoading.showToast(S.of(context).received_all);
+ }
+ },
+ child: Container(
+ height: h75,
+ width: w283,
+ decoration: const BoxDecoration(
+ color: Color(0xFFF8F8FF),
+ borderRadius: BorderRadius.all(Radius.circular(7)),
+ ),
+ margin: const EdgeInsets.only(left: 15, right: 15),
+ child: Stack(
+ children: [
+ Positioned(
+ top: 20,
+ left: 10,
+ child: Text(
+ "${S.of(context).Watch_the} (${NetworkConfig.usedRewardCount}/${NetworkConfig.totalRewardCount})",
+ style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
+ ),
+ ),
+ Positioned(
+ top: t40,
+ left: 10,
+ child: Text(
+ S.of(context).Earn_paint,
+ style: TextStyle(fontSize: 10, color: Color(0xFF999999)),
+ ),
+ ),
+ Positioned(
+ right: 4,
+ top: 18,
+ child: Stack(
+ alignment: Alignment.center,
+ children: [
+ Image(width: w85, height: h45, image: AssetImage('assets/images/view_ad.png')),
+ Positioned(
+ top: 10,
+ child: Text(
+ S.of(context).Watch,
+ style: TextStyle(fontSize: 14, color: Colors.white),
+ ))
+ ],
+ ))
+ ],
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/dialog/delete_img.dart b/lib/dialog/delete_img.dart
new file mode 100644
index 0000000..a4ca6f8
--- /dev/null
+++ b/lib/dialog/delete_img.dart
@@ -0,0 +1,102 @@
+import 'package:flutter/material.dart';
+
+import '../generated/l10n.dart';
+
+///删除图片提示
+class DeleteImg extends StatefulWidget {
+ Function onTap;
+
+ DeleteImg({required this.onTap});
+
+ @override
+ State createState() => _DeleteImgState();
+}
+
+class _DeleteImgState extends State {
+ @override
+ Widget build(BuildContext context) {
+ final size = MediaQuery.of(context).size;
+ final h260 = size.width / 1.3846153846153; //120
+ return Material(
+ type: MaterialType.transparency, //透明类型
+ color: const Color(0x00000000),
+ child: Container(
+ alignment: Alignment.center,
+ child: Container(
+ width: double.infinity,
+ margin: EdgeInsets.only(left: 16, right: 16),
+ decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(13))),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Container(
+ margin: EdgeInsets.only(top: 27),
+ child: Text(
+ S.of(context).Tip,
+ style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
+ ),
+ ),
+ Container(
+ margin: EdgeInsets.only(top: 27),
+ child: Text(
+ S.of(context).Are_you_sure,
+ textAlign: TextAlign.center,
+ style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
+ ),
+ ),
+ Container(
+ margin: EdgeInsets.only(top: 38, left: 23, right: 23, bottom: 36),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GestureDetector(
+ onTap: () {
+ // widget.onTap(0);
+ Navigator.pop(context);
+ },
+ child: Container(
+ width: 132,
+ height: 37,
+ alignment: Alignment.center,
+ decoration: BoxDecoration(
+ color: Color(0xFFEEE3FF),
+ borderRadius: BorderRadius.all(Radius.circular(7)),
+ ),
+ child: Text(
+ S.of(context).Cancel,
+ style: TextStyle(color: Color(0xFF8841FF)),
+ ),
+ ),
+ ),
+ GestureDetector(
+ onTap: () {
+ Navigator.pop(context);
+ widget.onTap(1);
+ },
+ child: Container(
+ width: 132,
+ height: 37,
+ alignment: Alignment.center,
+ decoration: const BoxDecoration(
+ gradient: LinearGradient(
+ begin: Alignment.centerLeft, //渐变开始于上面的中间开始
+ end: Alignment.centerRight, //渐变结束于下面的中间
+ colors: [Color(0xFF843FFF), Color(0xFFE975FF)]),
+ borderRadius: BorderRadius.all(Radius.circular(7)),
+ ),
+ child: Text(
+ S.of(context).Sure,
+ style: TextStyle(color: Colors.white),
+ ),
+ ),
+ ),
+ ],
+ ),
+ )
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/dialog/free_upper_limit_dialog.dart b/lib/dialog/free_upper_limit_dialog.dart
new file mode 100644
index 0000000..b27ddba
--- /dev/null
+++ b/lib/dialog/free_upper_limit_dialog.dart
@@ -0,0 +1,107 @@
+import 'package:flutter/material.dart';
+
+import '../generated/l10n.dart';
+
+///免费保存上限
+class FreeUpperLimitDialog extends StatefulWidget {
+ Function onTap;
+
+ FreeUpperLimitDialog({Key? key, required this.onTap}) : super(key: key);
+
+ @override
+ State createState() => _FreeUpperLimitDialogState();
+}
+
+class _FreeUpperLimitDialogState extends State {
+ @override
+ Widget build(BuildContext context) {
+ final size = MediaQuery.of(context).size;
+ final h20 = size.width / 18; //20
+ final b25 = size.width / 14.4; //25
+ final t30 = size.width / 12; //30
+ final t27 = size.width / 13.33333333; //27
+ final w132 = size.width / 2.7272727272; //132
+ final h37 = size.width / 9.7297297297; //37
+ return Material(
+ type: MaterialType.transparency, //透明类型
+ color: const Color(0x00000000),
+ child: Container(
+ alignment: Alignment.center,
+ child: Container(
+ margin: EdgeInsets.only(left: 15, right: 15),
+ padding: EdgeInsets.only(left: h20, right: h20, bottom: b25),
+ decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(13))),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Container(
+ margin: EdgeInsets.only(top: t30),
+ child: Text(
+ S.of(context).Save_picture,
+ style: TextStyle(fontSize: h20),
+ ),
+ ),
+ Container(
+ margin: EdgeInsets.only(top: h20),
+ child: Text(
+ S.of(context).Free_users,
+ style: TextStyle(fontSize: 14),
+ ),
+ ),
+ Container(
+ margin: EdgeInsets.only(top: 10),
+ child: Text(
+ S.of(context).More_pictures,
+ style: TextStyle(fontSize: 14),
+ ),
+ ),
+ Container(
+ margin: EdgeInsets.only(top: t27, bottom: 10),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GestureDetector(
+ onTap: () {
+ Navigator.pop(context);
+ },
+ child: Container(
+ width: w132,
+ height: h37,
+ alignment: Alignment.center,
+ decoration: BoxDecoration(color: Color(0xFFEEE3FF), borderRadius: BorderRadius.all(Radius.circular(7))),
+ child: Text(
+ S.of(context).Cancel,
+ style: TextStyle(color: Color(0xFF8841FF)),
+ ),
+ ),
+ ),
+ GestureDetector(
+ onTap: () {
+ Navigator.pop(context);
+ widget.onTap(1);
+ },
+ child: Container(
+ width: w132,
+ height: h37,
+ alignment: Alignment.center,
+ decoration: const BoxDecoration(
+ gradient: LinearGradient(
+ begin: Alignment.centerLeft, //渐变开始于上面的中间开始
+ end: Alignment.centerRight, //渐变结束于下面的中间
+ colors: [Color(0xFF808EEF), Color(0xFFBE6FDF)]),
+ borderRadius: BorderRadius.all(Radius.circular(7))),
+ child: Text(
+ S.of(context).to_pay,
+ style: TextStyle(color: Colors.white),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ )));
+ }
+}
diff --git a/lib/dialog/guideDialog.dart b/lib/dialog/guideDialog.dart
new file mode 100644
index 0000000..d3ad3c9
--- /dev/null
+++ b/lib/dialog/guideDialog.dart
@@ -0,0 +1,231 @@
+import 'package:flutter/material.dart';
+
+import '../generated/l10n.dart';
+
+class guideDialog extends StatefulWidget {
+ // 点击返回index 0 1
+ Function onTap;
+ final String name;
+ final List list;
+ final List selectList;
+
+ guideDialog({Key? key, required this.onTap, required this.name, required this.list, required this.selectList}) : super(key: key);
+
+ @override
+ _guideDialogState createState() => _guideDialogState();
+}
+
+class _guideDialogState extends State {
+ List selectList = [];
+
+ @override
+ void initState() {
+ // TODO: implement initState
+ super.initState();
+ if (widget.selectList != null && widget.selectList.isNotEmpty) {
+ selectList = widget.selectList;
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final size = MediaQuery.of(context).size;
+ final h328 = size.width / 1.097561;
+ final h564 = size.width / 0.64;
+ return Material(
+ type: MaterialType.transparency, //透明类型
+ color: const Color(0x1A000000),
+ child: Center(
+ // ClipRRect 创建圆角矩形 要不然发现下边button不是圆角
+ child: Container(
+ width: h328,
+ height: h564,
+ decoration: const BoxDecoration(
+ color: Colors.white,
+ //设置四周圆角 角度
+ borderRadius: BorderRadius.all(Radius.circular(6.6))),
+ child: Stack(
+ alignment: Alignment.topCenter,
+ children: [
+ Container(
+ margin: const EdgeInsets.only(top: 14),
+ child: Text(
+ widget.name,
+ style: const TextStyle(color: Colors.black, fontSize: 18, fontWeight: FontWeight.w800),
+ ),
+ ),
+ Container(
+ margin: const EdgeInsets.only(left: 12, right: 12, top: 52, bottom: 58),
+ child: SingleChildScrollView(
+ child: Column(
+ children: [
+ ListView.builder(
+ shrinkWrap: true,
+ itemCount: widget.list.length,
+ padding: const EdgeInsets.all(0),
+ //数据的数量
+ itemBuilder: (context, index) {
+ return GestureDetector(
+ onTap: () {},
+ child: Container(
+ margin: const EdgeInsets.only(bottom: 13),
+ decoration: const BoxDecoration(
+ color: Color(0xFFF3F3FB),
+ //设置四周圆角 角度
+ borderRadius: BorderRadius.all(Radius.circular(6.6))),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Container(
+ margin: const EdgeInsets.only(left: 13, top: 13),
+ alignment: Alignment.centerLeft,
+ child: Text(
+ widget.list[index]["name"].toString(),
+ style: const TextStyle(color: Colors.black, fontSize: 16),
+ ),
+ ),
+ Container(
+ margin: const EdgeInsets.only(left: 13, bottom: 18, top: 18),
+ child: Wrap(
+ spacing: 15.0,
+ //主轴间距
+ runSpacing: 15,
+ //副轴间距
+ alignment: WrapAlignment.start,
+ //主轴上的对齐方式
+ crossAxisAlignment: WrapCrossAlignment.center,
+ //副轴上的对齐方式
+ children: List.generate(
+ widget.list[index]["content"].length,
+ (int i) {
+ return _sizeItem2(index, widget.list[index]["content"][i], i);
+ },
+ ).toList(),
+ ),
+ ),
+ ],
+ ),
+ ));
+ },
+ physics: const NeverScrollableScrollPhysics(),
+ //类似 cellForRow 函数
+ scrollDirection: Axis.vertical),
+ ],
+ ),
+ )),
+ Align(
+ alignment: Alignment.bottomCenter,
+ child: GestureDetector(
+ onTap: () {
+ if (widget.onTap != null) {
+ Navigator.pop(context);
+ widget.onTap(selectList);
+ }
+ },
+ child: Container(
+ height: 40,
+ alignment: Alignment.center,
+ margin: const EdgeInsets.only(bottom: 11, left: 23, right: 23),
+ decoration: const BoxDecoration(
+ gradient: LinearGradient(
+ begin: Alignment.centerLeft, //渐变开始于上面的中间开始
+ end: Alignment.centerRight, //渐变结束于下面的中间
+ colors: [Color(0xFF808EEF), Color(0xFFBE6FDF)]),
+ borderRadius: BorderRadius.all(Radius.circular(20))),
+ child: Text(
+ S.of(context).Save,
+ style: const TextStyle(color: Colors.white, fontSize: 16),
+ ),
+ ),
+ )),
+ Positioned(
+ top: 15,
+ right: 15,
+ child: GestureDetector(
+ onTap: () {
+ Navigator.pop(context);
+ },
+ child: const SizedBox(
+ width: 20,
+ height: 20,
+ child: Image(
+ width: 20,
+ height: 20,
+ image: AssetImage('assets/images/cuo.png'),
+ ),
+ ),
+ ))
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+
+ _sizeItem2(index, String bean, i) {
+ bool isSelect = false;
+ if (selectList != null && selectList.isNotEmpty) {
+ for (var v in selectList) {
+ if (bean == v) {
+ isSelect = true;
+ }
+ }
+ }
+
+ return Container(
+ child: GestureDetector(
+ onTap: () {
+ if (selectList.contains(bean)) {
+ selectList.remove(bean);
+ } else {
+ selectList.add(bean);
+ }
+ print(selectList); //{a: a3, 2: b3, 3: null}
+ setState(() {});
+ },
+ child: Container(
+ padding: const EdgeInsets.only(left: 10, right: 10, top: 1, bottom: 1),
+ decoration: BoxDecoration(
+ //设置四周圆角 角度
+ borderRadius: const BorderRadius.all(Radius.circular(3.5)),
+ //设置四周边框
+ border: Border.all(width: 1, color: Color(isSelect ? 0xFFBE75FF : 0xFF666666)),
+ color: Color(isSelect ? 0xFFBE75FF : 0x00FFFFFF),
+ ),
+ child: Text(
+ bean,
+ overflow: TextOverflow.ellipsis,
+ style: TextStyle(color: Color(isSelect ? 0xFFFFFFFF : 0xFF999999), fontSize: 12),
+ ),
+ ),
+ ),
+ );
+ }
+/* _sizeItem2(List list) {
+ return list.map((e) {
+ int index = list.indexOf(e);
+ return GestureDetector(
+ onTap: () {
+ mainBodyIndex = index;
+ t2 = responseData["body"][index]["content"];
+ setState(() {});
+ },
+ child: Container(
+ alignment: Alignment.center,
+ decoration: BoxDecoration(
+ color: const Color(0xFFF3F3FB),
+ //设置四周圆角 角度
+ borderRadius: const BorderRadius.all(Radius.circular(6.6)),
+ //设置四周边框
+ border: Border.all(width: 1, color: Color(mainBodyIndex == index ? 0xFF8841FF : 0xFFFFFFFF)),
+ ),
+ child: Text(
+ list[index],
+ overflow: TextOverflow.ellipsis,
+ style: TextStyle(color: Color(mainBodyIndex == index ? 0xFF8841FF : 0xFF999999), fontSize: 12),
+ ),
+ ),
+ );
+ }).toList();
+ }*/
+}
diff --git a/lib/dialog/guide_theme_switch_tip.dart b/lib/dialog/guide_theme_switch_tip.dart
new file mode 100644
index 0000000..8dfd358
--- /dev/null
+++ b/lib/dialog/guide_theme_switch_tip.dart
@@ -0,0 +1,113 @@
+import 'package:flutter/material.dart';
+
+import '../generated/l10n.dart';
+
+///引导模式切换主题提示
+class GuideThemeSwitchTip extends StatefulWidget {
+ Function onTap;
+ String theme;
+
+ GuideThemeSwitchTip(this.theme, {Key? key, required this.onTap}) : super(key: key);
+
+ @override
+ State createState() => _GuideThemeSwitchTipState();
+}
+
+class _GuideThemeSwitchTipState extends State {
+ @override
+ Widget build(BuildContext context) {
+ final size = MediaQuery.of(context).size;
+ final h20 = size.width / 18; //20
+ final b25 = size.width / 14.4; //25
+ final t30 = size.width / 12; //30
+ final t27 = size.width / 13.33333333; //27
+ final w132 = size.width / 2.7272727272; //132
+ final h37 = size.width / 9.7297297297; //37
+ return Material(
+ type: MaterialType.transparency, //透明类型
+ color: const Color(0x00000000),
+ child: Container(
+ alignment: Alignment.center,
+ child: Container(
+ margin: EdgeInsets.only(left: 15, right: 15),
+ padding: EdgeInsets.only(left: h20, right: h20, bottom: b25),
+ decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(13))),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Container(
+ margin: EdgeInsets.only(top: t30),
+ child: Text(
+ S.of(context).switch_the_subject,
+ style: TextStyle(color: Colors.black, fontSize: 18),
+ ),
+ ),
+ Container(
+ margin: EdgeInsets.only(top: h20),
+ child: RichText(
+ text: TextSpan(children: [
+ TextSpan(
+ text: S.of(context).After_confirmation,
+ style: TextStyle(color: Colors.black, fontSize: 13),
+ ),
+ TextSpan(
+ text: widget.theme,
+ style: TextStyle(color: Colors.black, fontSize: 13),
+ ),
+ TextSpan(
+ text: S.of(context).some_unshared,
+ style: TextStyle(color: Colors.black, fontSize: 13),
+ ),
+ ]),
+ ),
+ ),
+ Container(
+ margin: EdgeInsets.only(top: t27, bottom: 10),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GestureDetector(
+ onTap: () {
+ Navigator.pop(context);
+ },
+ child: Container(
+ width: w132,
+ height: h37,
+ alignment: Alignment.center,
+ decoration: BoxDecoration(color: Color(0xFFEEE3FF), borderRadius: BorderRadius.all(Radius.circular(7))),
+ child: Text(
+ S.of(context).Cancel,
+ style: TextStyle(color: Color(0xFF8841FF)),
+ ),
+ ),
+ ),
+ GestureDetector(
+ onTap: () {
+ Navigator.pop(context);
+ widget.onTap(1);
+ },
+ child: Container(
+ width: w132,
+ height: h37,
+ alignment: Alignment.center,
+ decoration: const BoxDecoration(
+ gradient: LinearGradient(
+ begin: Alignment.centerLeft, //渐变开始于上面的中间开始
+ end: Alignment.centerRight, //渐变结束于下面的中间
+ colors: [Color(0xFF808EEF), Color(0xFFBE6FDF)]),
+ borderRadius: BorderRadius.all(Radius.circular(7))),
+ child: Text(
+ S.of(context).Cover,
+ style: TextStyle(color: Colors.white),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ )));
+ }
+}
diff --git a/lib/dialog/influential_prompt_dialog.dart b/lib/dialog/influential_prompt_dialog.dart
new file mode 100644
index 0000000..2341581
--- /dev/null
+++ b/lib/dialog/influential_prompt_dialog.dart
@@ -0,0 +1,106 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_easyloading/flutter_easyloading.dart';
+
+import '../generated/l10n.dart';
+
+class InfluentialPromptDialog extends StatefulWidget {
+ Function onTap;
+ String prompt;
+
+ InfluentialPromptDialog({required this.prompt, required this.onTap});
+
+ @override
+ State createState() => _InfluentialPromptDialogState();
+}
+
+class _InfluentialPromptDialogState extends State {
+ @override
+ Widget build(BuildContext context) {
+ final size = MediaQuery.of(context).size;
+
+
+
+ return Material(
+ type: MaterialType.transparency, //透明类型
+ color: const Color(0x00000000),
+ child: Container(
+ width: size.width,
+ color: const Color(0x70000000),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Container(
+ alignment: Alignment.centerLeft,
+ margin: const EdgeInsets.only(top: 20, left: 14),
+ child: Text(
+ S.of(context).Painting_parameters,
+ style: const TextStyle(color: Color(0xFFC4C4C4)),
+ ),
+ ),
+ Container(
+ alignment: Alignment.centerLeft,
+ margin: const EdgeInsets.only(left: 15, right: 15, top: 13),
+ child: Text(
+ widget.prompt,
+ style: const TextStyle(color: Colors.white),
+ ),
+ ),
+ Container(height: 22),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ ///复制提示词
+ GestureDetector(
+ onTap: () {
+ EasyLoading.showToast(S.of(context).Already_copied);
+ Clipboard.setData(ClipboardData(text: widget.prompt));
+ },
+ child: Container(
+ alignment: Alignment.center,
+ margin: const EdgeInsets.only(left: 16),
+ width: 154.67,
+ height: 32,
+ decoration: const BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.all(Radius.circular(16)),
+ ),
+ child: Text(
+ S.of(context).copy_prompt_word,
+ style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w600),
+ ),
+ ),
+ ),
+
+ ///画同款
+ GestureDetector(
+ onTap: () {
+ widget.onTap();
+ },
+ child: Container(
+ alignment: Alignment.center,
+ margin: const EdgeInsets.only(right: 16),
+ width: 154.67,
+ height: 32,
+ decoration: const BoxDecoration(
+ gradient: LinearGradient(
+ begin: Alignment.centerLeft, //渐变开始于上面的中间开始
+ end: Alignment.centerRight, //渐变结束于下面的中间
+ colors: [Color(0xFF808EEF), Color(0xFFBE6FDF)]),
+ borderRadius: BorderRadius.all(Radius.circular(16)),
+ ),
+ child: Text(
+ S.of(context).Draw_the_same,
+ style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: Colors.white),
+ ),
+ ),
+ ),
+ ],
+ ),
+ Container(height: 22),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/dialog/invitation_code_dialog.dart b/lib/dialog/invitation_code_dialog.dart
new file mode 100644
index 0000000..dedec1b
--- /dev/null
+++ b/lib/dialog/invitation_code_dialog.dart
@@ -0,0 +1,145 @@
+import 'dart:async';
+import 'dart:ui';
+
+import 'package:aiplot/network/NetworkConfig.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/rendering.dart';
+import 'package:flutter_easyloading/flutter_easyloading.dart';
+
+import '../generated/l10n.dart';
+import '../tools/me/me_info_model.dart';
+
+///填写邀请码弹框
+class InvitationCodeDialog extends StatefulWidget {
+ InvitationCodeDialog({Key? key}) : super(key: key);
+
+ @override
+ State createState() => _InvitationCodeDialogState();
+}
+
+class _InvitationCodeDialogState extends State {
+ TextEditingController _textEditingController = TextEditingController();
+ String text = "";
+
+ void _textFieldChanged(String str) {
+ text = str.toUpperCase();
+ _textEditingController.value = _textEditingController.value.copyWith(text: text.toUpperCase());
+ }
+
+ StreamSubscription? subscription;
+ final MeInfoModel _viewModel = MeInfoModel();
+
+ @override
+ void initState() {
+ // TODO: implement initState
+ super.initState();
+
+ //网络请求回调
+ subscription = _viewModel.streamController.stream.listen((newData) {
+ String code = newData['code'];
+ if (code.isNotEmpty) {
+ EasyLoading.dismiss();
+ switch (code) {
+ case "fillInInvitationCode":
+ Navigator.pop(context);
+ String message = newData['data'];
+ EasyLoading.showToast(message);
+ break;
+ default:
+ String message = newData['data'];
+ EasyLoading.showToast(message);
+ break;
+ }
+ }
+ setState(() {});
+ });
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final size = MediaQuery.of(context).size;
+ return Material(
+ type: MaterialType.transparency, //透明类型
+ color: const Color(0x00000000),
+ child: Container(
+ alignment: Alignment.center,
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Container(
+ width: size.width,
+ margin: EdgeInsets.only(left: 25, right: 25),
+ decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(7))),
+ child: Column(
+ children: [
+ Container(
+ alignment: Alignment.centerLeft,
+ margin: EdgeInsets.only(top: 22, left: 34),
+ child: Text(
+ S.of(context).Invitation_code,
+ style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
+ ),
+ ),
+ Container(
+ alignment: Alignment.centerLeft,
+ margin: EdgeInsets.only(top: 11, left: 34, right: 34),
+ child: Text("${S.of(context).Fill_in} ${NetworkConfig.appConfigBean!.InviteeNumber} ${S.of(context).Painting_points}"),
+ ),
+ Container(
+ height: 37,
+ alignment: Alignment.center,
+ margin: const EdgeInsets.only(top: 11, left: 34, right: 34),
+ decoration: const BoxDecoration(
+ color: Color(0xFFF0F0FF),
+ borderRadius: BorderRadius.all(Radius.circular(7)),
+ ),
+ child: TextField(
+ controller: _textEditingController,
+ keyboardType: TextInputType.name,
+ cursorColor: Color(0xFF843FFF),
+ decoration: InputDecoration.collapsed(hintStyle: const TextStyle(fontSize: 16.0, color: Color(0xFFB5B5B5)), hintText: ''),
+ //文本对齐方式
+ textAlign: TextAlign.center,
+ //最大长度,设置此项会让TextField右下角有一个输入数量的统计字符串
+ //最大行数
+ maxLines: 1,
+ //输入文本的样式
+ style: const TextStyle(fontSize: 18.0, color: Color(0xFF843FFF), fontWeight: FontWeight.w500),
+ onChanged: _textFieldChanged,
+ autofocus: false,
+ ),
+ ),
+ GestureDetector(
+ onTap: () {
+ if (text != "") {
+ _viewModel.fillInInvitationCode(text);
+ } else {
+ EasyLoading.showToast(S.of(context).Please_fill_in);
+ }
+ },
+ child: Container(
+ height: 45,
+ width: double.infinity,
+ alignment: Alignment.center,
+ margin: EdgeInsets.only(top: 30),
+ decoration: const BoxDecoration(
+ gradient: LinearGradient(
+ begin: Alignment.centerLeft, //渐变开始于上面的中间开始
+ end: Alignment.centerRight, //渐变结束于下面的中间
+ colors: [Color(0xFF843FFF), Color(0xFFF87DFF)]),
+ borderRadius: BorderRadius.only(bottomLeft: Radius.circular(7), bottomRight: Radius.circular(7))),
+ child: Text(
+ S.of(context).Sure,
+ style: TextStyle(color: Colors.white, fontSize: 16),
+ ),
+ ),
+ )
+ ],
+ ),
+ )
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/dialog/login_dialog.dart b/lib/dialog/login_dialog.dart
new file mode 100644
index 0000000..e03e58b
--- /dev/null
+++ b/lib/dialog/login_dialog.dart
@@ -0,0 +1,176 @@
+import 'package:aiplot/network/NetworkConfig.dart';
+import 'package:flutter/gestures.dart';
+import 'package:flutter/material.dart';
+
+import '../generated/l10n.dart';
+import '../tools/web/CommonlyWebPage.dart';
+
+class LoginDialog extends StatefulWidget {
+ Function onTap; //0 手机登录 1 谷歌登录
+
+ LoginDialog(Key key, {required this.onTap}) : super(key: key);
+
+ @override
+ State createState() => LoginDialogState();
+}
+
+class LoginDialogState extends State {
+ //用来收手势监听
+ final TapGestureRecognizer _tgr1 = TapGestureRecognizer();
+ final TapGestureRecognizer _tgr2 = TapGestureRecognizer();
+
+ @override
+ void initState() {
+ // TODO: implement initState
+ super.initState();
+ }
+
+ @override
+ void dispose() {
+ // TODO: implement dispose
+ _tgr1.dispose();
+ _tgr2.dispose();
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final size = MediaQuery.of(context).size;
+ final t37 = size.width / 9.729729729729;
+ final w97 = size.width / 3.7113402061855;
+ final b104 = size.width / 3.4615384615384;
+ final w48 = size.width / 7.5;
+ final w301 = size.width / 1.1960132890365;
+ final h56 = size.width / 6.4285714285714;
+ final w38 = size.width / 9.4736842105263;
+ final h342 = size.width / 1.0526315789473;
+
+ return Stack(
+ alignment: Alignment.center,
+ children: [
+ Positioned(
+ bottom: 0,
+ child: SizedBox(
+ height: h342,
+ child: Stack(
+ alignment: Alignment.center,
+ children: [
+ Image(image: AssetImage('assets/images/login_bg.png')),
+ Positioned(
+ top: t37,
+ child: Image(
+ width: w97,
+ height: w97,
+ image: AssetImage('assets/images/login_logo.png'),
+ )),
+
+ ///谷歌登录
+ Positioned(
+ bottom: b104,
+ child: GestureDetector(
+ onTap: () {
+ if (NetworkConfig.isTest) {
+ widget.onTap(0);
+ } else {
+ widget.onTap(1);
+ }
+ },
+ child: Stack(
+ alignment: Alignment.center,
+ children: [
+ Image(
+ width: w301,
+ height: h56,
+ image: const AssetImage('assets/images/google_login.png'),
+ ),
+ Positioned(
+ top: 12,
+ child: Row(
+ children: [
+ const Image(width: 27, height: 27, image: AssetImage('assets/images/google_logo.png')),
+ Container(
+ margin: const EdgeInsets.only(left: 5),
+ child: Text(
+ S.of(context).Google,
+ style: const TextStyle(color: Colors.white, fontSize: 16),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ )),
+
+ ///隐私协议,用户政策
+ Positioned(
+ bottom: w38,
+ child: RichText(
+ textAlign: TextAlign.center,
+ text: TextSpan(children: [
+ TextSpan(
+ style: const TextStyle(
+ color: Color(0xFF999999),
+ fontSize: 11.0,
+ // fontWeight: FontWeight.w800,
+ ),
+ text: S.of(context).By_continuing),
+ TextSpan(
+ style: const TextStyle(
+ color: Colors.black,
+ fontSize: 11.0,
+ ),
+ recognizer: _tgr1
+ ..onTap = () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ //导航打开新视图
+ builder: (context) => CommonlyWebPage(
+ url: "https://appfiles.hissai.com/hissai/UserAgreement_EN.html",
+ title: S.of(context).User_Agreement,
+ ) //打开第二个页面,并传值,传递值的名称是model
+ ));
+ },
+ text: "《${S.of(context).User_Agreement}》\n",
+ ),
+ TextSpan(
+ style: const TextStyle(
+ color: Color(0xFF999999),
+ fontSize: 11.0,
+ // fontWeight: FontWeight.w800,
+ ),
+ text: S.of(context).and),
+ TextSpan(
+ style: const TextStyle(
+ color: Colors.black,
+ fontSize: 11,
+ ),
+ recognizer: _tgr2
+ ..onTap = () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ //导航打开新视图
+ builder: (context) => CommonlyWebPage(
+ url: "https://appfiles.hissai.com/hissai/PrivacyPolicy_EN.html",
+ title: S.of(context).Privacy_Policy,
+ ) //打开第二个页面,并传值,传递值的名称是model
+ ));
+ },
+ text: "《${S.of(context).Privacy_Policy}》",
+ ),
+ ]),
+ ),
+ )
+ ],
+ ),
+ )),
+ ],
+ );
+ }
+
+ void Pop() {
+ Navigator.pop(context);
+ }
+}
diff --git a/lib/dialog/newDialog.dart b/lib/dialog/newDialog.dart
new file mode 100644
index 0000000..de5f77e
--- /dev/null
+++ b/lib/dialog/newDialog.dart
@@ -0,0 +1,162 @@
+import 'package:cached_network_image/cached_network_image.dart';
+import 'package:flutter/material.dart';
+
+import '../bean/popout_bean.dart';
+
+///弹框列表
+class newDialog extends StatefulWidget {
+ // 点击返回index 0 1
+ Function onTap;
+ final PopoutBean popoutBean;
+
+ newDialog({required this.onTap, required this.popoutBean});
+
+ @override
+ _newDialogState createState() => _newDialogState();
+}
+
+class _newDialogState extends State