Commit 73dc7111 authored by jiangjiantao's avatar jiangjiantao

dev

parent 15d25b56
......@@ -44,9 +44,11 @@ dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
implementation("com.squareup.okhttp3:okhttp:4.9.3")
implementation("com.squareup.okhttp3:logging-interceptor:3.9.0")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation 'androidx.annotation:annotation:1.1.0'
testImplementation 'junit:junit:4.+'
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation('com.squareup.retrofit2:converter-simplexml:2.9.0') {
exclude group: 'xpp3', module: 'xpp3'
......
......@@ -2,6 +2,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.miya.fastcashier">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
......@@ -10,15 +14,15 @@
android:supportsRtl="true"
android:theme="@style/Theme.MiYaFastCashier">
<activity
android:name=".ui.login.ui.login.LoginActivity"
android:label="@string/title_activity_login">
android:name=".ui.login.ui.login.LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity"></activity>
<activity android:name=".MainActivity">
</activity>
</application>
</manifest>
\ No newline at end of file
package com.miya.fastcashier.beans
import com.google.gson.annotations.SerializedName
data class LoginRequest(@SerializedName("userName") val userName: String,
@SerializedName("password") val password: String,
@SerializedName("serialNo") val serialNo: String)
package com.miya.fastcashier.repository
class LoginRepository {
}
\ No newline at end of file
package com.miya.fastcashier.service
data class BaseResult<T>(val code: String, val msg: String, val data: T)
\ No newline at end of file
package com.miya.fastcashier.service
import com.miya.fastcashier.beans.SelfCashierAccountInfo
import com.miya.fastcashier.beans.LoginRequest;
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.Body
import retrofit2.http.POST
interface LoginService {
@POST("verify/auth/token")
suspend fun login(@Body loginRequestCall: LoginRequest): BaseResult<SelfCashierAccountInfo>
companion object {
private const val BASE_URL = "https://hhmspre.miyapay.com/"
private var service: LoginService? = null
fun getApi(): LoginService {
if (null == service) {
val httpLoggingInterceptor =
HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BASIC }
val client = OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
.build()
val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
service = retrofit.create(LoginService::class.java)
}
return service!!
}
}
}
\ No newline at end of file
package com.miya.fastcashier.ui.login.ui.login
/**
* User details post authentication that is exposed to the UI
*/
data class LoggedInUserView(
val displayName: String
//... other data fields that may be accessible to the UI
)
\ No newline at end of file
......@@ -8,6 +8,7 @@ import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.EditText
......@@ -29,102 +30,23 @@ class LoginActivity : AppCompatActivity() {
val username = binding.username
val password = binding.password
val login = binding.login
val loading = binding.loading
// loginViewModel = ViewModelProvider(this, LoginViewModelFactory())
// .get(LoginViewModel::class.java)
//
// loginViewModel.loginFormState.observe(this@LoginActivity, Observer {
// val loginState = it ?: return@Observer
//
// // disable login button unless both username / password is valid
// login.isEnabled = loginState.isDataValid
//
// if (loginState.usernameError != null) {
// username.error = getString(loginState.usernameError)
// }
// if (loginState.passwordError != null) {
// password.error = getString(loginState.passwordError)
// }
// })
loginViewModel = ViewModelProvider(this)
.get(LoginViewModel::class.java)
loginViewModel.loginResult.observe(this@LoginActivity, Observer {
val loginResult = it ?: return@Observer
loading.visibility = View.GONE
if (loginResult.error != null) {
showLoginFailed(loginResult.error)
loginViewModel.loginLiveData.observe(this) { result ->
val selfCashierAccountInfo = result.getOrNull()
if (null == selfCashierAccountInfo) {
Log.e("######","失败")
return@observe
}
if (loginResult.success != null) {
updateUiWithUser(loginResult.success)
Log.e("######","成功")
}
setResult(Activity.RESULT_OK)
//Complete and destroy login activity once successful
finish()
})
username.afterTextChanged {
loginViewModel.loginDataChanged(
username.text.toString(),
password.text.toString()
)
binding.login.setOnClickListener{
loginViewModel.login("miyago","123456")
}
password.apply {
afterTextChanged {
loginViewModel.loginDataChanged(
username.text.toString(),
password.text.toString()
)
}
setOnEditorActionListener { _, actionId, _ ->
when (actionId) {
EditorInfo.IME_ACTION_DONE ->
loginViewModel.login(
username.text.toString(),
password.text.toString()
)
}
false
}
login.setOnClickListener {
loading.visibility = View.VISIBLE
loginViewModel.login(username.text.toString(), password.text.toString())
}
}
}
private fun updateUiWithUser(model: LoggedInUserView) {
val welcome = getString(R.string.welcome)
val displayName = model.displayName
// TODO : initiate successful logged in experience
Toast.makeText(
applicationContext,
"$welcome $displayName",
Toast.LENGTH_LONG
).show()
}
private fun showLoginFailed(@StringRes errorString: Int) {
Toast.makeText(applicationContext, errorString, Toast.LENGTH_SHORT).show()
}
}
/**
* Extension function to simplify setting an afterTextChanged action to EditText components.
*/
fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
this.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(editable: Editable?) {
afterTextChanged.invoke(editable.toString())
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
})
}
\ No newline at end of file
package com.miya.fastcashier.ui.login.ui.login
/**
* Authentication result : success (user details) or error message.
*/
data class LoginResult(
val success: LoggedInUserView? = null,
val error: Int? = null
)
\ No newline at end of file
......@@ -26,6 +26,7 @@ class MainFragment : Fragment() {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
// TODO: Use the ViewModel
}
......
......@@ -3,54 +3,30 @@ package com.miya.fastcashier.viewmodel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import android.util.Patterns
import com.miya.fastcashier.R
import com.miya.fastcashier.repository.LoginRepository
import androidx.lifecycle.viewModelScope
import com.miya.fastcashier.beans.LoginRequest
import com.miya.fastcashier.beans.SelfCashierAccountInfo
import com.miya.fastcashier.service.BaseResult
import com.miya.fastcashier.service.LoginService
import kotlinx.coroutines.launch
import java.lang.RuntimeException
import com.miya.fastcashier.ui.login.ui.login.LoggedInUserView
import com.miya.fastcashier.ui.login.ui.login.LoginResult
class LoginViewModel : ViewModel() {
val loginLiveData: MutableLiveData<Result<BaseResult<SelfCashierAccountInfo>>> = MutableLiveData()
fun login(userName:String,passWord:String) {
viewModelScope.launch {
val result = try {
// 网络返回成功
Result.success(LoginService.getApi().login(LoginRequest(userName,passWord,"")))
} catch (e: Exception) {
// 网络返回失败
Result.failure(e)
}
// 注意这里是主线程,直接用setValue()即可
loginLiveData.value = result
}
}
class LoginViewModel(private val loginRepository: LoginRepository) : ViewModel() {
//
// private val _loginForm = MutableLiveData<LoginFormState>()
// val loginFormState: LiveData<LoginFormState> = _loginForm
//
// private val _loginResult = MutableLiveData<LoginResult>()
// val loginResult: LiveData<LoginResult> = _loginResult
//
// fun login(username: String, password: String) {
// // can be launched in a separate asynchronous job
//// val result = loginRepository.login(username, password)
////
//// if (result is Result.Success) {
//// _loginResult.value =
//// LoginResult(success = LoggedInUserView(displayName = result.data.displayName))
//// } else {
//// _loginResult.value = LoginResult(error = R.string.login_failed)
//// }
// }
//
// fun loginDataChanged(username: String, password: String) {
// if (!isUserNameValid(username)) {
// _loginForm.value = LoginFormState(usernameError = R.string.invalid_username)
// } else if (!isPasswordValid(password)) {
// _loginForm.value = LoginFormState(passwordError = R.string.invalid_password)
// } else {
// _loginForm.value = LoginFormState(isDataValid = true)
// }
// }
//
// // A placeholder username validation check
// private fun isUserNameValid(username: String): Boolean {
// return if (username.contains('@')) {
// Patterns.EMAIL_ADDRESS.matcher(username).matches()
// } else {
// username.isNotBlank()
// }
// }
//
// // A placeholder password validation check
// private fun isPasswordValid(password: String): Boolean {
// return password.length > 5
// }
}
\ No newline at end of file
......@@ -50,7 +50,7 @@
android:layout_marginTop="16dp"
android:layout_marginEnd="48dp"
android:layout_marginBottom="64dp"
android:enabled="false"
android:enabled="true"
android:text="@string/action_sign_in"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment