1、账号绑定、解绑
2、账户管理、切换
3、切换、绑定、解绑后更新
This commit is contained in:
shenzuqiang 2026-02-28 11:33:37 +08:00
parent f78f459616
commit 1168061f72
14 changed files with 466 additions and 54 deletions

View File

@ -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()
// 未登录,显示登录页

View File

@ -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>,
)

View File

@ -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)

View File

@ -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)

View File

@ -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)
)
}
}
}
}
}
}

View File

@ -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

View File

@ -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(

View File

@ -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")

View File

@ -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())
}

View File

@ -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]
}
}

View File

@ -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)

View File

@ -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 // 开始加载
}

View File

@ -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 { "退出登录失败" })

View File

@ -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>?>
/**
* 上传文件