diff --git a/background/src/main/AndroidManifest.xml b/background/src/main/AndroidManifest.xml
index 5528c76..a4efbc5 100644
--- a/background/src/main/AndroidManifest.xml
+++ b/background/src/main/AndroidManifest.xml
@@ -4,6 +4,8 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/background/src/main/java/com/gyf/csams/InitActivity.kt b/background/src/main/java/com/gyf/csams/InitActivity.kt
index 46e03f5..14ed4d7 100644
--- a/background/src/main/java/com/gyf/csams/InitActivity.kt
+++ b/background/src/main/java/com/gyf/csams/InitActivity.kt
@@ -1,14 +1,20 @@
package com.gyf.csams
import android.app.Activity
+import com.google.gson.reflect.TypeToken
import com.gyf.csams.account.ui.LoginActivity
import com.gyf.csams.main.ui.MainActivity
import com.gyf.lib.uikit.AbstractInitActivity
import com.gyf.lib.util.AccountApi
+import com.gyf.lib.util.ApiResponse
+import com.gyf.lib.util.ManagerVo
+import java.lang.reflect.Type
-class InitActivity : AbstractInitActivity() {
+class InitActivity : AbstractInitActivity() {
override val main: Class = MainActivity::class.java
override val login: Class = LoginActivity::class.java
override val api: AccountApi = AccountApi.BackgroundToken
+
+ override val typeToken: Type = object : TypeToken>() {}.type
}
\ No newline at end of file
diff --git a/background/src/main/java/com/gyf/csams/account/model/LoginViewModel.kt b/background/src/main/java/com/gyf/csams/account/model/LoginViewModel.kt
index 1aa1c2a..edddac8 100644
--- a/background/src/main/java/com/gyf/csams/account/model/LoginViewModel.kt
+++ b/background/src/main/java/com/gyf/csams/account/model/LoginViewModel.kt
@@ -9,8 +9,7 @@ import com.gyf.lib.uikit.FormStatus
import com.gyf.lib.uikit.ValidStringForm
import com.gyf.lib.util.AccountApi
import com.gyf.lib.util.ClientType
-
-data class ManagerVo(val account: String, val password: String, val device: String)
+import com.gyf.lib.util.ManagerLoginVo
class LoginViewModel(application: Application) : AbstractLoginViewModel(application) {
override val id = ValidStringForm(formDesc = "管理帐号", textLength = 8)
@@ -25,7 +24,7 @@ class LoginViewModel(application: Application) : AbstractLoginViewModel(applicat
override fun loginParam(): Any {
val account = "${id.formValue.value}"
val password = "${password.formValue.value}"
- return ManagerVo(
+ return ManagerLoginVo(
account = account,
password = password,
device = "${Build.MANUFACTURER} ${Build.MODEL}"
diff --git a/background/src/main/java/com/gyf/csams/main/model/AssociationManagementViewModel.kt b/background/src/main/java/com/gyf/csams/main/model/AssociationManagementViewModel.kt
index 7b5370d..0f12568 100644
--- a/background/src/main/java/com/gyf/csams/main/model/AssociationManagementViewModel.kt
+++ b/background/src/main/java/com/gyf/csams/main/model/AssociationManagementViewModel.kt
@@ -1,49 +1,12 @@
package com.gyf.csams.main.model
import android.app.Application
-import androidx.lifecycle.viewModelScope
import com.gyf.lib.model.ScrollViewModel
-import com.gyf.lib.util.randomChinese
-import kotlinx.coroutines.launch
+import com.gyf.lib.util.AssociationLevel
+import com.gyf.lib.util.AssociationVo
-/**
- * 社团级别
- *
- */
-enum class AssociationLevel {
- A,
- B,
- C,
- D
-}
-/**
- * 所属院系
- *
- */
-enum class AssociationFaculty(val desc: String, val range: 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)
-}
-/**
- * 社团
- *
- * @property name 社团名称
- */
-data class AssociationVo(
- val associationId: Long, val name: String, val commander: String,
- val faculty: AssociationFaculty, val level: AssociationLevel, val desc: String
-)
/**
* 数据状态管理
@@ -59,22 +22,7 @@ class AssociationManagementViewModel(application: Application) : ScrollViewModel
}
override fun load() {
- viewModelScope.launch {
- _data.value?.apply {
- repeat(initSize) {
- add(
- AssociationVo(
- associationId = (0..65535L).random(),
- name = randomChinese(5),
- commander = randomChinese(3),
- faculty = AssociationFaculty.values().random(),
- level = AssociationLevel.values().random(),
- desc = randomChinese(20)
- )
- )
- }
- }
- }
+ TODO()
}
override fun loadMore(callback: (message: String) -> Unit) {
@@ -82,18 +30,10 @@ class AssociationManagementViewModel(application: Application) : ScrollViewModel
}
/**
- * TODO 更新社团级别
*
* @param level
*/
- fun update(associationVo: AssociationVo, level: AssociationLevel) {
- _data.value?.apply {
- val i = indexOf(associationVo)
- set(i, associationVo.copy(level = level))
- val new = mutableListOf()
- new.addAll(this)
- clear()
- _data.postValue(new)
- }
+ fun update(associationDto: AssociationVo, level: AssociationLevel) {
+ TODO("更新社团级别")
}
}
\ No newline at end of file
diff --git a/background/src/main/java/com/gyf/csams/main/model/AuditAssociationViewModel.kt b/background/src/main/java/com/gyf/csams/main/model/AuditAssociationViewModel.kt
new file mode 100644
index 0000000..347dfdc
--- /dev/null
+++ b/background/src/main/java/com/gyf/csams/main/model/AuditAssociationViewModel.kt
@@ -0,0 +1,81 @@
+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
+
+
+class AuditAssociationViewModel(application: Application) : ScrollViewModel(
+ application
+) {
+ override val initSize: Int = 10
+
+ init {
+ load { }
+ }
+
+ override fun load(callback: (message: String) -> Unit) {
+ viewModelScope.launch {
+ HttpClient.post(
+ Api.buildUrl(AssociationApi.Audit), HttpCallback>(
+ action = "获取审核列表",
+ onSuccess = { it ->
+ it.body?.let {
+ _data.postValue(it)
+ }
+ },
+ typeToken = object :
+ TypeToken>>() {}.type
+ ),
+ jsonParam = OnlyToken(clientType = ClientType.Background)
+ )
+ }
+ }
+
+ override fun loadMore(callback: (message: String) -> Unit) {
+ TODO("Not yet implemented")
+ }
+
+
+ /**
+ * 受理注册资料
+ *
+ * @param callback
+ */
+ fun accept(regId: Int, isFirstAccept: Boolean, callback: (message: String) -> Unit) {
+ viewModelScope.launch {
+ HttpClient.post(
+ Api.buildUrl(AssociationApi.Accept),
+ HttpCallback(action = "受理社团注册资料", onSuccess = {
+ callback(it.message)
+ }, typeToken = object : TypeToken>() {}.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(action = "提交审核结果", onSuccess = {
+ callback(it.message)
+ }, typeToken = object : TypeToken>() {}.type),
+ jsonParam = CheckRegVo(
+ regId = regId, result = result,
+ cause = cause
+ )
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/background/src/main/java/com/gyf/csams/main/model/BackgroundViewModel.kt b/background/src/main/java/com/gyf/csams/main/model/BackgroundViewModel.kt
new file mode 100644
index 0000000..f691b3c
--- /dev/null
+++ b/background/src/main/java/com/gyf/csams/main/model/BackgroundViewModel.kt
@@ -0,0 +1,11 @@
+package com.gyf.csams.main.model
+
+import android.app.Application
+import com.gyf.lib.model.SysMessageViewModel
+import com.gyf.lib.util.ClientType
+
+class BackgroundViewModel(application: Application) : SysMessageViewModel(application) {
+ override fun clientType(): ClientType {
+ return ClientType.Background
+ }
+}
\ No newline at end of file
diff --git a/background/src/main/java/com/gyf/csams/main/model/CheckActViewModel.kt b/background/src/main/java/com/gyf/csams/main/model/CheckActViewModel.kt
index ef4735c..f43d15f 100644
--- a/background/src/main/java/com/gyf/csams/main/model/CheckActViewModel.kt
+++ b/background/src/main/java/com/gyf/csams/main/model/CheckActViewModel.kt
@@ -3,17 +3,12 @@ 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
-data class ApplyActVo(
- val activityName: String, val activityTime: String,
- val location: String, val desc: String,
- val size: Int
-)
-
/**
* 活动数据管理
diff --git a/background/src/main/java/com/gyf/csams/main/model/CheckQualityReportViewModel.kt b/background/src/main/java/com/gyf/csams/main/model/CheckQualityReportViewModel.kt
index e6b0f27..06972a4 100644
--- a/background/src/main/java/com/gyf/csams/main/model/CheckQualityReportViewModel.kt
+++ b/background/src/main/java/com/gyf/csams/main/model/CheckQualityReportViewModel.kt
@@ -1,31 +1,13 @@
package com.gyf.csams.main.model
import android.app.Application
-import androidx.annotation.IntRange
import androidx.lifecycle.viewModelScope
import com.gyf.lib.model.ApplyViewModel
+import com.gyf.lib.util.QualityReportVo
import com.gyf.lib.util.randomChinese
import kotlinx.coroutines.launch
-const val MAX_SCORE = 5L
-
-/**
- * 活动质量汇报单
- *
- * @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
-)
/**
* 活动质量汇报单评价
diff --git a/background/src/main/java/com/gyf/csams/main/model/MainViewModel.kt b/background/src/main/java/com/gyf/csams/main/model/MainViewModel.kt
deleted file mode 100644
index 26f2166..0000000
--- a/background/src/main/java/com/gyf/csams/main/model/MainViewModel.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.gyf.csams.main.model
-
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.ViewModel
-import com.gyf.lib.uikit.PersonInfoVo
-import com.gyf.lib.util.randomChinese
-
-/**
- * 部长
- *
- * @property name 姓名
- * @property duty 职务
- * @property headImg 头像
- * @property desc 个人简介
- */
-data class MinisterVo(
- override val name: String,
- override val duty: String,
- override val headImg: String,
- override val desc: String
-) : PersonInfoVo()
-
-class MainViewModel : ViewModel() {
- private val _person = MutableLiveData()
- val person: LiveData = _person
-
- init {
- loadInfo()
- }
-
- private fun loadInfo() {
- _person.postValue(
- MinisterVo(
- name = randomChinese(3),
- duty = "总部长",
- headImg = "",
- desc = randomChinese(8)
- )
- )
- }
-}
\ No newline at end of file
diff --git a/background/src/main/java/com/gyf/csams/main/model/ManagementOfficerModel.kt b/background/src/main/java/com/gyf/csams/main/model/ManagementOfficerModel.kt
index ff2fcb5..b2b428e 100644
--- a/background/src/main/java/com/gyf/csams/main/model/ManagementOfficerModel.kt
+++ b/background/src/main/java/com/gyf/csams/main/model/ManagementOfficerModel.kt
@@ -3,49 +3,14 @@ package com.gyf.csams.main.model
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.viewModelScope
-import com.gyf.lib.util.randomChinese
-import com.gyf.lib.util.randomNum
-import com.orhanobut.logger.Logger
-import kotlinx.coroutines.launch
+import com.gyf.lib.util.AllOfficerVo
+import com.gyf.lib.util.ManagerInfoVo
enum class ColumnType {
Text,
DropMenu
}
-/**
- * 职务
- *
- * @property desc
- */
-enum class Duty(val desc: String) {
- Minister("部长"),
- Manager("干事")
-}
-
-/**
- * 人员信息
- *
- * @property name 名字
- * @property studentId 学号
- * @property mobile 手机号
- * @property duty 职务
- * @property counselor 导员
- */
-data class OfficerVo(
- val name: String,
- val studentId: String,
- val mobile: String,
- val duty: Duty,
- val counselor: String
-)
-
-data class AllOfficerVo(
- val secretariat: MutableList,
- val propaganda: MutableList,
- val publicRelationsDepartment: MutableList
-)
/**
* 部门干事数据状态管理
@@ -55,69 +20,20 @@ class ManagementOfficerModel : ViewModel() {
private val _data = MutableLiveData()
val data: LiveData = _data
+
init {
load()
}
- private fun replace(
- list: MutableList,
- index: Int,
- callback: (s: MutableList) -> Unit
- ) {
- val s = mutableListOf()
- list[index] = list[index].copy(duty = Duty.Minister)
- s.add(list[index])
- s.addAll(list.filter { officerVo -> officerVo != list[index] }
- .map { officerVo -> officerVo.copy(duty = Duty.Manager) })
- callback(s)
- }
-
- fun updateDuty(list: MutableList, index: Int) {
- _data.value?.apply {
- Logger.i("$secretariat")
- when (list) {
- secretariat -> replace(list = list, index = index) {
- _data.postValue(copy(secretariat = it))
- }
- propaganda -> replace(list = list, index = index) {
- _data.postValue(copy(propaganda = it))
- }
- publicRelationsDepartment -> replace(list = list, index = index) {
- _data.postValue(copy(publicRelationsDepartment = it))
- }
- }
-
-
- }
+ fun updateDuty(list: MutableList, index: Int) {
+ TODO("更新职务")
}
/**
- * TODO 加载部门成员
*
*/
private fun load() {
- viewModelScope.launch {
- val officerVoList = mutableListOf()
- val baseSize = 3
- val peopleSize = 5
- repeat(peopleSize * baseSize) {
- officerVoList.add(
- OfficerVo(
- name = randomChinese(3), studentId = randomNum(8), mobile = randomNum(11),
- if (it % peopleSize == 0) Duty.Minister else Duty.Manager, counselor = ""
- )
- )
- }
- val all = officerVoList.chunked(peopleSize)
- _data.postValue(
- AllOfficerVo(
- secretariat = all[0].toMutableList(),
- propaganda = all[1].toMutableList(),
- publicRelationsDepartment = all[2].toMutableList()
- )
- )
- }
-
+ TODO("加载部门成员")
}
}
\ No newline at end of file
diff --git a/background/src/main/java/com/gyf/csams/main/model/ManagerActViewModel.kt b/background/src/main/java/com/gyf/csams/main/model/ManagerActViewModel.kt
index 10c9b96..f3180ea 100644
--- a/background/src/main/java/com/gyf/csams/main/model/ManagerActViewModel.kt
+++ b/background/src/main/java/com/gyf/csams/main/model/ManagerActViewModel.kt
@@ -1,17 +1,12 @@
package com.gyf.csams.main.model
import android.app.Application
-import androidx.annotation.IntRange
import com.gyf.lib.model.ScrollViewModel
+import com.gyf.lib.util.ActivityVo
import com.gyf.lib.util.randomChinese
import com.gyf.lib.util.randomDateTime
import com.gyf.lib.util.randomNum
-import java.util.*
-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
-)
/**
* 活动信息数据管理
diff --git a/background/src/main/java/com/gyf/csams/main/model/MenuViewModel.kt b/background/src/main/java/com/gyf/csams/main/model/MenuViewModel.kt
index b8c0591..53e7fc1 100644
--- a/background/src/main/java/com/gyf/csams/main/model/MenuViewModel.kt
+++ b/background/src/main/java/com/gyf/csams/main/model/MenuViewModel.kt
@@ -9,7 +9,8 @@ enum class MenuType(val desc: String, val clazz: Map
"社团管理",
mapOf(
"社团信息管理" to AssociationManagementActivity::class.java,
- "审核换名申请表" to RenameActivity::class.java
+ "审核社团换名" to RenameActivity::class.java,
+ "审核社团注册" to AuditAssociationActivity::class.java
),
),
Act(
diff --git a/background/src/main/java/com/gyf/csams/main/model/RenameViewModel.kt b/background/src/main/java/com/gyf/csams/main/model/RenameViewModel.kt
index 4086745..73375c6 100644
--- a/background/src/main/java/com/gyf/csams/main/model/RenameViewModel.kt
+++ b/background/src/main/java/com/gyf/csams/main/model/RenameViewModel.kt
@@ -5,29 +5,19 @@ import androidx.lifecycle.viewModelScope
import com.gyf.csams.R
import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.uikit.StringForm
+import com.gyf.lib.util.RenameVo
import com.gyf.lib.util.randomChinese
import com.gyf.lib.util.randomNum
import kotlinx.coroutines.launch
-/**
- * 换名申请表
- *
- * @property studentId 学号
- * @property oldName 社团原名
- * @property newName 社团新名
- * @property reason 申请理由
- */
-data class RenameVo(
- val studentId: String,
- val oldName: String,
- val newName: String,
- val reason: String
-)
class RenameViewModel(application: Application) : ScrollViewModel(application) {
val approverOrigin =
- StringForm(formDesc = application.getString(R.string.approver_origin), textLength = 30)
+ StringForm(
+ formDesc = application.getString(R.string.first_approver_origin),
+ textLength = 30
+ )
override val initSize: Int = 10
diff --git a/background/src/main/java/com/gyf/csams/main/ui/AssociationManagementActivity.kt b/background/src/main/java/com/gyf/csams/main/ui/AssociationManagementActivity.kt
index aaa854c..3672ae5 100644
--- a/background/src/main/java/com/gyf/csams/main/ui/AssociationManagementActivity.kt
+++ b/background/src/main/java/com/gyf/csams/main/ui/AssociationManagementActivity.kt
@@ -16,10 +16,10 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
-import com.gyf.csams.main.model.AssociationLevel
import com.gyf.csams.main.model.AssociationManagementViewModel
import com.gyf.lib.uikit.Body
import com.gyf.lib.uikit.MainBoxFrame
+import com.gyf.lib.util.AssociationLevel
/**
* 社团管理
@@ -52,7 +52,7 @@ class AssociationManagementActivity : ComponentActivity() {
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
- text = "$associationId",
+ text = "$id",
style = MaterialTheme.typography.h6
)
Text(
@@ -68,7 +68,9 @@ class AssociationManagementActivity : ComponentActivity() {
verticalAlignment = Alignment.CenterVertically
) {
Text(
- text = commander,
+ text = ""
+ /**TODO 用户**/
+ ,
style = MaterialTheme.typography.h5
)
Text(
@@ -80,7 +82,7 @@ class AssociationManagementActivity : ComponentActivity() {
expanded = true
}) {
Text(
- text = level.name,
+ text = level?.name ?: "暂无评级",
style = MaterialTheme.typography.h5
)
DropdownMenu(
@@ -89,7 +91,7 @@ class AssociationManagementActivity : ComponentActivity() {
AssociationLevel.values().forEach {
DropdownMenuItem(onClick = {
model.update(
- associationVo = this@apply,
+ associationDto = this@apply,
level = it
)
expanded = false
diff --git a/background/src/main/java/com/gyf/csams/main/ui/AuditAssociationActivity.kt b/background/src/main/java/com/gyf/csams/main/ui/AuditAssociationActivity.kt
new file mode 100644
index 0000000..20ddfa1
--- /dev/null
+++ b/background/src/main/java/com/gyf/csams/main/ui/AuditAssociationActivity.kt
@@ -0,0 +1,310 @@
+package com.gyf.csams.main.ui
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.border
+import androidx.compose.foundation.layout.*
+import androidx.compose.material.ExperimentalMaterialApi
+import androidx.compose.material.MaterialTheme
+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.coil.rememberCoilPainter
+import com.google.accompanist.insets.ExperimentalAnimatedInsets
+import com.google.accompanist.insets.navigationBarsWithImePadding
+import com.gyf.csams.R
+import com.gyf.csams.main.model.AuditAssociationViewModel
+import com.gyf.csams.uikit.RowItem
+import com.gyf.csams.uikit.TestTableImeSimple
+import com.gyf.lib.uikit.*
+import com.gyf.lib.util.*
+
+class AuditAssociationActivity : ComponentActivity() {
+ @ExperimentalMaterialApi
+ @ExperimentalAnimatedInsets
+ @ExperimentalComposeApi
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ WindowCompat.setDecorFitsSystemWindows(window, false)
+ setContent {
+ ImeBody {
+ val model: AuditAssociationViewModel = viewModel()
+ val data by model.data.observeAsState()
+ TestTableImeSimple(
+ title = R.string.association_reg_title
+ ) {
+ data?.forEach {
+ item {
+ RegisterForm(vo = it)
+ Spacer(modifier = Modifier.height(10.dp))
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ @Composable
+ private fun CheckForm(
+ vo: DisposeRegInfoVo,
+ scaffoldModel: ScaffoldModel = viewModel(),
+ auditAssociationViewModel: AuditAssociationViewModel = viewModel(),
+ first: @Composable () -> Unit,
+ last: @Composable () -> Unit
+ ) {
+ val baseHeight = 50.dp
+
+ (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 = "确认"
+ ) {
+ auditAssociationViewModel.check(
+ regId = vo.log.id,
+ result = result,
+ cause = cause.formValue.value
+ ?: throw IllegalArgumentException("无法获取审核理由")
+ ) {
+ scaffoldModel.update(message = it, actionLabel = "刷新") {
+ auditAssociationViewModel.load { }
+ }
+ }
+ }
+ }
+
+ val accept: (m: String, isFirstAccept: Boolean) -> Unit =
+ { m: String, isFirstAccept: Boolean ->
+ scaffoldModel.update("确认${m}?", actionLabel = "确认") {
+ auditAssociationViewModel.accept(
+ regId = vo.log.id,
+ isFirstAccept = isFirstAccept
+ ) {
+ scaffoldModel.update(message = it, actionLabel = "刷新") {
+ auditAssociationViewModel.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(
+ modifier = Modifier.navigationBarsWithImePadding(),
+ form = cause
+ )
+ }
+ }
+
+ when {
+ //初审记录,负责人为空 等待初审
+ vo.log.nextAudit == null && vo.log.manager == null -> {
+ if (it.duty == Duty.PamphaBhusal) {
+ confirmDesc = R.string.accept_btn
+ onConfirm = { accept("受理", true) }
+ }
+ 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(baseHeight),
+ key = R.string.audit_phases, value = "等待初审"
+ )
+ }
+ //初审记录,负责人不为空 初审受理
+ vo.log.nextAudit == null && vo.log.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(baseHeight),
+ key = R.string.audit_phases, value = "初审受理"
+ )
+ }
+ //初审记录,审核通过(上报) 等待复审
+ vo.log.nextAudit != null && vo.log.nextAudit?.manager == null -> {
+
+ if (it.duty == Duty.Teacher) {
+ confirmDesc = R.string.recheck_btn
+ onConfirm = { accept("复审", false) }
+ }
+ first()
+ RowItem(key = R.string.first_approver_origin, value = vo.log.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(baseHeight),
+ key = R.string.audit_phases, value = "等待复审"
+ )
+ }
+ //复审记录,审核结果为空 复审受理
+ vo.log.nextAudit != null && vo.log.nextAudit?.result == null -> {
+ first()
+ RowItem(key = R.string.first_approver_origin, value = vo.log.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(baseHeight),
+ key = R.string.audit_phases, value = "复审受理"
+ )
+ }
+ else -> {
+ first()
+ RowItem(key = R.string.first_approver_origin, value = vo.log.cause)
+ RowItem(
+ key = R.string.first_result, value = when (vo.log.result) {
+ null -> ""
+ true -> "通过"
+ false -> "不通过"
+ }
+ )
+ last()
+ RowItem(
+ key = R.string.last_approver_origin,
+ value = vo.log.nextAudit?.cause ?: ""
+ )
+ RowItem(
+ key = R.string.last_result, value = when (vo.log.nextAudit?.result) {
+ null -> ""
+ true -> "通过"
+ false -> "不通过"
+ }
+ )
+ RowItem(
+ modifier = Modifier.height(baseHeight),
+ key = R.string.audit_phases, value = "完成审核"
+ )
+ }
+ }
+
+ if (confirmDesc != null) {
+ BottomButton(
+ confirmDesc = confirmDesc,
+ backDesc = backDesc,
+ modifier = Modifier.fillMaxWidth(),
+ onBack = onBack
+ ) {
+ onConfirm?.let { it() }
+ }
+ }
+ }
+ }
+
+ @Composable
+ private fun RegisterForm(
+ modifier: Modifier = Modifier, vo: DisposeRegInfoVo
+ ) {
+ Column(
+ modifier = modifier.border(
+ width = 1.dp,
+ color = MaterialTheme.colors.onBackground
+ )
+ ) {
+ val baseHeight = 50.dp
+
+ RowItem(
+ modifier = Modifier.height(baseHeight),
+ key = R.string.petitioner,
+ value = vo.log.user.name
+ )
+
+ RowItem(
+ modifier = Modifier.height(baseHeight),
+ key = R.string.association_name,
+ value = vo.name
+ )
+
+ RowItem(
+ modifier = Modifier.height(baseHeight),
+ key = R.string.association_desc,
+ value = vo.desc
+ )
+
+ RowItem(
+ modifier = Modifier.height(baseHeight * 3),
+ key = R.string.association_logo
+ ) {
+ //TODO 图片全屏显示
+ val painter =
+ rememberCoilPainter("${com.gyf.lib.BuildConfig.SERVER_ADDRESS}/${vo.logo}")
+ Image(painter = painter, contentDescription = null)
+ }
+
+ CheckForm(vo = vo, first = {
+ RowItem(
+ modifier = Modifier.height(baseHeight),
+ key = R.string.first_approver,
+ value = vo.log.manager?.name ?: ""
+ )
+ }, last = {
+ RowItem(
+ modifier = Modifier.height(baseHeight),
+ key = R.string.last_approver,
+ value = vo.log.nextAudit?.manager?.name ?: ""
+ )
+ })
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/background/src/main/java/com/gyf/csams/main/ui/CheckActActivity.kt b/background/src/main/java/com/gyf/csams/main/ui/CheckActActivity.kt
index 5478d15..95ac2b5 100644
--- a/background/src/main/java/com/gyf/csams/main/ui/CheckActActivity.kt
+++ b/background/src/main/java/com/gyf/csams/main/ui/CheckActActivity.kt
@@ -13,13 +13,14 @@ 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.ApplyActVo
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
/**
@@ -27,6 +28,7 @@ import com.gyf.lib.util.BottomButton
*
*/
class CheckActActivity : ComponentActivity() {
+ @ExperimentalAnimatedInsets
@ExperimentalComposeApi
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -69,11 +71,14 @@ class CheckActActivity : ComponentActivity() {
value = "${vo.size}"
)
RowItem(
- modifier = Modifier.height(baseHeight), key = R.string.approver, value = ""
+ modifier = Modifier.height(baseHeight), key = R.string.first_approver, value = ""
/**TODO 获取审批人**/
)
- RowItem(modifier = Modifier.height(baseHeight * 3), key = R.string.approver_origin) {
- BaseTextField(modifier = Modifier.fillMaxSize(), form = model.approverOrigin)
+ 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(
diff --git a/background/src/main/java/com/gyf/csams/main/ui/CheckQualityReportActivity.kt b/background/src/main/java/com/gyf/csams/main/ui/CheckQualityReportActivity.kt
index ef09308..57070af 100644
--- a/background/src/main/java/com/gyf/csams/main/ui/CheckQualityReportActivity.kt
+++ b/background/src/main/java/com/gyf/csams/main/ui/CheckQualityReportActivity.kt
@@ -12,21 +12,23 @@ import androidx.compose.ui.res.painterResource
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.CheckQualityReportViewModel
-import com.gyf.csams.main.model.MAX_SCORE
-import com.gyf.csams.main.model.QualityReportVo
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
+import com.gyf.lib.util.MAX_SCORE
+import com.gyf.lib.util.QualityReportVo
/**
* 审批质量报告单
*
*/
class CheckQualityReportActivity : ComponentActivity() {
+ @ExperimentalAnimatedInsets
@ExperimentalComposeApi
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -86,11 +88,14 @@ class CheckQualityReportActivity : ComponentActivity() {
}
}
RowItem(
- modifier = Modifier.height(baseHeight), key = R.string.approver, value = ""
+ modifier = Modifier.height(baseHeight), key = R.string.first_approver, value = ""
/**TODO 获取审批人**/
)
- RowItem(modifier = Modifier.height(baseHeight * 3), key = R.string.approver_origin) {
- BaseTextField(modifier = Modifier.fillMaxSize(), form = model.approverOrigin)
+ 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(
diff --git a/background/src/main/java/com/gyf/csams/main/ui/MainActivity.kt b/background/src/main/java/com/gyf/csams/main/ui/MainActivity.kt
index f7cc5bf..e57e1bf 100644
--- a/background/src/main/java/com/gyf/csams/main/ui/MainActivity.kt
+++ b/background/src/main/java/com/gyf/csams/main/ui/MainActivity.kt
@@ -9,19 +9,18 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.OutlinedButton
import androidx.compose.material.Text
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.livedata.observeAsState
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.account.model.LoginViewModel
-import com.gyf.csams.main.model.MainViewModel
import com.gyf.csams.main.model.MenuType
import com.gyf.lib.service.BaseActivity
import com.gyf.lib.uikit.*
import com.gyf.lib.util.ClientType
+import com.gyf.lib.util.ManagerInfoVo
+import com.gyf.lib.util.TokenManager
class MainActivity : BaseActivity() {
@@ -32,22 +31,33 @@ class MainActivity : BaseActivity() {
setContent {
Body {
- val model: MainViewModel = viewModel()
val loginViewModel: LoginViewModel = viewModel()
val scaffoldModel: ScaffoldModel = viewModel()
- val person by model.person.observeAsState()
MainColumnFrame(background = { /*TODO*/ }) {
- person?.let {
+ (TokenManager.getPersonInfo() as? ManagerInfoVo)?.let {
Profile(
modifier = Modifier
.weight(0.3F)
- .padding(10.dp), personInfoVo = it
+ .padding(10.dp),
+ personInfoVo = it
)
}
Column(
modifier = Modifier.weight(0.7F),
verticalArrangement = Arrangement.SpaceEvenly
) {
+
+ OutlinedButton(onClick = {
+ startActivity(
+ Intent(
+ this@MainActivity,
+ NotificationActivity::class.java
+ )
+ )
+ }, modifier = Modifier.fillMaxWidth()) {
+ Text(text = "我的通知")
+ }
+
OutlinedButton(onClick = {
startActivity(Intent(this@MainActivity, DepartmentActivity::class.java))
}, modifier = Modifier.fillMaxWidth()) {
diff --git a/background/src/main/java/com/gyf/csams/main/ui/ManagementOfficerActivity.kt b/background/src/main/java/com/gyf/csams/main/ui/ManagementOfficerActivity.kt
index 0c10c81..0da4b4b 100644
--- a/background/src/main/java/com/gyf/csams/main/ui/ManagementOfficerActivity.kt
+++ b/background/src/main/java/com/gyf/csams/main/ui/ManagementOfficerActivity.kt
@@ -21,14 +21,12 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.gyf.csams.R
-import com.gyf.csams.main.model.Duty
import com.gyf.csams.main.model.ManagementOfficerModel
-import com.gyf.csams.main.model.MinisterVo
-import com.gyf.csams.main.model.OfficerVo
import com.gyf.lib.uikit.Body
import com.gyf.lib.uikit.MainColumnFrame
import com.gyf.lib.uikit.Profile
import com.gyf.lib.uikit.ScaffoldModel
+import com.gyf.lib.util.ManagerInfoVo
import com.orhanobut.logger.Logger
/**
@@ -99,7 +97,7 @@ class ManagementOfficerActivity : ComponentActivity() {
model: ManagementOfficerModel = viewModel(),
scaffoldModel: ScaffoldModel = viewModel(),
@StringRes id: Int,
- officerVoList: MutableList,
+ officerVoList: MutableList,
) {
Column(
modifier = modifier
@@ -124,19 +122,13 @@ class ManagementOfficerActivity : ComponentActivity() {
.width(200.dp)
.fillMaxHeight()
.border(width = 1.dp, color = MaterialTheme.colors.onBackground),
- personInfoVo =
- MinisterVo(
- name = it.value.name,
- duty = it.value.duty.desc,
- headImg = "",
- desc = it.value.mobile
- )
+ personInfoVo = it.value
) {
Logger.i("expanded=$expanded")
Text(
text = it.value.duty.desc,
modifier = Modifier.clickable(onClick = {
- if (it.value.duty.desc != Duty.Minister.desc) expanded =
+ if (it.value.duty.isOfficer()) expanded =
true else scaffoldModel
.update(message = context.getString(R.string.update_duty_error))
})
@@ -149,7 +141,7 @@ class ManagementOfficerActivity : ComponentActivity() {
model.updateDuty(list = officerVoList, index = it.index)
expanded = false
}) {
- Text(text = Duty.Minister.desc)
+ Text(text = it.value.duty.desc)
}
}
}
diff --git a/background/src/main/java/com/gyf/csams/main/ui/ManagerActActivity.kt b/background/src/main/java/com/gyf/csams/main/ui/ManagerActActivity.kt
index 66017c9..f4c53fb 100644
--- a/background/src/main/java/com/gyf/csams/main/ui/ManagerActActivity.kt
+++ b/background/src/main/java/com/gyf/csams/main/ui/ManagerActActivity.kt
@@ -13,12 +13,13 @@ import androidx.compose.runtime.ExperimentalComposeApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
+import com.google.accompanist.insets.ExperimentalAnimatedInsets
import com.gyf.csams.R
-import com.gyf.csams.main.model.ActivityVo
-import com.gyf.csams.main.model.MAX_SCORE
import com.gyf.csams.main.model.ManagerActViewModel
import com.gyf.csams.uikit.RowItem
import com.gyf.csams.uikit.TestTable
+import com.gyf.lib.util.ActivityVo
+import com.gyf.lib.util.MAX_SCORE
import com.gyf.lib.util.format
/**
@@ -26,6 +27,7 @@ import com.gyf.lib.util.format
*
*/
class ManagerActActivity : ComponentActivity() {
+ @ExperimentalAnimatedInsets
@ExperimentalComposeApi
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
diff --git a/background/src/main/java/com/gyf/csams/main/ui/NotificationActivity.kt b/background/src/main/java/com/gyf/csams/main/ui/NotificationActivity.kt
new file mode 100644
index 0000000..0260864
--- /dev/null
+++ b/background/src/main/java/com/gyf/csams/main/ui/NotificationActivity.kt
@@ -0,0 +1,80 @@
+package com.gyf.csams.main.ui
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.material.Card
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Text
+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.gyf.csams.main.model.BackgroundViewModel
+import com.gyf.lib.uikit.Body
+import com.gyf.lib.uikit.MainColumnFrame
+import com.gyf.lib.util.NotificationVo
+import com.gyf.lib.util.format
+import java.util.*
+
+/**
+ * 通知
+ *
+ */
+class NotificationActivity : ComponentActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ setContent {
+ Body {
+ val model: BackgroundViewModel = viewModel()
+ val data by model.data.observeAsState()
+ MainColumnFrame(background = { /*TODO*/ }) {
+ if (data?.size == 0) {
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.Center
+ ) {
+ Text(text = "目前没有收到任何通知")
+ }
+ }
+ LazyColumn {
+ data?.forEach {
+ item {
+ MessageItem(content = it)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @Composable
+ private fun MessageItem(modifier: Modifier = Modifier, content: NotificationVo) {
+ Card(modifier = modifier, backgroundColor = MaterialTheme.colors.background) {
+ Column(modifier = Modifier.padding(10.dp)) {
+ Text(text = content.title, style = MaterialTheme.typography.h5)
+ Spacer(modifier = Modifier.height(5.dp))
+
+ Card(
+ backgroundColor = MaterialTheme.colors.background,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(10.dp)
+ ) {
+ Text(text = content.content)
+ }
+
+ Spacer(modifier = Modifier.height(10.dp))
+ Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
+ Text(text = Date(content.createTime).format())
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/background/src/main/java/com/gyf/csams/main/ui/RenameActivity.kt b/background/src/main/java/com/gyf/csams/main/ui/RenameActivity.kt
index 27d3c37..9e53a51 100644
--- a/background/src/main/java/com/gyf/csams/main/ui/RenameActivity.kt
+++ b/background/src/main/java/com/gyf/csams/main/ui/RenameActivity.kt
@@ -13,17 +13,19 @@ 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.main.model.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
+import com.gyf.lib.util.RenameVo
class RenameActivity : ComponentActivity() {
+ @ExperimentalAnimatedInsets
@ExperimentalComposeApi
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -63,10 +65,13 @@ class RenameActivity : ComponentActivity() {
value = renameVo.reason
)
RowItem(
- modifier = Modifier.height(baseHeight), key = R.string.approver, value = ""
+ modifier = Modifier.height(baseHeight), key = R.string.first_approver, value = ""
/**TODO 获取审批人**/
)
- RowItem(modifier = Modifier.height(baseHeight * 3), key = R.string.approver_origin) {
+ 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)
diff --git a/background/src/main/java/com/gyf/csams/uikit/Table.kt b/background/src/main/java/com/gyf/csams/uikit/Table.kt
index 384f86a..1ab38d1 100644
--- a/background/src/main/java/com/gyf/csams/uikit/Table.kt
+++ b/background/src/main/java/com/gyf/csams/uikit/Table.kt
@@ -2,25 +2,27 @@ package com.gyf.csams.uikit
import androidx.annotation.StringRes
import androidx.compose.foundation.border
+import androidx.compose.foundation.gestures.scrollBy
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.rememberLazyListState
-import androidx.compose.material.MaterialTheme
-import androidx.compose.material.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.ExperimentalComposeApi
-import androidx.compose.runtime.getValue
+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.graphics.Color
+import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
+import com.google.accompanist.insets.*
import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.uikit.Body
import com.gyf.lib.uikit.MainColumnFrame
+
/**
* 表格
*
@@ -65,6 +67,53 @@ fun TestTable(
}
}
+@ExperimentalAnimatedInsets
+@ExperimentalMaterialApi
+@Composable
+fun TestTableImeSimple(
+ modifier: Modifier = Modifier,
+ @StringRes title: Int? = null,
+ content: LazyListScope.() -> Unit
+) {
+ Column(modifier = modifier) {
+ title?.let {
+ Spacer(modifier = Modifier.height(20.dp))
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .border(width = 1.dp, color = MaterialTheme.colors.onBackground),
+ horizontalArrangement = Arrangement.Center,
+ ) {
+ Text(
+ text = stringResource(id = title),
+ style = MaterialTheme.typography.h4
+ )
+ }
+ }
+ val listState = rememberLazyListState()
+
+ val insets = LocalWindowInsets.current
+ val imeBottom = with(LocalDensity.current) { insets.ime.bottom.toDp() }
+ LazyColumn(
+ modifier = Modifier.fillMaxSize(),
+ state = listState,
+ content = content
+ )
+ LaunchedEffect(imeBottom) {
+ listState.scrollBy(imeBottom.value)
+ }
+
+ }
+}
+
+/**
+ * 表格行
+ *
+ * @param modifier
+ * @param key
+ * @param value
+ * @param content
+ */
/**
* 表格行
*
diff --git a/background/src/main/res/values-en/strings.xml b/background/src/main/res/values-en/strings.xml
index 1eed946..e8ec0f5 100644
--- a/background/src/main/res/values-en/strings.xml
+++ b/background/src/main/res/values-en/strings.xml
@@ -26,4 +26,9 @@
活动编号
活动社团
活动地点
+ 受理
+ 通过
+ 复审负责人
+ 初审结果
+ 复审结果
\ No newline at end of file
diff --git a/background/src/main/res/values-zh/strings.xml b/background/src/main/res/values-zh/strings.xml
index 1eed946..e8ec0f5 100644
--- a/background/src/main/res/values-zh/strings.xml
+++ b/background/src/main/res/values-zh/strings.xml
@@ -26,4 +26,9 @@
活动编号
活动社团
活动地点
+ 受理
+ 通过
+ 复审负责人
+ 初审结果
+ 复审结果
\ No newline at end of file
diff --git a/background/src/main/res/values/strings.xml b/background/src/main/res/values/strings.xml
index 1eed946..e8ec0f5 100644
--- a/background/src/main/res/values/strings.xml
+++ b/background/src/main/res/values/strings.xml
@@ -26,4 +26,9 @@
活动编号
活动社团
活动地点
+ 受理
+ 通过
+ 复审负责人
+ 初审结果
+ 复审结果
\ No newline at end of file
diff --git a/background/src/test/java/com/gyf/csams/ExampleUnitTest.kt b/background/src/test/java/com/gyf/csams/ExampleUnitTest.kt
index 8acd231..2829394 100644
--- a/background/src/test/java/com/gyf/csams/ExampleUnitTest.kt
+++ b/background/src/test/java/com/gyf/csams/ExampleUnitTest.kt
@@ -1,5 +1,8 @@
package com.gyf.csams
+import com.google.gson.reflect.TypeToken
+import com.gyf.lib.util.ApiResponse
+import com.orhanobut.logger.Logger
import org.junit.Assert.assertEquals
import org.junit.Test
@@ -13,4 +16,14 @@ class ExampleUnitTest {
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
+
+ @Test
+ fun typeToken() {
+ initToken()
+ }
+
+ inline fun initToken() {
+ val typeToken = object : TypeToken>() {}.type
+ Logger.i("typeToken=$typeToken")
+ }
}
\ No newline at end of file
diff --git a/foreground/src/main/AndroidManifest.xml b/foreground/src/main/AndroidManifest.xml
index 93cd004..8465d84 100644
--- a/foreground/src/main/AndroidManifest.xml
+++ b/foreground/src/main/AndroidManifest.xml
@@ -3,6 +3,7 @@
package="com.gyf.csams">
+
diff --git a/foreground/src/main/java/com/gyf/csams/InitActivity.kt b/foreground/src/main/java/com/gyf/csams/InitActivity.kt
index 11f50ad..d364379 100644
--- a/foreground/src/main/java/com/gyf/csams/InitActivity.kt
+++ b/foreground/src/main/java/com/gyf/csams/InitActivity.kt
@@ -1,14 +1,20 @@
package com.gyf.csams
import android.app.Activity
+import com.google.gson.reflect.TypeToken
import com.gyf.csams.account.ui.AccountActivity
import com.gyf.csams.main.ui.MainActivity
import com.gyf.lib.uikit.AbstractInitActivity
import com.gyf.lib.util.AccountApi
+import com.gyf.lib.util.ApiResponse
+import com.gyf.lib.util.UserVo
+import java.lang.reflect.Type
-class InitActivity : AbstractInitActivity() {
+class InitActivity : AbstractInitActivity() {
override val main: Class = MainActivity::class.java
override val login: Class = AccountActivity::class.java
override val api: AccountApi = AccountApi.ForegroundToken
+
+ override val typeToken: Type = object : TypeToken>() {}.type
}
\ No newline at end of file
diff --git a/foreground/src/main/java/com/gyf/csams/account/model/AccountViewModel.kt b/foreground/src/main/java/com/gyf/csams/account/model/AccountViewModel.kt
index 3e7999e..fd11abd 100644
--- a/foreground/src/main/java/com/gyf/csams/account/model/AccountViewModel.kt
+++ b/foreground/src/main/java/com/gyf/csams/account/model/AccountViewModel.kt
@@ -10,7 +10,6 @@ import com.google.gson.reflect.TypeToken
import com.gyf.csams.R
import com.gyf.csams.account.ui.AccountActivity
import com.gyf.csams.account.ui.AccountRoute
-import com.gyf.csams.util.SimpleCallback
import com.gyf.lib.model.AbstractLoginViewModel
import com.gyf.lib.uikit.FormStatus
import com.gyf.lib.uikit.ValidStringForm
@@ -19,37 +18,14 @@ import com.orhanobut.logger.Logger
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
-/**
- * 响应自动生成密码
- *
- * @property password
- */
-data class UserResDto(val password: String)
-
-/**
- * 构造登录、注册信息实体表单
- *
- * @property studentId 学号
- * @property name 姓名
- */
-data class UserVo(val studentId: String, val name: String)
-
-/**
- * 用户登陆表单
- *
- * @property studentId 学号
- * @property password 密码
- * @property device 设备型号
- */
-data class UserLoginVo(val studentId: String, val password: String, val device: String)
/**
* 密码弹窗信息
*
* @property message
- * @property userResDto
+ * @property userPasswordVo
*/
-data class DialogMessage(val message: String, val userResDto: UserResDto?)
+data class DialogMessage(val message: String, val userPasswordVo: UserPasswordVo?)
/**
* 注册表单
@@ -139,7 +115,7 @@ class AccountViewModel(application: Application) : AbstractLoginViewModel(applic
val url = Api.buildUrl(AccountApi.CheckId)
Logger.i("检测${id.formDesc},请求接口$url")
HttpClient.get(
- url, SimpleCallback(
+ url, HttpCallback(
action = "${id.formDesc}重复检测",
onSuccess = {
if (it.body == true) {
@@ -150,7 +126,7 @@ class AccountViewModel(application: Application) : AbstractLoginViewModel(applic
checkForm()
},
onFail = { Logger.e(it) },
- type = object : TypeToken>() {}.type
+ typeToken = object : TypeToken>() {}.type
), mapOf("studentId" to "${id.formValue.value}")
)
}
@@ -188,22 +164,22 @@ class AccountViewModel(application: Application) : AbstractLoginViewModel(applic
val url = Api.buildUrl(AccountApi.Register)
Logger.i("开始$regBtnDesc,请求接口:$url")
HttpClient.post(
- url, SimpleCallback(
+ url, HttpCallback(
action = regBtnDesc,
onSuccess = {
_dialogMsg.postValue(
DialogMessage(
message = it.message,
- userResDto = it.body
+ userPasswordVo = it.body
)
)
},
onFail = onFail,
- type = object : TypeToken>() {}.type
+ typeToken = object : TypeToken>() {}.type
),
- jsonParam = UserVo(
- studentId = "${id.formValue.value}",
- name = "${name.formValue.value}"
+ jsonParam = UserRegVo(
+ studentId = id.formValue.value ?: throw IllegalArgumentException("学号为空"),
+ name = name.formValue.value ?: throw IllegalArgumentException("姓名为空")
)
)
resetForm()
diff --git a/foreground/src/main/java/com/gyf/csams/account/ui/AccountActivity.kt b/foreground/src/main/java/com/gyf/csams/account/ui/AccountActivity.kt
index 7babd1e..56d3be5 100644
--- a/foreground/src/main/java/com/gyf/csams/account/ui/AccountActivity.kt
+++ b/foreground/src/main/java/com/gyf/csams/account/ui/AccountActivity.kt
@@ -41,7 +41,7 @@ class AccountActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
setContent {
- TestBody { nav, scaffoldState ->
+ NavBody { nav, scaffoldState ->
NavHost(navController = nav, startDestination = AccountRoute.Login.name) {
composable(AccountRoute.Login.name) {
Account(
@@ -241,7 +241,7 @@ class AccountActivity : ComponentActivity() {
private fun RegisterDialog(accountViewModel: AccountViewModel = viewModel()) {
val dialogMsg: DialogMessage? by accountViewModel.dialogMsg.observeAsState(null)
- val message = dialogMsg?.userResDto?.password
+ val message = dialogMsg?.userPasswordVo?.password
if (message?.isNotEmpty() == true) {
PasswordDialog(message = message)
}
diff --git a/foreground/src/main/java/com/gyf/csams/activity/model/ActivityDetailViewModel.kt b/foreground/src/main/java/com/gyf/csams/activity/model/ActivityDetailViewModel.kt
index 89f3f9a..5e91c8a 100644
--- a/foreground/src/main/java/com/gyf/csams/activity/model/ActivityDetailViewModel.kt
+++ b/foreground/src/main/java/com/gyf/csams/activity/model/ActivityDetailViewModel.kt
@@ -10,13 +10,9 @@ import com.gyf.csams.uikit.ActivityDetailMenu
import com.gyf.csams.uikit.TopMenuInterface
import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.uikit.ValidStringForm
-import com.gyf.lib.util.NOT_IMPL_TIP
-import com.gyf.lib.util.randomChinese
-import com.gyf.lib.util.randomDateTime
-import com.gyf.lib.util.randomNum
+import com.gyf.lib.util.*
import com.orhanobut.logger.Logger
import kotlinx.coroutines.launch
-import java.util.*
/**
* 活动详情菜单通用状态
@@ -27,21 +23,6 @@ class ActivityDetailViewModel : ViewModel(), TopMenuInterface = _currentMenu
}
-/**
- * TODO
- *
- * @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
-)
-
/**
* 活动信息
@@ -91,23 +72,6 @@ class ActivityInfoViewModel : ViewModel() {
}
-/**
- * 图片
- * @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
-)
/**
* 活动相册数据状态管理
@@ -179,12 +143,6 @@ class ActivityPhotoViewModel(application: Application) :
}
}
-data class ActivityMemberVo(val studentId: String, val name: String)
-
-data class ActivityMembersVo(
- val organizer: ActivityMemberVo,
- val participant: MutableList?
-)
class ActivityMemberViewModel(application: Application) :
ScrollViewModel(application) {
@@ -245,11 +203,6 @@ class ActivityMemberViewModel(application: Application) :
}
}
-data class BBSVo(val studentId: String, val name: String, val createTime: Date, val content: String)
-
-class T
-
-
class BBSCommentModel : AbstractComment() {
override val newContent = ValidStringForm(formDesc = "评论内容", textLength = 80)
diff --git a/foreground/src/main/java/com/gyf/csams/activity/ui/ActivityDetailActivity.kt b/foreground/src/main/java/com/gyf/csams/activity/ui/ActivityDetailActivity.kt
index 081e727..ded884c 100644
--- a/foreground/src/main/java/com/gyf/csams/activity/ui/ActivityDetailActivity.kt
+++ b/foreground/src/main/java/com/gyf/csams/activity/ui/ActivityDetailActivity.kt
@@ -24,9 +24,12 @@ import com.gyf.csams.R
import com.gyf.csams.activity.model.*
import com.gyf.csams.uikit.*
import com.gyf.lib.uikit.MainColumnFrame
+import com.gyf.lib.uikit.NavBody
import com.gyf.lib.uikit.ScaffoldModel
import com.gyf.lib.uikit.ShowSnackbar
-import com.gyf.lib.uikit.TestBody
+import com.gyf.lib.util.ActivityMemberVo
+import com.gyf.lib.util.ActivityPhotoVo
+import com.gyf.lib.util.BBSVo
import com.gyf.lib.util.format
/**
@@ -41,7 +44,7 @@ class ActivityDetailActivity : ComponentActivity() {
setContent {
- TestBody { nav, scaffoldState ->
+ NavBody { nav, scaffoldState ->
val model: ActivityDetailViewModel = viewModel()
val currentMenuName by model.currentMenu.observeAsState(ActivityDetailMenu.startMenu)
Column {
diff --git a/foreground/src/main/java/com/gyf/csams/association/model/AssociationViewModel.kt b/foreground/src/main/java/com/gyf/csams/association/model/AssociationViewModel.kt
index 68c66b1..58cbad0 100644
--- a/foreground/src/main/java/com/gyf/csams/association/model/AssociationViewModel.kt
+++ b/foreground/src/main/java/com/gyf/csams/association/model/AssociationViewModel.kt
@@ -9,7 +9,10 @@ import com.gyf.csams.uikit.AssociationMenu
import com.gyf.csams.uikit.TopMenuInterface
import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.uikit.StringForm
+import com.gyf.lib.util.HistoryActVo
+import com.gyf.lib.util.MemberVo
import com.gyf.lib.util.NOT_IMPL_TIP
+import com.gyf.lib.util.OngoingActVo
import com.orhanobut.logger.Logger
import kotlinx.coroutines.launch
@@ -42,8 +45,6 @@ class AssociationViewModel : ViewModel(), TopMenuInterface {
}
-data class MemberVo(val name: String)
-
/**
* 社团会员
*
@@ -111,16 +112,11 @@ class MemberViewModel(application: Application) : ScrollViewModel(appl
}
}
-
-data class OngoingActVo(val name: String)
-
class OngoingActViewModel : ViewModel() {
private val _act = MutableLiveData()
val act: LiveData = _act
}
-data class HistoryActVo(val name: String)
-
/**
* 历史活动
diff --git a/foreground/src/main/java/com/gyf/csams/association/model/ExamViewModel.kt b/foreground/src/main/java/com/gyf/csams/association/model/ExamViewModel.kt
index d2d88be..1afaea2 100644
--- a/foreground/src/main/java/com/gyf/csams/association/model/ExamViewModel.kt
+++ b/foreground/src/main/java/com/gyf/csams/association/model/ExamViewModel.kt
@@ -6,7 +6,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.uikit.StringForm
-import com.gyf.lib.util.NOT_IMPL_TIP
+import com.gyf.lib.util.*
import kotlinx.coroutines.launch
import kotlin.random.Random
@@ -22,49 +22,6 @@ enum class ExamActivityType(val menuName: String) {
JOIN_Association("入团申请表")
}
-/**
- * 题型
- *
- */
-enum class ExamType(val type: String) {
- //选择题
- CQ("选择题"),
-
- //开放题
- OQ("开放题")
-}
-
-sealed class Exam {
- abstract val examType: ExamType
- abstract val question: StringForm
-}
-
-
-/**
- * 开放题
- *
- * @property examType 题型描述
- * @property question 问题
- */
-data class OpenQuestionsVo(
- override val examType: ExamType = ExamType.OQ, override val question: StringForm
-
-) : Exam()
-
-/**
- * 选择题
- *
- * @property examType 题型描述
- * @property answers 答案
- * @property rightAnswer 正确答案
- * @property question 问题
- */
-data class ChoiceQuestionVo(
- override val examType: ExamType = ExamType.CQ,
- val answers: List,
- val rightAnswer: Int,
- override val question: StringForm
-) : Exam()
/**
diff --git a/foreground/src/main/java/com/gyf/csams/association/model/RegAssociationViewModel.kt b/foreground/src/main/java/com/gyf/csams/association/model/RegAssociationViewModel.kt
index 63c8ed7..5bae642 100644
--- a/foreground/src/main/java/com/gyf/csams/association/model/RegAssociationViewModel.kt
+++ b/foreground/src/main/java/com/gyf/csams/association/model/RegAssociationViewModel.kt
@@ -1,31 +1,40 @@
package com.gyf.csams.association.model
import android.app.Application
+import android.graphics.Bitmap
import android.net.Uri
+import androidx.core.graphics.drawable.toBitmap
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
+import coil.imageLoader
+import coil.request.ImageRequest
import com.google.gson.reflect.TypeToken
import com.gyf.csams.MainApplication
-import com.gyf.csams.util.SimpleCallback
+import com.gyf.lib.BuildConfig
import com.gyf.lib.uikit.FormStatus
import com.gyf.lib.uikit.ValidStringForm
import com.gyf.lib.util.*
import com.orhanobut.logger.Logger
import kotlinx.coroutines.launch
import java.io.File
+import java.io.FileOutputStream
import java.io.InputStream
-data class RegAssociationVo(val name: String, val desc: String, val fileId: Int, val token: Token)
+class TestStringForm(formDesc: String, textLength: Int) : ValidStringForm(formDesc, textLength) {
+
+ fun setValue(value: String) {
+ _formValue.postValue(value)
+ }
+}
class RegAssociationViewModel(application: Application) : AndroidViewModel(application) {
val frameDesc = "社团注册资料"
- val name = ValidStringForm(formDesc = "社团名称", textLength = 5)
- val desc = ValidStringForm(formDesc = "社团简介", textLength = 30)
-
+ val name = TestStringForm(formDesc = "社团名称", textLength = 5)
+ val desc = TestStringForm(formDesc = "社团简介", textLength = 30)
private val _picture = MutableLiveData()
val picture: LiveData = _picture
@@ -33,10 +42,17 @@ class RegAssociationViewModel(application: Application) : AndroidViewModel(appli
private val _fileId = MutableLiveData()
val fileId: LiveData = _fileId
+ private val _checkInfo = MutableLiveData()
+ val checkInfo: LiveData = _checkInfo
+
val picturePlaceHolder = "请上传图片"
val errorPicture = "图片加载失败,请联系管理员"
+ init {
+ read()
+ }
+
fun setPicture(uri: Uri) {
_picture.value = uri
}
@@ -49,40 +65,84 @@ class RegAssociationViewModel(application: Application) : AndroidViewModel(appli
throw IllegalArgumentException(UNKNOW_ERROR)
}
+ /**
+ * 加载历史提交的注册资料,可能为空
+ *
+ */
+ private fun read() {
+ viewModelScope.launch {
+ HttpClient.post(
+ Api.buildUrl(AssociationApi.Read),
+ HttpCallback(action = "加载历史注册资料", onSuccess = { it ->
+ it.body?.let { it ->
+ name.setValue(it.name)
+ desc.setValue(it.desc)
+ _checkInfo.postValue(it)
+ val context = getApplication()
+ val request = ImageRequest.Builder(context)
+ .data("${BuildConfig.SERVER_ADDRESS}/${it.logo}")
+ .target(
+ onSuccess = { result ->
+
+ it.logo.split("/").apply {
+ File.createTempFile(last(), null, context.cacheDir).apply {
+ Logger.d("文件路径:${absolutePath}")
+ FileOutputStream(this).use {
+ result.toBitmap().compress(
+ Bitmap.CompressFormat.JPEG,
+ 100,
+ it
+ )
+ }
+ }
+ .apply {
+ Logger.i("读取缓存图片")
+ setPicture(Uri.fromFile(this))
+ _fileId.postValue(it.fileId)
+ }
+
+ }
+ }
+ )
+ .build()
+ context.imageLoader.enqueue(request)
+ }
+ },
+ typeToken = object : TypeToken>() {}.type
+ ),
+ jsonParam = OnlyToken(clientType = ClientType.Foreground)
+ )
+ }
+ }
+
fun uploadPhoto(callback: (value: String) -> Unit) {
getInputSteam()?.readBytes()?.apply {
- val token = TokenManager.token
- if (token != null) {
-
- viewModelScope.launch {
- val context = getApplication()
-
- runCatching {
- val cacheFile = File(context.cacheDir, "${System.currentTimeMillis()}")
- cacheFile.writeBytes(this@apply)
-
- HttpClient.uploadFile(
- Api.buildUrl(AssociationApi.Logo),
- SimpleCallback>("上传图片", onSuccess = {
- Logger.i(it.message)
- callback(it.message)
- it.body?.let {
- _fileId.postValue(it.first())
- }
-
- }, onFail = {
- Logger.e(it)
- callback("图片上传失败")
- }, type = object : TypeToken>>() {}.type),
- token = token,
- fileList = arrayOf(cacheFile)
- )
- }
+ viewModelScope.launch {
+ val context = getApplication()
+
+ runCatching {
+ val cacheFile = File(context.cacheDir, "${System.currentTimeMillis()}")
+ cacheFile.writeBytes(this@apply)
+
+ HttpClient.uploadFile(
+ Api.buildUrl(AssociationApi.Logo),
+ HttpCallback>("上传图片", onSuccess = {
+ Logger.i(it.message)
+ callback(it.message)
+ it.body?.let {
+ _fileId.postValue(it.first())
+ }
+
+ }, onFail = {
+ Logger.e(it)
+ callback("图片上传失败")
+ }, typeToken = object : TypeToken>>() {}.type),
+ fileList = arrayOf(cacheFile)
+ )
}
- } else {
- callback(UNKNOW_ERROR)
}
+
}
}
@@ -94,15 +154,14 @@ class RegAssociationViewModel(application: Application) : AndroidViewModel(appli
fun register(callback: (value: String) -> Unit) {
val nameValue = name.formValue.value
val descValue = desc.formValue.value
- val token = TokenManager.token
val fileId = _fileId.value
- if (token != null && nameValue != null && descValue != null && fileId != null &&
+ if (nameValue != null && descValue != null && fileId != null &&
name.statusForm.value == FormStatus.Valid && desc.statusForm.value == FormStatus.Valid
) {
viewModelScope.launch {
HttpClient.post(
Api.buildUrl(AssociationApi.Register),
- SimpleCallback("注册社团", onSuccess = {
+ HttpCallback("注册社团", onSuccess = {
Logger.i(it.message)
callback(it.message)
name.clean()
@@ -110,13 +169,13 @@ class RegAssociationViewModel(application: Application) : AndroidViewModel(appli
_picture.postValue(null)
}, onFail = {
Logger.e(it)
- }, object : TypeToken>() {}.type),
+ }, typeToken = object : TypeToken>() {}.type),
jsonParam =
- RegAssociationVo(
+ AssociationRegVo(
name = nameValue,
desc = descValue,
- token = token,
- fileId = fileId
+ fileId = fileId,
+ id = checkInfo.value?.id
)
)
}
diff --git a/foreground/src/main/java/com/gyf/csams/association/ui/AssociationActivity.kt b/foreground/src/main/java/com/gyf/csams/association/ui/AssociationActivity.kt
index 2309d6d..429f03b 100644
--- a/foreground/src/main/java/com/gyf/csams/association/ui/AssociationActivity.kt
+++ b/foreground/src/main/java/com/gyf/csams/association/ui/AssociationActivity.kt
@@ -31,6 +31,8 @@ import com.gyf.csams.activity.ui.ApplyActActivity
import com.gyf.csams.association.model.*
import com.gyf.csams.uikit.*
import com.gyf.lib.uikit.*
+import com.gyf.lib.util.HistoryActVo
+import com.gyf.lib.util.MemberVo
import com.gyf.lib.util.randomChinese
import com.orhanobut.logger.Logger
@@ -44,7 +46,7 @@ class AssociationActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
setContent {
- TestBody { nav, scaffoldState ->
+ NavBody { nav, scaffoldState ->
val context = LocalContext.current as AssociationActivity
val model: AssociationViewModel = viewModel()
val currentMenuName: AssociationMenu by model.currentMenu.observeAsState(
diff --git a/foreground/src/main/java/com/gyf/csams/association/ui/ExamActivity.kt b/foreground/src/main/java/com/gyf/csams/association/ui/ExamActivity.kt
index 03bec82..e384a64 100644
--- a/foreground/src/main/java/com/gyf/csams/association/ui/ExamActivity.kt
+++ b/foreground/src/main/java/com/gyf/csams/association/ui/ExamActivity.kt
@@ -19,7 +19,9 @@ 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.*
+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.uikit.Background
import com.gyf.csams.uikit.BackgroundImage
import com.gyf.lib.uikit.BaseTextField
@@ -27,6 +29,9 @@ import com.gyf.lib.uikit.Body
import com.gyf.lib.uikit.MainColumnFrame
import com.gyf.lib.uikit.ScaffoldModel
import com.gyf.lib.util.BottomButton
+import com.gyf.lib.util.ChoiceQuestionVo
+import com.gyf.lib.util.Exam
+import com.gyf.lib.util.OpenQuestionsVo
/**
diff --git a/foreground/src/main/java/com/gyf/csams/association/ui/RegAssociationActivity.kt b/foreground/src/main/java/com/gyf/csams/association/ui/RegAssociationActivity.kt
index 82cc1bd..d2f1529 100644
--- a/foreground/src/main/java/com/gyf/csams/association/ui/RegAssociationActivity.kt
+++ b/foreground/src/main/java/com/gyf/csams/association/ui/RegAssociationActivity.kt
@@ -24,6 +24,9 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.buildAnnotatedString
+import androidx.compose.ui.text.withStyle
+import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
import androidx.lifecycle.viewmodel.compose.viewModel
@@ -33,8 +36,11 @@ import com.gyf.csams.uikit.Background
import com.gyf.csams.uikit.BackgroundImage
import com.gyf.lib.uikit.*
import com.gyf.lib.util.BottomButton
+import com.gyf.lib.util.CheckStatus
import com.gyf.lib.util.ImageUtil
+import com.gyf.lib.util.format
import com.orhanobut.logger.Logger
+import java.util.*
/**
@@ -57,6 +63,7 @@ class RegAssociationActivity : ComponentActivity() {
.weight(0.1F)
)
Title()
+ Tip()
Name()
Desc(
modifier = Modifier
@@ -76,11 +83,13 @@ class RegAssociationActivity : ComponentActivity() {
val name by model.name.statusForm.observeAsState()
val desc by model.name.statusForm.observeAsState()
val fileId by model.fileId.observeAsState()
+ val checkInfo by model.checkInfo.observeAsState()
BottomButton(
modifier = Modifier.fillMaxWidth(),
enabled = name == FormStatus.Valid && desc == FormStatus.Valid && fileId != null,
- confirmDesc = R.string.reg_btn
- ) {
+ confirmDesc = if (checkInfo != null) R.string.reg_again_btn else R.string.reg_btn,
+
+ ) {
model.register {
scaffoldModel.update(message = it, actionLabel = "返回") {
finish()
@@ -88,10 +97,50 @@ class RegAssociationActivity : ComponentActivity() {
}
}
Spacer(modifier = Modifier.weight(0.05F))
+ }
+ }
+
+ }
+ }
+
+ @Composable
+ private fun Tip(model: RegAssociationViewModel = viewModel()) {
+ val checkInfo by model.checkInfo.observeAsState()
+ checkInfo?.let {
+ Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
+ when (val status = it.checkStatus) {
+ CheckStatus.Finish -> Text(buildAnnotatedString {
+ withStyle(style = MaterialTheme.typography.h5.toParagraphStyle()) {
+ append("您于${Date(it.applyTime).format()}提交的${model.frameDesc}审核不通过原因如下:\n")
+ }
+ withStyle(
+ style = MaterialTheme.typography.h6.copy(color = MaterialTheme.colors.error)
+ .toParagraphStyle()
+ ) {
+ append("初审意见:${it.firstCause}\n")
+ it.lastCause?.let {
+ append("复审意见:${it}")
+ }
+ }
+ })
+ else -> {
+ Text(
+ text = status.desc, style =
+ MaterialTheme.typography.h5.copy(color = MaterialTheme.colors.primary)
+ )
}
}
+ }
+
}
+
+ }
+
+ @Preview
+ @Composable
+ private fun TestPreview9() {
+ Text(text = "123", color = MaterialTheme.colors.error)
}
@@ -187,30 +236,36 @@ class RegAssociationActivity : ComponentActivity() {
bitmap = it, contentDescription = null
)
}
- Column(
- modifier = Modifier.fillMaxHeight(),
- verticalArrangement = Arrangement.SpaceEvenly
- ) {
- IconButton(onClick = {
- loadPicture()
- }) {
- Image(
- painter = painterResource(id = R.drawable.ic_exchange_rate),
- contentDescription = null
- )
- }
- IconButton(onClick = {
- scaffoldModel.update("确认上传此图片?", actionLabel = "确定") {
- Logger.i("开始上传")
- model.uploadPhoto {
- scaffoldModel.update(message = it)
+ val checkInfo by model.checkInfo.observeAsState()
+ if (checkInfo == null || checkInfo?.checkStatus == CheckStatus.Finish) {
+ Column(
+ modifier = Modifier.fillMaxHeight(),
+ verticalArrangement = Arrangement.SpaceEvenly
+ ) {
+ IconButton(onClick = {
+ loadPicture()
+ }) {
+ Image(
+ painter = painterResource(id = R.drawable.ic_exchange_rate),
+ contentDescription = null
+ )
+ }
+ IconButton(onClick = {
+ scaffoldModel.update("确认上传此图片?", actionLabel = "确定") {
+ Logger.i("开始上传")
+ model.uploadPhoto {
+ scaffoldModel.update(
+ message = it,
+ actionLabel = "关闭提示"
+ )
+ }
}
+ }) {
+ Image(
+ painter = painterResource(id = R.drawable.ic_upload),
+ contentDescription = null
+ )
}
- }) {
- Image(
- painter = painterResource(id = R.drawable.ic_upload),
- contentDescription = null
- )
}
}
}
@@ -245,7 +300,11 @@ class RegAssociationActivity : ComponentActivity() {
*/
@Composable
private fun Name(model: RegAssociationViewModel = viewModel()) {
- BaseTextField(form = model.name, singeLine = true, modifier = Modifier.fillMaxWidth())
+ val checkInfo by model.checkInfo.observeAsState()
+ BaseTextField(
+ form = model.name, singeLine = true, modifier = Modifier.fillMaxWidth(),
+ readOnly = checkInfo?.checkStatus != CheckStatus.Finish
+ )
}
/**
@@ -254,7 +313,11 @@ class RegAssociationActivity : ComponentActivity() {
*/
@Composable
private fun Desc(model: RegAssociationViewModel = viewModel(), modifier: Modifier) {
- BaseTextField(form = model.desc, modifier = modifier)
+ val checkInfo by model.checkInfo.observeAsState()
+ BaseTextField(
+ form = model.desc, modifier = modifier,
+ readOnly = checkInfo?.checkStatus != CheckStatus.Finish
+ )
}
}
diff --git a/foreground/src/main/java/com/gyf/csams/main/model/MainViewModel.kt b/foreground/src/main/java/com/gyf/csams/main/model/MainViewModel.kt
index ce19116..d3b25d9 100644
--- a/foreground/src/main/java/com/gyf/csams/main/model/MainViewModel.kt
+++ b/foreground/src/main/java/com/gyf/csams/main/model/MainViewModel.kt
@@ -3,12 +3,9 @@ package com.gyf.csams.main.model
import android.app.Application
import androidx.lifecycle.*
import com.google.gson.reflect.TypeToken
-import com.gyf.csams.account.model.UserVo
import com.gyf.csams.uikit.AbstractComment
-import com.gyf.csams.util.SimpleCallback
import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.uikit.FormStatus
-import com.gyf.lib.uikit.PersonInfoVo
import com.gyf.lib.uikit.StringForm
import com.gyf.lib.uikit.ValidStringForm
import com.gyf.lib.util.*
@@ -17,9 +14,6 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
-data class LeaveMessageFormatVo(val message: String, val user: UserVo)
-
-
class NotificationViewModel(application: Application) : AndroidViewModel(application) {
private val _count = MutableLiveData()
@@ -35,24 +29,21 @@ class NotificationViewModel(application: Application) : AndroidViewModel(applica
*/
private fun count() {
viewModelScope.launch {
- TokenManager.token?.let {
- HttpClient.post(
- url = Api.buildUrl(NotificationApi.Count),
- SimpleCallback(action = "未读通知计数", onSuccess = {
- it.body?.let {
- _count.postValue(it)
- }
- Logger.i(it.message)
- }, onFail = {
- Logger.e(it)
- }, type = object : TypeToken>() {}.type),
- jsonParam = NotificationDto(
- receiverId = it.id,
- receiverClient = ClientType.Foreground,
- token = it
- )
+ HttpClient.post(
+ url = Api.buildUrl(NotificationApi.Count),
+ HttpCallback(action = "未读通知计数", onSuccess = {
+ it.body?.let {
+ _count.postValue(it)
+ }
+ Logger.i(it.message)
+ }, onFail = {
+ Logger.e(it)
+ }, typeToken = object : TypeToken>() {}.type),
+ jsonParam = NotificationDto(
+ receiverId = TokenManager.getToken().id,
+ receiverClient = ClientType.Foreground,
)
- }
+ )
}
}
}
@@ -87,32 +78,25 @@ class MarqueeViewModel : AbstractComment() {
* @param callback
*/
override fun send(callback: (message: String) -> Unit) {
- TokenManager.token.let {
- if (it != null) {
- viewModelScope.launch {
- HttpClient.post(url = Api.buildUrl(MainApi.LeaveMessage),
- SimpleCallback(
- action = "发送留言", onSuccess = {
- if (it.body == true) {
- callback("留言发送成功")
- newContent.clean()
- loadMessage(callback)
- } else {
- callback("留言发送失败")
- }
- }, onFail = {
- callback("留言发送失败")
- }, type = object : TypeToken>() {}.type
- ),
- jsonParam = LeaveMessageVo(
- message = newContent.formValue.value ?: "",
- token = it
- )
- )
- }
- } else {
- callback(UNKNOW_ERROR)
- }
+ viewModelScope.launch {
+ HttpClient.post(url = Api.buildUrl(MainApi.LeaveMessage),
+ HttpCallback(
+ action = "发送留言", onSuccess = {
+ if (it.body == true) {
+ callback("留言发送成功")
+ newContent.clean()
+ loadMessage(callback)
+ } else {
+ callback("留言发送失败")
+ }
+ }, onFail = {
+ callback("留言发送失败")
+ }, typeToken = object : TypeToken>() {}.type
+ ),
+ jsonParam = LeaveMessageVo(
+ message = newContent.formValue.value ?: ""
+ )
+ )
}
}
@@ -121,16 +105,22 @@ class MarqueeViewModel : AbstractComment() {
viewModelScope.launch {
HttpClient.post(
Api.buildUrl(MainApi.GetMessage),
- SimpleCallback>(action = "获取留言", onSuccess = {
+ HttpCallback>(
+ action = "获取留言",
+ onSuccess = {
// callback(it.message)
- Logger.i(it.message)
- it.body?.let {
- _marqueeTexts.postValue(it)
- }
- }, onFail = {
- Logger.e(it)
- callback("留言获取失败")
- }, type = object : TypeToken>>() {}.type),
+ Logger.i(it.message)
+ it.body?.let {
+ _marqueeTexts.postValue(it)
+ }
+ },
+ onFail = {
+ Logger.e(it)
+ callback("留言获取失败")
+ },
+ typeToken = object :
+ TypeToken>>() {}.type
+ ),
jsonParam = OnlyToken(clientType = ClientType.Foreground)
)
}
@@ -153,67 +143,47 @@ class MarqueeViewModel : AbstractComment() {
}
-
-/**
- * 社团
- *
- * @property name 社团名称
- */
-data class AssociationListVo(val name: String)
-
-data class LeaveMessageVo(val message: String, val token: Token)
-
/**
* 社团列表
*
*/
-class ListViewModel(application: Application) : ScrollViewModel(application) {
+class ListViewModel(application: Application) : ScrollViewModel(application) {
val name = StringForm(formDesc = "社团名称", textLength = 5)
val desc = StringForm(formDesc = "社团简介", textLength = 10)
- //社团列表加载数量
- val associationListSize = 10
-
- //社团列表
- private val _associationList = MutableLiveData>(mutableListOf())
- val associationListVo: LiveData> = _associationList
-
val searchDesc = "搜索"
-
- /**
- * TODO 社团检索
- *
- * @param callback
- */
- fun search(callback: (value: String) -> Unit) {
- Logger.i("搜索条件[社团名称:${name.formValue.value},社团简介:${desc.formValue.value}]")
- callback(NOT_IMPL_TIP)
- }
-
override val initSize: Int = 10
init {
- load()
-
+ load {}
}
/**
* 加载社团列表
*
*/
- override fun load() {
+ override fun load(callback: (message: String) -> Unit) {
viewModelScope.launch {
- _associationList.value?.apply {
- repeat(
- 10
- ) {
- add(AssociationListVo(name = "社团${_associationList.value?.size}"))
- }
-
- }
- Logger.i("初始化社团列表size=${_associationList.value?.size}")
+ HttpClient.post(
+ Api.buildUrl(AssociationApi.List),
+ HttpCallback>(
+ action = "加载社团列表",
+ onSuccess = {
+ it.body?.let {
+ _data.postValue(it)
+ }
+ callback(it.message)
+ },
+ typeToken = object :
+ TypeToken>>() {}.type
+ ),
+ jsonParam = SearchAssociationVo(
+ name = name.formValue.value ?: "",
+ desc = desc.formValue.value ?: ""
+ )
+ )
}
}
@@ -222,41 +192,10 @@ class ListViewModel(application: Application) : ScrollViewModel Unit) {
- viewModelScope.launch {
- _associationList.value?.apply {
- val list = mutableListOf()
- list.addAll(this)
- list.apply {
- repeat(10) {
- add(AssociationListVo(name = "社团${size}"))
- }
- }
- Logger.i("t.size=${size}")
- _associationList.postValue(list)
- Logger.i("加载更多社团size=${_associationList.value?.size}")
- callback("成功加载更多社团")
- }
- }
+ TODO(NOT_IMPL_TIP)
}
}
-/**
- * 我的信息
- *
- * @property studentId 学号
- * @property name 姓名
- * @property duty 职务
- * @property headImg 头像
- * @property desc 个人简介
- */
-data class InfoVo(
- val studentId: String,
- override val name: String,
- override val duty: String,
- override val headImg: String,
- override val desc: String
-) : PersonInfoVo()
-
/**
* 个人中心
@@ -268,8 +207,6 @@ class CenterViewModel : ViewModel() {
val myLikeActivity = "我点赞的社团活动"
val myCollectActivity = "我收藏的社团活动"
- private val _info = MutableLiveData()
- val info: LiveData = _info
init {
load()
@@ -277,13 +214,7 @@ class CenterViewModel : ViewModel() {
private fun load() {
viewModelScope.launch {
- _info.value = InfoVo(
- studentId = randomNum(),
- name = randomChinese(3),
- duty = randomChinese(3),
- headImg = "",
- desc = randomChinese(10)
- )
+ TODO()
}
}
diff --git a/foreground/src/main/java/com/gyf/csams/main/ui/MainActivity.kt b/foreground/src/main/java/com/gyf/csams/main/ui/MainActivity.kt
index 7f67775..7df1617 100644
--- a/foreground/src/main/java/com/gyf/csams/main/ui/MainActivity.kt
+++ b/foreground/src/main/java/com/gyf/csams/main/ui/MainActivity.kt
@@ -33,8 +33,7 @@ import com.gyf.csams.message.ui.MessageActivity
import com.gyf.csams.uikit.*
import com.gyf.lib.service.BaseActivity
import com.gyf.lib.uikit.*
-import com.gyf.lib.util.ClientType
-import com.gyf.lib.util.randomChinese
+import com.gyf.lib.util.*
/**
@@ -51,7 +50,7 @@ class MainActivity : BaseActivity() {
setContent {
val imageViewModel: ImageViewModel = viewModel()
- TestBody { nav, scaffoldState ->
+ NavBody { nav, scaffoldState ->
NavHost(navController = nav, startDestination = MainMenu.Main.name) {
composable(MainMenu.Main.name) {
Main(navController = nav)
@@ -94,16 +93,11 @@ class MainActivity : BaseActivity() {
mainMenu = MainMenu.Center,
nav = navController
) {
- val info by model.info.observeAsState()
-
- info?.let {
- Profile(
- modifier = Modifier
- .weight(0.3F)
- .padding(10.dp),
- personInfoVo = it
- )
- }
+ Profile(
+ modifier = Modifier
+ .weight(0.3F)
+ .padding(10.dp)
+ )
Column(
@@ -193,7 +187,11 @@ class MainActivity : BaseActivity() {
mainMenu = MainMenu.List,
nav = navController
) {
- RegisterAssociation()
+ val memberVo: AssociationMemberVo? =
+ (TokenManager.getOwnInfo() as? UserVo)?.associationMemberVo
+ if (memberVo == null) {
+ RegisterAssociation()
+ }
AssociationSearch()
AssociationListBody()
}
@@ -233,7 +231,7 @@ class MainActivity : BaseActivity() {
model: ListViewModel = viewModel(),
scaffoldModel: ScaffoldModel = viewModel()
) {
- val associationListList: MutableList? by model.associationListVo.observeAsState()
+ val associationListList: MutableList? by model.data.observeAsState()
val listState = rememberLazyListState()
LazyColumn(state = listState) {
@@ -267,13 +265,13 @@ class MainActivity : BaseActivity() {
}
}
- if (listState.layoutInfo.totalItemsCount - listState.firstVisibleItemIndex == model.associationListSize / 2 - 1) {
+ if (listState.layoutInfo.totalItemsCount - listState.firstVisibleItemIndex == model.initSize / 2 - 1) {
model.loadMore { scaffoldModel.update(message = it) }
}
}
@Composable
- private fun Association(associationListVo: AssociationListVo) {
+ private fun Association(associationListVo: AssociationVo) {
val context = LocalContext.current
Card(modifier = Modifier.clickable(onClick = {
context.startActivity(
@@ -307,7 +305,6 @@ class MainActivity : BaseActivity() {
model: ListViewModel = viewModel(),
scaffoldModel: ScaffoldModel = viewModel()
) {
-
Card(modifier = Modifier.padding(horizontal = 50.dp, vertical = 10.dp)) {
Column {
@@ -329,7 +326,11 @@ class MainActivity : BaseActivity() {
modifier = Modifier.fillMaxWidth()
) {
OutlinedButton(
- onClick = { model.search { scaffoldModel.update(message = it) } },
+ onClick = {
+ model.load {
+ scaffoldModel.update(message = it)
+ }
+ },
modifier = Modifier.width(100.dp)
) {
Text(text = model.searchDesc)
diff --git a/foreground/src/main/java/com/gyf/csams/message/model/ForegroundViewModel.kt b/foreground/src/main/java/com/gyf/csams/message/model/ForegroundViewModel.kt
new file mode 100644
index 0000000..213ce69
--- /dev/null
+++ b/foreground/src/main/java/com/gyf/csams/message/model/ForegroundViewModel.kt
@@ -0,0 +1,11 @@
+package com.gyf.csams.message.model
+
+import android.app.Application
+import com.gyf.lib.model.SysMessageViewModel
+import com.gyf.lib.util.ClientType
+
+class ForegroundViewModel(application: Application) : SysMessageViewModel(application) {
+ override fun clientType(): ClientType {
+ return ClientType.Foreground
+ }
+}
\ No newline at end of file
diff --git a/foreground/src/main/java/com/gyf/csams/message/ui/SysMessageActivity.kt b/foreground/src/main/java/com/gyf/csams/message/ui/SysMessageActivity.kt
index bad91f8..3b7316f 100644
--- a/foreground/src/main/java/com/gyf/csams/message/ui/SysMessageActivity.kt
+++ b/foreground/src/main/java/com/gyf/csams/message/ui/SysMessageActivity.kt
@@ -18,12 +18,17 @@ import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
-import com.gyf.csams.message.model.*
+import com.gyf.csams.message.model.ForegroundViewModel
+import com.gyf.csams.message.model.MessageType
import com.gyf.csams.uikit.Background
import com.gyf.csams.uikit.BackgroundImage
import com.gyf.csams.uikit.TextTopAppBar
+import com.gyf.lib.model.ActCheckContent
+import com.gyf.lib.model.JoinContent
+import com.gyf.lib.model.RenameContent
import com.gyf.lib.uikit.Body
import com.gyf.lib.uikit.MainColumnFrame
+import com.gyf.lib.util.NotificationVo
import com.gyf.lib.util.format
import java.util.*
@@ -54,7 +59,7 @@ class SysMessageActivity : ComponentActivity() {
@Composable
private fun MessageList(
modifier: Modifier = Modifier,
- model: SysMessageViewModel = viewModel()
+ model: ForegroundViewModel = viewModel()
) {
val listState = rememberLazyListState()
val list by model.data.observeAsState()
diff --git a/foreground/src/main/java/com/gyf/csams/uikit/BaseView.kt b/foreground/src/main/java/com/gyf/csams/uikit/BaseView.kt
index 51c3582..4b22214 100644
--- a/foreground/src/main/java/com/gyf/csams/uikit/BaseView.kt
+++ b/foreground/src/main/java/com/gyf/csams/uikit/BaseView.kt
@@ -23,7 +23,6 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -591,7 +590,6 @@ fun MainContent() {
.padding(32.dp),
verticalArrangement = Arrangement.spacedBy(24.dp)
) {
- var textState by remember { mutableStateOf(TextFieldValue()) }
val localFocusManager = LocalFocusManager.current
val focusRequester = FocusRequester()
diff --git a/foreground/src/main/java/com/gyf/csams/uikit/ViewModel.kt b/foreground/src/main/java/com/gyf/csams/uikit/ViewModel.kt
index 23b5e63..f3014f4 100644
--- a/foreground/src/main/java/com/gyf/csams/uikit/ViewModel.kt
+++ b/foreground/src/main/java/com/gyf/csams/uikit/ViewModel.kt
@@ -8,11 +8,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.google.gson.reflect.TypeToken
import com.gyf.csams.R
-import com.gyf.csams.util.SimpleCallback
-import com.gyf.lib.util.Api
-import com.gyf.lib.util.HttpClient
-import com.gyf.lib.util.ImageUtil
-import com.gyf.lib.util.MainApi
+import com.gyf.lib.util.*
import com.orhanobut.logger.Logger
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
@@ -57,7 +53,7 @@ class ImageViewModel(application: Application) : AndroidViewModel(application) {
HttpClient.get(
url = urlPath,
- SimpleCallback>("获取轮播图", onSuccess = {
+ HttpCallback>("获取轮播图", onSuccess = {
_imageUrls.postValue(it.body)
var index = 0
_imageUrls.value?.apply {
@@ -81,7 +77,7 @@ class ImageViewModel(application: Application) : AndroidViewModel(application) {
Logger.e("无法从接口地址:${urlPath}获取图片url列表")
_error.postValue(it)
defaultLoad()
- }, type = object : TypeToken>() {}.type)
+ }, typeToken = object : TypeToken>>() {}.type)
)
}.apply {
start()
diff --git a/foreground/src/main/java/com/gyf/csams/util/GsonUtil.kt b/foreground/src/main/java/com/gyf/csams/util/GsonUtil.kt
index bb35c32..47c6e63 100644
--- a/foreground/src/main/java/com/gyf/csams/util/GsonUtil.kt
+++ b/foreground/src/main/java/com/gyf/csams/util/GsonUtil.kt
@@ -2,8 +2,14 @@ package com.gyf.csams.util
import com.google.gson.*
import com.google.gson.reflect.TypeToken
-import com.gyf.csams.association.model.*
+import com.gyf.csams.association.model.ANSWER_SIZE
+import com.gyf.csams.association.model.ANSWER_TEXT_LENGTH
+import com.gyf.csams.association.model.QUESTION_TEXT_LENGTH
import com.gyf.lib.uikit.StringForm
+import com.gyf.lib.util.ChoiceQuestionVo
+import com.gyf.lib.util.Exam
+import com.gyf.lib.util.ExamType
+import com.gyf.lib.util.OpenQuestionsVo
import java.lang.reflect.Type
class OpenQuestionsVoSerializer : JsonSerializer {
diff --git a/foreground/src/main/java/com/gyf/csams/util/HttpCallback.kt b/foreground/src/main/java/com/gyf/csams/util/HttpCallback.kt
index 6cf0235..49122ba 100644
--- a/foreground/src/main/java/com/gyf/csams/util/HttpCallback.kt
+++ b/foreground/src/main/java/com/gyf/csams/util/HttpCallback.kt
@@ -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.lib.util.ApiResponse
+import com.gyf.lib.util.Exam
import com.gyf.lib.util.HttpCallback
import java.lang.reflect.Type
@@ -14,9 +14,9 @@ import java.lang.reflect.Type
* @property action
* @property onSuccess
* @property onFail
- * @property type
+
*/
-class SimpleCallback(
+class ExamCallback(
private val action: String,
private val onSuccess: (res: ApiResponse) -> Unit,
private val onFail: (error: String) -> Unit,
diff --git a/foreground/src/main/res/values-en/strings.xml b/foreground/src/main/res/values-en/strings.xml
index f9f4b66..3583d49 100644
--- a/foreground/src/main/res/values-en/strings.xml
+++ b/foreground/src/main/res/values-en/strings.xml
@@ -15,4 +15,5 @@
入学年份(四位)+班级代码(两位)+学生代码(两位)
同学您好\n
欢迎使用
+ 再次申请
\ No newline at end of file
diff --git a/foreground/src/main/res/values-zh/strings.xml b/foreground/src/main/res/values-zh/strings.xml
index f9f4b66..3583d49 100644
--- a/foreground/src/main/res/values-zh/strings.xml
+++ b/foreground/src/main/res/values-zh/strings.xml
@@ -15,4 +15,5 @@
入学年份(四位)+班级代码(两位)+学生代码(两位)
同学您好\n
欢迎使用
+ 再次申请
\ No newline at end of file
diff --git a/foreground/src/main/res/values/strings.xml b/foreground/src/main/res/values/strings.xml
index 3730508..36dbfa6 100644
--- a/foreground/src/main/res/values/strings.xml
+++ b/foreground/src/main/res/values/strings.xml
@@ -15,4 +15,5 @@
入学年份(四位)+班级代码(两位)+学生代码(两位)
同学您好\n
欢迎使用
+ 再次申请
\ No newline at end of file
diff --git a/foreground/src/test/java/com/gyf/csams/ExampleUnitTest.kt b/foreground/src/test/java/com/gyf/csams/ExampleUnitTest.kt
index 87a7a5c..1d75841 100644
--- a/foreground/src/test/java/com/gyf/csams/ExampleUnitTest.kt
+++ b/foreground/src/test/java/com/gyf/csams/ExampleUnitTest.kt
@@ -2,6 +2,7 @@ package com.gyf.csams
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
+import com.gyf.lib.uikit.StringForm
import com.gyf.lib.util.ApiResponse
import com.gyf.lib.util.randomChinese
import org.junit.Assert.assertEquals
@@ -39,9 +40,12 @@ class ExampleUnitTest {
repeat(100) {
println(randomChinese())
}
+ }
-// println(java.time.format.DateTimeFormatter.ISO_INSTANT
-// .format(java.time.Instant.ofEpochMilli(1532358895000)))
+ @Test
+ fun testFind() {
+ val s = StringForm(formDesc = "", textLength = 3)
+ println("${s.formValue.value}")
}
@Test
diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts
index 3da2b89..05334b4 100644
--- a/lib/build.gradle.kts
+++ b/lib/build.gradle.kts
@@ -54,12 +54,13 @@ dependencies {
//生命周期组件版本
val lifecycle_version = "2.3.1"
//https://developer.android.com/topic/libraries/architecture/workmanager/basics?hl=zh-cn
- val work_version = "2.5.0"
val room_version = "2.3.0"
- // Kotlin + coroutines
- api("androidx.work:work-runtime-ktx:$work_version")
-
+ val accompanist_version = "0.10.0"
+ //https://github.com/google/accompanist
+ 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 调整应用,同时还支持旧设备。
* https://developer.android.com/jetpack/androidx/releases/core
diff --git a/lib/src/main/java/com/gyf/lib/model/AbstractLoginViewModel.kt b/lib/src/main/java/com/gyf/lib/model/AbstractLoginViewModel.kt
index 14211d6..8891b86 100644
--- a/lib/src/main/java/com/gyf/lib/model/AbstractLoginViewModel.kt
+++ b/lib/src/main/java/com/gyf/lib/model/AbstractLoginViewModel.kt
@@ -30,7 +30,7 @@ abstract class AbstractLoginViewModel(application: Application) : AndroidViewMod
/**
* 完成登录状态
*/
- private val _finishLogin = MutableLiveData()
+ protected val _finishLogin = MutableLiveData()
val finishLogin: LiveData = _finishLogin
abstract fun checkForm(): Boolean
@@ -55,9 +55,9 @@ abstract class AbstractLoginViewModel(application: Application) : AndroidViewMod
val id = "${id.formValue.value}"
val password = "${password.formValue.value}"
Logger.i("使用账号:$id,密码:$password 进行登录")
- HttpClient.post(
- url,
- HttpCallback(
+
+ val call = when (clientType) {
+ ClientType.Background -> HttpCallback(
action = loginDesc,
onSuccess = {
Logger.i(it.message)
@@ -66,16 +66,40 @@ abstract class AbstractLoginViewModel(application: Application) : AndroidViewMod
it.body?.let {
val db = AppDatabase.getInstance(context)
viewModelScope.launch {
- TokenManager.token = it
- db?.tokenDao()?.save(token = it)
+ TokenManager.init(it)
+ db?.tokenDao()?.save(token = it.token)
}.invokeOnCompletion {
_finishLogin.postValue(true)
}
}
},
onFail = { callback(it) },
- type = object : TypeToken>() {}.type
- ),
+ typeToken = object : TypeToken>() {}.type
+ )
+ ClientType.Foreground -> HttpCallback(
+ action = loginDesc,
+ onSuccess = {
+ Logger.i(it.message)
+ callback(it.message)
+ val context = getApplication().applicationContext
+ it.body?.let {
+ val db = AppDatabase.getInstance(context)
+ viewModelScope.launch {
+ TokenManager.init(it)
+ db?.tokenDao()?.save(token = it.token)
+ }.invokeOnCompletion {
+ _finishLogin.postValue(true)
+ }
+ }
+ },
+ onFail = { callback(it) },
+ typeToken = object : TypeToken>() {}.type
+ )
+ }
+
+ HttpClient.post(
+ url,
+ call,
jsonParam = loginParam()
)
} else {
@@ -91,8 +115,7 @@ abstract class AbstractLoginViewModel(application: Application) : AndroidViewMod
* @param callback
*/
fun logout(context: Activity, callback: (message: String) -> Unit) {
- TokenManager.token?.let {
- Logger.i("帐号${it.id}将要退出登录")
+
viewModelScope.launch {
HttpClient.post(
Api.buildUrl(AccountApi.Logout),
@@ -112,16 +135,16 @@ abstract class AbstractLoginViewModel(application: Application) : AndroidViewMod
)
)
}
- TokenManager.token = null
+ TokenManager.clear()
}
}
callback(it.message)
- }, onFail = { callback("退出登陆失败") },
- type = object : TypeToken>() {}.type
+ },
+ onFail = { callback("退出登陆失败") },
+ typeToken = object : TypeToken>() {}.type
),
- jsonParam = OnlyToken(token = it, clientType = clientType)
+ jsonParam = OnlyToken(clientType = clientType)
)
- }
}
}
}
\ No newline at end of file
diff --git a/lib/src/main/java/com/gyf/lib/model/ApplyViewModel.kt b/lib/src/main/java/com/gyf/lib/model/ApplyViewModel.kt
index 68c138b..6f8454f 100644
--- a/lib/src/main/java/com/gyf/lib/model/ApplyViewModel.kt
+++ b/lib/src/main/java/com/gyf/lib/model/ApplyViewModel.kt
@@ -5,6 +5,9 @@ import com.gyf.lib.R
import com.gyf.lib.uikit.StringForm
abstract class ApplyViewModel(application: Application) : ScrollViewModel(application) {
- val approverOrigin =
- StringForm(formDesc = application.getString(R.string.approver_origin), textLength = 30)
+ val approveOrigin =
+ StringForm(
+ formDesc = application.getString(R.string.first_approver_origin),
+ textLength = 30
+ )
}
\ No newline at end of file
diff --git a/lib/src/main/java/com/gyf/lib/model/InitViewModel.kt b/lib/src/main/java/com/gyf/lib/model/InitViewModel.kt
index 5c2d119..d7e4633 100644
--- a/lib/src/main/java/com/gyf/lib/model/InitViewModel.kt
+++ b/lib/src/main/java/com/gyf/lib/model/InitViewModel.kt
@@ -9,6 +9,7 @@ import com.google.gson.reflect.TypeToken
import com.gyf.lib.util.*
import com.orhanobut.logger.Logger
import kotlinx.coroutines.launch
+import java.lang.reflect.Type
class InitViewModel(application: Application) : AndroidViewModel(application) {
/**
@@ -17,7 +18,6 @@ class InitViewModel(application: Application) : AndroidViewModel(application) {
private val _isNetWorkWorking = MutableLiveData()
val isNetWorkWorking: LiveData = _isNetWorkWorking
-
init {
checkServer()
}
@@ -32,7 +32,7 @@ class InitViewModel(application: Application) : AndroidViewModel(application) {
}, onFail = {
Logger.e(it)
_isNetWorkWorking.postValue(false)
- }, type = object : TypeToken>() {}.type)
+ }, typeToken = object : TypeToken>() {}.type)
)
}
@@ -41,7 +41,10 @@ class InitViewModel(application: Application) : AndroidViewModel(application) {
/**
* 查询本地是否有且只有一个用户token,如果有则自动登录
*/
- fun hasOnlyUserToken(onSuccess: () -> Unit, onFail: () -> Unit, api: AccountApi) {
+ fun hasOnlyUserToken(
+ onSuccess: () -> Unit, onFail: () -> Unit, api: AccountApi,
+ typeToken: Type
+ ) {
viewModelScope.launch {
val context = getApplication()
val db = AppDatabase.getInstance(context)
@@ -53,14 +56,12 @@ class InitViewModel(application: Application) : AndroidViewModel(application) {
Logger.i("${action}api=$url")
HttpClient.post(
url,
- HttpCallback(
+ HttpCallback(
action = action,
onSuccess = { it ->
it.body?.let {
Logger.i("token校验结果:${it}")
- if (it) {
- TokenManager.token = currentToken
- }
+ TokenManager.init(it)
onSuccess()
}
@@ -68,11 +69,10 @@ class InitViewModel(application: Application) : AndroidViewModel(application) {
onFail = {
Logger.e(it)
onFail()
- },
- type = object : TypeToken>() {}.type
- ),
+ }, typeToken = typeToken),
jsonParam = currentToken
)
+
} else if (tokenList != null && tokenList.size > 1) {
//TODO 实现切换历史登录帐号
diff --git a/lib/src/main/java/com/gyf/lib/model/ScrollViewModel.kt b/lib/src/main/java/com/gyf/lib/model/ScrollViewModel.kt
index c99f054..f31ae21 100644
--- a/lib/src/main/java/com/gyf/lib/model/ScrollViewModel.kt
+++ b/lib/src/main/java/com/gyf/lib/model/ScrollViewModel.kt
@@ -11,8 +11,13 @@ abstract class ScrollViewModel(application: Application) : AndroidViewModel(a
abstract val initSize: Int
+
//加载列表
- abstract fun load()
+ @Deprecated("")
+ open fun load() {
+ }
+
+ open fun load(callback: (message: String) -> Unit) {}
//加载更多数据
abstract fun loadMore(callback: (message: String) -> Unit)
diff --git a/foreground/src/main/java/com/gyf/csams/message/model/SysMessageViewModel.kt b/lib/src/main/java/com/gyf/lib/model/SysMessageViewModel.kt
similarity index 60%
rename from foreground/src/main/java/com/gyf/csams/message/model/SysMessageViewModel.kt
rename to lib/src/main/java/com/gyf/lib/model/SysMessageViewModel.kt
index de7aa97..c046f38 100644
--- a/foreground/src/main/java/com/gyf/csams/message/model/SysMessageViewModel.kt
+++ b/lib/src/main/java/com/gyf/lib/model/SysMessageViewModel.kt
@@ -1,12 +1,10 @@
-package com.gyf.csams.message.model
+package com.gyf.lib.model
import android.app.Application
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.google.gson.reflect.TypeToken
-import com.gyf.csams.util.SimpleCallback
-import com.gyf.lib.model.ScrollViewModel
import com.gyf.lib.util.*
import com.orhanobut.logger.Logger
import kotlinx.coroutines.launch
@@ -19,8 +17,6 @@ enum class SystemType(val desc: String) {
}
-data class NotificationVo(val title: String, val content: String, val id: Int, val createTime: Long)
-
/**
* 通知内容
*
@@ -82,7 +78,8 @@ data class RenameContent(
* 系统通知数据状态管理
*
*/
-class SysMessageViewModel(application: Application) : ScrollViewModel(application) {
+abstract class SysMessageViewModel(application: Application) :
+ ScrollViewModel(application) {
val title = "系统通知"
override val initSize: Int = 10
@@ -90,43 +87,43 @@ class SysMessageViewModel(application: Application) : ScrollViewModel()
val currentPage: LiveData = _currentPage
+ abstract fun clientType(): ClientType
+
init {
load()
}
+
/**
*加载通知列表
*
*/
- override fun load() {
+ final override fun load() {
viewModelScope.launch {
- TokenManager.token?.let { it ->
- HttpClient.post(
- Api.buildUrl(NotificationApi.List),
- SimpleCallback>(
- action = "获取通知列表",
- onSuccess = {
- it.body?.let {
- _data.postValue(it)
- }
- Logger.i(it.message)
- },
- onFail = {
- Logger.e(it)
- },
- type = object :
- TypeToken>>() {}.type
- ),
- jsonParam = NotificationDto(
- receiverId = it.id,
- receiverClient = ClientType.Foreground,
- token = it, page = PageDto(
- currentPage = _currentPage.value ?: 1,
- pageSize = initSize
- )
+ HttpClient.post(
+ Api.buildUrl(NotificationApi.List),
+ HttpCallback>(
+ action = "获取通知列表",
+ onSuccess = {
+ it.body?.let {
+ _data.postValue(it)
+ }
+ Logger.i(it.message)
+ },
+ onFail = {
+ Logger.e(it)
+ },
+ typeToken = object :
+ TypeToken>>() {}.type
+ ),
+ jsonParam = NotificationDto(
+ receiverId = TokenManager.getToken().id,
+ receiverClient = clientType(), page = PageDto(
+ currentPage = _currentPage.value ?: 1,
+ pageSize = initSize
)
)
- }
+ )
}
}
diff --git a/lib/src/main/java/com/gyf/lib/service/MessageService.kt b/lib/src/main/java/com/gyf/lib/service/MessageService.kt
index 0fd9f00..316e0e6 100644
--- a/lib/src/main/java/com/gyf/lib/service/MessageService.kt
+++ b/lib/src/main/java/com/gyf/lib/service/MessageService.kt
@@ -32,13 +32,11 @@ class MessageService : JobIntentService() {
}
override fun onHandleWork(intent: Intent) {
- TokenManager.token?.let { it ->
HttpClient.postAsync>(
url = Api.buildUrl(NotificationApi.Pull),
jsonParam = NotificationDto(
- receiverId = it.id,
- receiverClient = clientType,
- token = it
+ receiverId = TokenManager.getToken().id,
+ receiverClient = clientType
),
type = object : TypeToken>>() {}.type
)?.let { it1 ->
@@ -57,7 +55,6 @@ class MessageService : JobIntentService() {
notify(it.id, builder.build())
}
}
- }
}
}
}
\ No newline at end of file
diff --git a/lib/src/main/java/com/gyf/lib/uikit/AbstractInitActivity.kt b/lib/src/main/java/com/gyf/lib/uikit/AbstractInitActivity.kt
index 9e67730..fe51c67 100644
--- a/lib/src/main/java/com/gyf/lib/uikit/AbstractInitActivity.kt
+++ b/lib/src/main/java/com/gyf/lib/uikit/AbstractInitActivity.kt
@@ -12,12 +12,14 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.gyf.lib.BuildConfig
import com.gyf.lib.model.InitViewModel
import com.gyf.lib.util.AccountApi
+import com.gyf.lib.util.OwnInfoVo
import com.orhanobut.logger.Logger
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
+import java.lang.reflect.Type
-abstract class AbstractInitActivity : ComponentActivity() {
+abstract class AbstractInitActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
@@ -49,13 +51,15 @@ abstract class AbstractInitActivity : ComponentActivity() {
abstract val api: AccountApi
+ abstract val typeToken: Type
+
private fun init(initViewModel: InitViewModel) {
//后台检查token
- initViewModel.hasOnlyUserToken(onSuccess = {
+ initViewModel.hasOnlyUserToken(onSuccess = {
startActivity(Intent(this, main))
}, onFail = {
startActivity(Intent(this, login))
- }, api = api)
+ }, api = api, typeToken = typeToken)
GlobalScope.launch {
delay(1000)
finish()
diff --git a/lib/src/main/java/com/gyf/lib/uikit/MainFrame.kt b/lib/src/main/java/com/gyf/lib/uikit/MainFrame.kt
index 6120a9e..494261f 100644
--- a/lib/src/main/java/com/gyf/lib/uikit/MainFrame.kt
+++ b/lib/src/main/java/com/gyf/lib/uikit/MainFrame.kt
@@ -8,6 +8,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
+import com.google.accompanist.insets.ExperimentalAnimatedInsets
+import com.google.accompanist.insets.ProvideWindowInsets
import com.gyf.lib.uikit.theme.CSAMSTheme
@@ -157,9 +159,24 @@ fun Body(content: @Composable () -> Unit) {
}
}
+@ExperimentalAnimatedInsets
+@Composable
+fun ImeBody(content: @Composable () -> Unit) {
+ CSAMSTheme {
+ ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
+ Surface(color = MaterialTheme.colors.background) {
+ val scaffoldState = rememberScaffoldState()
+ Scaffold(scaffoldState = scaffoldState) {
+ content()
+ ShowSnackbar(scaffoldState = scaffoldState)
+ }
+ }
+ }
+ }
+}
@Composable
-fun TestBody(content: @Composable (nav: NavHostController, scaffoldState: ScaffoldState) -> Unit) {
+fun NavBody(content: @Composable (nav: NavHostController, scaffoldState: ScaffoldState) -> Unit) {
CSAMSTheme {
Surface(color = MaterialTheme.colors.background) {
val navController = rememberNavController()
@@ -170,4 +187,5 @@ fun TestBody(content: @Composable (nav: NavHostController, scaffoldState: Scaffo
}
}
}
-}
\ No newline at end of file
+}
+
diff --git a/lib/src/main/java/com/gyf/lib/uikit/Profile.kt b/lib/src/main/java/com/gyf/lib/uikit/Profile.kt
index faed256..fadc00e 100644
--- a/lib/src/main/java/com/gyf/lib/uikit/Profile.kt
+++ b/lib/src/main/java/com/gyf/lib/uikit/Profile.kt
@@ -12,21 +12,23 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
-import com.gyf.lib.util.ImageUtil
+import com.gyf.lib.util.*
-abstract class PersonInfoVo {
- abstract val name: String
- abstract val duty: String
- abstract val headImg: String
- abstract val desc: String
-}
-
@Composable
fun Profile(
modifier: Modifier,
- personInfoVo: PersonInfoVo,
- duty: @Composable () -> Unit = { Text(text = personInfoVo.duty) }
+ personInfoVo: PersonInfoVo = TokenManager.getOwnInfo(),
+ duty: @Composable () -> Unit = {
+ Text(
+ text = when (personInfoVo) {
+ is UserVo -> personInfoVo.manager?.duty?.desc ?: "----"
+ is ManagerVo -> personInfoVo.duty.desc
+ is ManagerInfoVo -> personInfoVo.duty.desc
+ else -> throw IllegalArgumentException("个人信息类型错误:${personInfoVo}")
+ }
+ )
+ }
) {
var headImg: ImageBitmap? by remember {
mutableStateOf(null)
diff --git a/lib/src/main/java/com/gyf/lib/util/Api.kt b/lib/src/main/java/com/gyf/lib/util/Api.kt
index 8caf4b2..6ed85a3 100644
--- a/lib/src/main/java/com/gyf/lib/util/Api.kt
+++ b/lib/src/main/java/com/gyf/lib/util/Api.kt
@@ -33,7 +33,6 @@ enum class AccountApi(val path: String) : UrlPath {
//后台登陆
BackgroundLogin("/login/${ClientType.Background.name.toLowerCase(Locale.ROOT)}"),
-
//前台令牌校验
ForegroundToken("${ForegroundLogin.path}/token"),
@@ -74,8 +73,12 @@ enum class MainApi(val path: String) : UrlPath {
*/
enum class AssociationApi(val path: String) : UrlPath {
Logo("/uploadLogo"),
- Register("/register");
-
+ Register("/register"),
+ Accept("/accept"),
+ List("/list"),
+ Check("/check"),
+ Audit("/audit"),
+ Read("/read");
override fun build(): String {
return "/api/association${this.path}"
diff --git a/lib/src/main/java/com/gyf/lib/util/BottomButton.kt b/lib/src/main/java/com/gyf/lib/util/BottomButton.kt
index 6f32556..ee725d7 100644
--- a/lib/src/main/java/com/gyf/lib/util/BottomButton.kt
+++ b/lib/src/main/java/com/gyf/lib/util/BottomButton.kt
@@ -22,7 +22,8 @@ fun BottomButton(
modifier: Modifier = Modifier,
enabled: Boolean = true,
@StringRes confirmDesc: Int = R.string.confirm_btn,
- @StringRes backDesc: Int = R.string.back_btn,
+ @StringRes backDesc: Int? = R.string.back_btn,
+ onBack: (() -> Unit)? = null,
onConfirm: () -> Unit
) {
val context = LocalContext.current as Activity
@@ -34,11 +35,16 @@ fun BottomButton(
) {
Text(text = stringResource(id = confirmDesc))
}
- Spacer(modifier = Modifier.width(10.dp))
- OutlinedButton(onClick = {
- context.onBackPressed()
- }, modifier = Modifier.background(color = MaterialTheme.colors.secondary)) {
- Text(text = stringResource(id = backDesc))
+
+ if (backDesc != null) {
+ Spacer(modifier = Modifier.width(10.dp))
+ OutlinedButton(onClick = {
+ if (onBack == null) context.onBackPressed() else onBack()
+ }, modifier = Modifier.background(color = MaterialTheme.colors.secondary)) {
+ Text(text = stringResource(id = backDesc))
+ }
}
+
}
-}
\ No newline at end of file
+}
+
diff --git a/lib/src/main/java/com/gyf/lib/util/HttpUtil.kt b/lib/src/main/java/com/gyf/lib/util/HttpUtil.kt
index a75e57f..6d2cfa0 100644
--- a/lib/src/main/java/com/gyf/lib/util/HttpUtil.kt
+++ b/lib/src/main/java/com/gyf/lib/util/HttpUtil.kt
@@ -1,6 +1,7 @@
package com.gyf.lib.util
import com.google.gson.Gson
+import com.google.gson.JsonSyntaxException
import com.orhanobut.logger.Logger
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
@@ -116,8 +117,9 @@ object HttpClient {
* @param url
* @param callback
*/
- fun uploadFile(url: String, callback: Callback, token: Token, vararg fileList: File) {
+ fun uploadFile(url: String, callback: Callback, vararg fileList: File) {
Logger.i("request url=$url")
+ val token = TokenManager.getToken()
val body = MultipartBody.Builder()
.addFormDataPart("id", token.id.toString())
.addFormDataPart("token", token.token)
@@ -155,9 +157,9 @@ interface GsonBuilderInterface {
open class HttpCallback(
private val action: String,
- private val onSuccess: (res: ApiResponse) -> Unit,
- private val onFail: (error: String) -> Unit,
- private val type: Type
+ private val onSuccess: (res: ApiResponse) -> Unit = { Logger.i(it.message) },
+ private val onFail: (error: String) -> Unit = { Logger.e(it) },
+ private val typeToken: Type
) : Callback, GsonBuilderInterface {
override val gson: Gson = Gson()
@@ -178,11 +180,18 @@ open class HttpCallback(
val body = response.body
if (body != null && body.contentType()?.subtype == "json") {
val jsonRes = body.string()
- Logger.json(jsonRes)
- val res: ApiResponse = gson.fromJson(jsonRes, type)
- Logger.i("json解析成功:$res")
+ Logger.i(jsonRes)
+ try {
+ val res: ApiResponse = gson.fromJson(jsonRes, typeToken)
+ onSuccess(res)
+ } catch (e: JsonSyntaxException) {
+ Logger.e(e, "json反序列化成${typeToken}失败")
+ onFail("json反序列化成${typeToken}失败")
+ } catch (e: Exception) {
+ Logger.e(e, "发生未知错误")
+ onFail("发生未知错误")
+ }
- onSuccess(res)
} else {
onFail("${action}失败,请联系管理员")
Logger.e("无法解析${action}请求响应数据:,响应码:${response.code},${response.body}")
diff --git a/lib/src/main/java/com/gyf/lib/util/TokenUtil.kt b/lib/src/main/java/com/gyf/lib/util/TokenUtil.kt
index 484c1c9..08f2431 100644
--- a/lib/src/main/java/com/gyf/lib/util/TokenUtil.kt
+++ b/lib/src/main/java/com/gyf/lib/util/TokenUtil.kt
@@ -17,16 +17,11 @@ data class Token(
)
abstract class ClientBaseVo {
- abstract val token: Token
+ val token: Token = TokenManager.getToken()
abstract val clientType: ClientType
}
-abstract class BaseToken {
- abstract val token: Token
-}
-
data class OnlyToken(
- override val token: Token = TokenManager.token ?: throw IllegalArgumentException("无法获取token"),
override val clientType: ClientType
) : ClientBaseVo()
@@ -46,8 +41,39 @@ interface TokenDao {
}
object TokenManager {
- var token: Token? = null
+ private var ownInfo: OwnInfoVo? = null
+ private lateinit var personInfo: PersonInfoVo
+
+ fun init(ownInfo: OwnInfoVo) {
+ this.ownInfo = ownInfo
+ when (ownInfo) {
+ is ManagerVo -> this.personInfo = ManagerInfoVo(
+ duty = ownInfo.duty,
+ name = ownInfo.name,
+ headImg = ownInfo.headImg,
+ desc = ownInfo.desc
+ )
+ is UserVo -> this.personInfo =
+ UserInfoVo(name = ownInfo.name, headImg = ownInfo.headImg, desc = ownInfo.desc)
+ else -> throw IllegalArgumentException("token失败")
+ }
+ }
+
+ fun clear() {
+ ownInfo = null
+ }
+ fun getOwnInfo(): OwnInfoVo {
+ return ownInfo ?: throw IllegalArgumentException("token没有初始化,非法调用")
+ }
+
+ fun getPersonInfo(): PersonInfoVo {
+ return personInfo
+ }
+
+ fun getToken(): Token {
+ return ownInfo?.token ?: throw IllegalArgumentException("token没有初始化,非法调用")
+ }
}
diff --git a/lib/src/main/java/com/gyf/lib/util/Vo.kt b/lib/src/main/java/com/gyf/lib/util/Vo.kt
new file mode 100644
index 0000000..4a61966
--- /dev/null
+++ b/lib/src/main/java/com/gyf/lib/util/Vo.kt
@@ -0,0 +1,477 @@
+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 associationMemberVo: AssociationMemberVo?
+) : 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
+)
+
+
+data class ActivityMemberVo(val studentId: String, val name: String)
+
+/**
+ * 活动成员
+ *
+ * @property organizer
+ * @property participant
+ */
+data class ActivityMembersVo(
+ val organizer: ActivityMemberVo,
+ val participant: MutableList?
+)
+
+
+/**
+ * 图片
+ * @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,
+ val propaganda: MutableList,
+ val publicRelationsDepartment: MutableList
+)
+
+
+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 id: 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 id: 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("审核完成")
+}
+
+data class AssociationMemberVo(
+ val association: AssociationVo,
+ val isHead: Boolean
+)
+
+//用户社团
+data class AssociationCheckVo(
+ override val id: Int,
+ override val name: String,
+ override val desc: String,
+ override val logo: String,
+ override val faculty: AssociationFaculty,
+ override val level: AssociationLevel?,
+ val checkStatus: CheckStatus,
+ val applyTime: Long,
+ val firstCause: String,
+ val lastCause: String?,
+ val fileId: Int
+) : 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 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,
+ 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 MemberVo(val name: 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 id: Int?, val name: String, val desc: String, val fileId: Int,
+ override val clientType: ClientType = ClientType.Foreground
+) : ClientBaseVo()
+
+/**
+ * 社团注册审核记录
+ *
+ */
+data class DisposeRegInfoVo(
+ val name: String,
+ val desc: String,
+ val logo: String,
+ val log: AuditLoggingVo
+)
+
+/**
+ * 通用审核记录
+ *
+ * @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 regId
+ * @property clientType
+ */
+data class AcceptRegAssociation(
+ val regId: Int,
+ val isFirstAccept: Boolean,
+ override val clientType: ClientType = ClientType.Background
+) : ClientBaseVo()
+
+/**
+ * 社团注册资料审核
+ *
+ * @property regId
+ * @property result
+ * @property cause
+ * @property clientType
+ */
+data class CheckRegVo(
+ val regId: Int, val result: Boolean, val cause: String,
+ override val clientType: ClientType = ClientType.Background
+) : ClientBaseVo()
+
+/**
+ * 换名申请表
+ *
+ * @property studentId 学号
+ * @property oldName 社团原名
+ * @property newName 社团新名
+ * @property reason 申请理由
+ */
+data class RenameVo(
+ val studentId: String,
+ val oldName: String,
+ val newName: String,
+ val reason: String
+)
\ No newline at end of file
diff --git a/lib/src/main/java/com/gyf/lib/util/vo.kt b/lib/src/main/java/com/gyf/lib/util/vo.kt
deleted file mode 100644
index 4b5e8d6..0000000
--- a/lib/src/main/java/com/gyf/lib/util/vo.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.gyf.lib.util
-
-
-data class NotificationVo(val title: String, val content: String, val id: Int)
-
-data class PageDto(val currentPage: Long, val pageSize: Int = 10)
-
-data class NotificationDto(
- val receiverId: Int,
- val receiverClient: ClientType,
- override val token: Token,
- val page: PageDto? = null,
- override val clientType: ClientType = receiverClient
-) : ClientBaseVo()
-
-
-/**
- * 客户端类型
- *
- */
-enum class ClientType {
- //前台
- Foreground,
-
- //后台
- Background
-}
\ No newline at end of file
diff --git a/lib/src/main/res/values-en/strings.xml b/lib/src/main/res/values-en/strings.xml
index 45a448e..1d82610 100644
--- a/lib/src/main/res/values-en/strings.xml
+++ b/lib/src/main/res/values-en/strings.xml
@@ -17,9 +17,17 @@
社团原名
社团新名
申请理由
- 审批人
- 审核理由
+ 初审负责人
+ 初审意见
抱歉此功能尚未开放
活动质量汇报单
登录
+ 社团注册资料
+ 社团简介
+ 社团logo
+ 社团名称
+ 审核结果
+ 复审
+ 审核阶段
+ 复审意见
\ No newline at end of file
diff --git a/lib/src/main/res/values-zh/strings.xml b/lib/src/main/res/values-zh/strings.xml
index 45a448e..1d82610 100644
--- a/lib/src/main/res/values-zh/strings.xml
+++ b/lib/src/main/res/values-zh/strings.xml
@@ -17,9 +17,17 @@
社团原名
社团新名
申请理由
- 审批人
- 审核理由
+ 初审负责人
+ 初审意见
抱歉此功能尚未开放
活动质量汇报单
登录
+ 社团注册资料
+ 社团简介
+ 社团logo
+ 社团名称
+ 审核结果
+ 复审
+ 审核阶段
+ 复审意见
\ No newline at end of file
diff --git a/lib/src/main/res/values/strings.xml b/lib/src/main/res/values/strings.xml
index 45a448e..1d82610 100644
--- a/lib/src/main/res/values/strings.xml
+++ b/lib/src/main/res/values/strings.xml
@@ -17,9 +17,17 @@
社团原名
社团新名
申请理由
- 审批人
- 审核理由
+ 初审负责人
+ 初审意见
抱歉此功能尚未开放
活动质量汇报单
登录
+ 社团注册资料
+ 社团简介
+ 社团logo
+ 社团名称
+ 审核结果
+ 复审
+ 审核阶段
+ 复审意见
\ No newline at end of file