From 731667db1ac658a6f6064ef328d04eb1d47c20ff Mon Sep 17 00:00:00 2001 From: cloudroam <cloudroam> Date: 星期一, 31 三月 2025 13:53:02 +0800 Subject: [PATCH] fix 登录 --- /dev/null | 1 app/src/main/java/com/example/firstapp/network/AuthInterceptor.kt | 24 ++++++++ app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt | 14 +++- app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt | 8 ++ app/src/main/java/com/example/firstapp/utils/PreferencesManager.kt | 40 +++++++++++++ app/src/main/java/com/example/firstapp/network/TokenExpiredInterceptor.kt | 19 ++++++ app/src/main/java/com/example/firstapp/database/service/ApiService.kt | 20 ++++++ app/src/main/java/com/example/firstapp/App.kt | 3 app/src/main/java/com/example/firstapp/database/response/UserInfo.kt | 5 - 9 files changed, 122 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/example/firstapp/App.kt b/app/src/main/java/com/example/firstapp/App.kt index 6663556..7c60e3a 100644 --- a/app/src/main/java/com/example/firstapp/App.kt +++ b/app/src/main/java/com/example/firstapp/App.kt @@ -39,6 +39,7 @@ import com.example.firstapp.utils.FRPC_LIB_VERSION import com.example.firstapp.utils.HistoryUtils import com.example.firstapp.utils.Log +import com.example.firstapp.utils.PreferencesManager import com.example.firstapp.utils.SettingUtils import com.example.firstapp.utils.SharedPreference @@ -154,7 +155,7 @@ try { context = applicationContext initLibs() - + PreferencesManager.init(this) //纯客户端模式 if (SettingUtils.enablePureClientMode) return diff --git a/app/src/main/java/com/example/firstapp/database/response/UserInfo.kt b/app/src/main/java/com/example/firstapp/database/response/UserInfo.kt index 3e5c46c..3903f45 100644 --- a/app/src/main/java/com/example/firstapp/database/response/UserInfo.kt +++ b/app/src/main/java/com/example/firstapp/database/response/UserInfo.kt @@ -6,7 +6,6 @@ val name: String, val cover: String, val contactTel: String, - val passTime: String, - val overTime: String, - val showed: Boolean + val memberOvertime: String, + val isMember: Boolean ) \ No newline at end of file diff --git a/app/src/main/java/com/example/firstapp/database/service/ApiService.kt b/app/src/main/java/com/example/firstapp/database/service/ApiService.kt index 99dbf56..1d4be56 100644 --- a/app/src/main/java/com/example/firstapp/database/service/ApiService.kt +++ b/app/src/main/java/com/example/firstapp/database/service/ApiService.kt @@ -13,7 +13,9 @@ import com.example.firstapp.database.response.UserInfo import com.example.firstapp.model.CategoryConfig import com.example.firstapp.model.CategoryConfigSync +import com.example.firstapp.network.AuthInterceptor import okhttp3.MultipartBody +import okhttp3.OkHttpClient import okhttp3.RequestBody import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory @@ -24,6 +26,7 @@ import retrofit2.http.Path import retrofit2.http.Query import retrofit2.http.Body +import java.util.concurrent.TimeUnit /** * API调用接口 @@ -39,9 +42,11 @@ @GET("sysDict/getByDictCodeAndItemText") suspend fun getDictValue(@Query("dictCode") dictCode: String, @Query("itemText") itemText: String): DictResponse + // 发送短信验证码 @POST("api/sms/send/code") suspend fun sendVerificationCode(@Body request: SmsSendRequest): LoginResponse + // 验证短信验证码 @POST("api/login/customer/phone/v2") suspend fun verifyCode(@Body request: SmsLoginRequest): TokenResponse @@ -51,11 +56,12 @@ @GET("v2/alipay/pay-order-info") suspend fun getPayOrderInfo(): AlipayOrderInfoResponse - @GET("flower/api/supplier/info/{phone}") + // 获取用户信息 + @GET("api/customer/info/{phone}") suspend fun getUserInfo(@Path("phone") phone: String): ApiResponse<UserInfo> @Multipart - @POST("api/supplier/operation/update") + @POST("flower/api/supplier/operation/update") suspend fun updateProfile( @Part("nickname") nickname: RequestBody, @Part avatar: MultipartBody.Part? @@ -73,9 +79,19 @@ private const val BASE_URL ="http://192.168.1.213:8080/flower/" + // 创建OkHttpClient,配置拦截器和超时时间 + private val okHttpClient = OkHttpClient.Builder() + .addInterceptor(AuthInterceptor()) + .connectTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .writeTimeout(30, TimeUnit.SECONDS) + .build() + + //添加Gson解析器,用于自动将JSON响应转换为Kotlin/Java对象 private val retrofit = Retrofit .Builder() + .client(okHttpClient) .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build() diff --git a/app/src/main/java/com/example/firstapp/database/service/RetrofitClient.kt b/app/src/main/java/com/example/firstapp/database/service/RetrofitClient.kt deleted file mode 100644 index 0519ecb..0000000 --- a/app/src/main/java/com/example/firstapp/database/service/RetrofitClient.kt +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/src/main/java/com/example/firstapp/network/AuthInterceptor.kt b/app/src/main/java/com/example/firstapp/network/AuthInterceptor.kt new file mode 100644 index 0000000..1f1a191 --- /dev/null +++ b/app/src/main/java/com/example/firstapp/network/AuthInterceptor.kt @@ -0,0 +1,24 @@ +package com.example.firstapp.network + +import com.example.firstapp.utils.PreferencesManager +import okhttp3.Interceptor +import okhttp3.Response + +class AuthInterceptor : Interceptor { + override fun intercept(chain: Interceptor.Chain): Response { + val originalRequest = chain.request() + + // 获取token + val token = PreferencesManager.getToken() + + // 如果token存在,添加到请求头 + return if (!token.isNullOrEmpty()) { + val newRequest = originalRequest.newBuilder() + .header("Authorization", "Bearer $token") + .build() + chain.proceed(newRequest) + } else { + chain.proceed(originalRequest) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/firstapp/network/TokenExpiredInterceptor.kt b/app/src/main/java/com/example/firstapp/network/TokenExpiredInterceptor.kt new file mode 100644 index 0000000..1c73d50 --- /dev/null +++ b/app/src/main/java/com/example/firstapp/network/TokenExpiredInterceptor.kt @@ -0,0 +1,19 @@ +package com.example.firstapp.network + +import com.example.firstapp.utils.PreferencesManager +import okhttp3.Interceptor +import okhttp3.Response + +class TokenExpiredInterceptor : Interceptor { + override fun intercept(chain: Interceptor.Chain): Response { + val response = chain.proceed(chain.request()) + + // 如果返回401,说明token可能过期 + if (response.code == 401) { + PreferencesManager.clearUserData() // 清除本地token + // TODO: 处理token过期,例如跳转到登录页面 + } + + return response + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt b/app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt index ee242e2..92f03e9 100644 --- a/app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt +++ b/app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt @@ -10,6 +10,7 @@ import com.example.firstapp.database.service.RetrofitClient import com.example.firstapp.utils.Log import com.example.firstapp.ui.home.HomeViewModel +import com.example.firstapp.utils.PreferencesManager class LoginViewModel : ViewModel() { @@ -64,7 +65,7 @@ //用于获取 HTTP 请求的相关信息(如请求头、Cookie 等),它会由 Spring 框架自动注入,不需要客户端显式传递。 val response = RetrofitClient.apiService.verifyCode(request) if (response.code == "0" && response.data != null) { - saveToken(response.data.value) // 这里获取的是 access_token + saveToken(response.data.value,phone) // 这里获取的是 access_token _loginState.value = true } else { _loginMessage.value = response.msg.ifEmpty { "登录失败" } @@ -86,9 +87,12 @@ } } - private fun saveToken(token: String) { + private fun saveToken(token: String,phone:String) { // TODO: 实现token存储逻辑 // 可能还需要存储 refresh_token + PreferencesManager.saveToken(token) + // 保存登录的手机号 + PreferencesManager.savePhone(phone) } } \ No newline at end of file diff --git a/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt b/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt index 527fa09..5f1ffe1 100644 --- a/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt +++ b/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt @@ -33,6 +33,7 @@ import com.bumptech.glide.Glide import com.example.firstapp.activity.VipActivity import com.example.firstapp.database.response.UserInfo +import com.example.firstapp.utils.PreferencesManager class NotificationsFragment : Fragment() { @@ -278,7 +279,14 @@ private suspend fun loadUserInfo() { try { - val response = RetrofitClient.apiService.getUserInfo("17586582287") + // 从本地获取保存的手机号 + val savedPhone = PreferencesManager.getPhone() + if (savedPhone.isNullOrEmpty()) { + Toast.makeText(context, "用户未登录", Toast.LENGTH_SHORT).show() + return + } + + val response = RetrofitClient.apiService.getUserInfo(savedPhone) if (response.code == "0" && response.data != null) { // 保存用户信息 currentUserInfo = response.data @@ -295,10 +303,10 @@ binding.tvUserId.text = "个人账号:${userInfo.contactTel}" // 设置VIP信息 - if (userInfo.showed) { + if (userInfo.isMember) { binding.ivVip.visibility = View.VISIBLE binding.cardVip.visibility = View.VISIBLE - binding.tvVipExpire.text = "${userInfo.overTime} 到期" + binding.tvVipExpire.text = "${userInfo.memberOvertime} 到期" } else { //非会员信息 binding.btnRenew.text = "立即开通" diff --git a/app/src/main/java/com/example/firstapp/utils/PreferencesManager.kt b/app/src/main/java/com/example/firstapp/utils/PreferencesManager.kt new file mode 100644 index 0000000..6f5eb54 --- /dev/null +++ b/app/src/main/java/com/example/firstapp/utils/PreferencesManager.kt @@ -0,0 +1,40 @@ +package com.example.firstapp.utils + +import android.content.Context +import android.content.SharedPreferences + +object PreferencesManager { + private const val PREF_NAME = "app_preferences" + private const val KEY_TOKEN = "user_token" + private const val KEY_PHONE = "user_phone" + + private lateinit var preferences: SharedPreferences + + fun init(context: Context) { + preferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) + } + + fun saveToken(token: String) { + preferences.edit().putString(KEY_TOKEN, token).apply() + } + + fun getToken(): String? { + return preferences.getString(KEY_TOKEN, null) + } + + fun savePhone(phone: String) { + preferences.edit().putString(KEY_PHONE, phone).apply() + } + + fun getPhone(): String? { + return preferences.getString(KEY_PHONE, null) + } + + fun clearUserData() { + preferences.edit().apply { + remove(KEY_TOKEN) + remove(KEY_PHONE) + apply() + } + } +} \ No newline at end of file -- Gitblit v1.9.3