diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
new file mode 100644
index 0000000..eecfd74
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
@@ -0,0 +1,43 @@
+package com.casic.smarttube.model;
+
+/**
+ * 普通实体类,失败/成功数据结构一致
+ */
+public class CommonResultModel {
+ private int code;
+ private String data;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
new file mode 100644
index 0000000..eecfd74
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
@@ -0,0 +1,43 @@
+package com.casic.smarttube.model;
+
+/**
+ * 普通实体类,失败/成功数据结构一致
+ */
+public class CommonResultModel {
+ private int code;
+ private String data;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
new file mode 100644
index 0000000..411674a
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
@@ -0,0 +1,49 @@
+package com.casic.smarttube.model;
+
+public class ErrorMessageModel {
+ private int code;
+ private String data;
+ private String exceptionClazz;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getExceptionClazz() {
+ return exceptionClazz;
+ }
+
+ public void setExceptionClazz(String exceptionClazz) {
+ this.exceptionClazz = exceptionClazz;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
new file mode 100644
index 0000000..eecfd74
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
@@ -0,0 +1,43 @@
+package com.casic.smarttube.model;
+
+/**
+ * 普通实体类,失败/成功数据结构一致
+ */
+public class CommonResultModel {
+ private int code;
+ private String data;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
new file mode 100644
index 0000000..411674a
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
@@ -0,0 +1,49 @@
+package com.casic.smarttube.model;
+
+public class ErrorMessageModel {
+ private int code;
+ private String data;
+ private String exceptionClazz;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getExceptionClazz() {
+ return exceptionClazz;
+ }
+
+ public void setExceptionClazz(String exceptionClazz) {
+ this.exceptionClazz = exceptionClazz;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
new file mode 100644
index 0000000..6497254
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
@@ -0,0 +1,62 @@
+package com.casic.smarttube.model;
+
+public class LoginResultModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private String kaptcha;
+ private String token;
+
+ public String getKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(String kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
new file mode 100644
index 0000000..eecfd74
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
@@ -0,0 +1,43 @@
+package com.casic.smarttube.model;
+
+/**
+ * 普通实体类,失败/成功数据结构一致
+ */
+public class CommonResultModel {
+ private int code;
+ private String data;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
new file mode 100644
index 0000000..411674a
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
@@ -0,0 +1,49 @@
+package com.casic.smarttube.model;
+
+public class ErrorMessageModel {
+ private int code;
+ private String data;
+ private String exceptionClazz;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getExceptionClazz() {
+ return exceptionClazz;
+ }
+
+ public void setExceptionClazz(String exceptionClazz) {
+ this.exceptionClazz = exceptionClazz;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
new file mode 100644
index 0000000..6497254
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
@@ -0,0 +1,62 @@
+package com.casic.smarttube.model;
+
+public class LoginResultModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private String kaptcha;
+ private String token;
+
+ public String getKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(String kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
new file mode 100644
index 0000000..d440bc8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
@@ -0,0 +1,80 @@
+package com.casic.smarttube.model;
+
+public class PublicKeyModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private boolean appKaptcha;
+ private boolean kaptcha;
+ private String publicKey;
+ private String sid;
+
+ public boolean isAppKaptcha() {
+ return appKaptcha;
+ }
+
+ public void setAppKaptcha(boolean appKaptcha) {
+ this.appKaptcha = appKaptcha;
+ }
+
+ public boolean isKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(boolean kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getPublicKey() {
+ return publicKey;
+ }
+
+ public void setPublicKey(String publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public String getSid() {
+ return sid;
+ }
+
+ public void setSid(String sid) {
+ this.sid = sid;
+ }
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
new file mode 100644
index 0000000..eecfd74
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
@@ -0,0 +1,43 @@
+package com.casic.smarttube.model;
+
+/**
+ * 普通实体类,失败/成功数据结构一致
+ */
+public class CommonResultModel {
+ private int code;
+ private String data;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
new file mode 100644
index 0000000..411674a
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
@@ -0,0 +1,49 @@
+package com.casic.smarttube.model;
+
+public class ErrorMessageModel {
+ private int code;
+ private String data;
+ private String exceptionClazz;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getExceptionClazz() {
+ return exceptionClazz;
+ }
+
+ public void setExceptionClazz(String exceptionClazz) {
+ this.exceptionClazz = exceptionClazz;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
new file mode 100644
index 0000000..6497254
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
@@ -0,0 +1,62 @@
+package com.casic.smarttube.model;
+
+public class LoginResultModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private String kaptcha;
+ private String token;
+
+ public String getKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(String kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
new file mode 100644
index 0000000..d440bc8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
@@ -0,0 +1,80 @@
+package com.casic.smarttube.model;
+
+public class PublicKeyModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private boolean appKaptcha;
+ private boolean kaptcha;
+ private String publicKey;
+ private String sid;
+
+ public boolean isAppKaptcha() {
+ return appKaptcha;
+ }
+
+ public void setAppKaptcha(boolean appKaptcha) {
+ this.appKaptcha = appKaptcha;
+ }
+
+ public boolean isKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(boolean kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getPublicKey() {
+ return publicKey;
+ }
+
+ public void setPublicKey(String publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public String getSid() {
+ return sid;
+ }
+
+ public void setSid(String sid) {
+ this.sid = sid;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
new file mode 100644
index 0000000..149bec8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
@@ -0,0 +1,227 @@
+package com.casic.smarttube.model;
+
+
+import java.util.List;
+
+public class UserDetailModel {
+ private int code;
+ private Data data;
+ private String message;
+ private boolean success;
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setData(Data data) {
+ this.data = data;
+ }
+
+ public Data getData() {
+ return data;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public boolean getSuccess() {
+ return success;
+ }
+
+ public static class Data {
+
+ private String account;
+ private String attr1;
+ private String avatar;
+ private String bizData;
+ private List dataScope;
+ private String deptId;
+ private String deptName;
+ private List devices;
+ private String id;
+ private String ipAddr;
+ private String name;
+ private String phone;
+ private List roleList;
+ private List roleNames;
+ private List roleTips;
+ private String scopeType;
+ private String sysData;
+ private String targetId;
+ private String targetName;
+ private String tenantId;
+
+ public void setAccount(String account) {
+ this.account = account;
+ }
+
+ public String getAccount() {
+ return account;
+ }
+
+ public void setAttr1(String attr1) {
+ this.attr1 = attr1;
+ }
+
+ public String getAttr1() {
+ return attr1;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setBizData(String bizData) {
+ this.bizData = bizData;
+ }
+
+ public String getBizData() {
+ return bizData;
+ }
+
+ public void setDataScope(List dataScope) {
+ this.dataScope = dataScope;
+ }
+
+ public List getDataScope() {
+ return dataScope;
+ }
+
+ public void setDeptId(String deptId) {
+ this.deptId = deptId;
+ }
+
+ public String getDeptId() {
+ return deptId;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDevices(List devices) {
+ this.devices = devices;
+ }
+
+ public List getDevices() {
+ return devices;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setIpAddr(String ipAddr) {
+ this.ipAddr = ipAddr;
+ }
+
+ public String getIpAddr() {
+ return ipAddr;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setRoleList(List roleList) {
+ this.roleList = roleList;
+ }
+
+ public List getRoleList() {
+ return roleList;
+ }
+
+ public void setRoleNames(List roleNames) {
+ this.roleNames = roleNames;
+ }
+
+ public List getRoleNames() {
+ return roleNames;
+ }
+
+ public void setRoleTips(List roleTips) {
+ this.roleTips = roleTips;
+ }
+
+ public List getRoleTips() {
+ return roleTips;
+ }
+
+ public void setScopeType(String scopeType) {
+ this.scopeType = scopeType;
+ }
+
+ public String getScopeType() {
+ return scopeType;
+ }
+
+ public void setSysData(String sysData) {
+ this.sysData = sysData;
+ }
+
+ public String getSysData() {
+ return sysData;
+ }
+
+ public void setTargetId(String targetId) {
+ this.targetId = targetId;
+ }
+
+ public String getTargetId() {
+ return targetId;
+ }
+
+ public void setTargetName(String targetName) {
+ this.targetName = targetName;
+ }
+
+ public String getTargetName() {
+ return targetName;
+ }
+
+ public void setTenantId(String tenantId) {
+ this.tenantId = tenantId;
+ }
+
+ public String getTenantId() {
+ return tenantId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
new file mode 100644
index 0000000..eecfd74
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
@@ -0,0 +1,43 @@
+package com.casic.smarttube.model;
+
+/**
+ * 普通实体类,失败/成功数据结构一致
+ */
+public class CommonResultModel {
+ private int code;
+ private String data;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
new file mode 100644
index 0000000..411674a
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
@@ -0,0 +1,49 @@
+package com.casic.smarttube.model;
+
+public class ErrorMessageModel {
+ private int code;
+ private String data;
+ private String exceptionClazz;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getExceptionClazz() {
+ return exceptionClazz;
+ }
+
+ public void setExceptionClazz(String exceptionClazz) {
+ this.exceptionClazz = exceptionClazz;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
new file mode 100644
index 0000000..6497254
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
@@ -0,0 +1,62 @@
+package com.casic.smarttube.model;
+
+public class LoginResultModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private String kaptcha;
+ private String token;
+
+ public String getKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(String kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
new file mode 100644
index 0000000..d440bc8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
@@ -0,0 +1,80 @@
+package com.casic.smarttube.model;
+
+public class PublicKeyModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private boolean appKaptcha;
+ private boolean kaptcha;
+ private String publicKey;
+ private String sid;
+
+ public boolean isAppKaptcha() {
+ return appKaptcha;
+ }
+
+ public void setAppKaptcha(boolean appKaptcha) {
+ this.appKaptcha = appKaptcha;
+ }
+
+ public boolean isKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(boolean kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getPublicKey() {
+ return publicKey;
+ }
+
+ public void setPublicKey(String publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public String getSid() {
+ return sid;
+ }
+
+ public void setSid(String sid) {
+ this.sid = sid;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
new file mode 100644
index 0000000..149bec8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
@@ -0,0 +1,227 @@
+package com.casic.smarttube.model;
+
+
+import java.util.List;
+
+public class UserDetailModel {
+ private int code;
+ private Data data;
+ private String message;
+ private boolean success;
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setData(Data data) {
+ this.data = data;
+ }
+
+ public Data getData() {
+ return data;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public boolean getSuccess() {
+ return success;
+ }
+
+ public static class Data {
+
+ private String account;
+ private String attr1;
+ private String avatar;
+ private String bizData;
+ private List dataScope;
+ private String deptId;
+ private String deptName;
+ private List devices;
+ private String id;
+ private String ipAddr;
+ private String name;
+ private String phone;
+ private List roleList;
+ private List roleNames;
+ private List roleTips;
+ private String scopeType;
+ private String sysData;
+ private String targetId;
+ private String targetName;
+ private String tenantId;
+
+ public void setAccount(String account) {
+ this.account = account;
+ }
+
+ public String getAccount() {
+ return account;
+ }
+
+ public void setAttr1(String attr1) {
+ this.attr1 = attr1;
+ }
+
+ public String getAttr1() {
+ return attr1;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setBizData(String bizData) {
+ this.bizData = bizData;
+ }
+
+ public String getBizData() {
+ return bizData;
+ }
+
+ public void setDataScope(List dataScope) {
+ this.dataScope = dataScope;
+ }
+
+ public List getDataScope() {
+ return dataScope;
+ }
+
+ public void setDeptId(String deptId) {
+ this.deptId = deptId;
+ }
+
+ public String getDeptId() {
+ return deptId;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDevices(List devices) {
+ this.devices = devices;
+ }
+
+ public List getDevices() {
+ return devices;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setIpAddr(String ipAddr) {
+ this.ipAddr = ipAddr;
+ }
+
+ public String getIpAddr() {
+ return ipAddr;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setRoleList(List roleList) {
+ this.roleList = roleList;
+ }
+
+ public List getRoleList() {
+ return roleList;
+ }
+
+ public void setRoleNames(List roleNames) {
+ this.roleNames = roleNames;
+ }
+
+ public List getRoleNames() {
+ return roleNames;
+ }
+
+ public void setRoleTips(List roleTips) {
+ this.roleTips = roleTips;
+ }
+
+ public List getRoleTips() {
+ return roleTips;
+ }
+
+ public void setScopeType(String scopeType) {
+ this.scopeType = scopeType;
+ }
+
+ public String getScopeType() {
+ return scopeType;
+ }
+
+ public void setSysData(String sysData) {
+ this.sysData = sysData;
+ }
+
+ public String getSysData() {
+ return sysData;
+ }
+
+ public void setTargetId(String targetId) {
+ this.targetId = targetId;
+ }
+
+ public String getTargetId() {
+ return targetId;
+ }
+
+ public void setTargetName(String targetName) {
+ this.targetName = targetName;
+ }
+
+ public String getTargetName() {
+ return targetName;
+ }
+
+ public void setTenantId(String tenantId) {
+ this.tenantId = tenantId;
+ }
+
+ public String getTenantId() {
+ return tenantId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
new file mode 100644
index 0000000..b44fec6
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
@@ -0,0 +1,24 @@
+package com.casic.smarttube.utils
+
+import com.pengxh.kt.lite.utils.SaveKeyValues
+
+object AuthenticationHelper {
+
+ fun savePublicKey(key: String) {
+ SaveKeyValues.putValue("keyString", key)
+ }
+
+ val publicKey: String?
+ get() = SaveKeyValues.getValue("keyString", "") as String?
+
+ fun saveToken(token: String?) {
+ SaveKeyValues.putValue("token", token!!)
+ }
+
+ val token: String?
+ get() = SaveKeyValues.getValue("token", "") as String?
+
+ fun removeToken() {
+ SaveKeyValues.removeKey("token")
+ }
+}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
new file mode 100644
index 0000000..eecfd74
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
@@ -0,0 +1,43 @@
+package com.casic.smarttube.model;
+
+/**
+ * 普通实体类,失败/成功数据结构一致
+ */
+public class CommonResultModel {
+ private int code;
+ private String data;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
new file mode 100644
index 0000000..411674a
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
@@ -0,0 +1,49 @@
+package com.casic.smarttube.model;
+
+public class ErrorMessageModel {
+ private int code;
+ private String data;
+ private String exceptionClazz;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getExceptionClazz() {
+ return exceptionClazz;
+ }
+
+ public void setExceptionClazz(String exceptionClazz) {
+ this.exceptionClazz = exceptionClazz;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
new file mode 100644
index 0000000..6497254
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
@@ -0,0 +1,62 @@
+package com.casic.smarttube.model;
+
+public class LoginResultModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private String kaptcha;
+ private String token;
+
+ public String getKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(String kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
new file mode 100644
index 0000000..d440bc8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
@@ -0,0 +1,80 @@
+package com.casic.smarttube.model;
+
+public class PublicKeyModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private boolean appKaptcha;
+ private boolean kaptcha;
+ private String publicKey;
+ private String sid;
+
+ public boolean isAppKaptcha() {
+ return appKaptcha;
+ }
+
+ public void setAppKaptcha(boolean appKaptcha) {
+ this.appKaptcha = appKaptcha;
+ }
+
+ public boolean isKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(boolean kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getPublicKey() {
+ return publicKey;
+ }
+
+ public void setPublicKey(String publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public String getSid() {
+ return sid;
+ }
+
+ public void setSid(String sid) {
+ this.sid = sid;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
new file mode 100644
index 0000000..149bec8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
@@ -0,0 +1,227 @@
+package com.casic.smarttube.model;
+
+
+import java.util.List;
+
+public class UserDetailModel {
+ private int code;
+ private Data data;
+ private String message;
+ private boolean success;
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setData(Data data) {
+ this.data = data;
+ }
+
+ public Data getData() {
+ return data;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public boolean getSuccess() {
+ return success;
+ }
+
+ public static class Data {
+
+ private String account;
+ private String attr1;
+ private String avatar;
+ private String bizData;
+ private List dataScope;
+ private String deptId;
+ private String deptName;
+ private List devices;
+ private String id;
+ private String ipAddr;
+ private String name;
+ private String phone;
+ private List roleList;
+ private List roleNames;
+ private List roleTips;
+ private String scopeType;
+ private String sysData;
+ private String targetId;
+ private String targetName;
+ private String tenantId;
+
+ public void setAccount(String account) {
+ this.account = account;
+ }
+
+ public String getAccount() {
+ return account;
+ }
+
+ public void setAttr1(String attr1) {
+ this.attr1 = attr1;
+ }
+
+ public String getAttr1() {
+ return attr1;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setBizData(String bizData) {
+ this.bizData = bizData;
+ }
+
+ public String getBizData() {
+ return bizData;
+ }
+
+ public void setDataScope(List dataScope) {
+ this.dataScope = dataScope;
+ }
+
+ public List getDataScope() {
+ return dataScope;
+ }
+
+ public void setDeptId(String deptId) {
+ this.deptId = deptId;
+ }
+
+ public String getDeptId() {
+ return deptId;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDevices(List devices) {
+ this.devices = devices;
+ }
+
+ public List getDevices() {
+ return devices;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setIpAddr(String ipAddr) {
+ this.ipAddr = ipAddr;
+ }
+
+ public String getIpAddr() {
+ return ipAddr;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setRoleList(List roleList) {
+ this.roleList = roleList;
+ }
+
+ public List getRoleList() {
+ return roleList;
+ }
+
+ public void setRoleNames(List roleNames) {
+ this.roleNames = roleNames;
+ }
+
+ public List getRoleNames() {
+ return roleNames;
+ }
+
+ public void setRoleTips(List roleTips) {
+ this.roleTips = roleTips;
+ }
+
+ public List getRoleTips() {
+ return roleTips;
+ }
+
+ public void setScopeType(String scopeType) {
+ this.scopeType = scopeType;
+ }
+
+ public String getScopeType() {
+ return scopeType;
+ }
+
+ public void setSysData(String sysData) {
+ this.sysData = sysData;
+ }
+
+ public String getSysData() {
+ return sysData;
+ }
+
+ public void setTargetId(String targetId) {
+ this.targetId = targetId;
+ }
+
+ public String getTargetId() {
+ return targetId;
+ }
+
+ public void setTargetName(String targetName) {
+ this.targetName = targetName;
+ }
+
+ public String getTargetName() {
+ return targetName;
+ }
+
+ public void setTenantId(String tenantId) {
+ this.tenantId = tenantId;
+ }
+
+ public String getTenantId() {
+ return tenantId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
new file mode 100644
index 0000000..b44fec6
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
@@ -0,0 +1,24 @@
+package com.casic.smarttube.utils
+
+import com.pengxh.kt.lite.utils.SaveKeyValues
+
+object AuthenticationHelper {
+
+ fun savePublicKey(key: String) {
+ SaveKeyValues.putValue("keyString", key)
+ }
+
+ val publicKey: String?
+ get() = SaveKeyValues.getValue("keyString", "") as String?
+
+ fun saveToken(token: String?) {
+ SaveKeyValues.putValue("token", token!!)
+ }
+
+ val token: String?
+ get() = SaveKeyValues.getValue("token", "") as String?
+
+ fun removeToken() {
+ SaveKeyValues.removeKey("token")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/Constant.kt b/app/src/main/java/com/casic/smarttube/utils/Constant.kt
deleted file mode 100644
index d921387..0000000
--- a/app/src/main/java/com/casic/smarttube/utils/Constant.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.casic.smarttube.utils
-
-import android.Manifest
-
-
-object Constant {
- val USER_PERMISSIONS = arrayOf(
- Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
- Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
- Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
- Manifest.permission.READ_PHONE_STATE
- )
-
- const val PERMISSIONS_CODE = 999
-}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
new file mode 100644
index 0000000..eecfd74
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
@@ -0,0 +1,43 @@
+package com.casic.smarttube.model;
+
+/**
+ * 普通实体类,失败/成功数据结构一致
+ */
+public class CommonResultModel {
+ private int code;
+ private String data;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
new file mode 100644
index 0000000..411674a
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
@@ -0,0 +1,49 @@
+package com.casic.smarttube.model;
+
+public class ErrorMessageModel {
+ private int code;
+ private String data;
+ private String exceptionClazz;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getExceptionClazz() {
+ return exceptionClazz;
+ }
+
+ public void setExceptionClazz(String exceptionClazz) {
+ this.exceptionClazz = exceptionClazz;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
new file mode 100644
index 0000000..6497254
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
@@ -0,0 +1,62 @@
+package com.casic.smarttube.model;
+
+public class LoginResultModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private String kaptcha;
+ private String token;
+
+ public String getKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(String kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
new file mode 100644
index 0000000..d440bc8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
@@ -0,0 +1,80 @@
+package com.casic.smarttube.model;
+
+public class PublicKeyModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private boolean appKaptcha;
+ private boolean kaptcha;
+ private String publicKey;
+ private String sid;
+
+ public boolean isAppKaptcha() {
+ return appKaptcha;
+ }
+
+ public void setAppKaptcha(boolean appKaptcha) {
+ this.appKaptcha = appKaptcha;
+ }
+
+ public boolean isKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(boolean kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getPublicKey() {
+ return publicKey;
+ }
+
+ public void setPublicKey(String publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public String getSid() {
+ return sid;
+ }
+
+ public void setSid(String sid) {
+ this.sid = sid;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
new file mode 100644
index 0000000..149bec8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
@@ -0,0 +1,227 @@
+package com.casic.smarttube.model;
+
+
+import java.util.List;
+
+public class UserDetailModel {
+ private int code;
+ private Data data;
+ private String message;
+ private boolean success;
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setData(Data data) {
+ this.data = data;
+ }
+
+ public Data getData() {
+ return data;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public boolean getSuccess() {
+ return success;
+ }
+
+ public static class Data {
+
+ private String account;
+ private String attr1;
+ private String avatar;
+ private String bizData;
+ private List dataScope;
+ private String deptId;
+ private String deptName;
+ private List devices;
+ private String id;
+ private String ipAddr;
+ private String name;
+ private String phone;
+ private List roleList;
+ private List roleNames;
+ private List roleTips;
+ private String scopeType;
+ private String sysData;
+ private String targetId;
+ private String targetName;
+ private String tenantId;
+
+ public void setAccount(String account) {
+ this.account = account;
+ }
+
+ public String getAccount() {
+ return account;
+ }
+
+ public void setAttr1(String attr1) {
+ this.attr1 = attr1;
+ }
+
+ public String getAttr1() {
+ return attr1;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setBizData(String bizData) {
+ this.bizData = bizData;
+ }
+
+ public String getBizData() {
+ return bizData;
+ }
+
+ public void setDataScope(List dataScope) {
+ this.dataScope = dataScope;
+ }
+
+ public List getDataScope() {
+ return dataScope;
+ }
+
+ public void setDeptId(String deptId) {
+ this.deptId = deptId;
+ }
+
+ public String getDeptId() {
+ return deptId;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDevices(List devices) {
+ this.devices = devices;
+ }
+
+ public List getDevices() {
+ return devices;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setIpAddr(String ipAddr) {
+ this.ipAddr = ipAddr;
+ }
+
+ public String getIpAddr() {
+ return ipAddr;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setRoleList(List roleList) {
+ this.roleList = roleList;
+ }
+
+ public List getRoleList() {
+ return roleList;
+ }
+
+ public void setRoleNames(List roleNames) {
+ this.roleNames = roleNames;
+ }
+
+ public List getRoleNames() {
+ return roleNames;
+ }
+
+ public void setRoleTips(List roleTips) {
+ this.roleTips = roleTips;
+ }
+
+ public List getRoleTips() {
+ return roleTips;
+ }
+
+ public void setScopeType(String scopeType) {
+ this.scopeType = scopeType;
+ }
+
+ public String getScopeType() {
+ return scopeType;
+ }
+
+ public void setSysData(String sysData) {
+ this.sysData = sysData;
+ }
+
+ public String getSysData() {
+ return sysData;
+ }
+
+ public void setTargetId(String targetId) {
+ this.targetId = targetId;
+ }
+
+ public String getTargetId() {
+ return targetId;
+ }
+
+ public void setTargetName(String targetName) {
+ this.targetName = targetName;
+ }
+
+ public String getTargetName() {
+ return targetName;
+ }
+
+ public void setTenantId(String tenantId) {
+ this.tenantId = tenantId;
+ }
+
+ public String getTenantId() {
+ return tenantId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
new file mode 100644
index 0000000..b44fec6
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
@@ -0,0 +1,24 @@
+package com.casic.smarttube.utils
+
+import com.pengxh.kt.lite.utils.SaveKeyValues
+
+object AuthenticationHelper {
+
+ fun savePublicKey(key: String) {
+ SaveKeyValues.putValue("keyString", key)
+ }
+
+ val publicKey: String?
+ get() = SaveKeyValues.getValue("keyString", "") as String?
+
+ fun saveToken(token: String?) {
+ SaveKeyValues.putValue("token", token!!)
+ }
+
+ val token: String?
+ get() = SaveKeyValues.getValue("token", "") as String?
+
+ fun removeToken() {
+ SaveKeyValues.removeKey("token")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/Constant.kt b/app/src/main/java/com/casic/smarttube/utils/Constant.kt
deleted file mode 100644
index d921387..0000000
--- a/app/src/main/java/com/casic/smarttube/utils/Constant.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.casic.smarttube.utils
-
-import android.Manifest
-
-
-object Constant {
- val USER_PERMISSIONS = arrayOf(
- Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
- Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
- Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
- Manifest.permission.READ_PHONE_STATE
- )
-
- const val PERMISSIONS_CODE = 999
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
new file mode 100644
index 0000000..bb97c01
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
@@ -0,0 +1,29 @@
+package com.casic.smarttube.utils;
+
+import android.app.Activity
+import android.view.WindowManager
+import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
+
+object DialogHelper {
+ private lateinit var loadingDialog: QMUITipDialog
+
+ fun showLoadingDialog(activity: Activity, message: String?) {
+ loadingDialog = QMUITipDialog.Builder(activity)
+ .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+ .setTipWord(message)
+ .create()
+ if (!activity.isDestroyed) {
+ try {
+ loadingDialog.show()
+ } catch (e: WindowManager.BadTokenException) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ fun dismissLoadingDialog() {
+ if (loadingDialog.isShowing) {
+ loadingDialog.dismiss()
+ }
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
new file mode 100644
index 0000000..eecfd74
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
@@ -0,0 +1,43 @@
+package com.casic.smarttube.model;
+
+/**
+ * 普通实体类,失败/成功数据结构一致
+ */
+public class CommonResultModel {
+ private int code;
+ private String data;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
new file mode 100644
index 0000000..411674a
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
@@ -0,0 +1,49 @@
+package com.casic.smarttube.model;
+
+public class ErrorMessageModel {
+ private int code;
+ private String data;
+ private String exceptionClazz;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getExceptionClazz() {
+ return exceptionClazz;
+ }
+
+ public void setExceptionClazz(String exceptionClazz) {
+ this.exceptionClazz = exceptionClazz;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
new file mode 100644
index 0000000..6497254
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
@@ -0,0 +1,62 @@
+package com.casic.smarttube.model;
+
+public class LoginResultModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private String kaptcha;
+ private String token;
+
+ public String getKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(String kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
new file mode 100644
index 0000000..d440bc8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
@@ -0,0 +1,80 @@
+package com.casic.smarttube.model;
+
+public class PublicKeyModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private boolean appKaptcha;
+ private boolean kaptcha;
+ private String publicKey;
+ private String sid;
+
+ public boolean isAppKaptcha() {
+ return appKaptcha;
+ }
+
+ public void setAppKaptcha(boolean appKaptcha) {
+ this.appKaptcha = appKaptcha;
+ }
+
+ public boolean isKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(boolean kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getPublicKey() {
+ return publicKey;
+ }
+
+ public void setPublicKey(String publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public String getSid() {
+ return sid;
+ }
+
+ public void setSid(String sid) {
+ this.sid = sid;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
new file mode 100644
index 0000000..149bec8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
@@ -0,0 +1,227 @@
+package com.casic.smarttube.model;
+
+
+import java.util.List;
+
+public class UserDetailModel {
+ private int code;
+ private Data data;
+ private String message;
+ private boolean success;
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setData(Data data) {
+ this.data = data;
+ }
+
+ public Data getData() {
+ return data;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public boolean getSuccess() {
+ return success;
+ }
+
+ public static class Data {
+
+ private String account;
+ private String attr1;
+ private String avatar;
+ private String bizData;
+ private List dataScope;
+ private String deptId;
+ private String deptName;
+ private List devices;
+ private String id;
+ private String ipAddr;
+ private String name;
+ private String phone;
+ private List roleList;
+ private List roleNames;
+ private List roleTips;
+ private String scopeType;
+ private String sysData;
+ private String targetId;
+ private String targetName;
+ private String tenantId;
+
+ public void setAccount(String account) {
+ this.account = account;
+ }
+
+ public String getAccount() {
+ return account;
+ }
+
+ public void setAttr1(String attr1) {
+ this.attr1 = attr1;
+ }
+
+ public String getAttr1() {
+ return attr1;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setBizData(String bizData) {
+ this.bizData = bizData;
+ }
+
+ public String getBizData() {
+ return bizData;
+ }
+
+ public void setDataScope(List dataScope) {
+ this.dataScope = dataScope;
+ }
+
+ public List getDataScope() {
+ return dataScope;
+ }
+
+ public void setDeptId(String deptId) {
+ this.deptId = deptId;
+ }
+
+ public String getDeptId() {
+ return deptId;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDevices(List devices) {
+ this.devices = devices;
+ }
+
+ public List getDevices() {
+ return devices;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setIpAddr(String ipAddr) {
+ this.ipAddr = ipAddr;
+ }
+
+ public String getIpAddr() {
+ return ipAddr;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setRoleList(List roleList) {
+ this.roleList = roleList;
+ }
+
+ public List getRoleList() {
+ return roleList;
+ }
+
+ public void setRoleNames(List roleNames) {
+ this.roleNames = roleNames;
+ }
+
+ public List getRoleNames() {
+ return roleNames;
+ }
+
+ public void setRoleTips(List roleTips) {
+ this.roleTips = roleTips;
+ }
+
+ public List getRoleTips() {
+ return roleTips;
+ }
+
+ public void setScopeType(String scopeType) {
+ this.scopeType = scopeType;
+ }
+
+ public String getScopeType() {
+ return scopeType;
+ }
+
+ public void setSysData(String sysData) {
+ this.sysData = sysData;
+ }
+
+ public String getSysData() {
+ return sysData;
+ }
+
+ public void setTargetId(String targetId) {
+ this.targetId = targetId;
+ }
+
+ public String getTargetId() {
+ return targetId;
+ }
+
+ public void setTargetName(String targetName) {
+ this.targetName = targetName;
+ }
+
+ public String getTargetName() {
+ return targetName;
+ }
+
+ public void setTenantId(String tenantId) {
+ this.tenantId = tenantId;
+ }
+
+ public String getTenantId() {
+ return tenantId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
new file mode 100644
index 0000000..b44fec6
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
@@ -0,0 +1,24 @@
+package com.casic.smarttube.utils
+
+import com.pengxh.kt.lite.utils.SaveKeyValues
+
+object AuthenticationHelper {
+
+ fun savePublicKey(key: String) {
+ SaveKeyValues.putValue("keyString", key)
+ }
+
+ val publicKey: String?
+ get() = SaveKeyValues.getValue("keyString", "") as String?
+
+ fun saveToken(token: String?) {
+ SaveKeyValues.putValue("token", token!!)
+ }
+
+ val token: String?
+ get() = SaveKeyValues.getValue("token", "") as String?
+
+ fun removeToken() {
+ SaveKeyValues.removeKey("token")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/Constant.kt b/app/src/main/java/com/casic/smarttube/utils/Constant.kt
deleted file mode 100644
index d921387..0000000
--- a/app/src/main/java/com/casic/smarttube/utils/Constant.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.casic.smarttube.utils
-
-import android.Manifest
-
-
-object Constant {
- val USER_PERMISSIONS = arrayOf(
- Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
- Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
- Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
- Manifest.permission.READ_PHONE_STATE
- )
-
- const val PERMISSIONS_CODE = 999
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
new file mode 100644
index 0000000..bb97c01
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
@@ -0,0 +1,29 @@
+package com.casic.smarttube.utils;
+
+import android.app.Activity
+import android.view.WindowManager
+import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
+
+object DialogHelper {
+ private lateinit var loadingDialog: QMUITipDialog
+
+ fun showLoadingDialog(activity: Activity, message: String?) {
+ loadingDialog = QMUITipDialog.Builder(activity)
+ .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+ .setTipWord(message)
+ .create()
+ if (!activity.isDestroyed) {
+ try {
+ loadingDialog.show()
+ } catch (e: WindowManager.BadTokenException) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ fun dismissLoadingDialog() {
+ if (loadingDialog.isShowing) {
+ loadingDialog.dismiss()
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
new file mode 100644
index 0000000..cee379c
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
@@ -0,0 +1,43 @@
+package com.casic.smarttube.utils
+
+import android.Manifest
+
+
+object LocalConstant {
+ /**
+ * =============================================================================================
+ * Array
+ * =============================================================================================
+ * */
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
+ Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
+ Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.READ_PHONE_STATE
+ )
+
+ /**
+ * =============================================================================================
+ * Int
+ * =============================================================================================
+ * */
+ const val PERMISSIONS_CODE = 999
+
+ /**
+ * =============================================================================================
+ * Long
+ * =============================================================================================
+ * */
+
+
+ /**
+ * =============================================================================================
+ * String
+ * =============================================================================================
+ * */
+ const val USER_DETAIL_MODEL = "userDetailModel"
+ const val SERVER_BASE_URL = "http://111.198.10.15:11304"
+ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val ACCOUNT = "account"
+ const val PASSWORD = "password"
+}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
new file mode 100644
index 0000000..eecfd74
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
@@ -0,0 +1,43 @@
+package com.casic.smarttube.model;
+
+/**
+ * 普通实体类,失败/成功数据结构一致
+ */
+public class CommonResultModel {
+ private int code;
+ private String data;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
new file mode 100644
index 0000000..411674a
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
@@ -0,0 +1,49 @@
+package com.casic.smarttube.model;
+
+public class ErrorMessageModel {
+ private int code;
+ private String data;
+ private String exceptionClazz;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getExceptionClazz() {
+ return exceptionClazz;
+ }
+
+ public void setExceptionClazz(String exceptionClazz) {
+ this.exceptionClazz = exceptionClazz;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
new file mode 100644
index 0000000..6497254
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
@@ -0,0 +1,62 @@
+package com.casic.smarttube.model;
+
+public class LoginResultModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private String kaptcha;
+ private String token;
+
+ public String getKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(String kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
new file mode 100644
index 0000000..d440bc8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
@@ -0,0 +1,80 @@
+package com.casic.smarttube.model;
+
+public class PublicKeyModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private boolean appKaptcha;
+ private boolean kaptcha;
+ private String publicKey;
+ private String sid;
+
+ public boolean isAppKaptcha() {
+ return appKaptcha;
+ }
+
+ public void setAppKaptcha(boolean appKaptcha) {
+ this.appKaptcha = appKaptcha;
+ }
+
+ public boolean isKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(boolean kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getPublicKey() {
+ return publicKey;
+ }
+
+ public void setPublicKey(String publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public String getSid() {
+ return sid;
+ }
+
+ public void setSid(String sid) {
+ this.sid = sid;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
new file mode 100644
index 0000000..149bec8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
@@ -0,0 +1,227 @@
+package com.casic.smarttube.model;
+
+
+import java.util.List;
+
+public class UserDetailModel {
+ private int code;
+ private Data data;
+ private String message;
+ private boolean success;
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setData(Data data) {
+ this.data = data;
+ }
+
+ public Data getData() {
+ return data;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public boolean getSuccess() {
+ return success;
+ }
+
+ public static class Data {
+
+ private String account;
+ private String attr1;
+ private String avatar;
+ private String bizData;
+ private List dataScope;
+ private String deptId;
+ private String deptName;
+ private List devices;
+ private String id;
+ private String ipAddr;
+ private String name;
+ private String phone;
+ private List roleList;
+ private List roleNames;
+ private List roleTips;
+ private String scopeType;
+ private String sysData;
+ private String targetId;
+ private String targetName;
+ private String tenantId;
+
+ public void setAccount(String account) {
+ this.account = account;
+ }
+
+ public String getAccount() {
+ return account;
+ }
+
+ public void setAttr1(String attr1) {
+ this.attr1 = attr1;
+ }
+
+ public String getAttr1() {
+ return attr1;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setBizData(String bizData) {
+ this.bizData = bizData;
+ }
+
+ public String getBizData() {
+ return bizData;
+ }
+
+ public void setDataScope(List dataScope) {
+ this.dataScope = dataScope;
+ }
+
+ public List getDataScope() {
+ return dataScope;
+ }
+
+ public void setDeptId(String deptId) {
+ this.deptId = deptId;
+ }
+
+ public String getDeptId() {
+ return deptId;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDevices(List devices) {
+ this.devices = devices;
+ }
+
+ public List getDevices() {
+ return devices;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setIpAddr(String ipAddr) {
+ this.ipAddr = ipAddr;
+ }
+
+ public String getIpAddr() {
+ return ipAddr;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setRoleList(List roleList) {
+ this.roleList = roleList;
+ }
+
+ public List getRoleList() {
+ return roleList;
+ }
+
+ public void setRoleNames(List roleNames) {
+ this.roleNames = roleNames;
+ }
+
+ public List getRoleNames() {
+ return roleNames;
+ }
+
+ public void setRoleTips(List roleTips) {
+ this.roleTips = roleTips;
+ }
+
+ public List getRoleTips() {
+ return roleTips;
+ }
+
+ public void setScopeType(String scopeType) {
+ this.scopeType = scopeType;
+ }
+
+ public String getScopeType() {
+ return scopeType;
+ }
+
+ public void setSysData(String sysData) {
+ this.sysData = sysData;
+ }
+
+ public String getSysData() {
+ return sysData;
+ }
+
+ public void setTargetId(String targetId) {
+ this.targetId = targetId;
+ }
+
+ public String getTargetId() {
+ return targetId;
+ }
+
+ public void setTargetName(String targetName) {
+ this.targetName = targetName;
+ }
+
+ public String getTargetName() {
+ return targetName;
+ }
+
+ public void setTenantId(String tenantId) {
+ this.tenantId = tenantId;
+ }
+
+ public String getTenantId() {
+ return tenantId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
new file mode 100644
index 0000000..b44fec6
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
@@ -0,0 +1,24 @@
+package com.casic.smarttube.utils
+
+import com.pengxh.kt.lite.utils.SaveKeyValues
+
+object AuthenticationHelper {
+
+ fun savePublicKey(key: String) {
+ SaveKeyValues.putValue("keyString", key)
+ }
+
+ val publicKey: String?
+ get() = SaveKeyValues.getValue("keyString", "") as String?
+
+ fun saveToken(token: String?) {
+ SaveKeyValues.putValue("token", token!!)
+ }
+
+ val token: String?
+ get() = SaveKeyValues.getValue("token", "") as String?
+
+ fun removeToken() {
+ SaveKeyValues.removeKey("token")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/Constant.kt b/app/src/main/java/com/casic/smarttube/utils/Constant.kt
deleted file mode 100644
index d921387..0000000
--- a/app/src/main/java/com/casic/smarttube/utils/Constant.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.casic.smarttube.utils
-
-import android.Manifest
-
-
-object Constant {
- val USER_PERMISSIONS = arrayOf(
- Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
- Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
- Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
- Manifest.permission.READ_PHONE_STATE
- )
-
- const val PERMISSIONS_CODE = 999
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
new file mode 100644
index 0000000..bb97c01
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
@@ -0,0 +1,29 @@
+package com.casic.smarttube.utils;
+
+import android.app.Activity
+import android.view.WindowManager
+import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
+
+object DialogHelper {
+ private lateinit var loadingDialog: QMUITipDialog
+
+ fun showLoadingDialog(activity: Activity, message: String?) {
+ loadingDialog = QMUITipDialog.Builder(activity)
+ .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+ .setTipWord(message)
+ .create()
+ if (!activity.isDestroyed) {
+ try {
+ loadingDialog.show()
+ } catch (e: WindowManager.BadTokenException) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ fun dismissLoadingDialog() {
+ if (loadingDialog.isShowing) {
+ loadingDialog.dismiss()
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
new file mode 100644
index 0000000..cee379c
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
@@ -0,0 +1,43 @@
+package com.casic.smarttube.utils
+
+import android.Manifest
+
+
+object LocalConstant {
+ /**
+ * =============================================================================================
+ * Array
+ * =============================================================================================
+ * */
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
+ Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
+ Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.READ_PHONE_STATE
+ )
+
+ /**
+ * =============================================================================================
+ * Int
+ * =============================================================================================
+ * */
+ const val PERMISSIONS_CODE = 999
+
+ /**
+ * =============================================================================================
+ * Long
+ * =============================================================================================
+ * */
+
+
+ /**
+ * =============================================================================================
+ * String
+ * =============================================================================================
+ * */
+ const val USER_DETAIL_MODEL = "userDetailModel"
+ const val SERVER_BASE_URL = "http://111.198.10.15:11304"
+ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val ACCOUNT = "account"
+ const val PASSWORD = "password"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt b/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt
new file mode 100644
index 0000000..14e2f56
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt
@@ -0,0 +1,58 @@
+package com.casic.smarttube.utils
+
+import android.util.Base64
+import java.security.*
+import java.security.spec.InvalidKeySpecException
+import java.security.spec.X509EncodedKeySpec
+import javax.crypto.BadPaddingException
+import javax.crypto.Cipher
+import javax.crypto.IllegalBlockSizeException
+import javax.crypto.NoSuchPaddingException
+
+object RSAUtils {
+ //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding"
+ private fun processData(srcData: ByteArray, key: Key): ByteArray? { //用来保存处理结果
+ var resultBytes: ByteArray? = null
+ try { //获取Cipher实例
+ val cipher = Cipher.getInstance("RSA/None/PKCS1Padding")
+ //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥
+ cipher.init(Cipher.ENCRYPT_MODE, key)
+ //处理数据
+ resultBytes = cipher.doFinal(srcData)
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ } catch (e: NoSuchPaddingException) {
+ e.printStackTrace()
+ } catch (e: InvalidKeyException) {
+ e.printStackTrace()
+ } catch (e: BadPaddingException) {
+ e.printStackTrace()
+ } catch (e: IllegalBlockSizeException) {
+ e.printStackTrace()
+ }
+ return resultBytes
+ }
+
+ fun encryptDataByPublicKey(srcData: ByteArray, publicKey: PublicKey): String {
+ val resultBytes =
+ processData(srcData, publicKey)
+ return Base64.encodeToString(resultBytes, Base64.DEFAULT)
+ }
+
+ fun keyStrToPublicKey(publicKeyStr: String?): PublicKey? {
+ var publicKey: PublicKey? = null
+ val keyBytes =
+ Base64.decode(publicKeyStr, Base64.DEFAULT)
+ val keySpec =
+ X509EncodedKeySpec(keyBytes)
+ try {
+ val keyFactory = KeyFactory.getInstance("RSA")
+ publicKey = keyFactory.generatePublic(keySpec)
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ } catch (e: InvalidKeySpecException) {
+ e.printStackTrace()
+ }
+ return publicKey
+ }
+}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
new file mode 100644
index 0000000..eecfd74
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
@@ -0,0 +1,43 @@
+package com.casic.smarttube.model;
+
+/**
+ * 普通实体类,失败/成功数据结构一致
+ */
+public class CommonResultModel {
+ private int code;
+ private String data;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
new file mode 100644
index 0000000..411674a
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
@@ -0,0 +1,49 @@
+package com.casic.smarttube.model;
+
+public class ErrorMessageModel {
+ private int code;
+ private String data;
+ private String exceptionClazz;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getExceptionClazz() {
+ return exceptionClazz;
+ }
+
+ public void setExceptionClazz(String exceptionClazz) {
+ this.exceptionClazz = exceptionClazz;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
new file mode 100644
index 0000000..6497254
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
@@ -0,0 +1,62 @@
+package com.casic.smarttube.model;
+
+public class LoginResultModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private String kaptcha;
+ private String token;
+
+ public String getKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(String kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
new file mode 100644
index 0000000..d440bc8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
@@ -0,0 +1,80 @@
+package com.casic.smarttube.model;
+
+public class PublicKeyModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private boolean appKaptcha;
+ private boolean kaptcha;
+ private String publicKey;
+ private String sid;
+
+ public boolean isAppKaptcha() {
+ return appKaptcha;
+ }
+
+ public void setAppKaptcha(boolean appKaptcha) {
+ this.appKaptcha = appKaptcha;
+ }
+
+ public boolean isKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(boolean kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getPublicKey() {
+ return publicKey;
+ }
+
+ public void setPublicKey(String publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public String getSid() {
+ return sid;
+ }
+
+ public void setSid(String sid) {
+ this.sid = sid;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
new file mode 100644
index 0000000..149bec8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
@@ -0,0 +1,227 @@
+package com.casic.smarttube.model;
+
+
+import java.util.List;
+
+public class UserDetailModel {
+ private int code;
+ private Data data;
+ private String message;
+ private boolean success;
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setData(Data data) {
+ this.data = data;
+ }
+
+ public Data getData() {
+ return data;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public boolean getSuccess() {
+ return success;
+ }
+
+ public static class Data {
+
+ private String account;
+ private String attr1;
+ private String avatar;
+ private String bizData;
+ private List dataScope;
+ private String deptId;
+ private String deptName;
+ private List devices;
+ private String id;
+ private String ipAddr;
+ private String name;
+ private String phone;
+ private List roleList;
+ private List roleNames;
+ private List roleTips;
+ private String scopeType;
+ private String sysData;
+ private String targetId;
+ private String targetName;
+ private String tenantId;
+
+ public void setAccount(String account) {
+ this.account = account;
+ }
+
+ public String getAccount() {
+ return account;
+ }
+
+ public void setAttr1(String attr1) {
+ this.attr1 = attr1;
+ }
+
+ public String getAttr1() {
+ return attr1;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setBizData(String bizData) {
+ this.bizData = bizData;
+ }
+
+ public String getBizData() {
+ return bizData;
+ }
+
+ public void setDataScope(List dataScope) {
+ this.dataScope = dataScope;
+ }
+
+ public List getDataScope() {
+ return dataScope;
+ }
+
+ public void setDeptId(String deptId) {
+ this.deptId = deptId;
+ }
+
+ public String getDeptId() {
+ return deptId;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDevices(List devices) {
+ this.devices = devices;
+ }
+
+ public List getDevices() {
+ return devices;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setIpAddr(String ipAddr) {
+ this.ipAddr = ipAddr;
+ }
+
+ public String getIpAddr() {
+ return ipAddr;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setRoleList(List roleList) {
+ this.roleList = roleList;
+ }
+
+ public List getRoleList() {
+ return roleList;
+ }
+
+ public void setRoleNames(List roleNames) {
+ this.roleNames = roleNames;
+ }
+
+ public List getRoleNames() {
+ return roleNames;
+ }
+
+ public void setRoleTips(List roleTips) {
+ this.roleTips = roleTips;
+ }
+
+ public List getRoleTips() {
+ return roleTips;
+ }
+
+ public void setScopeType(String scopeType) {
+ this.scopeType = scopeType;
+ }
+
+ public String getScopeType() {
+ return scopeType;
+ }
+
+ public void setSysData(String sysData) {
+ this.sysData = sysData;
+ }
+
+ public String getSysData() {
+ return sysData;
+ }
+
+ public void setTargetId(String targetId) {
+ this.targetId = targetId;
+ }
+
+ public String getTargetId() {
+ return targetId;
+ }
+
+ public void setTargetName(String targetName) {
+ this.targetName = targetName;
+ }
+
+ public String getTargetName() {
+ return targetName;
+ }
+
+ public void setTenantId(String tenantId) {
+ this.tenantId = tenantId;
+ }
+
+ public String getTenantId() {
+ return tenantId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
new file mode 100644
index 0000000..b44fec6
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
@@ -0,0 +1,24 @@
+package com.casic.smarttube.utils
+
+import com.pengxh.kt.lite.utils.SaveKeyValues
+
+object AuthenticationHelper {
+
+ fun savePublicKey(key: String) {
+ SaveKeyValues.putValue("keyString", key)
+ }
+
+ val publicKey: String?
+ get() = SaveKeyValues.getValue("keyString", "") as String?
+
+ fun saveToken(token: String?) {
+ SaveKeyValues.putValue("token", token!!)
+ }
+
+ val token: String?
+ get() = SaveKeyValues.getValue("token", "") as String?
+
+ fun removeToken() {
+ SaveKeyValues.removeKey("token")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/Constant.kt b/app/src/main/java/com/casic/smarttube/utils/Constant.kt
deleted file mode 100644
index d921387..0000000
--- a/app/src/main/java/com/casic/smarttube/utils/Constant.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.casic.smarttube.utils
-
-import android.Manifest
-
-
-object Constant {
- val USER_PERMISSIONS = arrayOf(
- Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
- Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
- Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
- Manifest.permission.READ_PHONE_STATE
- )
-
- const val PERMISSIONS_CODE = 999
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
new file mode 100644
index 0000000..bb97c01
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
@@ -0,0 +1,29 @@
+package com.casic.smarttube.utils;
+
+import android.app.Activity
+import android.view.WindowManager
+import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
+
+object DialogHelper {
+ private lateinit var loadingDialog: QMUITipDialog
+
+ fun showLoadingDialog(activity: Activity, message: String?) {
+ loadingDialog = QMUITipDialog.Builder(activity)
+ .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+ .setTipWord(message)
+ .create()
+ if (!activity.isDestroyed) {
+ try {
+ loadingDialog.show()
+ } catch (e: WindowManager.BadTokenException) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ fun dismissLoadingDialog() {
+ if (loadingDialog.isShowing) {
+ loadingDialog.dismiss()
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
new file mode 100644
index 0000000..cee379c
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
@@ -0,0 +1,43 @@
+package com.casic.smarttube.utils
+
+import android.Manifest
+
+
+object LocalConstant {
+ /**
+ * =============================================================================================
+ * Array
+ * =============================================================================================
+ * */
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
+ Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
+ Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.READ_PHONE_STATE
+ )
+
+ /**
+ * =============================================================================================
+ * Int
+ * =============================================================================================
+ * */
+ const val PERMISSIONS_CODE = 999
+
+ /**
+ * =============================================================================================
+ * Long
+ * =============================================================================================
+ * */
+
+
+ /**
+ * =============================================================================================
+ * String
+ * =============================================================================================
+ * */
+ const val USER_DETAIL_MODEL = "userDetailModel"
+ const val SERVER_BASE_URL = "http://111.198.10.15:11304"
+ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val ACCOUNT = "account"
+ const val PASSWORD = "password"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt b/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt
new file mode 100644
index 0000000..14e2f56
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt
@@ -0,0 +1,58 @@
+package com.casic.smarttube.utils
+
+import android.util.Base64
+import java.security.*
+import java.security.spec.InvalidKeySpecException
+import java.security.spec.X509EncodedKeySpec
+import javax.crypto.BadPaddingException
+import javax.crypto.Cipher
+import javax.crypto.IllegalBlockSizeException
+import javax.crypto.NoSuchPaddingException
+
+object RSAUtils {
+ //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding"
+ private fun processData(srcData: ByteArray, key: Key): ByteArray? { //用来保存处理结果
+ var resultBytes: ByteArray? = null
+ try { //获取Cipher实例
+ val cipher = Cipher.getInstance("RSA/None/PKCS1Padding")
+ //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥
+ cipher.init(Cipher.ENCRYPT_MODE, key)
+ //处理数据
+ resultBytes = cipher.doFinal(srcData)
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ } catch (e: NoSuchPaddingException) {
+ e.printStackTrace()
+ } catch (e: InvalidKeyException) {
+ e.printStackTrace()
+ } catch (e: BadPaddingException) {
+ e.printStackTrace()
+ } catch (e: IllegalBlockSizeException) {
+ e.printStackTrace()
+ }
+ return resultBytes
+ }
+
+ fun encryptDataByPublicKey(srcData: ByteArray, publicKey: PublicKey): String {
+ val resultBytes =
+ processData(srcData, publicKey)
+ return Base64.encodeToString(resultBytes, Base64.DEFAULT)
+ }
+
+ fun keyStrToPublicKey(publicKeyStr: String?): PublicKey? {
+ var publicKey: PublicKey? = null
+ val keyBytes =
+ Base64.decode(publicKeyStr, Base64.DEFAULT)
+ val keySpec =
+ X509EncodedKeySpec(keyBytes)
+ try {
+ val keyFactory = KeyFactory.getInstance("RSA")
+ publicKey = keyFactory.generatePublic(keySpec)
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ } catch (e: InvalidKeySpecException) {
+ e.printStackTrace()
+ }
+ return publicKey
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt
new file mode 100644
index 0000000..660496f
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt
@@ -0,0 +1,47 @@
+package com.casic.smarttube.utils.retrofit;
+
+import android.util.Log
+import com.casic.smarttube.utils.LocalConstant
+import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import okhttp3.OkHttpClient
+import okhttp3.logging.HttpLoggingInterceptor
+import org.jetbrains.annotations.NotNull
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+import retrofit2.converter.scalars.ScalarsConverterFactory
+import java.util.concurrent.TimeUnit
+
+object RetrofitFactory {
+ private const val kTag = "RetrofitFactory"
+
+ private val httpClient: OkHttpClient by lazy { createOKHttpClient() }
+
+ fun createRetrofit(clazz: Class): T {
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return Retrofit.Builder()
+ .baseUrl(defaultValue)
+ .addConverterFactory(ScalarsConverterFactory.create()) //字符串转换器
+ .addConverterFactory(GsonConverterFactory.create()) //Gson转换器
+ .addCallAdapterFactory(CoroutineCallAdapterFactory.invoke()) //协程请求适配器
+ .client(httpClient) //log拦截器
+ .build().create(clazz)
+ }
+
+ private fun createOKHttpClient(): OkHttpClient { //日志显示级别
+ val interceptor =
+ HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
+ override fun log(@NotNull message: String) {
+ Log.d(kTag, ">>>>> $message")
+ }
+ })
+ interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
+ val builder = OkHttpClient.Builder()
+ .connectTimeout(15, TimeUnit.SECONDS)
+ .readTimeout(15, TimeUnit.SECONDS)
+ .writeTimeout(15, TimeUnit.SECONDS)
+ return builder.addInterceptor(interceptor).build()
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
new file mode 100644
index 0000000..eecfd74
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
@@ -0,0 +1,43 @@
+package com.casic.smarttube.model;
+
+/**
+ * 普通实体类,失败/成功数据结构一致
+ */
+public class CommonResultModel {
+ private int code;
+ private String data;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
new file mode 100644
index 0000000..411674a
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
@@ -0,0 +1,49 @@
+package com.casic.smarttube.model;
+
+public class ErrorMessageModel {
+ private int code;
+ private String data;
+ private String exceptionClazz;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getExceptionClazz() {
+ return exceptionClazz;
+ }
+
+ public void setExceptionClazz(String exceptionClazz) {
+ this.exceptionClazz = exceptionClazz;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
new file mode 100644
index 0000000..6497254
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
@@ -0,0 +1,62 @@
+package com.casic.smarttube.model;
+
+public class LoginResultModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private String kaptcha;
+ private String token;
+
+ public String getKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(String kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
new file mode 100644
index 0000000..d440bc8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
@@ -0,0 +1,80 @@
+package com.casic.smarttube.model;
+
+public class PublicKeyModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private boolean appKaptcha;
+ private boolean kaptcha;
+ private String publicKey;
+ private String sid;
+
+ public boolean isAppKaptcha() {
+ return appKaptcha;
+ }
+
+ public void setAppKaptcha(boolean appKaptcha) {
+ this.appKaptcha = appKaptcha;
+ }
+
+ public boolean isKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(boolean kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getPublicKey() {
+ return publicKey;
+ }
+
+ public void setPublicKey(String publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public String getSid() {
+ return sid;
+ }
+
+ public void setSid(String sid) {
+ this.sid = sid;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
new file mode 100644
index 0000000..149bec8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
@@ -0,0 +1,227 @@
+package com.casic.smarttube.model;
+
+
+import java.util.List;
+
+public class UserDetailModel {
+ private int code;
+ private Data data;
+ private String message;
+ private boolean success;
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setData(Data data) {
+ this.data = data;
+ }
+
+ public Data getData() {
+ return data;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public boolean getSuccess() {
+ return success;
+ }
+
+ public static class Data {
+
+ private String account;
+ private String attr1;
+ private String avatar;
+ private String bizData;
+ private List dataScope;
+ private String deptId;
+ private String deptName;
+ private List devices;
+ private String id;
+ private String ipAddr;
+ private String name;
+ private String phone;
+ private List roleList;
+ private List roleNames;
+ private List roleTips;
+ private String scopeType;
+ private String sysData;
+ private String targetId;
+ private String targetName;
+ private String tenantId;
+
+ public void setAccount(String account) {
+ this.account = account;
+ }
+
+ public String getAccount() {
+ return account;
+ }
+
+ public void setAttr1(String attr1) {
+ this.attr1 = attr1;
+ }
+
+ public String getAttr1() {
+ return attr1;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setBizData(String bizData) {
+ this.bizData = bizData;
+ }
+
+ public String getBizData() {
+ return bizData;
+ }
+
+ public void setDataScope(List dataScope) {
+ this.dataScope = dataScope;
+ }
+
+ public List getDataScope() {
+ return dataScope;
+ }
+
+ public void setDeptId(String deptId) {
+ this.deptId = deptId;
+ }
+
+ public String getDeptId() {
+ return deptId;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDevices(List devices) {
+ this.devices = devices;
+ }
+
+ public List getDevices() {
+ return devices;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setIpAddr(String ipAddr) {
+ this.ipAddr = ipAddr;
+ }
+
+ public String getIpAddr() {
+ return ipAddr;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setRoleList(List roleList) {
+ this.roleList = roleList;
+ }
+
+ public List getRoleList() {
+ return roleList;
+ }
+
+ public void setRoleNames(List roleNames) {
+ this.roleNames = roleNames;
+ }
+
+ public List getRoleNames() {
+ return roleNames;
+ }
+
+ public void setRoleTips(List roleTips) {
+ this.roleTips = roleTips;
+ }
+
+ public List getRoleTips() {
+ return roleTips;
+ }
+
+ public void setScopeType(String scopeType) {
+ this.scopeType = scopeType;
+ }
+
+ public String getScopeType() {
+ return scopeType;
+ }
+
+ public void setSysData(String sysData) {
+ this.sysData = sysData;
+ }
+
+ public String getSysData() {
+ return sysData;
+ }
+
+ public void setTargetId(String targetId) {
+ this.targetId = targetId;
+ }
+
+ public String getTargetId() {
+ return targetId;
+ }
+
+ public void setTargetName(String targetName) {
+ this.targetName = targetName;
+ }
+
+ public String getTargetName() {
+ return targetName;
+ }
+
+ public void setTenantId(String tenantId) {
+ this.tenantId = tenantId;
+ }
+
+ public String getTenantId() {
+ return tenantId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
new file mode 100644
index 0000000..b44fec6
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
@@ -0,0 +1,24 @@
+package com.casic.smarttube.utils
+
+import com.pengxh.kt.lite.utils.SaveKeyValues
+
+object AuthenticationHelper {
+
+ fun savePublicKey(key: String) {
+ SaveKeyValues.putValue("keyString", key)
+ }
+
+ val publicKey: String?
+ get() = SaveKeyValues.getValue("keyString", "") as String?
+
+ fun saveToken(token: String?) {
+ SaveKeyValues.putValue("token", token!!)
+ }
+
+ val token: String?
+ get() = SaveKeyValues.getValue("token", "") as String?
+
+ fun removeToken() {
+ SaveKeyValues.removeKey("token")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/Constant.kt b/app/src/main/java/com/casic/smarttube/utils/Constant.kt
deleted file mode 100644
index d921387..0000000
--- a/app/src/main/java/com/casic/smarttube/utils/Constant.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.casic.smarttube.utils
-
-import android.Manifest
-
-
-object Constant {
- val USER_PERMISSIONS = arrayOf(
- Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
- Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
- Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
- Manifest.permission.READ_PHONE_STATE
- )
-
- const val PERMISSIONS_CODE = 999
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
new file mode 100644
index 0000000..bb97c01
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
@@ -0,0 +1,29 @@
+package com.casic.smarttube.utils;
+
+import android.app.Activity
+import android.view.WindowManager
+import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
+
+object DialogHelper {
+ private lateinit var loadingDialog: QMUITipDialog
+
+ fun showLoadingDialog(activity: Activity, message: String?) {
+ loadingDialog = QMUITipDialog.Builder(activity)
+ .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+ .setTipWord(message)
+ .create()
+ if (!activity.isDestroyed) {
+ try {
+ loadingDialog.show()
+ } catch (e: WindowManager.BadTokenException) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ fun dismissLoadingDialog() {
+ if (loadingDialog.isShowing) {
+ loadingDialog.dismiss()
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
new file mode 100644
index 0000000..cee379c
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
@@ -0,0 +1,43 @@
+package com.casic.smarttube.utils
+
+import android.Manifest
+
+
+object LocalConstant {
+ /**
+ * =============================================================================================
+ * Array
+ * =============================================================================================
+ * */
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
+ Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
+ Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.READ_PHONE_STATE
+ )
+
+ /**
+ * =============================================================================================
+ * Int
+ * =============================================================================================
+ * */
+ const val PERMISSIONS_CODE = 999
+
+ /**
+ * =============================================================================================
+ * Long
+ * =============================================================================================
+ * */
+
+
+ /**
+ * =============================================================================================
+ * String
+ * =============================================================================================
+ * */
+ const val USER_DETAIL_MODEL = "userDetailModel"
+ const val SERVER_BASE_URL = "http://111.198.10.15:11304"
+ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val ACCOUNT = "account"
+ const val PASSWORD = "password"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt b/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt
new file mode 100644
index 0000000..14e2f56
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt
@@ -0,0 +1,58 @@
+package com.casic.smarttube.utils
+
+import android.util.Base64
+import java.security.*
+import java.security.spec.InvalidKeySpecException
+import java.security.spec.X509EncodedKeySpec
+import javax.crypto.BadPaddingException
+import javax.crypto.Cipher
+import javax.crypto.IllegalBlockSizeException
+import javax.crypto.NoSuchPaddingException
+
+object RSAUtils {
+ //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding"
+ private fun processData(srcData: ByteArray, key: Key): ByteArray? { //用来保存处理结果
+ var resultBytes: ByteArray? = null
+ try { //获取Cipher实例
+ val cipher = Cipher.getInstance("RSA/None/PKCS1Padding")
+ //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥
+ cipher.init(Cipher.ENCRYPT_MODE, key)
+ //处理数据
+ resultBytes = cipher.doFinal(srcData)
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ } catch (e: NoSuchPaddingException) {
+ e.printStackTrace()
+ } catch (e: InvalidKeyException) {
+ e.printStackTrace()
+ } catch (e: BadPaddingException) {
+ e.printStackTrace()
+ } catch (e: IllegalBlockSizeException) {
+ e.printStackTrace()
+ }
+ return resultBytes
+ }
+
+ fun encryptDataByPublicKey(srcData: ByteArray, publicKey: PublicKey): String {
+ val resultBytes =
+ processData(srcData, publicKey)
+ return Base64.encodeToString(resultBytes, Base64.DEFAULT)
+ }
+
+ fun keyStrToPublicKey(publicKeyStr: String?): PublicKey? {
+ var publicKey: PublicKey? = null
+ val keyBytes =
+ Base64.decode(publicKeyStr, Base64.DEFAULT)
+ val keySpec =
+ X509EncodedKeySpec(keyBytes)
+ try {
+ val keyFactory = KeyFactory.getInstance("RSA")
+ publicKey = keyFactory.generatePublic(keySpec)
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ } catch (e: InvalidKeySpecException) {
+ e.printStackTrace()
+ }
+ return publicKey
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt
new file mode 100644
index 0000000..660496f
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt
@@ -0,0 +1,47 @@
+package com.casic.smarttube.utils.retrofit;
+
+import android.util.Log
+import com.casic.smarttube.utils.LocalConstant
+import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import okhttp3.OkHttpClient
+import okhttp3.logging.HttpLoggingInterceptor
+import org.jetbrains.annotations.NotNull
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+import retrofit2.converter.scalars.ScalarsConverterFactory
+import java.util.concurrent.TimeUnit
+
+object RetrofitFactory {
+ private const val kTag = "RetrofitFactory"
+
+ private val httpClient: OkHttpClient by lazy { createOKHttpClient() }
+
+ fun createRetrofit(clazz: Class): T {
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return Retrofit.Builder()
+ .baseUrl(defaultValue)
+ .addConverterFactory(ScalarsConverterFactory.create()) //字符串转换器
+ .addConverterFactory(GsonConverterFactory.create()) //Gson转换器
+ .addCallAdapterFactory(CoroutineCallAdapterFactory.invoke()) //协程请求适配器
+ .client(httpClient) //log拦截器
+ .build().create(clazz)
+ }
+
+ private fun createOKHttpClient(): OkHttpClient { //日志显示级别
+ val interceptor =
+ HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
+ override fun log(@NotNull message: String) {
+ Log.d(kTag, ">>>>> $message")
+ }
+ })
+ interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
+ val builder = OkHttpClient.Builder()
+ .connectTimeout(15, TimeUnit.SECONDS)
+ .readTimeout(15, TimeUnit.SECONDS)
+ .writeTimeout(15, TimeUnit.SECONDS)
+ return builder.addInterceptor(interceptor).build()
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt
new file mode 100644
index 0000000..6dad7b3
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt
@@ -0,0 +1,52 @@
+package com.casic.smarttube.utils.retrofit
+
+import okhttp3.MultipartBody
+import retrofit2.http.*
+
+
+interface RetrofitService {
+ /**
+ * PublicKey校验
+ */
+ @GET("/config/baseConfig")
+ suspend fun obtainPublicKey(): String
+
+ /**
+ * 登录并获取Token
+ *
+ * @param sid
+ * @param account 用户名
+ * @param secretKey 加密后的密码
+ */
+ @FormUrlEncoded
+ @POST("/user/login")
+ suspend fun obtainLoginResult(
+ @Field("sid") sid: String,
+ @Field("username") account: String,
+ @Field("password") secretKey: String
+ ): String
+
+ /**
+ * 退出登录
+ */
+ @GET("/user/logout")
+ suspend fun loginOut(@Header("token") token: String): String
+
+ /**
+ * 获取用户信息
+ */
+ @GET("/user/info")
+ suspend fun obtainUserDetail(@Header("token") token: String): String
+
+ /**
+ * 上传图片
+ * 系统路径static拼接图片返回路径
+ * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg
+ */
+ @Multipart
+ @POST("/imageUpload")
+ suspend fun uploadImage(
+ @Header("token") token: String,
+ @Part file: MultipartBody.Part
+ ): String
+}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
new file mode 100644
index 0000000..eecfd74
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
@@ -0,0 +1,43 @@
+package com.casic.smarttube.model;
+
+/**
+ * 普通实体类,失败/成功数据结构一致
+ */
+public class CommonResultModel {
+ private int code;
+ private String data;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
new file mode 100644
index 0000000..411674a
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
@@ -0,0 +1,49 @@
+package com.casic.smarttube.model;
+
+public class ErrorMessageModel {
+ private int code;
+ private String data;
+ private String exceptionClazz;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getExceptionClazz() {
+ return exceptionClazz;
+ }
+
+ public void setExceptionClazz(String exceptionClazz) {
+ this.exceptionClazz = exceptionClazz;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
new file mode 100644
index 0000000..6497254
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
@@ -0,0 +1,62 @@
+package com.casic.smarttube.model;
+
+public class LoginResultModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private String kaptcha;
+ private String token;
+
+ public String getKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(String kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
new file mode 100644
index 0000000..d440bc8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
@@ -0,0 +1,80 @@
+package com.casic.smarttube.model;
+
+public class PublicKeyModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private boolean appKaptcha;
+ private boolean kaptcha;
+ private String publicKey;
+ private String sid;
+
+ public boolean isAppKaptcha() {
+ return appKaptcha;
+ }
+
+ public void setAppKaptcha(boolean appKaptcha) {
+ this.appKaptcha = appKaptcha;
+ }
+
+ public boolean isKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(boolean kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getPublicKey() {
+ return publicKey;
+ }
+
+ public void setPublicKey(String publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public String getSid() {
+ return sid;
+ }
+
+ public void setSid(String sid) {
+ this.sid = sid;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
new file mode 100644
index 0000000..149bec8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
@@ -0,0 +1,227 @@
+package com.casic.smarttube.model;
+
+
+import java.util.List;
+
+public class UserDetailModel {
+ private int code;
+ private Data data;
+ private String message;
+ private boolean success;
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setData(Data data) {
+ this.data = data;
+ }
+
+ public Data getData() {
+ return data;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public boolean getSuccess() {
+ return success;
+ }
+
+ public static class Data {
+
+ private String account;
+ private String attr1;
+ private String avatar;
+ private String bizData;
+ private List dataScope;
+ private String deptId;
+ private String deptName;
+ private List devices;
+ private String id;
+ private String ipAddr;
+ private String name;
+ private String phone;
+ private List roleList;
+ private List roleNames;
+ private List roleTips;
+ private String scopeType;
+ private String sysData;
+ private String targetId;
+ private String targetName;
+ private String tenantId;
+
+ public void setAccount(String account) {
+ this.account = account;
+ }
+
+ public String getAccount() {
+ return account;
+ }
+
+ public void setAttr1(String attr1) {
+ this.attr1 = attr1;
+ }
+
+ public String getAttr1() {
+ return attr1;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setBizData(String bizData) {
+ this.bizData = bizData;
+ }
+
+ public String getBizData() {
+ return bizData;
+ }
+
+ public void setDataScope(List dataScope) {
+ this.dataScope = dataScope;
+ }
+
+ public List getDataScope() {
+ return dataScope;
+ }
+
+ public void setDeptId(String deptId) {
+ this.deptId = deptId;
+ }
+
+ public String getDeptId() {
+ return deptId;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDevices(List devices) {
+ this.devices = devices;
+ }
+
+ public List getDevices() {
+ return devices;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setIpAddr(String ipAddr) {
+ this.ipAddr = ipAddr;
+ }
+
+ public String getIpAddr() {
+ return ipAddr;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setRoleList(List roleList) {
+ this.roleList = roleList;
+ }
+
+ public List getRoleList() {
+ return roleList;
+ }
+
+ public void setRoleNames(List roleNames) {
+ this.roleNames = roleNames;
+ }
+
+ public List getRoleNames() {
+ return roleNames;
+ }
+
+ public void setRoleTips(List roleTips) {
+ this.roleTips = roleTips;
+ }
+
+ public List getRoleTips() {
+ return roleTips;
+ }
+
+ public void setScopeType(String scopeType) {
+ this.scopeType = scopeType;
+ }
+
+ public String getScopeType() {
+ return scopeType;
+ }
+
+ public void setSysData(String sysData) {
+ this.sysData = sysData;
+ }
+
+ public String getSysData() {
+ return sysData;
+ }
+
+ public void setTargetId(String targetId) {
+ this.targetId = targetId;
+ }
+
+ public String getTargetId() {
+ return targetId;
+ }
+
+ public void setTargetName(String targetName) {
+ this.targetName = targetName;
+ }
+
+ public String getTargetName() {
+ return targetName;
+ }
+
+ public void setTenantId(String tenantId) {
+ this.tenantId = tenantId;
+ }
+
+ public String getTenantId() {
+ return tenantId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
new file mode 100644
index 0000000..b44fec6
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
@@ -0,0 +1,24 @@
+package com.casic.smarttube.utils
+
+import com.pengxh.kt.lite.utils.SaveKeyValues
+
+object AuthenticationHelper {
+
+ fun savePublicKey(key: String) {
+ SaveKeyValues.putValue("keyString", key)
+ }
+
+ val publicKey: String?
+ get() = SaveKeyValues.getValue("keyString", "") as String?
+
+ fun saveToken(token: String?) {
+ SaveKeyValues.putValue("token", token!!)
+ }
+
+ val token: String?
+ get() = SaveKeyValues.getValue("token", "") as String?
+
+ fun removeToken() {
+ SaveKeyValues.removeKey("token")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/Constant.kt b/app/src/main/java/com/casic/smarttube/utils/Constant.kt
deleted file mode 100644
index d921387..0000000
--- a/app/src/main/java/com/casic/smarttube/utils/Constant.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.casic.smarttube.utils
-
-import android.Manifest
-
-
-object Constant {
- val USER_PERMISSIONS = arrayOf(
- Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
- Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
- Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
- Manifest.permission.READ_PHONE_STATE
- )
-
- const val PERMISSIONS_CODE = 999
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
new file mode 100644
index 0000000..bb97c01
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
@@ -0,0 +1,29 @@
+package com.casic.smarttube.utils;
+
+import android.app.Activity
+import android.view.WindowManager
+import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
+
+object DialogHelper {
+ private lateinit var loadingDialog: QMUITipDialog
+
+ fun showLoadingDialog(activity: Activity, message: String?) {
+ loadingDialog = QMUITipDialog.Builder(activity)
+ .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+ .setTipWord(message)
+ .create()
+ if (!activity.isDestroyed) {
+ try {
+ loadingDialog.show()
+ } catch (e: WindowManager.BadTokenException) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ fun dismissLoadingDialog() {
+ if (loadingDialog.isShowing) {
+ loadingDialog.dismiss()
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
new file mode 100644
index 0000000..cee379c
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
@@ -0,0 +1,43 @@
+package com.casic.smarttube.utils
+
+import android.Manifest
+
+
+object LocalConstant {
+ /**
+ * =============================================================================================
+ * Array
+ * =============================================================================================
+ * */
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
+ Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
+ Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.READ_PHONE_STATE
+ )
+
+ /**
+ * =============================================================================================
+ * Int
+ * =============================================================================================
+ * */
+ const val PERMISSIONS_CODE = 999
+
+ /**
+ * =============================================================================================
+ * Long
+ * =============================================================================================
+ * */
+
+
+ /**
+ * =============================================================================================
+ * String
+ * =============================================================================================
+ * */
+ const val USER_DETAIL_MODEL = "userDetailModel"
+ const val SERVER_BASE_URL = "http://111.198.10.15:11304"
+ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val ACCOUNT = "account"
+ const val PASSWORD = "password"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt b/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt
new file mode 100644
index 0000000..14e2f56
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt
@@ -0,0 +1,58 @@
+package com.casic.smarttube.utils
+
+import android.util.Base64
+import java.security.*
+import java.security.spec.InvalidKeySpecException
+import java.security.spec.X509EncodedKeySpec
+import javax.crypto.BadPaddingException
+import javax.crypto.Cipher
+import javax.crypto.IllegalBlockSizeException
+import javax.crypto.NoSuchPaddingException
+
+object RSAUtils {
+ //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding"
+ private fun processData(srcData: ByteArray, key: Key): ByteArray? { //用来保存处理结果
+ var resultBytes: ByteArray? = null
+ try { //获取Cipher实例
+ val cipher = Cipher.getInstance("RSA/None/PKCS1Padding")
+ //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥
+ cipher.init(Cipher.ENCRYPT_MODE, key)
+ //处理数据
+ resultBytes = cipher.doFinal(srcData)
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ } catch (e: NoSuchPaddingException) {
+ e.printStackTrace()
+ } catch (e: InvalidKeyException) {
+ e.printStackTrace()
+ } catch (e: BadPaddingException) {
+ e.printStackTrace()
+ } catch (e: IllegalBlockSizeException) {
+ e.printStackTrace()
+ }
+ return resultBytes
+ }
+
+ fun encryptDataByPublicKey(srcData: ByteArray, publicKey: PublicKey): String {
+ val resultBytes =
+ processData(srcData, publicKey)
+ return Base64.encodeToString(resultBytes, Base64.DEFAULT)
+ }
+
+ fun keyStrToPublicKey(publicKeyStr: String?): PublicKey? {
+ var publicKey: PublicKey? = null
+ val keyBytes =
+ Base64.decode(publicKeyStr, Base64.DEFAULT)
+ val keySpec =
+ X509EncodedKeySpec(keyBytes)
+ try {
+ val keyFactory = KeyFactory.getInstance("RSA")
+ publicKey = keyFactory.generatePublic(keySpec)
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ } catch (e: InvalidKeySpecException) {
+ e.printStackTrace()
+ }
+ return publicKey
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt
new file mode 100644
index 0000000..660496f
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt
@@ -0,0 +1,47 @@
+package com.casic.smarttube.utils.retrofit;
+
+import android.util.Log
+import com.casic.smarttube.utils.LocalConstant
+import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import okhttp3.OkHttpClient
+import okhttp3.logging.HttpLoggingInterceptor
+import org.jetbrains.annotations.NotNull
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+import retrofit2.converter.scalars.ScalarsConverterFactory
+import java.util.concurrent.TimeUnit
+
+object RetrofitFactory {
+ private const val kTag = "RetrofitFactory"
+
+ private val httpClient: OkHttpClient by lazy { createOKHttpClient() }
+
+ fun createRetrofit(clazz: Class): T {
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return Retrofit.Builder()
+ .baseUrl(defaultValue)
+ .addConverterFactory(ScalarsConverterFactory.create()) //字符串转换器
+ .addConverterFactory(GsonConverterFactory.create()) //Gson转换器
+ .addCallAdapterFactory(CoroutineCallAdapterFactory.invoke()) //协程请求适配器
+ .client(httpClient) //log拦截器
+ .build().create(clazz)
+ }
+
+ private fun createOKHttpClient(): OkHttpClient { //日志显示级别
+ val interceptor =
+ HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
+ override fun log(@NotNull message: String) {
+ Log.d(kTag, ">>>>> $message")
+ }
+ })
+ interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
+ val builder = OkHttpClient.Builder()
+ .connectTimeout(15, TimeUnit.SECONDS)
+ .readTimeout(15, TimeUnit.SECONDS)
+ .writeTimeout(15, TimeUnit.SECONDS)
+ return builder.addInterceptor(interceptor).build()
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt
new file mode 100644
index 0000000..6dad7b3
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt
@@ -0,0 +1,52 @@
+package com.casic.smarttube.utils.retrofit
+
+import okhttp3.MultipartBody
+import retrofit2.http.*
+
+
+interface RetrofitService {
+ /**
+ * PublicKey校验
+ */
+ @GET("/config/baseConfig")
+ suspend fun obtainPublicKey(): String
+
+ /**
+ * 登录并获取Token
+ *
+ * @param sid
+ * @param account 用户名
+ * @param secretKey 加密后的密码
+ */
+ @FormUrlEncoded
+ @POST("/user/login")
+ suspend fun obtainLoginResult(
+ @Field("sid") sid: String,
+ @Field("username") account: String,
+ @Field("password") secretKey: String
+ ): String
+
+ /**
+ * 退出登录
+ */
+ @GET("/user/logout")
+ suspend fun loginOut(@Header("token") token: String): String
+
+ /**
+ * 获取用户信息
+ */
+ @GET("/user/info")
+ suspend fun obtainUserDetail(@Header("token") token: String): String
+
+ /**
+ * 上传图片
+ * 系统路径static拼接图片返回路径
+ * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg
+ */
+ @Multipart
+ @POST("/imageUpload")
+ suspend fun uploadImage(
+ @Header("token") token: String,
+ @Part file: MultipartBody.Part
+ ): String
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt
new file mode 100644
index 0000000..db99cfb
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt
@@ -0,0 +1,50 @@
+package com.casic.smarttube.utils.retrofit
+
+import com.casic.smarttube.utils.AuthenticationHelper
+import okhttp3.MediaType.Companion.toMediaTypeOrNull
+import okhttp3.MultipartBody
+import okhttp3.RequestBody
+import java.io.File
+
+
+object RetrofitServiceManager {
+
+ private val api by lazy { RetrofitFactory.createRetrofit(RetrofitService::class.java) }
+
+ /**
+ * 验证PublicKey
+ */
+ suspend fun authenticate(): String {
+ return api.obtainPublicKey()
+ }
+
+ /**
+ * 登录并获取Token
+ */
+ suspend fun login(sid: String, account: String, secretKey: String): String {
+ return api.obtainLoginResult(sid, account, secretKey)
+ }
+
+ /**
+ * 退出登录
+ */
+ suspend fun loginOut(): String {
+ return api.loginOut(AuthenticationHelper.token!!)
+ }
+
+ /**
+ * 获取用户信息
+ */
+ suspend fun obtainUserDetail(): String {
+ return api.obtainUserDetail(AuthenticationHelper.token!!)
+ }
+
+ /**
+ * 上传图片
+ */
+ suspend fun uploadImage(image: File): String {
+ val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image)
+ val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody)
+ return api.uploadImage(AuthenticationHelper.token!!, imagePart)
+ }
+}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
new file mode 100644
index 0000000..eecfd74
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
@@ -0,0 +1,43 @@
+package com.casic.smarttube.model;
+
+/**
+ * 普通实体类,失败/成功数据结构一致
+ */
+public class CommonResultModel {
+ private int code;
+ private String data;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
new file mode 100644
index 0000000..411674a
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
@@ -0,0 +1,49 @@
+package com.casic.smarttube.model;
+
+public class ErrorMessageModel {
+ private int code;
+ private String data;
+ private String exceptionClazz;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getExceptionClazz() {
+ return exceptionClazz;
+ }
+
+ public void setExceptionClazz(String exceptionClazz) {
+ this.exceptionClazz = exceptionClazz;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
new file mode 100644
index 0000000..6497254
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
@@ -0,0 +1,62 @@
+package com.casic.smarttube.model;
+
+public class LoginResultModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private String kaptcha;
+ private String token;
+
+ public String getKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(String kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
new file mode 100644
index 0000000..d440bc8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
@@ -0,0 +1,80 @@
+package com.casic.smarttube.model;
+
+public class PublicKeyModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private boolean appKaptcha;
+ private boolean kaptcha;
+ private String publicKey;
+ private String sid;
+
+ public boolean isAppKaptcha() {
+ return appKaptcha;
+ }
+
+ public void setAppKaptcha(boolean appKaptcha) {
+ this.appKaptcha = appKaptcha;
+ }
+
+ public boolean isKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(boolean kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getPublicKey() {
+ return publicKey;
+ }
+
+ public void setPublicKey(String publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public String getSid() {
+ return sid;
+ }
+
+ public void setSid(String sid) {
+ this.sid = sid;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
new file mode 100644
index 0000000..149bec8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
@@ -0,0 +1,227 @@
+package com.casic.smarttube.model;
+
+
+import java.util.List;
+
+public class UserDetailModel {
+ private int code;
+ private Data data;
+ private String message;
+ private boolean success;
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setData(Data data) {
+ this.data = data;
+ }
+
+ public Data getData() {
+ return data;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public boolean getSuccess() {
+ return success;
+ }
+
+ public static class Data {
+
+ private String account;
+ private String attr1;
+ private String avatar;
+ private String bizData;
+ private List dataScope;
+ private String deptId;
+ private String deptName;
+ private List devices;
+ private String id;
+ private String ipAddr;
+ private String name;
+ private String phone;
+ private List roleList;
+ private List roleNames;
+ private List roleTips;
+ private String scopeType;
+ private String sysData;
+ private String targetId;
+ private String targetName;
+ private String tenantId;
+
+ public void setAccount(String account) {
+ this.account = account;
+ }
+
+ public String getAccount() {
+ return account;
+ }
+
+ public void setAttr1(String attr1) {
+ this.attr1 = attr1;
+ }
+
+ public String getAttr1() {
+ return attr1;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setBizData(String bizData) {
+ this.bizData = bizData;
+ }
+
+ public String getBizData() {
+ return bizData;
+ }
+
+ public void setDataScope(List dataScope) {
+ this.dataScope = dataScope;
+ }
+
+ public List getDataScope() {
+ return dataScope;
+ }
+
+ public void setDeptId(String deptId) {
+ this.deptId = deptId;
+ }
+
+ public String getDeptId() {
+ return deptId;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDevices(List devices) {
+ this.devices = devices;
+ }
+
+ public List getDevices() {
+ return devices;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setIpAddr(String ipAddr) {
+ this.ipAddr = ipAddr;
+ }
+
+ public String getIpAddr() {
+ return ipAddr;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setRoleList(List roleList) {
+ this.roleList = roleList;
+ }
+
+ public List getRoleList() {
+ return roleList;
+ }
+
+ public void setRoleNames(List roleNames) {
+ this.roleNames = roleNames;
+ }
+
+ public List getRoleNames() {
+ return roleNames;
+ }
+
+ public void setRoleTips(List roleTips) {
+ this.roleTips = roleTips;
+ }
+
+ public List getRoleTips() {
+ return roleTips;
+ }
+
+ public void setScopeType(String scopeType) {
+ this.scopeType = scopeType;
+ }
+
+ public String getScopeType() {
+ return scopeType;
+ }
+
+ public void setSysData(String sysData) {
+ this.sysData = sysData;
+ }
+
+ public String getSysData() {
+ return sysData;
+ }
+
+ public void setTargetId(String targetId) {
+ this.targetId = targetId;
+ }
+
+ public String getTargetId() {
+ return targetId;
+ }
+
+ public void setTargetName(String targetName) {
+ this.targetName = targetName;
+ }
+
+ public String getTargetName() {
+ return targetName;
+ }
+
+ public void setTenantId(String tenantId) {
+ this.tenantId = tenantId;
+ }
+
+ public String getTenantId() {
+ return tenantId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
new file mode 100644
index 0000000..b44fec6
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
@@ -0,0 +1,24 @@
+package com.casic.smarttube.utils
+
+import com.pengxh.kt.lite.utils.SaveKeyValues
+
+object AuthenticationHelper {
+
+ fun savePublicKey(key: String) {
+ SaveKeyValues.putValue("keyString", key)
+ }
+
+ val publicKey: String?
+ get() = SaveKeyValues.getValue("keyString", "") as String?
+
+ fun saveToken(token: String?) {
+ SaveKeyValues.putValue("token", token!!)
+ }
+
+ val token: String?
+ get() = SaveKeyValues.getValue("token", "") as String?
+
+ fun removeToken() {
+ SaveKeyValues.removeKey("token")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/Constant.kt b/app/src/main/java/com/casic/smarttube/utils/Constant.kt
deleted file mode 100644
index d921387..0000000
--- a/app/src/main/java/com/casic/smarttube/utils/Constant.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.casic.smarttube.utils
-
-import android.Manifest
-
-
-object Constant {
- val USER_PERMISSIONS = arrayOf(
- Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
- Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
- Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
- Manifest.permission.READ_PHONE_STATE
- )
-
- const val PERMISSIONS_CODE = 999
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
new file mode 100644
index 0000000..bb97c01
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
@@ -0,0 +1,29 @@
+package com.casic.smarttube.utils;
+
+import android.app.Activity
+import android.view.WindowManager
+import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
+
+object DialogHelper {
+ private lateinit var loadingDialog: QMUITipDialog
+
+ fun showLoadingDialog(activity: Activity, message: String?) {
+ loadingDialog = QMUITipDialog.Builder(activity)
+ .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+ .setTipWord(message)
+ .create()
+ if (!activity.isDestroyed) {
+ try {
+ loadingDialog.show()
+ } catch (e: WindowManager.BadTokenException) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ fun dismissLoadingDialog() {
+ if (loadingDialog.isShowing) {
+ loadingDialog.dismiss()
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
new file mode 100644
index 0000000..cee379c
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
@@ -0,0 +1,43 @@
+package com.casic.smarttube.utils
+
+import android.Manifest
+
+
+object LocalConstant {
+ /**
+ * =============================================================================================
+ * Array
+ * =============================================================================================
+ * */
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
+ Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
+ Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.READ_PHONE_STATE
+ )
+
+ /**
+ * =============================================================================================
+ * Int
+ * =============================================================================================
+ * */
+ const val PERMISSIONS_CODE = 999
+
+ /**
+ * =============================================================================================
+ * Long
+ * =============================================================================================
+ * */
+
+
+ /**
+ * =============================================================================================
+ * String
+ * =============================================================================================
+ * */
+ const val USER_DETAIL_MODEL = "userDetailModel"
+ const val SERVER_BASE_URL = "http://111.198.10.15:11304"
+ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val ACCOUNT = "account"
+ const val PASSWORD = "password"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt b/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt
new file mode 100644
index 0000000..14e2f56
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt
@@ -0,0 +1,58 @@
+package com.casic.smarttube.utils
+
+import android.util.Base64
+import java.security.*
+import java.security.spec.InvalidKeySpecException
+import java.security.spec.X509EncodedKeySpec
+import javax.crypto.BadPaddingException
+import javax.crypto.Cipher
+import javax.crypto.IllegalBlockSizeException
+import javax.crypto.NoSuchPaddingException
+
+object RSAUtils {
+ //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding"
+ private fun processData(srcData: ByteArray, key: Key): ByteArray? { //用来保存处理结果
+ var resultBytes: ByteArray? = null
+ try { //获取Cipher实例
+ val cipher = Cipher.getInstance("RSA/None/PKCS1Padding")
+ //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥
+ cipher.init(Cipher.ENCRYPT_MODE, key)
+ //处理数据
+ resultBytes = cipher.doFinal(srcData)
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ } catch (e: NoSuchPaddingException) {
+ e.printStackTrace()
+ } catch (e: InvalidKeyException) {
+ e.printStackTrace()
+ } catch (e: BadPaddingException) {
+ e.printStackTrace()
+ } catch (e: IllegalBlockSizeException) {
+ e.printStackTrace()
+ }
+ return resultBytes
+ }
+
+ fun encryptDataByPublicKey(srcData: ByteArray, publicKey: PublicKey): String {
+ val resultBytes =
+ processData(srcData, publicKey)
+ return Base64.encodeToString(resultBytes, Base64.DEFAULT)
+ }
+
+ fun keyStrToPublicKey(publicKeyStr: String?): PublicKey? {
+ var publicKey: PublicKey? = null
+ val keyBytes =
+ Base64.decode(publicKeyStr, Base64.DEFAULT)
+ val keySpec =
+ X509EncodedKeySpec(keyBytes)
+ try {
+ val keyFactory = KeyFactory.getInstance("RSA")
+ publicKey = keyFactory.generatePublic(keySpec)
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ } catch (e: InvalidKeySpecException) {
+ e.printStackTrace()
+ }
+ return publicKey
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt
new file mode 100644
index 0000000..660496f
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt
@@ -0,0 +1,47 @@
+package com.casic.smarttube.utils.retrofit;
+
+import android.util.Log
+import com.casic.smarttube.utils.LocalConstant
+import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import okhttp3.OkHttpClient
+import okhttp3.logging.HttpLoggingInterceptor
+import org.jetbrains.annotations.NotNull
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+import retrofit2.converter.scalars.ScalarsConverterFactory
+import java.util.concurrent.TimeUnit
+
+object RetrofitFactory {
+ private const val kTag = "RetrofitFactory"
+
+ private val httpClient: OkHttpClient by lazy { createOKHttpClient() }
+
+ fun createRetrofit(clazz: Class): T {
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return Retrofit.Builder()
+ .baseUrl(defaultValue)
+ .addConverterFactory(ScalarsConverterFactory.create()) //字符串转换器
+ .addConverterFactory(GsonConverterFactory.create()) //Gson转换器
+ .addCallAdapterFactory(CoroutineCallAdapterFactory.invoke()) //协程请求适配器
+ .client(httpClient) //log拦截器
+ .build().create(clazz)
+ }
+
+ private fun createOKHttpClient(): OkHttpClient { //日志显示级别
+ val interceptor =
+ HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
+ override fun log(@NotNull message: String) {
+ Log.d(kTag, ">>>>> $message")
+ }
+ })
+ interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
+ val builder = OkHttpClient.Builder()
+ .connectTimeout(15, TimeUnit.SECONDS)
+ .readTimeout(15, TimeUnit.SECONDS)
+ .writeTimeout(15, TimeUnit.SECONDS)
+ return builder.addInterceptor(interceptor).build()
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt
new file mode 100644
index 0000000..6dad7b3
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt
@@ -0,0 +1,52 @@
+package com.casic.smarttube.utils.retrofit
+
+import okhttp3.MultipartBody
+import retrofit2.http.*
+
+
+interface RetrofitService {
+ /**
+ * PublicKey校验
+ */
+ @GET("/config/baseConfig")
+ suspend fun obtainPublicKey(): String
+
+ /**
+ * 登录并获取Token
+ *
+ * @param sid
+ * @param account 用户名
+ * @param secretKey 加密后的密码
+ */
+ @FormUrlEncoded
+ @POST("/user/login")
+ suspend fun obtainLoginResult(
+ @Field("sid") sid: String,
+ @Field("username") account: String,
+ @Field("password") secretKey: String
+ ): String
+
+ /**
+ * 退出登录
+ */
+ @GET("/user/logout")
+ suspend fun loginOut(@Header("token") token: String): String
+
+ /**
+ * 获取用户信息
+ */
+ @GET("/user/info")
+ suspend fun obtainUserDetail(@Header("token") token: String): String
+
+ /**
+ * 上传图片
+ * 系统路径static拼接图片返回路径
+ * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg
+ */
+ @Multipart
+ @POST("/imageUpload")
+ suspend fun uploadImage(
+ @Header("token") token: String,
+ @Part file: MultipartBody.Part
+ ): String
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt
new file mode 100644
index 0000000..db99cfb
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt
@@ -0,0 +1,50 @@
+package com.casic.smarttube.utils.retrofit
+
+import com.casic.smarttube.utils.AuthenticationHelper
+import okhttp3.MediaType.Companion.toMediaTypeOrNull
+import okhttp3.MultipartBody
+import okhttp3.RequestBody
+import java.io.File
+
+
+object RetrofitServiceManager {
+
+ private val api by lazy { RetrofitFactory.createRetrofit(RetrofitService::class.java) }
+
+ /**
+ * 验证PublicKey
+ */
+ suspend fun authenticate(): String {
+ return api.obtainPublicKey()
+ }
+
+ /**
+ * 登录并获取Token
+ */
+ suspend fun login(sid: String, account: String, secretKey: String): String {
+ return api.obtainLoginResult(sid, account, secretKey)
+ }
+
+ /**
+ * 退出登录
+ */
+ suspend fun loginOut(): String {
+ return api.loginOut(AuthenticationHelper.token!!)
+ }
+
+ /**
+ * 获取用户信息
+ */
+ suspend fun obtainUserDetail(): String {
+ return api.obtainUserDetail(AuthenticationHelper.token!!)
+ }
+
+ /**
+ * 上传图片
+ */
+ suspend fun uploadImage(image: File): String {
+ val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image)
+ val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody)
+ return api.uploadImage(AuthenticationHelper.token!!, imagePart)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/view/LoginActivity.kt b/app/src/main/java/com/casic/smarttube/view/LoginActivity.kt
new file mode 100644
index 0000000..aeccd80
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/view/LoginActivity.kt
@@ -0,0 +1,134 @@
+package com.casic.smarttube.view
+
+import android.text.Editable
+import android.text.TextWatcher
+import android.view.KeyEvent
+import android.view.inputmethod.EditorInfo
+import android.widget.EditText
+import android.widget.TextView
+import androidx.lifecycle.ViewModelProvider
+import com.casic.smarttube.R
+import com.casic.smarttube.utils.AuthenticationHelper
+import com.casic.smarttube.utils.DialogHelper
+import com.casic.smarttube.utils.LocalConstant
+import com.casic.smarttube.utils.RSAUtils
+import com.casic.smarttube.vm.AuthenticateViewModel
+import com.casic.smarttube.vm.LoginViewModel
+import com.casic.smarttube.vm.UserViewModel
+import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import com.pengxh.kt.lite.vm.LoadState
+import kotlinx.android.synthetic.main.activity_login.*
+
+class LoginActivity : KotlinBaseActivity() {
+
+ private lateinit var authenticateViewModel: AuthenticateViewModel
+ private lateinit var loginViewModel: LoginViewModel
+ private lateinit var userViewModel: UserViewModel
+ private val textWatcher = object : TextWatcher {
+ override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
+
+ }
+
+ override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
+
+ }
+
+ override fun afterTextChanged(s: Editable) {
+ if (s.toString().trim { it <= ' ' }.length > 16) {
+ inputLayout.error = "密码长度超出限制"
+ } else {
+ inputLayout.error = null
+ }
+ }
+ }
+
+ override fun initLayoutView(): Int = R.layout.activity_login
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(true).init()
+ }
+
+ override fun initData() {
+ // 设置默认账号密码
+ userNameView.setText(SaveKeyValues.getValue(LocalConstant.ACCOUNT, "") as String)
+ userPasswordView.setText(SaveKeyValues.getValue(LocalConstant.PASSWORD, "") as String)
+ authenticateViewModel = ViewModelProvider(this).get(AuthenticateViewModel::class.java)
+ loginViewModel = ViewModelProvider(this).get(LoginViewModel::class.java)
+ userViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
+ }
+
+ override fun initEvent() {
+ val editText: EditText? = inputLayout.editText
+ editText?.addTextChangedListener(textWatcher)
+ //点击输入法键盘"完成"
+ editText?.setOnEditorActionListener { _: TextView?, actionId: Int, _: KeyEvent? ->
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ authenticateViewModel.obtainPublicKey()
+ return@setOnEditorActionListener true
+ }
+ false
+ }
+
+ loginButton.setOnClickListener {
+ val account = userNameView.text.toString().trim()
+ val userPassword = userPasswordView.text.toString().trim()
+ if (account.isBlank()) {
+ "用户名不能为空".show(this)
+ return@setOnClickListener
+ }
+ if (userPassword.isBlank()) {
+ "密码不能为空".show(this)
+ return@setOnClickListener
+ }
+ SaveKeyValues.putValue(LocalConstant.ACCOUNT, account)
+ SaveKeyValues.putValue(LocalConstant.PASSWORD, userPassword)
+ authenticateViewModel.obtainPublicKey()
+ }
+ authenticateViewModel.keyModel.observe(this, {
+ if (it.code == 200) {//用code判断,别的判断可能有坑
+ val keyString = it.data!!.publicKey!!
+ /**
+ * 修改密码需要用到key,先存着
+ * */
+ AuthenticationHelper.savePublicKey(keyString)
+ val publicKey = RSAUtils.keyStrToPublicKey(keyString)
+
+ val account = userNameView.text.toString()
+ val userPassword = userPasswordView.text.toString()
+ val dataByPublicKey =
+ RSAUtils.encryptDataByPublicKey(userPassword.toByteArray(), publicKey!!)
+ //登录并获取Token,POST请求
+ loginViewModel.enter(it.data!!.sid!!, account, dataByPublicKey)
+ loginViewModel.enterResultModel.observe(this, { loginResult ->
+ if (loginResult.code == 200) {
+ AuthenticationHelper.saveToken(loginResult.data!!.token!!)
+ /**
+ * 获取token之后保存用户信息
+ * */
+ userViewModel.obtainUserDetail()
+ //验证成功登录
+ this.navigatePageTo()
+ finish()
+ }
+ })
+ loginViewModel.loadState.observe(this, { loginState ->
+ when (loginState) {
+ is LoadState.Loading -> {
+ DialogHelper.showLoadingDialog(this, "登录中,请稍后")
+ }
+ is LoadState.Success -> {
+ DialogHelper.dismissLoadingDialog()
+ }
+ else -> {
+ DialogHelper.dismissLoadingDialog()
+ }
+ }
+ })
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
new file mode 100644
index 0000000..eecfd74
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
@@ -0,0 +1,43 @@
+package com.casic.smarttube.model;
+
+/**
+ * 普通实体类,失败/成功数据结构一致
+ */
+public class CommonResultModel {
+ private int code;
+ private String data;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
new file mode 100644
index 0000000..411674a
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
@@ -0,0 +1,49 @@
+package com.casic.smarttube.model;
+
+public class ErrorMessageModel {
+ private int code;
+ private String data;
+ private String exceptionClazz;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getExceptionClazz() {
+ return exceptionClazz;
+ }
+
+ public void setExceptionClazz(String exceptionClazz) {
+ this.exceptionClazz = exceptionClazz;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
new file mode 100644
index 0000000..6497254
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
@@ -0,0 +1,62 @@
+package com.casic.smarttube.model;
+
+public class LoginResultModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private String kaptcha;
+ private String token;
+
+ public String getKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(String kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
new file mode 100644
index 0000000..d440bc8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
@@ -0,0 +1,80 @@
+package com.casic.smarttube.model;
+
+public class PublicKeyModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private boolean appKaptcha;
+ private boolean kaptcha;
+ private String publicKey;
+ private String sid;
+
+ public boolean isAppKaptcha() {
+ return appKaptcha;
+ }
+
+ public void setAppKaptcha(boolean appKaptcha) {
+ this.appKaptcha = appKaptcha;
+ }
+
+ public boolean isKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(boolean kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getPublicKey() {
+ return publicKey;
+ }
+
+ public void setPublicKey(String publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public String getSid() {
+ return sid;
+ }
+
+ public void setSid(String sid) {
+ this.sid = sid;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
new file mode 100644
index 0000000..149bec8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
@@ -0,0 +1,227 @@
+package com.casic.smarttube.model;
+
+
+import java.util.List;
+
+public class UserDetailModel {
+ private int code;
+ private Data data;
+ private String message;
+ private boolean success;
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setData(Data data) {
+ this.data = data;
+ }
+
+ public Data getData() {
+ return data;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public boolean getSuccess() {
+ return success;
+ }
+
+ public static class Data {
+
+ private String account;
+ private String attr1;
+ private String avatar;
+ private String bizData;
+ private List dataScope;
+ private String deptId;
+ private String deptName;
+ private List devices;
+ private String id;
+ private String ipAddr;
+ private String name;
+ private String phone;
+ private List roleList;
+ private List roleNames;
+ private List roleTips;
+ private String scopeType;
+ private String sysData;
+ private String targetId;
+ private String targetName;
+ private String tenantId;
+
+ public void setAccount(String account) {
+ this.account = account;
+ }
+
+ public String getAccount() {
+ return account;
+ }
+
+ public void setAttr1(String attr1) {
+ this.attr1 = attr1;
+ }
+
+ public String getAttr1() {
+ return attr1;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setBizData(String bizData) {
+ this.bizData = bizData;
+ }
+
+ public String getBizData() {
+ return bizData;
+ }
+
+ public void setDataScope(List dataScope) {
+ this.dataScope = dataScope;
+ }
+
+ public List getDataScope() {
+ return dataScope;
+ }
+
+ public void setDeptId(String deptId) {
+ this.deptId = deptId;
+ }
+
+ public String getDeptId() {
+ return deptId;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDevices(List devices) {
+ this.devices = devices;
+ }
+
+ public List getDevices() {
+ return devices;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setIpAddr(String ipAddr) {
+ this.ipAddr = ipAddr;
+ }
+
+ public String getIpAddr() {
+ return ipAddr;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setRoleList(List roleList) {
+ this.roleList = roleList;
+ }
+
+ public List getRoleList() {
+ return roleList;
+ }
+
+ public void setRoleNames(List roleNames) {
+ this.roleNames = roleNames;
+ }
+
+ public List getRoleNames() {
+ return roleNames;
+ }
+
+ public void setRoleTips(List roleTips) {
+ this.roleTips = roleTips;
+ }
+
+ public List getRoleTips() {
+ return roleTips;
+ }
+
+ public void setScopeType(String scopeType) {
+ this.scopeType = scopeType;
+ }
+
+ public String getScopeType() {
+ return scopeType;
+ }
+
+ public void setSysData(String sysData) {
+ this.sysData = sysData;
+ }
+
+ public String getSysData() {
+ return sysData;
+ }
+
+ public void setTargetId(String targetId) {
+ this.targetId = targetId;
+ }
+
+ public String getTargetId() {
+ return targetId;
+ }
+
+ public void setTargetName(String targetName) {
+ this.targetName = targetName;
+ }
+
+ public String getTargetName() {
+ return targetName;
+ }
+
+ public void setTenantId(String tenantId) {
+ this.tenantId = tenantId;
+ }
+
+ public String getTenantId() {
+ return tenantId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
new file mode 100644
index 0000000..b44fec6
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
@@ -0,0 +1,24 @@
+package com.casic.smarttube.utils
+
+import com.pengxh.kt.lite.utils.SaveKeyValues
+
+object AuthenticationHelper {
+
+ fun savePublicKey(key: String) {
+ SaveKeyValues.putValue("keyString", key)
+ }
+
+ val publicKey: String?
+ get() = SaveKeyValues.getValue("keyString", "") as String?
+
+ fun saveToken(token: String?) {
+ SaveKeyValues.putValue("token", token!!)
+ }
+
+ val token: String?
+ get() = SaveKeyValues.getValue("token", "") as String?
+
+ fun removeToken() {
+ SaveKeyValues.removeKey("token")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/Constant.kt b/app/src/main/java/com/casic/smarttube/utils/Constant.kt
deleted file mode 100644
index d921387..0000000
--- a/app/src/main/java/com/casic/smarttube/utils/Constant.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.casic.smarttube.utils
-
-import android.Manifest
-
-
-object Constant {
- val USER_PERMISSIONS = arrayOf(
- Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
- Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
- Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
- Manifest.permission.READ_PHONE_STATE
- )
-
- const val PERMISSIONS_CODE = 999
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
new file mode 100644
index 0000000..bb97c01
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
@@ -0,0 +1,29 @@
+package com.casic.smarttube.utils;
+
+import android.app.Activity
+import android.view.WindowManager
+import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
+
+object DialogHelper {
+ private lateinit var loadingDialog: QMUITipDialog
+
+ fun showLoadingDialog(activity: Activity, message: String?) {
+ loadingDialog = QMUITipDialog.Builder(activity)
+ .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+ .setTipWord(message)
+ .create()
+ if (!activity.isDestroyed) {
+ try {
+ loadingDialog.show()
+ } catch (e: WindowManager.BadTokenException) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ fun dismissLoadingDialog() {
+ if (loadingDialog.isShowing) {
+ loadingDialog.dismiss()
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
new file mode 100644
index 0000000..cee379c
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
@@ -0,0 +1,43 @@
+package com.casic.smarttube.utils
+
+import android.Manifest
+
+
+object LocalConstant {
+ /**
+ * =============================================================================================
+ * Array
+ * =============================================================================================
+ * */
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
+ Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
+ Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.READ_PHONE_STATE
+ )
+
+ /**
+ * =============================================================================================
+ * Int
+ * =============================================================================================
+ * */
+ const val PERMISSIONS_CODE = 999
+
+ /**
+ * =============================================================================================
+ * Long
+ * =============================================================================================
+ * */
+
+
+ /**
+ * =============================================================================================
+ * String
+ * =============================================================================================
+ * */
+ const val USER_DETAIL_MODEL = "userDetailModel"
+ const val SERVER_BASE_URL = "http://111.198.10.15:11304"
+ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val ACCOUNT = "account"
+ const val PASSWORD = "password"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt b/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt
new file mode 100644
index 0000000..14e2f56
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt
@@ -0,0 +1,58 @@
+package com.casic.smarttube.utils
+
+import android.util.Base64
+import java.security.*
+import java.security.spec.InvalidKeySpecException
+import java.security.spec.X509EncodedKeySpec
+import javax.crypto.BadPaddingException
+import javax.crypto.Cipher
+import javax.crypto.IllegalBlockSizeException
+import javax.crypto.NoSuchPaddingException
+
+object RSAUtils {
+ //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding"
+ private fun processData(srcData: ByteArray, key: Key): ByteArray? { //用来保存处理结果
+ var resultBytes: ByteArray? = null
+ try { //获取Cipher实例
+ val cipher = Cipher.getInstance("RSA/None/PKCS1Padding")
+ //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥
+ cipher.init(Cipher.ENCRYPT_MODE, key)
+ //处理数据
+ resultBytes = cipher.doFinal(srcData)
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ } catch (e: NoSuchPaddingException) {
+ e.printStackTrace()
+ } catch (e: InvalidKeyException) {
+ e.printStackTrace()
+ } catch (e: BadPaddingException) {
+ e.printStackTrace()
+ } catch (e: IllegalBlockSizeException) {
+ e.printStackTrace()
+ }
+ return resultBytes
+ }
+
+ fun encryptDataByPublicKey(srcData: ByteArray, publicKey: PublicKey): String {
+ val resultBytes =
+ processData(srcData, publicKey)
+ return Base64.encodeToString(resultBytes, Base64.DEFAULT)
+ }
+
+ fun keyStrToPublicKey(publicKeyStr: String?): PublicKey? {
+ var publicKey: PublicKey? = null
+ val keyBytes =
+ Base64.decode(publicKeyStr, Base64.DEFAULT)
+ val keySpec =
+ X509EncodedKeySpec(keyBytes)
+ try {
+ val keyFactory = KeyFactory.getInstance("RSA")
+ publicKey = keyFactory.generatePublic(keySpec)
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ } catch (e: InvalidKeySpecException) {
+ e.printStackTrace()
+ }
+ return publicKey
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt
new file mode 100644
index 0000000..660496f
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt
@@ -0,0 +1,47 @@
+package com.casic.smarttube.utils.retrofit;
+
+import android.util.Log
+import com.casic.smarttube.utils.LocalConstant
+import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import okhttp3.OkHttpClient
+import okhttp3.logging.HttpLoggingInterceptor
+import org.jetbrains.annotations.NotNull
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+import retrofit2.converter.scalars.ScalarsConverterFactory
+import java.util.concurrent.TimeUnit
+
+object RetrofitFactory {
+ private const val kTag = "RetrofitFactory"
+
+ private val httpClient: OkHttpClient by lazy { createOKHttpClient() }
+
+ fun createRetrofit(clazz: Class): T {
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return Retrofit.Builder()
+ .baseUrl(defaultValue)
+ .addConverterFactory(ScalarsConverterFactory.create()) //字符串转换器
+ .addConverterFactory(GsonConverterFactory.create()) //Gson转换器
+ .addCallAdapterFactory(CoroutineCallAdapterFactory.invoke()) //协程请求适配器
+ .client(httpClient) //log拦截器
+ .build().create(clazz)
+ }
+
+ private fun createOKHttpClient(): OkHttpClient { //日志显示级别
+ val interceptor =
+ HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
+ override fun log(@NotNull message: String) {
+ Log.d(kTag, ">>>>> $message")
+ }
+ })
+ interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
+ val builder = OkHttpClient.Builder()
+ .connectTimeout(15, TimeUnit.SECONDS)
+ .readTimeout(15, TimeUnit.SECONDS)
+ .writeTimeout(15, TimeUnit.SECONDS)
+ return builder.addInterceptor(interceptor).build()
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt
new file mode 100644
index 0000000..6dad7b3
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt
@@ -0,0 +1,52 @@
+package com.casic.smarttube.utils.retrofit
+
+import okhttp3.MultipartBody
+import retrofit2.http.*
+
+
+interface RetrofitService {
+ /**
+ * PublicKey校验
+ */
+ @GET("/config/baseConfig")
+ suspend fun obtainPublicKey(): String
+
+ /**
+ * 登录并获取Token
+ *
+ * @param sid
+ * @param account 用户名
+ * @param secretKey 加密后的密码
+ */
+ @FormUrlEncoded
+ @POST("/user/login")
+ suspend fun obtainLoginResult(
+ @Field("sid") sid: String,
+ @Field("username") account: String,
+ @Field("password") secretKey: String
+ ): String
+
+ /**
+ * 退出登录
+ */
+ @GET("/user/logout")
+ suspend fun loginOut(@Header("token") token: String): String
+
+ /**
+ * 获取用户信息
+ */
+ @GET("/user/info")
+ suspend fun obtainUserDetail(@Header("token") token: String): String
+
+ /**
+ * 上传图片
+ * 系统路径static拼接图片返回路径
+ * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg
+ */
+ @Multipart
+ @POST("/imageUpload")
+ suspend fun uploadImage(
+ @Header("token") token: String,
+ @Part file: MultipartBody.Part
+ ): String
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt
new file mode 100644
index 0000000..db99cfb
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt
@@ -0,0 +1,50 @@
+package com.casic.smarttube.utils.retrofit
+
+import com.casic.smarttube.utils.AuthenticationHelper
+import okhttp3.MediaType.Companion.toMediaTypeOrNull
+import okhttp3.MultipartBody
+import okhttp3.RequestBody
+import java.io.File
+
+
+object RetrofitServiceManager {
+
+ private val api by lazy { RetrofitFactory.createRetrofit(RetrofitService::class.java) }
+
+ /**
+ * 验证PublicKey
+ */
+ suspend fun authenticate(): String {
+ return api.obtainPublicKey()
+ }
+
+ /**
+ * 登录并获取Token
+ */
+ suspend fun login(sid: String, account: String, secretKey: String): String {
+ return api.obtainLoginResult(sid, account, secretKey)
+ }
+
+ /**
+ * 退出登录
+ */
+ suspend fun loginOut(): String {
+ return api.loginOut(AuthenticationHelper.token!!)
+ }
+
+ /**
+ * 获取用户信息
+ */
+ suspend fun obtainUserDetail(): String {
+ return api.obtainUserDetail(AuthenticationHelper.token!!)
+ }
+
+ /**
+ * 上传图片
+ */
+ suspend fun uploadImage(image: File): String {
+ val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image)
+ val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody)
+ return api.uploadImage(AuthenticationHelper.token!!, imagePart)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/view/LoginActivity.kt b/app/src/main/java/com/casic/smarttube/view/LoginActivity.kt
new file mode 100644
index 0000000..aeccd80
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/view/LoginActivity.kt
@@ -0,0 +1,134 @@
+package com.casic.smarttube.view
+
+import android.text.Editable
+import android.text.TextWatcher
+import android.view.KeyEvent
+import android.view.inputmethod.EditorInfo
+import android.widget.EditText
+import android.widget.TextView
+import androidx.lifecycle.ViewModelProvider
+import com.casic.smarttube.R
+import com.casic.smarttube.utils.AuthenticationHelper
+import com.casic.smarttube.utils.DialogHelper
+import com.casic.smarttube.utils.LocalConstant
+import com.casic.smarttube.utils.RSAUtils
+import com.casic.smarttube.vm.AuthenticateViewModel
+import com.casic.smarttube.vm.LoginViewModel
+import com.casic.smarttube.vm.UserViewModel
+import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import com.pengxh.kt.lite.vm.LoadState
+import kotlinx.android.synthetic.main.activity_login.*
+
+class LoginActivity : KotlinBaseActivity() {
+
+ private lateinit var authenticateViewModel: AuthenticateViewModel
+ private lateinit var loginViewModel: LoginViewModel
+ private lateinit var userViewModel: UserViewModel
+ private val textWatcher = object : TextWatcher {
+ override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
+
+ }
+
+ override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
+
+ }
+
+ override fun afterTextChanged(s: Editable) {
+ if (s.toString().trim { it <= ' ' }.length > 16) {
+ inputLayout.error = "密码长度超出限制"
+ } else {
+ inputLayout.error = null
+ }
+ }
+ }
+
+ override fun initLayoutView(): Int = R.layout.activity_login
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(true).init()
+ }
+
+ override fun initData() {
+ // 设置默认账号密码
+ userNameView.setText(SaveKeyValues.getValue(LocalConstant.ACCOUNT, "") as String)
+ userPasswordView.setText(SaveKeyValues.getValue(LocalConstant.PASSWORD, "") as String)
+ authenticateViewModel = ViewModelProvider(this).get(AuthenticateViewModel::class.java)
+ loginViewModel = ViewModelProvider(this).get(LoginViewModel::class.java)
+ userViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
+ }
+
+ override fun initEvent() {
+ val editText: EditText? = inputLayout.editText
+ editText?.addTextChangedListener(textWatcher)
+ //点击输入法键盘"完成"
+ editText?.setOnEditorActionListener { _: TextView?, actionId: Int, _: KeyEvent? ->
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ authenticateViewModel.obtainPublicKey()
+ return@setOnEditorActionListener true
+ }
+ false
+ }
+
+ loginButton.setOnClickListener {
+ val account = userNameView.text.toString().trim()
+ val userPassword = userPasswordView.text.toString().trim()
+ if (account.isBlank()) {
+ "用户名不能为空".show(this)
+ return@setOnClickListener
+ }
+ if (userPassword.isBlank()) {
+ "密码不能为空".show(this)
+ return@setOnClickListener
+ }
+ SaveKeyValues.putValue(LocalConstant.ACCOUNT, account)
+ SaveKeyValues.putValue(LocalConstant.PASSWORD, userPassword)
+ authenticateViewModel.obtainPublicKey()
+ }
+ authenticateViewModel.keyModel.observe(this, {
+ if (it.code == 200) {//用code判断,别的判断可能有坑
+ val keyString = it.data!!.publicKey!!
+ /**
+ * 修改密码需要用到key,先存着
+ * */
+ AuthenticationHelper.savePublicKey(keyString)
+ val publicKey = RSAUtils.keyStrToPublicKey(keyString)
+
+ val account = userNameView.text.toString()
+ val userPassword = userPasswordView.text.toString()
+ val dataByPublicKey =
+ RSAUtils.encryptDataByPublicKey(userPassword.toByteArray(), publicKey!!)
+ //登录并获取Token,POST请求
+ loginViewModel.enter(it.data!!.sid!!, account, dataByPublicKey)
+ loginViewModel.enterResultModel.observe(this, { loginResult ->
+ if (loginResult.code == 200) {
+ AuthenticationHelper.saveToken(loginResult.data!!.token!!)
+ /**
+ * 获取token之后保存用户信息
+ * */
+ userViewModel.obtainUserDetail()
+ //验证成功登录
+ this.navigatePageTo()
+ finish()
+ }
+ })
+ loginViewModel.loadState.observe(this, { loginState ->
+ when (loginState) {
+ is LoadState.Loading -> {
+ DialogHelper.showLoadingDialog(this, "登录中,请稍后")
+ }
+ is LoadState.Success -> {
+ DialogHelper.dismissLoadingDialog()
+ }
+ else -> {
+ DialogHelper.dismissLoadingDialog()
+ }
+ }
+ })
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/view/PermissionActivity.kt b/app/src/main/java/com/casic/smarttube/view/PermissionActivity.kt
index c05f04a..d6dee4d 100644
--- a/app/src/main/java/com/casic/smarttube/view/PermissionActivity.kt
+++ b/app/src/main/java/com/casic/smarttube/view/PermissionActivity.kt
@@ -1,32 +1,46 @@
package com.casic.smarttube.view
-import android.os.Bundle
-import androidx.appcompat.app.AppCompatActivity
import com.amap.api.navi.NaviSetting
-import com.casic.smarttube.utils.Constant
+import com.casic.smarttube.R
+import com.casic.smarttube.utils.LocalConstant
+import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.extensions.convertColor
import com.pengxh.kt.lite.extensions.navigatePageTo
-import com.pengxh.kt.lite.utils.PageNavigationManager
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_permssion.*
import pub.devrel.easypermissions.EasyPermissions
import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks
-class PermissionActivity : AppCompatActivity(), PermissionCallbacks {
+class PermissionActivity : KotlinBaseActivity(), PermissionCallbacks {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- PageNavigationManager.addActivity(this)
+ override fun initLayoutView(): Int = R.layout.activity_permssion
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(true).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.white.convertColor(this))
+ }
+
+ override fun initData() {
//判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。
- if (EasyPermissions.hasPermissions(this, *Constant.USER_PERMISSIONS)) {
+ if (EasyPermissions.hasPermissions(this, *LocalConstant.USER_PERMISSIONS)) {
startSplashScreenActivity()
} else {
- EasyPermissions.requestPermissions(
- this,
- "需要获取相关权限",
- Constant.PERMISSIONS_CODE,
- *Constant.USER_PERMISSIONS
- )
+ enterMainButton.setOnClickListener {
+ EasyPermissions.requestPermissions(
+ this@PermissionActivity,
+ resources.getString(R.string.app_name) + "需要获取存储相关权限",
+ LocalConstant.PERMISSIONS_CODE,
+ *LocalConstant.USER_PERMISSIONS
+ )
+ }
}
}
+ override fun initEvent() {
+
+ }
+
private fun startSplashScreenActivity() {
//先把导航隐私政策声明,后面导航会用到
NaviSetting.updatePrivacyShow(this, true, true)
@@ -36,9 +50,7 @@
}
override fun onRequestPermissionsResult(
- requestCode: Int,
- permissions: Array,
- grantResults: IntArray
+ requestCode: Int, permissions: Array, grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
new file mode 100644
index 0000000..eecfd74
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
@@ -0,0 +1,43 @@
+package com.casic.smarttube.model;
+
+/**
+ * 普通实体类,失败/成功数据结构一致
+ */
+public class CommonResultModel {
+ private int code;
+ private String data;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
new file mode 100644
index 0000000..411674a
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
@@ -0,0 +1,49 @@
+package com.casic.smarttube.model;
+
+public class ErrorMessageModel {
+ private int code;
+ private String data;
+ private String exceptionClazz;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getExceptionClazz() {
+ return exceptionClazz;
+ }
+
+ public void setExceptionClazz(String exceptionClazz) {
+ this.exceptionClazz = exceptionClazz;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
new file mode 100644
index 0000000..6497254
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
@@ -0,0 +1,62 @@
+package com.casic.smarttube.model;
+
+public class LoginResultModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private String kaptcha;
+ private String token;
+
+ public String getKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(String kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
new file mode 100644
index 0000000..d440bc8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
@@ -0,0 +1,80 @@
+package com.casic.smarttube.model;
+
+public class PublicKeyModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private boolean appKaptcha;
+ private boolean kaptcha;
+ private String publicKey;
+ private String sid;
+
+ public boolean isAppKaptcha() {
+ return appKaptcha;
+ }
+
+ public void setAppKaptcha(boolean appKaptcha) {
+ this.appKaptcha = appKaptcha;
+ }
+
+ public boolean isKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(boolean kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getPublicKey() {
+ return publicKey;
+ }
+
+ public void setPublicKey(String publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public String getSid() {
+ return sid;
+ }
+
+ public void setSid(String sid) {
+ this.sid = sid;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
new file mode 100644
index 0000000..149bec8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
@@ -0,0 +1,227 @@
+package com.casic.smarttube.model;
+
+
+import java.util.List;
+
+public class UserDetailModel {
+ private int code;
+ private Data data;
+ private String message;
+ private boolean success;
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setData(Data data) {
+ this.data = data;
+ }
+
+ public Data getData() {
+ return data;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public boolean getSuccess() {
+ return success;
+ }
+
+ public static class Data {
+
+ private String account;
+ private String attr1;
+ private String avatar;
+ private String bizData;
+ private List dataScope;
+ private String deptId;
+ private String deptName;
+ private List devices;
+ private String id;
+ private String ipAddr;
+ private String name;
+ private String phone;
+ private List roleList;
+ private List roleNames;
+ private List roleTips;
+ private String scopeType;
+ private String sysData;
+ private String targetId;
+ private String targetName;
+ private String tenantId;
+
+ public void setAccount(String account) {
+ this.account = account;
+ }
+
+ public String getAccount() {
+ return account;
+ }
+
+ public void setAttr1(String attr1) {
+ this.attr1 = attr1;
+ }
+
+ public String getAttr1() {
+ return attr1;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setBizData(String bizData) {
+ this.bizData = bizData;
+ }
+
+ public String getBizData() {
+ return bizData;
+ }
+
+ public void setDataScope(List dataScope) {
+ this.dataScope = dataScope;
+ }
+
+ public List getDataScope() {
+ return dataScope;
+ }
+
+ public void setDeptId(String deptId) {
+ this.deptId = deptId;
+ }
+
+ public String getDeptId() {
+ return deptId;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDevices(List devices) {
+ this.devices = devices;
+ }
+
+ public List getDevices() {
+ return devices;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setIpAddr(String ipAddr) {
+ this.ipAddr = ipAddr;
+ }
+
+ public String getIpAddr() {
+ return ipAddr;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setRoleList(List roleList) {
+ this.roleList = roleList;
+ }
+
+ public List getRoleList() {
+ return roleList;
+ }
+
+ public void setRoleNames(List roleNames) {
+ this.roleNames = roleNames;
+ }
+
+ public List getRoleNames() {
+ return roleNames;
+ }
+
+ public void setRoleTips(List roleTips) {
+ this.roleTips = roleTips;
+ }
+
+ public List getRoleTips() {
+ return roleTips;
+ }
+
+ public void setScopeType(String scopeType) {
+ this.scopeType = scopeType;
+ }
+
+ public String getScopeType() {
+ return scopeType;
+ }
+
+ public void setSysData(String sysData) {
+ this.sysData = sysData;
+ }
+
+ public String getSysData() {
+ return sysData;
+ }
+
+ public void setTargetId(String targetId) {
+ this.targetId = targetId;
+ }
+
+ public String getTargetId() {
+ return targetId;
+ }
+
+ public void setTargetName(String targetName) {
+ this.targetName = targetName;
+ }
+
+ public String getTargetName() {
+ return targetName;
+ }
+
+ public void setTenantId(String tenantId) {
+ this.tenantId = tenantId;
+ }
+
+ public String getTenantId() {
+ return tenantId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
new file mode 100644
index 0000000..b44fec6
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
@@ -0,0 +1,24 @@
+package com.casic.smarttube.utils
+
+import com.pengxh.kt.lite.utils.SaveKeyValues
+
+object AuthenticationHelper {
+
+ fun savePublicKey(key: String) {
+ SaveKeyValues.putValue("keyString", key)
+ }
+
+ val publicKey: String?
+ get() = SaveKeyValues.getValue("keyString", "") as String?
+
+ fun saveToken(token: String?) {
+ SaveKeyValues.putValue("token", token!!)
+ }
+
+ val token: String?
+ get() = SaveKeyValues.getValue("token", "") as String?
+
+ fun removeToken() {
+ SaveKeyValues.removeKey("token")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/Constant.kt b/app/src/main/java/com/casic/smarttube/utils/Constant.kt
deleted file mode 100644
index d921387..0000000
--- a/app/src/main/java/com/casic/smarttube/utils/Constant.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.casic.smarttube.utils
-
-import android.Manifest
-
-
-object Constant {
- val USER_PERMISSIONS = arrayOf(
- Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
- Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
- Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
- Manifest.permission.READ_PHONE_STATE
- )
-
- const val PERMISSIONS_CODE = 999
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
new file mode 100644
index 0000000..bb97c01
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
@@ -0,0 +1,29 @@
+package com.casic.smarttube.utils;
+
+import android.app.Activity
+import android.view.WindowManager
+import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
+
+object DialogHelper {
+ private lateinit var loadingDialog: QMUITipDialog
+
+ fun showLoadingDialog(activity: Activity, message: String?) {
+ loadingDialog = QMUITipDialog.Builder(activity)
+ .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+ .setTipWord(message)
+ .create()
+ if (!activity.isDestroyed) {
+ try {
+ loadingDialog.show()
+ } catch (e: WindowManager.BadTokenException) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ fun dismissLoadingDialog() {
+ if (loadingDialog.isShowing) {
+ loadingDialog.dismiss()
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
new file mode 100644
index 0000000..cee379c
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
@@ -0,0 +1,43 @@
+package com.casic.smarttube.utils
+
+import android.Manifest
+
+
+object LocalConstant {
+ /**
+ * =============================================================================================
+ * Array
+ * =============================================================================================
+ * */
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
+ Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
+ Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.READ_PHONE_STATE
+ )
+
+ /**
+ * =============================================================================================
+ * Int
+ * =============================================================================================
+ * */
+ const val PERMISSIONS_CODE = 999
+
+ /**
+ * =============================================================================================
+ * Long
+ * =============================================================================================
+ * */
+
+
+ /**
+ * =============================================================================================
+ * String
+ * =============================================================================================
+ * */
+ const val USER_DETAIL_MODEL = "userDetailModel"
+ const val SERVER_BASE_URL = "http://111.198.10.15:11304"
+ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val ACCOUNT = "account"
+ const val PASSWORD = "password"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt b/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt
new file mode 100644
index 0000000..14e2f56
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt
@@ -0,0 +1,58 @@
+package com.casic.smarttube.utils
+
+import android.util.Base64
+import java.security.*
+import java.security.spec.InvalidKeySpecException
+import java.security.spec.X509EncodedKeySpec
+import javax.crypto.BadPaddingException
+import javax.crypto.Cipher
+import javax.crypto.IllegalBlockSizeException
+import javax.crypto.NoSuchPaddingException
+
+object RSAUtils {
+ //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding"
+ private fun processData(srcData: ByteArray, key: Key): ByteArray? { //用来保存处理结果
+ var resultBytes: ByteArray? = null
+ try { //获取Cipher实例
+ val cipher = Cipher.getInstance("RSA/None/PKCS1Padding")
+ //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥
+ cipher.init(Cipher.ENCRYPT_MODE, key)
+ //处理数据
+ resultBytes = cipher.doFinal(srcData)
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ } catch (e: NoSuchPaddingException) {
+ e.printStackTrace()
+ } catch (e: InvalidKeyException) {
+ e.printStackTrace()
+ } catch (e: BadPaddingException) {
+ e.printStackTrace()
+ } catch (e: IllegalBlockSizeException) {
+ e.printStackTrace()
+ }
+ return resultBytes
+ }
+
+ fun encryptDataByPublicKey(srcData: ByteArray, publicKey: PublicKey): String {
+ val resultBytes =
+ processData(srcData, publicKey)
+ return Base64.encodeToString(resultBytes, Base64.DEFAULT)
+ }
+
+ fun keyStrToPublicKey(publicKeyStr: String?): PublicKey? {
+ var publicKey: PublicKey? = null
+ val keyBytes =
+ Base64.decode(publicKeyStr, Base64.DEFAULT)
+ val keySpec =
+ X509EncodedKeySpec(keyBytes)
+ try {
+ val keyFactory = KeyFactory.getInstance("RSA")
+ publicKey = keyFactory.generatePublic(keySpec)
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ } catch (e: InvalidKeySpecException) {
+ e.printStackTrace()
+ }
+ return publicKey
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt
new file mode 100644
index 0000000..660496f
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt
@@ -0,0 +1,47 @@
+package com.casic.smarttube.utils.retrofit;
+
+import android.util.Log
+import com.casic.smarttube.utils.LocalConstant
+import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import okhttp3.OkHttpClient
+import okhttp3.logging.HttpLoggingInterceptor
+import org.jetbrains.annotations.NotNull
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+import retrofit2.converter.scalars.ScalarsConverterFactory
+import java.util.concurrent.TimeUnit
+
+object RetrofitFactory {
+ private const val kTag = "RetrofitFactory"
+
+ private val httpClient: OkHttpClient by lazy { createOKHttpClient() }
+
+ fun createRetrofit(clazz: Class): T {
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return Retrofit.Builder()
+ .baseUrl(defaultValue)
+ .addConverterFactory(ScalarsConverterFactory.create()) //字符串转换器
+ .addConverterFactory(GsonConverterFactory.create()) //Gson转换器
+ .addCallAdapterFactory(CoroutineCallAdapterFactory.invoke()) //协程请求适配器
+ .client(httpClient) //log拦截器
+ .build().create(clazz)
+ }
+
+ private fun createOKHttpClient(): OkHttpClient { //日志显示级别
+ val interceptor =
+ HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
+ override fun log(@NotNull message: String) {
+ Log.d(kTag, ">>>>> $message")
+ }
+ })
+ interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
+ val builder = OkHttpClient.Builder()
+ .connectTimeout(15, TimeUnit.SECONDS)
+ .readTimeout(15, TimeUnit.SECONDS)
+ .writeTimeout(15, TimeUnit.SECONDS)
+ return builder.addInterceptor(interceptor).build()
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt
new file mode 100644
index 0000000..6dad7b3
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt
@@ -0,0 +1,52 @@
+package com.casic.smarttube.utils.retrofit
+
+import okhttp3.MultipartBody
+import retrofit2.http.*
+
+
+interface RetrofitService {
+ /**
+ * PublicKey校验
+ */
+ @GET("/config/baseConfig")
+ suspend fun obtainPublicKey(): String
+
+ /**
+ * 登录并获取Token
+ *
+ * @param sid
+ * @param account 用户名
+ * @param secretKey 加密后的密码
+ */
+ @FormUrlEncoded
+ @POST("/user/login")
+ suspend fun obtainLoginResult(
+ @Field("sid") sid: String,
+ @Field("username") account: String,
+ @Field("password") secretKey: String
+ ): String
+
+ /**
+ * 退出登录
+ */
+ @GET("/user/logout")
+ suspend fun loginOut(@Header("token") token: String): String
+
+ /**
+ * 获取用户信息
+ */
+ @GET("/user/info")
+ suspend fun obtainUserDetail(@Header("token") token: String): String
+
+ /**
+ * 上传图片
+ * 系统路径static拼接图片返回路径
+ * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg
+ */
+ @Multipart
+ @POST("/imageUpload")
+ suspend fun uploadImage(
+ @Header("token") token: String,
+ @Part file: MultipartBody.Part
+ ): String
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt
new file mode 100644
index 0000000..db99cfb
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt
@@ -0,0 +1,50 @@
+package com.casic.smarttube.utils.retrofit
+
+import com.casic.smarttube.utils.AuthenticationHelper
+import okhttp3.MediaType.Companion.toMediaTypeOrNull
+import okhttp3.MultipartBody
+import okhttp3.RequestBody
+import java.io.File
+
+
+object RetrofitServiceManager {
+
+ private val api by lazy { RetrofitFactory.createRetrofit(RetrofitService::class.java) }
+
+ /**
+ * 验证PublicKey
+ */
+ suspend fun authenticate(): String {
+ return api.obtainPublicKey()
+ }
+
+ /**
+ * 登录并获取Token
+ */
+ suspend fun login(sid: String, account: String, secretKey: String): String {
+ return api.obtainLoginResult(sid, account, secretKey)
+ }
+
+ /**
+ * 退出登录
+ */
+ suspend fun loginOut(): String {
+ return api.loginOut(AuthenticationHelper.token!!)
+ }
+
+ /**
+ * 获取用户信息
+ */
+ suspend fun obtainUserDetail(): String {
+ return api.obtainUserDetail(AuthenticationHelper.token!!)
+ }
+
+ /**
+ * 上传图片
+ */
+ suspend fun uploadImage(image: File): String {
+ val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image)
+ val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody)
+ return api.uploadImage(AuthenticationHelper.token!!, imagePart)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/view/LoginActivity.kt b/app/src/main/java/com/casic/smarttube/view/LoginActivity.kt
new file mode 100644
index 0000000..aeccd80
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/view/LoginActivity.kt
@@ -0,0 +1,134 @@
+package com.casic.smarttube.view
+
+import android.text.Editable
+import android.text.TextWatcher
+import android.view.KeyEvent
+import android.view.inputmethod.EditorInfo
+import android.widget.EditText
+import android.widget.TextView
+import androidx.lifecycle.ViewModelProvider
+import com.casic.smarttube.R
+import com.casic.smarttube.utils.AuthenticationHelper
+import com.casic.smarttube.utils.DialogHelper
+import com.casic.smarttube.utils.LocalConstant
+import com.casic.smarttube.utils.RSAUtils
+import com.casic.smarttube.vm.AuthenticateViewModel
+import com.casic.smarttube.vm.LoginViewModel
+import com.casic.smarttube.vm.UserViewModel
+import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import com.pengxh.kt.lite.vm.LoadState
+import kotlinx.android.synthetic.main.activity_login.*
+
+class LoginActivity : KotlinBaseActivity() {
+
+ private lateinit var authenticateViewModel: AuthenticateViewModel
+ private lateinit var loginViewModel: LoginViewModel
+ private lateinit var userViewModel: UserViewModel
+ private val textWatcher = object : TextWatcher {
+ override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
+
+ }
+
+ override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
+
+ }
+
+ override fun afterTextChanged(s: Editable) {
+ if (s.toString().trim { it <= ' ' }.length > 16) {
+ inputLayout.error = "密码长度超出限制"
+ } else {
+ inputLayout.error = null
+ }
+ }
+ }
+
+ override fun initLayoutView(): Int = R.layout.activity_login
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(true).init()
+ }
+
+ override fun initData() {
+ // 设置默认账号密码
+ userNameView.setText(SaveKeyValues.getValue(LocalConstant.ACCOUNT, "") as String)
+ userPasswordView.setText(SaveKeyValues.getValue(LocalConstant.PASSWORD, "") as String)
+ authenticateViewModel = ViewModelProvider(this).get(AuthenticateViewModel::class.java)
+ loginViewModel = ViewModelProvider(this).get(LoginViewModel::class.java)
+ userViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
+ }
+
+ override fun initEvent() {
+ val editText: EditText? = inputLayout.editText
+ editText?.addTextChangedListener(textWatcher)
+ //点击输入法键盘"完成"
+ editText?.setOnEditorActionListener { _: TextView?, actionId: Int, _: KeyEvent? ->
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ authenticateViewModel.obtainPublicKey()
+ return@setOnEditorActionListener true
+ }
+ false
+ }
+
+ loginButton.setOnClickListener {
+ val account = userNameView.text.toString().trim()
+ val userPassword = userPasswordView.text.toString().trim()
+ if (account.isBlank()) {
+ "用户名不能为空".show(this)
+ return@setOnClickListener
+ }
+ if (userPassword.isBlank()) {
+ "密码不能为空".show(this)
+ return@setOnClickListener
+ }
+ SaveKeyValues.putValue(LocalConstant.ACCOUNT, account)
+ SaveKeyValues.putValue(LocalConstant.PASSWORD, userPassword)
+ authenticateViewModel.obtainPublicKey()
+ }
+ authenticateViewModel.keyModel.observe(this, {
+ if (it.code == 200) {//用code判断,别的判断可能有坑
+ val keyString = it.data!!.publicKey!!
+ /**
+ * 修改密码需要用到key,先存着
+ * */
+ AuthenticationHelper.savePublicKey(keyString)
+ val publicKey = RSAUtils.keyStrToPublicKey(keyString)
+
+ val account = userNameView.text.toString()
+ val userPassword = userPasswordView.text.toString()
+ val dataByPublicKey =
+ RSAUtils.encryptDataByPublicKey(userPassword.toByteArray(), publicKey!!)
+ //登录并获取Token,POST请求
+ loginViewModel.enter(it.data!!.sid!!, account, dataByPublicKey)
+ loginViewModel.enterResultModel.observe(this, { loginResult ->
+ if (loginResult.code == 200) {
+ AuthenticationHelper.saveToken(loginResult.data!!.token!!)
+ /**
+ * 获取token之后保存用户信息
+ * */
+ userViewModel.obtainUserDetail()
+ //验证成功登录
+ this.navigatePageTo()
+ finish()
+ }
+ })
+ loginViewModel.loadState.observe(this, { loginState ->
+ when (loginState) {
+ is LoadState.Loading -> {
+ DialogHelper.showLoadingDialog(this, "登录中,请稍后")
+ }
+ is LoadState.Success -> {
+ DialogHelper.dismissLoadingDialog()
+ }
+ else -> {
+ DialogHelper.dismissLoadingDialog()
+ }
+ }
+ })
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/view/PermissionActivity.kt b/app/src/main/java/com/casic/smarttube/view/PermissionActivity.kt
index c05f04a..d6dee4d 100644
--- a/app/src/main/java/com/casic/smarttube/view/PermissionActivity.kt
+++ b/app/src/main/java/com/casic/smarttube/view/PermissionActivity.kt
@@ -1,32 +1,46 @@
package com.casic.smarttube.view
-import android.os.Bundle
-import androidx.appcompat.app.AppCompatActivity
import com.amap.api.navi.NaviSetting
-import com.casic.smarttube.utils.Constant
+import com.casic.smarttube.R
+import com.casic.smarttube.utils.LocalConstant
+import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.extensions.convertColor
import com.pengxh.kt.lite.extensions.navigatePageTo
-import com.pengxh.kt.lite.utils.PageNavigationManager
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_permssion.*
import pub.devrel.easypermissions.EasyPermissions
import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks
-class PermissionActivity : AppCompatActivity(), PermissionCallbacks {
+class PermissionActivity : KotlinBaseActivity(), PermissionCallbacks {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- PageNavigationManager.addActivity(this)
+ override fun initLayoutView(): Int = R.layout.activity_permssion
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(true).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.white.convertColor(this))
+ }
+
+ override fun initData() {
//判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。
- if (EasyPermissions.hasPermissions(this, *Constant.USER_PERMISSIONS)) {
+ if (EasyPermissions.hasPermissions(this, *LocalConstant.USER_PERMISSIONS)) {
startSplashScreenActivity()
} else {
- EasyPermissions.requestPermissions(
- this,
- "需要获取相关权限",
- Constant.PERMISSIONS_CODE,
- *Constant.USER_PERMISSIONS
- )
+ enterMainButton.setOnClickListener {
+ EasyPermissions.requestPermissions(
+ this@PermissionActivity,
+ resources.getString(R.string.app_name) + "需要获取存储相关权限",
+ LocalConstant.PERMISSIONS_CODE,
+ *LocalConstant.USER_PERMISSIONS
+ )
+ }
}
}
+ override fun initEvent() {
+
+ }
+
private fun startSplashScreenActivity() {
//先把导航隐私政策声明,后面导航会用到
NaviSetting.updatePrivacyShow(this, true, true)
@@ -36,9 +50,7 @@
}
override fun onRequestPermissionsResult(
- requestCode: Int,
- permissions: Array,
- grantResults: IntArray
+ requestCode: Int, permissions: Array, grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
diff --git a/app/src/main/java/com/casic/smarttube/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/smarttube/view/SplashScreenActivity.kt
index ba7ef6c..5b00fc6 100644
--- a/app/src/main/java/com/casic/smarttube/view/SplashScreenActivity.kt
+++ b/app/src/main/java/com/casic/smarttube/view/SplashScreenActivity.kt
@@ -1,11 +1,39 @@
package com.casic.smarttube.view
+import android.annotation.SuppressLint
+import android.os.CountDownTimer
+import androidx.lifecycle.ViewModelProvider
import com.casic.smarttube.R
+import com.casic.smarttube.vm.UserViewModel
import com.gyf.immersionbar.ImmersionBar
import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.extensions.navigatePageTo
+@SuppressLint("CustomSplashScreen")
class SplashScreenActivity : KotlinBaseActivity() {
+ private lateinit var userDetailViewModel: UserViewModel
+ private val countDownTimer = object : CountDownTimer(1000, 500) {
+ override fun onFinish() {
+ /**
+ * 获取token之后保存用户信息
+ * */
+ userDetailViewModel.obtainUserDetail()
+ userDetailViewModel.userDetailModel.observe(this@SplashScreenActivity, {
+ if (it.code == 200) {
+ navigatePageTo()
+ } else {
+ navigatePageTo()
+ }
+ finish()
+ })
+ }
+
+ override fun onTick(millisUntilFinished: Long) {
+
+ }
+ }
+
override fun initLayoutView(): Int = R.layout.activity_splash
override fun setupTopBarLayout() {
@@ -13,10 +41,10 @@
}
override fun initData() {
-
+ userDetailViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
}
override fun initEvent() {
-
+ countDownTimer.start()
}
}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index a2ebaeb..ec40a5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,9 @@
implementation 'pub.devrel:easypermissions:3.0.0'
//沉浸式状态栏。基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
+ //Loading框
+ implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
+ implementation 'com.qmuiteam:arch:0.3.1'
//MVVM+LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index 0999d5f..07fbb2e 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96992be..135b8bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
diff --git a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
index 4ee1561..de0d0b9 100644
--- a/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/smarttube/base/BaseApplication.kt
@@ -2,11 +2,19 @@
import android.app.Application
import com.pengxh.kt.lite.utils.SaveKeyValues
+import kotlin.properties.Delegates
class BaseApplication : Application() {
+ companion object {
+ private var instance: BaseApplication by Delegates.notNull()
+
+ fun obtainInstance() = instance
+ }
+
override fun onCreate() {
super.onCreate()
+ instance = this
SaveKeyValues.initSharedPreferences(this)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt
new file mode 100644
index 0000000..e585cca
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt
@@ -0,0 +1,35 @@
+package com.casic.smarttube.extensions
+
+import com.casic.smarttube.model.ErrorMessageModel
+import com.casic.smarttube.utils.LocalConstant
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import org.json.JSONObject
+import java.util.*
+
+/**
+ * String扩展方法
+ */
+fun String.separateResponseCode(): Int {
+ if (this.isBlank()) {
+ return 404
+ }
+ return JSONObject(this).getInt("code")
+}
+
+fun String.toErrorMessage(): String {
+ val errorModel = Gson().fromJson(
+ this, object : TypeToken() {}.type
+ )
+ return errorModel.message.toString()
+}
+
+//拼接图片地址
+fun String.combineImagePath(): String {
+ if (this.isEmpty()) return this
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return "$defaultValue/static/${this.replace("\\", "/")}"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
new file mode 100644
index 0000000..eecfd74
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/CommonResultModel.java
@@ -0,0 +1,43 @@
+package com.casic.smarttube.model;
+
+/**
+ * 普通实体类,失败/成功数据结构一致
+ */
+public class CommonResultModel {
+ private int code;
+ private String data;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
new file mode 100644
index 0000000..411674a
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/ErrorMessageModel.java
@@ -0,0 +1,49 @@
+package com.casic.smarttube.model;
+
+public class ErrorMessageModel {
+ private int code;
+ private String data;
+ private String exceptionClazz;
+ private String message;
+ private boolean isSuccess;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getExceptionClazz() {
+ return exceptionClazz;
+ }
+
+ public void setExceptionClazz(String exceptionClazz) {
+ this.exceptionClazz = exceptionClazz;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
new file mode 100644
index 0000000..6497254
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/LoginResultModel.java
@@ -0,0 +1,62 @@
+package com.casic.smarttube.model;
+
+public class LoginResultModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private String kaptcha;
+ private String token;
+
+ public String getKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(String kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
new file mode 100644
index 0000000..d440bc8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/PublicKeyModel.java
@@ -0,0 +1,80 @@
+package com.casic.smarttube.model;
+
+public class PublicKeyModel {
+
+ private int code;
+ private DataBean data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public DataBean getData() {
+ return data;
+ }
+
+ public void setData(DataBean data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataBean {
+ private boolean appKaptcha;
+ private boolean kaptcha;
+ private String publicKey;
+ private String sid;
+
+ public boolean isAppKaptcha() {
+ return appKaptcha;
+ }
+
+ public void setAppKaptcha(boolean appKaptcha) {
+ this.appKaptcha = appKaptcha;
+ }
+
+ public boolean isKaptcha() {
+ return kaptcha;
+ }
+
+ public void setKaptcha(boolean kaptcha) {
+ this.kaptcha = kaptcha;
+ }
+
+ public String getPublicKey() {
+ return publicKey;
+ }
+
+ public void setPublicKey(String publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public String getSid() {
+ return sid;
+ }
+
+ public void setSid(String sid) {
+ this.sid = sid;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
new file mode 100644
index 0000000..149bec8
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/model/UserDetailModel.java
@@ -0,0 +1,227 @@
+package com.casic.smarttube.model;
+
+
+import java.util.List;
+
+public class UserDetailModel {
+ private int code;
+ private Data data;
+ private String message;
+ private boolean success;
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setData(Data data) {
+ this.data = data;
+ }
+
+ public Data getData() {
+ return data;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public boolean getSuccess() {
+ return success;
+ }
+
+ public static class Data {
+
+ private String account;
+ private String attr1;
+ private String avatar;
+ private String bizData;
+ private List dataScope;
+ private String deptId;
+ private String deptName;
+ private List devices;
+ private String id;
+ private String ipAddr;
+ private String name;
+ private String phone;
+ private List roleList;
+ private List roleNames;
+ private List roleTips;
+ private String scopeType;
+ private String sysData;
+ private String targetId;
+ private String targetName;
+ private String tenantId;
+
+ public void setAccount(String account) {
+ this.account = account;
+ }
+
+ public String getAccount() {
+ return account;
+ }
+
+ public void setAttr1(String attr1) {
+ this.attr1 = attr1;
+ }
+
+ public String getAttr1() {
+ return attr1;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setBizData(String bizData) {
+ this.bizData = bizData;
+ }
+
+ public String getBizData() {
+ return bizData;
+ }
+
+ public void setDataScope(List dataScope) {
+ this.dataScope = dataScope;
+ }
+
+ public List getDataScope() {
+ return dataScope;
+ }
+
+ public void setDeptId(String deptId) {
+ this.deptId = deptId;
+ }
+
+ public String getDeptId() {
+ return deptId;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDevices(List devices) {
+ this.devices = devices;
+ }
+
+ public List getDevices() {
+ return devices;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setIpAddr(String ipAddr) {
+ this.ipAddr = ipAddr;
+ }
+
+ public String getIpAddr() {
+ return ipAddr;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setRoleList(List roleList) {
+ this.roleList = roleList;
+ }
+
+ public List getRoleList() {
+ return roleList;
+ }
+
+ public void setRoleNames(List roleNames) {
+ this.roleNames = roleNames;
+ }
+
+ public List getRoleNames() {
+ return roleNames;
+ }
+
+ public void setRoleTips(List roleTips) {
+ this.roleTips = roleTips;
+ }
+
+ public List getRoleTips() {
+ return roleTips;
+ }
+
+ public void setScopeType(String scopeType) {
+ this.scopeType = scopeType;
+ }
+
+ public String getScopeType() {
+ return scopeType;
+ }
+
+ public void setSysData(String sysData) {
+ this.sysData = sysData;
+ }
+
+ public String getSysData() {
+ return sysData;
+ }
+
+ public void setTargetId(String targetId) {
+ this.targetId = targetId;
+ }
+
+ public String getTargetId() {
+ return targetId;
+ }
+
+ public void setTargetName(String targetName) {
+ this.targetName = targetName;
+ }
+
+ public String getTargetName() {
+ return targetName;
+ }
+
+ public void setTenantId(String tenantId) {
+ this.tenantId = tenantId;
+ }
+
+ public String getTenantId() {
+ return tenantId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
new file mode 100644
index 0000000..b44fec6
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/AuthenticationHelper.kt
@@ -0,0 +1,24 @@
+package com.casic.smarttube.utils
+
+import com.pengxh.kt.lite.utils.SaveKeyValues
+
+object AuthenticationHelper {
+
+ fun savePublicKey(key: String) {
+ SaveKeyValues.putValue("keyString", key)
+ }
+
+ val publicKey: String?
+ get() = SaveKeyValues.getValue("keyString", "") as String?
+
+ fun saveToken(token: String?) {
+ SaveKeyValues.putValue("token", token!!)
+ }
+
+ val token: String?
+ get() = SaveKeyValues.getValue("token", "") as String?
+
+ fun removeToken() {
+ SaveKeyValues.removeKey("token")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/Constant.kt b/app/src/main/java/com/casic/smarttube/utils/Constant.kt
deleted file mode 100644
index d921387..0000000
--- a/app/src/main/java/com/casic/smarttube/utils/Constant.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.casic.smarttube.utils
-
-import android.Manifest
-
-
-object Constant {
- val USER_PERMISSIONS = arrayOf(
- Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
- Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
- Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
- Manifest.permission.READ_PHONE_STATE
- )
-
- const val PERMISSIONS_CODE = 999
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
new file mode 100644
index 0000000..bb97c01
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/DialogHelper.kt
@@ -0,0 +1,29 @@
+package com.casic.smarttube.utils;
+
+import android.app.Activity
+import android.view.WindowManager
+import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
+
+object DialogHelper {
+ private lateinit var loadingDialog: QMUITipDialog
+
+ fun showLoadingDialog(activity: Activity, message: String?) {
+ loadingDialog = QMUITipDialog.Builder(activity)
+ .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+ .setTipWord(message)
+ .create()
+ if (!activity.isDestroyed) {
+ try {
+ loadingDialog.show()
+ } catch (e: WindowManager.BadTokenException) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ fun dismissLoadingDialog() {
+ if (loadingDialog.isShowing) {
+ loadingDialog.dismiss()
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
new file mode 100644
index 0000000..cee379c
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt
@@ -0,0 +1,43 @@
+package com.casic.smarttube.utils
+
+import android.Manifest
+
+
+object LocalConstant {
+ /**
+ * =============================================================================================
+ * Array
+ * =============================================================================================
+ * */
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
+ Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
+ Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.READ_PHONE_STATE
+ )
+
+ /**
+ * =============================================================================================
+ * Int
+ * =============================================================================================
+ * */
+ const val PERMISSIONS_CODE = 999
+
+ /**
+ * =============================================================================================
+ * Long
+ * =============================================================================================
+ * */
+
+
+ /**
+ * =============================================================================================
+ * String
+ * =============================================================================================
+ * */
+ const val USER_DETAIL_MODEL = "userDetailModel"
+ const val SERVER_BASE_URL = "http://111.198.10.15:11304"
+ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val ACCOUNT = "account"
+ const val PASSWORD = "password"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt b/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt
new file mode 100644
index 0000000..14e2f56
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/RSAUtils.kt
@@ -0,0 +1,58 @@
+package com.casic.smarttube.utils
+
+import android.util.Base64
+import java.security.*
+import java.security.spec.InvalidKeySpecException
+import java.security.spec.X509EncodedKeySpec
+import javax.crypto.BadPaddingException
+import javax.crypto.Cipher
+import javax.crypto.IllegalBlockSizeException
+import javax.crypto.NoSuchPaddingException
+
+object RSAUtils {
+ //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding"
+ private fun processData(srcData: ByteArray, key: Key): ByteArray? { //用来保存处理结果
+ var resultBytes: ByteArray? = null
+ try { //获取Cipher实例
+ val cipher = Cipher.getInstance("RSA/None/PKCS1Padding")
+ //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥
+ cipher.init(Cipher.ENCRYPT_MODE, key)
+ //处理数据
+ resultBytes = cipher.doFinal(srcData)
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ } catch (e: NoSuchPaddingException) {
+ e.printStackTrace()
+ } catch (e: InvalidKeyException) {
+ e.printStackTrace()
+ } catch (e: BadPaddingException) {
+ e.printStackTrace()
+ } catch (e: IllegalBlockSizeException) {
+ e.printStackTrace()
+ }
+ return resultBytes
+ }
+
+ fun encryptDataByPublicKey(srcData: ByteArray, publicKey: PublicKey): String {
+ val resultBytes =
+ processData(srcData, publicKey)
+ return Base64.encodeToString(resultBytes, Base64.DEFAULT)
+ }
+
+ fun keyStrToPublicKey(publicKeyStr: String?): PublicKey? {
+ var publicKey: PublicKey? = null
+ val keyBytes =
+ Base64.decode(publicKeyStr, Base64.DEFAULT)
+ val keySpec =
+ X509EncodedKeySpec(keyBytes)
+ try {
+ val keyFactory = KeyFactory.getInstance("RSA")
+ publicKey = keyFactory.generatePublic(keySpec)
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ } catch (e: InvalidKeySpecException) {
+ e.printStackTrace()
+ }
+ return publicKey
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt
new file mode 100644
index 0000000..660496f
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitFactory.kt
@@ -0,0 +1,47 @@
+package com.casic.smarttube.utils.retrofit;
+
+import android.util.Log
+import com.casic.smarttube.utils.LocalConstant
+import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import okhttp3.OkHttpClient
+import okhttp3.logging.HttpLoggingInterceptor
+import org.jetbrains.annotations.NotNull
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+import retrofit2.converter.scalars.ScalarsConverterFactory
+import java.util.concurrent.TimeUnit
+
+object RetrofitFactory {
+ private const val kTag = "RetrofitFactory"
+
+ private val httpClient: OkHttpClient by lazy { createOKHttpClient() }
+
+ fun createRetrofit(clazz: Class): T {
+ val defaultValue = SaveKeyValues.getValue(
+ LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL
+ ) as String
+ return Retrofit.Builder()
+ .baseUrl(defaultValue)
+ .addConverterFactory(ScalarsConverterFactory.create()) //字符串转换器
+ .addConverterFactory(GsonConverterFactory.create()) //Gson转换器
+ .addCallAdapterFactory(CoroutineCallAdapterFactory.invoke()) //协程请求适配器
+ .client(httpClient) //log拦截器
+ .build().create(clazz)
+ }
+
+ private fun createOKHttpClient(): OkHttpClient { //日志显示级别
+ val interceptor =
+ HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
+ override fun log(@NotNull message: String) {
+ Log.d(kTag, ">>>>> $message")
+ }
+ })
+ interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
+ val builder = OkHttpClient.Builder()
+ .connectTimeout(15, TimeUnit.SECONDS)
+ .readTimeout(15, TimeUnit.SECONDS)
+ .writeTimeout(15, TimeUnit.SECONDS)
+ return builder.addInterceptor(interceptor).build()
+ }
+}
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt
new file mode 100644
index 0000000..6dad7b3
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt
@@ -0,0 +1,52 @@
+package com.casic.smarttube.utils.retrofit
+
+import okhttp3.MultipartBody
+import retrofit2.http.*
+
+
+interface RetrofitService {
+ /**
+ * PublicKey校验
+ */
+ @GET("/config/baseConfig")
+ suspend fun obtainPublicKey(): String
+
+ /**
+ * 登录并获取Token
+ *
+ * @param sid
+ * @param account 用户名
+ * @param secretKey 加密后的密码
+ */
+ @FormUrlEncoded
+ @POST("/user/login")
+ suspend fun obtainLoginResult(
+ @Field("sid") sid: String,
+ @Field("username") account: String,
+ @Field("password") secretKey: String
+ ): String
+
+ /**
+ * 退出登录
+ */
+ @GET("/user/logout")
+ suspend fun loginOut(@Header("token") token: String): String
+
+ /**
+ * 获取用户信息
+ */
+ @GET("/user/info")
+ suspend fun obtainUserDetail(@Header("token") token: String): String
+
+ /**
+ * 上传图片
+ * 系统路径static拼接图片返回路径
+ * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg
+ */
+ @Multipart
+ @POST("/imageUpload")
+ suspend fun uploadImage(
+ @Header("token") token: String,
+ @Part file: MultipartBody.Part
+ ): String
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt
new file mode 100644
index 0000000..db99cfb
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt
@@ -0,0 +1,50 @@
+package com.casic.smarttube.utils.retrofit
+
+import com.casic.smarttube.utils.AuthenticationHelper
+import okhttp3.MediaType.Companion.toMediaTypeOrNull
+import okhttp3.MultipartBody
+import okhttp3.RequestBody
+import java.io.File
+
+
+object RetrofitServiceManager {
+
+ private val api by lazy { RetrofitFactory.createRetrofit(RetrofitService::class.java) }
+
+ /**
+ * 验证PublicKey
+ */
+ suspend fun authenticate(): String {
+ return api.obtainPublicKey()
+ }
+
+ /**
+ * 登录并获取Token
+ */
+ suspend fun login(sid: String, account: String, secretKey: String): String {
+ return api.obtainLoginResult(sid, account, secretKey)
+ }
+
+ /**
+ * 退出登录
+ */
+ suspend fun loginOut(): String {
+ return api.loginOut(AuthenticationHelper.token!!)
+ }
+
+ /**
+ * 获取用户信息
+ */
+ suspend fun obtainUserDetail(): String {
+ return api.obtainUserDetail(AuthenticationHelper.token!!)
+ }
+
+ /**
+ * 上传图片
+ */
+ suspend fun uploadImage(image: File): String {
+ val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image)
+ val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody)
+ return api.uploadImage(AuthenticationHelper.token!!, imagePart)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/smarttube/view/LoginActivity.kt b/app/src/main/java/com/casic/smarttube/view/LoginActivity.kt
new file mode 100644
index 0000000..aeccd80
--- /dev/null
+++ b/app/src/main/java/com/casic/smarttube/view/LoginActivity.kt
@@ -0,0 +1,134 @@
+package com.casic.smarttube.view
+
+import android.text.Editable
+import android.text.TextWatcher
+import android.view.KeyEvent
+import android.view.inputmethod.EditorInfo
+import android.widget.EditText
+import android.widget.TextView
+import androidx.lifecycle.ViewModelProvider
+import com.casic.smarttube.R
+import com.casic.smarttube.utils.AuthenticationHelper
+import com.casic.smarttube.utils.DialogHelper
+import com.casic.smarttube.utils.LocalConstant
+import com.casic.smarttube.utils.RSAUtils
+import com.casic.smarttube.vm.AuthenticateViewModel
+import com.casic.smarttube.vm.LoginViewModel
+import com.casic.smarttube.vm.UserViewModel
+import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.SaveKeyValues
+import com.pengxh.kt.lite.vm.LoadState
+import kotlinx.android.synthetic.main.activity_login.*
+
+class LoginActivity : KotlinBaseActivity() {
+
+ private lateinit var authenticateViewModel: AuthenticateViewModel
+ private lateinit var loginViewModel: LoginViewModel
+ private lateinit var userViewModel: UserViewModel
+ private val textWatcher = object : TextWatcher {
+ override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
+
+ }
+
+ override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
+
+ }
+
+ override fun afterTextChanged(s: Editable) {
+ if (s.toString().trim { it <= ' ' }.length > 16) {
+ inputLayout.error = "密码长度超出限制"
+ } else {
+ inputLayout.error = null
+ }
+ }
+ }
+
+ override fun initLayoutView(): Int = R.layout.activity_login
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(true).init()
+ }
+
+ override fun initData() {
+ // 设置默认账号密码
+ userNameView.setText(SaveKeyValues.getValue(LocalConstant.ACCOUNT, "") as String)
+ userPasswordView.setText(SaveKeyValues.getValue(LocalConstant.PASSWORD, "") as String)
+ authenticateViewModel = ViewModelProvider(this).get(AuthenticateViewModel::class.java)
+ loginViewModel = ViewModelProvider(this).get(LoginViewModel::class.java)
+ userViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
+ }
+
+ override fun initEvent() {
+ val editText: EditText? = inputLayout.editText
+ editText?.addTextChangedListener(textWatcher)
+ //点击输入法键盘"完成"
+ editText?.setOnEditorActionListener { _: TextView?, actionId: Int, _: KeyEvent? ->
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ authenticateViewModel.obtainPublicKey()
+ return@setOnEditorActionListener true
+ }
+ false
+ }
+
+ loginButton.setOnClickListener {
+ val account = userNameView.text.toString().trim()
+ val userPassword = userPasswordView.text.toString().trim()
+ if (account.isBlank()) {
+ "用户名不能为空".show(this)
+ return@setOnClickListener
+ }
+ if (userPassword.isBlank()) {
+ "密码不能为空".show(this)
+ return@setOnClickListener
+ }
+ SaveKeyValues.putValue(LocalConstant.ACCOUNT, account)
+ SaveKeyValues.putValue(LocalConstant.PASSWORD, userPassword)
+ authenticateViewModel.obtainPublicKey()
+ }
+ authenticateViewModel.keyModel.observe(this, {
+ if (it.code == 200) {//用code判断,别的判断可能有坑
+ val keyString = it.data!!.publicKey!!
+ /**
+ * 修改密码需要用到key,先存着
+ * */
+ AuthenticationHelper.savePublicKey(keyString)
+ val publicKey = RSAUtils.keyStrToPublicKey(keyString)
+
+ val account = userNameView.text.toString()
+ val userPassword = userPasswordView.text.toString()
+ val dataByPublicKey =
+ RSAUtils.encryptDataByPublicKey(userPassword.toByteArray(), publicKey!!)
+ //登录并获取Token,POST请求
+ loginViewModel.enter(it.data!!.sid!!, account, dataByPublicKey)
+ loginViewModel.enterResultModel.observe(this, { loginResult ->
+ if (loginResult.code == 200) {
+ AuthenticationHelper.saveToken(loginResult.data!!.token!!)
+ /**
+ * 获取token之后保存用户信息
+ * */
+ userViewModel.obtainUserDetail()
+ //验证成功登录
+ this.navigatePageTo