355 lines
12 KiB
Plaintext
355 lines
12 KiB
Plaintext
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<string, Object>;
|
|
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)
|
|
}
|
|
} |