1029 lines
29 KiB
Vue
1029 lines
29 KiB
Vue
<template>
|
||
<!-- 底部弹窗蒙层 -->
|
||
<view class="login-mask" :style="{background:maskShow?`rgba(0, 0, 0, 0.5)`:`transparent`}" @tap="closeWindow">
|
||
<!-- 底部弹窗内容 -->
|
||
<view class="login-popup" @tap.stop.prevent v-show="maskShow">
|
||
<!-- 弹窗头部:标题+关闭按钮 -->
|
||
<view class="popup-header">
|
||
<text class="popup-title">登录享更多服务</text>
|
||
</view>
|
||
<image class="popup-close" src="/static/images/icons/close.png" @click="closeWindow" />
|
||
|
||
<!-- 登录选项卡 -->
|
||
<view class="login-tabs">
|
||
<view class="tab-item" :class="{active: loginType === 'code'}" @click="loginType = 'code'">验证码</view>
|
||
<view class="tab-line"></view>
|
||
<view class="tab-item" :class="{active: loginType === 'account'}" @click="loginType = 'account'">账号密码
|
||
</view>
|
||
<view class="tab-line"></view>
|
||
<view class="tab-item" :class="{active: loginType === 'onekey'}" @click="handleOnekeyTab">一键登录</view>
|
||
</view>
|
||
|
||
<!-- 输入区域(根据选项卡切换) -->
|
||
<view class="input-area">
|
||
<!-- 验证码登录 -->
|
||
<template v-if="loginType === 'code'">
|
||
<view class="input-item">
|
||
<uv-album></uv-album>
|
||
<image class="input-icon-phone" mode="widthFix" src="/static/images/icons/log_phone.png" />
|
||
<input type="number" v-model="phone" placeholder="请输入手机号码" :adjust-position="false"
|
||
class="input-text" @input="handlePhoneInput" />
|
||
</view>
|
||
<!-- 手机号错误提示 -->
|
||
<text class="input-error" v-if="phoneError">{{phoneError}}</text>
|
||
|
||
<view class="input-item">
|
||
<image class="input-icon-password" mode="widthFix"
|
||
src="/static/images/icons/log_password.png" />
|
||
<input type="number" v-model="code" placeholder="请输入验证码" :adjust-position="false"
|
||
class="input-text" maxlength="6" />
|
||
<uv-code keepRunning :seconds="seconds" @end="end" @start="start" ref="code"
|
||
@change="codeChange"></uv-code>
|
||
<text class="get-code-btn" :class="{running:runningCode,noPhone:!phone}"
|
||
@tap="getCode">{{tips}}</text>
|
||
</view>
|
||
</template>
|
||
|
||
<!-- 账号密码登录 -->
|
||
<template v-else-if="loginType === 'account'">
|
||
<view class="input-item">
|
||
<image class="input-icon-phone" mode="widthFix" src="/static/images/icons/log_phone.png" />
|
||
<input v-model="phone" placeholder="请输入账号" class="input-text" :adjust-position="false"
|
||
@input="handlePhoneInput" />
|
||
</view>
|
||
<!-- 手机号错误提示 -->
|
||
<text class="input-error" v-if="phoneError">请输入正确的账号</text>
|
||
|
||
<view class="input-item">
|
||
<image class="input-icon-password" mode="widthFix"
|
||
src="/static/images/icons/log_password.png" />
|
||
<input type="text" v-model="password" placeholder="请输入密码" :adjust-position="false"
|
||
:password="!showPassword" class="input-text" />
|
||
<image src="/static/images/icons/noLook.png" mode="widthFix" class="look-icon"
|
||
v-if="!showPassword" @click.stop="showPassword = true"></image>
|
||
<image src="/static/images//icons/look.png" mode="widthFix" class="look-icon"
|
||
@click.stop="showPassword = false" v-else></image>
|
||
</view>
|
||
</template>
|
||
</view>
|
||
|
||
<!-- 登录按钮(根据选项卡/输入状态切换样式) -->
|
||
<view class="login-btn" :class="{active: canLogin}" @click="handleLogin">
|
||
立即登录
|
||
</view>
|
||
|
||
<!-- 协议勾选 -->
|
||
<view class="agree">
|
||
<agree-radio :isAgree="isAgree" @change-agree="changeAgree" class="agree-btn"></agree-radio>
|
||
<view class="agree-card">
|
||
<text class="agree-text">未注册手机号登录后将自动生成账号,且代表您已阅读并同意,</text>
|
||
<text class="agreement" @click="goAgreement(28)">《用户注册协议》</text>
|
||
<text class="agreement" @click="goAgreement(26)">《隐私政策》</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
isNotificationsEnabled,
|
||
permissions,
|
||
registPush
|
||
} from '@/utils/AS-NotifyTheAuthority.js'
|
||
import AgreeRadio from '@/components/agree-radio/agree-radio.vue'
|
||
import request from '@/utils/request';
|
||
import uiConfig from "@/utils/ui-config.js"
|
||
const aLiSDKModule = uni.requireNativePlugin('AliCloud-NirvanaPns');
|
||
|
||
export default {
|
||
components: {
|
||
AgreeRadio
|
||
},
|
||
data() {
|
||
return {
|
||
isFirst:false,//是否第一次打开
|
||
showPassword: false, // 是否展示密码
|
||
maskShow: true,
|
||
loginType: 'code', // 当前选项卡:code/account/onekey
|
||
phone: '', // 验证码-手机号
|
||
code: '', // 验证码-验证码
|
||
password: '', // 账号密码-密码
|
||
account: '', // 账号密码-账号
|
||
isAgree: false, // 协议勾选状态
|
||
tips: '',
|
||
seconds: 60,
|
||
phoneError: '', // 手机号错误提示
|
||
runningCode: false, //是否在倒计时
|
||
}
|
||
},
|
||
onLoad() {
|
||
// this.checkAndroidPermission()
|
||
this.isFirst = true
|
||
this.handleOnekeyTab()
|
||
},
|
||
computed: {
|
||
// 判断是否可登录(匹配示例按钮状态)
|
||
canLogin() {
|
||
if (this.loginType === 'code') {
|
||
return this.isAgree && this.phone && this.code && this.code.length >= 4 && !this.phoneError;
|
||
} else if (this.loginType === 'account') {
|
||
return this.isAgree && this.phone && this.password && !this.phoneError;
|
||
} else if (this.loginType === 'onekey') {
|
||
return this.isAgree;
|
||
}
|
||
return false;
|
||
}
|
||
},
|
||
methods: {
|
||
/**
|
||
* 检查安卓系统权限(设备信息/短信)
|
||
*/
|
||
checkAndroidPermission() {
|
||
// #ifdef APP-PLUS
|
||
const permissions = [
|
||
'android.permission.READ_PHONE_STATE'
|
||
];
|
||
|
||
plus.android.requestPermissions(permissions, (result) => {
|
||
const { granted, neverDenied } = result;
|
||
console.log(11111111,result)
|
||
if (neverDenied.length > 0) {
|
||
// 永久拒绝:引导用户去系统设置页开启
|
||
uni.showModal({
|
||
title: '权限提示',
|
||
content: '需要您开启设备信息和短信权限才能使用一键登录',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
plus.android.openSettings(); // 打开安卓设置页
|
||
}
|
||
}
|
||
});
|
||
} else if (granted.length === permissions.length) {
|
||
// 已授权:继续运营商一键登录
|
||
this.checkOperatorAuth();
|
||
}
|
||
}, (err) => {
|
||
console.error('申请权限失败:', err);
|
||
});
|
||
// #endif
|
||
},
|
||
// 是否同意修改
|
||
changeAgree(value) {
|
||
this.isAgree = value;
|
||
},
|
||
goAgreement(type) {
|
||
uni.navigateTo({
|
||
url: "/pages/agreement/agreement?type=" + type
|
||
})
|
||
},
|
||
codeChange(text) {
|
||
this.tips = text;
|
||
},
|
||
|
||
/**
|
||
* 获取手机号今日获取验证码的次数
|
||
* @param {String} phone - 手机号
|
||
* @returns {Number} 今日获取次数
|
||
*/
|
||
getPhoneCodeCount(phone) {
|
||
// 生成今日日期(YYYY-MM-DD),作为本地存储key的一部分,确保按自然日统计
|
||
const today = new Date().toISOString().split('T')[0];
|
||
// 定义本地存储的key:code_count_手机号_日期
|
||
const storageKey = `code_count_${phone}_${today}`;
|
||
// 从本地存储获取次数,默认0
|
||
const count = uni.getStorageSync(storageKey) || 0;
|
||
return Number(count);
|
||
},
|
||
|
||
/**
|
||
* 更新手机号今日获取验证码的次数(+1)
|
||
* @param {String} phone - 手机号
|
||
*/
|
||
updatePhoneCodeCount(phone) {
|
||
const today = new Date().toISOString().split('T')[0];
|
||
const storageKey = `code_count_${phone}_${today}`;
|
||
const count = this.getPhoneCodeCount(phone);
|
||
// 存储新的次数(+1)
|
||
uni.setStorageSync(storageKey, count + 1);
|
||
},
|
||
getCode() {
|
||
let that = this
|
||
// 验证手机号(双重校验,确保接口请求时手机号合法)
|
||
if (this.phoneError) {
|
||
uni.showToast({
|
||
title: this.phoneError,
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
if (!this.phone) {
|
||
uni.showToast({
|
||
title: "请输入手机号",
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
|
||
// ------ 单日单手机号最多获取10次:开始 ------
|
||
const codeCount = this.getPhoneCodeCount(this.phone);
|
||
if (codeCount >= 10) {
|
||
uni.showToast({
|
||
title: '今日获取验证码次数已达上限,请明日再试',
|
||
icon: 'none',
|
||
duration: 2000
|
||
});
|
||
return;
|
||
}
|
||
// ------ 单日单手机号最多获取10次:结束 ------
|
||
|
||
if (this.$refs.code.canGetCode) {
|
||
uni.showLoading({
|
||
title: '正在获取验证码'
|
||
})
|
||
// 请求获取验证码接口
|
||
request.post('/user/sendcode', {
|
||
account: that.phone,
|
||
type: 2
|
||
}).then(result => {
|
||
uni.hideLoading();
|
||
if (result.state == 1) {
|
||
uni.showToast({
|
||
title: result.msg,
|
||
icon: 'none'
|
||
})
|
||
this.$refs.code.start();
|
||
// 更新手机号今日获取次数(仅当接口请求成功时计数)
|
||
this.updatePhoneCodeCount(this.phone);
|
||
} else {
|
||
uni.showToast({
|
||
title: result.msg,
|
||
icon: 'none'
|
||
})
|
||
}
|
||
}).catch(err => {
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: err.msg,
|
||
icon: 'none'
|
||
})
|
||
})
|
||
} else {
|
||
uni.$uv.toast('倒计时结束后再发送');
|
||
}
|
||
},
|
||
end() {
|
||
this.runningCode = false
|
||
},
|
||
start() {
|
||
this.runningCode = true
|
||
},
|
||
// 关闭弹窗
|
||
closeWindow() {
|
||
uni.navigateBack({
|
||
delta: 1
|
||
});
|
||
},
|
||
|
||
// 点击“一键登录”选项卡:直接唤起原生弹窗(不处理类型切换)
|
||
handleOnekeyTab() {
|
||
// this.loginType = 'onekey';
|
||
// 延迟100ms确保选项卡切换完成后调用
|
||
try {
|
||
// 加速登录页加载
|
||
aLiSDKModule.accelerateLoginPage(5000, (result) => {
|
||
console.log('加速授权页结果:', JSON.stringify(result));
|
||
|
||
if (result.resultCode === '600000') {
|
||
console.log("加速授权页拉起成功");
|
||
// 延迟执行,确保配置构建完成
|
||
setTimeout(() => {
|
||
try {
|
||
// 额外的try/catch,防止配置构建或登录控制器调用出错
|
||
const config = uiConfig.buildSheet();
|
||
this._presentLoginController(config);
|
||
} catch (innerError) {
|
||
this.maskShow = true
|
||
console.error("构建登录配置或调用登录控制器失败:", innerError);
|
||
// 这里可以添加配置构建失败后的备用操作
|
||
}
|
||
}, 100);
|
||
} else {
|
||
if(!this.isFirst){
|
||
if(result.resultCode == 600004 || result.resultCode ==600008){
|
||
uni.showToast({
|
||
title: "蜂窝网络未开启",
|
||
icon: 'none'
|
||
});
|
||
}else if(result.resultCode == 600007 || result.resultCode ==600009){
|
||
uni.showToast({
|
||
title: "未检测到sim卡",
|
||
icon: 'none'
|
||
});
|
||
}else{
|
||
uni.showToast({
|
||
title: "唤起授权页失败",
|
||
icon: 'none'
|
||
});
|
||
}
|
||
}
|
||
|
||
this.maskShow = true
|
||
this.isFirst = false
|
||
console.error("授权页加速拉起失败:", result);
|
||
}
|
||
});
|
||
} catch (error) {
|
||
// 捕获aLiSDKModule未定义或其他执行错误
|
||
this.maskShow = true
|
||
console.error("跳转到登录页时发生错误:", error);
|
||
|
||
}
|
||
// aLiSDKModule.accelerateLoginPage(5000, result => {
|
||
// console.log(JSON.stringify(result));
|
||
// if ('600000' == result.resultCode) {
|
||
// console.log("加速授权页拉起成功");
|
||
// setTimeout(() => {
|
||
// const config = uiConfig.buildSheet();
|
||
// this._presentLoginController(config);
|
||
// }, 200);
|
||
// } else {
|
||
// console.log("授权页加速拉起失败," + result.msg);
|
||
// }
|
||
// });
|
||
},
|
||
|
||
/**
|
||
* 密码登录辅助方法:获取账号密码错误次数
|
||
* @param {String} account - 登录账号(手机号)
|
||
* @returns {Number} 错误次数(默认0)
|
||
*/
|
||
getPwdErrorCount(account) {
|
||
const storageKey = `pwd_error_count_${account}`;
|
||
return Number(uni.getStorageSync(storageKey)) || 0;
|
||
},
|
||
|
||
/**
|
||
* 密码登录辅助方法:更新账号密码错误次数
|
||
* @param {String} account - 登录账号(手机号)
|
||
* @param {Number} count - 最新错误次数
|
||
*/
|
||
updatePwdErrorCount(account, count) {
|
||
const storageKey = `pwd_error_count_${account}`;
|
||
uni.setStorageSync(storageKey, count);
|
||
},
|
||
|
||
/**
|
||
* 密码登录辅助方法:获取账号锁定时间戳
|
||
* @param {String} account - 登录账号(手机号)
|
||
* @returns {Number} 锁定时间戳(毫秒,默认0)
|
||
*/
|
||
getPwdLockTime(account) {
|
||
const storageKey = `pwd_lock_time_${account}`;
|
||
return Number(uni.getStorageSync(storageKey)) || 0;
|
||
},
|
||
|
||
/**
|
||
* 密码登录辅助方法:设置账号锁定(记录锁定时间戳)
|
||
* @param {String} account - 登录账号(手机号)
|
||
*/
|
||
setPwdLock(account) {
|
||
const storageKey = `pwd_lock_time_${account}`;
|
||
uni.setStorageSync(storageKey, Date.now()); // 存储当前时间戳
|
||
},
|
||
|
||
/**
|
||
* 密码登录辅助方法:清除账号锁定缓存(错误次数+锁定时间)
|
||
* @param {String} account - 登录账号(手机号)
|
||
*/
|
||
clearPwdLockCache(account) {
|
||
uni.removeStorageSync(`pwd_error_count_${account}`);
|
||
uni.removeStorageSync(`pwd_lock_time_${account}`);
|
||
},
|
||
|
||
/**
|
||
* 密码登录辅助方法:检查账号是否被锁定
|
||
* @param {String} account - 登录账号(手机号)
|
||
* @returns {Object} { isLocked: Boolean, remainingTime: Number }
|
||
* remainingTime: 剩余锁定时间(秒),0表示未锁定
|
||
*/
|
||
checkAccountLocked(account) {
|
||
const lockTime = this.getPwdLockTime(account);
|
||
if (!lockTime) return {
|
||
isLocked: false,
|
||
remainingTime: 0
|
||
};
|
||
|
||
const now = Date.now();
|
||
const lockDuration = 3600 * 1000; // 1小时(毫秒)
|
||
const remainingTime = Math.ceil((lockTime + lockDuration - now) / 1000); // 剩余锁定时间(秒)
|
||
|
||
if (remainingTime > 0) {
|
||
return {
|
||
isLocked: true,
|
||
remainingTime
|
||
};
|
||
} else {
|
||
// 锁定时间已过,自动清除缓存
|
||
this.clearPwdLockCache(account);
|
||
return {
|
||
isLocked: false,
|
||
remainingTime: 0
|
||
};
|
||
}
|
||
},
|
||
|
||
// 执行登录
|
||
handleLogin() {
|
||
let that = this;
|
||
// 手机号错误时直接返回
|
||
if (this.phoneError) {
|
||
uni.showToast({
|
||
title: this.phoneError,
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
|
||
if (this.loginType === 'code') {
|
||
// 验证码登录:调用后端接口(示例)
|
||
if (!this.phone) {
|
||
uni.showToast({
|
||
title: "请输入手机号",
|
||
icon: 'none'
|
||
})
|
||
return
|
||
} else if (!that.code) {
|
||
uni.showToast({
|
||
title: '请输入验证码',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
} else if (this.code.length < 4) { // 修复逻辑:原代码是>=4时提示错误,改为<4
|
||
uni.showToast({
|
||
title: '请输入正确验证码',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
} else if (!that.isAgree) {
|
||
uni.showToast({
|
||
title: '请先阅读并同意《用户注册协议》与《隐私政策》',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
} else {
|
||
request.post('/sj/codelogin', {
|
||
account: that.phone,
|
||
code: that.code,
|
||
deviceid: getApp().globalData.deviceid
|
||
}).then(result => {
|
||
if (result.code == 200) {
|
||
|
||
uni.setStorageSync('accessToken', result.data.access_token);
|
||
uni.setStorageSync('refreshToken', result.data.refresh_token);
|
||
uni.setStorageSync('refresh_token_expries', result.data.refresh_token_expries);
|
||
uni.setStorageSync('loginAccount', that.phone); // 保存登录的手机号
|
||
registPush();
|
||
this.messageUpudateNum()
|
||
this.closeWindow();
|
||
} else {
|
||
uni.showToast({
|
||
title: result.msg,
|
||
icon: 'none'
|
||
})
|
||
}
|
||
}).catch(err => {
|
||
uni.showToast({
|
||
title: err.msg,
|
||
icon: 'none'
|
||
})
|
||
})
|
||
}
|
||
|
||
} else if (this.loginType === 'account') {
|
||
// 账号密码登录:先检查账号是否锁定
|
||
const {
|
||
isLocked,
|
||
remainingTime
|
||
} = this.checkAccountLocked(this.phone);
|
||
if (isLocked) {
|
||
// 计算小时、分钟、秒,优化提示文案
|
||
const hours = Math.floor(remainingTime / 3600);
|
||
const minutes = Math.floor((remainingTime % 3600) / 60);
|
||
const seconds = remainingTime % 60;
|
||
let lockTip = '';
|
||
if (hours > 0) {
|
||
lockTip = `该账号因多次密码错误已锁定,请${hours}小时${minutes}分钟后重试`;
|
||
} else if (minutes > 0) {
|
||
lockTip = `该账号因多次密码错误已锁定,请${minutes}分钟${seconds}秒后重试`;
|
||
} else {
|
||
lockTip = `该账号因多次密码错误已锁定,请${seconds}秒后重试或找回密码`;
|
||
}
|
||
uni.showToast({
|
||
title: lockTip,
|
||
icon: 'none',
|
||
duration: 3000
|
||
});
|
||
return false;
|
||
}
|
||
|
||
// 密码格式校验
|
||
let reg = that.validatePassword(that.password);
|
||
if (!this.phone) {
|
||
uni.showToast({
|
||
title: "请输入手机号",
|
||
icon: 'none'
|
||
})
|
||
return
|
||
} else if (!that.password) {
|
||
uni.showToast({
|
||
title: '请输入密码',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
} else if (!reg) {
|
||
uni.showToast({
|
||
title: '请输入正确的密码(6-20位字母 + 数字/符号组合)',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
} else if (!that.isAgree) {
|
||
uni.showToast({
|
||
title: '请先阅读并同意《用户注册协议》与《隐私政策》',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
} else {
|
||
request.post('/sj/accountlogin', {
|
||
account: that.phone,
|
||
password: that.password,
|
||
deviceid: getApp().globalData.deviceid
|
||
}).then(result => {
|
||
console.log(result)
|
||
if (result.code == 200) {
|
||
// 登录成功:清除该账号的密码错误次数和锁定缓存
|
||
that.clearPwdLockCache(that.phone);
|
||
uni.setStorageSync('accessToken', result.data.access_token);
|
||
uni.setStorageSync('refreshToken', result.data.refresh_token);
|
||
uni.setStorageSync('refresh_token_expries', result.data.refresh_token_expries);
|
||
uni.setStorageSync('loginAccount', that.phone); // 保存登录的手机号
|
||
registPush();
|
||
that.messageUpudateNum()
|
||
that.closeWindow();
|
||
} else {
|
||
// 登录失败:判断是否为密码错误(假设后端返回msg包含“密码错误”关键词,可根据实际接口调整)
|
||
if (result.code === 502) {
|
||
const currentErrorCount = that.getPwdErrorCount(that.phone);
|
||
const maxErrorCount = 5;
|
||
const remainingCount = maxErrorCount - currentErrorCount - 1;
|
||
|
||
if (remainingCount > 0) {
|
||
// 未达最大错误次数:更新错误次数,提示剩余次数
|
||
that.updatePwdErrorCount(that.phone, currentErrorCount + 1);
|
||
uni.showToast({
|
||
title: `密码错误,还有${remainingCount}次机会`,
|
||
icon: 'none',
|
||
duration: 2000
|
||
});
|
||
} else {
|
||
// 达最大错误次数:锁定账号,提示锁定信息
|
||
that.updatePwdErrorCount(that.phone, maxErrorCount);
|
||
that.setPwdLock(that.phone);
|
||
uni.showToast({
|
||
title: '该账号因多次密码错误已锁定,请1小时后重试或找回密码',
|
||
icon: 'none',
|
||
duration: 3000
|
||
});
|
||
}
|
||
} else {
|
||
// 其他错误(如账号不存在等),直接提示
|
||
uni.showToast({
|
||
title: result.msg,
|
||
icon: 'none'
|
||
});
|
||
}
|
||
}
|
||
}).catch(err => {
|
||
uni.showToast({
|
||
title: err.msg,
|
||
icon: 'none'
|
||
})
|
||
})
|
||
}
|
||
}
|
||
},
|
||
// 密码格式校验
|
||
validatePassword(password) {
|
||
// 正则说明:
|
||
// (?=.*[A-Za-z]):必须包含至少一个字母
|
||
// (?=.*\d):必须包含至少一个数字
|
||
// [\w\W]{6,20}:匹配任意字符(字母、数字、符号、中文等),长度6-20位
|
||
// 若想限制仅允许常见符号(排除中文),可改用:/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d!@#$%^&*()_+\-=\[\]{}|;':",./<>?]{6,20}$/
|
||
const reg = /^(?=.*[A-Za-z])(?=.*\d)[\w\W]{6,20}$/;
|
||
return reg.test(password);
|
||
},
|
||
|
||
quitLoginPage() {
|
||
aLiSDKModule.quitLoginPage();
|
||
this.maskShow = true
|
||
},
|
||
|
||
// 阿里云一键登录原生弹窗逻辑
|
||
_presentLoginController(config) {
|
||
let that = this
|
||
uni.showLoading({
|
||
mask: true,
|
||
});
|
||
// 调用该接口首先会弹起授权页,点击授权页的登录按钮获取Token
|
||
aLiSDKModule.getLoginToken(
|
||
5000,
|
||
config,
|
||
tokenResult => {
|
||
uni.hideLoading();
|
||
console.log("tokenResult:", JSON.stringify(tokenResult));
|
||
|
||
if ("600001" == tokenResult.resultCode) {
|
||
console.log("授权页拉起成功");
|
||
this.maskShow = false
|
||
aLiSDKModule.setCheckboxIsChecked(false);
|
||
} else if ("600000" == tokenResult.resultCode) {
|
||
console.log("获取Token成功,接下来拿着结果里面的Token去服务端换取手机号码,SDK服务到此结束");
|
||
request.post('/sj/phoneLogin', {
|
||
token: tokenResult.token,
|
||
}).then(result => {
|
||
if (result.code == 200) {
|
||
// 登录成功:
|
||
uni.setStorageSync('accessToken', result.data.access_token);
|
||
uni.setStorageSync('refreshToken', result.data.refresh_token);
|
||
uni.setStorageSync('refresh_token_expries', result.data
|
||
.refresh_token_expries);
|
||
uni.setStorageSync('loginAccount', result.data.account); // 保存登录的手机号
|
||
registPush();
|
||
that.messageUpudateNum()
|
||
that.closeWindow();
|
||
} else {
|
||
uni.showToast({
|
||
title: result.msg,
|
||
icon: 'none'
|
||
});
|
||
}
|
||
}).catch(err => {
|
||
uni.showToast({
|
||
title: err.msg,
|
||
icon: 'none'
|
||
})
|
||
}).finally(() => {
|
||
//手动关闭授权页
|
||
this.quitLoginPage();
|
||
})
|
||
|
||
} else {
|
||
|
||
if (tokenResult.msg) {
|
||
//手动关闭授权页
|
||
if(!this.isFirst){
|
||
uni.showToast({
|
||
title: tokenResult.msg,
|
||
icon: 'none'
|
||
})
|
||
}
|
||
|
||
}
|
||
this.maskShow = true
|
||
this.quitLoginPage();
|
||
}
|
||
this.isFirst = false
|
||
|
||
},
|
||
clickResult => {
|
||
console.log(JSON.stringify(clickResult));
|
||
switch (clickResult.resultCode) {
|
||
case "700000":
|
||
this.closeWindow()
|
||
this.quitLoginPage();
|
||
console.log("用户点击了返回");
|
||
break
|
||
case "700001":
|
||
this.quitLoginPage();
|
||
console.log("用户切换其他登录方式");
|
||
break
|
||
case "700002":
|
||
console.log("用户点击登录按钮");
|
||
if (!clickResult.result.isChecked) {
|
||
if (!config.uiConfig.setPrivacyAlertIsNeedShow) {
|
||
plus.nativeUI.toast("请同意服务条款");
|
||
}
|
||
}
|
||
break;
|
||
case "700003":
|
||
console.log("用户点击checkBox");
|
||
break
|
||
case "700004":
|
||
console.log("用户点击协议");
|
||
break
|
||
case "700010":
|
||
this.closeWindow()
|
||
console.log("用户点击返回按钮,Android专用");
|
||
this.quitLoginPage();
|
||
break
|
||
case "700011":
|
||
this.closeWindow()
|
||
console.log("用户使用物理返回键,Android专用");
|
||
this.quitLoginPage();
|
||
break
|
||
case "700006":
|
||
console.log("弹出二次授权弹窗");
|
||
break
|
||
case "700007":
|
||
console.log("关闭二次授权弹窗");
|
||
break
|
||
case "700008":
|
||
console.log("点击二次授权弹窗确认按钮");
|
||
break
|
||
case "700009":
|
||
console.log("点击二次授权弹窗协议");
|
||
break
|
||
}
|
||
},
|
||
customUiResult => {
|
||
console.log("点击了自定义控件 " + JSON.stringify(customUiResult));
|
||
if ("close" == customUiResult.widgetId) {
|
||
aLiSDKModule.quitLoginPage();
|
||
} else if ("closePrivacyAlert" == customUiResult.widgetId) {
|
||
aLiSDKModule.closePrivactAlertView();
|
||
} else {
|
||
plus.nativeUI.toast("点击了自定义按钮,widgetId:" + customUiResult.widgetId);
|
||
}
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 手机号输入实时校验
|
||
* 1. 过滤非数字字符(兼容部分设备type="number"仍可输入非数字的情况)
|
||
* 2. 实时校验11位数字,非11位显示错误提示
|
||
*/
|
||
handlePhoneInput() {
|
||
// 过滤非数字字符(账号密码登录时账号可能为手机号,统一过滤)
|
||
this.phone = this.phone.replace(/\D/g, '');
|
||
if (this.loginType === 'code' && this.phone.length > 0 && !uni.$uv.test.mobile(this.phone)) {
|
||
this.phoneError = '请输入正确的手机号';
|
||
} else if (this.loginType === 'account' && this.phone.length > 0 && this.phone.length < 6) {
|
||
this.phoneError = '请输入正确的账号';
|
||
} else {
|
||
this.phoneError = '';
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
/* 蒙层:全屏半透明,底部对齐弹窗 */
|
||
page {
|
||
width: 100%;
|
||
height: 100%;
|
||
background: transparent;
|
||
}
|
||
|
||
.login-mask {
|
||
position: fixed;
|
||
top: 0;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
// width: 100%;
|
||
// height: 100%;
|
||
// position: relative;
|
||
// width: 100vw;
|
||
// height: 100vh;
|
||
background: transparent;
|
||
// display: flex;
|
||
// flex-direction: column;
|
||
// justify-content: flex-end;
|
||
z-index: 999;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 底部弹窗:宽度100%,顶部圆角 */
|
||
.login-popup {
|
||
position: absolute;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
// width: 100%;
|
||
background: #fff;
|
||
border-top-left-radius: 20rpx;
|
||
border-top-right-radius: 20rpx;
|
||
padding: 42rpx 66rpx 100rpx 66rpx;
|
||
box-sizing: border-box;
|
||
// position: relative;
|
||
}
|
||
|
||
/* 弹窗头部:标题+关闭按钮 */
|
||
.popup-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 55rpx;
|
||
|
||
.popup-title {
|
||
width: 100%;
|
||
font-weight: 500;
|
||
font-size: 30rpx;
|
||
color: #333333;
|
||
line-height: 42rpx;
|
||
text-align: center;
|
||
font-style: normal;
|
||
}
|
||
}
|
||
|
||
.popup-close {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
position: absolute;
|
||
top: 37rpx;
|
||
right: 40rpx;
|
||
}
|
||
|
||
/* 登录选项卡 */
|
||
.login-tabs {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 55rpx;
|
||
padding: 0 96rpx;
|
||
|
||
.tab-line {
|
||
width: 2rpx;
|
||
height: 20rpx;
|
||
background: #D8D8D8;
|
||
border-radius: 1rpx;
|
||
}
|
||
|
||
.tab-item {
|
||
font-weight: 400;
|
||
font-size: 26rpx;
|
||
color: #333333;
|
||
line-height: 37rpx;
|
||
text-align: center;
|
||
font-style: normal;
|
||
position: relative;
|
||
padding-bottom: 6rpx;
|
||
|
||
&.active {
|
||
color: #f00;
|
||
|
||
&::after {
|
||
content: '';
|
||
position: absolute;
|
||
bottom: 0rpx;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 40rpx;
|
||
border-radius: 2rpx;
|
||
height: 4rpx;
|
||
background: #f00;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 输入区域 */
|
||
.input-area {
|
||
margin-bottom: 80rpx;
|
||
|
||
.input-item {
|
||
display: flex;
|
||
align-items: center;
|
||
box-sizing: border-box;
|
||
width: 618rpx;
|
||
height: 98rpx;
|
||
background: #F5F5F5;
|
||
border-radius: 49rpx;
|
||
padding: 28rpx 24rpx 28rpx 30rpx;
|
||
margin-bottom: 30rpx;
|
||
position: relative;
|
||
|
||
.look-icon {
|
||
width: 37rpx;
|
||
position: absolute;
|
||
top: 50%;
|
||
right: 30rpx;
|
||
transform: translateY(-50%);
|
||
}
|
||
|
||
.input-icon-phone {
|
||
width: 30rpx;
|
||
height: 32rpx;
|
||
margin-right: 19rpx;
|
||
}
|
||
|
||
.input-icon-password {
|
||
width: 32rpx;
|
||
height: 38rpx;
|
||
margin-right: 19rpx;
|
||
}
|
||
|
||
.input-text {
|
||
flex: 1;
|
||
font-size: 30rpx;
|
||
height: 40rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.get-code-btn {
|
||
font-weight: 400;
|
||
font-size: 30rpx;
|
||
color: #FF4767;
|
||
line-height: 42rpx;
|
||
text-align: center;
|
||
font-style: normal;
|
||
}
|
||
|
||
.running {
|
||
color: #999999;
|
||
}
|
||
|
||
.noPhone {
|
||
color: #999999;
|
||
}
|
||
|
||
.eye-icon {
|
||
font-size: 30rpx;
|
||
color: #666;
|
||
margin-left: 15rpx;
|
||
}
|
||
}
|
||
|
||
// 错误提示样式
|
||
.input-error {
|
||
display: block;
|
||
font-size: 24rpx;
|
||
color: #FF4767;
|
||
margin-left: 30rpx;
|
||
margin-top: -20rpx;
|
||
margin-bottom: 20rpx;
|
||
line-height: 1.2;
|
||
}
|
||
}
|
||
|
||
/* 登录按钮:匹配示例的粉/红切换 */
|
||
.login-btn {
|
||
width: 590rpx;
|
||
height: 98rpx;
|
||
background: rgba(232, 16, 30, 0.4);
|
||
border-radius: 50rpx;
|
||
font-weight: 500;
|
||
font-size: 30rpx;
|
||
color: #FFFFFF;
|
||
text-align: center;
|
||
font-style: normal;
|
||
margin: 0 auto;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-bottom: 30rpx;
|
||
|
||
&.active {
|
||
background: rgba(232, 16, 30, 1);
|
||
}
|
||
}
|
||
|
||
.agree {
|
||
display: flex;
|
||
flex-flow: row nowrap;
|
||
flex-direction: row;
|
||
align-items: flex-start;
|
||
|
||
.agree-btn {
|
||
transform: translateY(4rpx);
|
||
margin-right: 8rpx;
|
||
}
|
||
|
||
.agree-card {
|
||
.agreement {
|
||
font-weight: 400;
|
||
font-size: 26rpx;
|
||
color: rgba(232, 16, 30, 1);
|
||
line-height: 37rpx;
|
||
margin: 0 10rpx;
|
||
}
|
||
|
||
.agree-text {
|
||
font-weight: 400;
|
||
font-size: 26rpx;
|
||
color: #898989;
|
||
line-height: 37rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.uni-input-placeholder{
|
||
font-weight: 400;
|
||
font-size: 30rpx;
|
||
color: #BCC0C0;
|
||
line-height: 42rpx;
|
||
text-align: left;
|
||
font-style: normal;
|
||
}
|
||
</style> |