You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
329 lines
9.6 KiB
329 lines
9.6 KiB
package com.gyf.csams.account.model
|
|
|
|
import android.app.Application
|
|
import android.content.Intent
|
|
import android.os.Build
|
|
import androidx.lifecycle.AndroidViewModel
|
|
import androidx.lifecycle.LiveData
|
|
import androidx.lifecycle.MutableLiveData
|
|
import androidx.lifecycle.viewModelScope
|
|
import com.google.gson.Gson
|
|
import com.google.gson.reflect.TypeToken
|
|
import com.gyf.csams.AccountApi
|
|
import com.gyf.csams.Api
|
|
import com.gyf.csams.InitActivity
|
|
import com.gyf.csams.account.ui.AccountRoute
|
|
import com.gyf.csams.uikit.StringForm
|
|
import com.gyf.csams.util.*
|
|
import com.orhanobut.logger.Logger
|
|
import kotlinx.coroutines.Job
|
|
import kotlinx.coroutines.launch
|
|
import kotlinx.serialization.Serializable
|
|
|
|
/**
|
|
* 响应自动生成密码
|
|
*
|
|
* @property password
|
|
*/
|
|
@Serializable
|
|
data class UserResDto(val password: String)
|
|
|
|
/**
|
|
* 构造登录、注册信息实体表单
|
|
*
|
|
* @property studentId 学号
|
|
* @property name 姓名
|
|
*/
|
|
data class UserVo(val studentId: String, val name: String)
|
|
|
|
/**
|
|
* 用户登陆表单
|
|
*
|
|
* @property studentId 学号
|
|
* @property password 密码
|
|
* @property device 设备型号
|
|
*/
|
|
data class UserLoginVo(val studentId: String, val password: String, val device: String)
|
|
|
|
/**
|
|
* 密码弹窗信息
|
|
*
|
|
* @property message
|
|
* @property userResDto
|
|
*/
|
|
data class DialogMessage(val message: String, val userResDto: UserResDto?)
|
|
|
|
typealias Token = TokenResDto
|
|
|
|
/**
|
|
* 注册表单
|
|
*/
|
|
class AccountViewModel(application: Application) : AndroidViewModel(application) {
|
|
|
|
|
|
//欢迎信息
|
|
val welcomeStart = "同学您好\n"
|
|
val welcomeEnd = "欢迎使用"
|
|
|
|
//学号
|
|
val studentId = object : StringForm(formDesc = "学号", textLength = 8) {
|
|
override fun onChange(value: String) {
|
|
super.onChange(value)
|
|
viewModelScope.launch {
|
|
checkRepeat()
|
|
}
|
|
}
|
|
}
|
|
private val _isValidStudentId = MutableLiveData<Boolean>()
|
|
val isValidStudentId: LiveData<Boolean> = _isValidStudentId
|
|
|
|
val studentIdFormat = "入学年份(四位)+班级代码(两位)+学生代码(两位)"
|
|
|
|
//学号已存在
|
|
private val _isRepeat = MutableLiveData<Boolean?>()
|
|
val isRepeat: LiveData<Boolean?> = _isRepeat
|
|
|
|
val regBtnDesc = "注册"
|
|
|
|
//已注册
|
|
val registered = "已$regBtnDesc"
|
|
|
|
//可注册
|
|
val canRegister = "可$regBtnDesc"
|
|
|
|
//提示信息
|
|
val checkRegTip = "检测学号是否已${regBtnDesc}。。。"
|
|
|
|
private var checkJob: Job? = null
|
|
|
|
//姓名
|
|
val name = object : StringForm(formDesc = "姓名", textLength = 4) {
|
|
override fun onChange(value: String) {
|
|
super.onChange(value)
|
|
checkForm()
|
|
}
|
|
}
|
|
private val _isValidName = MutableLiveData<Boolean>()
|
|
val isValidName: LiveData<Boolean> = _isValidName
|
|
val nameFormat = "姓名不能为空"
|
|
|
|
//密码
|
|
val password = object : StringForm(formDesc = "密码", textLength = 8) {
|
|
override fun onChange(value: String) {
|
|
super.onChange(value)
|
|
checkForm()
|
|
}
|
|
}
|
|
private val _isValidPwd = MutableLiveData<Boolean>()
|
|
val isValidPwd: LiveData<Boolean> = _isValidPwd
|
|
val passwordFormat = "八位纯数字"
|
|
|
|
|
|
//注册按钮
|
|
private val _isValidForm = MutableLiveData<Boolean>()
|
|
|
|
val isValidForm: LiveData<Boolean> = _isValidForm
|
|
|
|
//注册请求响应信息
|
|
private val _snackBarMsg = MutableLiveData<String>()
|
|
val snackBarMsg: LiveData<String> = _snackBarMsg
|
|
|
|
private val _dialogMsg = MutableLiveData<DialogMessage>()
|
|
val dialogMsg: LiveData<DialogMessage> = _dialogMsg
|
|
|
|
val loginDesc = "登陆"
|
|
|
|
//返回登陆
|
|
val backLogin = "返回$loginDesc"
|
|
|
|
//确定按钮
|
|
val confirmDesc = "确定"
|
|
|
|
//显示密码提示
|
|
val title = "提示信息"
|
|
val passwordTip = "密码会在点击${regBtnDesc}以后,在后台自动生成,请留意系统提示。"
|
|
val passwordDialogStart = "${regBtnDesc}成功,后台为您自动生成的密码是"
|
|
val passwordDialogEnd = "\n密码有且只有这里显示一次,请在记住密码后点击确定或${backLogin}。"
|
|
|
|
//转到注册
|
|
var goRegister = "转到$regBtnDesc"
|
|
|
|
/**
|
|
* 完成登录状态
|
|
*/
|
|
private val _finishLogin = MutableLiveData<Boolean>()
|
|
val finishLogin: LiveData<Boolean> = _finishLogin
|
|
|
|
lateinit var route: AccountRoute
|
|
|
|
/**
|
|
* 检查学号格式
|
|
*
|
|
*/
|
|
private fun checkStudentId(): Boolean {
|
|
_isValidStudentId.value = studentId.formValue.value?.matches(Regex("\\d{8}"))
|
|
return _isValidStudentId.value == true
|
|
}
|
|
|
|
/**
|
|
* 检查学号是否已注册
|
|
*
|
|
*/
|
|
private suspend fun checkRepeat() {
|
|
if (checkStudentId()) {
|
|
if (checkJob?.isActive == true) {
|
|
checkJob?.join()
|
|
} else {
|
|
_isRepeat.postValue(null)
|
|
checkJob = viewModelScope.launch {
|
|
val url = Api.buildUrl(AccountApi.CheckId)
|
|
Logger.i("检测${studentId.formDesc},请求接口$url")
|
|
HttpClient.get(
|
|
url, SimpleCallback<Boolean>(
|
|
action = "${studentId.formDesc}重复检测",
|
|
onSuccess = {
|
|
_isRepeat.postValue(it.body)
|
|
_isValidForm.postValue(_isValidName.value == true && it.body == false)
|
|
},
|
|
onFail = { _snackBarMsg.postValue(it) },
|
|
type = object : TypeToken<ApiResponse<Boolean>>() {}.type
|
|
), mapOf("studentId" to "${studentId.formValue.value}")
|
|
)
|
|
}
|
|
}
|
|
} else {
|
|
_isValidForm.postValue(false)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 检测姓名
|
|
*
|
|
* @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
|
|
}
|
|
|
|
private fun checkForm(): Boolean {
|
|
if (checkJob?.isActive == true) {
|
|
_isValidForm.value = false
|
|
} else {
|
|
_isValidForm.value =
|
|
checkStudentId() && (if (route == AccountRoute.register) checkName() && isRepeat.value == false else checkPassword())
|
|
}
|
|
return _isValidForm.value == true
|
|
}
|
|
|
|
/**
|
|
* 注册
|
|
*
|
|
*/
|
|
fun register() {
|
|
if (checkForm()) {
|
|
val url = Api.buildUrl(AccountApi.Register)
|
|
Logger.i("开始$regBtnDesc,请求接口:$url")
|
|
HttpClient.post(
|
|
url, SimpleCallback<UserResDto>(
|
|
action = regBtnDesc,
|
|
onSuccess = {
|
|
_dialogMsg.postValue(
|
|
DialogMessage(
|
|
message = it.message,
|
|
userResDto = it.body
|
|
)
|
|
)
|
|
},
|
|
onFail = { _snackBarMsg.postValue(it) },
|
|
type = object : TypeToken<ApiResponse<UserResDto>>() {}.type
|
|
),
|
|
jsonBody = Gson().toJson(
|
|
UserVo(
|
|
studentId = "${studentId.formValue.value}",
|
|
name = "${name.formValue.value}"
|
|
)
|
|
)
|
|
)
|
|
resetForm()
|
|
} else {
|
|
Logger.wtf("表单校验失败,无法$regBtnDesc!!!")
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* 重置信息
|
|
*
|
|
*/
|
|
fun resetRegisterResMsg() {
|
|
_snackBarMsg.value = ""
|
|
}
|
|
|
|
fun resetDialogMsg() {
|
|
_dialogMsg.value = null
|
|
}
|
|
|
|
private fun resetForm() {
|
|
studentId.onChange("")
|
|
name.onChange("")
|
|
}
|
|
|
|
/**
|
|
* 登录
|
|
*
|
|
*/
|
|
fun login() {
|
|
if (checkForm()) {
|
|
val url = Api.buildUrl(AccountApi.Login)
|
|
Logger.i("开始$loginDesc,请求接口:$url")
|
|
HttpClient.post(
|
|
url,
|
|
SimpleCallback<Token>(
|
|
action = loginDesc,
|
|
onSuccess = {
|
|
_snackBarMsg.postValue(it.message)
|
|
|
|
val context = getApplication<Application>().applicationContext
|
|
val token = it.body?.token
|
|
if (token != null) {
|
|
val db = AppDatabase.getInstance(context)
|
|
viewModelScope.launch {
|
|
db?.tokenDao()?.save(token = token)
|
|
}.invokeOnCompletion {
|
|
context.startActivity(Intent(context, InitActivity::class.java))
|
|
_finishLogin.postValue(true)
|
|
}
|
|
}
|
|
},
|
|
onFail = { _snackBarMsg.postValue(it) },
|
|
type = object : TypeToken<ApiResponse<Token>>() {}.type
|
|
),
|
|
jsonBody = Gson().toJson(
|
|
UserLoginVo(
|
|
studentId = "${studentId.formValue.value}",
|
|
password = "${password.formValue.value}",
|
|
device = "${Build.MANUFACTURER} ${Build.MODEL}"
|
|
)
|
|
)
|
|
)
|
|
} else {
|
|
Logger.wtf("表单校验失败,无法$loginDesc!!!")
|
|
}
|
|
}
|
|
|
|
|
|
} |