parent
4145e3fbef
commit
9b12cef29c
@ -0,0 +1 @@ |
|||||||
|
336c59a7cdc6f9b18fecb981ae5b14f6b7366d90 |
@ -0,0 +1 @@ |
|||||||
|
a30262664371040b970f72f5089d69a476fed40b |
@ -0,0 +1 @@ |
|||||||
|
a524dd25e1d96e659662021decd71ed8bfce7a78 |
@ -0,0 +1 @@ |
|||||||
|
27a39082c3e76250c3bed8df065a0febcc36c901 |
@ -0,0 +1 @@ |
|||||||
|
95c6b9f9e380ae08145d3219b820d65a3a7b268b |
@ -0,0 +1,32 @@ |
|||||||
|
package com.gyf.csams.activity.model |
||||||
|
|
||||||
|
import android.app.Application |
||||||
|
import androidx.lifecycle.viewModelScope |
||||||
|
import com.google.gson.reflect.TypeToken |
||||||
|
import com.gyf.csams.module.ActivityVo |
||||||
|
import com.gyf.csams.module.ApiResponse |
||||||
|
import com.gyf.csams.module.FindTendencyVo |
||||||
|
import com.gyf.csams.module.TendencyType |
||||||
|
import com.gyf.lib.model.ScrollViewModel |
||||||
|
import com.gyf.lib.util.* |
||||||
|
import kotlinx.coroutines.launch |
||||||
|
|
||||||
|
class TendencyViewModel(application: Application) : |
||||||
|
ScrollViewModel<ActivityVo>(application = application) { |
||||||
|
|
||||||
|
fun load(type: TendencyType) { |
||||||
|
viewModelScope.launch { |
||||||
|
HttpClient.post( |
||||||
|
url = Api.buildUrl(ActivityApi.FindTendency), |
||||||
|
callback = HttpCallback<MutableList<ActivityVo>>( |
||||||
|
action = "加载${type.desc}活动", |
||||||
|
onSuccess = { |
||||||
|
it.body?.apply { _data.postValue(this) } |
||||||
|
}, |
||||||
|
typeToken = object : TypeToken<ApiResponse<MutableList<ActivityVo>>>() {}.type |
||||||
|
), |
||||||
|
jsonParam = FindTendencyVo(type = type, token = TokenManager.getToken()) |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
package com.gyf.csams.activity.ui |
||||||
|
|
||||||
|
import android.os.Bundle |
||||||
|
import androidx.activity.ComponentActivity |
||||||
|
import androidx.activity.compose.setContent |
||||||
|
import androidx.compose.foundation.layout.Arrangement |
||||||
|
import androidx.compose.foundation.layout.Row |
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth |
||||||
|
import androidx.compose.material.MaterialTheme |
||||||
|
import androidx.compose.material.Text |
||||||
|
import androidx.compose.runtime.LaunchedEffect |
||||||
|
import androidx.compose.runtime.getValue |
||||||
|
import androidx.compose.runtime.livedata.observeAsState |
||||||
|
import androidx.compose.ui.Modifier |
||||||
|
import androidx.lifecycle.viewmodel.compose.viewModel |
||||||
|
import com.gyf.csams.activity.model.TendencyViewModel |
||||||
|
import com.gyf.csams.module.TendencyType |
||||||
|
import com.gyf.csams.uikit.Activities |
||||||
|
import com.gyf.csams.uikit.Background |
||||||
|
import com.gyf.csams.uikit.BackgroundImage |
||||||
|
import com.gyf.lib.uikit.Body |
||||||
|
import com.gyf.lib.uikit.MainColumnFrame |
||||||
|
|
||||||
|
class TendencyActivity : ComponentActivity() { |
||||||
|
|
||||||
|
private val type: TendencyType |
||||||
|
get() { |
||||||
|
return intent.getSerializableExtra(TendencyType::class.java.name) as TendencyType |
||||||
|
} |
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) { |
||||||
|
super.onCreate(savedInstanceState) |
||||||
|
|
||||||
|
setContent { |
||||||
|
Body { |
||||||
|
MainColumnFrame(background = { |
||||||
|
Background( |
||||||
|
image = BackgroundImage.AssociationMain, |
||||||
|
alpha = 07F |
||||||
|
) |
||||||
|
}) { |
||||||
|
val model: TendencyViewModel = viewModel() |
||||||
|
LaunchedEffect(type) { |
||||||
|
model.load(type = type) |
||||||
|
} |
||||||
|
val data by model.data.observeAsState() |
||||||
|
Row( |
||||||
|
modifier = Modifier.fillMaxWidth(), |
||||||
|
horizontalArrangement = Arrangement.Center |
||||||
|
) { |
||||||
|
Text(text = "我的${type.desc}", style = MaterialTheme.typography.h4) |
||||||
|
} |
||||||
|
Activities(list = data, modifier = Modifier.fillMaxWidth()) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,72 @@ |
|||||||
|
package com.gyf.csams.uikit |
||||||
|
|
||||||
|
import android.content.Intent |
||||||
|
import androidx.compose.foundation.Image |
||||||
|
import androidx.compose.foundation.clickable |
||||||
|
import androidx.compose.foundation.layout.* |
||||||
|
import androidx.compose.foundation.lazy.LazyColumn |
||||||
|
import androidx.compose.foundation.lazy.rememberLazyListState |
||||||
|
import androidx.compose.material.Divider |
||||||
|
import androidx.compose.material.MaterialTheme |
||||||
|
import androidx.compose.material.Text |
||||||
|
import androidx.compose.runtime.Composable |
||||||
|
import androidx.compose.ui.Alignment |
||||||
|
import androidx.compose.ui.Modifier |
||||||
|
import androidx.compose.ui.platform.LocalContext |
||||||
|
import androidx.compose.ui.res.painterResource |
||||||
|
import androidx.compose.ui.unit.dp |
||||||
|
import com.gyf.csams.R |
||||||
|
import com.gyf.csams.activity.ui.ActivityDetailActivity |
||||||
|
import com.gyf.csams.module.ActivityVo |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 历史活动 |
||||||
|
* |
||||||
|
* @param modifier |
||||||
|
*/ |
||||||
|
@Composable |
||||||
|
private fun HistoryActivity(modifier: Modifier, activityVo: ActivityVo) { |
||||||
|
val context = LocalContext.current |
||||||
|
Box(modifier = modifier.clickable(onClick = { |
||||||
|
context.startActivity(Intent(context, ActivityDetailActivity::class.java).apply { |
||||||
|
putExtra(ActivityDetailActivity::class.java.name, activityVo.activityId) |
||||||
|
}) |
||||||
|
}), contentAlignment = Alignment.Center) { |
||||||
|
Image( |
||||||
|
painter = painterResource(id = R.drawable.history_activity_border), |
||||||
|
contentDescription = null, |
||||||
|
modifier = Modifier.fillMaxSize() |
||||||
|
) |
||||||
|
Image( |
||||||
|
painter = painterResource(id = R.drawable.ic_launcher_foreground), |
||||||
|
contentDescription = null, |
||||||
|
modifier = Modifier.fillMaxSize() |
||||||
|
) |
||||||
|
Text(text = activityVo.activityName) |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Composable |
||||||
|
fun Activities(modifier: Modifier = Modifier, list: List<ActivityVo>?) { |
||||||
|
val listState = rememberLazyListState() |
||||||
|
LazyColumn(state = listState, modifier = modifier) { |
||||||
|
list?.chunked(2)?.forEach { |
||||||
|
item { |
||||||
|
Row(modifier = Modifier.fillMaxWidth()) { |
||||||
|
HistoryActivity(modifier = Modifier.weight(0.4F), it[0]) |
||||||
|
Spacer(modifier = Modifier.weight(0.2F)) |
||||||
|
if (it.size == 2) HistoryActivity( |
||||||
|
modifier = Modifier.weight(0.4F), |
||||||
|
it[1] |
||||||
|
) |
||||||
|
else Box(modifier = Modifier.weight(0.4F)) |
||||||
|
} |
||||||
|
Spacer(modifier = Modifier.height(10.dp)) |
||||||
|
Divider(color = MaterialTheme.colors.background) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,125 +0,0 @@ |
|||||||
package com.gyf.csams.util |
|
||||||
|
|
||||||
import com.google.gson.* |
|
||||||
import com.google.gson.reflect.TypeToken |
|
||||||
import com.gyf.csams.association.model.* |
|
||||||
|
|
||||||
import com.gyf.lib.uikit.StringForm |
|
||||||
import java.lang.reflect.Type |
|
||||||
|
|
||||||
class OpenQuestionsVoSerializer : JsonSerializer<OpenQuestionsVo> { |
|
||||||
override fun serialize( |
|
||||||
vo: OpenQuestionsVo?, |
|
||||||
p1: Type?, |
|
||||||
p2: JsonSerializationContext? |
|
||||||
): JsonElement { |
|
||||||
val gson = Gson() |
|
||||||
val c = JsonObject() |
|
||||||
c.add("examType", gson.toJsonTree(vo?.examType?.name)) |
|
||||||
// c.add("question", gson.toJsonTree(vo?.question?.formValue?.value)) |
|
||||||
return c |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
class OpenQuestionsVoDeserializer : JsonDeserializer<OpenQuestionsVo> { |
|
||||||
override fun deserialize( |
|
||||||
json: JsonElement?, |
|
||||||
p1: Type?, |
|
||||||
p2: JsonDeserializationContext? |
|
||||||
): OpenQuestionsVo { |
|
||||||
val root = json?.asJsonObject |
|
||||||
val value = root?.get("question")?.asString |
|
||||||
val question = StringForm(formDesc = "问题", textLength = QUESTION_TEXT_LENGTH) |
|
||||||
if (value != null) { |
|
||||||
question.onChange(value) |
|
||||||
TODO() |
|
||||||
// return OpenQuestionsVo(question = question) |
|
||||||
} else { |
|
||||||
throw NullPointerException("问题无法解析!!!!") |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
class ChoiceQuestionVoSerializer : JsonSerializer<ChoiceQuestionVo> { |
|
||||||
override fun serialize( |
|
||||||
vo: ChoiceQuestionVo?, |
|
||||||
p1: Type?, |
|
||||||
p2: JsonSerializationContext? |
|
||||||
): JsonElement { |
|
||||||
val gson = Gson() |
|
||||||
val c = JsonObject() |
|
||||||
c.add("examType", gson.toJsonTree(vo?.examType?.name)) |
|
||||||
// c.add("question", gson.toJsonTree(vo?.question?.formValue?.value)) |
|
||||||
// c.add("answers", gson.toJsonTree(vo?.answers)) |
|
||||||
c.add("rightAnswer", gson.toJsonTree(vo?.rightAnswer)) |
|
||||||
return c |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
class ChoiceQuestionVoDeserializer : JsonDeserializer<ChoiceQuestionVo> { |
|
||||||
override fun deserialize( |
|
||||||
json: JsonElement?, |
|
||||||
p1: Type?, |
|
||||||
p2: JsonDeserializationContext? |
|
||||||
): ChoiceQuestionVo { |
|
||||||
val root = json?.asJsonObject |
|
||||||
val value = root?.get("question")?.asString |
|
||||||
val question = StringForm(formDesc = "问题", textLength = QUESTION_TEXT_LENGTH) |
|
||||||
if (value != null) { |
|
||||||
question.onChange(value) |
|
||||||
val gson = Gson() |
|
||||||
val answers: List<String> = |
|
||||||
gson.fromJson(root.get("answers"), object : TypeToken<List<String>>() {}.type) |
|
||||||
if (answers.size != ANSWER_SIZE) { |
|
||||||
throw IllegalArgumentException("选项数量!=$QUESTION_TEXT_LENGTH") |
|
||||||
} |
|
||||||
val rightAnswer = root.get("rightAnswer").asInt |
|
||||||
TODO() |
|
||||||
// return ChoiceQuestionVo( |
|
||||||
// question = question, |
|
||||||
// answers = answers.map { |
|
||||||
// StringForm( |
|
||||||
// formDesc = "选项", |
|
||||||
// textLength = ANSWER_TEXT_LENGTH, |
|
||||||
// value = it |
|
||||||
// ) |
|
||||||
// }, |
|
||||||
// rightAnswer = rightAnswer |
|
||||||
// ) |
|
||||||
} else { |
|
||||||
throw NullPointerException("问题无法解析!!!!") |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 题目反序列化 |
|
||||||
* |
|
||||||
*/ |
|
||||||
class ExamDeserializer : JsonDeserializer<Exam> { |
|
||||||
companion object { |
|
||||||
val gson: Gson = GsonBuilder() |
|
||||||
.registerTypeAdapter(OpenQuestionsVo::class.java, OpenQuestionsVoDeserializer()) |
|
||||||
.registerTypeAdapter(ChoiceQuestionVo::class.java, ChoiceQuestionVoDeserializer()) |
|
||||||
.create() |
|
||||||
} |
|
||||||
|
|
||||||
override fun deserialize(json: JsonElement?, p1: Type?, p2: JsonDeserializationContext?): Exam { |
|
||||||
val root = json?.asJsonObject |
|
||||||
|
|
||||||
val type = root?.get("examType")?.asString |
|
||||||
|
|
||||||
return when (gson.fromJson(type, ExamType::class.java)) { |
|
||||||
ExamType.CQ -> gson.fromJson( |
|
||||||
json, |
|
||||||
object : TypeToken<ChoiceQuestionVo>() {}.type |
|
||||||
) |
|
||||||
ExamType.OQ -> gson.fromJson( |
|
||||||
json, |
|
||||||
object : TypeToken<OpenQuestionsVo>() {}.type |
|
||||||
) |
|
||||||
null -> throw NullPointerException("无法识别题目类型!") |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
@ -1,28 +0,0 @@ |
|||||||
package com.gyf.csams.util |
|
||||||
|
|
||||||
import com.google.gson.Gson |
|
||||||
import com.google.gson.GsonBuilder |
|
||||||
import com.gyf.csams.association.model.Exam |
|
||||||
import com.gyf.csams.module.ApiResponse |
|
||||||
import com.gyf.lib.util.HttpCallback |
|
||||||
import java.lang.reflect.Type |
|
||||||
|
|
||||||
/** |
|
||||||
* http请求回调 |
|
||||||
* |
|
||||||
* @param T |
|
||||||
* @property action |
|
||||||
* @property onSuccess |
|
||||||
* @property onFail |
|
||||||
|
|
||||||
*/ |
|
||||||
class ExamCallback<T>( |
|
||||||
private val action: String, |
|
||||||
private val onSuccess: (res: ApiResponse<T>) -> Unit, |
|
||||||
private val onFail: (error: String) -> Unit, |
|
||||||
private val type: Type |
|
||||||
) : HttpCallback<T>(action, onSuccess, onFail, type) { |
|
||||||
override val gson: Gson = GsonBuilder() |
|
||||||
.registerTypeAdapter(Exam::class.java, ExamDeserializer()) |
|
||||||
.create() |
|
||||||
} |
|
@ -0,0 +1 @@ |
|||||||
|
eae2136da161924597d752b7575d0f33e2638267 |
@ -0,0 +1 @@ |
|||||||
|
be99b75ae53194a79345f0278d9c17ce543ade81 |
@ -0,0 +1 @@ |
|||||||
|
165cccf559b817f7b0d4c102ba53ff6beb5369c6 |
@ -0,0 +1 @@ |
|||||||
|
7373621983602f41e9c55827a7e62c78ff6899b8 |
@ -0,0 +1 @@ |
|||||||
|
0a6f90b1de328db428af6dbea2322a79a104c562 |
@ -0,0 +1 @@ |
|||||||
|
1eae31cbbcf67f843d39243caf7df8c569c13b77 |
@ -0,0 +1 @@ |
|||||||
|
4d806e13be16ad9726fa260878473f041f153a58 |
@ -0,0 +1 @@ |
|||||||
|
0149273fe46069663a6c9ff375bab6e81aaae9d8 |
@ -0,0 +1 @@ |
|||||||
|
4e6cdc0a5379ae11e7ecd9862df219a2e8e30966 |
@ -0,0 +1 @@ |
|||||||
|
7758a1ac02f112f2cc4b9a770e6e503b51123cb7 |
@ -0,0 +1 @@ |
|||||||
|
24b3200ded1804dbeede2ad13209502ecb694a94 |
@ -0,0 +1 @@ |
|||||||
|
17a3a14f87bc6dfaa5222edd157e546f8c3d3b71 |
@ -0,0 +1 @@ |
|||||||
|
40c3c72f459198c56917d4cf2dd095c14e98727f |
@ -0,0 +1 @@ |
|||||||
|
1ee13a1678f539bc50c1a6cf8c2a4cd3ad66d643 |
@ -0,0 +1 @@ |
|||||||
|
6a42e4773be7fccb574c6021c78f8ff16c38268b |
@ -0,0 +1 @@ |
|||||||
|
0e6b6965957df34b335709e70db54ec18f85eb83 |
@ -0,0 +1 @@ |
|||||||
|
a530f977cd4e84c53f98dc954e03290cf35cc443 |
@ -0,0 +1 @@ |
|||||||
|
bba77fabcbaea7c81c93497dc15a5bd35f373f5e |
@ -0,0 +1 @@ |
|||||||
|
35980a5473e21920506edcbe0a31e75d9263e978 |
@ -0,0 +1 @@ |
|||||||
|
d9686761bcd5d3992c8a1135838400ac61bb7e47 |
@ -0,0 +1 @@ |
|||||||
|
110603101ef93e9ceca51de555a93b5e3d2de994 |
Loading…
Reference in new issue