1、增加网络检测,无网和有网状态时的处理
This commit is contained in:
shenzuqiang 2026-03-09 14:49:26 +08:00
parent 2d8343ac5c
commit 6598b54e85
9 changed files with 248 additions and 446 deletions

View File

@ -4,7 +4,7 @@
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2026-03-09T01:29:27.555907500Z">
<DropdownSelection timestamp="2026-03-09T06:18:00.411600700Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=JRBI89BIE6AI5TG6" />

View File

@ -36,7 +36,6 @@ 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.livedata.observeAsState
import androidx.compose.runtime.mutableIntStateOf
@ -88,18 +87,18 @@ import org.json.JSONObject
@Composable
fun LoginScreen(navController: NavHostController? = null, generalViewModel: GeneralViewModel, loginViewModel: LoginViewModel, isVisibilityBreak: Boolean) {
val context = LocalContext.current
val networkStatus by generalViewModel.networkStatus.observeAsState(initial = true)
var showNetworkDisconnected by remember { mutableStateOf(false) }
// 网络状态监听
LaunchedEffect(networkStatus) {
if (!networkStatus) {
// 网络断开时的处理
Log.w("NetworkStatus","网络断开")
}else{
Log.w("NetworkStatus","网络已连接")
}
}
// val networkStatus by generalViewModel.networkStatus.observeAsState(initial = true)
// var showNetworkDisconnected by remember { mutableStateOf(false) }
//
// // 网络状态监听
// LaunchedEffect(networkStatus) {
// if (!networkStatus) {
// // 网络断开时的处理
// Log.w("NetworkStatus","网络断开")
// }else{
// Log.w("NetworkStatus","网络已连接")
// }
// }
//关于登录的事件监听
LaunchedEffect(Unit) {
@ -127,7 +126,6 @@ fun LoginScreen(navController: NavHostController? = null, generalViewModel: Gene
}
loginViewModel.loginResult.value = null //清理loginState
}else if(loginViewModel.loginResult.value != null && loginViewModel.loginResult.value?.data?.token == null){
// loginViewModel.setLogin(false) //登录失败
Log.w("LoginScreen","登录失败,无有效的Token")
Toast.makeText(context, "登录失败,请重新登录", Toast.LENGTH_SHORT).show()//提示登录成功
}
@ -154,7 +152,7 @@ fun LoginScreen(navController: NavHostController? = null, generalViewModel: Gene
when(loginViewModel.loginScreenType.value){
LoginScreenType.LOGIN_ONE_KEY -> {
//一键登录
OneKeyLoginScreen(context, loginViewModel, generalViewModel)
OneKeyLoginScreen(context, loginViewModel)
}
LoginScreenType.LOGIN_WX -> {
//微信登录
@ -172,7 +170,7 @@ fun LoginScreen(navController: NavHostController? = null, generalViewModel: Gene
}
else -> {
//默认验证码登录
CaptchaLoginScreen(context, loginViewModel, generalViewModel)
CaptchaLoginScreen(context, loginViewModel)
}
}
@ -188,22 +186,22 @@ fun LoginScreen(navController: NavHostController? = null, generalViewModel: Gene
}
}
LaunchedEffect(networkStatus) {
delay(1000L)
showNetworkDisconnected = true
}
if(showNetworkDisconnected){
if(!networkStatus){
NetworkDisconnectedPage(onNetworkStatus = {isNetworkAvailable->
if(isNetworkAvailable){
Toast.makeText(context, "网络已连接", Toast.LENGTH_SHORT).show()
}else{
Toast.makeText(context, "网络已断开", Toast.LENGTH_SHORT).show()
}
generalViewModel.setNetworkStatus(isNetworkAvailable)
})
}
}
// LaunchedEffect(networkStatus) {
// delay(1000L)
// showNetworkDisconnected = true
// }
// if(showNetworkDisconnected){
// if(!networkStatus){
// NetworkDisconnectedPage(generalViewModel = generalViewModel, onNetworkStatus = {isNetworkAvailable->
// if(isNetworkAvailable){
// Toast.makeText(context, "网络已连接", Toast.LENGTH_SHORT).show()
// }else{
// Toast.makeText(context, "网络已断开", Toast.LENGTH_SHORT).show()
// }
// generalViewModel.setNetworkStatus(isNetworkAvailable)
// })
// }
// }
// 顶部栏
TitleBar(navController = navController, paddingValues = it, title = "", showSave = false, showBreak = isVisibilityBreak)
@ -216,7 +214,7 @@ fun LoginScreen(navController: NavHostController? = null, generalViewModel: Gene
* 验证码登录
*/
@Composable
private fun CaptchaLoginScreen(context: Context, viewModel: LoginViewModel, generalViewModel: GeneralViewModel) {
private fun CaptchaLoginScreen(context: Context, viewModel: LoginViewModel) {
val gradientBrush = Brush.verticalGradient(
colors = listOf(
Color(0xFF91FEFA), // 浅蓝色
@ -255,7 +253,7 @@ private fun CaptchaLoginScreen(context: Context, viewModel: LoginViewModel, gene
.height(55.dp)
.background(gradientBrush)
)
Column() {
Column {
Text(
text = "欢迎登录",
modifier = Modifier.padding(start = 12.dp),
@ -564,6 +562,7 @@ private fun CaptchaLoginScreen(context: Context, viewModel: LoginViewModel, gene
}
pop()
}
@Suppress("DEPRECATION")
ClickableText(
text = annotatedText,
onClick = { offset ->
@ -598,8 +597,8 @@ private fun CaptchaLoginScreen(context: Context, viewModel: LoginViewModel, gene
*/
@SuppressLint("UseKtx", "InflateParams", "SetTextI18n")
@Composable
private fun OneKeyLoginScreen(context: Context, viewModel: LoginViewModel, generalViewModel: GeneralViewModel) {
val ONEKEY_TAG = "OneKeyLoginScreen"
private fun OneKeyLoginScreen(context: Context, viewModel: LoginViewModel) {
val TAG = "Rabbit_LoginPage_OneKeyLoginScreen"
val preLoginResult = GYManager.getInstance().preLoginResult
val phoneNumber = viewModel.oneKeyPreLogin?.number ?: ""
@ -608,13 +607,13 @@ private fun OneKeyLoginScreen(context: Context, viewModel: LoginViewModel, gener
val privacyUrl = preLoginResult.privacyUrl
// 详细打印preLoginResult信息
Log.w(ONEKEY_TAG, "=== preLoginResult 详细信息 ===")
Log.w(ONEKEY_TAG, "preLoginResult对象: $preLoginResult")
Log.w(ONEKEY_TAG, "operator: ${preLoginResult.operator}")
Log.w(ONEKEY_TAG, "isValid: ${preLoginResult.isValid}")
Log.w(ONEKEY_TAG, "privacyName: ${preLoginResult.privacyName}")
Log.w(ONEKEY_TAG, "privacyUrl: ${preLoginResult.privacyUrl}")
Log.w(ONEKEY_TAG, "================================")
Log.w(TAG, "=== preLoginResult 详细信息 ===")
Log.w(TAG, "preLoginResult对象: $preLoginResult")
Log.w(TAG, "operator: ${preLoginResult.operator}")
Log.w(TAG, "isValid: ${preLoginResult.isValid}")
Log.w(TAG, "privacyName: ${preLoginResult.privacyName}")
Log.w(TAG, "privacyUrl: ${preLoginResult.privacyUrl}")
Log.w(TAG, "================================")
val agreementText = "登录即认可${privacyName}、《用户协议》和《隐私政策》并使用本机号码登录"
@ -851,6 +850,7 @@ private fun WxLoginScreen(
}
pop()
}
@Suppress("DEPRECATION")
ClickableText(
text = annotatedText,
onClick = { offset ->
@ -1026,6 +1026,7 @@ private fun AliPayLoginScreen(
}
pop()
}
@Suppress("DEPRECATION")
ClickableText(
text = annotatedText,
onClick = { offset ->
@ -1055,189 +1056,6 @@ private fun AliPayLoginScreen(
}
}
/**
* 一键登录页
* 至少包含号码栏(NumberTextview)品牌露出(SloganTextview)登录按钮(LoginButton)隐私确认(PrivacyCheckbox)隐私标题(PrivacyTextview)
*/
/*
@SuppressLint("UseKtx")
@Composable
private fun OneKeyLoginScreen(context: Context, viewModel: LoginViewModel) {
val preLoginResult = GYManager.getInstance().preLoginResult
preLoginResult.operator
preLoginResult.isValid
Column(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(top = 230.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
text = "18698756851",
fontWeight = FontWeight.Bold,
fontSize = 36.sp,
color = Color(0xFF1A1A1A),
modifier = Modifier
.wrapContentWidth()
.wrapContentHeight(),
)
Text(
text = "天翼账号提供认证服务",
fontWeight = FontWeight.Normal,
fontSize = 14.sp,
color = Color(0xFF767676),
modifier = Modifier
.wrapContentWidth()
.wrapContentHeight(),
)
// 登录按钮
Box(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(start = 30.dp, end = 30.dp, top = 46.dp)
.background(
Color(0xFF252525),
shape = RoundedCornerShape(359.dp),
)
.clickable {
// 点击登录
if (validateCaptchaLoginEmpty(
context = context,
viewModel = viewModel,
showToast = true
)
) {
//TODO 验证码登录请求
Toast.makeText(context, "登录成功!", Toast.LENGTH_SHORT).show()
}
}
) {
Text(
"本机号码一键绑定",
color = Color(0xFFC2FF43),
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(vertical = 12.dp)
.align(Alignment.Center)
)
}
Row(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(start = 30.dp, end = 30.dp, top = 14.dp)
) {
Checkbox(
checked = viewModel.isPolicyAgreement.value,
onCheckedChange = { isChecked ->
viewModel.setIsPolicyAgreement(isChecked)
},
modifier = Modifier
.size(16.dp)
.scale(0.35f)
.padding(top = 16.dp, start = 6.dp)
.background(
if (viewModel.isPolicyAgreement.value) Color(0xFF252525)
else Color.Transparent,
shape = RoundedCornerShape(36.dp)
)
.border(
width = 1.dp,
color = if (viewModel.isPolicyAgreement.value) Color(0xFF252525)
else Color(0xFFCCCCCC),
shape = RoundedCornerShape(36.dp)
),
colors = androidx.compose.material3.CheckboxDefaults.colors(
checkedColor = Color.Transparent, // 隐藏默认背景
uncheckedColor = Color.Transparent, // 隐藏默认背景
checkmarkColor = Color.White
)
)
val annotatedText = buildAnnotatedString {
append("我已阅读并同意")
// 用户协议部分
pushStringAnnotation(tag = "SERVICE_AGREEMENT", annotation = "service_agreement")
withStyle(style = SpanStyle(
color = Color(0xFF767676),
fontWeight = FontWeight.Bold,
//textDecoration = TextDecoration.Underline
)) {
append("${preLoginResult.privacyName}")
}
pop()
append("")
// 用户协议部分
pushStringAnnotation(tag = "USER_AGREEMENT", annotation = "user_agreement")
withStyle(style = SpanStyle(
color = Color(0xFF767676),
fontWeight = FontWeight.Bold,
//textDecoration = TextDecoration.Underline
)) {
append("《用户协议》")
}
pop()
append("")
// 隐私政策部分
pushStringAnnotation(tag = "PRIVACY_POLICY", annotation = "privacy_policy")
withStyle(style = SpanStyle(
color = Color(0xFF767676),
fontWeight = FontWeight.Bold,
//textDecoration = TextDecoration.Underline
)) {
append("《隐私政策》")
}
pop()
}
ClickableText(
text = annotatedText,
onClick = { offset ->
annotatedText.getStringAnnotations(offset, offset)
.firstOrNull()?.let { annotation ->
when (annotation.tag) {
"SERVICE_AGREEMENT" -> {
// 打开服务协议
preLoginResult.privacyUrl?.let {
Intent(Intent.ACTION_VIEW, it.toUri()).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}.let { intent ->
context.startActivity(intent)
}
}
}
"USER_AGREEMENT" -> {
//TODO 打开用户协议
Toast.makeText(context, "打开用户协议", Toast.LENGTH_SHORT).show()
}
"PRIVACY_POLICY" -> {
//TODO 打开隐私政策
Toast.makeText(context, "打开隐私政策", Toast.LENGTH_SHORT).show()
}
}
}
},
style = androidx.compose.ui.text.TextStyle(
fontSize = 12.sp,
color = Color.Gray
),
modifier = Modifier
.padding(start = 4.dp)
.align(Alignment.CenterVertically)
)
}
}
}
*/
@Composable
private fun OtherLoginBar(viewModel: LoginViewModel) {
Column(
@ -1429,7 +1247,7 @@ enum class LoginScreenType {
@Preview(showBackground = true)
@Composable
private fun PreviewOneKeyLoginScreen() {
OneKeyLoginScreen(LocalContext.current, viewModel(), viewModel())
OneKeyLoginScreen(LocalContext.current, viewModel())
}

View File

@ -50,6 +50,7 @@ import com.img.rabbit.route.ScreenRoute
import com.img.rabbit.viewmodel.BindViewModel
import com.img.rabbit.viewmodel.GeneralViewModel
import com.img.rabbit.viewmodel.LoginViewModel
import kotlinx.coroutines.delay
// 定义底部导航的标签页
sealed class TabItem(val title: String, val router:String, val normalIconRes: Int, val selectedIconRes: Int, val normalColor: Color, val selectedColor: Color) {
@ -60,15 +61,10 @@ sealed class TabItem(val title: String, val router:String, val normalIconRes: In
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@Composable
fun MainScreen(generalViewModel: GeneralViewModel, loginViewModel: LoginViewModel) {
val context = LocalContext.current
val navController = rememberNavController()
val networkStatus by generalViewModel.networkStatus.observeAsState(initial = true)
val isNavigationBarVisible by generalViewModel.isNavigationBarVisible.observeAsState(initial = true)
val tabItems = listOf(
TabItem.Home,
TabItem.Mine
)
val tabItems = listOf( TabItem.Home, TabItem.Mine )
var selectedTab: TabItem by remember { mutableStateOf(TabItem.Home) }
// 获取当前路由状态
@ -91,7 +87,14 @@ fun MainScreen(generalViewModel: GeneralViewModel, loginViewModel: LoginViewMode
if (!networkStatus) {
// 网络断开时的处理
Log.w("NetworkStatus","网络断开")
//延迟500ms确保页面初始化完成后再跳转网络错误页面
delay(500)
navController.navigate("netError")
generalViewModel.setNavigationBarVisible(false)
}else{
if(navBackStackEntry?.destination?.route == "home"||navBackStackEntry?.destination?.route == "mine"){
generalViewModel.setNavigationBarVisible(true)
}
Log.w("NetworkStatus","网络已连接")
}
}
@ -266,6 +269,16 @@ fun MainScreen(generalViewModel: GeneralViewModel, loginViewModel: LoginViewMode
bindType = backStackEntry.arguments?.getInt("type")?:BindViewModel.BindType.FROM_PHONE.type
)
}
//无网承载页
composable(ScreenRoute.NetError.route) {
NetworkDisconnectedPage(
navController = navController,
generalViewModel = generalViewModel,
){
}
}
}
// 根据选中的Tab切换导航路由

View File

@ -1,6 +1,6 @@
package com.img.rabbit.pages
import androidx.compose.animation.core.Animatable
import android.util.Log
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@ -15,6 +15,9 @@ 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.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -26,13 +29,25 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import com.img.rabbit.R
import com.img.rabbit.utils.NetworkStatus
import com.img.rabbit.viewmodel.GeneralViewModel
@Composable
fun NetworkDisconnectedPage(onNetworkStatus: (Boolean) -> Unit) {
fun NetworkDisconnectedPage(navController: NavHostController? = null, generalViewModel: GeneralViewModel, onNetworkStatus: (Boolean) -> Unit) {
val context = LocalContext.current
val scale = remember { Animatable(0f) }
val networkStatus by generalViewModel.networkStatus.observeAsState(initial = true)
// 网络状态监听
LaunchedEffect(networkStatus) {
if (networkStatus) {
// 网络连接时,自动回到上一页
Log.w("NetworkStatus","网络已连接")
navController?.popBackStack()
}
}
Box(
modifier = Modifier.fillMaxSize().background(color = Color.White)
@ -143,5 +158,5 @@ fun NetworkDisconnectedPage(onNetworkStatus: (Boolean) -> Unit) {
@Preview
@Composable
private fun PreviewNetworkDisconnectedPage() {
NetworkDisconnectedPage(onNetworkStatus = {})
NetworkDisconnectedPage(generalViewModel = viewModel(), onNetworkStatus = {})
}

View File

@ -58,10 +58,8 @@ import com.img.rabbit.pages.LoadingCallback
import com.img.rabbit.provider.storage.GlobalStateManager
import com.img.rabbit.provider.storage.PreferenceUtil
import com.img.rabbit.route.ScreenRoute
import com.img.rabbit.utils.AppEventBus
import com.img.rabbit.utils.UniAppUtils
import com.img.rabbit.utils.UniMpUpdate
import com.img.rabbit.utils.UniMpWXPayEvent
import com.img.rabbit.viewmodel.GeneralViewModel
import io.dcloud.feature.sdk.DCUniMPSDK
import kotlinx.coroutines.CoroutineScope
@ -99,16 +97,6 @@ fun HomeScreen(
}
}
LaunchedEffect(Unit) {
AppEventBus.events.collect { event ->
when (event) {
is UniMpWXPayEvent.PayResult -> {
Log.i("HomeScreen", "HomeScreen----->PayResult: ${event.code}")
}
}
}
}
LaunchedEffect(Unit) {
DCUniMPSDK.getInstance().setOnUniMPEventCallBack { _, _, data, _ ->//appid, event, data, callback ->
//拉起微信小程序来支付
@ -198,12 +186,7 @@ fun HomeScreen(
uniMp
) { uniState, _, progress ->
progressPair[uniMpId]
?: mutableMapOf<String, Float>().apply {
put(
uniMpId,
0f
)
}
?: mutableMapOf<String, Float>().apply { put(uniMpId, 0f) }
when (uniState) {
UniMpUpdate.DOWNLOAD_START -> {
//资源开始下载

View File

@ -35,7 +35,6 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@ -68,7 +67,6 @@ import com.g.gysdk.GyCallBack
import com.img.rabbit.R
import com.img.rabbit.config.Constants.agreementUrl
import com.img.rabbit.config.Constants.privacyUrl
import com.img.rabbit.pages.NetworkDisconnectedPage
import com.img.rabbit.pages.toolbar.TitleBar
import com.img.rabbit.utils.AgreementTextHelper
import com.img.rabbit.utils.AppEventBus
@ -84,18 +82,6 @@ import org.json.JSONObject
@Composable
fun BindScreen(navController: NavHostController, viewModel: BindViewModel = viewModel(), generalViewModel: GeneralViewModel, bindType: Int) {
val context = LocalContext.current
val networkStatus by generalViewModel.networkStatus.observeAsState(initial = true)
var showNetworkDisconnected by remember { mutableStateOf(false) }
// 网络状态监听
LaunchedEffect(networkStatus) {
if (!networkStatus) {
// 网络断开时的处理
Log.w("NetworkStatus","网络断开")
}else{
Log.w("NetworkStatus","网络已连接")
}
}
//关于绑定授权的事件监听
LaunchedEffect(Unit) {
@ -205,23 +191,6 @@ fun BindScreen(navController: NavHostController, viewModel: BindViewModel = view
}
}
LaunchedEffect(networkStatus) {
delay(1000L)
showNetworkDisconnected = true
}
if(showNetworkDisconnected){
if(!networkStatus){
NetworkDisconnectedPage(onNetworkStatus = {isNetworkAvailable->
if(isNetworkAvailable){
Toast.makeText(context, "网络已连接", Toast.LENGTH_SHORT).show()
}else{
Toast.makeText(context, "网络已断开", Toast.LENGTH_SHORT).show()
}
generalViewModel.setNetworkStatus(isNetworkAvailable)
})
}
}
val title = if(bindType == BindViewModel.BindType.FROM_PHONE.type){
"绑定手机号"
}else{
@ -282,7 +251,7 @@ private fun OneKeyBindScreen(context: Context, viewModel: BindViewModel) {
"天翼账号提供认证服务"
}
"CU" -> {//联通
"联通账号提供认证服务"
"认证服务由联通统一认证提供"
}
else -> {//移动
"移动账号提供认证服务"
@ -314,7 +283,6 @@ private fun OneKeyBindScreen(context: Context, viewModel: BindViewModel) {
}
val loginButton = view.findViewById<TextView>(R.id.layout_one_key_login_btn)
loginButton.setOnClickListener {
// 处理登录点击
oneKeyLogin(
context = context,
@ -325,7 +293,18 @@ private fun OneKeyBindScreen(context: Context, viewModel: BindViewModel) {
privacyTv = agreementTextView,
viewModel = viewModel
)
}
// loginButton.setOnClickListener {
// // 处理登录点击
// oneKeyLogin(
// context = context,
// numberTv = phoneTextView,
// sloganTv = serviceTextView,
// loginBtn = loginButton,
// checkBox = checkbox,
// privacyTv = agreementTextView,
// viewModel = viewModel
// )
// }
}
)
}

View File

@ -28,5 +28,5 @@ sealed class ScreenRoute(val route: String) {
object BindAccount : ScreenRoute("bindAccount")
object ManagerAccount : ScreenRoute("managerAccount")
object AboutMine : ScreenRoute("aboutMine")
object Bind : ScreenRoute("bind")
object NetError : ScreenRoute("netError")
}

View File

@ -30,7 +30,7 @@ import kotlinx.coroutines.launch
@SuppressLint("ObsoleteSdkInt")
class GeneralViewModel(application: Application) : AndroidViewModel(application) {
lateinit var api: IWXAPI
lateinit var receiver: android.content.BroadcastReceiver
lateinit var receiver: BroadcastReceiver
private val _networkStatus = MutableLiveData<Boolean>()
val networkStatus: LiveData<Boolean> = _networkStatus
fun setNetworkStatus(status: Boolean) {
@ -138,6 +138,9 @@ class GeneralViewModel(application: Application) : AndroidViewModel(application)
@OptIn(DelicateCoroutinesApi::class)
fun getServerTime() {
if (networkStatus.value != true) {
return
}
GlobalScope.launch {
val response = ApiManager.serviceVo.getServerTime()
if (response.status) {

View File

@ -78,15 +78,6 @@ class LoginViewModel : BaseViewModel() {
_policyAgreement.value = isAgreement
}
// private val _isLogin = mutableStateOf(false)
// val isLogin: State<Boolean> = _isLogin
//
// fun setLogin(isLogin: Boolean) {
// _isLogin.value = isLogin
// }
// 登录获取结果
val loginResult = mutableStateOf<ResultVo<LoginInfoEntity>?>(null)