xugenyuan

ref |> 新增一键登录逻辑

Signed-off-by: xugenyuan <xugenyuan@wondertek.com.cn>
export { add } from "./src/main/ets/utils/Calc"
export { SettingPasswordParams } from "./src/main/ets/pages/login/SettingPasswordLayout"
\ No newline at end of file
export { SettingPasswordParams } from "./src/main/ets/pages/login/SettingPasswordLayout"
export { LoginModule } from './src/main/ets/LoginModule'
\ No newline at end of file
... ...
import HuaweiAuth from './utils/HuaweiAuth'
import { JumpInterceptorAction, RouterJumpInterceptor, WDRouterPage } from 'wdRouter'
import { BusinessError } from '@kit.BasicServicesKit'
import { router } from '@kit.ArkUI'
class LoginJumpHandler implements JumpInterceptorAction {
/// 说明是调用了跳转 WDRouterPage.loginPage 页面的行为
on(params?: object | undefined, singleMode?: boolean | undefined): boolean {
HuaweiAuth.sharedInstance().fetchAnonymousPhone().then((anonymousPhone) => {
router.pushUrl({url: WDRouterPage.oneKeyLoginPage.url()})
}).catch((error: string) => {
router.pushUrl({url: WDRouterPage.loginPage.url()})
})
return true
}
}
export class LoginModule {
static startup() {
/// 初始化华为一键登录相关
if (HuaweiAuth.enable) {
HuaweiAuth.sharedInstance().rePrefetchAnonymousPhone()
RouterJumpInterceptor.register(WDRouterPage.loginPage, new LoginJumpHandler())
}
}
}
\ No newline at end of file
... ...
... ... @@ -9,6 +9,10 @@ import { WDRouterPage } from 'wdRouter/src/main/ets/router/WDRouterPage';
import { WDRouterRule } from 'wdRouter/src/main/ets/router/WDRouterRule';
import { Params } from '../../../../../../../commons/wdRouter/oh_modules/wdBean/src/main/ets/bean/content/Params'
import {InterestsHobbiesModel} from '../../../../../../../products/phone/src/main/ets/pages/viewModel/InterestsHobbiesModel'
import HuaweiAuth from '../../utils/HuaweiAuth'
import { loginComponentManager, LoginWithHuaweiIDButton } from '@hms.core.account.LoginComponent'
import { BusinessError } from '@ohos.base'
@Extend(Row)
function otherStyle() {
.backgroundImageSize(ImageSize.Cover)
... ... @@ -56,7 +60,6 @@ struct LoginPage {
})
loginViewModel = new LoginViewModel()
@State isProtocol:boolean=false
onCodeSend() {
Logger.debug(TAG, "isCodeSend:" + this.isCodeSend + "")
if (this.isCodeSend) {
... ...
... ... @@ -15,6 +15,7 @@ struct LoginProtocolWebview {
userProtocol = "https://cdnpeoplefrontuat.aikan.pdnews.cn/rmrb/rmrb-protocol-zh-web/0.0.1/app/protocol-1005.html"
privateProtocol = 'https://cdnpeoplefrontuat.aikan.pdnews.cn/rmrb/rmrb-protocol-zh-web/0.0.1/app/protocol-1001.html'
logoutProtocol = 'https://cdnpeoplefrontuat.aikan.pdnews.cn/rmrb/rmrb-protocol-zh-web/0.0.1/app/protocol-1003.html'
huaweiAuthProtocol = 'https://privacy.consumer.huawei.com/legal/id/authentication-terms.htm?code=CN&language=zh-CN'
async aboutToAppear() {
if (router.getParams()) {
... ... @@ -30,6 +31,9 @@ struct LoginProtocolWebview {
}else if(params.contentID == "3"){ //注销协议
this.webUrl = await SPHelper.default.get(SpConstants.LOGOUT_PROTOCOL, this.logoutProtocol) as string
this.webviewController.loadUrl(this.webUrl)
} else if(params.contentID == "4"){ //华为用户认证协议
this.webUrl = this.huaweiAuthProtocol
this.webviewController.loadUrl(this.webUrl)
}
}
... ...
import { router } from '@kit.ArkUI'
import { Params } from 'wdBean/Index'
import { WDRouterPage, WDRouterRule } from 'wdRouter/Index'
import HuaweiAuth from '../../utils/HuaweiAuth'
import { BusinessError } from '@kit.BasicServicesKit'
@Entry
@Component
struct OneKeyLoginPage {
anonymousPhone: string = ''
@State agreeProtocol: boolean = false
aboutToAppear(): void {
this.anonymousPhone = HuaweiAuth.sharedInstance().anonymousPhone||""
}
build() {
Column() {
this.CloseRow()
Image($r("app.media.login_logo"))
.width(120)
.height(66)
.margin({ top: 78, bottom: 74})
.align(Alignment.Center)
Text(this.anonymousPhone)
.fontSize(30)
.fontWeight(600)
.fontColor("#222222")
.margin({bottom: 10})
.align(Alignment.Center)
this.ProtocolRow()
Row() {
Button("华为账号一键登录")
.type(ButtonType.Normal)
.height(48)
.backgroundColor(!this.agreeProtocol ? Color.Grey : Color.Red)
.width("100%")
.onClick((event) => {
if (!this.agreeProtocol) {
return
}
HuaweiAuth.sharedInstance().oneKeyLogin().then((authorizeCode) => {
//TODO: 调用服务端接口登录
}).catch((error: BusinessError) => {
})
})
}
.padding({ left: 25, right: 25 })
.margin({top: 15})
Button("其他手机号登录")
.type(ButtonType.Normal)
.align(Alignment.Center)
.foregroundColor("#666666")
.backgroundColor(Color.White)
.onClick((event) => {
router.replaceUrl({url: WDRouterPage.loginPage.url()})
})
}
}
@Builder ProtocolRow() {
Row({space: 4}) {
Image(this.agreeProtocol ? $r('app.media.login_checkbox_select') : $r('app.media.login_checkbox_unselected'))
.width(15)
.height(15)
.onClick(() => {
this.agreeProtocol = !this.agreeProtocol
})
Text() {
Span("我已阅读并同意").fontColor("#999999").fontSize(12)
Span("《用户协议》").fontColor("#ED2800").fontSize(12).onClick(() => {
let bean = { contentID: "1", pageID: "" } as Params
WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage, bean)
})
Span("、").fontColor("#999999").fontSize(12)
Span("《隐私政策》").fontColor("#ED2800").fontSize(12).onClick(() => {
let bean = { contentID: "2", pageID: "" } as Params
WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage, bean)
})
Span("和").fontColor("#999999").fontSize(12)
Span("《华为账号用户认证协议》").fontColor("#ED2800").fontSize(12).onClick(() => {
let bean = { contentID: "4", pageID: "" } as Params
WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage, bean)
})
}
.layoutWeight(1)
}
.margin({top: 15})
.padding({ left: 25, right: 25 })
.width('100%')
}
@Builder CloseRow() {
Row() {
Blank()
Image($r('app.media.login_closed'))
.width(24)
.height(24)
.onClick(() => router.back())
}.margin({ top: 15, right: 15 })
.width("100%")
}
}
\ No newline at end of file
... ...
import { authentication, extendService } from '@kit.AccountKit';
import { Logger } from 'wdKit/Index';
import { util } from '@kit.ArkTS';
import { DEFAULT } from '@ohos/hypium';
import { BusinessError } from '@kit.BasicServicesKit';
const TAG = "HuaweiOneKeyAuth"
export default class HuaweiAuth {
// 是否开启
static enable = false
// 匿名手机号
private _anonymousPhone?: string
get anonymousPhone() {
return this._anonymousPhone
}
private static instance: HuaweiAuth
static sharedInstance(): HuaweiAuth {
if (!HuaweiAuth.instance) {
HuaweiAuth.instance = new HuaweiAuth()
}
return HuaweiAuth.instance
}
// 重新预取手机号(App启动未登录、回前台未登录、和退出登录 时调用提前取号)
rePrefetchAnonymousPhone() {
this._anonymousPhone = undefined
this.fetchAnonymousPhone()
}
// 要登录时,先调用。如果获取到手机号了 则弹起一键登录页面
fetchAnonymousPhone() : Promise<string> {
return new Promise((resolve, fail) => {
if (this.anonymousPhone) {
resolve(this.anonymousPhone)
return
}
let authRequest = new authentication.HuaweiIDProvider().createAuthorizationWithHuaweiIDRequest();
// 权限有 phone 、email、realTimePhone、quickLoginMobilePhone,这里用获取匿名手机号
authRequest.scopes = ['quickLoginAnonymousPhone'];
authRequest.state = util.generateRandomUUID();
authRequest.forceAuthorization = false;
let controller = new authentication.AuthenticationController(getContext(this));
try {
controller.executeRequest(authRequest).then((response: authentication.AuthorizationWithHuaweiIDResponse) => {
let anonymousPhone = response.data?.extraInfo?.quickLoginAnonymousPhone;
if (anonymousPhone) {
Logger.info(TAG, 'get anonymousPhone, ' + JSON.stringify(response));
this._anonymousPhone = anonymousPhone as string
resolve(this._anonymousPhone)
return;
}
Logger.info(TAG, 'get anonymousPhone is empty. ' + JSON.stringify(response));
fail("获取匿名手机号为空")
}).catch((err: BusinessError) => {
Logger.error(TAG, 'get anonymousPhone failed. ' + JSON.stringify(err));
fail("获取匿名手机号失败")
})
} catch (err) {
Logger.error(TAG, 'get anonymousPhone fail. ' + JSON.stringify(err));
fail("获取匿名手机号失败")
}
})
}
// 华为账号一键登录授权
// 返回结果为 Authorization Code
oneKeyLogin() : Promise<string> {
let loginRequest = new authentication.HuaweiIDProvider().createLoginWithHuaweiIDRequest();
// 当用户未登录华为帐号时,是否强制拉起华为帐号登录界面
loginRequest.forceLogin = true;
loginRequest.state = util.generateRandomUUID();
return new Promise((resolve, fail) => {
try {
let controller = new authentication.AuthenticationController(getContext(this));
controller.executeRequest(loginRequest, (err, data) => {
if (err) {
Logger.error(TAG, 'login fail, ' + JSON.stringify(err))
fail(err)
return;
}
let loginWithHuaweiIDResponse = data as authentication.LoginWithHuaweiIDResponse;
let state = loginWithHuaweiIDResponse.state;
if (state != undefined && loginRequest.state != state) {
Logger.error(TAG, 'login fail, The state is different' + JSON.stringify(loginWithHuaweiIDResponse))
fail({
code: 99999,
name: "一键登录",
message:"状态错误:" + `请求状态 ${loginRequest.state}, 结果状态 ${state}`
} as BusinessError)
return;
}
Logger.info(TAG, 'login success, ' + JSON.stringify(loginWithHuaweiIDResponse));
let loginWithHuaweiIDCredential = loginWithHuaweiIDResponse.data!;
let authorizationCode = loginWithHuaweiIDCredential.authorizationCode;
resolve(authorizationCode!)
});
} catch (error) {
Logger.error(TAG, 'login fail, ' + JSON.stringify(error))
fail(error)
}
});
}
// 打开账户中心
openAccountCenter() {
try {
extendService.startAccountCenter(getContext(this), (err, data) => {
if (err) {
Logger.info(TAG, 'startAccountCenterWithCallback fail,error: ' + JSON.stringify(err));
return;
}
Logger.info(TAG, 'startAccountCenterWithCallback success');
});
} catch (error) {
Logger.error(TAG, 'startAccountCenterWithCallback fail,error: ' + JSON.stringify(error));
}
}
}
... ...
... ... @@ -6,6 +6,7 @@
"pages/login/LoginProtocolWebview",
"pages/login/SettingPasswordPage",
"pages/login/SettingPasswordLayout",
"pages/guide/GuidePages"
"pages/guide/GuidePages",
"pages/login/OneKeyLoginPage"
]
}
... ...