| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- 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<Boolean> 登录是否成功
- */
- public static CompletableFuture<Boolean> login(Context context) {
- CompletableFuture<Boolean> 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<Boolean> 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<String, String> 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<String, String> 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<Boolean> future) {
- api.http(context, option, new TypeToken<R<LoginRes>>() {
- }).thenAccept((R<LoginRes> 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<Boolean> future) {
- // 这里需要显示手机号输入对话框
- // 由于PhoneDialog可能不存在,这里提供一个占位实现
- // 实际使用时需要根据项目中的对话框实现进行调整
- // 示例:假设有一个PhoneDialog.show方法
- // PhoneDialog.show(context, (phone, code) -> {
- // hwResult.setPhone(phone);
- // // 使用手机号和验证码登录
- // ApiOption option = new ApiOption();
- // option.setUrl("/member/hw/login");
- // java.util.Map<String, String> 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<HWResult> 华为账号信息
- */
- public static CompletableFuture<HWResult> getHuaWeiAccount(Context context) {
- CompletableFuture<HWResult> 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<AuthAccount> 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<AuthAccount> taskSignIn = accountAuthService.signIn();
- taskSignIn.addOnSuccessListener(new OnSuccessListener<AuthAccount>() {
- @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<HWResult> 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));
- }
- }
|