import { TitleBar } from '../../view/TitleBar'; import systemDateTime from '@ohos.systemDateTime'; import { ToastUtils } from '../../utils/ToastUtils'; import { common } from '@kit.AbilityKit'; import { RouterUrls } from '../../common/RouterUrls'; import { Constants } from '../../common/Constants'; import LoginViewModel from '../../viewModel/LoginViewModel'; import { AppUtil, RandomUtil, StrUtil } from '@pura/harmony-utils'; import { SendCodeEntity } from '../../entity/SendCodeEntity'; import { LoginEntity } from '../../entity/LoginEntity'; import { ConfigManager } from '../../manager/UserConfigManager'; import { LoginTipDialog } from '../../dialog/LoginTipDialog'; import { LevelMode, router } from '@kit.ArkUI'; import { LoginManager } from '../../manager/LoginGlobalManager'; import { OnWXResp, WXApi, WXEventHandler } from '../../utils/wechat/WXApiEventHandlerImpl'; import * as WxOpenSdk from '@tencent/wechat_open_sdk'; import { ErrCode, SendAuthResp } from '@tencent/wechat_open_sdk'; import BuildProfile from 'BuildProfile'; import { LoadingDialog } from '../../dialog/LoadingDialog'; import { EventConstants } from '../../common/EventConstants'; import { EventReportManager } from '../../manager/EventReportManager'; @Entry @ComponentV2 struct LoginPage { @Local from: number = 0; @Local isAgree: boolean = false; @Local countDownTime: number = 0; loginTipDialogController?: CustomDialogController | null; viewModel: LoginViewModel = new LoginViewModel(this.getUIContext()); clickTime: number = 0; phone: string = ''; code: string = ''; timestamp: string = ''; intervalId: number = -1; //从微信返回的回调 onWXResp: OnWXResp = (resp) => { //微信返回的数据 if (resp instanceof SendAuthResp && resp.state?.endsWith('phone')) { const authResult = JSON.stringify(resp ?? {}, null , 2); const errCode = JSON.parse(authResult).errCode as number; if (errCode === ErrCode.ERR_OK) { const authCode = JSON.parse(authResult).code as string; this.viewModel.wxLogin(authCode); } else { ToastUtils.show(JSON.parse(authResult).errStr); } } } @Monitor('viewModel.codeEntity') onCodeChange(monitor: IMonitor) { const code = monitor.value()?.now as SendCodeEntity; ToastUtils.show('验证码已发送'); this.timestamp = code.timestamp; this.countDownTime = 60; this.intervalId = setInterval(() => { if (this.countDownTime > 0) { this.countDownTime-- } else { if (this.intervalId !== 0) { clearInterval(this.intervalId); } } }, 1000) } @Monitor('viewModel.phoneLoginEntity') onPhoneLogin(monitor: IMonitor) { const loginEntity = monitor.value()?.now as LoginEntity; EventReportManager.eventReport(EventConstants.LOGIN, 'phone', this.phone) LoginManager.saveToken(loginEntity.token); LoginManager.saveLastLoginType('phone') ConfigManager.userConfig() .then(() => { if (this.from === 0) { this.toMainPage(); } else { this.getUIContext().getRouter().back() } }) } @Monitor('viewModel.wxLoginEntity') onWxLogin(monitor: IMonitor) { const loginEntity = monitor.value()?.now as LoginEntity; EventReportManager.eventReport(EventConstants.LOGIN, 'weixin') LoginManager.saveToken(loginEntity.token); LoginManager.saveLastLoginType('weixin') ConfigManager.userConfig() .then(() => { if (this.from === 0) { this.toMainPage(); } else { this.getUIContext().getRouter().back() } }) } aboutToAppear() { WXEventHandler.registerOnWXRespCallback(this.onWXResp) this.initParams(); } aboutToDisappear() { WXEventHandler.unregisterOnWXRespCallback(this.onWXResp) this.loginTipDialogController = null } initParams() { const params = this.getUIContext().getRouter().getParams() as Record; if (params) { this.from = params.from as number; } } sendCode() { if (StrUtil.isEmpty(this.phone)) { ToastUtils.show('请输入手机号'); return; } if (this.phone.length != 11) { ToastUtils.show('请输入正确的手机号'); return; } this.viewModel.sendCode(this.phone); EventReportManager.eventReport(EventConstants.GET_CODE, "code_login", this.phone) } toMainPage() { this.getUIContext().getRouter().replaceUrl({ url: RouterUrls.MAIN_PAGE }, router.RouterMode.Single); AppUtil.getContext().eventHub.emit(EventConstants.LoginSuccessEvent); } async wxAuth() { if (!WXApi.isWXAppInstalled()) { ToastUtils.show('未安装微信客户端,请先下载安装微信客户端'); return; } LoadingDialog.show(this.getUIContext()); let req = new WxOpenSdk.SendAuthReq; req.isOption1 = false; req.nonAutomatic = true; req.scope = 'snsapi_userinfo'; req.state = BuildProfile.BUNDLE_NAME + RandomUtil.getRandomInt(0, 1000) + '_phone'; req.transaction =''; await WXApi.sendReq(AppUtil.getContext(), req) LoadingDialog.dismiss(); } showLoginTipDialog(type: number) { this.loginTipDialogController = new CustomDialogController({ builder: LoginTipDialog({ confirm: () => { this.isAgree = true; if (type === 0) { this.viewModel.phoneLogin(this.phone, this.code, this.timestamp); } else if (type === 1) { this.wxAuth(); } } }), cornerRadius: 20, maskColor: '#CC000000', levelMode: LevelMode.EMBEDDED, backgroundBlurStyle: BlurStyle.NONE }) this.loginTipDialogController.open(); } onBackPress(): boolean | void { if (this.from === 0) { if (systemDateTime.getTime() - this.clickTime < 1500) { (this.getUIContext().getHostContext() as common.UIAbilityContext).terminateSelf(); } else { EventReportManager.eventReport(EventConstants.EXIT_APP, 'login') this.clickTime = systemDateTime.getTime(); ToastUtils.show('双击退出应用'); } return true; } } build() { Stack({alignContent: Alignment.TopStart}) { Image($r('app.media.ic_login_top_bg')).width('100%') Column() { TitleBar({ showBack: this.from !== 0 }).width('100%') Image($r('app.media.ic_login_logo')) .margin({ top: 10 }) .width(80) .height(80) Text($r('app.string.app_name')) .fontColor($r('app.color.color_212226')) .fontSize(18) .fontFamily('almmsht') .margin({ top: 12 }) .width('auto') Row(){ Image($r('app.media.ic_login_phone')).width(22).height(22) TextInput({ placeholder: '请输入您的手机号' }) .type(InputType.PhoneNumber) .fontColor($r('app.color.color_1a1a1a')) .fontSize(16) .placeholderColor($r('app.color.color_bcbcbc')) .placeholderFont({ size: 16 }) .maxLength(11) .backgroundColor(Color.Transparent) .onChange((value: string) => { this.phone = value; }) } .height(50) .margin({ top: 50, left: 38, right: 38 }) Divider().strokeWidth(1).color($r('app.color.color_dfdfdf')).margin({ left: 38, right: 38 }) RelativeContainer() { Row() { Image($r('app.media.ic_login_code')).width(22).height(22) TextInput({ placeholder: '请输入验证码' }) .type(InputType.Number) .fontColor($r('app.color.color_1a1a1a')) .fontSize(16) .placeholderColor($r('app.color.color_bcbcbc')) .placeholderFont({ size: 16 }) .maxLength(6) .backgroundColor(Color.Transparent) .onChange((value: string) => { this.code = value; }) } .id('row_code') Text(this.countDownTime === 0 && StrUtil.isEmpty(this.timestamp) ? '获取验证码' : this.countDownTime > 0 ? `${this.countDownTime}s` : '重新发送') .fontColor(this.countDownTime === 0 ? $r("app.color.color_466afd") : $r('app.color.color_999999')) .fontSize(14) .alignRules({ top: { anchor: 'row_code', align: VerticalAlign.Top }, right: { anchor: 'row_code', align: HorizontalAlign.End }, bottom: { anchor: 'row_code', align: VerticalAlign.Bottom }, }) .margin({ right: 16 }) .width('auto') .onClick(() => { if (this.countDownTime === 0) { this.sendCode(); } }) }.margin({ top: 26, left: 38, right: 38 }).height(50) Divider().strokeWidth(1).color($r('app.color.color_dfdfdf')).margin({ left: 38, right: 38 }) Stack() { Button('登录', { type: ButtonType.Capsule, stateEffect: true }) .width('100%') .height(50) .fontColor(Color.White) .fontSize(16) .fontWeight(FontWeight.Medium) .backgroundColor($r("app.color.color_466afd")) }.margin({ top: 40 }).padding({ left: 38, right: 38 }) .onClick(() => { if (StrUtil.isEmpty(this.phone)) { ToastUtils.show('请输入手机号'); return; } if (this.phone.length != 11) { ToastUtils.show('请输入正确的手机号'); return; } if (StrUtil.isEmpty(this.code)) { ToastUtils.show('请输入验证码'); return; } if (this.isAgree) { this.viewModel.phoneLogin(this.phone, this.code, this.timestamp); } else { this.showLoginTipDialog(0); } }) Row() { Image(this.isAgree ? $r('app.media.ic_check_true') : $r('app.media.ic_check_false')).width(16).height(16) Text() { Span('我已阅读并同意') Span('《用户协议》').fontColor($r("app.color.color_466afd")) .onClick(() => { this.getUIContext() .getRouter() .pushUrl({ url: RouterUrls.WEB_PAGE, params: { title: '用户协议', url: Constants.USER_AGREEMENT } }) }) Span('和') Span('《隐私政策》').fontColor($r("app.color.color_466afd")) .onClick(() => { this.getUIContext() .getRouter() .pushUrl({ url: RouterUrls.WEB_PAGE, params: { title: '隐私政策', url: Constants.PRIVACY_POLICY } }) }) } .fontColor($r('app.color.color_999999')) .fontSize(12) .margin({ left: 4, top: 2 }) } .alignItems(VerticalAlign.Top) .margin({ left: 38, top: 16, right: 38 }) .onClick(() => { this.isAgree = !this.isAgree; }) Blank().layoutWeight(1) Text('其他登录方式') .fontColor('#AAAAAA') .fontSize(10) .width('auto') .visibility(ConfigManager.getLoginType().length > 1 ? Visibility.Visible : Visibility.None) Row() { Image($r('app.media.ic_wx_login')) .margin({ left: 25, right: 25 }) .width(38) .height(38) .id('iv_wx_login') .onClick(() => { if (this.isAgree) { this.wxAuth() } else { this.showLoginTipDialog(1); } }) .visibility(ConfigManager.getLoginType().includes('weixin') ? Visibility.Visible : Visibility.None) Image($r('app.media.ic_onekey_login')) .margin({ left: 25, right: 25 }) .width(38) .height(38) .id('iv_onekey_login') .visibility(Visibility.None) } .margin({ top: 20, bottom: 50 }) } .width('100%') .height('100%') } .backgroundColor(Color.White) } }