master
pan 4 years ago
parent 52c6088fd8
commit 18b9ef396f
  1. 6
      foreground/src/main/java/com/gyf/csams/Api.kt
  2. 31
      foreground/src/main/java/com/gyf/csams/InitActivity.kt
  3. 29
      foreground/src/main/java/com/gyf/csams/InitViewModel.kt
  4. 14
      foreground/src/main/java/com/gyf/csams/account/model/AccountViewModel.kt
  5. 35
      foreground/src/main/java/com/gyf/csams/account/ui/AccountActivity.kt
  6. 43
      foreground/src/main/java/com/gyf/csams/activity/model/ApplyActViewModel.kt
  7. 8
      lib/src/main/java/com/gyf/lib/uikit/BaseTextField.kt
  8. 14
      lib/src/main/java/com/gyf/lib/uikit/MainFrame.kt
  9. 5
      lib/src/main/java/com/gyf/lib/uikit/Snackbar.kt
  10. 5
      lib/src/main/java/com/gyf/lib/util/HttpUtil.kt

@ -5,6 +5,12 @@ interface UrlPath {
fun build(): String
}
enum class TestApi(val path: String) : UrlPath {
Test("test");
override fun build(): String = "/api/${this.path}"
}
/**
* 帐号接口
*

@ -7,11 +7,14 @@ import androidx.activity.compose.setContent
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.viewmodel.compose.viewModel
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
class InitActivity : ComponentActivity() {
@ -22,19 +25,25 @@ class InitActivity : ComponentActivity() {
// 检查网络
setContent {
val initViewModel: InitViewModel = viewModel()
initViewModel.checkServer()
val isNetWorkWorking: Boolean? by initViewModel.isNetWorkWorking.observeAsState(null)
when (isNetWorkWorking) {
null -> AnimationText(text = "检查服务器网络状态中!!!")
true -> {
Init()
finish()
}
false -> {
TODO("无法连接到服务器,请检查本地网络或联系管理员")
Body {
MainBoxFrame(background = { /*TODO*/ }, contentAlignment = Alignment.Center) {
val initViewModel: InitViewModel = viewModel()
val isNetWorkWorking: Boolean? by initViewModel.isNetWorkWorking.observeAsState(
null
)
when (isNetWorkWorking) {
null -> AnimationText(text = "测试服务端运行状态中。。。")
true -> {
Init()
finish()
}
false -> {
AnimationText(text = "无法连接到服务端,请检查服务端地址${BuildConfig.SERVER_ADDRESS}是否配置正确")
}
}
}
}
}
}

@ -13,6 +13,7 @@ import com.gyf.csams.util.Token
import com.gyf.lib.util.ApiResponse
import com.gyf.lib.util.HttpClient
import com.orhanobut.logger.Logger
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
data class TokenVo(val token: String, val studentId: String)
@ -30,10 +31,25 @@ class InitViewModel : ViewModel() {
private val _token = MutableLiveData<Boolean>()
val token: LiveData<Boolean> = _token
init {
checkServer()
}
fun checkServer() {
private fun checkServer() {
Logger.i("测试连接到服务端")
_isNetWorkWorking.postValue(true)
viewModelScope.launch {
delay(5000)
HttpClient.get(
Api.buildUrl(TestApi.Test),
SimpleCallback<Boolean>(action = "测试", onSuccess = {
_isNetWorkWorking.postValue(true)
}, onFail = {
Logger.e(it)
_isNetWorkWorking.postValue(false)
}, type = object : TypeToken<ApiResponse<Boolean>>() {}.type)
)
}
}
/**
@ -52,9 +68,12 @@ class InitViewModel : ViewModel() {
url,
SimpleCallback<Boolean>(
action = action,
onSuccess = {
_token.postValue(it.body)
Logger.i("token校验结果:${it.body}")
onSuccess = { it ->
it.body?.let {
_token.postValue(it)
Logger.i("token校验结果:${it}")
}
},
onFail = { TODO("token校验失败") },
type = object : TypeToken<ApiResponse<Boolean>>() {}.type

@ -65,13 +65,17 @@ typealias Token = TokenResDto
* 注册表单
*/
class AccountViewModel(application: Application) : AndroidViewModel(application) {
val welcomeEnd = application.getString(R.string.welcome_end)
val welcomeStart = application.getString(R.string.welcome_start)
//学号
val studentId = object : ValidStringForm(formDesc = "学号", textLength = 8) {
override fun check() {
_formValue.value?.let {
when {
!it.matches(Regex("\\d{8}")) -> _statusForm.value = FormStatus.FormatError
it.matches(Regex("\\d{8}")) -> checkRepeat(_statusForm)
route == AccountRoute.Login -> _statusForm.value = FormStatus.Valid
route == AccountRoute.Register -> checkRepeat(_statusForm)
}
}
}
@ -252,6 +256,10 @@ class AccountViewModel(application: Application) : AndroidViewModel(application)
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<Token>(
@ -275,8 +283,8 @@ class AccountViewModel(application: Application) : AndroidViewModel(application)
),
jsonBody = Gson().toJson(
UserLoginVo(
studentId = "${studentId.formValue.value}",
password = "${password.formValue.value}",
studentId = studentId,
password = password,
device = "${Build.MANUFACTURER} ${Build.MODEL}"
)
)

@ -27,10 +27,7 @@ import com.gyf.csams.BuildConfig
import com.gyf.csams.R
import com.gyf.csams.account.model.AccountViewModel
import com.gyf.csams.account.model.DialogMessage
import com.gyf.lib.uikit.BaseTextField
import com.gyf.lib.uikit.Body
import com.gyf.lib.uikit.FormStatus
import com.gyf.lib.uikit.ScaffoldModel
import com.gyf.lib.uikit.*
enum class AccountRoute {
@ -43,12 +40,13 @@ class AccountActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
setContent {
Body { nav ->
TestBody { nav, scaffoldState ->
NavHost(navController = nav, startDestination = AccountRoute.Login.name) {
composable(AccountRoute.Login.name) {
Account(
route = AccountRoute.Login
) { isValidForm: Boolean, accountViewModel: AccountViewModel, scaffoldModel: ScaffoldModel ->
Spacer(modifier = Modifier.height(10.dp))
OutlinedButton(
onClick = {
@ -70,15 +68,16 @@ class AccountActivity : ComponentActivity() {
finish()
}
OutlinedButton(
onClick = { nav.navigate(AccountRoute.Register.name) },
modifier = Modifier.fillMaxWidth(),
colors = ButtonDefaults.outlinedButtonColors(
contentColor = MaterialTheme.colors.onBackground
)
) {
Text(text = accountViewModel.goRegister)
}
OutlinedButton(
onClick = { nav.navigate(AccountRoute.Register.name) },
modifier = Modifier.fillMaxWidth(),
colors = ButtonDefaults.outlinedButtonColors(
contentColor = MaterialTheme.colors.onBackground
)
) {
Text(text = accountViewModel.goRegister)
}
ShowSnackbar(scaffoldState = scaffoldState)
}
}
@ -147,10 +146,10 @@ class AccountActivity : ComponentActivity() {
append(accountViewModel.name.formValue.value ?: "")
}
withStyle(style = MaterialTheme.typography.subtitle1.toSpanStyle()) {
append(stringResource(id = R.string.welcome_start))
append(accountViewModel.welcomeStart)
}
withStyle(style = MaterialTheme.typography.subtitle2.toSpanStyle()) {
append(stringResource(id = R.string.welcome_end))
append(accountViewModel.welcomeEnd)
}
withStyle(
style = MaterialTheme.typography.subtitle2.toSpanStyle()
@ -160,7 +159,7 @@ class AccountActivity : ComponentActivity() {
}
})
StudentId(checkRepeat = route == AccountRoute.Register)
StudentId()
Spacer(modifier = Modifier.height(10.dp))
@ -184,7 +183,7 @@ class AccountActivity : ComponentActivity() {
* @param accountViewModel
*/
@Composable
private fun StudentId(accountViewModel: AccountViewModel = viewModel(), checkRepeat: Boolean) {
private fun StudentId(accountViewModel: AccountViewModel = viewModel()) {
Column {

@ -30,6 +30,30 @@ import kotlinx.coroutines.launch
import java.util.*
class SizeForm(val application: Application) :
StringForm(formDesc = application.getString(R.string.activity_size), textLength = 2) {
val _formError = MutableLiveData<String>()
val formError: LiveData<String> = _formError
val maxActivitySize = application.resources.getInteger(R.integer.activity_size)
val rangeError = application.getString(R.string.activity_size_error, 1, maxActivitySize)
override fun onChange(value: String) {
if (value.length > textLength) {
_formError.value = "${formDesc}不能超过最大长度$textLength"
_formValue.value = value.slice(IntRange(0, textLength - 1))
} else if (value.matches(Regex("\\d+")) && value.toInt() !in 1..maxActivitySize) {
Logger.i("活动人数:${value}不合法")
_formError.value = rangeError
} else {
_formValue.value = value
_formError.value = ""
}
}
}
/**
* 申请活动数据状态管理
*
@ -49,24 +73,9 @@ class ApplyActViewModel(application: Application) : AndroidViewModel(application
StringForm(formDesc = application.getString(R.string.activity_address), textLength = 30)
val activityDesc =
StringForm(formDesc = application.getString(R.string.activity_desc), textLength = 50)
val maxActivitySize = application.resources.getInteger(R.integer.activity_size)
val activitySize = object :
StringForm(formDesc = application.getString(R.string.activity_size), textLength = 2) {
override fun onChange(value: String) {
if (value.length > textLength) {
// formError.value = "${formDesc}不能超过最大长度$textLength"
_formValue.value = value.slice(IntRange(0, textLength - 1))
} else if (value.matches(Regex("\\d+")) && value.toInt() !in 1..maxActivitySize) {
Logger.i("活动人数:${value}不合法")
// formError.value =
// application.getString(R.string.activity_size_error, 1, maxActivitySize)
} else {
_formValue.value = value
// formError.value = ""
}
}
}
val activitySize = SizeForm(application = application)
val city =
object : StringForm(formDesc = application.getString(R.string.city), textLength = 4) {
override val formPlaceholder = ""

@ -32,9 +32,6 @@ enum class FormStatus {
Valid
}
interface FormLength {
val textLength: Int
}
abstract class FormName<T>(val formDesc: String) {
protected val _formValue = MutableLiveData<T>()
@ -52,9 +49,8 @@ abstract class FormName<T>(val formDesc: String) {
*
* @param formDesc
*/
open class StringForm(formDesc: String, override val textLength: Int) :
FormName<String>(formDesc = formDesc),
FormLength {
open class StringForm(formDesc: String, val textLength: Int) :
FormName<String>(formDesc = formDesc) {
constructor(formDesc: String, textLength: Int, value: String) : this(
formDesc = formDesc,

@ -178,3 +178,17 @@ fun Body(content: @Composable (nav: NavHostController) -> Unit) {
}
}
}
@Composable
fun TestBody(content: @Composable (nav: NavHostController, scaffoldState: ScaffoldState) -> Unit) {
CSAMSTheme {
Surface(color = MaterialTheme.colors.background) {
val navController = rememberNavController()
val scaffoldState = rememberScaffoldState()
Scaffold(scaffoldState = scaffoldState) {
content(nav = navController, scaffoldState = scaffoldState)
}
}
}
}

@ -32,10 +32,11 @@ class ScaffoldModel : ViewModel() {
fun update(message: String? = null, actionLabel: String? = null, callback: () -> Unit? = {}) {
if (message == null) {
_data.value = null
_data.postValue(null)
} else {
_data.value =
_data.postValue(
SnackBar(message = message, actionLabel = actionLabel, callback = callback)
)
}
}
}

@ -140,9 +140,10 @@ abstract class HttpCallback<T>(
val body = response.body
if (body != null && body.contentType()?.subtype == "json") {
val jsonRes = body.string()
val res: ApiResponse<T> = gson.fromJson(jsonRes, type)
Logger.i("${action}请求响应成功:")
Logger.json(jsonRes)
val res: ApiResponse<T> = gson.fromJson(jsonRes, type)
Logger.i("json解析成功:$res")
onSuccess(res)
} else {
onFail("${action}失败,请联系管理员")

Loading…
Cancel
Save