package com.fujica.abk.api; import com.fujica.abk.common.EventBus; import com.fujica.abk.component.AuthorizationDialog; import com.fujica.abk.model.out.LoginRes; import com.fujica.abk.utils.Log; import com.fujica.abk.utils.R; import com.fujica.abk.utils.Toast; import com.fujica.abk.utils.api; import com.fujica.abk.utils.ApiOption; import com.google.gson.reflect.TypeToken; import com.huawei.hms.accountsdk.exception.ApiException; import com.huawei.hms.accountsdk.support.account.AccountAuthManager; import com.huawei.hms.accountsdk.support.account.request.AccountAuthParams; import com.huawei.hms.accountsdk.support.account.request.AccountAuthParamsHelper; import com.huawei.hms.accountsdk.support.account.result.AuthAccount; import com.huawei.hms.accountsdk.support.account.service.AccountAuthService; import com.huawei.hms.accountsdk.support.account.tasks.OnFailureListener; import com.huawei.hms.accountsdk.support.account.tasks.OnSuccessListener; import com.huawei.hms.accountsdk.support.account.tasks.Task; import ohos.app.Context; import java.util.concurrent.CompletableFuture; /** * 认证工具类 */ public class auth { // 登录状态标志,防止并发登录 private static boolean authing = false; /** * 登录 * * @param context 上下文 * @return CompletableFuture 登录是否成功 */ public static CompletableFuture login(Context context) { CompletableFuture future = new CompletableFuture<>(); // 检查是否正在登录 if (authing) { Log.info("正在登录中,请勿重复操作"); Toast.info(context, "正在登录中..."); future.complete(false); return future; } if (cache.isAuth(context)) { future.complete(true); return future; } // 设置登录状态 authing = true; if (config.isDebug) { proceedWithLogin(context, future); } else { // 登录之前先显示授权确认弹框 // 确保在主线程中执行 context.getUITaskDispatcher().asyncDispatch(() -> { AuthorizationDialog authDialog = new AuthorizationDialog(context); authDialog.setOnAuthorizationListener(new AuthorizationDialog.OnAuthorizationListener() { @Override public void onAuthorized() { // 用户确认授权后,继续登录流程 proceedWithLogin(context, future); } @Override public void onCancelled() { // 用户取消授权 Toast.error(context, "已取消授权"); authing = false; // 重置登录状态 future.complete(false); } }); authDialog.show(); }); } return future; } /** * 执行实际的登录流程 */ private static void proceedWithLogin(Context context, CompletableFuture future) { if (config.isDebug) { HWResult hwResult = new HWResult(); hwResult.setAppId(config.getAppId()); //dev环境 // hwResult.setOpenId("AAAjdc3utGbjvCsmhASifWUoEpmH"); //dev环境 hwResult.setOpenId("oq5PA6YFGAqRhTuipxFpZNK_EN04"); ApiOption option = new ApiOption(); option.setUrl("/member/hw/login"); option.setMethod(ApiOption.POST); // 注意:HMS SDK可能不直接提供authorizationCode,这里需要根据实际情况调整 // 如果HMS SDK不提供code,可能需要使用其他方式获取 java.util.Map data = new java.util.HashMap<>(); data.put("appId", config.getAppId()); data.put("code", hwResult.getCode()); // 需要从授权结果中获取 data.put("openId", hwResult.getOpenId()); data.put("unionId", hwResult.getUnionId()); data.put("source", "7"); option.setData(data); processCodeLogin(context, option, hwResult, future); return; } try { // 先获取华为账号信息 getHuaWeiAccount(context).thenAccept(hwResult -> { if (!hwResult.isSuccess()) { authing = false; // 重置登录状态 future.complete(false); return; } // 使用授权码登录 ApiOption option = new ApiOption(); option.setUrl("/member/hw/code/login"); option.setMethod(ApiOption.POST); // 注意:HMS SDK可能不直接提供authorizationCode,这里需要根据实际情况调整 // 如果HMS SDK不提供code,可能需要使用其他方式获取 java.util.Map data = new java.util.HashMap<>(); data.put("appId", config.getAppId()); data.put("code", hwResult.getCode()); // 需要从授权结果中获取 data.put("openId", hwResult.getOpenId()); data.put("unionId", hwResult.getUnionId()); data.put("source", "7"); option.setData(data); processCodeLogin(context, option, hwResult, future); }).exceptionally(e -> { try { Log.error(e); future.complete(false); return null; } finally { authing = false; } }); } catch (Exception e) { try { Log.error(e); future.complete(false); } finally { authing = false; } } } /** * 处理授权码登录 * * @param context 上下文 * @param option API选项 * @param hwResult 华为账号信息 * @param future 异步结果 */ private static void processCodeLogin(Context context, ApiOption option, HWResult hwResult, CompletableFuture future) { api.http(context, option, new TypeToken>() { }).thenAccept((R result) -> { try { if (result != null && result.isSuccess() && result.getData() != null) { LoginRes res = result.getData(); cache.setOpenId(context, res.getOpenId()); cache.setToken(context, res.getToken()); cache.setMobile(context, res.getMobile()); // 发布登录成功事件,通知UI更新 EventBus.getInstance().emit("onLoginSuccess"); future.complete(true); } else { future.complete(false); } } finally { // 确保最终重置登录状态 authing = false; } }).exceptionally(e -> { try { Log.error(e); future.complete(false); return null; } finally { // 确保最终重置登录状态 authing = false; } }); } /** * 处理手机号登录 */ private static void handlePhoneLogin(Context context, HWResult hwResult, CompletableFuture future) { // 这里需要显示手机号输入对话框 // 由于PhoneDialog可能不存在,这里提供一个占位实现 // 实际使用时需要根据项目中的对话框实现进行调整 // 示例:假设有一个PhoneDialog.show方法 // PhoneDialog.show(context, (phone, code) -> { // hwResult.setPhone(phone); // // 使用手机号和验证码登录 // ApiOption option = new ApiOption(); // option.setUrl("/member/hw/login"); // java.util.Map data = new java.util.HashMap<>(); // data.put("phone", phone); // data.put("code", code); // data.put("openId", hwResult.getOpenId()); // data.put("unionId", hwResult.getUnionId()); // data.put("appId", config.appId); // data.put("source", 7); // option.setData(data); // // return api.post1(context, option).thenApply(result -> { // if (result != null && result.isSuccess() && result.getData() != null) { // LoginRes loginRes = (LoginRes) result.getData(); // if (loginRes != null) { // cache.setOpenId(context, hwResult.getOpenId()); // cache.setToken(context, loginRes.getToken()); // cache.setMobile(context, loginRes.getMobile()); // return true; // } // } // return false; // }); // }); // 暂时返回false,需要根据实际项目中的PhoneDialog实现进行调整 authing = false; // 重置登录状态 future.complete(false); } /** * 获取华为账号信息 * * @param context 上下文 * @return CompletableFuture 华为账号信息 */ public static CompletableFuture getHuaWeiAccount(Context context) { CompletableFuture future = new CompletableFuture<>(); try { // 创建授权请求参数 AccountAuthParams accountAuthParams = new AccountAuthParamsHelper( AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM) .setAuthorizationCode() .createParams(); AccountAuthService accountAuthService; try { accountAuthService = AccountAuthManager.getService(accountAuthParams); } catch (ApiException e) { Log.error("Init Huawei accountAuthService FAILED: " + e.getStatusCode()); Toast.error(context, "登录失败:" + e.getStatusCode()); future.complete(new HWResult(false)); return future; } // 先尝试静默登录 Task taskSilentSignIn = accountAuthService.silentSignIn(); taskSilentSignIn.addOnSuccessListener(authAccount -> { HWResult result = new HWResult(true); result.setCode(authAccount.getAuthorizationCode()); result.setAppId(config.getAppId()); result.setOpenId(authAccount.getOpenId()); result.setUnionId(authAccount.getUnionId()); // HMS SDK可能不直接提供手机号,需要单独申请权限 result.setPhone(""); future.complete(result); }); taskSilentSignIn.addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { if (e instanceof ApiException) { ApiException apiException = (ApiException) e; int statusCode = apiException.getStatusCode(); // 静默登录失败,尝试前台登录 Task taskSignIn = accountAuthService.signIn(); taskSignIn.addOnSuccessListener(new OnSuccessListener() { @Override public void onSuccess(AuthAccount authAccount) { HWResult result = new HWResult(true); result.setCode(authAccount.getAuthorizationCode()); result.setAppId(config.getAppId()); result.setOpenId(authAccount.getOpenId()); result.setUnionId(authAccount.getUnionId()); result.setPhone(""); future.complete(result); } }); taskSignIn.addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { handleAuthError(context, e, future); } }); } else { handleAuthError(context, e, future); } } }); } catch (Exception e) { handleAuthError(context, e, future); } return future; } /** * 处理认证错误 */ private static void handleAuthError(Context context, Exception error, CompletableFuture future) { if (error instanceof ApiException) { ApiException apiException = (ApiException) error; int code = apiException.getStatusCode(); // 模拟器调试模式 if (code == 12300001 && config.isDebug) { HWResult result = new HWResult(true); result.setAppId(config.getAppId()); result.setOpenId("AAAjdc3utGbjvphuWASifWUoEpm1"); result.setUnionId(""); result.setPhone(""); future.complete(result); return; } // 用户取消 if (code == 1001502012) { Toast.error(context, "已取消关联"); future.complete(new HWResult(false)); return; } Toast.error(context, "关联失败: " + code + ", " + apiException.getMessage()); Log.error("Failed to auth. Code: " + code + ", message: " + apiException.getMessage()); } else { Toast.error(context, "关联失败: " + error.getMessage()); Log.error(error); } future.complete(new HWResult(false)); } }