parent
d6d3193837
commit
f093f47c37
@ -0,0 +1,29 @@ |
||||
package com.gyf.csams.main.model |
||||
|
||||
import android.app.Application |
||||
import com.google.gson.reflect.TypeToken |
||||
import com.gyf.csams.module.AuditActVo |
||||
import com.gyf.lib.util.ActivityApi |
||||
import com.gyf.lib.util.ApiResponse |
||||
|
||||
import com.gyf.lib.util.UrlPath |
||||
import java.lang.reflect.Type |
||||
|
||||
|
||||
/** |
||||
* 活动审核 |
||||
* |
||||
*/ |
||||
class AuditActViewModel(application: Application) : BaseAuditViewModel<AuditActVo>(application) { |
||||
override val auditApi: UrlPath = ActivityApi.Audit |
||||
override val acceptApi: UrlPath = ActivityApi.Accept |
||||
override val checkApi: UrlPath = ActivityApi.Check |
||||
override val typeToken: Type = |
||||
object : TypeToken<ApiResponse<MutableList<AuditActVo>>>() {}.type |
||||
|
||||
init { |
||||
load { } |
||||
} |
||||
|
||||
|
||||
} |
@ -1,78 +1,28 @@ |
||||
package com.gyf.csams.main.model |
||||
|
||||
import android.app.Application |
||||
import androidx.lifecycle.viewModelScope |
||||
import com.google.gson.reflect.TypeToken |
||||
import com.gyf.lib.model.ScrollViewModel |
||||
import com.gyf.lib.util.* |
||||
import kotlinx.coroutines.launch |
||||
import com.gyf.csams.module.AuditAssociationVo |
||||
import com.gyf.lib.util.ApiResponse |
||||
import com.gyf.lib.util.AssociationApi |
||||
|
||||
import com.gyf.lib.util.UrlPath |
||||
import java.lang.reflect.Type |
||||
|
||||
class AuditAssociationViewModel(application: Application) : ScrollViewModel<DisposeRegInfoVo>( |
||||
|
||||
class AuditAssociationViewModel(application: Application) : BaseAuditViewModel<AuditAssociationVo>( |
||||
application |
||||
) { |
||||
override val initSize: Int = 10 |
||||
|
||||
override val auditApi: UrlPath = AssociationApi.Audit |
||||
override val acceptApi: UrlPath = AssociationApi.Accept |
||||
override val checkApi: UrlPath = AssociationApi.Check |
||||
override val typeToken: Type = |
||||
object : TypeToken<ApiResponse<MutableList<AuditAssociationVo>>>() {}.type |
||||
|
||||
init { |
||||
load { } |
||||
} |
||||
|
||||
fun load(callback: (message: String) -> Unit) { |
||||
viewModelScope.launch { |
||||
HttpClient.post( |
||||
Api.buildUrl(AssociationApi.Audit), HttpCallback<MutableList<DisposeRegInfoVo>>( |
||||
action = "获取审核列表", |
||||
onSuccess = { it -> |
||||
it.body?.let { |
||||
_data.postValue(it) |
||||
} |
||||
}, |
||||
typeToken = object : |
||||
TypeToken<ApiResponse<MutableList<DisposeRegInfoVo>>>() {}.type |
||||
), |
||||
jsonParam = OnlyToken(clientType = ClientType.Background) |
||||
) |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
/** |
||||
* 受理注册资料 |
||||
* |
||||
* @param callback |
||||
*/ |
||||
fun accept(regId: Int, isFirstAccept: Boolean, callback: (message: String) -> Unit) { |
||||
viewModelScope.launch { |
||||
HttpClient.post( |
||||
Api.buildUrl(AssociationApi.Accept), |
||||
HttpCallback<Boolean>(action = "受理社团注册资料", onSuccess = { |
||||
callback(it.message) |
||||
}, typeToken = object : TypeToken<ApiResponse<Boolean>>() {}.type), |
||||
jsonParam = AcceptRegAssociation(regId = regId, isFirstAccept = isFirstAccept) |
||||
) |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 提交审核结果 |
||||
* |
||||
* @param regId |
||||
* @param result |
||||
* @param callback |
||||
*/ |
||||
fun check(regId: Int, cause: String, result: Boolean, callback: (message: String) -> Unit) { |
||||
viewModelScope.launch { |
||||
HttpClient.post( |
||||
Api.buildUrl(AssociationApi.Check), |
||||
HttpCallback<Boolean>(action = "提交审核结果", onSuccess = { |
||||
callback(it.message) |
||||
}, typeToken = object : TypeToken<ApiResponse<Boolean>>() {}.type), |
||||
jsonParam = CheckRegVo( |
||||
regId = regId, result = result, |
||||
cause = cause |
||||
) |
||||
) |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,89 @@ |
||||
package com.gyf.csams.main.model |
||||
|
||||
import android.app.Application |
||||
import androidx.lifecycle.viewModelScope |
||||
import com.google.gson.reflect.TypeToken |
||||
import com.gyf.csams.module.AcceptVo |
||||
import com.gyf.csams.module.AuditVo |
||||
import com.gyf.csams.module.CheckVo |
||||
import com.gyf.csams.module.ClientType |
||||
import com.gyf.lib.model.ScrollViewModel |
||||
import com.gyf.lib.util.* |
||||
import kotlinx.coroutines.launch |
||||
import java.lang.reflect.Type |
||||
|
||||
|
||||
abstract class BaseAuditViewModel<T : AuditVo>(application: Application) : |
||||
ScrollViewModel<T>(application = application) { |
||||
|
||||
abstract val auditApi: UrlPath |
||||
abstract val acceptApi: UrlPath |
||||
abstract val checkApi: UrlPath |
||||
|
||||
abstract val typeToken: Type |
||||
|
||||
/** |
||||
* 加载审核记录 |
||||
* |
||||
* @param callback |
||||
*/ |
||||
fun load(callback: (message: String) -> Unit) { |
||||
viewModelScope.launch { |
||||
HttpClient.post( |
||||
Api.buildUrl(auditApi), HttpCallback<MutableList<T>>( |
||||
action = "加载资料", |
||||
onSuccess = { it -> |
||||
it.body?.let { |
||||
_data.postValue(it) |
||||
} |
||||
}, |
||||
typeToken = typeToken |
||||
), |
||||
jsonParam = OnlyToken(clientType = ClientType.Background) |
||||
) |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 受理资料 |
||||
* |
||||
* @param callback |
||||
*/ |
||||
fun accept(auditId: Int, callback: (message: String) -> Unit) { |
||||
viewModelScope.launch { |
||||
HttpClient.post( |
||||
Api.buildUrl(acceptApi), |
||||
HttpCallback<Boolean>(action = "受理资料", onSuccess = { |
||||
callback(it.message) |
||||
}, typeToken = object : TypeToken<ApiResponse<Boolean>>() {}.type), |
||||
jsonParam = AcceptVo(auditId = auditId, token = TokenManager.getToken()) |
||||
) |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 审核资料 |
||||
* |
||||
* @param auditId |
||||
* @param result |
||||
* @param callback |
||||
*/ |
||||
fun check(auditId: Int, cause: String, result: Boolean, callback: (message: String) -> Unit) { |
||||
viewModelScope.launch { |
||||
HttpClient.post( |
||||
Api.buildUrl(checkApi), |
||||
HttpCallback<Boolean>(action = "审核资料", onSuccess = { |
||||
callback(it.message) |
||||
}, typeToken = object : TypeToken<ApiResponse<Boolean>>() {}.type), |
||||
jsonParam = CheckVo( |
||||
auditId = auditId, |
||||
result = result, |
||||
cause = cause, |
||||
token = TokenManager.getToken() |
||||
) |
||||
) |
||||
} |
||||
} |
||||
|
||||
} |
@ -1,46 +0,0 @@ |
||||
package com.gyf.csams.main.model |
||||
|
||||
import android.app.Application |
||||
import androidx.lifecycle.viewModelScope |
||||
import com.gyf.lib.model.ApplyViewModel |
||||
import com.gyf.lib.util.ApplyActVo |
||||
import com.gyf.lib.util.format |
||||
import com.gyf.lib.util.randomChinese |
||||
import com.gyf.lib.util.randomDateTime |
||||
import kotlinx.coroutines.launch |
||||
|
||||
|
||||
/** |
||||
* 活动数据管理 |
||||
* |
||||
*/ |
||||
class CheckActViewModel(application: Application) : ApplyViewModel<ApplyActVo>(application) { |
||||
override val initSize: Int = 10 |
||||
|
||||
init { |
||||
load() |
||||
} |
||||
|
||||
fun load() { |
||||
viewModelScope.launch { |
||||
_data.value?.apply { |
||||
repeat(initSize) { |
||||
add( |
||||
ApplyActVo( |
||||
activityName = randomChinese(5), |
||||
activityTime = randomDateTime().format(), |
||||
location = randomChinese(10), |
||||
desc = randomChinese(10), |
||||
size = 10 |
||||
) |
||||
) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
fun loadMore(callback: (message: String) -> Unit) { |
||||
TODO("Not yet implemented") |
||||
} |
||||
|
||||
} |
@ -0,0 +1,96 @@ |
||||
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.core.view.WindowCompat |
||||
import androidx.lifecycle.viewmodel.compose.viewModel |
||||
import com.google.accompanist.insets.ExperimentalAnimatedInsets |
||||
import com.gyf.csams.R |
||||
import com.gyf.csams.main.model.AuditActViewModel |
||||
import com.gyf.csams.module.AuditActVo |
||||
import com.gyf.csams.uikit.BASE_HEIGHT |
||||
import com.gyf.csams.uikit.CheckForm |
||||
import com.gyf.csams.uikit.RowItem |
||||
import com.gyf.csams.uikit.TestTableImeSimple |
||||
import com.gyf.lib.uikit.ImeBody |
||||
|
||||
import com.gyf.lib.util.DateTimeUtil.datetimeFormat |
||||
import java.util.* |
||||
|
||||
/** |
||||
* 审批社团活动 |
||||
* |
||||
*/ |
||||
class AuditActActivity : ComponentActivity() { |
||||
@ExperimentalMaterialApi |
||||
@ExperimentalAnimatedInsets |
||||
@ExperimentalComposeApi |
||||
override fun onCreate(savedInstanceState: Bundle?) { |
||||
super.onCreate(savedInstanceState) |
||||
WindowCompat.setDecorFitsSystemWindows(window, false) |
||||
setContent { |
||||
ImeBody { |
||||
val model: AuditActViewModel = viewModel() |
||||
val data by model.data.observeAsState() |
||||
TestTableImeSimple( |
||||
title = R.string.activity_association |
||||
) { |
||||
data?.forEach { |
||||
item { |
||||
RegisterForm(vo = it) |
||||
CheckForm<AuditActVo, AuditActViewModel>(vo = it) |
||||
Spacer(modifier = Modifier.height(10.dp)) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
@Composable |
||||
private fun RegisterForm( |
||||
modifier: Modifier = Modifier, |
||||
vo: AuditActVo |
||||
) { |
||||
Column(modifier = modifier) { |
||||
vo.activityVo.activityTime |
||||
RowItem( |
||||
modifier = Modifier.height(BASE_HEIGHT), |
||||
key = R.string.activity_name, |
||||
value = vo.activityVo.activityName |
||||
) |
||||
RowItem( |
||||
modifier = Modifier.height(BASE_HEIGHT), |
||||
key = R.string.activity_time, |
||||
value = Date(vo.activityVo.activityTime).datetimeFormat() |
||||
) |
||||
RowItem( |
||||
modifier = Modifier.height(BASE_HEIGHT * 1.5F), |
||||
key = R.string.activity_address, |
||||
value = vo.activityVo.activityAddress |
||||
) |
||||
RowItem( |
||||
modifier = Modifier.height(BASE_HEIGHT * 3), |
||||
key = R.string.activity_desc, |
||||
value = vo.activityVo.activityDesc |
||||
) |
||||
RowItem( |
||||
modifier = Modifier.height(BASE_HEIGHT), |
||||
key = R.string.activity_size, |
||||
value = "${vo.activityVo.activitySize}" |
||||
) |
||||
} |
||||
} |
||||
} |
@ -1,92 +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.CheckActViewModel |
||||
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.ApplyActVo |
||||
import com.gyf.lib.util.BottomButton |
||||
|
||||
/** |
||||
* 审批社团活动 |
||||
* |
||||
*/ |
||||
class CheckActActivity : ComponentActivity() { |
||||
@ExperimentalAnimatedInsets |
||||
@ExperimentalComposeApi |
||||
override fun onCreate(savedInstanceState: Bundle?) { |
||||
super.onCreate(savedInstanceState) |
||||
|
||||
setContent { |
||||
TestTable( |
||||
clazz = CheckActViewModel::class.java, |
||||
title = R.string.activity_application |
||||
) { |
||||
ApplyActForm(vo = it) |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Composable |
||||
private fun ApplyActForm( |
||||
modifier: Modifier = Modifier, model: CheckActViewModel = viewModel(), |
||||
scaffoldModel: ScaffoldModel = viewModel(), vo: ApplyActVo |
||||
) { |
||||
Column(modifier = modifier) { |
||||
val baseHeight = 50.dp |
||||
RowItem( |
||||
modifier = Modifier.height(baseHeight), |
||||
key = R.string.activity_name, |
||||
value = vo.activityName |
||||
) |
||||
RowItem( |
||||
modifier = Modifier.height(baseHeight * 1.5F), |
||||
key = R.string.activity_address, |
||||
value = vo.location |
||||
) |
||||
RowItem( |
||||
modifier = Modifier.height(baseHeight * 3), |
||||
key = R.string.activity_desc, |
||||
value = vo.desc |
||||
) |
||||
RowItem( |
||||
modifier = Modifier.height(baseHeight), |
||||
key = R.string.activity_size, |
||||
value = "${vo.size}" |
||||
) |
||||
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.approveOrigin) |
||||
} |
||||
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) |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,266 @@ |
||||
package com.gyf.csams.uikit |
||||
|
||||
import androidx.annotation.StringRes |
||||
import androidx.compose.foundation.layout.* |
||||
import androidx.compose.material.ExperimentalMaterialApi |
||||
import androidx.compose.runtime.Composable |
||||
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.BaseAuditViewModel |
||||
import com.gyf.csams.module.AuditVo |
||||
import com.gyf.csams.module.Duty |
||||
import com.gyf.csams.module.ManagerVo |
||||
import com.gyf.lib.uikit.* |
||||
import com.gyf.lib.util.BottomButton |
||||
import com.gyf.lib.util.TokenManager |
||||
|
||||
val BASE_HEIGHT = 50.dp |
||||
|
||||
@ExperimentalMaterialApi |
||||
@ExperimentalAnimatedInsets |
||||
@Composable |
||||
inline fun <reified T : AuditVo, reified E : BaseAuditViewModel<T>> ContentCheckForm( |
||||
@StringRes title: Int, |
||||
crossinline RegisterForm: @Composable (vo: T) -> Unit |
||||
) { |
||||
ImeBody { |
||||
val model: E = viewModel() |
||||
val data by model.data.observeAsState() |
||||
TestTableImeSimple( |
||||
title = title |
||||
) { |
||||
data?.forEach { |
||||
item { |
||||
RegisterForm(vo = it) |
||||
CheckForm<T, E>(vo = it) |
||||
Spacer(modifier = Modifier.height(10.dp)) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 表格审核组件 |
||||
* |
||||
* @param VO |
||||
* @param M |
||||
* @param vo |
||||
* @param scaffoldModel |
||||
* @param model |
||||
* @param first |
||||
* @param last |
||||
*/ |
||||
@Composable |
||||
inline fun <reified VO : AuditVo, reified M : BaseAuditViewModel<VO>> CheckForm( |
||||
vo: VO, |
||||
scaffoldModel: ScaffoldModel = viewModel(), |
||||
model: M = viewModel(), |
||||
first: @Composable () -> Unit = { |
||||
RowItem( |
||||
modifier = Modifier.height(BASE_HEIGHT), |
||||
key = R.string.first_approver, |
||||
value = vo.audit.manager?.name ?: "" |
||||
) |
||||
}, |
||||
last: @Composable () -> Unit = { |
||||
RowItem( |
||||
modifier = Modifier.height(BASE_HEIGHT), |
||||
key = R.string.last_approver, |
||||
value = vo.audit.nextAudit?.manager?.name ?: "" |
||||
) |
||||
} |
||||
) { |
||||
|
||||
|
||||
(TokenManager.getOwnInfo() as? ManagerVo)?.let { it -> |
||||
var confirmDesc: Int? = null |
||||
var backDesc: Int? = null |
||||
var onConfirm: (() -> Unit)? = null |
||||
var onBack: (() -> Unit)? = null |
||||
val check: (result: Boolean, cause: StringForm) -> Unit = |
||||
{ result: Boolean, cause: StringForm -> |
||||
scaffoldModel.update( |
||||
message = "确认${if (result) "上报" else "驳回"}?", |
||||
actionLabel = "确认" |
||||
) { |
||||
model.check( |
||||
auditId = vo.audit.id, |
||||
result = result, |
||||
cause = cause.formValue.value |
||||
?: throw IllegalArgumentException("无法获取审核理由") |
||||
) { |
||||
scaffoldModel.update(message = it, actionLabel = "刷新") { |
||||
model.load { } |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
val accept: (m: String) -> Unit = |
||||
{ m: String -> |
||||
scaffoldModel.update("确认${m}?", actionLabel = "确认") { |
||||
model.accept( |
||||
auditId = vo.audit.id |
||||
) { |
||||
scaffoldModel.update(message = it, actionLabel = "刷新") { |
||||
model.load { } |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
val doCheck: @Composable () -> Unit = { |
||||
val cause = ValidStringForm( |
||||
formDesc = "审核理由", |
||||
textLength = 20 |
||||
) |
||||
val statusForm by cause.statusForm.observeAsState() |
||||
|
||||
onConfirm = { |
||||
if (statusForm == FormStatus.Empty) { |
||||
scaffoldModel.update("${cause.formDesc}不能为空", actionLabel = "知道了") |
||||
} else { |
||||
check(true, cause) |
||||
} |
||||
} |
||||
onBack = { |
||||
if (statusForm == FormStatus.Empty) { |
||||
scaffoldModel.update("${cause.formDesc}不能为空", actionLabel = "知道了") |
||||
} else { |
||||
check(false, cause) |
||||
} |
||||
} |
||||
|
||||
Row( |
||||
modifier = Modifier.fillMaxWidth(), |
||||
horizontalArrangement = Arrangement.Center |
||||
) { |
||||
BaseTextField( |
||||
form = cause |
||||
) |
||||
} |
||||
} |
||||
|
||||
when { |
||||
//初审记录,负责人为空 等待初审 |
||||
vo.audit.nextAudit == null && vo.audit.manager == null -> { |
||||
if (it.duty == Duty.PamphaBhusal) { |
||||
confirmDesc = R.string.accept_btn |
||||
onConfirm = { accept("受理") } |
||||
} |
||||
first() |
||||
RowItem(key = R.string.first_approver_origin, value = "") |
||||
RowItem(key = R.string.first_result, value = "") |
||||
last() |
||||
RowItem(key = R.string.last_approver_origin, value = "") |
||||
RowItem(key = R.string.last_result, value = "") |
||||
RowItem( |
||||
modifier = Modifier.height(BASE_HEIGHT), |
||||
key = R.string.audit_phases, value = "等待初审" |
||||
) |
||||
} |
||||
//初审记录,负责人不为空 初审受理 |
||||
vo.audit.nextAudit == null && vo.audit.manager != null -> { |
||||
|
||||
first() |
||||
if (it.duty == Duty.PamphaBhusal) { |
||||
confirmDesc = R.string.reported_btn |
||||
backDesc = R.string.reject_btn |
||||
|
||||
doCheck() |
||||
} else { |
||||
RowItem(key = R.string.first_approver_origin, value = "") |
||||
} |
||||
RowItem(key = R.string.first_result, value = "") |
||||
last() |
||||
RowItem(key = R.string.last_approver_origin, value = "") |
||||
RowItem(key = R.string.last_result, value = "") |
||||
RowItem( |
||||
modifier = Modifier.height(BASE_HEIGHT), |
||||
key = R.string.audit_phases, value = "初审受理" |
||||
) |
||||
} |
||||
//初审记录,审核通过(上报) 等待复审 |
||||
vo.audit.nextAudit != null && vo.audit.nextAudit?.manager == null -> { |
||||
|
||||
if (it.duty == Duty.Teacher) { |
||||
confirmDesc = R.string.recheck_btn |
||||
onConfirm = { accept("复审") } |
||||
} |
||||
first() |
||||
RowItem(key = R.string.first_approver_origin, value = vo.audit.cause) |
||||
RowItem(key = R.string.first_result, value = "通过") |
||||
last() |
||||
RowItem(key = R.string.last_approver_origin, value = "") |
||||
RowItem(key = R.string.last_result, value = "") |
||||
RowItem( |
||||
modifier = Modifier.height(BASE_HEIGHT), |
||||
key = R.string.audit_phases, value = "等待复审" |
||||
) |
||||
} |
||||
//复审记录,审核结果为空 复审受理 |
||||
vo.audit.nextAudit != null && vo.audit.nextAudit?.result == null -> { |
||||
first() |
||||
RowItem(key = R.string.first_approver_origin, value = vo.audit.cause) |
||||
RowItem(key = R.string.first_result, value = "通过") |
||||
last() |
||||
if (it.duty == Duty.Teacher) { |
||||
confirmDesc = R.string.allow_btn |
||||
backDesc = R.string.reject_btn |
||||
doCheck() |
||||
} else { |
||||
RowItem(key = R.string.last_approver_origin, value = "") |
||||
} |
||||
RowItem(key = R.string.last_result, value = "") |
||||
RowItem( |
||||
modifier = Modifier.height(BASE_HEIGHT), |
||||
key = R.string.audit_phases, value = "复审受理" |
||||
) |
||||
} |
||||
else -> { |
||||
first() |
||||
RowItem(key = R.string.first_approver_origin, value = vo.audit.cause) |
||||
RowItem( |
||||
key = R.string.first_result, value = when (vo.audit.result) { |
||||
null -> "" |
||||
true -> "通过" |
||||
false -> "不通过" |
||||
} |
||||
) |
||||
last() |
||||
RowItem( |
||||
key = R.string.last_approver_origin, |
||||
value = vo.audit.nextAudit?.cause ?: "" |
||||
) |
||||
RowItem( |
||||
key = R.string.last_result, value = when (vo.audit.nextAudit?.result) { |
||||
null -> "" |
||||
true -> "通过" |
||||
false -> "不通过" |
||||
} |
||||
) |
||||
RowItem( |
||||
modifier = Modifier.height(BASE_HEIGHT), |
||||
key = R.string.audit_phases, value = "完成审核" |
||||
) |
||||
} |
||||
} |
||||
|
||||
if (confirmDesc != null) { |
||||
BottomButton( |
||||
confirmDesc = confirmDesc, |
||||
backDesc = backDesc, |
||||
modifier = Modifier.fillMaxWidth(), |
||||
onBack = onBack |
||||
) { |
||||
onConfirm?.let { it() } |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,9 @@ |
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:width="64dp" |
||||
android:height="64dp" |
||||
android:viewportWidth="1024" |
||||
android:viewportHeight="1024"> |
||||
<path |
||||
android:fillColor="#FF000000" |
||||
android:pathData="M512,149.33c200.3,0 362.67,162.37 362.67,362.67s-162.37,362.67 -362.67,362.67S149.33,712.3 149.33,512 311.7,149.33 512,149.33zM512,213.33c-164.95,0 -298.67,133.72 -298.67,298.67s133.72,298.67 298.67,298.67 298.67,-133.72 298.67,-298.67 -133.72,-298.67 -298.67,-298.67zM544,291.82v201.13h140.76v64L512,556.95a32,32 0,0 1,-32 -32L480,291.84h64z" /> |
||||
</vector> |
@ -0,0 +1,53 @@ |
||||
package com.gyf.lib.util |
||||
|
||||
import java.sql.Timestamp |
||||
import java.text.SimpleDateFormat |
||||
import java.util.* |
||||
|
||||
object DateTimeUtil { |
||||
|
||||
const val DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm" |
||||
|
||||
|
||||
const val DATE_FORMAT = "yyyy-MM-dd" |
||||
|
||||
const val TIME_FORMAT = "HH:mm" |
||||
|
||||
const val DATETIME_FORMAT = "yyyy-MM-dd HH:mm" |
||||
|
||||
const val START_TIME = "2021-01-01 00:00" |
||||
|
||||
fun String.toTimeStamp(pattern: String = DATE_TIME_FORMAT): Timestamp { |
||||
return Timestamp(this.toDate(pattern).time) |
||||
} |
||||
|
||||
fun String.toDate(pattern: String = DATE_TIME_FORMAT): Date { |
||||
return SimpleDateFormat(pattern, Locale.CHINA).parse(this) |
||||
?: throw IllegalArgumentException("日期字符串按[$pattern]转换失败") |
||||
} |
||||
|
||||
|
||||
val startUnix = SimpleDateFormat(DATETIME_FORMAT, Locale.CHINA).parse(START_TIME)?.time |
||||
|
||||
fun randomDateTime(): Date { |
||||
if (startUnix != null) { |
||||
return Date("${(startUnix..Date().time).random()}".toLong()) |
||||
} else { |
||||
throw IllegalArgumentException("生成随机失败,无法获取起始时间") |
||||
} |
||||
} |
||||
|
||||
|
||||
fun Date.datetimeFormat(): String { |
||||
return SimpleDateFormat(DATETIME_FORMAT, Locale.CHINA).format(this) |
||||
} |
||||
|
||||
|
||||
fun Date.dateFormat(): String { |
||||
return SimpleDateFormat(DATE_FORMAT, Locale.CHINA).format(this) |
||||
} |
||||
|
||||
fun Date.timeFormat(): String { |
||||
return SimpleDateFormat(TIME_FORMAT, Locale.CHINA).format(this) |
||||
} |
||||
} |
@ -1,527 +0,0 @@ |
||||
package com.gyf.lib.util |
||||
|
||||
import androidx.annotation.IntRange |
||||
import com.gyf.lib.uikit.StringForm |
||||
import java.util.* |
||||
|
||||
/** |
||||
* 一般信息 |
||||
* |
||||
*/ |
||||
abstract class PersonInfoVo { |
||||
abstract val name: String |
||||
abstract val headImg: String? |
||||
abstract val desc: String |
||||
} |
||||
|
||||
|
||||
enum class Duty(val desc: String, val level: Int) { |
||||
|
||||
Teacher("老师", 1), |
||||
PamphaBhusal("总部长", 2), |
||||
SecretaryOfTheMinister("秘书部部长", 3), |
||||
PropagandaDepartment("宣传部部长", 3), |
||||
LiaisonMinister("外联部部长", 3), |
||||
SecretaryDepartmentOfficer("秘书部干事", 4), |
||||
PublicityDepartmentOfficer("宣传部干事", 4), |
||||
LiaisonOfficer("外联部干事", 4); |
||||
|
||||
|
||||
/** |
||||
* 是否是部门部长 |
||||
* |
||||
*/ |
||||
fun isMinister(): Boolean { |
||||
return minister.contains(this) |
||||
} |
||||
|
||||
fun isOfficer(): Boolean { |
||||
return officer.contains(this) |
||||
} |
||||
|
||||
} |
||||
|
||||
private val minister = |
||||
arrayOf(Duty.SecretaryOfTheMinister, Duty.LiaisonMinister, Duty.PropagandaDepartment) |
||||
private val officer = |
||||
arrayOf(Duty.SecretaryDepartmentOfficer, Duty.PublicityDepartmentOfficer, Duty.LiaisonOfficer) |
||||
|
||||
/** |
||||
* 个人信息 |
||||
* |
||||
*/ |
||||
abstract class OwnInfoVo : PersonInfoVo() { |
||||
abstract val token: Token |
||||
} |
||||
|
||||
data class ManagerInfoVo( |
||||
val duty: Duty, |
||||
override val name: String, |
||||
override val headImg: String?, |
||||
override val desc: String |
||||
) : PersonInfoVo() |
||||
|
||||
data class UserInfoVo( |
||||
override val name: String, |
||||
override val headImg: String?, |
||||
override val desc: String |
||||
) : PersonInfoVo() |
||||
|
||||
|
||||
/** |
||||
* 管理员个人信息 |
||||
* |
||||
* @property account 管理员账号 |
||||
* @property name 姓名 |
||||
* @property duty 职务 |
||||
* @property headImg 头像 |
||||
* @property desc 个人简介 |
||||
*/ |
||||
data class ManagerVo( |
||||
val account: String, |
||||
val duty: Duty, |
||||
override val token: Token, |
||||
override val name: String, |
||||
override val headImg: String?, |
||||
override val desc: String |
||||
) : OwnInfoVo() |
||||
|
||||
|
||||
/** |
||||
* 用户个人信息 |
||||
* |
||||
* @property studentId 学号 |
||||
* @property name 姓名 |
||||
* @property headImg 头像 |
||||
* @property desc 个人简介 |
||||
*/ |
||||
data class UserVo( |
||||
val studentId: String, |
||||
val manager: ManagerVo? = null, |
||||
override val token: Token, |
||||
override val name: String, |
||||
override val headImg: String?, |
||||
override val desc: String, |
||||
val associationVo: AssociationVo?, |
||||
val isHead: Boolean? |
||||
) : OwnInfoVo() |
||||
|
||||
data class PageDto(val currentPage: Long, val pageSize: Int = 10) |
||||
|
||||
data class NotificationDto( |
||||
val receiverId: Int, |
||||
val receiverClient: ClientType, |
||||
val page: PageDto? = null, |
||||
override val clientType: ClientType = receiverClient |
||||
) : ClientBaseVo() |
||||
|
||||
data class UserRegVo(val studentId: String, val name: String) |
||||
|
||||
/** |
||||
* 客户端类型 |
||||
* |
||||
*/ |
||||
enum class ClientType { |
||||
//前台 |
||||
Foreground, |
||||
|
||||
//后台 |
||||
Background |
||||
} |
||||
|
||||
|
||||
data class NotificationVo(val title: String, val content: String, val id: Int, val createTime: Long) |
||||
|
||||
|
||||
/** |
||||
* 响应自动生成密码 |
||||
* |
||||
* @property password |
||||
*/ |
||||
data class UserPasswordVo(val password: String) |
||||
|
||||
|
||||
/** |
||||
* 用户登陆表单 |
||||
* |
||||
* @property studentId 学号 |
||||
* @property password 密码 |
||||
* @property device 设备型号 |
||||
*/ |
||||
data class UserLoginVo(val studentId: String, val password: String, val device: String) |
||||
|
||||
|
||||
/** |
||||
* |
||||
* @property associationName 社团名字 |
||||
* @property activityName 活动名 |
||||
* @property activityTime 活动时间 |
||||
* @property activityLocation 活动地点 |
||||
* @property activityDesc 活动介绍 |
||||
*/ |
||||
data class ActivityDetailVo( |
||||
val associationName: String, val activityName: String, |
||||
val activityTime: Date, val activityLocation: String, |
||||
val activityDesc: String |
||||
) |
||||
|
||||
/** |
||||
* 图片 |
||||
* @property name 文件名 |
||||
* @property size 文件大小 |
||||
* @property url 文件路径 |
||||
* @property md5 文件hash |
||||
* @property createTime 文件创建时间 |
||||
* @property studentId 文件上传人 |
||||
*/ |
||||
data class ActivityPhotoVo( |
||||
val name: String, |
||||
val size: Long, |
||||
val url: String, |
||||
val md5: String, |
||||
val createTime: Date, |
||||
val studentId: String |
||||
) |
||||
|
||||
const val MAX_SCORE = 5L |
||||
|
||||
data class ActivityVo( |
||||
val activityId: Long, val activityName: String, val association: String, |
||||
@IntRange(from = 1, to = MAX_SCORE) val score: Int, val activityTime: Date, val location: String |
||||
) |
||||
|
||||
|
||||
data class AllOfficerVo( |
||||
val secretariat: MutableList<ManagerInfoVo>, |
||||
val propaganda: MutableList<ManagerInfoVo>, |
||||
val publicRelationsDepartment: MutableList<ManagerInfoVo> |
||||
) |
||||
|
||||
|
||||
data class ApplyActVo( |
||||
val activityName: String, val activityTime: String, |
||||
val location: String, val desc: String, |
||||
val size: Int |
||||
) |
||||
|
||||
data class LeaveMessageVo( |
||||
val message: String, |
||||
override val clientType: ClientType = ClientType.Foreground |
||||
) : ClientBaseVo() |
||||
|
||||
/** |
||||
* 社团级别 |
||||
* |
||||
*/ |
||||
enum class AssociationLevel { |
||||
A, |
||||
B, |
||||
C, |
||||
D |
||||
} |
||||
|
||||
/** |
||||
* 所属院系 |
||||
* |
||||
*/ |
||||
enum class AssociationFaculty(val desc: String, val range: kotlin.ranges.IntRange) { |
||||
ForeignLanguageDept("外语系", 0..0), |
||||
CivilEngineeringDept("土木工程", 1..10), |
||||
SEM("经理管理学院", 11..20), |
||||
MechanicalEngineeringDept("机械工程", 21..30), |
||||
TransportationDept("交通运输", 31..40), |
||||
ArchitectureAndArts("建筑与艺术", 41..50), |
||||
ElectricalDept("电气", 51..60), |
||||
MaterialsDept("材料", 61..70), |
||||
MessageDept("信息", 71..80), |
||||
MathematicsDept("数理", 81..90), |
||||
GraduateStudent("研究生", 91..99) |
||||
} |
||||
|
||||
abstract class BaseAssociationVo { |
||||
abstract val associationId: Int |
||||
abstract val name: String |
||||
abstract val desc: String |
||||
abstract val logo: String |
||||
abstract val faculty: AssociationFaculty |
||||
abstract val level: AssociationLevel? |
||||
} |
||||
|
||||
/** |
||||
* 社团列表 |
||||
* |
||||
*/ |
||||
class AssociationVo( |
||||
override val associationId: Int, |
||||
override val name: String, |
||||
override val desc: String, |
||||
override val logo: String, |
||||
override val faculty: AssociationFaculty, |
||||
override val level: AssociationLevel? |
||||
) : BaseAssociationVo() |
||||
|
||||
//审核状态 |
||||
enum class CheckStatus(val desc: String) { |
||||
WaitFirst("等待初审"), |
||||
AcceptFirst("初审受理"), |
||||
WaitLast("等待复审"), |
||||
AcceptLast("复审受理"), |
||||
Finish("审核完成") |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 活动照片 |
||||
* |
||||
* @property path |
||||
*/ |
||||
data class AssociationActPhotoVo(val path: String) |
||||
|
||||
data class AssociationMainVo( |
||||
val associationVo: AssociationVo, val head: UserInfoVo, |
||||
val photos: List<AssociationActPhotoVo>? = null |
||||
) |
||||
|
||||
data class AuditCheckVo( |
||||
val checkStatus: CheckStatus, val applyTime: Long, |
||||
val firstCause: String, val lastCause: String? |
||||
) |
||||
|
||||
//前台社团注册资料 |
||||
data class AssociationCheckVo( |
||||
override val associationId: Int, |
||||
override val name: String, |
||||
override val desc: String, |
||||
override val logo: String, |
||||
override val faculty: AssociationFaculty, |
||||
override val level: AssociationLevel?, |
||||
val fileId: Int, |
||||
val auditCheckVo: AuditCheckVo |
||||
) : BaseAssociationVo() |
||||
|
||||
/** |
||||
* 搜索社团 |
||||
* |
||||
* @property name |
||||
* @property desc |
||||
* @property clientType |
||||
*/ |
||||
data class SearchAssociationVo( |
||||
val name: String, val desc: String, |
||||
override val clientType: ClientType = ClientType.Foreground |
||||
) : ClientBaseVo() |
||||
|
||||
data class ShowAssociationVo( |
||||
val id: Int, |
||||
override val clientType: ClientType = ClientType.Foreground |
||||
) : ClientBaseVo() |
||||
|
||||
|
||||
data class QueryAssociationMembers( |
||||
val id: Int, |
||||
val name: String? = null, |
||||
override val clientType: ClientType = ClientType.Foreground |
||||
) : ClientBaseVo() |
||||
|
||||
data class BBSVo(val studentId: String, val name: String, val createTime: Date, val content: String) |
||||
|
||||
|
||||
/** |
||||
* 题型 |
||||
* |
||||
*/ |
||||
enum class ExamType(val type: String) { |
||||
//选择题 |
||||
CQ("选择题"), |
||||
|
||||
//开放题 |
||||
OQ("开放题") |
||||
} |
||||
|
||||
abstract class Exam { |
||||
abstract val examType: ExamType |
||||
abstract val question: StringForm |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 选择题 |
||||
* |
||||
* @property examType 题型描述 |
||||
* @property answers 答案 |
||||
* @property rightAnswer 正确答案 |
||||
* @property question 问题 |
||||
*/ |
||||
data class ChoiceQuestionVo( |
||||
override val examType: ExamType = ExamType.CQ, |
||||
val answers: List<StringForm>, |
||||
val rightAnswer: Int, |
||||
override val question: StringForm |
||||
) : Exam() |
||||
|
||||
|
||||
data class HistoryActVo(val name: String) |
||||
|
||||
|
||||
/** |
||||
* 开放题 |
||||
* |
||||
* @property examType 题型描述 |
||||
* @property question 问题 |
||||
*/ |
||||
data class OpenQuestionsVo( |
||||
override val examType: ExamType = ExamType.OQ, override val question: StringForm |
||||
) : Exam() |
||||
|
||||
|
||||
data class LeaveMessageFormatVo(val message: String, val user: UserInfoVo) |
||||
|
||||
|
||||
data class ManagerLoginVo(val account: String, val password: String, val device: String) |
||||
|
||||
data class OngoingActVo(val name: String) |
||||
|
||||
/** |
||||
* 活动质量汇报单 |
||||
* |
||||
* @property applyName 申请人 |
||||
* @property activityName 活动名称 |
||||
* @property merit 优点 |
||||
* @property defect 缺点 |
||||
* @property score 星级评价 |
||||
*/ |
||||
data class QualityReportVo( |
||||
val applyName: String, |
||||
val activityName: String, |
||||
val merit: String, |
||||
val defect: String, |
||||
@IntRange(from = 1L, to = MAX_SCORE) val score: Int |
||||
) |
||||
|
||||
/** |
||||
* 社团注册资料表单 |
||||
* |
||||
* @property name |
||||
* @property desc |
||||
* @property fileId |
||||
*/ |
||||
data class AssociationRegVo( |
||||
val associationId: Int?, val name: String, val desc: String, val fileId: Int, |
||||
override val clientType: ClientType = ClientType.Foreground |
||||
) : ClientBaseVo() |
||||
|
||||
|
||||
abstract class AuditVo { |
||||
abstract val audit: AuditLoggingVo |
||||
} |
||||
|
||||
/** |
||||
* 社团注册审核记录 |
||||
* |
||||
*/ |
||||
data class AuditAssociationVo( |
||||
val name: String, |
||||
val desc: String, |
||||
val logo: String, |
||||
override val audit: AuditLoggingVo |
||||
) : AuditVo() |
||||
|
||||
/** |
||||
* 通用审核记录 |
||||
* |
||||
* @property id |
||||
* @property user |
||||
* @property applyTime |
||||
* @property manager |
||||
* @property acceptTime |
||||
* @property cause |
||||
* @property result |
||||
* @property auditTime |
||||
* @property nextAudit |
||||
*/ |
||||
data class AuditLoggingVo( |
||||
val id: Int, val user: UserInfoVo, val applyTime: Long, val manager: ManagerInfoVo?, |
||||
val acceptTime: Long?, val cause: String?, val result: Boolean?, |
||||
val auditTime: Long?, val nextAudit: AuditLoggingVo? |
||||
) |
||||
|
||||
/** |
||||
* 社团注册资料受理 |
||||
* |
||||
* @property auditId |
||||
* @property clientType |
||||
*/ |
||||
data class AcceptVo( |
||||
val auditId: Int, |
||||
override val clientType: ClientType = ClientType.Background |
||||
) : ClientBaseVo() |
||||
|
||||
/** |
||||
* 社团注册资料审核 |
||||
* |
||||
* @property auditId |
||||
* @property result |
||||
* @property cause |
||||
* @property clientType |
||||
*/ |
||||
data class CheckVo( |
||||
val auditId: Int, val result: Boolean, val cause: String, |
||||
override val clientType: ClientType = ClientType.Background |
||||
) : ClientBaseVo() |
||||
|
||||
|
||||
/** |
||||
* 前台活动申请书 |
||||
* |
||||
* @property activityId |
||||
* @property activityName |
||||
* @property activityTime |
||||
* @property activityAddress |
||||
* @property activityDesc |
||||
* @property activitySize |
||||
* @property clientType |
||||
*/ |
||||
data class ActivityApplyVo( |
||||
val activityId: Int?, val associationId: Int, |
||||
val activityName: String, val activityTime: Long, |
||||
val activityAddress: String, |
||||
val activityDesc: String, val activitySize: Int, |
||||
override val clientType: ClientType = ClientType.Foreground |
||||
) : ClientBaseVo() |
||||
|
||||
/** |
||||
* 后台活动申请书 |
||||
* |
||||
* @property auditId |
||||
* @property activityName |
||||
* @property activityTime |
||||
* @property activityAddress |
||||
* @property activityDesc |
||||
* @property activitySize |
||||
*/ |
||||
data class AuditActVo( |
||||
val auditId: Int, val activityName: String, val activityTime: Long, |
||||
val activityAddress: String, |
||||
val activityDesc: String, val activitySize: Int, |
||||
override val audit: AuditLoggingVo |
||||
) : AuditVo() |
||||
|
||||
/** |
||||
* 换名申请表 |
||||
* |
||||
* @property studentId 学号 |
||||
* @property oldName 社团原名 |
||||
* @property newName 社团新名 |
||||
* @property reason 申请理由 |
||||
*/ |
||||
data class RenameVo( |
||||
val studentId: String, |
||||
val oldName: String, |
||||
val newName: String, |
||||
val reason: String |
||||
) |
||||
|
||||
abstract class ClientBaseVo { |
||||
val token: Token = TokenManager.getToken() |
||||
abstract val clientType: ClientType |
||||
} |
@ -1,4 +1,5 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
<integer name="activity_size">20</integer> |
||||
<integer name="name_length">4</integer> |
||||
</resources> |
@ -1,4 +1,5 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
<integer name="activity_size">20</integer> |
||||
<integer name="name_length">4</integer> |
||||
</resources> |
@ -1,4 +1,5 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
<integer name="activity_size">20</integer> |
||||
<integer name="name_length">4</integer> |
||||
</resources> |
Loading…
Reference in new issue