答辩测试版

master
pan 4 years ago
parent 61113b6f5a
commit acb519df85
  1. 2
      background/src/main/AndroidManifest.xml
  2. 6
      background/src/main/java/com/gyf/csams/account/model/LoginViewModel.kt
  3. 49
      background/src/main/java/com/gyf/csams/main/model/AssociationManagementViewModel.kt
  4. 2
      background/src/main/java/com/gyf/csams/main/model/AuditActViewModel.kt
  5. 2
      background/src/main/java/com/gyf/csams/main/model/AuditAssociationViewModel.kt
  6. 25
      background/src/main/java/com/gyf/csams/main/model/AuditRenameViewModel.kt
  7. 3
      background/src/main/java/com/gyf/csams/main/model/BaseAuditViewModel.kt
  8. 4
      background/src/main/java/com/gyf/csams/main/model/CheckQualityReportViewModel.kt
  9. 50
      background/src/main/java/com/gyf/csams/main/model/ManagementOfficerModel.kt
  10. 19
      background/src/main/java/com/gyf/csams/main/model/ManagerActViewModel.kt
  11. 17
      background/src/main/java/com/gyf/csams/main/model/MenuViewModel.kt
  12. 46
      background/src/main/java/com/gyf/csams/main/model/RenameViewModel.kt
  13. 13
      background/src/main/java/com/gyf/csams/main/ui/AssociationManagementActivity.kt
  14. 87
      background/src/main/java/com/gyf/csams/main/ui/AuditRenameActivity.kt
  15. 45
      background/src/main/java/com/gyf/csams/main/ui/DepartmentActivity.kt
  16. 11
      background/src/main/java/com/gyf/csams/main/ui/MainActivity.kt
  17. 5
      background/src/main/java/com/gyf/csams/main/ui/ManagementOfficerActivity.kt
  18. 87
      background/src/main/java/com/gyf/csams/main/ui/RenameActivity.kt
  19. 9
      background/src/main/java/com/gyf/csams/uikit/CheckForm.kt
  20. 2
      foreground/src/main/AndroidManifest.xml
  21. 12
      foreground/src/main/java/com/gyf/csams/account/model/AccountViewModel.kt
  22. 2
      foreground/src/main/java/com/gyf/csams/account/ui/AccountActivity.kt
  23. 6
      foreground/src/main/java/com/gyf/csams/activity/model/ActivityDetailViewModel.kt
  24. 31
      foreground/src/main/java/com/gyf/csams/activity/model/ApplyActViewModel.kt
  25. 25
      foreground/src/main/java/com/gyf/csams/activity/ui/ApplyActActivity.kt
  26. 8
      foreground/src/main/java/com/gyf/csams/association/model/AssociationViewModel.kt
  27. 109
      foreground/src/main/java/com/gyf/csams/association/model/ExamViewModel.kt
  28. 8
      foreground/src/main/java/com/gyf/csams/association/model/RegAssociationViewModel.kt
  29. 87
      foreground/src/main/java/com/gyf/csams/association/model/RenameViewModel.kt
  30. 72
      foreground/src/main/java/com/gyf/csams/association/ui/AssociationActivity.kt
  31. 105
      foreground/src/main/java/com/gyf/csams/association/ui/ExamActivity.kt
  32. 99
      foreground/src/main/java/com/gyf/csams/association/ui/ReNameActivity.kt
  33. 195
      foreground/src/main/java/com/gyf/csams/association/ui/RenameActivity.kt
  34. 2
      foreground/src/main/java/com/gyf/csams/main/model/MainViewModel.kt
  35. 145
      foreground/src/main/java/com/gyf/csams/main/ui/MainActivity.kt
  36. 19
      foreground/src/main/java/com/gyf/csams/uikit/BaseView.kt
  37. 92
      foreground/src/main/java/com/gyf/csams/uikit/ViewModel.kt
  38. 8
      foreground/src/main/java/com/gyf/csams/util/GsonUtil.kt
  39. 2
      foreground/src/main/java/com/gyf/csams/util/HttpCallback.kt
  40. 2
      foreground/src/test/java/com/gyf/csams/ExampleUnitTest.kt
  41. 1
      lib/build.gradle.kts
  42. 15
      lib/src/main/java/com/gyf/lib/uikit/BaseTextField.kt
  43. 36
      lib/src/main/java/com/gyf/lib/util/Api.kt
  44. 1
      lib/src/test/java/com/gyf/lib/ExampleUnitTest.kt

@ -39,7 +39,7 @@
<!--菜单-->
<activity android:name=".main.ui.MenuActivity" />
<!--社团换名-->
<activity android:name=".main.ui.RenameActivity" />
<activity android:name=".main.ui.AuditRenameActivity" />
<!--活动管理-->
<activity android:name=".main.ui.ManagerActActivity" />
<!--审核社团注册-->

@ -23,11 +23,9 @@ class LoginViewModel(application: Application) : AbstractLoginViewModel(applicat
}
override fun loginParam(): Any {
val account = "${id.formValue.value}"
val password = "${password.formValue.value}"
return ManagerLoginVo(
account = account,
password = password,
account = id.getValue(),
password = password.getValue(),
device = "${Build.MANUFACTURER} ${Build.MODEL}"
)
}

@ -1,9 +1,13 @@
package com.gyf.csams.main.model
import android.app.Application
import com.gyf.csams.module.AssociationLevel
import com.gyf.csams.module.AssociationVo
import androidx.lifecycle.viewModelScope
import com.google.gson.reflect.TypeToken
import com.gyf.csams.module.*
import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.util.*
import com.orhanobut.logger.Logger
import kotlinx.coroutines.launch
/**
@ -13,25 +17,50 @@ import com.gyf.lib.model.ScrollViewModel
class AssociationManagementViewModel(application: Application) : ScrollViewModel<AssociationVo>(
application
) {
override val initSize: Int = 10
init {
load()
}
fun load() {
TODO("数据状态管理")
}
fun loadMore(callback: (message: String) -> Unit) {
TODO("Not yet implemented")
viewModelScope.launch {
HttpClient.post(
url = Api.buildUrl(AssociationApi.ListAll),
callback = HttpCallback<MutableList<AssociationVo>>(action = "加载社团",
onSuccess = { it ->
it.body?.let {
_data.postValue(it)
}
},
typeToken = object :
TypeToken<ApiResponse<MutableList<AssociationVo>>>() {}.type
),
jsonParam = OnlyToken(clientType = ClientType.Background)
)
}
}
/**
*
* @param level
*/
fun update(associationDto: AssociationVo, level: AssociationLevel) {
TODO("更新社团级别")
fun update(
associationVo: AssociationVo,
level: AssociationLevel,
callback: (m: String) -> Unit
) {
Logger.i("社团:${associationVo.name}")
HttpClient.post(url = Api.buildUrl(AssociationApi.Update),
callback = HttpCallback<Boolean>(action = "社团等级更新",
onSuccess = {
callback(it.message)
}, typeToken = object : TypeToken<ApiResponse<Boolean>>() {}.type
),
jsonParam = UpdateAssociationVo(
associationVo = associationVo.copy(level = level),
token = TokenManager.getToken(),
clientType = ClientType.Background
)
)
}
}

@ -21,7 +21,7 @@ class AuditActViewModel(application: Application) : BaseAuditViewModel<AuditActV
object : TypeToken<ApiResponse<MutableList<AuditActVo>>>() {}.type
init {
load { }
load()
}

@ -20,7 +20,7 @@ class AuditAssociationViewModel(application: Application) : BaseAuditViewModel<A
object : TypeToken<ApiResponse<MutableList<AuditAssociationVo>>>() {}.type
init {
load { }
load()
}

@ -0,0 +1,25 @@
package com.gyf.csams.main.model
import android.app.Application
import com.google.gson.reflect.TypeToken
import com.gyf.csams.module.ApiResponse
import com.gyf.csams.module.AuditRenameVo
import com.gyf.lib.util.AssociationApi
import com.gyf.lib.util.UrlPath
import java.lang.reflect.Type
class AuditRenameViewModel(application: Application) :
BaseAuditViewModel<AuditRenameVo>(application) {
override val auditApi: UrlPath = AssociationApi.RenameAudit
override val acceptApi: UrlPath = AssociationApi.RenameAccept
override val checkApi: UrlPath = AssociationApi.RenameCheck
override val typeToken: Type =
object : TypeToken<ApiResponse<MutableList<AuditRenameVo>>>() {}.type
init {
load()
}
}

@ -22,9 +22,8 @@ abstract class BaseAuditViewModel<T : AuditVo>(application: Application) :
/**
* 加载审核记录
*
* @param callback
*/
fun load(callback: (message: String) -> Unit) {
fun load() {
viewModelScope.launch {
HttpClient.post(
Api.buildUrl(auditApi), HttpCallback<MutableList<T>>(

@ -38,8 +38,4 @@ class CheckQualityReportViewModel(application: Application) : ApplyViewModel<Qua
}
}
}
fun loadMore(callback: (message: String) -> Unit) {
TODO("Not yet implemented")
}
}

@ -3,8 +3,15 @@ package com.gyf.csams.main.model
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.gson.reflect.TypeToken
import com.gyf.csams.module.AllOfficerVo
import com.gyf.csams.module.ManagerInfoVo
import com.gyf.csams.module.ApiResponse
import com.gyf.csams.module.ClientType
import com.gyf.csams.module.ManagerDutySumVo
import com.gyf.lib.util.*
import com.orhanobut.logger.Logger
import kotlinx.coroutines.launch
enum class ColumnType {
@ -21,20 +28,53 @@ class ManagementOfficerModel : ViewModel() {
private val _data = MutableLiveData<AllOfficerVo>()
val data: LiveData<AllOfficerVo> = _data
//部门概况
private val _simpleData = MutableLiveData<ManagerDutySumVo>()
val simpleData: LiveData<ManagerDutySumVo> = _simpleData
init {
load()
}
fun updateDuty(list: MutableList<ManagerInfoVo>, index: Int) {
TODO("更新职务")
//TODO 更新职务
fun updateDuty() {
Logger.i("更新职务")
}
/**
*
*加载部门概况
*/
private fun load() {
TODO("加载部门成员")
viewModelScope.launch {
HttpClient.post(url = Api.buildUrl(AccountApi.Load),
callback = HttpCallback<ManagerDutySumVo>(action = "加载部门概况", onSuccess =
{ it ->
it.body?.let {
_simpleData.postValue(it)
}
}, typeToken = object : TypeToken<ApiResponse<ManagerDutySumVo>>() {}.type
),
jsonParam = OnlyToken(clientType = ClientType.Background)
)
}
}
/**
* 加载部门详情
*
*/
fun loadDetail() {
viewModelScope.launch {
HttpClient.post(
url = Api.buildUrl(AccountApi.LoadDetail),
callback = HttpCallback<AllOfficerVo>(action = "加载部门详情", onSuccess = { it ->
it.body?.let {
_data.postValue(it)
}
}, typeToken = object : TypeToken<ApiResponse<AllOfficerVo>>() {}.type),
jsonParam = OnlyToken(clientType = ClientType.Background)
)
}
}
}

@ -1,8 +1,12 @@
package com.gyf.csams.main.model
import android.app.Application
import com.google.gson.reflect.TypeToken
import com.gyf.csams.module.ApiResponse
import com.gyf.csams.module.ClientType
import com.gyf.csams.module.ManagerActVo
import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.util.*
/**
@ -20,10 +24,17 @@ class ManagerActViewModel(application: Application) : ScrollViewModel<ManagerAct
}
fun load() {
TODO("活动信息管理")
HttpClient.post(url = Api.buildUrl(ActivityApi.ListAll),
callback = HttpCallback<MutableList<ManagerActVo>>(action = "查看活动信息",
onSuccess = { it ->
it.body.let {
_data.postValue(it)
}
}, typeToken = object : TypeToken<ApiResponse<MutableList<ManagerActVo>>>() {}.type
),
jsonParam = OnlyToken(clientType = ClientType.Background)
)
}
fun loadMore(callback: (message: String) -> Unit) {
TODO("Not yet implemented")
}
}

@ -1,29 +1,22 @@
package com.gyf.csams.main.model
import android.app.Activity
import androidx.lifecycle.ViewModel
import com.gyf.csams.main.ui.AuditActActivity
import com.gyf.csams.main.ui.AuditAssociationActivity
import com.gyf.csams.main.ui.RenameActivity
import com.gyf.csams.main.ui.*
enum class MenuType(val desc: String, val clazz: Map<String, Class<out Activity>>) {
Association(
"社团管理",
mapOf(
// TODO "社团信息管理" to AssociationManagementActivity::class.java,
"审核社团换名" to RenameActivity::class.java,
"社团信息管理" to AssociationManagementActivity::class.java,
"审核社团换名" to AuditRenameActivity::class.java,
"审核社团注册" to AuditAssociationActivity::class.java
),
),
Act(
"活动管理", mapOf(
"审核社团活动" to AuditActActivity::class.java,
// TODO "审核质量报告单" to CheckQualityReportActivity::class.java,
// "查看社团活动" to ManagerActActivity::class.java
"审核质量报告单" to CheckQualityReportActivity::class.java,
"查看社团活动" to ManagerActActivity::class.java
)
)
}
class MenuViewModel : ViewModel() {
}

@ -1,46 +0,0 @@
package com.gyf.csams.main.model
import android.app.Application
import androidx.lifecycle.viewModelScope
import com.gyf.csams.R
import com.gyf.csams.module.RenameVo
import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.uikit.StringForm
import com.gyf.lib.util.randomChinese
import com.gyf.lib.util.randomNum
import kotlinx.coroutines.launch
class RenameViewModel(application: Application) : ScrollViewModel<RenameVo>(application) {
val approverOrigin =
StringForm(
formDesc = application.getString(R.string.first_approver_origin),
textLength = 30
)
override val initSize: Int = 10
init {
load()
}
fun load() {
viewModelScope.launch {
_data.value?.apply {
repeat(initSize) {
add(
RenameVo(
studentId = randomNum(8),
oldName = randomChinese(5),
newName = randomChinese(5),
reason = randomChinese(10)
)
)
}
}
}
}
}

@ -20,6 +20,7 @@ import com.gyf.csams.main.model.AssociationManagementViewModel
import com.gyf.csams.module.AssociationLevel
import com.gyf.lib.uikit.Body
import com.gyf.lib.uikit.MainBoxFrame
import com.gyf.lib.uikit.ScaffoldModel
/**
* 社团管理
@ -85,15 +86,23 @@ class AssociationManagementActivity : ComponentActivity() {
text = level?.name ?: "暂无评级",
style = MaterialTheme.typography.h5
)
val scaffoldModel: ScaffoldModel = viewModel()
DropdownMenu(
expanded = expanded,
onDismissRequest = { /*TODO*/ }) {
AssociationLevel.values().forEach {
DropdownMenuItem(onClick = {
model.update(
associationDto = this@apply,
associationVo = this@apply,
level = it
)
) {
scaffoldModel.update(
message = it,
actionLabel = "刷新"
) {
model.load()
}
}
expanded = false
}) {
Text(text = it.name)

@ -0,0 +1,87 @@
package com.gyf.csams.main.ui
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ExperimentalComposeApi
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.google.accompanist.insets.ExperimentalAnimatedInsets
import com.gyf.csams.R
import com.gyf.csams.main.model.AuditRenameViewModel
import com.gyf.csams.module.AuditRenameVo
import com.gyf.csams.uikit.CheckForm
import com.gyf.csams.uikit.RowItem
import com.gyf.csams.uikit.TestTable
import com.gyf.csams.uikit.TestTableImeSimple
import com.gyf.lib.uikit.ImeBody
class AuditRenameActivity : ComponentActivity() {
@ExperimentalMaterialApi
@ExperimentalAnimatedInsets
@ExperimentalComposeApi
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
TestTable(clazz = AuditRenameViewModel::class.java, title = R.string.rename_form) {
RenameForm(vo = it)
}
ImeBody {
val model: AuditRenameViewModel = viewModel()
val data by model.data.observeAsState()
TestTableImeSimple(
title = R.string.rename_form
) {
data?.forEach {
item {
RenameForm(vo = it)
CheckForm<AuditRenameVo, AuditRenameViewModel>(vo = it)
Spacer(modifier = Modifier.height(10.dp))
}
}
}
}
}
}
@Composable
private fun RenameForm(
modifier: Modifier = Modifier,
vo: AuditRenameVo
) {
Column(modifier = modifier) {
val baseHeight = 50.dp
RowItem(
modifier = Modifier.height(baseHeight),
key = R.string.petitioner,
value = vo.audit.user.name
)
RowItem(
modifier = Modifier.height(baseHeight),
key = R.string.oldname,
value = vo.associationVo.name
)
RowItem(
modifier = Modifier.height(baseHeight),
key = R.string.newname,
value = vo.renameVo.newName
)
RowItem(
modifier = Modifier.height(baseHeight * 3),
key = R.string.reason_for_application,
value = vo.renameVo.cause
)
}
}
}

@ -10,11 +10,15 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.gyf.csams.R
import com.gyf.csams.main.model.ManagementOfficerModel
import com.gyf.csams.module.ManagerDutyVo
import com.gyf.lib.uikit.Body
import com.gyf.lib.uikit.MainColumnFrame
@ -29,6 +33,7 @@ class DepartmentActivity : ComponentActivity() {
setContent {
Body {
val model: ManagementOfficerModel = viewModel()
MainColumnFrame(background = { /*TODO*/ }) {
val weight = 0.1F
val departWeight = 0.2F
@ -92,19 +97,28 @@ class DepartmentActivity : ComponentActivity() {
}
val simpleData by model.simpleData.observeAsState()
simpleData?.let {
DepartmentItem(modifier = Modifier.weight(weight = departWeight),
id = R.string.secretariat,
onClick = { dialogContent = R.string.secretariat },
managerDutyVo = it.secretariat
)
Spacer(modifier = Modifier.weight(space))
DepartmentItem(modifier = Modifier.weight(weight = departWeight),
id = R.string.propaganda_department,
onClick = { dialogContent = R.string.propaganda_department },
managerDutyVo = it.propaganda
)
Spacer(modifier = Modifier.weight(space))
DepartmentItem(modifier = Modifier.weight(weight = departWeight),
id = R.string.public_relations_department,
onClick = { dialogContent = R.string.public_relations_department },
managerDutyVo = it.publicRelationsDepartment
)
Spacer(modifier = Modifier.weight(space))
}
DepartmentItem(modifier = Modifier.weight(weight = departWeight),
id = R.string.secretariat,
onClick = { dialogContent = R.string.secretariat })
Spacer(modifier = Modifier.weight(space))
DepartmentItem(modifier = Modifier.weight(weight = departWeight),
id = R.string.propaganda_department,
onClick = { dialogContent = R.string.propaganda_department })
Spacer(modifier = Modifier.weight(space))
DepartmentItem(modifier = Modifier.weight(weight = departWeight),
id = R.string.public_relations_department,
onClick = { dialogContent = R.string.public_relations_department })
Spacer(modifier = Modifier.weight(space))
}
}
}
@ -114,7 +128,8 @@ class DepartmentActivity : ComponentActivity() {
private fun DepartmentItem(
modifier: Modifier = Modifier,
@StringRes id: Int,
onClick: () -> Unit
onClick: () -> Unit,
managerDutyVo: ManagerDutyVo
) {
Row(
modifier = modifier
@ -141,13 +156,13 @@ class DepartmentActivity : ComponentActivity() {
.fillMaxHeight(),
verticalArrangement = Arrangement.SpaceBetween
) {
RowItem(text = "部门部长:")
RowItem(text = "部门部长:${managerDutyVo.manager.name}")
OutlinedButton(modifier = Modifier.fillMaxWidth(), onClick = {
startActivity(Intent(applicationContext, ManagementOfficerActivity::class.java))
}) {
Text(text = stringResource(id = R.string.management_officer))
}
RowItem(text = "部门总人数:")
RowItem(text = "部门总人数:${managerDutyVo.people}")
}
}
}

@ -59,12 +59,11 @@ class MainActivity : BaseActivity() {
Text(text = "我的通知")
}
// TODO 部门管理
// OutlinedButton(onClick = {
// startActivity(Intent(this@MainActivity, DepartmentActivity::class.java))
// }, modifier = Modifier.fillMaxWidth()) {
// Text(text = stringResource(id = R.string.department_management))
// }
OutlinedButton(onClick = {
startActivity(Intent(this@MainActivity, DepartmentActivity::class.java))
}, modifier = Modifier.fillMaxWidth()) {
Text(text = stringResource(id = R.string.department_management))
}
OutlinedButton(onClick = {
startActivity(
Intent(

@ -41,6 +41,7 @@ class ManagementOfficerActivity : ComponentActivity() {
MainColumnFrame(background = { /*TODO*/ }) {
val weight = 1 / 3F
val model: ManagementOfficerModel = viewModel()
model.loadDetail()
val data by model.data.observeAsState()
Logger.i("$data")
data?.apply {
@ -79,7 +80,7 @@ class ManagementOfficerActivity : ComponentActivity() {
model: ManagementOfficerModel = viewModel(),
scaffoldModel: ScaffoldModel = viewModel(),
@StringRes id: Int,
officerVoList: MutableList<ManagerInfoVo>,
officerVoList: List<ManagerInfoVo>,
) {
Column(
modifier = modifier
@ -119,7 +120,7 @@ class ManagementOfficerActivity : ComponentActivity() {
expanded = expanded,
onDismissRequest = { /*TODO*/ }) {
DropdownMenuItem(onClick = {
model.updateDuty(list = officerVoList, index = it.index)
model.updateDuty()
expanded = false
}) {
Text(text = it.value.duty.desc)

@ -1,87 +0,0 @@
package com.gyf.csams.main.ui
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ExperimentalComposeApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.google.accompanist.insets.ExperimentalAnimatedInsets
import com.gyf.csams.R
import com.gyf.csams.main.model.RenameViewModel
import com.gyf.csams.module.RenameVo
import com.gyf.csams.uikit.RowItem
import com.gyf.csams.uikit.TestTable
import com.gyf.lib.uikit.BaseTextField
import com.gyf.lib.uikit.ScaffoldModel
import com.gyf.lib.util.BottomButton
class RenameActivity : ComponentActivity() {
@ExperimentalAnimatedInsets
@ExperimentalComposeApi
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
TestTable(clazz = RenameViewModel::class.java, title = R.string.rename_form) {
RenameForm(renameVo = it)
}
}
}
@Composable
private fun RenameForm(
modifier: Modifier = Modifier, model: RenameViewModel = viewModel(),
scaffoldModel: ScaffoldModel = viewModel(), renameVo: RenameVo
) {
Column(modifier = modifier) {
val baseHeight = 50.dp
RowItem(
modifier = Modifier.height(baseHeight),
key = R.string.petitioner,
value = renameVo.studentId
)
RowItem(
modifier = Modifier.height(baseHeight),
key = R.string.oldname,
value = renameVo.oldName
)
RowItem(
modifier = Modifier.height(baseHeight),
key = R.string.newname,
value = renameVo.newName
)
RowItem(
modifier = Modifier.height(baseHeight * 3),
key = R.string.reason_for_application,
value = renameVo.reason
)
RowItem(
modifier = Modifier.height(baseHeight), key = R.string.first_approver, value = ""
/**TODO 获取审批人**/
)
RowItem(
modifier = Modifier.height(baseHeight * 3),
key = R.string.first_approver_origin
) {
BaseTextField(modifier = Modifier.fillMaxSize(), form = model.approverOrigin)
}
val message = stringResource(id = R.string.not_impl_error)
BottomButton(
confirmDesc = R.string.reported_btn, backDesc = R.string.reject_btn,
modifier = Modifier.fillMaxWidth()
) {
scaffoldModel.update(message = message)
}
}
}
}

@ -92,11 +92,10 @@ inline fun <reified VO : AuditVo, reified M : BaseAuditViewModel<VO>> CheckForm(
model.check(
auditId = vo.audit.id,
result = result,
cause = cause.formValue.value
?: throw IllegalArgumentException("无法获取审核理由")
cause = cause.getValue()
) {
scaffoldModel.update(message = it, actionLabel = "刷新") {
model.load { }
model.load()
}
}
}
@ -109,7 +108,7 @@ inline fun <reified VO : AuditVo, reified M : BaseAuditViewModel<VO>> CheckForm(
auditId = vo.audit.id
) {
scaffoldModel.update(message = it, actionLabel = "刷新") {
model.load { }
model.load()
}
}
}
@ -166,7 +165,7 @@ inline fun <reified VO : AuditVo, reified M : BaseAuditViewModel<VO>> CheckForm(
)
}
//初审记录,负责人不为空 初审受理
vo.audit.nextAudit == null && vo.audit.manager != null -> {
vo.audit.nextAudit == null && vo.audit.manager != null && vo.audit.result == null -> {
first()
if (it.duty == Duty.PamphaBhusal) {

@ -67,7 +67,7 @@
<activity android:name=".association.ui.AssociationActivity" />
<!--社团重命名主界面-->
<activity android:name=".association.ui.ReNameActivity" />
<activity android:name=".association.ui.RenameActivity" />
<!--题库界面-->
<activity android:name=".association.ui.ExamActivity" />

@ -132,18 +132,16 @@ class AccountViewModel(application: Application) : AbstractLoginViewModel(applic
},
onFail = { Logger.e(it) },
typeToken = object : TypeToken<ApiResponse<Boolean>>() {}.type
), mapOf("studentId" to "${id.formValue.value}")
), mapOf("studentId" to id.getValue())
)
}
}
}
override fun loginParam(): Any {
val studentId = "${id.formValue.value}"
val password = "${password.formValue.value}"
return UserLoginVo(
studentId = studentId,
password = password,
studentId = id.getValue(),
password = password.getValue(),
device = "${Build.MANUFACTURER} ${Build.MODEL}"
)
}
@ -183,8 +181,8 @@ class AccountViewModel(application: Application) : AbstractLoginViewModel(applic
typeToken = object : TypeToken<ApiResponse<String>>() {}.type
),
jsonParam = UserRegVo(
studentId = id.formValue.value ?: throw IllegalArgumentException("学号为空"),
name = name.formValue.value ?: throw IllegalArgumentException("姓名为空")
studentId = id.getValue(),
name = name.getValue()
)
)
resetForm()

@ -218,7 +218,7 @@ class AccountActivity : ComponentActivity() {
color = MaterialTheme.colors.error
)
) {
append(accountViewModel.id.formValue.value ?: "")
append(accountViewModel.id.getValue())
}
append(accountViewModel.registered)
})

@ -112,8 +112,7 @@ class ActivityPhotoViewModel(application: Application) :
),
params = mapOf(
"activityId" to "$activityId",
"name" to (name.formValue.value
?: throw IllegalArgumentException("照片名字为空"))
"name" to name.getValue()
),
fileList = arrayOf(cacheFile)
)
@ -172,8 +171,7 @@ class BBSCommentModel : AbstractComment() {
),
jsonParam =
SendBBSVo(
content = newContent.formValue.value
?: throw IllegalArgumentException("评论内容为空"),
content = newContent.getValue(),
token = TokenManager.getToken(),
activityId = activityId ?: throw IllegalArgumentException("活动id没有初始化")
)

@ -83,7 +83,7 @@ class ApplyActViewModel(application: Application) : AndroidViewModel(application
val checkInfo: LiveData<ApiResponse<ActivityCheckVo>> = _checkInfo
init {
read { }
read()
}
val city =
@ -587,13 +587,8 @@ class ApplyActViewModel(application: Application) : AndroidViewModel(application
*
*/
fun apply(callback: (message: String) -> Unit) {
val activityName = activityName.formValue.value ?: throw IllegalArgumentException("活动名称为空")
val activityDate = activityDate.formValue.value ?: throw IllegalArgumentException("活动日期为空")
val activityTime = activityTime.formValue.value ?: throw IllegalArgumentException("活动时间为空")
val activityDesc = activityDesc.formValue.value ?: throw IllegalArgumentException("活动介绍为空")
val activitySize = activitySize.formValue.value ?: throw IllegalArgumentException("活动规模为空")
val activityAddress =
activityAddress.formValue.value ?: throw IllegalArgumentException("活动地点为空")
val associationId = (TokenManager.getOwnInfo() as? UserVo)?.associationVo?.associationId
?: throw IllegalArgumentException("社团id为空")
viewModelScope.launch {
@ -608,12 +603,12 @@ class ApplyActViewModel(application: Application) : AndroidViewModel(application
jsonParam = ActivityApplyVo(
associationId = associationId,
activityVo = ActivityVo(
activityName = activityName,
activityTime = "$activityDate $activityTime".toDate().time,
activityAddress = activityAddress,
activityDesc = activityDesc,
activitySize = activitySize.toInt(),
activityId = _checkInfo.value?.body?.activityId
activityName = activityName.getValue(),
activityTime = "${activityDate.getValue()} ${activityTime.getValue()}".toDate().time,
activityAddress = activityAddress.getValue(),
activityDesc = activityDesc.getValue(),
activitySize = activitySize.getValue().toInt(),
activityId = _checkInfo.value?.body?.activityVo?.activityId
),
token = TokenManager.getToken()
)
@ -627,10 +622,12 @@ class ApplyActViewModel(application: Application) : AndroidViewModel(application
*
* @param callback
*/
private fun read(callback: (message: String) -> Unit) {
private fun read() {
viewModelScope.launch {
HttpClient.post(url = Api.buildUrl(ActivityApi.Read),
HttpCallback<ActivityCheckVo>(action = "查看活动申请书审核进度",
HttpClient.post(
url = Api.buildUrl(ActivityApi.Read),
HttpCallback<ActivityCheckVo>(
action = "查看活动申请书审核进度",
onSuccess = { it ->
_checkInfo.postValue(it)
it.body?.activityVo?.let {

@ -13,8 +13,11 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
@ -197,14 +200,14 @@ class ApplyActActivity : AppCompatActivity() {
)
}
Spacer(modifier = Modifier.weight(0.05F))
val activityName = model.activityName.statusForm.observeAsState()
val activityDate = model.activityDate.statusForm.observeAsState()
val activityTime = model.activityTime.statusForm.observeAsState()
val activityDesc = model.activityDesc.statusForm.observeAsState()
val activitySize = model.activitySize.statusForm.observeAsState()
val activityName by model.activityName.statusForm.observeAsState()
val activityDate by model.activityDate.statusForm.observeAsState()
val activityTime by model.activityTime.statusForm.observeAsState()
val activityDesc by model.activityDesc.statusForm.observeAsState()
val activitySize by model.activitySize.statusForm.observeAsState()
BottomButton(
modifier = Modifier.fillMaxWidth(),
enabled = check(
enabled = checkForm(
activityName,
activityDate,
activityTime,
@ -234,14 +237,6 @@ class ApplyActActivity : AppCompatActivity() {
return flag == true
}
private fun check(vararg arrayOfStates: State<FormStatus?>): Boolean {
arrayOfStates.forEach {
if (it.value != FormStatus.Valid) {
return false
}
}
return true
}
@Composable
private fun SelectIcon(modifier: Modifier = Modifier) {

@ -21,6 +21,10 @@ class AssociationViewModel : ViewModel(), TopMenuInterface<AssociationMenu> {
override val _currentMenu: MutableLiveData<AssociationMenu> = MutableLiveData()
override val currentMenu: LiveData<AssociationMenu> = _currentMenu
private val _dropDownMenuResult = MutableLiveData<String?>()
val dropDownMenuResult: LiveData<String?> = _dropDownMenuResult
/**
* 下拉菜单状态
*/
@ -30,6 +34,10 @@ class AssociationViewModel : ViewModel(), TopMenuInterface<AssociationMenu> {
private val _associationVo = MutableLiveData<AssociationMainVo>()
val associationVo: LiveData<AssociationMainVo> = _associationVo
fun update(message: String?) {
_dropDownMenuResult.postValue(message)
}
fun load(id: Int) {
viewModelScope.launch {
HttpClient.post(

@ -3,11 +3,9 @@ package com.gyf.csams.association.model
import android.app.Application
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.gyf.csams.module.ChoiceQuestionVo
import com.gyf.csams.module.Exam
import com.gyf.csams.module.ExamType
import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.uikit.StringForm
import com.gyf.lib.uikit.ValidStringForm
import com.gyf.lib.util.NOT_IMPL_TIP
/**
@ -41,6 +39,61 @@ const val ANSWER_SIZE = 4
const val ANSWER_TEXT_LENGTH = 15
/**
* 题型
*
*/
enum class ExamType(val type: String) {
//选择题
CQ("选择题"),
//开放题
OQ("开放题")
}
abstract class Exam {
abstract val examType: ExamType
//**TODO 题目反序列化
abstract val question: String?
abstract val _question: StringForm?
}
/**
* 选择题
*
* @property examType 题型描述
* @property answers 答案
* @property rightAnswer 正确答案
* @property question 问题
* TODO 题目反序列化
*/
data class ChoiceQuestionVo(
val id: Int? = null,
override val examType: ExamType = ExamType.CQ,
val _answers: MutableList<StringForm> = mutableListOf(),
val answers: List<String> = ('A'..'D').map { "选项${it}" }.toList(),
val rightAnswer: Int,
override val question: String? = null,
override val _question: StringForm?,
) : Exam()
/**
* 开放题
*
* @property examType 题型描述
* @property question 问题
* TODO 题目反序列化
*/
data class OpenQuestionsVo(
override val examType: ExamType = ExamType.OQ,
override val question: String? = null,
override val _question: StringForm?
) : Exam()
/**
* 题库状态管理
*
@ -54,9 +107,6 @@ class ExamViewModel(application: Application) : ScrollViewModel<Exam>(applicatio
val actionLabel = "确定"
override val initSize = 10
private val _newExam: MutableLiveData<Exam> = MutableLiveData(createExam(ExamType.CQ))
val newExam: LiveData<Exam> = _newExam
@ -64,9 +114,7 @@ class ExamViewModel(application: Application) : ScrollViewModel<Exam>(applicatio
load()
}
fun createQuestion(): StringForm {
return StringForm(formDesc = "问题", textLength = QUESTION_TEXT_LENGTH)
}
/**
* 切换题型
@ -85,7 +133,18 @@ class ExamViewModel(application: Application) : ScrollViewModel<Exam>(applicatio
* @return
*/
private fun createExam(type: ExamType): Exam {
TODO("创建题目")
val questionForm = ValidStringForm(formDesc = "", textLength = QUESTION_TEXT_LENGTH)
val answerA = ValidStringForm(formDesc = "选项A", textLength = ANSWER_TEXT_LENGTH)
val answerB = ValidStringForm(formDesc = "选项B", textLength = ANSWER_TEXT_LENGTH)
val answerC = ValidStringForm(formDesc = "选项C", textLength = ANSWER_TEXT_LENGTH)
val answerD = ValidStringForm(formDesc = "选项D", textLength = ANSWER_TEXT_LENGTH)
return ChoiceQuestionVo(
_answers = mutableListOf(answerA, answerB, answerC, answerD),
rightAnswer = 0,
_question = questionForm,
)
}
@ -113,7 +172,7 @@ class ExamViewModel(application: Application) : ScrollViewModel<Exam>(applicatio
* @param callback
*/
fun updateExam(callback: (message: String) -> Unit) {
callback(NOT_IMPL_TIP)
}
/**
@ -130,36 +189,10 @@ class ExamViewModel(application: Application) : ScrollViewModel<Exam>(applicatio
*
*/
fun load() {
TODO("加载题目")
}
/**
*TODO 加载更多题目
*
* @param callback
*/
fun loadMore(callback: (message: String) -> Unit) {
// _data.value?.apply {
// val list= mutableListOf<Exam>()
// list.addAll(this)
// list.apply {
// repeat(10) {
// if (Random.nextBoolean()) add(OpenQuestionsVo(question = "这是一道开放题:$size")) else add(
// ChoiceQuestionVo(
// question = "这是一道选择题:$size,请从选项中选出正确答案",
// answers = listOf("选项A", "选项B", "选项C", "选项D"),
// rightAnswer = 3
// )
// )
// }
// }
// _data.postValue(list)
// callback("成功加载更多题目")
// }
// callback(NOT_IMPL_TIP)
}
fun addQuestion() {
_data.value?.apply {
_newExam.value?.let {

@ -158,10 +158,8 @@ class RegAssociationViewModel(application: Application) : AndroidViewModel(appli
* @param callback
*/
fun register(callback: (value: String) -> Unit) {
val nameValue = name.formValue.value
val descValue = desc.formValue.value
val fileId = _fileId.value
if (nameValue != null && descValue != null && fileId != null &&
if (fileId != null &&
name.statusForm.value == FormStatus.Valid && desc.statusForm.value == FormStatus.Valid
) {
viewModelScope.launch {
@ -177,8 +175,8 @@ class RegAssociationViewModel(application: Application) : AndroidViewModel(appli
Logger.e(it)
}, typeToken = object : TypeToken<ApiResponse<Boolean>>() {}.type),
jsonParam = AssociationRegVo(
name = nameValue,
desc = descValue,
name = name.getValue(),
desc = desc.getValue(),
fileId = fileId,
associationId = _checkInfo.value?.body?.associationVo?.associationId,
token = TokenManager.getToken()

@ -1,8 +1,14 @@
package com.gyf.csams.association.model
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.gyf.lib.uikit.StringForm
import com.gyf.lib.util.NOT_IMPL_TIP
import androidx.lifecycle.viewModelScope
import com.google.gson.reflect.TypeToken
import com.gyf.csams.module.*
import com.gyf.lib.uikit.AsyncStringForm
import com.gyf.lib.util.*
import kotlinx.coroutines.launch
/**
* 社团重命名状态管理
@ -11,18 +17,79 @@ import com.gyf.lib.util.NOT_IMPL_TIP
class RenameViewModel : ViewModel() {
val menuName = "换名申请表"
val oldName = StringForm(formDesc = "社团原名", textLength = 10)
val newName = StringForm(formDesc = "社团新名", textLength = 10)
val cause = StringForm(formDesc = "换名原因", textLength = 30)
val oldName = AsyncStringForm(formDesc = "社团原名", textLength = 10)
val postDesc = "提交申请"
val back = "返回"
val newName = AsyncStringForm(formDesc = "社团新名", textLength = 10)
val cause = AsyncStringForm(formDesc = "换名原因", textLength = 30)
private val _actionResult = MutableLiveData<String>()
val actionResult: LiveData<String> = _actionResult
private fun clean() {
newName.clean()
cause.clean()
}
private val _checkInfo = MutableLiveData<ApiResponse<RenameCheckVo>>()
val checkInfo: LiveData<ApiResponse<RenameCheckVo>> = _checkInfo
init {
read()
}
/**
* 提交重命名申请
*
*/
fun apply(associationId: Int) {
viewModelScope.launch {
HttpClient.post(
url = Api.buildUrl(AssociationApi.RenameRegister),
callback = HttpCallback<Boolean>(action = "提交换名申请表", onSuccess = {
it.body?.let {
if (it) {
clean()
}
}
_actionResult.postValue(it.message)
}, typeToken = object : TypeToken<ApiResponse<Boolean>>() {}.type),
jsonParam = RenameApplyVo(
rename = RenameVo(
newName = newName.getValue(),
cause = cause.getValue(),
renameId = _checkInfo.value?.body?.renameVo?.renameId
),
associationId = associationId,
token = TokenManager.getToken()
)
)
}
}
/**
* TODO 提交表单
* 查看审核进度
*
* @param callback
*/
fun post(callback: (message: String) -> Unit) {
callback(NOT_IMPL_TIP)
private fun read() {
viewModelScope.launch {
HttpClient.post(url = Api.buildUrl(AssociationApi.RenameRead),
callback = HttpCallback<RenameCheckVo>(action = "查看审核进度",
onSuccess = { it ->
_checkInfo.postValue(it)
it.body?.renameVo?.let {
newName.setValue(it.newName)
cause.setValue(it.cause)
}
}, typeToken = object : TypeToken<ApiResponse<RenameCheckVo>>() {}.type
),
jsonParam = OnlyToken(clientType = ClientType.Foreground)
)
}
}
}

@ -3,7 +3,9 @@ package com.gyf.csams.association.ui
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
@ -11,9 +13,7 @@ import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -34,6 +34,8 @@ import com.gyf.csams.module.ActivityVo
import com.gyf.csams.uikit.*
import com.gyf.lib.uikit.*
import com.gyf.lib.util.TokenManager
import com.orhanobut.logger.Logger
import kotlinx.coroutines.delay
/**
@ -45,7 +47,7 @@ class AssociationActivity : ComponentActivity() {
private val associationId: Int
get() {
val id = intent.getIntExtra(
AssociationActivity::javaClass.name,
AssociationActivity::class.java.name,
0
)
return if (id == 0) throw IllegalArgumentException("社团id:${id}不合法,初始化失败") else id
@ -63,12 +65,26 @@ class AssociationActivity : ComponentActivity() {
val intent = Intent(this, ExamActivity::class.java)
val expanded by model.expanded.observeAsState(false)
var message: String? by remember {
mutableStateOf(null)
}
//TODO重命名操作反馈
val rename =
rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == RESULT_OK) {
val m = it.data?.getStringExtra(RenameActivity::class.java.name)
Logger.i("社团重命名返回:${m}")
message = m
}
}
Column {
TextTopAppBar(nav = nav,
currentMenuName = currentMenuName.menuName,
menuNames = AssociationMenu.values(),
iconMenu = { model.switchType() }) {
Row {
DropdownMenu(
expanded = expanded,
onDismissRequest = { },
@ -85,7 +101,7 @@ class AssociationActivity : ComponentActivity() {
ApplyActActivity::class.java
).apply {
putExtra(
AssociationActivity::javaClass.name,
AssociationActivity::class.java.name,
associationId
)
}
@ -120,12 +136,15 @@ class AssociationActivity : ComponentActivity() {
}
}
DropdownMenuItem(onClick = {
startActivity(
Intent(
this@AssociationActivity,
ReNameActivity::class.java
rename.launch(Intent(
this@AssociationActivity,
RenameActivity::class.java
).apply {
putExtra(
AssociationActivity::class.java.name,
associationId
)
)
})
model.close()
}) {
Row(verticalAlignment = Alignment.CenterVertically) {
@ -136,6 +155,7 @@ class AssociationActivity : ComponentActivity() {
)
}
}
}
TokenManager.getUserInfo()?.associationVo == null -> DropdownMenuItem(
onClick = {
@ -187,6 +207,22 @@ class AssociationActivity : ComponentActivity() {
composable(AssociationMenu.Main.name) {
model.clickMenu(AssociationMenu.Main)
Main()
//TODO 提示
val scaffoldModel: ScaffoldModel = viewModel()
message?.let {
scaffoldModel.update(message = message, actionLabel = "刷新")
val s by scaffoldModel.data.observeAsState()
if (s == null) {
message = null
// nav.navigate(AssociationMenu.Main.name)
}
LaunchedEffect(message) {
delay(it.length * 300L)
message = null
// nav.navigate(AssociationMenu.Main.name)
}
}
ShowSnackbar(scaffoldState = scaffoldState)
}
composable(AssociationMenu.ActivityList.name) {
@ -202,6 +238,18 @@ class AssociationActivity : ComponentActivity() {
}
}
//TODO下拉菜单操作反馈
@Composable
private fun ShowTip(
model: AssociationViewModel = viewModel(),
scaffoldModel: ScaffoldModel = viewModel()
) {
val m by model.dropDownMenuResult.observeAsState()
m?.let {
Logger.i("收到${it}")
scaffoldModel.update(message = it, actionLabel = "关闭提示")
}
}
/**
* 社团成员
@ -466,9 +514,7 @@ class AssociationActivity : ComponentActivity() {
private fun OngoingActivity(
modifier: Modifier = Modifier
) {
Row(modifier = modifier.clickable(onClick = {
startActivity(Intent(this, ActivityDetailActivity::class.java))
}), horizontalArrangement = Arrangement.Center) {
Row(horizontalArrangement = Arrangement.Center) {
val weight = 0.5F
val spaceWeight = (1 - 0.5F) / 2
Spacer(modifier = Modifier.weight(spaceWeight))

@ -18,12 +18,7 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.gyf.csams.R
import com.gyf.csams.association.model.ANSWER_SIZE
import com.gyf.csams.association.model.ExamActivityType
import com.gyf.csams.association.model.ExamViewModel
import com.gyf.csams.module.ChoiceQuestionVo
import com.gyf.csams.module.Exam
import com.gyf.csams.module.OpenQuestionsVo
import com.gyf.csams.association.model.*
import com.gyf.csams.uikit.Background
import com.gyf.csams.uikit.BackgroundImage
import com.gyf.lib.uikit.BaseTextField
@ -119,9 +114,9 @@ class ExamActivity : ComponentActivity() {
newExam?.let {
item {
Column {
OutlinedButton(onClick = { model.switchType(it) }) {
Text(text = "切换到${if (newExam is ChoiceQuestionVo) "开放题" else "选择题"}")
}
// OutlinedButton(onClick = { model.switchType(it) }) {
// Text(text = "切换到${if (newExam is ChoiceQuestionVo) "开放题" else "选择题"}")
// }
ExamChild(it = it, examHeight = examHeight, isAdd = true)
}
}
@ -159,9 +154,9 @@ class ExamActivity : ComponentActivity() {
}
if (listState.layoutInfo.totalItemsCount - listState.firstVisibleItemIndex == model.initSize / 2 - 1) {
model.loadMore { scaffoldModel.update(message = it) }
}
// if (listState.layoutInfo.totalItemsCount - listState.firstVisibleItemIndex == model.initSize / 2 - 1) {
// model.loadMore { scaffoldModel.update(message = it) }
// }
}
@ -175,17 +170,16 @@ class ExamActivity : ComponentActivity() {
@Composable
private fun Question(
modifier: Modifier = Modifier,
exam: Exam,
model: ExamViewModel = viewModel()
exam: Exam
) {
/*问题**/
val s = model.createQuestion()
BaseTextField(
form = s,
modifier = modifier
.fillMaxSize()
.background(color = MaterialTheme.colors.background)
)
exam._question?.let {
BaseTextField(
form = it,
modifier = modifier
.fillMaxSize()
.background(color = MaterialTheme.colors.background)
)
}
}
@ -201,43 +195,46 @@ class ExamActivity : ComponentActivity() {
exam: Exam
) {
val list by model.data.observeAsState()
val newExam by model.newExam.observeAsState()
Box(
contentAlignment = Alignment.Center,
modifier = modifier
) {
IconButton(onClick = {
if (isAdd) {
if ((newExam?.question ?: "").isNotEmpty()) {
scaffoldModel.update(
message = model.addTip,
actionLabel = model.actionLabel
) {
model.addQuestion()
model.newExam.value?._question?.let {
val value by it.formValue.observeAsState()
Box(
contentAlignment = Alignment.Center,
modifier = modifier
) {
IconButton(onClick = {
if (isAdd) {
if ((value?.isNotEmpty() == true)) {
scaffoldModel.update(
message = model.addTip,
actionLabel = model.actionLabel
) {
model.addQuestion()
}
} else {
scaffoldModel.update(message = model.questionIsNull)
}
} else {
scaffoldModel.update(message = model.questionIsNull)
}
} else {
if (list?.size == 1) {
scaffoldModel.update(model.deleteLeastOne)
} else {
scaffoldModel.update(
message = model.deleteTip,
actionLabel = model.actionLabel
) {
model.deleteQuestion(exam = exam)
if (list?.size == 1) {
scaffoldModel.update(model.deleteLeastOne)
} else {
scaffoldModel.update(
message = model.deleteTip,
actionLabel = model.actionLabel
) {
model.deleteQuestion(exam = exam)
}
}
}
}) {
Icon(
painter = painterResource(id = if (isAdd) R.drawable.ic_add_select else R.drawable.ic_sami_select),
contentDescription = null
)
}
}) {
Icon(
painter = painterResource(id = if (isAdd) R.drawable.ic_add_select else R.drawable.ic_sami_select),
contentDescription = null
)
}
}
}
@ -309,7 +306,7 @@ class ExamActivity : ComponentActivity() {
.weight(1 - questionWeight)
) {
choiceQuestionVo.answers.apply {
choiceQuestionVo._answers.apply {
Column {
forEach {
Row(
@ -327,8 +324,8 @@ class ExamActivity : ComponentActivity() {
val isRightAnswer =
choiceQuestionVo.rightAnswer == answerIndex
RadioButton(selected = isRightAnswer, onClick = click)
val c = model.createQuestion()
BaseTextField(form = c)
BaseTextField(form = it)
}
}
}

@ -1,99 +0,0 @@
package com.gyf.csams.association.ui
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.gyf.csams.association.model.RenameViewModel
import com.gyf.csams.uikit.Background
import com.gyf.csams.uikit.BackgroundImage
import com.gyf.lib.uikit.BaseTextField
import com.gyf.lib.uikit.Body
import com.gyf.lib.uikit.MainColumnFrame
import com.gyf.lib.uikit.ScaffoldModel
import com.gyf.lib.util.BottomButton
/**
* 社团重命名
*
*/
class ReNameActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Body {
MainColumnFrame(background = { Background(image = BackgroundImage.Rename) }) {
Spacer(
modifier = Modifier
.weight(0.2F)
)
Title(modifier = Modifier.weight(0.1F))
OldName(modifier = Modifier.weight(0.1F))
NewName(modifier = Modifier.weight(0.1F))
Cause(modifier = Modifier.weight(0.2F))
Spacer(modifier = Modifier.height(10.dp))
val model: RenameViewModel = viewModel()
val scaffoldModel: ScaffoldModel = viewModel()
BottomButton(
modifier = Modifier
.weight(0.1F)
.fillMaxWidth()
) {
model.post { scaffoldModel.update(message = it) }
}
Spacer(modifier = Modifier.weight(1 - 0.2F * 2 - 0.1F * 4))
}
}
}
}
/**
* 标题
*
*/
@Composable
private fun Title(modifier: Modifier = Modifier, model: RenameViewModel = viewModel()) {
Row(modifier = modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
Text(text = model.menuName, style = MaterialTheme.typography.h4)
}
}
/**
* 社团原名
*
*/
@Composable
private fun OldName(modifier: Modifier = Modifier, model: RenameViewModel = viewModel()) {
BaseTextField(form = model.oldName, modifier = modifier.fillMaxWidth(), singeLine = true)
}
/**
* 社团新名
*
*/
@Composable
private fun NewName(modifier: Modifier = Modifier, model: RenameViewModel = viewModel()) {
BaseTextField(form = model.newName, modifier = modifier.fillMaxWidth(), singeLine = true)
}
/**
* 换名原因
*
*/
@Composable
private fun Cause(modifier: Modifier = Modifier, model: RenameViewModel = viewModel()) {
BaseTextField(form = model.cause, modifier = modifier.fillMaxWidth())
}
}

@ -0,0 +1,195 @@
package com.gyf.csams.association.ui
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.gyf.csams.association.model.AssociationViewModel
import com.gyf.csams.association.model.RenameViewModel
import com.gyf.csams.module.CheckStatus
import com.gyf.csams.uikit.Background
import com.gyf.csams.uikit.BackgroundImage
import com.gyf.csams.uikit.CheckTip
import com.gyf.lib.uikit.BaseTextField
import com.gyf.lib.uikit.Body
import com.gyf.lib.uikit.MainColumnFrame
import com.gyf.lib.uikit.checkForm
import com.gyf.lib.util.BottomButton
import com.orhanobut.logger.Logger
/**
* 社团重命名
*
*/
class RenameActivity : ComponentActivity() {
private val associationId: Int
get() {
val id = intent.getIntExtra(
AssociationActivity::class.java.name,
0
)
return if (id == 0) throw IllegalArgumentException("社团id:${id}不合法,初始化失败") else id
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Body {
MainColumnFrame(background = { Background(image = BackgroundImage.Rename) }) {
val model: RenameViewModel = viewModel()
val checkInfo by model.checkInfo.observeAsState()
checkInfo?.body?.auditCheckVo.let {
if (it == null) {
Title(modifier = Modifier.weight(0.2F))
} else {
Title()
CheckTip(it = it, modifier = Modifier.weight(0.15F))
}
}
OldName(modifier = Modifier.weight(0.1F))
NewName(modifier = Modifier.weight(0.1F))
Cause(modifier = Modifier.weight(0.2F))
Spacer(modifier = Modifier.height(10.dp))
val oldNameStatus by model.oldName.statusForm.observeAsState()
val newNameStatus by model.newName.statusForm.observeAsState()
val cause by model.cause.statusForm.observeAsState()
val hasError = repeatError()
BottomButton(
modifier = Modifier
.weight(0.1F)
.fillMaxWidth(),
enabled = checkForm(newNameStatus, cause) && !hasError
) {
model.apply(associationId = associationId)
}
val actionResult by model.actionResult.observeAsState()
actionResult?.let {
if (it.isNotEmpty()) {
setResult(
RESULT_OK,
Intent().apply {
putExtra(
RenameActivity::class.java.name,
actionResult
)
})
finish()
} else {
Logger.w("申请已提交,但是没有收到返回")
}
}
Spacer(modifier = Modifier.weight(1 - 0.2F * 2 - 0.1F * 4))
}
}
}
}
//TODO 合并ValidStringForm
@Composable
private fun repeatError(model: RenameViewModel = viewModel()): Boolean {
val oldName by model.oldName.formValue.observeAsState()
val newName by model.newName.formValue.observeAsState()
return oldName?.isNotEmpty() == true && newName?.isNotEmpty() == true && oldName == newName
}
@Composable
private fun isReadOnly(model: RenameViewModel): Boolean {
val checkInfo by model.checkInfo.observeAsState()
val flag = (checkInfo?.body?.let { it.auditCheckVo.checkStatus != CheckStatus.Finish })
Logger.d("flag=${flag}")
return flag == true
}
/**
* 标题
*
*/
@Composable
private fun Title(modifier: Modifier = Modifier, model: RenameViewModel = viewModel()) {
Row(modifier = modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
Text(text = model.menuName, style = MaterialTheme.typography.h6)
}
}
/**
* 社团原名
*
*/
@Composable
private fun OldName(
modifier: Modifier = Modifier,
model: RenameViewModel = viewModel(),
ass: AssociationViewModel = viewModel()
) {
LaunchedEffect(associationId) {
ass.load(id = associationId)
}
val associationVo by ass.associationVo.observeAsState()
associationVo?.let {
model.oldName.setValue(it.associationVo.name)
}
BaseTextField(
form = model.oldName, modifier = modifier.fillMaxWidth(), singeLine = true,
readOnly = true, isError = repeatError()
)
if (repeatError()) {
Text(text = "社团原名和社团新名不能重复", color = MaterialTheme.colors.error)
}
}
/**
* 社团新名
*
*/
@Composable
private fun NewName(modifier: Modifier = Modifier, model: RenameViewModel = viewModel()) {
BaseTextField(
form = model.newName, modifier = modifier.fillMaxWidth(), singeLine = true,
readOnly = isReadOnly(model = model), isError = repeatError()
)
if (repeatError()) {
Text(text = "社团原名和社团新名不能重复", color = MaterialTheme.colors.error)
}
}
/**
* 换名原因
*
*/
@Composable
private fun Cause(modifier: Modifier = Modifier, model: RenameViewModel = viewModel()) {
BaseTextField(
form = model.cause, modifier = modifier.fillMaxWidth(),
readOnly = isReadOnly(model = model)
)
}
}

@ -96,7 +96,7 @@ class MarqueeViewModel : AbstractComment() {
}, typeToken = object : TypeToken<ApiResponse<Boolean>>() {}.type
),
jsonParam = LeaveMessageVo(
message = newContent.formValue.value ?: "",
message = newContent.getValue(),
token = TokenManager.getToken()
)
)

@ -26,6 +26,11 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import com.google.accompanist.coil.rememberCoilPainter
import com.google.accompanist.imageloading.ImageLoadState
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.HorizontalPager
import com.google.accompanist.pager.PagerState
import com.google.accompanist.pager.rememberPagerState
import com.gyf.csams.R
import com.gyf.csams.account.model.AccountViewModel
import com.gyf.csams.account.model.RefreshViewModel
@ -34,14 +39,12 @@ import com.gyf.csams.association.ui.AssociationActivity
import com.gyf.csams.association.ui.RegAssociationActivity
import com.gyf.csams.main.model.*
import com.gyf.csams.message.ui.SysMessageActivity
import com.gyf.csams.module.AssociationVo
import com.gyf.csams.module.CheckStatus
import com.gyf.csams.module.ClientType
import com.gyf.csams.module.UserVo
import com.gyf.csams.module.*
import com.gyf.csams.uikit.*
import com.gyf.lib.service.BaseActivity
import com.gyf.lib.uikit.*
import com.gyf.lib.util.*
import com.orhanobut.logger.Logger
/**
@ -52,23 +55,20 @@ class MainActivity : BaseActivity() {
override val clientType: ClientType = ClientType.Foreground
@ExperimentalPagerApi
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val imageViewModel: ImageViewModel = viewModel()
NavBody { nav, scaffoldState ->
NavHost(navController = nav, startDestination = MainMenu.Main.name) {
composable(MainMenu.Main.name) {
Main(navController = nav)
ShowSnackbar(scaffoldState = scaffoldState)
imageViewModel.start()
}
composable(MainMenu.List.name) {
AssociationList(navController = nav)
ShowSnackbar(scaffoldState = scaffoldState)
imageViewModel.cancel()
}
composable(MainMenu.Center.name) {
val refresh: RefreshViewModel = viewModel()
@ -78,7 +78,6 @@ class MainActivity : BaseActivity() {
Center(navController = nav)
ShowSnackbar(scaffoldState = scaffoldState)
}
imageViewModel.cancel()
}
}
@ -124,7 +123,7 @@ class MainActivity : BaseActivity() {
this@MainActivity,
AssociationActivity::class.java
).apply {
putExtra(AssociationActivity::javaClass.name, it)
putExtra(AssociationActivity::class.java.name, it)
})
}
// CenterMenuItem(text = model.myJoinActivity)
@ -171,6 +170,7 @@ class MainActivity : BaseActivity() {
/**
* 主界面
*/
@ExperimentalPagerApi
@Composable
private fun Main(navController: NavHostController) {
MainColumnFrame(
@ -178,21 +178,27 @@ class MainActivity : BaseActivity() {
mainMenu = MainMenu.Main,
nav = navController
) {
Column(modifier = Modifier.weight(0.33F)) {
Notification()
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 15.dp),
verticalArrangement = Arrangement.SpaceEvenly
) {
MessageBoard()
ClubActivitiesTitle()
val viewModel: ImageViewModel = viewModel()
val imageList by viewModel.imageList.observeAsState()
imageList?.let {
val pagerState = rememberPagerState(pageCount = it.size)
Column(modifier = Modifier.weight(0.33F)) {
Notification()
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 15.dp),
verticalArrangement = Arrangement.SpaceEvenly
) {
MessageBoard()
ClubActivitiesTitle(vo = it[pagerState.currentPage])
}
}
Column(modifier = Modifier.weight(0.66F)) {
PosterWithDesc(pagerState = pagerState, imgList = it)
}
}
Column(modifier = Modifier.weight(0.66F)) {
PosterWithDesc()
}
}
}
@ -235,9 +241,6 @@ class MainActivity : BaseActivity() {
RESULT_OK -> {
it.data?.getStringExtra(RegAssociationActivity::class.java.name)?.let {
if (it == CheckStatus.Finish.name) {
// model.load {
// scaffoldModel.update(message = "社团审核通过",actionLabel = "关闭提示")
// }
navController.navigate(MainMenu.List.name)
}
}
@ -318,7 +321,7 @@ class MainActivity : BaseActivity() {
private fun Association(associationVo: AssociationVo) {
Card(modifier = Modifier.clickable(onClick = {
val intent = Intent(this, AssociationActivity::class.java)
intent.putExtra(AssociationActivity::javaClass.name, associationVo.associationId)
intent.putExtra(AssociationActivity::class.java.name, associationVo.associationId)
startActivity(intent)
})) {
val backgroundImage = rememberCoilPainter(request = R.drawable.association_list_border)
@ -459,8 +462,9 @@ class MainActivity : BaseActivity() {
* 活动标题
*
*/
@ExperimentalPagerApi
@Composable
private fun ClubActivitiesTitle(modifier: Modifier = Modifier) {
private fun ClubActivitiesTitle(modifier: Modifier = Modifier, vo: MainActivityPhotoVo) {
Card(modifier = modifier, backgroundColor = MaterialTheme.colors.background) {
Row(
modifier = Modifier
@ -469,7 +473,7 @@ class MainActivity : BaseActivity() {
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "超级课程表X滴滴出行-了不起的社团",
text = vo.activityVo.activityName,
style = MaterialTheme.typography.h6,
overflow = TextOverflow.Ellipsis,
maxLines = 1
@ -483,35 +487,72 @@ class MainActivity : BaseActivity() {
* 带介绍活动海报
*
*/
@ExperimentalPagerApi
@Composable
private fun PosterWithDesc(
scaffoldModel: ScaffoldModel = viewModel(),
viewModel: ImageViewModel = viewModel()
pagerState: PagerState,
imgList: List<MainActivityPhotoVo>
) {
imgList.let {
HorizontalPager(state = pagerState) { page ->
// Our page content
Logger.i("page=${page}")
Column {
val photo = rememberCoilPainter(request = Api.buildUrl(it[page].url))
Poster(
modifier = Modifier
.weight(0.6F)
.fillMaxWidth()
) {
when (photo.loadState) {
is ImageLoadState.Loading -> {
// Display a circular progress indicator whilst loading
CircularProgressIndicator()
}
is ImageLoadState.Error -> {
// If you wish to display some content if the request fails
Logger.e("轮播图加载失败")
}
else ->
it[page].apply {
Image(
painter = photo,
contentDescription = activityVo.activityName,
modifier = Modifier.clickable(onClick = {
startActivity(
Intent(
this@MainActivity,
ActivityDetailActivity::class.java
).apply {
putExtra(
ActivityDetailActivity::class.java.name,
activityVo.activityId
)
putExtra(
AssociationActivity::class.java.name,
associationVo.associationId
)
})
})
)
}
val error by viewModel.error.observeAsState()
error?.let {
scaffoldModel.update(message = it)
viewModel.clearError()
}
Carousel(imageBitmap = viewModel.image) {
Column(modifier = Modifier.clickable(onClick = {
startActivity(Intent(this, ActivityDetailActivity::class.java))
})) {
Poster(
modifier = Modifier
.weight(0.6F)
.fillMaxWidth()
)
DescCard(
modifier = Modifier
.weight(0.4F)
.fillMaxWidth(),
content = randomChinese(500)
)
}
}
DescCard(
modifier = Modifier
.weight(0.4F)
.fillMaxWidth(),
content = it[page].activityVo.activityDesc
)
}
}
}
}
}

@ -462,6 +462,25 @@ fun Background(image: BackgroundImage, alpha: Float = DefaultAlpha) {
}
@Composable
fun Poster(modifier: Modifier = Modifier, image: @Composable () -> Unit) {
Card(
modifier = modifier,
backgroundColor = Color.Transparent
) {
Box(contentAlignment = Alignment.Center) {
Image(
painter = painterResource(id = R.drawable.hot_activity_background),
contentDescription = null,
modifier = Modifier.fillMaxSize()
)
Box(modifier = Modifier.padding(vertical = 10.dp)) {
image()
}
}
}
}
/**
* 活动海报
*

@ -1,100 +1,48 @@
package com.gyf.csams.uikit
import android.app.Application
import androidx.compose.ui.graphics.ImageBitmap
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.R
import com.gyf.csams.module.ApiResponse
import com.gyf.csams.module.ClientType
import com.gyf.csams.module.MainActivityPhotoVo
import com.gyf.lib.util.*
import com.orhanobut.logger.Logger
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class ImageViewModel(application: Application) : AndroidViewModel(application) {
private val _image = MutableLiveData<ImageBitmap>()
private val _imageUrls = MutableLiveData<List<String>?>()
val image: LiveData<ImageBitmap> = _image
private var job: Job? = null
private val _error = MutableLiveData<String?>()
val error: LiveData<String?> = _error
private val urlPath = Api.buildUrl(MainApi.HotActivity)
fun clearError() {
_error.value = null
}
/**
* 加载默认图片
*
*/
private fun defaultLoad() {
viewModelScope.launch {
_image.postValue(
ImageUtil.getImage(
getApplication(),
R.drawable.ic_launcher_foreground
)
)
}
private val _imageList = MutableLiveData<List<MainActivityPhotoVo>>()
val imageList: LiveData<List<MainActivityPhotoVo>> = _imageList
init {
load()
}
/**
* 循环加载网络图片
*
*/
fun start() {
Logger.i("启动轮播")
if (job == null || job?.isCompleted == true || job?.isCancelled == true) {
job = viewModelScope.launch {
HttpClient.get(
url = urlPath,
HttpCallback<List<String>>("获取轮播图", onSuccess = {
_imageUrls.postValue(it.body)
var index = 0
_imageUrls.value?.apply {
viewModelScope.launch {
do {
val imageBitmap =
ImageUtil.getImage(
context = getApplication(),
data = get(index)
)
Logger.e("成功从image url:${get(index)}解析图片")
imageBitmap?.apply {
_image.postValue(this)
}
delay(5000)
index = if (index == size - 1) 0 else index.plus(1)
} while (job?.isActive == true)
}
fun load() {
viewModelScope.launch {
HttpClient.post(
url = Api.buildUrl(MainApi.HotActivity),
callback = HttpCallback<List<MainActivityPhotoVo>>(action = "加载活动轮播图",
onSuccess = {
it.body?.let {
_imageList.postValue(it)
}
}, onFail = {
Logger.e("无法从接口地址:${urlPath}获取图片url列表")
_error.postValue(it)
defaultLoad()
}, typeToken = object : TypeToken<ApiResponse<List<String>>>() {}.type)
)
}.apply {
start()
}
},
typeToken = object : TypeToken<ApiResponse<List<MainActivityPhotoVo>>>() {}.type
),
jsonParam = OnlyToken(clientType = ClientType.Foreground)
)
}
}
fun cancel() {
Logger.i("停止轮播")
job?.cancel()
}
override fun onCleared() {
super.onCleared()
cancel()
}
}

@ -2,12 +2,8 @@ package com.gyf.csams.util
import com.google.gson.*
import com.google.gson.reflect.TypeToken
import com.gyf.csams.association.model.ANSWER_SIZE
import com.gyf.csams.association.model.QUESTION_TEXT_LENGTH
import com.gyf.csams.module.ChoiceQuestionVo
import com.gyf.csams.module.Exam
import com.gyf.csams.module.ExamType
import com.gyf.csams.module.OpenQuestionsVo
import com.gyf.csams.association.model.*
import com.gyf.lib.uikit.StringForm
import java.lang.reflect.Type

@ -2,8 +2,8 @@ package com.gyf.csams.util
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.gyf.csams.association.model.Exam
import com.gyf.csams.module.ApiResponse
import com.gyf.csams.module.Exam
import com.gyf.lib.util.HttpCallback
import java.lang.reflect.Type

@ -50,7 +50,7 @@ class ExampleUnitTest {
@Test
fun testLib() {
println(mutableListOf(('A'..'D').map { "选项${it}" }))
}
}

@ -63,6 +63,7 @@ dependencies {
api("com.google.accompanist:accompanist-insets:$accompanist_version")
api("com.google.accompanist:accompanist-systemuicontroller:$accompanist_version")
api("com.google.accompanist:accompanist-coil:$accompanist_version")
api("com.google.accompanist:accompanist-pager:$accompanist_version")
/**
* 针对最新的平台功能和 API 调整应用,同时还支持旧设备。
* https://developer.android.com/jetpack/androidx/releases/core

@ -18,6 +18,15 @@ import androidx.lifecycle.MutableLiveData
import com.orhanobut.logger.Logger
fun checkForm(vararg arrayOfStates: FormStatus?): Boolean {
arrayOfStates.forEach {
if (it != FormStatus.Valid) {
return false
}
}
return true
}
enum class FormStatus {
//空
Empty,
@ -25,7 +34,7 @@ enum class FormStatus {
//格式不匹配
FormatError,
//学号已存在
//重复
Repeat,
//校验通过
@ -66,6 +75,10 @@ open class StringForm(formDesc: String, val textLength: Int) :
Logger.i("${formDesc}更新值:${_formValue.value}")
}
fun getValue(): String {
return _formValue.value ?: throw IllegalArgumentException("获取${formDesc}失败,值为空!")
}
fun clean() {
_formValue.postValue("")
}

@ -44,8 +44,13 @@ enum class AccountApi(val path: String) : UrlPath {
Logout("/logout"),
//刷新用户信息
Refresh("/refresh");
Refresh("/refresh"),
//加载部门干事概况
Load("/load/manager"),
//加载部门详情
LoadDetail("${Load.path}/detail");
override fun build(): String {
return "/api/account${this.path}"
@ -90,6 +95,11 @@ enum class AssociationApi(val path: String) : UrlPath {
//模糊查询社团
List("/list"),
//后台社团管理
ListAll("${List.path}/all"),
Update("/update"),
//审核注册资料
Check("/check"),
@ -103,8 +113,25 @@ enum class AssociationApi(val path: String) : UrlPath {
Load("/load"),
//加载社团成员
LoadMember("${Load.path}/members");
LoadMember("${Load.path}/members"),
//社团重命名
Rename("/rename"),
//提交换名申请表
RenameRegister("${Rename.path}${Register.path}"),
//换名申请表受理
RenameAccept("${Rename.path}${Accept.path}"),
//换名申请表审核
RenameCheck("${Rename.path}${Check.path}"),
//换名申请表审核记录
RenameAudit("${Rename.path}${Audit.path}"),
//换名申请表审核进度
RenameRead("${Rename.path}${Read.path}");
override fun build(): String {
return "/api/association${this.path}"
@ -148,7 +175,10 @@ enum class ActivityApi(val path: String) : UrlPath {
Comment("/comment"),
//发送评论
SendComment("${Comment.path}/send");
SendComment("${Comment.path}/send"),
//后台活动查看
ListAll("/list/all");
override fun build(): String {

@ -19,6 +19,5 @@ class ExampleUnitTest {
@Test
fun testClientToken() {
}
}
Loading…
Cancel
Save