parent
f78f459616
commit
1168061f72
|
|
@ -93,7 +93,9 @@ class MainActivity : ComponentActivity() {
|
|||
var loginViewModel: LoginViewModel = viewModel()
|
||||
val context = LocalContext.current
|
||||
var showSplash by remember { mutableStateOf(false) }
|
||||
var globalLogout by mutableStateOf(GlobalStateManager(context).globalLogoutFlow().collectAsState(initial = false))
|
||||
var globalLogin by mutableStateOf(GlobalStateManager(context).globalLoginNotifyFlow().collectAsState(initial = false))
|
||||
var globalLogout by mutableStateOf(GlobalStateManager(context).globalLogoutNotifyFlow().collectAsState(initial = false))
|
||||
var globalUnBind by mutableStateOf(GlobalStateManager(context).globalUnBindNotifyFlow().collectAsState(initial = false))
|
||||
|
||||
LaunchedEffect(generalViewModel.agreementStatus.value) {
|
||||
if (generalViewModel.agreementStatus.value == true){
|
||||
|
|
@ -111,13 +113,36 @@ class MainActivity : ComponentActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
//初始化微信登录
|
||||
//loginViewModel.initWXApi(this)
|
||||
// 设置启动页显示条件
|
||||
splashScreen.setKeepOnScreenCondition {
|
||||
splashViewModel.isLoading.value // 当为 true 时,启动页不消失
|
||||
}
|
||||
// 登录成功后,2秒后自动更新状态
|
||||
if(globalLogin.value == true){
|
||||
GlobalScope.launch {
|
||||
//延迟2秒,方便处理多有事件都收到通知
|
||||
delay(2*1000)
|
||||
GlobalStateManager(context).storeGlobalLoginNotify(false)
|
||||
}
|
||||
}
|
||||
|
||||
// 退出成功后,2秒后自动更新状态
|
||||
if(globalLogout.value == true){
|
||||
GlobalScope.launch {
|
||||
//延迟2秒,方便处理多有事件都收到通知
|
||||
delay(2*1000)
|
||||
GlobalStateManager(context).storeGlobalLogoutNotify(false)
|
||||
}
|
||||
}
|
||||
|
||||
// 解绑成功后,2秒后自动更新状态
|
||||
if(globalUnBind.value == true){
|
||||
GlobalScope.launch {
|
||||
//延迟2秒,方便处理多有事件都收到通知
|
||||
delay(2*1000)
|
||||
GlobalStateManager(context).storeGlobalUnBindNotify(false)
|
||||
}
|
||||
}
|
||||
|
||||
AppTheme {
|
||||
SplashScreenContent{
|
||||
|
|
@ -148,10 +173,6 @@ class MainActivity : ComponentActivity() {
|
|||
loginViewModel.requestUserConfig()
|
||||
//loginViewModel.initWXApi(this)
|
||||
}
|
||||
// 初始化全局注销状态为 false
|
||||
GlobalScope.launch {
|
||||
GlobalStateManager(context).storeGlobalLogout(false)
|
||||
}
|
||||
|
||||
val token = PreferenceUtil.getAccessToken()
|
||||
// 未登录,显示登录页
|
||||
|
|
|
|||
|
|
@ -28,5 +28,10 @@ class UserInfoEntity(
|
|||
val weixinAppId: String = "",
|
||||
val weixinAppIdType: String = "",
|
||||
val weixinAppOpenId: String = "",
|
||||
val weixinOpenId: String = ""
|
||||
val weixinOpenId: String = "",
|
||||
|
||||
//目前由/api/user/account提供
|
||||
val vip_type: Int = 0,
|
||||
val create_time: String = "",
|
||||
val bind: ArrayList<String>,
|
||||
)
|
||||
|
|
@ -106,14 +106,22 @@ fun LoginScreen(navController: NavHostController? = null, generalViewModel: Gene
|
|||
if (loginViewModel.loginState.value !=null && loginViewModel.loginState.value?.data?.token != null) {
|
||||
//登录成功
|
||||
PreferenceUtil.saveAccessToken(loginViewModel.loginState.value?.data?.token)
|
||||
// 获取用户配置
|
||||
loginViewModel.requestUserConfig()
|
||||
// 获取用户信息
|
||||
loginViewModel.requestUserInfo()
|
||||
|
||||
loginViewModel.setLogin(true)
|
||||
Toast.makeText(context, "登录成功", Toast.LENGTH_SHORT).show()
|
||||
|
||||
//更新登录状态
|
||||
GlobalStateManager(context).storeGlobalLoginNotify(true)
|
||||
//清理loginState
|
||||
loginViewModel.loginState.value = null
|
||||
//提示登录成功
|
||||
Toast.makeText(context, "登录成功", Toast.LENGTH_SHORT).show()
|
||||
// 当允许返回上一页时,登录成功后,返回上一页
|
||||
if(isVisibilityBreak){
|
||||
navController?.popBackStack()
|
||||
}
|
||||
}else if(loginViewModel.loginState.value !=null && loginViewModel.loginState.value?.data?.token == null){
|
||||
//登录失败
|
||||
loginViewModel.setLogin(false)
|
||||
|
|
|
|||
|
|
@ -214,10 +214,10 @@ fun MainScreen(generalViewModel: GeneralViewModel, loginViewModel: LoginViewMode
|
|||
|
||||
// 设置页面(Setting)
|
||||
composable(ScreenRoute.BindAccount.route) {
|
||||
AccountBindScreen(navController = navController)
|
||||
AccountBindScreen(navController = navController, loginViewModel = loginViewModel)
|
||||
}
|
||||
composable(ScreenRoute.ManagerAccount.route) {
|
||||
AccountManagerScreen(navController = navController)
|
||||
AccountManagerScreen(navController = navController, loginViewModel = loginViewModel)
|
||||
}
|
||||
composable(ScreenRoute.AboutMine.route) {
|
||||
AboutScreen(navController = navController)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,211 @@
|
|||
package com.img.rabbit.pages.dialog
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.foundation.layout.wrapContentWidth
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.img.rabbit.R
|
||||
|
||||
@Composable
|
||||
fun TipsDialog(
|
||||
title: String?,
|
||||
content1: String?,
|
||||
content2: String?,
|
||||
cancel: String="取消",
|
||||
confirm: String="确定",
|
||||
data: Any? = null,
|
||||
onStatusChange: (state: Boolean, isCancel:Boolean, data: Any?) -> Unit
|
||||
){
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(Color(0x80000000))
|
||||
.clickable(
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
) {
|
||||
onStatusChange(false, true, data)
|
||||
},
|
||||
verticalArrangement = Arrangement.Center
|
||||
){
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight()
|
||||
.padding(horizontal = 36.dp)
|
||||
.background(Color.White, shape = RoundedCornerShape(26.dp))
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.clickable(
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
) {
|
||||
//什么都不用做,只是解决点击穿透问题
|
||||
}
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(id = R.mipmap.ic_dialog_top_mask1),
|
||||
contentDescription = null,
|
||||
contentScale = ContentScale.FillWidth,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight()
|
||||
.padding(top = 46.dp)
|
||||
) {
|
||||
if(!title.isNullOrEmpty()){
|
||||
Text(
|
||||
text = title,
|
||||
fontSize = 18.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = Color(0xFF1A1A1A),
|
||||
modifier = Modifier
|
||||
.wrapContentSize()
|
||||
.align(Alignment.CenterHorizontally)
|
||||
)
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(14.dp)
|
||||
)
|
||||
|
||||
if(!content1.isNullOrEmpty()){
|
||||
Text(
|
||||
text = content1,
|
||||
fontSize = 12.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
color = Color(0xFF767676),
|
||||
modifier = Modifier
|
||||
.wrapContentSize()
|
||||
.align(Alignment.CenterHorizontally)
|
||||
)
|
||||
}
|
||||
|
||||
if(!content2.isNullOrEmpty()){
|
||||
Text(
|
||||
text = content2,
|
||||
fontSize = 12.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
color = Color(0xFF767676),
|
||||
modifier = Modifier
|
||||
.wrapContentSize()
|
||||
.align(Alignment.CenterHorizontally)
|
||||
)
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(16.dp)
|
||||
)
|
||||
|
||||
//取消
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 18.dp, end = 18.dp, bottom = 20.dp)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight()
|
||||
.weight(1f)
|
||||
.background(
|
||||
Color(0x00000000),
|
||||
shape = RoundedCornerShape(359.dp),
|
||||
)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = Color(0xFF000000),
|
||||
shape = RoundedCornerShape(359.dp)
|
||||
)
|
||||
.clickable(
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
) {
|
||||
onStatusChange(false, true, data)
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
cancel,
|
||||
color = Color(0xFF1A1A1A),
|
||||
fontSize = 16.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
modifier = Modifier
|
||||
.wrapContentWidth()
|
||||
.wrapContentHeight()
|
||||
.padding(vertical = 12.dp)
|
||||
.align(Alignment.Center)
|
||||
)
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.width(11.dp)
|
||||
)
|
||||
|
||||
//确定
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight()
|
||||
.weight(1f)
|
||||
.background(
|
||||
Color(0xFF252525),
|
||||
shape = RoundedCornerShape(359.dp),
|
||||
)
|
||||
.clickable(
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
) {
|
||||
onStatusChange(false, false, data)
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
confirm,
|
||||
color = Color(0xFFC2FF43),
|
||||
fontSize = 16.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
modifier = Modifier
|
||||
.wrapContentWidth()
|
||||
.wrapContentHeight()
|
||||
.padding(vertical = 12.dp)
|
||||
.align(Alignment.Center)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.img.rabbit.pages.screen
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.Image
|
||||
|
|
@ -21,9 +22,12 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
|||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
|
|
@ -44,11 +48,17 @@ import androidx.navigation.compose.rememberNavController
|
|||
import coil3.compose.AsyncImage
|
||||
import com.img.rabbit.BuildConfig
|
||||
import com.img.rabbit.R
|
||||
import com.img.rabbit.provider.storage.GlobalStateManager
|
||||
import com.img.rabbit.provider.storage.PreferenceUtil
|
||||
import com.img.rabbit.utils.AppUpdate
|
||||
import com.img.rabbit.viewmodel.GeneralViewModel
|
||||
import com.img.rabbit.viewmodel.LoginViewModel
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@SuppressLint("UnrememberedMutableState", "CoroutineCreationDuringComposition")
|
||||
@Composable
|
||||
fun MineScreen(
|
||||
navController: NavHostController,
|
||||
|
|
@ -56,8 +66,12 @@ fun MineScreen(
|
|||
) {
|
||||
val TAG = "Rabbit_Mine"
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
var globalLogin by mutableStateOf(GlobalStateManager(context).globalLoginNotifyFlow().collectAsState(initial = false))
|
||||
var globalUnBind by mutableStateOf(GlobalStateManager(context).globalUnBindNotifyFlow().collectAsState(initial = false))
|
||||
|
||||
val vipMember by remember { mutableStateOf(false) }
|
||||
val userInfo by remember { mutableStateOf(PreferenceUtil.getUserInfo()) }
|
||||
var userInfo by remember { mutableStateOf(PreferenceUtil.getUserInfo()) }
|
||||
|
||||
// 监听返回事件
|
||||
val currentBackStackEntry = navController.currentBackStackEntry
|
||||
|
|
@ -70,6 +84,13 @@ fun MineScreen(
|
|||
}
|
||||
}
|
||||
|
||||
//刷新用户信息
|
||||
if(globalLogin.value == true || globalUnBind.value == true){
|
||||
scope.launch {
|
||||
delay(300)
|
||||
userInfo = PreferenceUtil.getUserInfo()
|
||||
}
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.img.rabbit.pages.screen.mine
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
|
|
@ -20,6 +21,7 @@ import androidx.compose.material3.Scaffold
|
|||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
|
|
@ -41,12 +43,15 @@ import androidx.navigation.NavHostController
|
|||
import androidx.navigation.compose.rememberNavController
|
||||
import com.img.rabbit.R
|
||||
import com.img.rabbit.pages.toolbar.TitleBar
|
||||
import com.img.rabbit.provider.storage.GlobalStateManager
|
||||
import com.img.rabbit.utils.AppDataStoreUtils
|
||||
import com.img.rabbit.viewmodel.LoginViewModel
|
||||
|
||||
@SuppressLint("UnrememberedMutableState")
|
||||
@Composable
|
||||
fun SettingScreen(navController: NavHostController, loginViewModel: LoginViewModel) {
|
||||
val context = LocalContext.current
|
||||
var globalLogin by mutableStateOf(GlobalStateManager(context).globalLoginNotifyFlow().collectAsState(initial = false))
|
||||
var cacheDataSize by remember { mutableStateOf("正在计算...") }
|
||||
/*
|
||||
LaunchedEffect(loginViewModel.logoutState.value) {
|
||||
|
|
@ -73,6 +78,11 @@ fun SettingScreen(navController: NavHostController, loginViewModel: LoginViewMod
|
|||
cacheDataSize = totalDataCacheSize
|
||||
}
|
||||
}
|
||||
if(globalLogin.value == true){
|
||||
navController.popBackStack()
|
||||
}
|
||||
|
||||
|
||||
|
||||
Scaffold{
|
||||
Column(
|
||||
|
|
|
|||
|
|
@ -46,13 +46,15 @@ import androidx.navigation.NavHostController
|
|||
import androidx.navigation.compose.rememberNavController
|
||||
import com.img.rabbit.R
|
||||
import com.img.rabbit.pages.toolbar.TitleBar
|
||||
import com.img.rabbit.provider.storage.GlobalStateManager
|
||||
import com.img.rabbit.provider.storage.PreferenceUtil
|
||||
import com.img.rabbit.viewmodel.AccountBindViewModel
|
||||
import com.img.rabbit.viewmodel.BindViewModel
|
||||
import com.img.rabbit.viewmodel.LoginViewModel
|
||||
|
||||
@SuppressLint("UnrememberedMutableState")
|
||||
@Composable
|
||||
fun AccountBindScreen(navController: NavHostController, viewModel: AccountBindViewModel = viewModel()) {
|
||||
fun AccountBindScreen(navController: NavHostController, viewModel: AccountBindViewModel = viewModel(), loginViewModel: LoginViewModel) {
|
||||
val context = LocalContext.current
|
||||
/**
|
||||
* 0:m默认未绑定,1:已绑定手机号(去解绑),2:已绑定微信(去解绑)
|
||||
|
|
@ -63,8 +65,15 @@ fun AccountBindScreen(navController: NavHostController, viewModel: AccountBindVi
|
|||
|
||||
LaunchedEffect(viewModel.unBindState.value) {
|
||||
if(viewModel.unBindState.value != null){
|
||||
// 获取用户配置
|
||||
loginViewModel.requestUserConfig()
|
||||
// 获取用户信息
|
||||
loginViewModel.requestUserInfo()
|
||||
|
||||
Toast.makeText(context, "解绑成功!", Toast.LENGTH_SHORT).show()
|
||||
viewModel.unBindState.value = null
|
||||
GlobalStateManager(context).storeGlobalUnBindNotify(true)
|
||||
navController.popBackStack()
|
||||
}
|
||||
}
|
||||
LaunchedEffect(viewModel.errorState.value) {
|
||||
|
|
@ -453,7 +462,7 @@ private fun UnBindPhoneDialog(
|
|||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun PreviewAccountBindScreen(){
|
||||
AccountBindScreen(navController = rememberNavController())
|
||||
AccountBindScreen(navController = rememberNavController(), loginViewModel = LoginViewModel())
|
||||
}
|
||||
|
||||
@SuppressLint("UnrememberedMutableState")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.img.rabbit.pages.screen.mine.setting
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
|
|
@ -21,9 +23,11 @@ import androidx.compose.material3.Scaffold
|
|||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
|
|
@ -31,6 +35,7 @@ import androidx.compose.ui.draw.scale
|
|||
import androidx.compose.ui.draw.shadow
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -40,27 +45,60 @@ import androidx.lifecycle.viewmodel.compose.viewModel
|
|||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import coil3.compose.AsyncImage
|
||||
import com.img.rabbit.R
|
||||
import com.img.rabbit.bean.local.UserInfo
|
||||
import com.img.rabbit.bean.response.UserInfoEntity
|
||||
import com.img.rabbit.pages.dialog.TipsDialog
|
||||
import com.img.rabbit.pages.toolbar.TitleBar
|
||||
import com.img.rabbit.provider.storage.GlobalStateManager
|
||||
import com.img.rabbit.provider.storage.PreferenceUtil
|
||||
import com.img.rabbit.viewmodel.AccountManagerViewModel
|
||||
import com.img.rabbit.viewmodel.LoginViewModel
|
||||
|
||||
@SuppressLint("UnrememberedMutableState")
|
||||
@Composable
|
||||
fun AccountManagerScreen(navController: NavHostController, viewModel: AccountManagerViewModel = viewModel()) {
|
||||
val userList by remember {
|
||||
mutableStateOf(
|
||||
listOf(
|
||||
UserInfo(1, "张三", "https://cdn.batiao8.com/jietutu/logo.png","",true),
|
||||
UserInfo(2, "李四", "https://cdn.batiao8.com/jietutu/logo.png","",false),
|
||||
UserInfo(3, "王五", "https://cdn.batiao8.com/jietutu/logo.png","",false),
|
||||
)
|
||||
)
|
||||
}
|
||||
fun AccountManagerScreen(navController: NavHostController, viewModel: AccountManagerViewModel = viewModel(), loginViewModel: LoginViewModel) {
|
||||
val context = LocalContext.current
|
||||
var globalLogin by mutableStateOf(GlobalStateManager(context).globalLoginNotifyFlow().collectAsState(initial = false))
|
||||
var showDialogStatus by mutableStateOf(false)
|
||||
var selectedUserInfo by mutableStateOf<UserInfoEntity?>(null)
|
||||
|
||||
val userList by remember { viewModel.accountState }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.requestAccount()
|
||||
}
|
||||
|
||||
if(globalLogin.value == true){
|
||||
viewModel.requestAccount()
|
||||
}
|
||||
|
||||
LaunchedEffect(viewModel.switchState.value) {
|
||||
if (viewModel.switchState.value != null && viewModel.switchState.value?.data?.token != null) {
|
||||
// 切换账号成功
|
||||
PreferenceUtil.saveAccessToken(viewModel.switchState.value?.data?.token)
|
||||
// 获取用户配置
|
||||
loginViewModel.requestUserConfig()
|
||||
// 获取用户信息
|
||||
loginViewModel.requestUserInfo()
|
||||
|
||||
loginViewModel.setLogin(true)
|
||||
//更新登录状态
|
||||
GlobalStateManager(context).storeGlobalLoginNotify(true)
|
||||
//清理loginState
|
||||
loginViewModel.loginState.value = null
|
||||
Toast.makeText(context, "切换账号成功!", Toast.LENGTH_SHORT).show()
|
||||
|
||||
navController.popBackStack()
|
||||
}
|
||||
}
|
||||
LaunchedEffect(viewModel.errorState.value) {
|
||||
if(viewModel.errorState.value != null){
|
||||
Toast.makeText(context, "切换账号失败...", Toast.LENGTH_SHORT).show()
|
||||
viewModel.errorState.value = null
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold{
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
|
|
@ -94,11 +132,16 @@ fun AccountManagerScreen(navController: NavHostController, viewModel: AccountMan
|
|||
Box(
|
||||
modifier = Modifier.fillMaxSize().padding(top = 55.dp, start = 17.dp, end = 17.dp)
|
||||
){
|
||||
//TODO 设置内容
|
||||
// 设置内容
|
||||
LazyColumn {
|
||||
// 添加五个项目
|
||||
items(userList.size) { index ->
|
||||
ListItem(userList[index])
|
||||
items(userList?.size ?: 0) { index ->
|
||||
userList?.get(index)?.let {userInfoEntity ->
|
||||
ListItem(userInfoEntity){
|
||||
showDialogStatus = true
|
||||
selectedUserInfo = userInfoEntity
|
||||
}
|
||||
}
|
||||
}
|
||||
item {
|
||||
AddItem(navController)
|
||||
|
|
@ -106,12 +149,31 @@ fun AccountManagerScreen(navController: NavHostController, viewModel: AccountMan
|
|||
}
|
||||
}
|
||||
}
|
||||
if(showDialogStatus){
|
||||
TipsDialog(
|
||||
title = "您确定要切换账户吗?",
|
||||
content1 = "",
|
||||
content2 = null,
|
||||
cancel = "取消",
|
||||
confirm = "确定",
|
||||
data = selectedUserInfo,
|
||||
onStatusChange = { status, isCancel, data ->
|
||||
if(!isCancel && data != null){
|
||||
// 切换账号
|
||||
viewModel.switchAccount((data as UserInfoEntity).user_id)
|
||||
}
|
||||
showDialogStatus = status
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ListItem(item: UserInfo){
|
||||
private fun ListItem(item: UserInfoEntity, onChange: (UserInfoEntity) -> Unit){
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
|
|
@ -136,26 +198,28 @@ private fun ListItem(item: UserInfo){
|
|||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
) {
|
||||
//TODO 切换账号
|
||||
//navController.navigate("feedback")
|
||||
// 切换账号
|
||||
onChange(item)
|
||||
},
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(id = R.mipmap.ic_launcher_logo),
|
||||
contentDescription = null,
|
||||
AsyncImage(
|
||||
model = item.avater,
|
||||
contentDescription = "用户头像",
|
||||
contentScale = ContentScale.FillWidth,
|
||||
modifier = Modifier
|
||||
.size(46.dp)
|
||||
.align(Alignment.CenterVertically)
|
||||
.clip(RoundedCornerShape(8.dp))
|
||||
.clip(RoundedCornerShape(8.dp)),
|
||||
fallback = painterResource(id = R.mipmap.ic_launcher_logo),
|
||||
error = painterResource(id = R.mipmap.ic_launcher_logo)
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier.weight(1f)
|
||||
){
|
||||
Text(
|
||||
text = "小林",
|
||||
text = item.name,
|
||||
fontSize = 14.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = Color(0xFF1A1A1A),
|
||||
|
|
@ -164,7 +228,7 @@ private fun ListItem(item: UserInfo){
|
|||
.padding(start = 8.dp)
|
||||
)
|
||||
Text(
|
||||
text = "ID:123456",
|
||||
text = "ID:${item.user_id}",
|
||||
fontSize = 12.sp,
|
||||
color = Color(0xFF767676),
|
||||
fontWeight = FontWeight.Normal,
|
||||
|
|
@ -174,11 +238,13 @@ private fun ListItem(item: UserInfo){
|
|||
)
|
||||
}
|
||||
|
||||
|
||||
Row(
|
||||
modifier = Modifier.wrapContentSize()
|
||||
) {
|
||||
val isLogin = PreferenceUtil.getUserInfo()?.user_id == item.user_id
|
||||
Checkbox(
|
||||
checked = item.login,
|
||||
checked = isLogin,
|
||||
onCheckedChange = { isChecked ->
|
||||
//viewModel.setIsPolicyAgreement(isChecked)
|
||||
},
|
||||
|
|
@ -187,13 +253,13 @@ private fun ListItem(item: UserInfo){
|
|||
.scale(0.35f)
|
||||
.padding(start = 6.dp)
|
||||
.background(
|
||||
if (item.login) Color(0xFF252525)
|
||||
if (isLogin) Color(0xFF252525)
|
||||
else Color.Transparent,
|
||||
shape = RoundedCornerShape(36.dp)
|
||||
)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = if (item.login) Color(0xFF252525)
|
||||
color = if (isLogin) Color(0xFF252525)
|
||||
else Color(0xFFCCCCCC),
|
||||
shape = RoundedCornerShape(36.dp)
|
||||
)
|
||||
|
|
@ -273,5 +339,5 @@ private fun AddItem(navController: NavController){
|
|||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun PreviewAccountManagerScreen(){
|
||||
AccountManagerScreen(navController = rememberNavController())
|
||||
AccountManagerScreen(navController = rememberNavController(), loginViewModel = viewModel())
|
||||
}
|
||||
|
|
@ -19,7 +19,9 @@ class GlobalStateManager(
|
|||
companion object {
|
||||
private val GLOBAL_LOADING = booleanPreferencesKey("global_loading")
|
||||
private val GLOBAL_WX_AUTHORIZATION = stringPreferencesKey("global_wx_authorization")
|
||||
private val GLOBAL_LOGOUT = booleanPreferencesKey("global_logout")
|
||||
private val GLOBAL_LOGIN_NOTIFY = booleanPreferencesKey("global_login_notify")
|
||||
private val GLOBAL_LOGOUT_NOTIFY = booleanPreferencesKey("global_logout_notify")
|
||||
private val GLOBAL_UNBIND_NOTIFY = booleanPreferencesKey("global_unbind_notify")
|
||||
}
|
||||
|
||||
suspend fun storeGlobalLoading(value: Boolean) {
|
||||
|
|
@ -49,15 +51,40 @@ class GlobalStateManager(
|
|||
}
|
||||
|
||||
|
||||
suspend fun storeGlobalLogout(value: Boolean) {
|
||||
suspend fun storeGlobalLoginNotify(value: Boolean) {
|
||||
context.storeData.edit { preferences ->
|
||||
preferences[GLOBAL_LOGOUT] = value
|
||||
preferences[GLOBAL_LOGIN_NOTIFY] = value
|
||||
}
|
||||
}
|
||||
fun globalLogoutFlow(): Flow<Boolean?> {
|
||||
fun globalLoginNotifyFlow(): Flow<Boolean?> {
|
||||
return context.storeData.data.map {
|
||||
preferences ->
|
||||
preferences[GLOBAL_LOGOUT]
|
||||
preferences[GLOBAL_LOGIN_NOTIFY]
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun storeGlobalUnBindNotify(value: Boolean) {
|
||||
context.storeData.edit { preferences ->
|
||||
preferences[GLOBAL_UNBIND_NOTIFY] = value
|
||||
}
|
||||
}
|
||||
fun globalUnBindNotifyFlow(): Flow<Boolean?> {
|
||||
return context.storeData.data.map {
|
||||
preferences ->
|
||||
preferences[GLOBAL_UNBIND_NOTIFY]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
suspend fun storeGlobalLogoutNotify(value: Boolean) {
|
||||
context.storeData.edit { preferences ->
|
||||
preferences[GLOBAL_LOGOUT_NOTIFY] = value
|
||||
}
|
||||
}
|
||||
fun globalLogoutNotifyFlow(): Flow<Boolean?> {
|
||||
return context.storeData.data.map {
|
||||
preferences ->
|
||||
preferences[GLOBAL_LOGOUT_NOTIFY]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import com.img.rabbit.provider.storage.PreferenceUtil
|
|||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
|
||||
class AccountBindViewModel : BaseViewModel() {
|
||||
// 登录状态
|
||||
// 解绑状态
|
||||
val unBindState = mutableStateOf<ResultVo<LoginInfoEntity>?>(null)
|
||||
// 错误状态
|
||||
val errorState = mutableStateOf<ErrorBean?>(null)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,21 @@
|
|||
package com.img.rabbit.viewmodel
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import com.google.gson.JsonObject
|
||||
import com.img.rabbit.bean.local.ErrorBean
|
||||
import com.img.rabbit.bean.response.LoginInfoEntity
|
||||
import com.img.rabbit.bean.response.UserInfoEntity
|
||||
import com.img.rabbit.provider.api.ApiManager
|
||||
import okhttp3.RequestBody
|
||||
import com.img.rabbit.provider.api.ResultVo
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
|
||||
class AccountManagerViewModel : BaseViewModel() {
|
||||
// 获取账号状态
|
||||
@SuppressLint("MutableCollectionMutableState")
|
||||
val accountState = mutableStateOf<MutableList<UserInfoEntity>?>(null)
|
||||
@SuppressLint("MutableCollectionMutableState")
|
||||
val switchState = mutableStateOf<ResultVo<LoginInfoEntity>?>(null)
|
||||
// 错误状态
|
||||
val errorState = mutableStateOf<ErrorBean?>(null)
|
||||
|
||||
|
|
@ -14,9 +24,33 @@ class AccountManagerViewModel : BaseViewModel() {
|
|||
mLaunch {
|
||||
val response = ApiManager.serviceVo.account()
|
||||
if (response.status) {
|
||||
// TODO 处理获取账号列表
|
||||
// 处理获取账号列表
|
||||
accountState.value = response.data
|
||||
}else{
|
||||
errorState.value = ErrorBean(response.code.toString(), response.message.ifEmpty { "提交失败..." })
|
||||
errorState.value = ErrorBean(response.code.toString(), response.message.ifEmpty { "获取账号失败..." })
|
||||
}
|
||||
isLoading.value = false // 开始加载
|
||||
}
|
||||
}
|
||||
|
||||
fun switchAccount(userId: String) {
|
||||
isLoading.value = true // 开始加载
|
||||
|
||||
// 调用 API 获取数据
|
||||
val jsonSwitch = JsonObject()
|
||||
jsonSwitch.addProperty("user_id", userId)
|
||||
|
||||
val jsonObject = JsonObject()
|
||||
jsonObject.addProperty("type", "device")
|
||||
jsonObject.add("data", jsonSwitch)
|
||||
|
||||
mLaunch {
|
||||
val response = ApiManager.serviceVo.login(jsonObject.toString().toRequestBody())
|
||||
if (response.status) {
|
||||
// 处理切换账号
|
||||
switchState.value = response
|
||||
}else{
|
||||
errorState.value = ErrorBean(response.code.toString(), response.message.ifEmpty { "切换账号失败..." })
|
||||
}
|
||||
isLoading.value = false // 开始加载
|
||||
}
|
||||
|
|
|
|||
|
|
@ -408,7 +408,7 @@ class LoginViewModel : BaseViewModel() {
|
|||
// 跳转登录页面
|
||||
//restViewModel.intValue = 1
|
||||
GlobalScope.launch {
|
||||
GlobalStateManager(context).storeGlobalLogout(true)
|
||||
GlobalStateManager(context).storeGlobalLogoutNotify(true)
|
||||
}
|
||||
} else {
|
||||
errorState.value = ErrorBean(response.code.toString(), response.message.ifEmpty { "退出登录失败" })
|
||||
|
|
|
|||
|
|
@ -82,8 +82,8 @@ interface ServiceVo {
|
|||
/**
|
||||
* 获取账号列表
|
||||
*/
|
||||
@POST("/api/user/account")
|
||||
suspend fun account(): ResultVo<Any>//@Query("scene") scene: String="account"
|
||||
@GET("/api/user/account")
|
||||
suspend fun account(@Query("scene") scene: String="account"): ResultVo<MutableList<UserInfoEntity>?>
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
|
|
|
|||
Loading…
Reference in New Issue