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

3 years ago
package com.gyf.csams.account.model
import android.app.Application
import android.content.Intent
import android.os.Build
import androidx.lifecycle.AndroidViewModel
3 years ago
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
3 years ago
import androidx.lifecycle.viewModelScope
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.gyf.csams.AccountApi
3 years ago
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.*
3 years ago
import com.orhanobut.logger.Logger
3 years ago
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
/**
* 响应自动生成密码
*
* @property password
*/
3 years ago
@Serializable
data class UserResDto(val password: String)
3 years ago
/**
* 构造登录注册信息实体表单
*
* @property studentId 学号
* @property name 姓名
*/
data class UserVo(val studentId: String, val name: String)
3 years ago
/**
* 用户登陆表单
*
* @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?)
3 years ago
typealias Token = TokenResDto
3 years ago
/**
* 注册表单
*/
class AccountViewModel(application: Application) : AndroidViewModel(application) {
3 years ago
//欢迎信息
val welcomeStart = "同学您好\n"
val welcomeEnd = "欢迎使用"
3 years ago
3 years ago
//学号
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 = "入学年份(四位)+班级代码(两位)+学生代码(两位)"
3 years ago
//学号已存在
private val _isRepeat = MutableLiveData<Boolean?>()
val isRepeat: LiveData<Boolean?> = _isRepeat
val regBtnDesc = "注册"
3 years ago
//已注册
val registered = "$regBtnDesc"
3 years ago
//可注册
val canRegister = "$regBtnDesc"
3 years ago
//提示信息
val checkRegTip = "检测学号是否已${regBtnDesc}。。。"
3 years ago
private var checkJob: Job? = null
3 years ago
//姓名
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 = "八位纯数字"
3 years ago
//注册按钮
private val _isValidForm = MutableLiveData<Boolean>()
val isValidForm: LiveData<Boolean> = _isValidForm
3 years ago
//注册请求响应信息
private val _snackBarMsg = MutableLiveData<String>()
val snackBarMsg: LiveData<String> = _snackBarMsg
3 years ago
private val _dialogMsg = MutableLiveData<DialogMessage>()
val dialogMsg: LiveData<DialogMessage> = _dialogMsg
3 years ago
val loginDesc = "登陆"
3 years ago
//返回登陆
val backLogin = "返回$loginDesc"
3 years ago
//确定按钮
val confirmDesc = "确定"
3 years ago
//显示密码提示
val title = "提示信息"
val passwordTip = "密码会在点击${regBtnDesc}以后,在后台自动生成,请留意系统提示。"
val passwordDialogStart = "${regBtnDesc}成功,后台为您自动生成的密码是"
val passwordDialogEnd = "\n密码有且只有这里显示一次,请在记住密码后点击确定或${backLogin}"
3 years ago
//转到注册
var goRegister = "转到$regBtnDesc"
/**
* 完成登录状态
*/
private val _finishLogin = MutableLiveData<Boolean>()
val finishLogin: LiveData<Boolean> = _finishLogin
lateinit var route: AccountRoute
3 years ago
/**
* 检查学号格式
*
*/
private fun checkStudentId(): Boolean {
_isValidStudentId.value = studentId.formValue.value?.matches(Regex("\\d{8}"))
return _isValidStudentId.value == true
3 years ago
}
3 years ago
/**
* 检查学号是否已注册
*
*/
private suspend fun checkRepeat() {
3 years ago
if (checkStudentId()) {
if (checkJob?.isActive == true) {
checkJob?.join()
} else {
3 years ago
_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}")
)
3 years ago
}
}
} else {
3 years ago
_isValidForm.postValue(false)
}
}
/**
* 检测姓名
*
* @return
*/
private fun checkName(): Boolean {
_isValidName.value = name.formValue.value?.isNotEmpty()
return _isValidName.value == true
3 years ago
}
/**
* 检测密码
*
* @return
*/
private fun checkPassword(): Boolean {
_isValidPwd.value = password.formValue.value?.matches(Regex("\\d{8}"))
return _isValidPwd.value == true
}
3 years ago
private fun checkForm(): Boolean {
if (checkJob?.isActive == true) {
3 years ago
_isValidForm.value = false
} else {
_isValidForm.value =
checkStudentId() && (if (route == AccountRoute.register) checkName() && isRepeat.value == false else checkPassword())
3 years ago
}
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}"
)
)
)
3 years ago
resetForm()
} else {
Logger.wtf("表单校验失败,无法$regBtnDesc!!!")
3 years ago
}
}
3 years ago
/**
*
*/
3 years ago
/**
* 重置信息
*
*/
fun resetRegisterResMsg() {
_snackBarMsg.value = ""
3 years ago
}
fun resetDialogMsg() {
_dialogMsg.value = null
3 years ago
}
private fun resetForm() {
studentId.onChange("")
name.onChange("")
3 years ago
}
/**
* 登录
*
*/
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!!!")
}
}
3 years ago
}