From a63603d1e0bf2fa85eed67581ac8ea32546bf3e4 Mon Sep 17 00:00:00 2001 From: MTing Date: Thu, 28 Aug 2025 13:46:49 +0800 Subject: [PATCH] init newwork Util & Glide Util & finish login --- app/build.gradle | 10 + app/src/main/AndroidManifest.xml | 5 + .../main/java/com/ouxuan/oxface/MainActivity.java | 321 +++++++++++++++- .../java/com/ouxuan/oxface/OxFaceApplication.java | 20 + .../com/ouxuan/oxface/network/NetworkConfig.java | 45 +++ .../com/ouxuan/oxface/network/NetworkManager.java | 222 +++++++++++ .../ouxuan/oxface/network/api/PadApiService.java | 304 +++++++++++++++ .../ouxuan/oxface/network/api/UserApiService.java | 215 +++++++++++ .../oxface/network/callback/NetworkCallback.java | 44 +++ .../network/interceptor/HeaderInterceptor.java | 62 +++ .../ouxuan/oxface/network/model/ApiResponse.java | 67 ++++ .../ouxuan/oxface/network/utils/NetworkUtils.java | 422 +++++++++++++++++++++ app/src/main/res/layout/dialog_login_success.xml | 4 +- 13 files changed, 1726 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/com/ouxuan/oxface/OxFaceApplication.java create mode 100644 app/src/main/java/com/ouxuan/oxface/network/NetworkConfig.java create mode 100644 app/src/main/java/com/ouxuan/oxface/network/NetworkManager.java create mode 100644 app/src/main/java/com/ouxuan/oxface/network/api/PadApiService.java create mode 100644 app/src/main/java/com/ouxuan/oxface/network/api/UserApiService.java create mode 100644 app/src/main/java/com/ouxuan/oxface/network/callback/NetworkCallback.java create mode 100644 app/src/main/java/com/ouxuan/oxface/network/interceptor/HeaderInterceptor.java create mode 100644 app/src/main/java/com/ouxuan/oxface/network/model/ApiResponse.java create mode 100644 app/src/main/java/com/ouxuan/oxface/network/utils/NetworkUtils.java diff --git a/app/build.gradle b/app/build.gradle index a1338f7..06581c4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -35,6 +35,16 @@ dependencies { implementation 'com.google.android.material:material:1.10.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + // 网络请求相关依赖 + implementation 'com.squareup.okhttp3:okhttp:4.12.0' + implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.squareup.retrofit2:converter-gson:2.9.0' + implementation 'com.squareup.okhttp3:logging-interceptor:4.12.0' + implementation 'com.google.code.gson:gson:2.10.1' + + // 图片加载库 + implementation 'com.github.bumptech.glide:glide:4.16.0' + testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7b92de0..0b9c2e5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,7 +2,12 @@ + + + + () { + @Override + public void onStart() { + // 显示loading状态 + showToast("正在登录..."); + } - showLoginSuccessDialog(); - - if (username.equals("admin") && password.equals("123456")) { - } else { - showToast("用户名或密码错误"); - } + @Override + public void onSuccess(PadApiService.PadLoginResponse data) { + // 登录成功,保存token和用户信息 + android.util.Log.d("MainActivity", "Login success - data: " + (data != null ? data.toString() : "null")); + if (data != null) { + android.util.Log.d("MainActivity", "Token: " + data.getToken()); + android.util.Log.d("MainActivity", "Name: " + data.getName()); + android.util.Log.d("MainActivity", "Brand ID: " + data.getBrandId()); + } + + // 保存登录响应数据 + currentLoginData = data; + + saveAuthToken(data.getToken()); + saveUserInfo(data.getUserInfo()); + saveSessionId(data.getSessionId()); + + // 显示登录成功弹框,传入登录数据 + showToast("登录成功!"); + showLoginSuccessDialog(data); + } + + @Override + public void onError(int errorCode, String errorMessage) { + // 登录失败,显示错误信息 + android.util.Log.e("MainActivity", "Login error - Code: " + errorCode + ", Message: " + errorMessage); + showToast("登录失败: " + errorMessage); + } + + @Override + public void onComplete() { + // 请求完成 + } + }); + + // 如果需要保留原来的测试登录逻辑,可以保留下面的代码 + // if (username.equals("admin") && password.equals("123456")) { + // showLoginSuccessDialog(); + // } else { + // showToast("用户名或密码错误"); + // } } /** @@ -189,8 +241,9 @@ public class MainActivity extends AppCompatActivity { /** * 显示登录成功弹框 + * @param loginData 登录响应数据 */ - private void showLoginSuccessDialog() { + private void showLoginSuccessDialog(PadApiService.PadLoginResponse loginData) { // 创建自定义弹框 Dialog dialog = new Dialog(this); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); @@ -214,6 +267,32 @@ public class MainActivity extends AppCompatActivity { Spinner spinnerPlatform = dialog.findViewById(R.id.spinnerPlatform); View buttonEnter = dialog.findViewById(R.id.buttonEnter); View buttonClose = dialog.findViewById(R.id.buttonClose); + TextView textViewStoreName = dialog.findViewById(R.id.textViewStoreName); + ImageView imageViewStoreLogo = dialog.findViewById(R.id.imageViewStoreLogo); + + // 更新店铺信息 + if (loginData != null) { + // 更新店铺名称 + if (loginData.getName() != null && !loginData.getName().isEmpty()) { + textViewStoreName.setText("尊敬的" + loginData.getName()); + } + + // 加载店铺 Logo(如果有的话) + if (loginData.getLogo() != null && !loginData.getLogo().isEmpty()) { + android.util.Log.d("MainActivity", "Loading store logo from: " + loginData.getLogo()); + + // 使用 Glide 加载网络图片,设置圆形裁剪和默认图片 + Glide.with(this) + .load(loginData.getLogo()) + .apply(RequestOptions.bitmapTransform(new CircleCrop())) + .placeholder(R.drawable.ic_warriors_logo) // 加载中显示默认图片 + .error(R.drawable.ic_warriors_logo) // 加载失败显示默认图片 + .into(imageViewStoreLogo); + } else { + // 如果没有 Logo URL,使用默认图片 + imageViewStoreLogo.setImageResource(R.drawable.ic_warriors_logo); + } + } // 设置关闭按钮点击事件 buttonClose.setOnClickListener(new View.OnClickListener() { @@ -224,10 +303,7 @@ public class MainActivity extends AppCompatActivity { }); // 设置平台选择下拉框的数据 - String[] platforms = {"请选择设备", "平台1", "平台2", "平台3"}; - ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, platforms); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - spinnerPlatform.setAdapter(adapter); + loadPadList(dialog, spinnerPlatform); // 设置进入使用按钮点击事件 buttonEnter.setOnClickListener(new View.OnClickListener() { @@ -237,7 +313,8 @@ public class MainActivity extends AppCompatActivity { if (selectedPosition == 0) { showToast("请选择设备"); } else { - String selectedPlatform = platforms[selectedPosition]; + // 获取选中的设备名称 + String selectedPlatform = spinnerPlatform.getSelectedItem().toString(); // 显示loading动画 showLoadingInDialog(dialog, buttonEnter, selectedPlatform); @@ -286,4 +363,220 @@ public class MainActivity extends AppCompatActivity { } }, 5000); // 5秒延时 } + + /** + * 保存认证Token + * @param token 认证Token + */ + private void saveAuthToken(String token) { + getSharedPreferences("app_prefs", MODE_PRIVATE) + .edit() + .putString("auth_token", token) + .apply(); + } + + /** + * 获取认证Token + * @return 认证Token + */ + private String getAuthToken() { + return getSharedPreferences("app_prefs", MODE_PRIVATE) + .getString("auth_token", ""); + } + + /** + * 保存用户信息 + * @param userInfo 用户信息 + */ + private void saveUserInfo(PadApiService.UserInfo userInfo) { + if (userInfo != null) { + getSharedPreferences("app_prefs", MODE_PRIVATE) + .edit() + .putString("user_id", userInfo.getUserId()) + .putString("username", userInfo.getUsername()) + .putString("nickname", userInfo.getNickname()) + .putString("store_id", userInfo.getStoreId()) + .putString("store_name", userInfo.getStoreName()) + .putString("role", userInfo.getRole()) + .apply(); + } + } + + /** + * 保存会话ID + * @param sessionId 会话ID + */ + private void saveSessionId(String sessionId) { + getSharedPreferences("app_prefs", MODE_PRIVATE) + .edit() + .putString("session_id", sessionId) + .apply(); + } + + /** + * 获取用户ID + * @return 用户ID + */ + private String getUserId() { + return getSharedPreferences("app_prefs", MODE_PRIVATE) + .getString("user_id", ""); + } + + /** + * 获取会话ID + * @return 会话ID + */ + private String getSessionId() { + return getSharedPreferences("app_prefs", MODE_PRIVATE) + .getString("session_id", ""); + } + + /** + * 加载Pad列表数据 + * @param dialog 弹框实例 + * @param spinner 下拉框组件 + */ + private void loadPadList(Dialog dialog, Spinner spinner) { + // 首先设置默认的加载中选项 + String[] loadingItems = {"正在加载设备列表..."}; + ArrayAdapter loadingAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, loadingItems); + loadingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinner.setAdapter(loadingAdapter); + + // 调用API获取Pad列表 + NetworkUtils.getPadList(new NetworkCallback() { + @Override + public void onStart() { + // 加载开始 + } + + @Override + public void onSuccess(PadApiService.PadListResponse data) { + // 加载成功,更新下拉框数据 + java.util.List padList = data.getPadList(); + java.util.List padNames = new java.util.ArrayList<>(); + padNames.add("请选择设备"); // 默认选项 + + if (padList != null && !padList.isEmpty()) { + for (PadApiService.PadInfo padInfo : padList) { + padNames.add(padInfo.getPadName() + " (" + padInfo.getStatus() + ")"); + } + } else { + padNames.add("暂无可用设备"); + } + + // 更新Spinner数据 + ArrayAdapter adapter = new ArrayAdapter<>(MainActivity.this, + android.R.layout.simple_spinner_item, padNames); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinner.setAdapter(adapter); + + // 更新进入按钮的点击事件,传入真实的Pad数据 + updateEnterButtonClickListener(dialog, padList); + } + + @Override + public void onError(int errorCode, String errorMessage) { + // 加载失败,显示错误信息 + String[] errorItems = {"加载失败,请重试"}; + ArrayAdapter errorAdapter = new ArrayAdapter<>(MainActivity.this, + android.R.layout.simple_spinner_item, errorItems); + errorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinner.setAdapter(errorAdapter); + + showToast("获取设备列表失败: " + errorMessage); + } + }); + } + + /** + * 更新进入按钮的点击事件 + * @param dialog 弹框实例 + * @param padList Pad列表数据 + */ + private void updateEnterButtonClickListener(Dialog dialog, java.util.List padList) { + View buttonEnter = dialog.findViewById(R.id.buttonEnter); + Spinner spinnerPlatform = dialog.findViewById(R.id.spinnerPlatform); + + buttonEnter.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int selectedPosition = spinnerPlatform.getSelectedItemPosition(); + if (selectedPosition == 0) { + showToast("请选择设备"); + } else if (padList != null && selectedPosition <= padList.size()) { + // 获取选中的Pad信息 + PadApiService.PadInfo selectedPad = padList.get(selectedPosition - 1); // 减1因为第0个是“请选择设备” + + // 调用Pad选择API + selectPadAndEnter(dialog, buttonEnter, selectedPad); + } else { + showToast("请选择有效的设备"); + } + } + }); + } + + /** + * 选择Pad并进入使用 + * @param dialog 弹框实例 + * @param buttonEnter 进入按钮 + * @param selectedPad 选中的Pad信息 + */ + private void selectPadAndEnter(Dialog dialog, View buttonEnter, PadApiService.PadInfo selectedPad) { + // 禁用按钮防止重复点击 + buttonEnter.setEnabled(false); + + // 保存原始按钮文字 + TextView buttonText = (TextView) buttonEnter; + String originalText = buttonText.getText().toString(); + + // 显示loading文字 + buttonText.setText("正在进入..."); + + // 调用Pad选择API + NetworkUtils.selectPad(selectedPad.getPadId(), getUserId(), getSessionId(), + new NetworkCallback() { + @Override + public void onSuccess(PadApiService.PadSelectResponse data) { + // 选择成功 + showToast("进入 " + selectedPad.getPadName() + " 成功!"); + dialog.dismiss(); + + // 这里可以添加跳转到主界面的逻辑 + // 保存选中的Pad信息 + saveSelectedPadInfo(selectedPad, data); + } + + @Override + public void onError(int errorCode, String errorMessage) { + // 选择失败 + showToast("选择设备失败: " + errorMessage); + + // 恢复按钮状态 + buttonEnter.setEnabled(true); + buttonText.setText(originalText); + } + + @Override + public void onComplete() { + // 请求完成 + } + }); + } + + /** + * 保存选中的Pad信息 + * @param padInfo Pad信息 + * @param selectResponse 选择响应 + */ + private void saveSelectedPadInfo(PadApiService.PadInfo padInfo, PadApiService.PadSelectResponse selectResponse) { + getSharedPreferences("app_prefs", MODE_PRIVATE) + .edit() + .putString("selected_pad_id", padInfo.getPadId()) + .putString("selected_pad_name", padInfo.getPadName()) + .putString("session_token", selectResponse.getSessionToken()) + .putLong("valid_until", selectResponse.getValidUntil()) + .apply(); + } } \ No newline at end of file diff --git a/app/src/main/java/com/ouxuan/oxface/OxFaceApplication.java b/app/src/main/java/com/ouxuan/oxface/OxFaceApplication.java new file mode 100644 index 0000000..cdca7fb --- /dev/null +++ b/app/src/main/java/com/ouxuan/oxface/OxFaceApplication.java @@ -0,0 +1,20 @@ +package com.ouxuan.oxface; + +import android.app.Application; + +import com.ouxuan.oxface.network.utils.NetworkUtils; + +/** + * 应用程序Application类 + * 用于全局初始化各种模块 + */ +public class OxFaceApplication extends Application { + + @Override + public void onCreate() { + super.onCreate(); + + // 初始化网络模块 + NetworkUtils.init(this); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ouxuan/oxface/network/NetworkConfig.java b/app/src/main/java/com/ouxuan/oxface/network/NetworkConfig.java new file mode 100644 index 0000000..ef6a7e7 --- /dev/null +++ b/app/src/main/java/com/ouxuan/oxface/network/NetworkConfig.java @@ -0,0 +1,45 @@ +package com.ouxuan.oxface.network; + +/** + * 网络配置常量类 + * 用于管理API地址、超时时间等网络相关配置 + */ +public class NetworkConfig { + + // API基础URL - 欧轩智能测试环境 + public static final String BASE_URL = "https://testmanager.ouxuanzhineng.cn/"; + + // API版本路径 + public static final String API_VERSION = "v3/"; + + // 完整的API基础路径 + public static final String API_BASE_PATH = API_VERSION + "pad/"; + + // 连接超时时间(秒) + public static final int CONNECT_TIMEOUT = 30; + + // 读取超时时间(秒) + public static final int READ_TIMEOUT = 30; + + // 写入超时时间(秒) + public static final int WRITE_TIMEOUT = 30; + + // 是否开启日志打印(Debug模式) + public static final boolean ENABLE_LOG = true; + + // 通用请求头 + public static final String HEADER_CONTENT_TYPE = "Content-Type"; + public static final String HEADER_AUTHORIZATION = "Authorization"; + public static final String HEADER_USER_AGENT = "User-Agent"; + + // Content-Type类型 + public static final String CONTENT_TYPE_JSON = "application/json"; + public static final String CONTENT_TYPE_FORM = "application/x-www-form-urlencoded"; + + // HTTP状态码 + public static final int HTTP_SUCCESS = 200; + public static final int HTTP_UNAUTHORIZED = 401; + public static final int HTTP_FORBIDDEN = 403; + public static final int HTTP_NOT_FOUND = 404; + public static final int HTTP_SERVER_ERROR = 500; +} \ No newline at end of file diff --git a/app/src/main/java/com/ouxuan/oxface/network/NetworkManager.java b/app/src/main/java/com/ouxuan/oxface/network/NetworkManager.java new file mode 100644 index 0000000..044daa8 --- /dev/null +++ b/app/src/main/java/com/ouxuan/oxface/network/NetworkManager.java @@ -0,0 +1,222 @@ +package com.ouxuan.oxface.network; + +import android.content.Context; +import android.os.Handler; +import android.os.Looper; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.ouxuan.oxface.network.callback.NetworkCallback; +import com.ouxuan.oxface.network.interceptor.HeaderInterceptor; +import com.ouxuan.oxface.network.model.ApiResponse; + +import java.util.concurrent.TimeUnit; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +/** + * 网络请求管理器 + * 单例模式,统一管理所有网络请求 + */ +public class NetworkManager { + + private static volatile NetworkManager instance; + private OkHttpClient okHttpClient; + private Retrofit retrofit; + private Gson gson; + private Handler mainHandler; + + private NetworkManager(Context context) { + initOkHttpClient(context); + initRetrofit(); + initGson(); + mainHandler = new Handler(Looper.getMainLooper()); + } + + /** + * 获取NetworkManager单例实例 + * @param context 上下文 + * @return NetworkManager实例 + */ + public static NetworkManager getInstance(Context context) { + if (instance == null) { + synchronized (NetworkManager.class) { + if (instance == null) { + instance = new NetworkManager(context.getApplicationContext()); + } + } + } + return instance; + } + + /** + * 初始化OkHttpClient + */ + private void initOkHttpClient(Context context) { + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .connectTimeout(NetworkConfig.CONNECT_TIMEOUT, TimeUnit.SECONDS) + .readTimeout(NetworkConfig.READ_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(NetworkConfig.WRITE_TIMEOUT, TimeUnit.SECONDS) + .addInterceptor(new HeaderInterceptor(context)); + + // 添加日志拦截器(仅在Debug模式下) + if (NetworkConfig.ENABLE_LOG) { + HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); + loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + builder.addInterceptor(loggingInterceptor); + } + + okHttpClient = builder.build(); + } + + /** + * 初始化Retrofit + */ + private void initRetrofit() { + retrofit = new Retrofit.Builder() + .baseUrl(NetworkConfig.BASE_URL) + .client(okHttpClient) + .addConverterFactory(GsonConverterFactory.create()) + .build(); + } + + /** + * 初始化Gson + */ + private void initGson() { + gson = new GsonBuilder() + .setDateFormat("yyyy-MM-dd HH:mm:ss") + .create(); + } + + /** + * 获取Retrofit实例 + * @return Retrofit实例 + */ + public Retrofit getRetrofit() { + return retrofit; + } + + /** + * 创建API服务接口 + * @param serviceClass 服务接口类 + * @param 服务接口类型 + * @return 服务接口实例 + */ + public T createService(Class serviceClass) { + return retrofit.create(serviceClass); + } + + /** + * 执行GET请求 + * @param url 请求URL + * @param callback 回调接口 + * @param 响应数据类型 + */ + public void get(String url, NetworkCallback callback) { + Request request = new Request.Builder() + .url(url) + .get() + .build(); + + executeRequest(request, callback); + } + + /** + * 执行POST请求 + * @param url 请求URL + * @param jsonBody JSON格式的请求体 + * @param callback 回调接口 + * @param 响应数据类型 + */ + public void post(String url, String jsonBody, NetworkCallback callback) { + RequestBody requestBody = RequestBody.create( + MediaType.parse(NetworkConfig.CONTENT_TYPE_JSON), + jsonBody + ); + + Request request = new Request.Builder() + .url(url) + .post(requestBody) + .build(); + + executeRequest(request, callback); + } + + /** + * 执行POST请求(传入对象,自动转换为JSON) + * @param url 请求URL + * @param requestObject 请求对象 + * @param callback 回调接口 + * @param 响应数据类型 + */ + public void post(String url, Object requestObject, NetworkCallback callback) { + String jsonBody = gson.toJson(requestObject); + post(url, jsonBody, callback); + } + + /** + * 执行网络请求 + * @param request 请求对象 + * @param callback 回调接口 + * @param 响应数据类型 + */ + private void executeRequest(Request request, NetworkCallback callback) { + // 主线程回调请求开始 + mainHandler.post(() -> callback.onStart()); + + okHttpClient.newCall(request).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + try { + String responseBody = response.body().string(); + + if (response.isSuccessful()) { + // 解析响应数据 + ApiResponse apiResponse = gson.fromJson(responseBody, ApiResponse.class); + + // 主线程回调结果 + mainHandler.post(() -> { + if (apiResponse.isSuccess()) { + callback.onSuccess(apiResponse.getData()); + } else { + callback.onError(apiResponse.getCode(), apiResponse.getMessage()); + } + callback.onComplete(); + }); + } else { + // HTTP错误 + mainHandler.post(() -> { + callback.onError(response.code(), "HTTP Error: " + response.message()); + callback.onComplete(); + }); + } + } catch (Exception e) { + // 解析异常 + mainHandler.post(() -> { + callback.onException(e); + callback.onComplete(); + }); + } + } + + @Override + public void onFailure(Call call, java.io.IOException e) { + // 网络请求失败 + mainHandler.post(() -> { + callback.onException(e); + callback.onComplete(); + }); + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ouxuan/oxface/network/api/PadApiService.java b/app/src/main/java/com/ouxuan/oxface/network/api/PadApiService.java new file mode 100644 index 0000000..c60240c --- /dev/null +++ b/app/src/main/java/com/ouxuan/oxface/network/api/PadApiService.java @@ -0,0 +1,304 @@ +package com.ouxuan.oxface.network.api; + +import com.google.gson.annotations.SerializedName; +import com.ouxuan.oxface.network.model.ApiResponse; + +import retrofit2.Call; +import retrofit2.http.Body; +import retrofit2.http.GET; +import retrofit2.http.POST; +import retrofit2.http.Query; + +/** + * Pad相关API接口 + * 对应旧UniApp中的pad相关接口 + */ +public interface PadApiService { + + /** + * Pad登录接口 + * 对应旧接口: /v3/pad/login + * @param loginRequest 登录请求体 + * @return 登录响应 + */ + @POST("v3/pad/login") + Call> padLogin(@Body PadLoginRequest loginRequest); + + /** + * 获取Pad列表 + * 对应旧接口: /v3/pad/list + * @return Pad列表响应 + */ + @GET("v3/pad/list") + Call> padList(); + + /** + * 获取Pad列表(带查询参数) + * @param userId 用户ID(可选) + * @param status 状态筛选(可选) + * @return Pad列表响应 + */ + @GET("v3/pad/list") + Call> padList(@Query("userId") String userId, + @Query("status") String status); + + /** + * Pad选择确认 + * 对应旧接口: /v3/pad/select + * @param selectRequest 选择请求体 + * @return 选择确认响应 + */ + @POST("v3/pad/select") + Call> padSelect(@Body PadSelectRequest selectRequest); + + // ==================== 请求和响应数据模型 ==================== + + /** + * Pad登录请求模型 + */ + public static class PadLoginRequest { + private String username; // 用户名 + private String password; // 密码 + private String deviceId; // 设备ID + private String deviceType; // 设备类型(如:android) + private String appVersion; // 应用版本 + + public PadLoginRequest(String username, String password, String deviceId) { + this.username = username; + this.password = password; + this.deviceId = deviceId; + this.deviceType = "android"; + this.appVersion = "1.0.0"; + } + + // Getters and Setters + public String getUsername() { return username; } + public void setUsername(String username) { this.username = username; } + + public String getPassword() { return password; } + public void setPassword(String password) { this.password = password; } + + public String getDeviceId() { return deviceId; } + public void setDeviceId(String deviceId) { this.deviceId = deviceId; } + + public String getDeviceType() { return deviceType; } + public void setDeviceType(String deviceType) { this.deviceType = deviceType; } + + public String getAppVersion() { return appVersion; } + public void setAppVersion(String appVersion) { this.appVersion = appVersion; } + } + + /** + * Pad登录响应模型 - 匹配实际服务器返回结构 + */ + public static class PadLoginResponse { + @SerializedName("brand_id") + private int brand_id; // 品牌ID + + @SerializedName("logo") + private String logo; // Logo URL + + @SerializedName("name") + private String name; // 门店名称 + + @SerializedName("stadium_id") + private int stadium_id; // 场馆ID + + @SerializedName("token") + private String token; // 访问令牌 + + // Getters and Setters + public int getBrandId() { return brand_id; } + public void setBrandId(int brand_id) { this.brand_id = brand_id; } + + public String getLogo() { return logo; } + public void setLogo(String logo) { this.logo = logo; } + + public String getName() { return name; } + public void setName(String name) { this.name = name; } + + public int getStadiumId() { return stadium_id; } + public void setStadiumId(int stadium_id) { this.stadium_id = stadium_id; } + + public String getToken() { return token; } + public void setToken(String token) { this.token = token; } + + // 为了兼容原有代码,保留一些方法 + public UserInfo getUserInfo() { + // 根据实际数据构造UserInfo对象 + UserInfo userInfo = new UserInfo(); + userInfo.setStoreName(this.name); + userInfo.setStoreId(String.valueOf(this.stadium_id)); + return userInfo; + } + + public String getSessionId() { + // 从token中提取会话信息,或返回token作为sessionId + return this.token; + } + + @Override + public String toString() { + return "PadLoginResponse{" + + "brand_id=" + brand_id + + ", logo='" + logo + '\'' + + ", name='" + name + '\'' + + ", stadium_id=" + stadium_id + + ", token='" + token + '\'' + + '}'; + } + } + + /** + * 用户信息模型 + */ + public static class UserInfo { + private String userId; // 用户ID + private String username; // 用户名 + private String nickname; // 昵称 + private String role; // 角色 + private String storeId; // 店铺ID + private String storeName; // 店铺名称 + private String permissions; // 权限列表 + + // Getters and Setters + public String getUserId() { return userId; } + public void setUserId(String userId) { this.userId = userId; } + + public String getUsername() { return username; } + public void setUsername(String username) { this.username = username; } + + public String getNickname() { return nickname; } + public void setNickname(String nickname) { this.nickname = nickname; } + + public String getRole() { return role; } + public void setRole(String role) { this.role = role; } + + public String getStoreId() { return storeId; } + public void setStoreId(String storeId) { this.storeId = storeId; } + + public String getStoreName() { return storeName; } + public void setStoreName(String storeName) { this.storeName = storeName; } + + public String getPermissions() { return permissions; } + public void setPermissions(String permissions) { this.permissions = permissions; } + } + + /** + * Pad列表响应模型 + */ + public static class PadListResponse { + private java.util.List padList; // Pad设备列表 + private int totalCount; // 总数量 + private String lastUpdateTime; // 最后更新时间 + + // Getters and Setters + public java.util.List getPadList() { return padList; } + public void setPadList(java.util.List padList) { this.padList = padList; } + + public int getTotalCount() { return totalCount; } + public void setTotalCount(int totalCount) { this.totalCount = totalCount; } + + public String getLastUpdateTime() { return lastUpdateTime; } + public void setLastUpdateTime(String lastUpdateTime) { this.lastUpdateTime = lastUpdateTime; } + } + + /** + * Pad设备信息模型 + */ + public static class PadInfo { + private String padId; // Pad ID + private String padName; // Pad名称 + private String padType; // Pad类型 + private String status; // 状态(online/offline/busy) + private String location; // 位置 + private String description; // 描述 + private boolean isSelected; // 是否已选择 + private String lastActiveTime; // 最后活跃时间 + + // Getters and Setters + public String getPadId() { return padId; } + public void setPadId(String padId) { this.padId = padId; } + + public String getPadName() { return padName; } + public void setPadName(String padName) { this.padName = padName; } + + public String getPadType() { return padType; } + public void setPadType(String padType) { this.padType = padType; } + + public String getStatus() { return status; } + public void setStatus(String status) { this.status = status; } + + public String getLocation() { return location; } + public void setLocation(String location) { this.location = location; } + + public String getDescription() { return description; } + public void setDescription(String description) { this.description = description; } + + public boolean isSelected() { return isSelected; } + public void setSelected(boolean selected) { isSelected = selected; } + + public String getLastActiveTime() { return lastActiveTime; } + public void setLastActiveTime(String lastActiveTime) { this.lastActiveTime = lastActiveTime; } + } + + /** + * Pad选择请求模型 + */ + public static class PadSelectRequest { + private String padId; // 选择的Pad ID + private String userId; // 用户ID + private String sessionId; // 会话ID + private String selectReason; // 选择原因(可选) + + public PadSelectRequest(String padId, String userId, String sessionId) { + this.padId = padId; + this.userId = userId; + this.sessionId = sessionId; + } + + // Getters and Setters + public String getPadId() { return padId; } + public void setPadId(String padId) { this.padId = padId; } + + public String getUserId() { return userId; } + public void setUserId(String userId) { this.userId = userId; } + + public String getSessionId() { return sessionId; } + public void setSessionId(String sessionId) { this.sessionId = sessionId; } + + public String getSelectReason() { return selectReason; } + public void setSelectReason(String selectReason) { this.selectReason = selectReason; } + } + + /** + * Pad选择响应模型 + */ + public static class PadSelectResponse { + private String result; // 选择结果(success/failed) + private String message; // 响应消息 + private String selectedPadId; // 已选择的Pad ID + private String selectedPadName; // 已选择的Pad名称 + private String sessionToken; // 会话令牌 + private long validUntil; // 有效期至 + + // Getters and Setters + public String getResult() { return result; } + public void setResult(String result) { this.result = result; } + + public String getMessage() { return message; } + public void setMessage(String message) { this.message = message; } + + public String getSelectedPadId() { return selectedPadId; } + public void setSelectedPadId(String selectedPadId) { this.selectedPadId = selectedPadId; } + + public String getSelectedPadName() { return selectedPadName; } + public void setSelectedPadName(String selectedPadName) { this.selectedPadName = selectedPadName; } + + public String getSessionToken() { return sessionToken; } + public void setSessionToken(String sessionToken) { this.sessionToken = sessionToken; } + + public long getValidUntil() { return validUntil; } + public void setValidUntil(long validUntil) { this.validUntil = validUntil; } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ouxuan/oxface/network/api/UserApiService.java b/app/src/main/java/com/ouxuan/oxface/network/api/UserApiService.java new file mode 100644 index 0000000..bc9f785 --- /dev/null +++ b/app/src/main/java/com/ouxuan/oxface/network/api/UserApiService.java @@ -0,0 +1,215 @@ +package com.ouxuan.oxface.network.api; + +import com.ouxuan.oxface.network.model.ApiResponse; + +import retrofit2.Call; +import retrofit2.http.Body; +import retrofit2.http.GET; +import retrofit2.http.POST; +import retrofit2.http.Query; + +/** + * 用户相关API接口 + * 使用Retrofit注解定义RESTful API + */ +public interface UserApiService { + + /** + * 用户登录 + * @param loginRequest 登录请求体 + * @return 登录响应 + */ + @POST("auth/login") + Call> login(@Body LoginRequest loginRequest); + + /** + * 用户注册 + * @param registerRequest 注册请求体 + * @return 注册响应 + */ + @POST("auth/register") + Call> register(@Body RegisterRequest registerRequest); + + /** + * 获取用户信息 + * @param userId 用户ID + * @return 用户信息响应 + */ + @GET("user/info") + Call> getUserInfo(@Query("userId") String userId); + + /** + * 刷新Token + * @param refreshRequest 刷新Token请求 + * @return Token响应 + */ + @POST("auth/refresh") + Call> refreshToken(@Body RefreshTokenRequest refreshRequest); + + /** + * 用户登出 + * @return 登出响应 + */ + @POST("auth/logout") + Call> logout(); + + // ==================== 请求和响应数据模型 ==================== + + /** + * 登录请求模型 + */ + public static class LoginRequest { + private String username; + private String password; + private String deviceId; + + public LoginRequest(String username, String password, String deviceId) { + this.username = username; + this.password = password; + this.deviceId = deviceId; + } + + // Getters and Setters + public String getUsername() { return username; } + public void setUsername(String username) { this.username = username; } + + public String getPassword() { return password; } + public void setPassword(String password) { this.password = password; } + + public String getDeviceId() { return deviceId; } + public void setDeviceId(String deviceId) { this.deviceId = deviceId; } + } + + /** + * 登录响应模型 + */ + public static class LoginResponse { + private String token; + private String refreshToken; + private UserInfo userInfo; + private long expiresIn; + + // Getters and Setters + public String getToken() { return token; } + public void setToken(String token) { this.token = token; } + + public String getRefreshToken() { return refreshToken; } + public void setRefreshToken(String refreshToken) { this.refreshToken = refreshToken; } + + public UserInfo getUserInfo() { return userInfo; } + public void setUserInfo(UserInfo userInfo) { this.userInfo = userInfo; } + + public long getExpiresIn() { return expiresIn; } + public void setExpiresIn(long expiresIn) { this.expiresIn = expiresIn; } + } + + /** + * 用户信息模型 + */ + public static class UserInfo { + private String userId; + private String username; + private String nickname; + private String email; + private String avatar; + private String role; + + // Getters and Setters + public String getUserId() { return userId; } + public void setUserId(String userId) { this.userId = userId; } + + public String getUsername() { return username; } + public void setUsername(String username) { this.username = username; } + + public String getNickname() { return nickname; } + public void setNickname(String nickname) { this.nickname = nickname; } + + public String getEmail() { return email; } + public void setEmail(String email) { this.email = email; } + + public String getAvatar() { return avatar; } + public void setAvatar(String avatar) { this.avatar = avatar; } + + public String getRole() { return role; } + public void setRole(String role) { this.role = role; } + } + + /** + * 注册请求模型 + */ + public static class RegisterRequest { + private String username; + private String password; + private String email; + private String nickname; + + public RegisterRequest(String username, String password, String email, String nickname) { + this.username = username; + this.password = password; + this.email = email; + this.nickname = nickname; + } + + // Getters and Setters + public String getUsername() { return username; } + public void setUsername(String username) { this.username = username; } + + public String getPassword() { return password; } + public void setPassword(String password) { this.password = password; } + + public String getEmail() { return email; } + public void setEmail(String email) { this.email = email; } + + public String getNickname() { return nickname; } + public void setNickname(String nickname) { this.nickname = nickname; } + } + + /** + * 注册响应模型 + */ + public static class RegisterResponse { + private String userId; + private String message; + + // Getters and Setters + public String getUserId() { return userId; } + public void setUserId(String userId) { this.userId = userId; } + + public String getMessage() { return message; } + public void setMessage(String message) { this.message = message; } + } + + /** + * Token响应模型 + */ + public static class TokenResponse { + private String token; + private String refreshToken; + private long expiresIn; + + // Getters and Setters + public String getToken() { return token; } + public void setToken(String token) { this.token = token; } + + public String getRefreshToken() { return refreshToken; } + public void setRefreshToken(String refreshToken) { this.refreshToken = refreshToken; } + + public long getExpiresIn() { return expiresIn; } + public void setExpiresIn(long expiresIn) { this.expiresIn = expiresIn; } + } + + /** + * 刷新Token请求模型 + */ + public static class RefreshTokenRequest { + private String refreshToken; + + public RefreshTokenRequest(String refreshToken) { + this.refreshToken = refreshToken; + } + + // Getters and Setters + public String getRefreshToken() { return refreshToken; } + public void setRefreshToken(String refreshToken) { this.refreshToken = refreshToken; } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ouxuan/oxface/network/callback/NetworkCallback.java b/app/src/main/java/com/ouxuan/oxface/network/callback/NetworkCallback.java new file mode 100644 index 0000000..40a1fde --- /dev/null +++ b/app/src/main/java/com/ouxuan/oxface/network/callback/NetworkCallback.java @@ -0,0 +1,44 @@ +package com.ouxuan.oxface.network.callback; + +/** + * 网络请求回调接口 + * @param 响应数据类型 + */ +public interface NetworkCallback { + + /** + * 请求成功回调 + * @param data 响应数据 + */ + void onSuccess(T data); + + /** + * 请求失败回调 + * @param errorCode 错误码 + * @param errorMessage 错误信息 + */ + void onError(int errorCode, String errorMessage); + + /** + * 网络异常回调 + * @param throwable 异常信息 + */ + default void onException(Throwable throwable) { + onError(-1, throwable.getMessage()); + } + + /** + * 请求开始回调(可选实现) + */ + default void onStart() { + // 默认空实现 + } + + /** + * 请求完成回调(可选实现) + * 无论成功或失败都会调用 + */ + default void onComplete() { + // 默认空实现 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ouxuan/oxface/network/interceptor/HeaderInterceptor.java b/app/src/main/java/com/ouxuan/oxface/network/interceptor/HeaderInterceptor.java new file mode 100644 index 0000000..3c473b7 --- /dev/null +++ b/app/src/main/java/com/ouxuan/oxface/network/interceptor/HeaderInterceptor.java @@ -0,0 +1,62 @@ +package com.ouxuan.oxface.network.interceptor; + +import android.content.Context; +import android.content.SharedPreferences; + +import com.ouxuan.oxface.network.NetworkConfig; + +import java.io.IOException; + +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; + +/** + * 请求头拦截器 + * 用于添加通用请求头,如Authorization、User-Agent等 + */ +public class HeaderInterceptor implements Interceptor { + + private Context context; + + public HeaderInterceptor(Context context) { + this.context = context; + } + + @Override + public Response intercept(Chain chain) throws IOException { + Request originalRequest = chain.request(); + + // 构建新的请求,添加通用请求头 + Request.Builder requestBuilder = originalRequest.newBuilder() + .header(NetworkConfig.HEADER_CONTENT_TYPE, NetworkConfig.CONTENT_TYPE_JSON) + .header(NetworkConfig.HEADER_USER_AGENT, getUserAgent()) + .method(originalRequest.method(), originalRequest.body()); + + // 添加Authorization token(如果存在) + String token = getAuthToken(); + if (token != null && !token.isEmpty()) { + requestBuilder.header(NetworkConfig.HEADER_AUTHORIZATION, "Bearer " + token); + } + + Request newRequest = requestBuilder.build(); + return chain.proceed(newRequest); + } + + /** + * 获取用户认证Token + * @return token字符串 + */ + private String getAuthToken() { + SharedPreferences prefs = context.getSharedPreferences("app_prefs", Context.MODE_PRIVATE); + return prefs.getString("auth_token", ""); + } + + /** + * 获取User-Agent + * @return User-Agent字符串 + */ + private String getUserAgent() { + return "OxFaceAndroid/1.0 (Android)"; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ouxuan/oxface/network/model/ApiResponse.java b/app/src/main/java/com/ouxuan/oxface/network/model/ApiResponse.java new file mode 100644 index 0000000..947580a --- /dev/null +++ b/app/src/main/java/com/ouxuan/oxface/network/model/ApiResponse.java @@ -0,0 +1,67 @@ +package com.ouxuan.oxface.network.model; + +/** + * 通用API响应数据模型 + * @param 具体的数据类型 + */ +public class ApiResponse { + + private int code; // 响应状态码 + private String message; // 响应消息 + private T data; // 具体数据 + private boolean success; // 是否成功 + + public ApiResponse() { + } + + public ApiResponse(int code, String message, T data) { + this.code = code; + this.message = message; + this.data = data; + this.success = (code == 0); // 根据实际服务器响应,成功状态码是0 + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + this.success = (code == 0); // 根据实际服务器响应,成功状态码是0 + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + public boolean isSuccess() { + // 基于code字段动态判断成功状态,而不依赖success字段 + return code == 0; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + @Override + public String toString() { + return "ApiResponse{" + + "code=" + code + + ", message='" + message + '\'' + + ", data=" + data + + ", success=" + success + + '}'; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ouxuan/oxface/network/utils/NetworkUtils.java b/app/src/main/java/com/ouxuan/oxface/network/utils/NetworkUtils.java new file mode 100644 index 0000000..7f9ee3f --- /dev/null +++ b/app/src/main/java/com/ouxuan/oxface/network/utils/NetworkUtils.java @@ -0,0 +1,422 @@ +package com.ouxuan.oxface.network.utils; + +import android.content.Context; + +import com.ouxuan.oxface.network.NetworkManager; +import com.ouxuan.oxface.network.api.PadApiService; +import com.ouxuan.oxface.network.api.UserApiService; +import com.ouxuan.oxface.network.callback.NetworkCallback; +import com.ouxuan.oxface.network.model.ApiResponse; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +/** + * 网络请求工具类 + * 提供便捷的网络请求方法 + */ +public class NetworkUtils { + + private static NetworkManager networkManager; + private static UserApiService userApiService; + private static PadApiService padApiService; + + /** + * 初始化网络工具类 + * @param context 上下文 + */ + public static void init(Context context) { + networkManager = NetworkManager.getInstance(context); + userApiService = networkManager.createService(UserApiService.class); + padApiService = networkManager.createService(PadApiService.class); + } + + /** + * 用户登录 + * @param username 用户名 + * @param password 密码 + * @param deviceId 设备ID + * @param callback 回调接口 + */ + public static void login(String username, String password, String deviceId, + NetworkCallback callback) { + if (userApiService == null) { + callback.onError(-1, "NetworkUtils未初始化,请先调用init()方法"); + return; + } + + UserApiService.LoginRequest request = new UserApiService.LoginRequest(username, password, deviceId); + + callback.onStart(); + userApiService.login(request).enqueue(new Callback>() { + @Override + public void onResponse(Call> call, + Response> response) { + try { + if (response.isSuccessful() && response.body() != null) { + ApiResponse apiResponse = response.body(); + + if (apiResponse.isSuccess()) { + callback.onSuccess(apiResponse.getData()); + } else { + callback.onError(apiResponse.getCode(), apiResponse.getMessage()); + } + } else { + callback.onError(response.code(), "请求失败: " + response.message()); + } + } catch (Exception e) { + callback.onException(e); + } finally { + callback.onComplete(); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + callback.onException(t); + callback.onComplete(); + } + }); + } + + /** + * 用户注册 + * @param username 用户名 + * @param password 密码 + * @param email 邮箱 + * @param nickname 昵称 + * @param callback 回调接口 + */ + public static void register(String username, String password, String email, String nickname, + NetworkCallback callback) { + if (userApiService == null) { + callback.onError(-1, "NetworkUtils未初始化,请先调用init()方法"); + return; + } + + UserApiService.RegisterRequest request = new UserApiService.RegisterRequest(username, password, email, nickname); + + callback.onStart(); + userApiService.register(request).enqueue(new Callback>() { + @Override + public void onResponse(Call> call, + Response> response) { + try { + if (response.isSuccessful() && response.body() != null) { + ApiResponse apiResponse = response.body(); + + if (apiResponse.isSuccess()) { + callback.onSuccess(apiResponse.getData()); + } else { + callback.onError(apiResponse.getCode(), apiResponse.getMessage()); + } + } else { + callback.onError(response.code(), "请求失败: " + response.message()); + } + } catch (Exception e) { + callback.onException(e); + } finally { + callback.onComplete(); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + callback.onException(t); + callback.onComplete(); + } + }); + } + + /** + * 获取用户信息 + * @param userId 用户ID + * @param callback 回调接口 + */ + public static void getUserInfo(String userId, NetworkCallback callback) { + if (userApiService == null) { + callback.onError(-1, "NetworkUtils未初始化,请先调用init()方法"); + return; + } + + callback.onStart(); + userApiService.getUserInfo(userId).enqueue(new Callback>() { + @Override + public void onResponse(Call> call, + Response> response) { + try { + if (response.isSuccessful() && response.body() != null) { + ApiResponse apiResponse = response.body(); + + if (apiResponse.isSuccess()) { + callback.onSuccess(apiResponse.getData()); + } else { + callback.onError(apiResponse.getCode(), apiResponse.getMessage()); + } + } else { + callback.onError(response.code(), "请求失败: " + response.message()); + } + } catch (Exception e) { + callback.onException(e); + } finally { + callback.onComplete(); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + callback.onException(t); + callback.onComplete(); + } + }); + } + + /** + * 用户登出 + * @param callback 回调接口 + */ + public static void logout(NetworkCallback callback) { + if (userApiService == null) { + callback.onError(-1, "NetworkUtils未初始化,请先调用init()方法"); + return; + } + + callback.onStart(); + userApiService.logout().enqueue(new Callback>() { + @Override + public void onResponse(Call> call, + Response> response) { + try { + if (response.isSuccessful() && response.body() != null) { + ApiResponse apiResponse = response.body(); + + if (apiResponse.isSuccess()) { + callback.onSuccess(null); + } else { + callback.onError(apiResponse.getCode(), apiResponse.getMessage()); + } + } else { + callback.onError(response.code(), "请求失败: " + response.message()); + } + } catch (Exception e) { + callback.onException(e); + } finally { + callback.onComplete(); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + callback.onException(t); + callback.onComplete(); + } + }); + } + + /** + * 获取NetworkManager实例 + * @return NetworkManager实例 + */ + public static NetworkManager getNetworkManager() { + return networkManager; + } + + // ==================== Pad相关API调用方法 ==================== + + /** + * Pad登录 + * @param username 用户名 + * @param password 密码 + * @param deviceId 设备ID + * @param callback 回调接口 + */ + public static void padLogin(String username, String password, String deviceId, + NetworkCallback callback) { + if (padApiService == null) { + callback.onError(-1, "NetworkUtils未初始化,请先调用init()方法"); + return; + } + + PadApiService.PadLoginRequest request = new PadApiService.PadLoginRequest(username, password, deviceId); + + callback.onStart(); + padApiService.padLogin(request).enqueue(new Callback>() { + @Override + public void onResponse(Call> call, + Response> response) { + try { + if (response.isSuccessful() && response.body() != null) { + ApiResponse apiResponse = response.body(); + + // 添加详细的调试日志 + android.util.Log.d("NetworkUtils", "Response received - Code: " + apiResponse.getCode() + + ", Message: '" + apiResponse.getMessage() + "'" + + ", Success: " + apiResponse.isSuccess() + + ", Data: " + (apiResponse.getData() != null ? "not null" : "null")); + + if (apiResponse.isSuccess()) { + android.util.Log.d("NetworkUtils", "Calling onSuccess with data: " + apiResponse.getData()); + callback.onSuccess(apiResponse.getData()); + } else { + android.util.Log.d("NetworkUtils", "Calling onError - Code: " + apiResponse.getCode() + ", Message: " + apiResponse.getMessage()); + callback.onError(apiResponse.getCode(), apiResponse.getMessage()); + } + } else { + android.util.Log.e("NetworkUtils", "Response not successful or body is null - Code: " + response.code()); + callback.onError(response.code(), "请求失败: " + response.message()); + } + } catch (Exception e) { + callback.onException(e); + } finally { + callback.onComplete(); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + callback.onException(t); + callback.onComplete(); + } + }); + } + + /** + * 获取Pad列表 + * @param callback 回调接口 + */ + public static void getPadList(NetworkCallback callback) { + if (padApiService == null) { + callback.onError(-1, "NetworkUtils未初始化,请先调用init()方法"); + return; + } + + callback.onStart(); + padApiService.padList().enqueue(new Callback>() { + @Override + public void onResponse(Call> call, + Response> response) { + try { + if (response.isSuccessful() && response.body() != null) { + ApiResponse apiResponse = response.body(); + + if (apiResponse.isSuccess()) { + callback.onSuccess(apiResponse.getData()); + } else { + callback.onError(apiResponse.getCode(), apiResponse.getMessage()); + } + } else { + callback.onError(response.code(), "请求失败: " + response.message()); + } + } catch (Exception e) { + callback.onException(e); + } finally { + callback.onComplete(); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + callback.onException(t); + callback.onComplete(); + } + }); + } + + /** + * 获取Pad列表(带查询参数) + * @param userId 用户ID + * @param status 状态筛选 + * @param callback 回调接口 + */ + public static void getPadList(String userId, String status, + NetworkCallback callback) { + if (padApiService == null) { + callback.onError(-1, "NetworkUtils未初始化,请先调用init()方法"); + return; + } + + callback.onStart(); + padApiService.padList(userId, status).enqueue(new Callback>() { + @Override + public void onResponse(Call> call, + Response> response) { + try { + if (response.isSuccessful() && response.body() != null) { + ApiResponse apiResponse = response.body(); + + if (apiResponse.isSuccess()) { + callback.onSuccess(apiResponse.getData()); + } else { + callback.onError(apiResponse.getCode(), apiResponse.getMessage()); + } + } else { + callback.onError(response.code(), "请求失败: " + response.message()); + } + } catch (Exception e) { + callback.onException(e); + } finally { + callback.onComplete(); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + callback.onException(t); + callback.onComplete(); + } + }); + } + + /** + * Pad选择确认 + * @param padId 选择的Pad ID + * @param userId 用户ID + * @param sessionId 会话ID + * @param callback 回调接口 + */ + public static void selectPad(String padId, String userId, String sessionId, + NetworkCallback callback) { + if (padApiService == null) { + callback.onError(-1, "NetworkUtils未初始化,请先调用init()方法"); + return; + } + + PadApiService.PadSelectRequest request = new PadApiService.PadSelectRequest(padId, userId, sessionId); + + callback.onStart(); + padApiService.padSelect(request).enqueue(new Callback>() { + @Override + public void onResponse(Call> call, + Response> response) { + try { + if (response.isSuccessful() && response.body() != null) { + ApiResponse apiResponse = response.body(); + + if (apiResponse.isSuccess()) { + callback.onSuccess(apiResponse.getData()); + } else { + callback.onError(apiResponse.getCode(), apiResponse.getMessage()); + } + } else { + callback.onError(response.code(), "请求失败: " + response.message()); + } + } catch (Exception e) { + callback.onException(e); + } finally { + callback.onComplete(); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + callback.onException(t); + callback.onComplete(); + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_login_success.xml b/app/src/main/res/layout/dialog_login_success.xml index a258cb7..6697620 100644 --- a/app/src/main/res/layout/dialog_login_success.xml +++ b/app/src/main/res/layout/dialog_login_success.xml @@ -70,14 +70,16 @@ + android:contentDescription="Store Logo" />