From f15fd6588ef44b85b1abcb9b8c17f00dffa88f02 Mon Sep 17 00:00:00 2001
From: pan <1029559041@qq.com>
Date: Fri, 28 May 2021 00:05:54 +0800
Subject: [PATCH] =?UTF-8?q?=E5=89=8D=E5=8F=B0AndroidManifest.xml=20?=
=?UTF-8?q?=E5=88=A0=E9=99=A4=E9=83=A8=E5=88=86Activity=20exported?=
=?UTF-8?q?=E9=85=8D=E7=BD=AE=20=E7=BB=A7=E6=89=BF=E7=99=BB=E5=BD=95?=
=?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=88=B0lib=20=E7=A7=BB=E5=8A=A8=E5=8A=A8?=
=?UTF-8?q?=E7=94=BB=E6=96=87=E6=9C=AC=E7=BB=84=E4=BB=B6=E5=88=B0lib=20Scr?=
=?UTF-8?q?ollList.kt->ScrollViewModel.kt=20Api=E7=A7=BB=E5=8A=A8=E5=88=B0?=
=?UTF-8?q?lib?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
background/src/main/AndroidManifest.xml | 7 +-
.../main/java/com/gyf/csams/InitActivity.kt | 14 ++
.../gyf/csams/account/model/LoginViewModel.kt | 32 +++-
.../com/gyf/csams/account/ui/LoginActivity.kt | 38 +++--
.../model/AssociationManagementViewModel.kt | 7 +-
.../gyf/csams/main/model/CheckActViewModel.kt | 2 +-
.../main/model/CheckQualityReportViewModel.kt | 2 +-
.../csams/main/model/ManagerActViewModel.kt | 4 +-
.../gyf/csams/main/model/RenameViewModel.kt | 4 +-
.../main/ui/AssociationManagementActivity.kt | 2 -
.../com/gyf/csams/main/ui/MainActivity.kt | 1 +
.../main/java/com/gyf/csams/uikit/Table.kt | 4 +-
foreground/src/main/AndroidManifest.xml | 40 ++---
.../main/java/com/gyf/csams/InitActivity.kt | 65 +-------
.../csams/account/model/AccountViewModel.kt | 142 +++++-------------
.../gyf/csams/account/ui/AccountActivity.kt | 28 ++--
.../activity/model/ActivityDetailViewModel.kt | 13 +-
.../csams/activity/model/ApplyActViewModel.kt | 2 +-
.../association/model/AssociationViewModel.kt | 9 +-
.../csams/association/model/ExamViewModel.kt | 7 +-
.../model/RegAssociationViewModel.kt | 8 +-
.../association/model/RenameViewModel.kt | 2 +-
.../com/gyf/csams/main/model/MainViewModel.kt | 9 +-
.../com/gyf/csams/main/ui/MainActivity.kt | 2 +-
.../message/model/SysMessageViewModel.kt | 18 +--
.../main/java/com/gyf/csams/uikit/BaseView.kt | 24 ---
.../java/com/gyf/csams/uikit/ViewModel.kt | 4 +-
lib/src/main/java/com/gyf/lib/ScrollList.kt | 34 -----
.../gyf/lib/model/AbstractLoginViewModel.kt | 80 ++++++++++
.../com/gyf/{ => lib/model}/ApplyViewModel.kt | 5 +-
.../java/com/gyf/lib/model}/InitViewModel.kt | 15 +-
.../java/com/gyf/lib/model/ScrollViewModel.kt | 19 +++
.../gyf/lib/{ => service}/MessageService.kt | 15 +-
.../{ => lib/service}/NotificationWorker.kt | 9 +-
.../com/gyf/lib/uikit/AbstractInitActivity.kt | 66 ++++++++
.../java/com/gyf/lib/uikit/AnimationText.kt | 33 ++++
.../src/main/java/com/gyf/lib/util}/Api.kt | 24 ++-
.../main/java/com/gyf/lib/util/ContextUtil.kt | 4 +-
lib/src/main/res/values-en/strings.xml | 1 +
lib/src/main/res/values-zh/strings.xml | 1 +
lib/src/main/res/values/strings.xml | 1 +
41 files changed, 432 insertions(+), 365 deletions(-)
create mode 100644 background/src/main/java/com/gyf/csams/InitActivity.kt
delete mode 100644 lib/src/main/java/com/gyf/lib/ScrollList.kt
create mode 100644 lib/src/main/java/com/gyf/lib/model/AbstractLoginViewModel.kt
rename lib/src/main/java/com/gyf/{ => lib/model}/ApplyViewModel.kt (78%)
rename {foreground/src/main/java/com/gyf/csams => lib/src/main/java/com/gyf/lib/model}/InitViewModel.kt (90%)
create mode 100644 lib/src/main/java/com/gyf/lib/model/ScrollViewModel.kt
rename lib/src/main/java/com/gyf/lib/{ => service}/MessageService.kt (83%)
rename lib/src/main/java/com/gyf/{ => lib/service}/NotificationWorker.kt (93%)
create mode 100644 lib/src/main/java/com/gyf/lib/uikit/AbstractInitActivity.kt
create mode 100644 lib/src/main/java/com/gyf/lib/uikit/AnimationText.kt
rename {foreground/src/main/java/com/gyf/csams => lib/src/main/java/com/gyf/lib/util}/Api.kt (74%)
diff --git a/background/src/main/AndroidManifest.xml b/background/src/main/AndroidManifest.xml
index 75bf62d..64952af 100644
--- a/background/src/main/AndroidManifest.xml
+++ b/background/src/main/AndroidManifest.xml
@@ -2,6 +2,9 @@
+
+
+
@@ -22,7 +25,7 @@
-
+
diff --git a/background/src/main/java/com/gyf/csams/InitActivity.kt b/background/src/main/java/com/gyf/csams/InitActivity.kt
new file mode 100644
index 0000000..46e03f5
--- /dev/null
+++ b/background/src/main/java/com/gyf/csams/InitActivity.kt
@@ -0,0 +1,14 @@
+package com.gyf.csams
+
+import android.app.Activity
+import com.gyf.csams.account.ui.LoginActivity
+import com.gyf.csams.main.ui.MainActivity
+import com.gyf.lib.uikit.AbstractInitActivity
+import com.gyf.lib.util.AccountApi
+
+class InitActivity : AbstractInitActivity() {
+ override val main: Class = MainActivity::class.java
+ override val login: Class = LoginActivity::class.java
+
+ override val api: AccountApi = AccountApi.BackgroundToken
+}
\ No newline at end of file
diff --git a/background/src/main/java/com/gyf/csams/account/model/LoginViewModel.kt b/background/src/main/java/com/gyf/csams/account/model/LoginViewModel.kt
index 99354da..ad0d804 100644
--- a/background/src/main/java/com/gyf/csams/account/model/LoginViewModel.kt
+++ b/background/src/main/java/com/gyf/csams/account/model/LoginViewModel.kt
@@ -1,11 +1,31 @@
package com.gyf.csams.account.model
-import androidx.lifecycle.ViewModel
-import com.gyf.lib.uikit.StringForm
+import android.app.Application
+import android.os.Build
+import com.gyf.lib.model.AbstractLoginViewModel
+import com.gyf.lib.uikit.FormStatus
+import com.gyf.lib.uikit.ValidStringForm
+import com.gyf.lib.util.AccountApi
-class LoginViewModel : ViewModel() {
- val user = StringForm(formDesc = "管理帐号", textLength = 8)
- val password = StringForm(formDesc = "管理密码", textLength = 8)
+data class ManagerVo(val account: String, val password: String, val device: String)
- val login = "登录"
+class LoginViewModel(application: Application) : AbstractLoginViewModel(application) {
+ override val id = ValidStringForm(formDesc = "管理帐号", textLength = 8)
+ override val password: ValidStringForm = ValidStringForm(formDesc = "管理密码", textLength = 8)
+
+ override val api: AccountApi = AccountApi.BackgroundLogin
+
+ override fun checkForm(): Boolean {
+ return id.statusForm.value == FormStatus.Valid && password.statusForm.value == FormStatus.Valid
+ }
+
+ override fun loginParam(): Any {
+ val account = "${id.formValue.value}"
+ val password = "${password.formValue.value}"
+ return ManagerVo(
+ account = account,
+ password = password,
+ device = "${Build.MANUFACTURER} ${Build.MODEL}"
+ )
+ }
}
\ No newline at end of file
diff --git a/background/src/main/java/com/gyf/csams/account/ui/LoginActivity.kt b/background/src/main/java/com/gyf/csams/account/ui/LoginActivity.kt
index f93bbe3..f1744dd 100644
--- a/background/src/main/java/com/gyf/csams/account/ui/LoginActivity.kt
+++ b/background/src/main/java/com/gyf/csams/account/ui/LoginActivity.kt
@@ -10,17 +10,19 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.material.OutlinedButton
import androidx.compose.material.Text
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
+import com.gyf.csams.R
import com.gyf.csams.account.model.LoginViewModel
import com.gyf.csams.main.ui.MainActivity
-import com.gyf.lib.uikit.BaseTextField
-import com.gyf.lib.uikit.Body
-import com.gyf.lib.uikit.MainBoxFrame
+import com.gyf.lib.uikit.*
/**
* 登录
@@ -45,16 +47,34 @@ class LoginActivity : ComponentActivity() {
horizontalAlignment = Alignment.CenterHorizontally
) {
val model: LoginViewModel = viewModel()
- BaseTextField(form = model.user)
+ val scaffoldModel: ScaffoldModel = viewModel()
+ val idStatus by model.id.statusForm.observeAsState()
+ val passwordStatus by model.password.statusForm.observeAsState()
+ BaseTextField(form = model.id)
+
BaseTextField(
form = model.password,
visualTransformation = PasswordVisualTransformation()
)
- OutlinedButton(onClick = {
- context.startActivity(Intent(context, MainActivity::class.java))
- context.finish()
- }) {
- Text(text = model.login)
+ OutlinedButton(
+ onClick = {
+ model.login {
+ scaffoldModel.update(message = it)
+ }
+ },
+ enabled = idStatus == FormStatus.Valid && passwordStatus == FormStatus.Valid
+ ) {
+ Text(text = stringResource(id = R.string.login_btn))
+ }
+ val finishLogin: Boolean? by model.finishLogin.observeAsState()
+ if (finishLogin == true) {
+ startActivity(
+ Intent(
+ LocalContext.current,
+ MainActivity::class.java
+ )
+ )
+ finish()
}
}
}
diff --git a/background/src/main/java/com/gyf/csams/main/model/AssociationManagementViewModel.kt b/background/src/main/java/com/gyf/csams/main/model/AssociationManagementViewModel.kt
index 0487460..7b5370d 100644
--- a/background/src/main/java/com/gyf/csams/main/model/AssociationManagementViewModel.kt
+++ b/background/src/main/java/com/gyf/csams/main/model/AssociationManagementViewModel.kt
@@ -1,7 +1,8 @@
package com.gyf.csams.main.model
+import android.app.Application
import androidx.lifecycle.viewModelScope
-import com.gyf.lib.ScrollList
+import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.util.randomChinese
import kotlinx.coroutines.launch
@@ -48,7 +49,9 @@ data class AssociationVo(
* 数据状态管理
*
*/
-class AssociationManagementViewModel : ScrollList() {
+class AssociationManagementViewModel(application: Application) : ScrollViewModel(
+ application
+) {
override val initSize: Int = 10
init {
diff --git a/background/src/main/java/com/gyf/csams/main/model/CheckActViewModel.kt b/background/src/main/java/com/gyf/csams/main/model/CheckActViewModel.kt
index cd63b3a..ef4735c 100644
--- a/background/src/main/java/com/gyf/csams/main/model/CheckActViewModel.kt
+++ b/background/src/main/java/com/gyf/csams/main/model/CheckActViewModel.kt
@@ -2,7 +2,7 @@ package com.gyf.csams.main.model
import android.app.Application
import androidx.lifecycle.viewModelScope
-import com.gyf.ApplyViewModel
+import com.gyf.lib.model.ApplyViewModel
import com.gyf.lib.util.format
import com.gyf.lib.util.randomChinese
import com.gyf.lib.util.randomDateTime
diff --git a/background/src/main/java/com/gyf/csams/main/model/CheckQualityReportViewModel.kt b/background/src/main/java/com/gyf/csams/main/model/CheckQualityReportViewModel.kt
index abe20ce..e6b0f27 100644
--- a/background/src/main/java/com/gyf/csams/main/model/CheckQualityReportViewModel.kt
+++ b/background/src/main/java/com/gyf/csams/main/model/CheckQualityReportViewModel.kt
@@ -3,7 +3,7 @@ package com.gyf.csams.main.model
import android.app.Application
import androidx.annotation.IntRange
import androidx.lifecycle.viewModelScope
-import com.gyf.ApplyViewModel
+import com.gyf.lib.model.ApplyViewModel
import com.gyf.lib.util.randomChinese
import kotlinx.coroutines.launch
diff --git a/background/src/main/java/com/gyf/csams/main/model/ManagerActViewModel.kt b/background/src/main/java/com/gyf/csams/main/model/ManagerActViewModel.kt
index 03d58a6..10c9b96 100644
--- a/background/src/main/java/com/gyf/csams/main/model/ManagerActViewModel.kt
+++ b/background/src/main/java/com/gyf/csams/main/model/ManagerActViewModel.kt
@@ -2,7 +2,7 @@ package com.gyf.csams.main.model
import android.app.Application
import androidx.annotation.IntRange
-import com.gyf.lib.ScrollListW
+import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.util.randomChinese
import com.gyf.lib.util.randomDateTime
import com.gyf.lib.util.randomNum
@@ -20,7 +20,7 @@ data class ActivityVo(
*
* @param application
*/
-class ManagerActViewModel(application: Application) : ScrollListW(application) {
+class ManagerActViewModel(application: Application) : ScrollViewModel(application) {
override val initSize: Int = 10
init {
diff --git a/background/src/main/java/com/gyf/csams/main/model/RenameViewModel.kt b/background/src/main/java/com/gyf/csams/main/model/RenameViewModel.kt
index c19ce07..4086745 100644
--- a/background/src/main/java/com/gyf/csams/main/model/RenameViewModel.kt
+++ b/background/src/main/java/com/gyf/csams/main/model/RenameViewModel.kt
@@ -3,7 +3,7 @@ package com.gyf.csams.main.model
import android.app.Application
import androidx.lifecycle.viewModelScope
import com.gyf.csams.R
-import com.gyf.lib.ScrollListW
+import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.uikit.StringForm
import com.gyf.lib.util.randomChinese
import com.gyf.lib.util.randomNum
@@ -24,7 +24,7 @@ data class RenameVo(
val reason: String
)
-class RenameViewModel(application: Application) : ScrollListW(application) {
+class RenameViewModel(application: Application) : ScrollViewModel(application) {
val approverOrigin =
StringForm(formDesc = application.getString(R.string.approver_origin), textLength = 30)
diff --git a/background/src/main/java/com/gyf/csams/main/ui/AssociationManagementActivity.kt b/background/src/main/java/com/gyf/csams/main/ui/AssociationManagementActivity.kt
index 8414a5d..aaa854c 100644
--- a/background/src/main/java/com/gyf/csams/main/ui/AssociationManagementActivity.kt
+++ b/background/src/main/java/com/gyf/csams/main/ui/AssociationManagementActivity.kt
@@ -20,7 +20,6 @@ import com.gyf.csams.main.model.AssociationLevel
import com.gyf.csams.main.model.AssociationManagementViewModel
import com.gyf.lib.uikit.Body
import com.gyf.lib.uikit.MainBoxFrame
-import com.gyf.lib.uikit.ScaffoldModel
/**
* 社团管理
@@ -36,7 +35,6 @@ class AssociationManagementActivity : ComponentActivity() {
val model: AssociationManagementViewModel = viewModel()
val data by model.data.observeAsState()
val listState = rememberLazyListState()
- val scaffoldModel: ScaffoldModel = viewModel()
LazyColumn(modifier = Modifier.fillMaxSize(), state = listState) {
data?.forEach {
it.apply {
diff --git a/background/src/main/java/com/gyf/csams/main/ui/MainActivity.kt b/background/src/main/java/com/gyf/csams/main/ui/MainActivity.kt
index 3f85014..38cb0ee 100644
--- a/background/src/main/java/com/gyf/csams/main/ui/MainActivity.kt
+++ b/background/src/main/java/com/gyf/csams/main/ui/MainActivity.kt
@@ -24,6 +24,7 @@ import com.gyf.lib.uikit.*
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+
setContent {
Body {
val model: MainViewModel = viewModel()
diff --git a/background/src/main/java/com/gyf/csams/uikit/Table.kt b/background/src/main/java/com/gyf/csams/uikit/Table.kt
index d0d3365..384f86a 100644
--- a/background/src/main/java/com/gyf/csams/uikit/Table.kt
+++ b/background/src/main/java/com/gyf/csams/uikit/Table.kt
@@ -17,7 +17,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
-import com.gyf.lib.ScrollListW
+import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.uikit.Body
import com.gyf.lib.uikit.MainColumnFrame
@@ -29,7 +29,7 @@ import com.gyf.lib.uikit.MainColumnFrame
@ExperimentalComposeApi
@Composable
fun TestTable(
- clazz: Class>,
+ clazz: Class>,
@StringRes title: Int? = null,
callback: @Composable (vo: A) -> Unit
) {
diff --git a/foreground/src/main/AndroidManifest.xml b/foreground/src/main/AndroidManifest.xml
index 1f44dd9..93cd004 100644
--- a/foreground/src/main/AndroidManifest.xml
+++ b/foreground/src/main/AndroidManifest.xml
@@ -54,58 +54,38 @@
-
+ android:windowSoftInputMode="stateVisible|adjustResize" />
-
-
+
-
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
\ No newline at end of file
diff --git a/foreground/src/main/java/com/gyf/csams/InitActivity.kt b/foreground/src/main/java/com/gyf/csams/InitActivity.kt
index 53a48ef..11f50ad 100644
--- a/foreground/src/main/java/com/gyf/csams/InitActivity.kt
+++ b/foreground/src/main/java/com/gyf/csams/InitActivity.kt
@@ -1,63 +1,14 @@
package com.gyf.csams
-import android.content.Intent
-import android.os.Bundle
-import androidx.activity.ComponentActivity
-import androidx.activity.compose.setContent
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.livedata.observeAsState
-import androidx.compose.ui.Alignment
-import androidx.lifecycle.viewmodel.compose.viewModel
+import android.app.Activity
import com.gyf.csams.account.ui.AccountActivity
import com.gyf.csams.main.ui.MainActivity
-import com.gyf.csams.uikit.AnimationText
-import com.gyf.lib.uikit.Body
-import com.gyf.lib.uikit.MainBoxFrame
-import com.orhanobut.logger.Logger
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
+import com.gyf.lib.uikit.AbstractInitActivity
+import com.gyf.lib.util.AccountApi
-class InitActivity : ComponentActivity() {
-
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
-
-
- setContent {
- Body {
- MainBoxFrame(background = { /*TODO*/ }, contentAlignment = Alignment.Center) {
- val initViewModel: InitViewModel = viewModel()
- //检查网络
- val isNetWorkWorking: Boolean? by initViewModel.isNetWorkWorking.observeAsState(
- null
- )
- Logger.i("初始化")
- when (isNetWorkWorking) {
- null -> AnimationText(text = "测试服务端运行状态中。。。")
- true -> init(initViewModel = initViewModel)
- false -> AnimationText(text = "无法连接到服务端,请检查服务端地址${BuildConfig.SERVER_ADDRESS}是否配置正确")
- }
- }
- }
- }
-
- }
-
-
- private fun init(initViewModel: InitViewModel) {
- //后台检查token
- initViewModel.hasOnlyUserToken(onSuccess = {
- startActivity(Intent(this, MainActivity::class.java))
- }, onFail = {
- startActivity(Intent(this, AccountActivity::class.java))
- })
- GlobalScope.launch {
- delay(1000)
- finish()
- }
- }
-
-}
+class InitActivity : AbstractInitActivity() {
+ override val main: Class = MainActivity::class.java
+ override val login: Class = AccountActivity::class.java
+ override val api: AccountApi = AccountApi.ForegroundToken
+}
\ No newline at end of file
diff --git a/foreground/src/main/java/com/gyf/csams/account/model/AccountViewModel.kt b/foreground/src/main/java/com/gyf/csams/account/model/AccountViewModel.kt
index abf8c0b..468c0cf 100644
--- a/foreground/src/main/java/com/gyf/csams/account/model/AccountViewModel.kt
+++ b/foreground/src/main/java/com/gyf/csams/account/model/AccountViewModel.kt
@@ -2,20 +2,20 @@ package com.gyf.csams.account.model
import android.app.Application
import android.os.Build
-import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.google.gson.reflect.TypeToken
-import com.gyf.csams.AccountApi
-import com.gyf.csams.Api
import com.gyf.csams.R
import com.gyf.csams.account.ui.AccountRoute
import com.gyf.csams.util.SimpleCallback
+import com.gyf.lib.model.AbstractLoginViewModel
import com.gyf.lib.uikit.FormStatus
-import com.gyf.lib.uikit.StringForm
import com.gyf.lib.uikit.ValidStringForm
-import com.gyf.lib.util.*
+import com.gyf.lib.util.AccountApi
+import com.gyf.lib.util.Api
+import com.gyf.lib.util.ApiResponse
+import com.gyf.lib.util.HttpClient
import com.orhanobut.logger.Logger
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
@@ -55,12 +55,14 @@ data class DialogMessage(val message: String, val userResDto: UserResDto?)
/**
* 注册表单
*/
-class AccountViewModel(application: Application) : AndroidViewModel(application) {
+class AccountViewModel(application: Application) : AbstractLoginViewModel(application) {
val welcomeEnd = application.getString(R.string.welcome_end)
val welcomeStart = application.getString(R.string.welcome_start)
+ override val api: AccountApi = AccountApi.ForegroundLogin
+
//学号
- val studentId = object : ValidStringForm(formDesc = "学号", textLength = 8) {
+ override val id = object : ValidStringForm(formDesc = "学号", textLength = 8) {
override fun check() {
_formValue.value?.let {
when {
@@ -80,38 +82,31 @@ class AccountViewModel(application: Application) : AndroidViewModel(application)
private var checkJob: Job? = null
//姓名
- val name = object : StringForm(formDesc = "姓名", textLength = 4) {
- override fun onChange(value: String) {
- super.onChange(value)
+ val name = object : ValidStringForm(formDesc = "姓名", textLength = 4) {
+ override fun check() {
+ _statusForm.value = FormStatus.Valid
checkForm()
}
}
- private val _isValidName = MutableLiveData()
- val isValidName: LiveData = _isValidName
val nameFormat = "姓名不能为空"
//密码
- val password = object : StringForm(formDesc = "密码", textLength = 8) {
- override fun onChange(value: String) {
- super.onChange(value)
+ override val password = object : ValidStringForm(formDesc = "密码", textLength = 8) {
+ override fun check() {
+ _formValue.value?.let {
+ if (it.matches(Regex("\\d{8}"))) _statusForm.value =
+ FormStatus.Valid else _statusForm.value = FormStatus.FormatError
+ }
checkForm()
}
}
- private val _isValidPwd = MutableLiveData()
- val isValidPwd: LiveData = _isValidPwd
- val passwordFormat = "八位纯数字"
-
- //注册按钮
- private val _isValidForm = MutableLiveData()
+ val passwordFormat = "八位纯数字"
- val isValidForm: LiveData = _isValidForm
private val _dialogMsg = MutableLiveData()
val dialogMsg: LiveData = _dialogMsg
- val loginDesc = "登陆"
-
//返回登陆
val backLogin = "返回$loginDesc"
@@ -127,12 +122,6 @@ class AccountViewModel(application: Application) : AndroidViewModel(application)
//转到注册
var goRegister = "转到$regBtnDesc"
- /**
- * 完成登录状态
- */
- private val _finishLogin = MutableLiveData()
- val finishLogin: LiveData = _finishLogin
-
lateinit var route: AccountRoute
/**
@@ -146,51 +135,44 @@ class AccountViewModel(application: Application) : AndroidViewModel(application)
}
checkJob = viewModelScope.launch {
val url = Api.buildUrl(AccountApi.CheckId)
- Logger.i("检测${studentId.formDesc},请求接口$url")
+ Logger.i("检测${id.formDesc},请求接口$url")
HttpClient.get(
url, SimpleCallback(
- action = "${studentId.formDesc}重复检测",
+ action = "${id.formDesc}重复检测",
onSuccess = {
if (it.body == true) {
result.postValue(FormStatus.Repeat)
} else {
result.postValue(FormStatus.Valid)
}
+ checkForm()
},
onFail = { Logger.e(it) },
type = object : TypeToken>() {}.type
- ), mapOf("studentId" to "${studentId.formValue.value}")
+ ), mapOf("studentId" to "${id.formValue.value}")
)
}
}
}
- /**
- * 检测姓名
- *
- * @return
- */
- private fun checkName(): Boolean {
- _isValidName.value = name.formValue.value?.isNotEmpty()
- return _isValidName.value == true
- }
-
- /**
- * 检测密码
- *
- * @return
- */
- private fun checkPassword(): Boolean {
- _isValidPwd.value = password.formValue.value?.matches(Regex("\\d{8}"))
- return _isValidPwd.value == true
+ override fun loginParam(): Any {
+ val studentId = "${id.formValue.value}"
+ val password = "${password.formValue.value}"
+ return UserLoginVo(
+ studentId = studentId,
+ password = password,
+ device = "${Build.MANUFACTURER} ${Build.MODEL}"
+ )
}
- private fun checkForm(): Boolean {
+ override fun checkForm(): Boolean {
if (checkJob?.isActive == true) {
- _isValidForm.value = false
+ _isValidForm.postValue(false)
} else {
- _isValidForm.value =
- studentId.statusForm.value == FormStatus.Valid && (if (route == AccountRoute.Register) checkName() else checkPassword())
+ _isValidForm.postValue(
+ id.statusForm.value == FormStatus.Valid && (if (route == AccountRoute.Register) name.statusForm.value == FormStatus.Valid
+ else password.statusForm.value == FormStatus.Valid)
+ )
}
return _isValidForm.value == true
}
@@ -218,7 +200,7 @@ class AccountViewModel(application: Application) : AndroidViewModel(application)
type = object : TypeToken>() {}.type
),
jsonParam = UserVo(
- studentId = "${studentId.formValue.value}",
+ studentId = "${id.formValue.value}",
name = "${name.formValue.value}"
)
)
@@ -233,52 +215,8 @@ class AccountViewModel(application: Application) : AndroidViewModel(application)
}
private fun resetForm() {
- studentId.onChange("")
- name.onChange("")
- }
-
- /**
- * 登录
- *
- */
- fun login(callback: (message: String) -> Unit) {
- if (checkForm()) {
- val url = Api.buildUrl(AccountApi.Login)
- Logger.i("开始$loginDesc,请求接口:$url")
- val studentId = "${studentId.formValue.value}"
- val password = "${password.formValue.value}"
- this.studentId.formValue
- Logger.i("使用学号:$studentId,密码:$password 进行登录")
- HttpClient.post(
- url,
- SimpleCallback(
- action = loginDesc,
- onSuccess = {
- Logger.i(it.message)
- callback(it.message)
- val context = getApplication().applicationContext
- it.body?.let {
- val db = AppDatabase.getInstance(context)
- viewModelScope.launch {
- TokenManager.token = it
- db?.tokenDao()?.save(token = it)
- }.invokeOnCompletion {
- _finishLogin.postValue(true)
- }
- }
- },
- onFail = { callback(it) },
- type = object : TypeToken>() {}.type
- ),
- jsonParam = UserLoginVo(
- studentId = studentId,
- password = password,
- device = "${Build.MANUFACTURER} ${Build.MODEL}"
- )
- )
- } else {
- Logger.wtf("表单校验失败,无法$loginDesc!!!")
- }
+ id.clean()
+ name.clean()
}
diff --git a/foreground/src/main/java/com/gyf/csams/account/ui/AccountActivity.kt b/foreground/src/main/java/com/gyf/csams/account/ui/AccountActivity.kt
index 1aa5c80..7babd1e 100644
--- a/foreground/src/main/java/com/gyf/csams/account/ui/AccountActivity.kt
+++ b/foreground/src/main/java/com/gyf/csams/account/ui/AccountActivity.kt
@@ -62,7 +62,7 @@ class AccountActivity : ComponentActivity() {
.padding(bottom = 10.dp)
) {
- Text(text = accountViewModel.loginDesc)
+ Text(text = stringResource(id = R.string.login_btn))
}
val finishLogin: Boolean? by accountViewModel.finishLogin.observeAsState()
@@ -107,7 +107,7 @@ class AccountActivity : ComponentActivity() {
.fillMaxWidth()
.padding(bottom = 10.dp)
) {
- Text(text = accountViewModel.regBtnDesc)
+ Text(text = stringResource(id = R.string.reg_btn))
}
OutlinedButton(
@@ -196,9 +196,9 @@ class AccountActivity : ComponentActivity() {
Column {
- val isValidStudentId by accountViewModel.studentId.statusForm.observeAsState()
+ val isValidStudentId by accountViewModel.id.statusForm.observeAsState()
BaseTextField(
- form = accountViewModel.studentId, keyboardOptions = KeyboardOptions.Default.copy(
+ form = accountViewModel.id, keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Number,
imeAction = ImeAction.Done
), isError = isValidStudentId != FormStatus.Valid
@@ -213,13 +213,13 @@ class AccountActivity : ComponentActivity() {
)
FormStatus.Repeat ->
Text(buildAnnotatedString {
- append(accountViewModel.studentId.formDesc)
+ append(accountViewModel.id.formDesc)
withStyle(
style = MaterialTheme.typography.body1.toSpanStyle().copy(
color = MaterialTheme.colors.error
)
) {
- append(accountViewModel.studentId.formValue.value ?: "")
+ append(accountViewModel.id.formValue.value ?: "")
}
append(accountViewModel.registered)
})
@@ -306,10 +306,10 @@ class AccountActivity : ComponentActivity() {
private fun Name(accountViewModel: AccountViewModel = viewModel()) {
Column {
- val isValidName: Boolean by accountViewModel.isValidName.observeAsState(false)
- BaseTextField(form = accountViewModel.name, isError = !isValidName)
+ val formStatus by accountViewModel.name.statusForm.observeAsState()
+ BaseTextField(form = accountViewModel.name, isError = formStatus !== FormStatus.Valid)
- if (!isValidName) {
+ if (formStatus == FormStatus.Empty) {
Text(
text = accountViewModel.nameFormat,
color = MaterialTheme.colors.error
@@ -326,10 +326,10 @@ class AccountActivity : ComponentActivity() {
@Composable
private fun Password(accountViewModel: AccountViewModel = viewModel()) {
Column {
- val isValidPwd: Boolean by accountViewModel.isValidPwd.observeAsState(false)
+ val formStatus by accountViewModel.password.statusForm.observeAsState()
BaseTextField(
- form = accountViewModel.password, isError = !isValidPwd,
+ form = accountViewModel.password, isError = formStatus !== FormStatus.Valid,
keyboardOptions = KeyboardOptions.Default.copy(
imeAction = ImeAction.Done,
keyboardType = KeyboardType.Number,
@@ -337,11 +337,13 @@ class AccountActivity : ComponentActivity() {
)
- if (!isValidPwd) {
- Text(
+ when (formStatus) {
+ FormStatus.Empty, FormStatus.FormatError -> Text(
text = accountViewModel.passwordFormat,
color = MaterialTheme.colors.error
)
+ else -> {
+ }
}
}
}
diff --git a/foreground/src/main/java/com/gyf/csams/activity/model/ActivityDetailViewModel.kt b/foreground/src/main/java/com/gyf/csams/activity/model/ActivityDetailViewModel.kt
index 7f5dc3d..89f3f9a 100644
--- a/foreground/src/main/java/com/gyf/csams/activity/model/ActivityDetailViewModel.kt
+++ b/foreground/src/main/java/com/gyf/csams/activity/model/ActivityDetailViewModel.kt
@@ -1,15 +1,16 @@
package com.gyf.csams.activity.model
+import android.app.Application
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import com.gyf.csams.NOT_IMPL_TIP
import com.gyf.csams.uikit.AbstractComment
import com.gyf.csams.uikit.ActivityDetailMenu
import com.gyf.csams.uikit.TopMenuInterface
-import com.gyf.lib.ScrollList
+import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.uikit.ValidStringForm
+import com.gyf.lib.util.NOT_IMPL_TIP
import com.gyf.lib.util.randomChinese
import com.gyf.lib.util.randomDateTime
import com.gyf.lib.util.randomNum
@@ -112,7 +113,8 @@ data class ActivityPhotoVo(
* 活动相册数据状态管理
*
*/
-class ActivityPhotoViewModel : ScrollList() {
+class ActivityPhotoViewModel(application: Application) :
+ ScrollViewModel(application) {
override val initSize: Int = 10
init {
@@ -184,7 +186,8 @@ data class ActivityMembersVo(
val participant: MutableList?
)
-class ActivityMemberViewModel : ScrollList() {
+class ActivityMemberViewModel(application: Application) :
+ ScrollViewModel(application) {
override val initSize: Int = 10
private val _allMember = MutableLiveData()
@@ -264,7 +267,7 @@ class BBSCommentModel : AbstractComment() {
* 交流区数据状态管理
*
*/
-class BBSViewModel : ScrollList() {
+class BBSViewModel(application: Application) : ScrollViewModel(application) {
override val initSize: Int = 10
val title = "发送评论"
diff --git a/foreground/src/main/java/com/gyf/csams/activity/model/ApplyActViewModel.kt b/foreground/src/main/java/com/gyf/csams/activity/model/ApplyActViewModel.kt
index cc766ad..6139403 100644
--- a/foreground/src/main/java/com/gyf/csams/activity/model/ApplyActViewModel.kt
+++ b/foreground/src/main/java/com/gyf/csams/activity/model/ApplyActViewModel.kt
@@ -19,12 +19,12 @@ import com.baidu.mapapi.search.sug.SuggestionSearch
import com.baidu.mapapi.search.sug.SuggestionSearchOption
import com.gyf.csams.BuildConfig
import com.gyf.csams.MyLocationListener
-import com.gyf.csams.NOT_IMPL_TIP
import com.gyf.csams.R
import com.gyf.lib.uikit.ScaffoldModel
import com.gyf.lib.uikit.StringForm
import com.gyf.lib.util.ContextUtil
import com.gyf.lib.util.DATETIME_FORMAT
+import com.gyf.lib.util.NOT_IMPL_TIP
import com.orhanobut.logger.Logger
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
diff --git a/foreground/src/main/java/com/gyf/csams/association/model/AssociationViewModel.kt b/foreground/src/main/java/com/gyf/csams/association/model/AssociationViewModel.kt
index 105c7a8..68c66b1 100644
--- a/foreground/src/main/java/com/gyf/csams/association/model/AssociationViewModel.kt
+++ b/foreground/src/main/java/com/gyf/csams/association/model/AssociationViewModel.kt
@@ -1,14 +1,15 @@
package com.gyf.csams.association.model
+import android.app.Application
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import com.gyf.csams.NOT_IMPL_TIP
import com.gyf.csams.uikit.AssociationMenu
import com.gyf.csams.uikit.TopMenuInterface
-import com.gyf.lib.ScrollList
+import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.uikit.StringForm
+import com.gyf.lib.util.NOT_IMPL_TIP
import com.orhanobut.logger.Logger
import kotlinx.coroutines.launch
@@ -47,7 +48,7 @@ data class MemberVo(val name: String)
* 社团会员
*
*/
-class MemberViewModel : ScrollList() {
+class MemberViewModel(application: Application) : ScrollViewModel(application) {
val name = StringForm(formDesc = "姓名关键字", 5)
val search = "搜索"
@@ -125,7 +126,7 @@ data class HistoryActVo(val name: String)
* 历史活动
*
*/
-class HistoryActViewModel : ScrollList() {
+class HistoryActViewModel(application: Application) : ScrollViewModel(application) {
override val initSize = 10
init {
diff --git a/foreground/src/main/java/com/gyf/csams/association/model/ExamViewModel.kt b/foreground/src/main/java/com/gyf/csams/association/model/ExamViewModel.kt
index 65ccd8b..d2d88be 100644
--- a/foreground/src/main/java/com/gyf/csams/association/model/ExamViewModel.kt
+++ b/foreground/src/main/java/com/gyf/csams/association/model/ExamViewModel.kt
@@ -1,11 +1,12 @@
package com.gyf.csams.association.model
+import android.app.Application
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
-import com.gyf.csams.NOT_IMPL_TIP
-import com.gyf.lib.ScrollList
+import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.uikit.StringForm
+import com.gyf.lib.util.NOT_IMPL_TIP
import kotlinx.coroutines.launch
import kotlin.random.Random
@@ -88,7 +89,7 @@ const val ANSWER_TEXT_LENGTH = 15
*
*/
-class ExamViewModel : ScrollList() {
+class ExamViewModel(application: Application) : ScrollViewModel(application) {
val questionIsNull: String = "问题不能为空"
val deleteLeastOne: String = "至少保留一道题目"
val deleteTip = "确定删除此题目?"
diff --git a/foreground/src/main/java/com/gyf/csams/association/model/RegAssociationViewModel.kt b/foreground/src/main/java/com/gyf/csams/association/model/RegAssociationViewModel.kt
index cfdc89b..63c8ed7 100644
--- a/foreground/src/main/java/com/gyf/csams/association/model/RegAssociationViewModel.kt
+++ b/foreground/src/main/java/com/gyf/csams/association/model/RegAssociationViewModel.kt
@@ -7,17 +7,11 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.google.gson.reflect.TypeToken
-import com.gyf.csams.Api
-import com.gyf.csams.AssociationApi
import com.gyf.csams.MainApplication
-import com.gyf.csams.UNKNOW_ERROR
import com.gyf.csams.util.SimpleCallback
import com.gyf.lib.uikit.FormStatus
import com.gyf.lib.uikit.ValidStringForm
-import com.gyf.lib.util.ApiResponse
-import com.gyf.lib.util.HttpClient
-import com.gyf.lib.util.Token
-import com.gyf.lib.util.TokenManager
+import com.gyf.lib.util.*
import com.orhanobut.logger.Logger
import kotlinx.coroutines.launch
import java.io.File
diff --git a/foreground/src/main/java/com/gyf/csams/association/model/RenameViewModel.kt b/foreground/src/main/java/com/gyf/csams/association/model/RenameViewModel.kt
index 332a7e9..f07b224 100644
--- a/foreground/src/main/java/com/gyf/csams/association/model/RenameViewModel.kt
+++ b/foreground/src/main/java/com/gyf/csams/association/model/RenameViewModel.kt
@@ -1,8 +1,8 @@
package com.gyf.csams.association.model
import androidx.lifecycle.ViewModel
-import com.gyf.csams.NOT_IMPL_TIP
import com.gyf.lib.uikit.StringForm
+import com.gyf.lib.util.NOT_IMPL_TIP
/**
* 社团重命名状态管理
diff --git a/foreground/src/main/java/com/gyf/csams/main/model/MainViewModel.kt b/foreground/src/main/java/com/gyf/csams/main/model/MainViewModel.kt
index 727cc90..2b0676c 100644
--- a/foreground/src/main/java/com/gyf/csams/main/model/MainViewModel.kt
+++ b/foreground/src/main/java/com/gyf/csams/main/model/MainViewModel.kt
@@ -5,14 +5,13 @@ import android.app.Application
import android.content.Intent
import androidx.lifecycle.*
import com.google.gson.reflect.TypeToken
-import com.gyf.NotificationDto
-import com.gyf.ReceiverType
-import com.gyf.csams.*
import com.gyf.csams.account.model.UserVo
import com.gyf.csams.account.ui.AccountActivity
import com.gyf.csams.uikit.AbstractComment
import com.gyf.csams.util.SimpleCallback
-import com.gyf.lib.ScrollList
+import com.gyf.lib.model.ScrollViewModel
+import com.gyf.lib.service.NotificationDto
+import com.gyf.lib.service.ReceiverType
import com.gyf.lib.uikit.FormStatus
import com.gyf.lib.uikit.PersonInfoVo
import com.gyf.lib.uikit.StringForm
@@ -173,7 +172,7 @@ data class LeaveMessageVo(val message: String, val token: Token)
* 社团列表
*
*/
-class ListViewModel : ScrollList() {
+class ListViewModel(application: Application) : ScrollViewModel(application) {
val name = StringForm(formDesc = "社团名称", textLength = 5)
val desc = StringForm(formDesc = "社团简介", textLength = 10)
diff --git a/foreground/src/main/java/com/gyf/csams/main/ui/MainActivity.kt b/foreground/src/main/java/com/gyf/csams/main/ui/MainActivity.kt
index 2013f3b..f1b7aad 100644
--- a/foreground/src/main/java/com/gyf/csams/main/ui/MainActivity.kt
+++ b/foreground/src/main/java/com/gyf/csams/main/ui/MainActivity.kt
@@ -31,7 +31,7 @@ import com.gyf.csams.association.ui.RegAssociationActivity
import com.gyf.csams.main.model.*
import com.gyf.csams.message.ui.MessageActivity
import com.gyf.csams.uikit.*
-import com.gyf.lib.MessageService
+import com.gyf.lib.service.MessageService
import com.gyf.lib.uikit.*
import com.gyf.lib.util.randomChinese
diff --git a/foreground/src/main/java/com/gyf/csams/message/model/SysMessageViewModel.kt b/foreground/src/main/java/com/gyf/csams/message/model/SysMessageViewModel.kt
index ec9c389..3680088 100644
--- a/foreground/src/main/java/com/gyf/csams/message/model/SysMessageViewModel.kt
+++ b/foreground/src/main/java/com/gyf/csams/message/model/SysMessageViewModel.kt
@@ -1,20 +1,16 @@
package com.gyf.csams.message.model
+import android.app.Application
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.google.gson.reflect.TypeToken
-import com.gyf.NotificationDto
-import com.gyf.PageDto
-import com.gyf.ReceiverType
-import com.gyf.csams.Api
-import com.gyf.csams.NOT_IMPL_TIP
-import com.gyf.csams.NotificationApi
import com.gyf.csams.util.SimpleCallback
-import com.gyf.lib.ScrollList
-import com.gyf.lib.util.ApiResponse
-import com.gyf.lib.util.HttpClient
-import com.gyf.lib.util.TokenManager
+import com.gyf.lib.model.ScrollViewModel
+import com.gyf.lib.service.NotificationDto
+import com.gyf.lib.service.PageDto
+import com.gyf.lib.service.ReceiverType
+import com.gyf.lib.util.*
import com.orhanobut.logger.Logger
import kotlinx.coroutines.launch
import java.util.*
@@ -89,7 +85,7 @@ data class RenameContent(
* 系统通知数据状态管理
*
*/
-class SysMessageViewModel : ScrollList() {
+class SysMessageViewModel(application: Application) : ScrollViewModel(application) {
val title = "系统通知"
override val initSize: Int = 10
diff --git a/foreground/src/main/java/com/gyf/csams/uikit/BaseView.kt b/foreground/src/main/java/com/gyf/csams/uikit/BaseView.kt
index 298ec99..51c3582 100644
--- a/foreground/src/main/java/com/gyf/csams/uikit/BaseView.kt
+++ b/foreground/src/main/java/com/gyf/csams/uikit/BaseView.kt
@@ -3,7 +3,6 @@ package com.gyf.csams.uikit
import android.app.Activity
import androidx.annotation.DrawableRes
import androidx.compose.animation.Crossfade
-import androidx.compose.animation.animateColor
import androidx.compose.animation.core.*
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
@@ -39,29 +38,6 @@ import com.gyf.csams.main.model.MarqueeViewModel
import com.gyf.lib.uikit.*
import com.orhanobut.logger.Logger
-/**
- * 淡入淡出并且颜色变化文本
- *
- * @param text
- */
-@Composable
-fun AnimationText(text: String) {
- val infiniteTransition = rememberInfiniteTransition()
- val color by infiniteTransition.animateColor(
- initialValue = MaterialTheme.colors.primary,
- targetValue = MaterialTheme.colors.onPrimary,
- animationSpec = infiniteRepeatable(
- animation = tween(1000, easing = LinearEasing),
- repeatMode = RepeatMode.Reverse
- )
- )
-
- Text(
- text = text,
- color = color,
- style = MaterialTheme.typography.body1
- )
-}
/**
* 主菜单
diff --git a/foreground/src/main/java/com/gyf/csams/uikit/ViewModel.kt b/foreground/src/main/java/com/gyf/csams/uikit/ViewModel.kt
index 0b7fcb6..23b5e63 100644
--- a/foreground/src/main/java/com/gyf/csams/uikit/ViewModel.kt
+++ b/foreground/src/main/java/com/gyf/csams/uikit/ViewModel.kt
@@ -7,12 +7,12 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.google.gson.reflect.TypeToken
-import com.gyf.csams.Api
-import com.gyf.csams.MainApi
import com.gyf.csams.R
import com.gyf.csams.util.SimpleCallback
+import com.gyf.lib.util.Api
import com.gyf.lib.util.HttpClient
import com.gyf.lib.util.ImageUtil
+import com.gyf.lib.util.MainApi
import com.orhanobut.logger.Logger
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
diff --git a/lib/src/main/java/com/gyf/lib/ScrollList.kt b/lib/src/main/java/com/gyf/lib/ScrollList.kt
deleted file mode 100644
index 5cad943..0000000
--- a/lib/src/main/java/com/gyf/lib/ScrollList.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.gyf.lib
-
-import android.app.Application
-import androidx.lifecycle.AndroidViewModel
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.ViewModel
-
-@Deprecated(message = "", replaceWith = ReplaceWith(""))
-abstract class ScrollList : ViewModel() {
- protected val _data = MutableLiveData>(mutableListOf())
- val data: LiveData> = _data
-
- abstract val initSize: Int
-
- //加载列表
- abstract fun load()
-
- //加载更多数据
- abstract fun loadMore(callback: (message: String) -> Unit)
-}
-
-abstract class ScrollListW(application: Application) : AndroidViewModel(application) {
- protected val _data = MutableLiveData>(mutableListOf())
- val data: LiveData> = _data
-
- abstract val initSize: Int
-
- //加载列表
- abstract fun load()
-
- //加载更多数据
- abstract fun loadMore(callback: (message: String) -> Unit)
-}
\ No newline at end of file
diff --git a/lib/src/main/java/com/gyf/lib/model/AbstractLoginViewModel.kt b/lib/src/main/java/com/gyf/lib/model/AbstractLoginViewModel.kt
new file mode 100644
index 0000000..562c07d
--- /dev/null
+++ b/lib/src/main/java/com/gyf/lib/model/AbstractLoginViewModel.kt
@@ -0,0 +1,80 @@
+package com.gyf.lib.model
+
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.viewModelScope
+import com.google.gson.reflect.TypeToken
+import com.gyf.lib.R
+import com.gyf.lib.uikit.ValidStringForm
+import com.gyf.lib.util.*
+import com.orhanobut.logger.Logger
+import kotlinx.coroutines.launch
+
+abstract class AbstractLoginViewModel(application: Application) : AndroidViewModel(application) {
+
+ protected val loginDesc = application.getString(R.string.login_btn)
+
+ abstract val id: ValidStringForm
+ abstract val password: ValidStringForm
+
+
+ //注册按钮
+ protected val _isValidForm = MutableLiveData()
+
+ val isValidForm: LiveData = _isValidForm
+
+ /**
+ * 完成登录状态
+ */
+ private val _finishLogin = MutableLiveData()
+ val finishLogin: LiveData = _finishLogin
+
+ abstract fun checkForm(): Boolean
+
+ abstract fun loginParam(): Any
+
+ abstract val api: AccountApi
+
+ /**
+ * 登录
+ *
+ */
+ fun login(callback: (message: String) -> Unit) {
+ viewModelScope.launch {
+ if (checkForm()) {
+ val url = Api.buildUrl(api)
+ Logger.i("开始$loginDesc,请求接口:$url")
+ val id = "${id.formValue.value}"
+ val password = "${password.formValue.value}"
+ Logger.i("使用账号:$id,密码:$password 进行登录")
+ HttpClient.post(
+ url,
+ HttpCallback(
+ action = loginDesc,
+ onSuccess = {
+ Logger.i(it.message)
+ callback(it.message)
+ val context = getApplication().applicationContext
+ it.body?.let {
+ val db = AppDatabase.getInstance(context)
+ viewModelScope.launch {
+ TokenManager.token = it
+ db?.tokenDao()?.save(token = it)
+ }.invokeOnCompletion {
+ _finishLogin.postValue(true)
+ }
+ }
+ },
+ onFail = { callback(it) },
+ type = object : TypeToken>() {}.type
+ ),
+ jsonParam = loginParam()
+ )
+ } else {
+ Logger.wtf("表单校验失败,无法$loginDesc!!!")
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/src/main/java/com/gyf/ApplyViewModel.kt b/lib/src/main/java/com/gyf/lib/model/ApplyViewModel.kt
similarity index 78%
rename from lib/src/main/java/com/gyf/ApplyViewModel.kt
rename to lib/src/main/java/com/gyf/lib/model/ApplyViewModel.kt
index b8a8b8d..68c138b 100644
--- a/lib/src/main/java/com/gyf/ApplyViewModel.kt
+++ b/lib/src/main/java/com/gyf/lib/model/ApplyViewModel.kt
@@ -1,11 +1,10 @@
-package com.gyf
+package com.gyf.lib.model
import android.app.Application
import com.gyf.lib.R
-import com.gyf.lib.ScrollListW
import com.gyf.lib.uikit.StringForm
-abstract class ApplyViewModel(application: Application) : ScrollListW(application) {
+abstract class ApplyViewModel(application: Application) : ScrollViewModel(application) {
val approverOrigin =
StringForm(formDesc = application.getString(R.string.approver_origin), textLength = 30)
}
\ No newline at end of file
diff --git a/foreground/src/main/java/com/gyf/csams/InitViewModel.kt b/lib/src/main/java/com/gyf/lib/model/InitViewModel.kt
similarity index 90%
rename from foreground/src/main/java/com/gyf/csams/InitViewModel.kt
rename to lib/src/main/java/com/gyf/lib/model/InitViewModel.kt
index 7dd5dd7..5c2d119 100644
--- a/foreground/src/main/java/com/gyf/csams/InitViewModel.kt
+++ b/lib/src/main/java/com/gyf/lib/model/InitViewModel.kt
@@ -1,4 +1,4 @@
-package com.gyf.csams
+package com.gyf.lib.model
import android.app.Application
import androidx.lifecycle.AndroidViewModel
@@ -6,12 +6,10 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.google.gson.reflect.TypeToken
-import com.gyf.csams.util.SimpleCallback
import com.gyf.lib.util.*
import com.orhanobut.logger.Logger
import kotlinx.coroutines.launch
-
class InitViewModel(application: Application) : AndroidViewModel(application) {
/**
* 服务器网络状态是否正常,true=正常,false=不正常
@@ -29,7 +27,7 @@ class InitViewModel(application: Application) : AndroidViewModel(application) {
viewModelScope.launch {
HttpClient.get(
Api.buildUrl(TestApi.Test),
- SimpleCallback(action = "测试", onSuccess = {
+ HttpCallback(action = "测试", onSuccess = {
_isNetWorkWorking.postValue(true)
}, onFail = {
Logger.e(it)
@@ -40,23 +38,22 @@ class InitViewModel(application: Application) : AndroidViewModel(application) {
}
-
/**
* 查询本地是否有且只有一个用户token,如果有则自动登录
*/
- fun hasOnlyUserToken(onSuccess: () -> Unit, onFail: () -> Unit) {
+ fun hasOnlyUserToken(onSuccess: () -> Unit, onFail: () -> Unit, api: AccountApi) {
viewModelScope.launch {
- val context = getApplication()
+ val context = getApplication()
val db = AppDatabase.getInstance(context)
val tokenList = db?.tokenDao()?.queryAll()
if (tokenList != null && tokenList.size == 1) {
val currentToken: Token = tokenList[0]
- val url = Api.buildUrl(AccountApi.LoginToken)
+ val url = Api.buildUrl(api)
val action = "校验token"
Logger.i("${action}api=$url")
HttpClient.post(
url,
- SimpleCallback(
+ HttpCallback(
action = action,
onSuccess = { it ->
it.body?.let {
diff --git a/lib/src/main/java/com/gyf/lib/model/ScrollViewModel.kt b/lib/src/main/java/com/gyf/lib/model/ScrollViewModel.kt
new file mode 100644
index 0000000..c99f054
--- /dev/null
+++ b/lib/src/main/java/com/gyf/lib/model/ScrollViewModel.kt
@@ -0,0 +1,19 @@
+package com.gyf.lib.model
+
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+
+abstract class ScrollViewModel(application: Application) : AndroidViewModel(application) {
+ protected val _data = MutableLiveData>(mutableListOf())
+ val data: LiveData> = _data
+
+ abstract val initSize: Int
+
+ //加载列表
+ abstract fun load()
+
+ //加载更多数据
+ abstract fun loadMore(callback: (message: String) -> Unit)
+}
\ No newline at end of file
diff --git a/lib/src/main/java/com/gyf/lib/MessageService.kt b/lib/src/main/java/com/gyf/lib/service/MessageService.kt
similarity index 83%
rename from lib/src/main/java/com/gyf/lib/MessageService.kt
rename to lib/src/main/java/com/gyf/lib/service/MessageService.kt
index 1c383f8..63ff9d5 100644
--- a/lib/src/main/java/com/gyf/lib/MessageService.kt
+++ b/lib/src/main/java/com/gyf/lib/service/MessageService.kt
@@ -1,4 +1,4 @@
-package com.gyf.lib
+package com.gyf.lib.service
import android.content.Intent
import androidx.core.app.JobIntentService
@@ -6,14 +6,8 @@ import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
-import com.gyf.NOTIFICATION_API
-import com.gyf.NotificationDto
-import com.gyf.NotificationVo
-import com.gyf.ReceiverType
-import com.gyf.lib.util.ApiResponse
-import com.gyf.lib.util.HttpClient
-import com.gyf.lib.util.NotificationUtil
-import com.gyf.lib.util.TokenManager
+import com.gyf.lib.R
+import com.gyf.lib.util.*
import com.orhanobut.logger.Logger
class MessageService : JobIntentService() {
@@ -32,7 +26,8 @@ class MessageService : JobIntentService() {
override fun onHandleWork(intent: Intent) {
TokenManager.token?.let { it ->
- HttpClient.postAsync>(url = NOTIFICATION_API,
+ HttpClient.postAsync>(
+ url = Api.buildUrl(NotificationApi.Pull),
jsonParam = NotificationDto(
receiverId = it.id,
receiverClient = ReceiverType.Foreground.name,
diff --git a/lib/src/main/java/com/gyf/NotificationWorker.kt b/lib/src/main/java/com/gyf/lib/service/NotificationWorker.kt
similarity index 93%
rename from lib/src/main/java/com/gyf/NotificationWorker.kt
rename to lib/src/main/java/com/gyf/lib/service/NotificationWorker.kt
index 87079d5..be3a235 100644
--- a/lib/src/main/java/com/gyf/NotificationWorker.kt
+++ b/lib/src/main/java/com/gyf/lib/service/NotificationWorker.kt
@@ -1,4 +1,4 @@
-package com.gyf
+package com.gyf.lib.service
import android.content.Context
import androidx.work.Data
@@ -6,14 +6,10 @@ import androidx.work.Worker
import androidx.work.WorkerParameters
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
-import com.gyf.lib.BuildConfig
import com.gyf.lib.util.*
-
import com.orhanobut.logger.Logger
import java.net.SocketTimeoutException
-const val NOTIFICATION_API = "${BuildConfig.SERVER_ADDRESS}/api/notification/pull"
-
data class NotificationVo(val title: String, val content: String, val id: Int)
data class PageDto(val currentPage: Long, val pageSize: Int = 10)
@@ -44,7 +40,8 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) :
TokenManager.token?.let {
return try {
Logger.i("开始拉取通知")
- val data = HttpClient.postAsync(url = NOTIFICATION_API,
+ val data = HttpClient.postAsync(
+ url = Api.buildUrl(NotificationApi.Pull),
jsonParam = NotificationDto(
receiverId = it.id,
receiverClient = inputData.getString("receiverClient")
diff --git a/lib/src/main/java/com/gyf/lib/uikit/AbstractInitActivity.kt b/lib/src/main/java/com/gyf/lib/uikit/AbstractInitActivity.kt
new file mode 100644
index 0000000..9e67730
--- /dev/null
+++ b/lib/src/main/java/com/gyf/lib/uikit/AbstractInitActivity.kt
@@ -0,0 +1,66 @@
+package com.gyf.lib.uikit
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.ui.Alignment
+import androidx.lifecycle.viewmodel.compose.viewModel
+import com.gyf.lib.BuildConfig
+import com.gyf.lib.model.InitViewModel
+import com.gyf.lib.util.AccountApi
+import com.orhanobut.logger.Logger
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+
+abstract class AbstractInitActivity : ComponentActivity() {
+
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+
+ setContent {
+ Body {
+ MainBoxFrame(background = { /*TODO*/ }, contentAlignment = Alignment.Center) {
+ val initViewModel: InitViewModel = viewModel()
+ //检查网络
+ val isNetWorkWorking: Boolean? by initViewModel.isNetWorkWorking.observeAsState(
+ null
+ )
+ Logger.i("初始化")
+ when (isNetWorkWorking) {
+ null -> AnimationText(text = "测试服务端运行状态中。。。")
+ true -> init(initViewModel = initViewModel)
+ false -> AnimationText(text = "无法连接到服务端,请检查服务端地址${BuildConfig.SERVER_ADDRESS}是否配置正确")
+ }
+ }
+ }
+ }
+ }
+
+ protected abstract val main: Class
+
+ protected abstract val login: Class
+
+ abstract val api: AccountApi
+
+ private fun init(initViewModel: InitViewModel) {
+ //后台检查token
+ initViewModel.hasOnlyUserToken(onSuccess = {
+ startActivity(Intent(this, main))
+ }, onFail = {
+ startActivity(Intent(this, login))
+ }, api = api)
+ GlobalScope.launch {
+ delay(1000)
+ finish()
+ }
+ }
+
+}
+
diff --git a/lib/src/main/java/com/gyf/lib/uikit/AnimationText.kt b/lib/src/main/java/com/gyf/lib/uikit/AnimationText.kt
new file mode 100644
index 0000000..42236b4
--- /dev/null
+++ b/lib/src/main/java/com/gyf/lib/uikit/AnimationText.kt
@@ -0,0 +1,33 @@
+package com.gyf.lib.uikit
+
+import androidx.compose.animation.animateColor
+import androidx.compose.animation.core.*
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+
+
+/**
+ * 淡入淡出并且颜色变化文本
+ *
+ * @param text
+ */
+@Composable
+fun AnimationText(text: String) {
+ val infiniteTransition = rememberInfiniteTransition()
+ val color by infiniteTransition.animateColor(
+ initialValue = MaterialTheme.colors.primary,
+ targetValue = MaterialTheme.colors.onPrimary,
+ animationSpec = infiniteRepeatable(
+ animation = tween(1000, easing = LinearEasing),
+ repeatMode = RepeatMode.Reverse
+ )
+ )
+
+ Text(
+ text = text,
+ color = color,
+ style = MaterialTheme.typography.body1
+ )
+}
\ No newline at end of file
diff --git a/foreground/src/main/java/com/gyf/csams/Api.kt b/lib/src/main/java/com/gyf/lib/util/Api.kt
similarity index 74%
rename from foreground/src/main/java/com/gyf/csams/Api.kt
rename to lib/src/main/java/com/gyf/lib/util/Api.kt
index 1321671..be2e881 100644
--- a/foreground/src/main/java/com/gyf/csams/Api.kt
+++ b/lib/src/main/java/com/gyf/lib/util/Api.kt
@@ -1,4 +1,8 @@
-package com.gyf.csams
+package com.gyf.lib.util
+
+import com.gyf.lib.BuildConfig
+import com.gyf.lib.service.ReceiverType
+import java.util.*
interface UrlPath {
@@ -23,11 +27,18 @@ enum class AccountApi(val path: String) : UrlPath {
//学号检测
CheckId("/register/checkId"),
- //登录
- Login("/login"),
+ //前台登录
+ ForegroundLogin("/login/${ReceiverType.Foreground.name.toLowerCase(Locale.ROOT)}"),
+
+ //后台登陆
+ BackgroundLogin("/login/${ReceiverType.Background.name.toLowerCase(Locale.ROOT)}"),
+
+
+ //前台令牌校验
+ ForegroundToken("${ForegroundLogin.path}/token"),
- //令牌校验
- LoginToken("/login/token"),
+ //后台令牌校验
+ BackgroundToken("${BackgroundLogin.path}/token"),
//登出
Logout("/logout");
@@ -73,7 +84,8 @@ enum class AssociationApi(val path: String) : UrlPath {
enum class NotificationApi(val path: String) : UrlPath {
Count("/count"),
- List("/list");
+ List("/list"),
+ Pull("/pull");
override fun build(): String {
return "/api/notification${this.path}"
diff --git a/lib/src/main/java/com/gyf/lib/util/ContextUtil.kt b/lib/src/main/java/com/gyf/lib/util/ContextUtil.kt
index 9ef2d2a..7e78ec5 100644
--- a/lib/src/main/java/com/gyf/lib/util/ContextUtil.kt
+++ b/lib/src/main/java/com/gyf/lib/util/ContextUtil.kt
@@ -6,8 +6,8 @@ import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.lifecycle.LiveData
import androidx.work.*
-import com.gyf.NotificationWorker
-import com.gyf.ReceiverType
+import com.gyf.lib.service.NotificationWorker
+import com.gyf.lib.service.ReceiverType
import com.orhanobut.logger.Logger
import java.util.*
diff --git a/lib/src/main/res/values-en/strings.xml b/lib/src/main/res/values-en/strings.xml
index c0e336f..45a448e 100644
--- a/lib/src/main/res/values-en/strings.xml
+++ b/lib/src/main/res/values-en/strings.xml
@@ -21,4 +21,5 @@
审核理由
抱歉此功能尚未开放
活动质量汇报单
+ 登录
\ No newline at end of file
diff --git a/lib/src/main/res/values-zh/strings.xml b/lib/src/main/res/values-zh/strings.xml
index c0e336f..45a448e 100644
--- a/lib/src/main/res/values-zh/strings.xml
+++ b/lib/src/main/res/values-zh/strings.xml
@@ -21,4 +21,5 @@
审核理由
抱歉此功能尚未开放
活动质量汇报单
+ 登录
\ No newline at end of file
diff --git a/lib/src/main/res/values/strings.xml b/lib/src/main/res/values/strings.xml
index c0e336f..45a448e 100644
--- a/lib/src/main/res/values/strings.xml
+++ b/lib/src/main/res/values/strings.xml
@@ -21,4 +21,5 @@
审核理由
抱歉此功能尚未开放
活动质量汇报单
+ 登录
\ No newline at end of file