You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose登录界面逻辑搭建求助:对接Azure数据库

搭建对接Azure数据库的登录界面求助

我正在搭建一个对接Azure数据库的登录界面,该数据库需验证邮箱,这是我首次进行此类开发,此前曾基于Firebase实现登录页面。以下是相关代码,恳请各位提供技术帮助:

API定义

@Singleton
interface MMRApi {

    @FormUrlEncoded
    @POST(LOGIN_EP)
    suspend fun sendLoginInfo(
        @Field("EmailId") emailId: String,
        @Field("MobileMakeModel") mobileMake: String
    ): Response<LoginCreds>
}

请求与响应数据类

// 请求数据类
data class LoginCreds(
        @SerializedName("EmailId") val emailId: String,
        @SerializedName("MobileMakeModel") var mobileModel: String
    ){
        companion object{
            const val PLATFORM = "Android"
        }
    
     private fun getModel(): String{
         return "$PLATFORM ${Build.MODEL}".also { mobileModel = it }
     }
}

// 响应数据类
data class LoginResponse(
    @SerializedName("data") val data: List<DataInfo>,
    @SerializedName("status") val status: Int,
    @SerializedName("message") val message: String
){
    override fun toString(): String {
        return "\n" +
                "List of Data: $data" +
                "Status: $status" +
                "Message:$message"
    }
}

data class DataInfo(
    @SerializedName("Id") val id: Int,
    @SerializedName("CustomerId") val customerId: String,
    @SerializedName("UserAttributeId") val userAttributeId: Int,
    @SerializedName("Enabled") val enabled: Boolean
){
    override fun toString(): String {
        return "\n" +
                "Id: $id" +
                "CustomerId: $customerId" +
                "UserAttributeId: $userAttributeId" +
                "Enabled: $enabled"
    }
}

Repository层

class MMRRepository @Inject constructor(private val api: MMRApi) {

    suspend fun postLogin(emailId: String, mobileMake: String): Response<LoginCreds>{
        return api.sendLoginInfo(emailId, mobileMake)
    }
}

ViewModel层

@HiltViewModel
class LoginViewModel @Inject constructor(private val repository: MMRRepository)
    : ViewModel() {

    val loginPostResponse: MutableLiveData<Response<LoginCreds>> = MutableLiveData()

    fun pushLogin(emailId: String, mobileMake: String){
        viewModelScope.launch(Dispatchers.IO) {
            val response = repository.postLogin(emailId, mobileMake)
            loginPostResponse.postValue(response)
        }
    }
}

Composable界面

@Composable
fun MMRLoginScreen(navController: NavController, loginViewModel: LoginViewModel = hiltViewModel()){
    var emailId by rememberSaveable { mutableStateOf("") }

    Surface(modifier = Modifier
        .fillMaxSize()
        .padding(top = 65.dp)
    ) {
        Column(
            verticalArrangement = Arrangement.Top,
            horizontalAlignment = Alignment.CenterHorizontally,
        ) {
            Image(
                painter = painterResource(id = R.drawable.parabit_logo_orange_blue),
                contentDescription = stringResource(R.string.company_logo_string),
                contentScale = ContentScale.Fit,
                modifier = Modifier
                    .width(225.dp)
                    .height(95.dp)
                    .padding(top = 43.dp)
                )

            Text(
                text = "MMR Bluetooth Access Control",
                color = Color(0xFFF47B20),
                fontWeight = Bold,
                fontSize = 18.sp,
            )
            Spacer(modifier = Modifier.height(10.dp))

            LoginField(loading = false){
                loginViewModel.pushLogin(emailId = it, mobileMake = Build.MODEL)
                navController.navigate(MMRScreens.MainScreen.name)
            }

        }
    }
}

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun LoginField(
    loading: Boolean = false,
    onDone: (String) -> Unit = {email ->}
){
    val email = rememberSaveable { mutableStateOf("") }
    val keyboardController = LocalSoftwareKeyboardController.current
    val valid = remember(email.value){
        email.value.trim().isNotEmpty()
    }

    Column(
        modifier = Modifier,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        EmailInput(
            emailState = email,
        )

        SubmitButton(
            textId = "Login",
            loading = loading,
            validInputs = valid
        ){
            onDone(email.value.trim())
            keyboardController?.hide()
        }
    }
}

@Composable
fun SubmitButton(
    textId: String,
    loading: Boolean,
    validInputs: Boolean,
    onClick: () -> Unit
) {
    Button(
        onClick = onClick,
        modifier = Modifier
            .padding(3.dp)
            .fillMaxWidth(),
        enabled = !loading && validInputs,
        colors = ButtonDefaults.buttonColors(Color(0xFFF47B20))
    ) {
        if (loading) CircularProgressIndicator(modifier = Modifier.size(25.dp))
        else Text(text = textId, modifier = Modifier.padding(5.dp))
    }
}

内容的提问来源于stack exchange,提问作者OEThe11

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 23:45:37