提交 46220155 编写于 作者: 芊里

指纹解锁功能录入

上级 2b828b6a
<template>
<view class="content">
<view class="login-type">
<view v-for="(item,index) in loginTypeList" :key="index" @click="loginType = index" :class="{act: loginType === index}"
class="login-type-btn">{{item}}</view>
</view>
<view class="input-group" v-if="loginType === 0">
<view class="input-row border">
<text class="title">手机:</text>
<m-input class="m-input" type="text" clearable focus v-model="mobile" placeholder="请输入手机号码"></m-input>
</view>
<view class="input-row">
<text class="title">验证码:</text>
<m-input type="text" v-model="code" placeholder="请输入验证码"></m-input>
<view class="send-code-btn" @click="sendSmsCode">{{codeDuration ? codeDuration + 's' : '发送验证码' }}</view>
</view>
</view>
<view class="input-group" v-else>
<view class="input-row border">
<text class="title">账号:</text>
<m-input class="m-input" type="text" clearable focus v-model="username" placeholder="请输入账号"></m-input>
</view>
<view class="input-row border">
<text class="title">密码:</text>
<m-input type="password" displayable v-model="password" placeholder="请输入密码"></m-input>
</view>
<view v-if="needCaptcha" class="input-row">
<text class="title">验证码:</text>
<m-input type="text" v-model="captchaText" placeholder="请输入验证码"></m-input>
<view class="send-code-btn captcha-view" @click="captcha('refreshCaptcha')">
<i v-if="captchaing" class="uni-icon_toast uni-loading"></i>
<img v-if="!captchaing" :src="captchaBase64" width="100%" height="100%"></img>
</view>
</view>
</view>
<view class="btn-row">
<button type="primary" class="primary" :loading="loginBtnLoading" @tap="bindLogin">登录</button>
</view>
<view class="action-row">
<navigator url="../reg/reg">注册账号</navigator>
</view>
<view class="oauth-row" v-if="hasProvider" v-bind:style="{top: positionTop + 'px'}">
<view class="oauth-image" v-for="provider in providerList" :key="provider.value">
<image :src="provider.image" @tap="toLogin(provider.value)"></image>
<!-- #ifdef MP-WEIXIN -->
<button v-if="!isDevtools" open-type="getUserInfo" @getuserinfo="getUserInfo"></button>
<!-- #endif -->
</view>
</view>
<view class="oauth-row" v-if="hasProvider && !hasAppleLogin && platform ==='ios'" v-bind:style="{top: (positionTop - 50) + 'px'}">
<text style="color: #C8C7CC;text-align: center;font-size: 30rpx;">登录/注册即表示您同意
<text style="color: #C8C7CC;text-decoration: underline;" @click="toPrivacy">隐私政策</text>
<text></text>
<text style="color: #C8C7CC;text-decoration: underline;" @click="toService">服务协议</text>
</text>
</view>
</view>
</template>
<script>
import {
mapState,
mapMutations
} from 'vuex'
import mInput from '@/components/m-input.vue'
import {
univerifyLogin,
univerifyErrorHandler
} from '@/common/univerify.js'
import {
getDeviceUUID
} from '@/common/utils.js'
let weixinAuthService;
const captchaOptions = {
deviceId: getDeviceUUID(),
scene: 'login'
}
export default {
components: {
mInput
},
data() {
return {
platform: uni.getSystemInfoSync().platform,
loginType: 0,
loginTypeList: ['免密登录', '密码登录'],
mobile: '',
code: '',
providerList: [],
hasProvider: false,
username: '',
password: '',
positionTop: 0,
isDevtools: false,
codeDuration: 0,
loginBtnLoading: false,
hasAppleLogin: false,
needCaptcha: uni.getStorageSync('uni-needCaptcha'),
captchaing: false,
captchaBase64: '',
captchaText: ''
}
},
onLoad() {
// #ifdef APP-PLUS
plus.oauth.getServices((services) => {
weixinAuthService = services.find((service) => {
return service.id === 'weixin'
})
if (weixinAuthService) {
this.hasWeixinAuth = true
}
});
// #endif
if (this.needCaptcha) {
this.captcha('createCaptcha')
}
this.logout();
},
methods: {
...mapMutations({
login:'user/login',
logout:'user/logout'
}),
toPrivacy(){
uni.navigateTo({
url:'/pages/agree-list/privacy/privacy'
})
},
toService(){
uni.navigateTo({
url:'/pages/agree-list/service/service'
})
},
initProvider() {
const filters = ['weixin', 'qq', 'sinaweibo', 'univerify'];
uni.getProvider({
service: 'oauth',
success: (res) => {
if (res.provider && res.provider.length) {
if (res.provider.indexOf('apple') !== -1) {
this.hasAppleLogin = true;
}
for (let i = 0; i < res.provider.length; i++) {
const curProvider = res.provider[i];
if (~filters.indexOf(curProvider)) {
this.providerList.push({
value: curProvider,
image: '../../static/img/' + curProvider + '.png'
});
}
}
this.hasProvider = true;
}
},
fail: (err) => {
console.error('获取服务供应商失败:' + JSON.stringify(err));
}
});
},
initPosition() {
/**
* 使用 absolute 定位,并且设置 bottom 值进行定位。软键盘弹出时,底部会因为窗口变化而被顶上来。
* 反向使用 top 进行定位,可以避免此问题。
*/
this.positionTop = uni.getSystemInfoSync().windowHeight - 100;
},
sendSmsCode() {
if (this.codeDuration) {
uni.showModal({
content: `请在${this.codeDuration}秒后重试`,
showCancel: false
})
}
if (!/^1\d{10}$/.test(this.mobile)) {
uni.showModal({
content: '手机号码填写错误',
showCancel: false
})
return
}
uniCloud.callFunction({
name: 'user-center',
data: {
action: 'sendSmsCode',
params: {
mobile: this.mobile,
type: 'login'
}
},
success: (e) => {
if (e.result.code == 0) {
uni.showModal({
content: '验证码发送成功,请注意查收',
showCancel: false
})
this.codeDuration = 60
this.codeInterVal = setInterval(() => {
this.codeDuration--
if (this.codeDuration === 0) {
if (this.codeInterVal) {
clearInterval(this.codeInterVal)
this.codeInterVal = null
}
}
}, 1000)
} else {
uni.showModal({
content: '验证码发送失败:' + e.result.msg,
showCancel: false
})
}
},
fail(e) {
uni.showModal({
content: '验证码发送失败',
showCancel: false
})
}
})
},
async loginByPwd() {
/**
* 客户端对账号信息进行一些必要的校验。
* 实际开发中,根据业务需要进行处理,这里仅做示例。
*/
if (this.username.length < 3) {
uni.showToast({
icon: 'none',
title: '账号最短为 3 个字符'
});
return;
}
if (this.password.length < 6) {
uni.showToast({
icon: 'none',
title: '密码最短为 6 个字符'
});
return;
}
const data = {
username: this.username,
password: this.password,
captcha: this.captchaText,
...captchaOptions
};
this.loginBtnLoading = true
uniCloud.callFunction({
name: 'user-center',
data: {
action: 'login',
params: data
},
success: (e) => {
if (e.result.code == 0) {
this.needCaptcha = false;
uni.setStorageSync('uni-needCaptcha', this.needCaptcha)
uni.setStorageSync('uni_id_token', e.result.token)
// uni.setStorageSync('username', e.result.username)
// uni.setStorageSync('login_type', 'online')
// uni.setStorageSync('uni_id_has_pwd', true)
this.toMain(e.result.userInfo);
} else {
uni.showModal({
content: e.result.message,
showCancel: false
})
this.needCaptcha = e.result.needCaptcha;
uni.setStorageSync('uni-needCaptcha', this.needCaptcha)
if (this.needCaptcha) {
this.captcha('createCaptcha')
}
}
},
fail: (e) => {
uni.showModal({
content: JSON.stringify(e),
showCancel: false
})
},
complete: () => {
this.loginBtnLoading = false
}
})
},
loginBySms() {
if (!/^1\d{10}$/.test(this.mobile)) {
uni.showModal({
content: '手机号码填写错误',
showCancel: false
})
return
}
if (!/^\d{6}$/.test(this.code)) {
uni.showModal({
title: '验证码为6位纯数字',
showCancel: false
});
return;
}
uniCloud.callFunction({
name: 'user-center',
data: {
action: 'loginBySms',
params: {
mobile: this.mobile,
code: this.code
}
},
success: (e) => {
console.log('login success', e);
if (e.result.code == 0) {
const username = e.result.username || '新用户'
uni.setStorageSync('uni_id_token', e.result.token)
uni.setStorageSync('username', username)
uni.setStorageSync('login_type', 'online')
this.toMain(username);
} else {
uni.showModal({
content: e.result.msg,
showCancel: false
})
console.log('登录失败', e);
}
},
fail(e) {
uni.showModal({
content: JSON.stringify(e),
showCancel: false
})
}
})
},
bindLogin() {
switch (this.loginType) {
case 0:
this.loginBySms()
break;
case 1:
this.loginByPwd()
break;
default:
break;
}
},
oauth(value) {
return new Promise((resolve, reject) => {
// #ifdef APP-PLUS
weixinAuthService.authorize(function(res) {
resolve(res.code)
}, function(err) {
console.error(err)
reject(new Error('微信登录失败'))
});
// #endif
// #ifdef MP-WEIXIN
uni.login({
provider: 'weixin',
success(res) {
resolve(res.code)
},
fail(err) {
console.error('授权登录失败:' + JSON.stringify(err));
reject(new Error('微信登录失败'))
}
})
// #endif
})
},
getUserInfo({
detail
}) {
console.log('三方登录只演示登录api能力,暂未关联云端数据');
if (detail.userInfo) {
this.loginLocal(detail.userInfo);
} else {
uni.showToast({
icon: 'none',
title: '登陆失败'
});
}
},
loginLocal(userInfo) {
this.toMain(userInfo);
},
toMain(userInfo) {
this.login(userInfo);
uni.navigateBack();
},
toLogin(value) {
if (value === 'apple') {
this.loginByApple(value)
return;
}
if (value === 'weixin') {
this.loginByWeixin(value)
return;
}
if (value === 'univerify') {
univerifyLogin().catch(err => {
if (typeof err === 'boolean') return;
univerifyErrorHandler(err);
})
return;
}
uni.showModal({
content: `${value}登录只演示登录api能力,暂未关联云端数据`,
showCancel: false,
complete: () => {
console.log(`${value}登录只演示登录api能力,暂未关联云端数据`);
uni.login({
provider: value,
success: (res) => {
uni.getUserInfo({
provider: value,
success: (infoRes) => {
/**
* 实际开发中,获取用户信息后,需要将信息上报至服务端。
* 服务端可以用 userInfo.openId 作为用户的唯一标识新增或绑定用户信息。
*/
this.loginLocal(infoRes.userInfo);
},
fail() {
uni.showToast({
icon: 'none',
title: '登陆失败'
});
}
});
},
fail: (err) => {
console.error('授权登录失败:' + JSON.stringify(err));
}
});
}
})
},
loginByWeixin(value) {
this.oauth(value).then((code) => {
return uniCloud.callFunction({
name: 'user-center',
data: {
action: 'loginByWeixin',
params: {
code,
}
}
})
}).then((res) => {
if (res.result.code === 0) {
uni.setStorageSync('uni_id_token', res.result.token)
uni.setStorageSync('uni_id_token_expired', res.result.tokenExpired)
uni.setStorageSync('login_type', 'online')
uni.setStorageSync('username', '微信用户')
this.toMain('微信用户')
}
}).catch((e) => {
console.error(e)
uni.showModal({
showCancel: false,
content: '微信登录失败,请稍后再试'
})
})
},
async loginByApple(value) {
if (!this.hasAppleLogin) {
uni.showModal({
showCancel: false,
content: `暂无法使用苹果登录,Apple登录集成教程:\nhttps://ask.dcloud.net.cn/article/36651`
})
return
};
let Provider = value;
const [loginErr, loginData] = await uni.login({
provider: Provider
});
if (loginErr) {
uni.showModal({
showCancel: false,
content: '苹果登录失败,请稍后再试'
})
return;
}
// 获取用户信息
const [getUserInfoErr, result] = await uni.getUserInfo({
provider: Provider
});
if (getUserInfoErr) {
let content = getUserInfoErr.errMsg;
if (~content.indexOf('uni.login')) {
content = '请先完成登录操作';
}
uni.showModal({
title: '获取用户信息失败',
content: '错误原因' + content,
showCancel: false
});
return;
}
// uni-id 苹果登录
uniCloud.callFunction({
name: 'user-center',
data: {
action: 'loginByApple',
params: result.userInfo
},
success: (e) => {
console.log('loginByApple success', e);
if (!e.success) {
uni.showModal({
showCancel: false,
content: JSON.stringify(e.message)
})
return;
}
const userInfo = e.result.userInfo;
uni.setStorageSync('uni_id_token', e.result.token)
this.toMain(userInfo);
},
fail: (e) => {
uni.showModal({
content: `苹果登录失败: ${JSON.stringify(e)}`,
showCancel: false
})
}
})
},
async captcha(action, args) {
if (this.captchaing) return;
// 验证不loading
this.captchaing = true;
let {
result: res
} = await uniCloud.callFunction({
name: 'user-center',
data: {
action,
params: {
...captchaOptions,
...args
}
}
})
this.captchaing = false;
if (res.code === 0) {
this.captchaBase64 = res.captchaBase64
} else {
uni.showToast({
icon: 'none',
title: res.message,
duration: 1000
})
}
return res;
},
openAppleLoginDoc() {
// #ifdef APP-PLUS
plus.webview.open('https://ask.dcloud.net.cn/article/36651')
// #endif
}
},
onReady() {
this.initPosition();
this.initProvider();
// #ifdef MP-WEIXIN
this.isDevtools = uni.getSystemInfoSync().platform === 'devtools';
// #endif
}
}
</script>
<style scoped>
@import "/common/login.css";
.login-type {
display: flex;
justify-content: center;
}
.login-type-btn {
line-height: 30px;
margin: 0px 15px;
}
.login-type-btn.act {
color: #0FAEFF;
border-bottom: solid 1px #0FAEFF;
}
.send-code-btn {
width: 120px;
text-align: center;
background-color: #0FAEFF;
color: #FFFFFF;
}
.action-row {
display: flex;
flex-direction: row;
justify-content: center;
}
.action-row navigator {
color: #007aff;
padding: 0 10px;
}
.oauth-row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
flex-wrap: wrap;
position: absolute;
top: 0;
left: 0;
width: 100%;
}
.oauth-image {
position: relative;
width: 50px;
height: 50px;
border: 1px solid #dddddd;
border-radius: 50px;
background-color: #ffffff;
}
.oauth-image image {
width: 30px;
height: 30px;
margin: 10px;
}
.oauth-image button {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
opacity: 0;
}
.captcha-view {
line-height: 0;
justify-content: center;
align-items: center;
display: flex;
position: relative;
background-color: #f3f3f3;
}
</style>
<template>
<view class="content">
<view v-if="hasLogin" class="hello">
<view class="title">
您好 {{userName}},您已成功登录。
</view>
<view class="ul">
<view>这是 uni-app 带登录模板的示例App首页。</view>
<view>在 “我的” 中点击 “退出” 可以 “注销当前账户”</view>
</view>
</view>
<view v-if="!hasLogin" class="hello">
<view class="title">
您好 游客。
</view>
<view class="ul">
<view>这是 uni-app 带登录模板的示例App首页。</view>
<view>在 “我的” 中点击 “登录” 可以 “登录您的账户”</view>
</view>
</view>
</view>
</template>
<script>
import {
mapState,
mapMutations
} from 'vuex'
import {
univerifyLogin
} from '@/common/univerify.js'
export default {
computed: mapState(['forcedLogin', 'hasLogin', 'userName']),
onLoad() {
const loginType = uni.getStorageSync('login_type')
if (loginType === 'local') {
this.login(uni.getStorageSync('username'))
return
}
let uniIdToken = uni.getStorageSync('uni_id_token')
if (uniIdToken) {
this.login(uni.getStorageSync('username'))
uniCloud.callFunction({
name: 'user-center',
data: {
action: 'checkToken',
},
success: (e) => {
console.log('checkToken success', e);
if (e.result.code > 0) {
//token过期或token不合法,重新登录
if (this.forcedLogin) {
uni.reLaunch({
url: '../login/login'
});
} else {
uni.navigateTo({
url: '../login/login'
});
}
}
},
fail(e) {
uni.showModal({
content: JSON.stringify(e),
showCancel: false
})
}
})
} else {
this.guideToLogin()
}
},
methods: {
...mapMutations(['login']),
guideToLogin() {
uni.showModal({
title: '未登录',
content: '您未登录,需要登录后才能继续',
/**
* 如果需要强制登录,不显示取消按钮
*/
showCancel: !this.forcedLogin,
success: (res) => {
if (res.confirm) {
univerifyLogin().catch((err) => {
if (err === false) return;
/**
* 如果需要强制登录,使用reLaunch方式
*/
if (this.forcedLogin) {
uni.reLaunch({
url: '../login/login'
});
} else {
uni.navigateTo({
url: '../login/login'
});
}
})
}
}
});
}
}
}
</script>
<style>
.hello {
display: flex;
flex: 1;
flex-direction: column;
}
.title {
color: #8f8f94;
margin-top: 25px;
}
.ul {
font-size: 15px;
color: #8f8f94;
margin-top: 25px;
}
.ul>view {
line-height: 25px;
}
</style>
<template>
<view class="content">
<view class="input-group">
<view class="input-row">
<text class="title">邮箱:</text>
<m-input type="text" focus clearable v-model="email" placeholder="请输入邮箱"></m-input>
</view>
</view>
<view class="btn-row">
<button type="primary" class="primary" @tap="findPassword">提交</button>
</view>
</view>
</template>
<script>
import mInput from '../../components/m-input.vue';
export default {
components: {
mInput
},
data() {
return {
email: ''
}
},
methods: {
findPassword() {
/**
* 仅做示例
*/
if (this.email.length < 3 || !~this.email.indexOf('@')) {
uni.showToast({
icon: 'none',
title: '邮箱地址不合法',
});
return;
}
uni.showToast({
icon: 'none',
title: '已发送重置邮件至注册邮箱,请注意查收。',
duration: 3000
});
}
}
}
</script>
<style>
</style>
<template>
<view style="padding: 20px;flex: 1;">
<view class="uni-header">
<view class="uni-group">
<view class="uni-title">修改密码</view>
</view>
</view>
<uni-forms ref="form" validateTrigger="bind" :rules="rules" @submit="submit">
<uni-forms-item label="旧密码" name="oldPassword" labelWidth="85">
<input class="uni-input-border" type="password" placeholder="旧密码" @blur="binddata('oldPassword',$event.detail.value)" />
</uni-forms-item>
<uni-forms-item label="新密码" name="newPassword" labelWidth="85">
<input class="uni-input-border" :password="showPassword" placeholder="新密码" @blur="binddata('newPassword',$event.detail.value)" />
<text class="uni-icon-password-eye pointer" :class="[!showPassword ? 'uni-eye-active' : '']" @click="changePassword">&#xe568;</text>
</uni-forms-item>
<uni-forms-item label="确认新密码" name="passwordConfirmation" labelWidth="85" :errorMessage="errorMessage">
<input @confirm="confirmForm('passwordConfirmation',$event.detail.value)" class="uni-input-border" :password="showPasswordAgain"
placeholder="确认新密码" @blur="binddata('passwordConfirmation',$event.detail.value)" />
<text class="uni-icon-password-eye pointer" :class="[!showPasswordAgain ? 'uni-eye-active' : '']" @click="changePasswordAgain">&#xe568;</text>
</uni-forms-item>
<view class="uni-button-group pointer">
<button class="uni-button uni-button-full" type="primary" @click="submitForm">保存</button>
</view>
</uni-forms>
</view>
</template>
<script>
import {
mapState,
mapMutations
} from 'vuex'
export default {
data() {
return {
showPassword: true,
showPasswordAgain: true,
errorMessage: '',
password: {
oldPassword: '',
newPassword: '',
passwordConfirmation: ''
},
rules: {
oldPassword: {
rules: [{
required: true,
errorMessage: '请输入旧密码'
}]
},
newPassword: {
rules: [{
required: true,
errorMessage: '请输入新密码'
},
{
minLength: 6,
errorMessage: '密码长度最小{minLength}个字符'
}
]
},
passwordConfirmation: {
rules: [{
required: true,
errorMessage: '请确认新密码'
},
{
minLength: 6,
errorMessage: '密码长度最小{minLength}个字符'
}
]
}
}
}
},
props: {
hasBackButton: {
type: Boolean,
default: false
},
isPhone: {
type: Boolean,
default: true
}
},
computed: {
...mapState('user', ['userInfo'])
},
methods: {
...mapMutations(['logout']),
submit(event) {
const {
errors,
value
} = event.detail
if (errors) return
if (value.newPassword !== value.passwordConfirmation) {
this.errorMessage = '两次输入密码不相同'
return
}
this.save(value)
},
confirmForm(name, value) {
this.binddata(name, value)
this.submitForm()
},
submitForm() {
this.errorMessage = ''
this.$refs.form.submit()
},
save(formData) {
let that = this
uni.showLoading()
uniCloud.callFunction({
name: 'user-center',
data: {
action: 'updatePwd',
params: {
...formData
}
},
success: (res) => {
uni.hideLoading()
if (res.result.code === 0) {
uni.showModal({
title: '提示',
content: res.result.msg,
showCancel: false,
success: (res) => {
if (res.confirm) {
that.logout();
uni.removeStorageSync('uni_id_token')
uni.removeStorageSync('username')
uni.reLaunch({
url: '/pages/login/login'
})
}
}
});
} else {
uni.showToast({
title: res.result.msg,
icon: 'none',
duration: 2000
})
}
},
fail: (e) => {
uni.hideLoading()
uni.showModal({
content: '修改密码失败',
showCancel: false
})
}
})
},
changePassword: function() {
this.showPassword = !this.showPassword;
},
changePasswordAgain: function() {
this.showPasswordAgain = !this.showPasswordAgain;
}
}
}
</script>
<style>
/* 标题栏 */
.uni-header {
padding: 0 15px;
display: flex;
height: 55px;
align-items: center;
justify-content: space-between;
border-bottom: 1px #f5f5f5 solid;
}
.uni-title {
margin-right: 10px;
font-size: 16px;
font-weight: 500;
color: #333;
}
.uni-group {
display: flex;
align-items: center;
justify-content: center;
word-break: keep-all;
}
/* 容器 */
.uni-container {
padding: 15px;
box-sizing: border-box;
}
/* 按钮样式 */
.uni-button-group {
margin-top: 30px;
display: flex;
align-items: center;
justify-content: center;
}
.pointer {
cursor: pointer;
}
.uni-input-border,
.uni-textarea-border {
width: 100%;
font-size: 14px;
color: #666;
border: 1px #e5e5e5 solid;
border-radius: 5px;
box-sizing: border-box;
}
.uni-input-border {
padding: 0 10px;
height: 35px;
}
.uni-icon-password-eye {
position: absolute;
right: 8px;
top: 6px;
font-family: uniicons;
font-size: 20px;
font-weight: normal;
font-style: normal;
width: 24px;
height: 24px;
line-height: 24px;
color: #999999;
}
.uni-eye-active {
color: #007AFF;
}
.uni-button {
padding: 10px 20px;
font-size: 14px;
border-radius: 4px;
line-height: 1;
margin: 0;
box-sizing: border-box;
overflow: initial;
}
.uni-button-full {
width: 100%;
}
</style>
<template>
<view class="content">
<view class="input-group">
<view class="input-row border">
<text class="title">账号:</text>
<m-input type="text" focus clearable v-model="username" placeholder="请输入账号"></m-input>
</view>
<view class="input-row border">
<text class="title">密码:</text>
<m-input type="password" displayable v-model="password" placeholder="请输入密码"></m-input>
</view>
<view class="input-row">
<text class="title">确认密码:</text>
<m-input type="password" displayable v-model="confirmPassword" placeholder="请确认密码"></m-input>
</view>
</view>
<view class="btn-row">
<button type="primary" class="primary" @tap="register">注册并登录</button>
</view>
</view>
</template>
<script>
import mInput from '@/components/m-input.vue';
import { mapMutations } from 'vuex';
export default {
components: {
mInput
},
data() {
return {
username: '',
password: '',
confirmPassword: ''
}
},
methods: {
...mapMutations({
'login':'user/login'
}),
register() {
/**
* 客户端对账号信息进行一些必要的校验。
* 实际开发中,根据业务需要进行处理,这里仅做示例。
*/
if (this.username.length < 3) {
uni.showToast({
icon: 'none',
title: '账号最短为 3 个字符'
});
return;
}
if (this.password.length < 6) {
uni.showToast({
icon: 'none',
title: '密码最短为 6 个字符'
});
return;
}
if (this.password !== this.confirmPassword) {
uni.showToast({
icon: 'none',
title: '两次密码输入不一致'
});
return;
}
const data = {
username: this.username,
password: this.password
}
uniCloud.callFunction({
name: 'user-center',
data: {
action: 'register',
params: data
},
success(e) {
console.log("注册", e);
if (e.result.code === 0) {
uni.showToast({
title: '注册成功'
});
this.login(e.result.userInfo);
uni.navigateBack(2);
} else {
uni.showModal({
content: JSON.stringify(e.result),
showCancel: false
})
}
},
fail(e) {
uni.showModal({
content: JSON.stringify(e),
showCancel: false
})
}
})
}
}
}
</script>
<style>
@import "/common/login.css";
</style>
<template>
<view class="content">
<uni-list class="content">
<uni-list-item v-for="(item,index) in agreeList" :key="index" :title="item.title" :to="item.to" :clickable="true" @click="itemClick(item)" :showSwitch="item.showSwitch" :switchChecked="item.isChecked" link></uni-list-item>
</uni-list>
<button class="bottom-back" @click="clickLogout"><text class="bottom-back-text">退出登录</text></button>
</view>
</template>
<script>
import { isOn, setting } from '@/common/dc-push/push.js';
import { mapMutations } from 'vuex';
export default {
data() {
return {
agreeList:[
{
title:'个人资料',
to:''
},
{
title:'修改密码',
to:''
},{
title:'注销用户',
event:''
},{
title:'推送功能',
name:'push',
event:'openSetting',
isChecked:false,
showSwitch:true
},{
title:'清理缓存',
event:''
}
]
}
},
onShow() {
let pushIsOn = isOn();
this.agreeList.forEach(item=>{
item.name == 'push' ? (item.isChecked = pushIsOn) : '';
})
},
methods:{
...mapMutations({
logout:'user/logout'
}),
clickLogout(){
this.logout();
uni.navigateBack();
},
itemClick(item){
if(!item.to && item.event){
this[item.event]();
}
},
/**
* 打开设置页面
*/
openSetting(){
setting();
}
}
}
</script>
<style>
.content{
width: 750rpx;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
/* align-items: center; */
flex: 1;
}
.bottom-back{
width: 750rpx;
height: 120rpx;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
/* #ifndef APP-NVUE */
border: none;
/* #endif */
border-width: 0;
border-radius: 0;
}
.bottom-back-text{
font-size: 40rpx;
color: #DD524D;
}
</style>
<template>
<view class="content">
<!-- 功能列表 -->
<uni-list class="content">
<uni-list-item v-for="(item,index) in agreeList" :key="index" :title="item.title" :to="item.to"
:clickable="true" @click="itemClick(item)" :showSwitch="item.showSwitch" :switchChecked="item.isChecked"
:link="item.to"></uni-list-item>
</uni-list>
<!-- 退出按钮 -->
<button class="bottom-back" @click="clickLogout"><text class="bottom-back-text">退出登录</text></button>
<!-- 弹窗 -->
<uni-popup type="center" ref="dialog">
<uni-popup-dialog type="warning" content="是否退出登录?" @confirm="confirm"></uni-popup-dialog>
</uni-popup>
</view>
</template>
<script>
import {
isOn,
setting
} from '@/common/dc-push/push.js';
import {
mapMutations
} from 'vuex';
export default {
data() {
return {
agreeList: [{
title: '个人资料',
to: ''
},
{
title: '修改密码',
to: ''
}, {
title: '注销用户',
event: ''
},
//#ifdef APP-PLUS
{
title: '推送功能',
name: 'push',
event: 'openSetting',
isChecked: false,
showSwitch: true
},
{
title: '清理缓存',
event: ''
},
//#endif
]
}
},
onLoad() {
this.initSoterAuthentication();
},
onShow() {
this.checkPush();
},
methods: {
...mapMutations({
logout: 'user/logout'
}),
checkPush(){
// 手机端获取推送是否开启
//#ifdef APP-PLUS
let pushIsOn = isOn();
this.agreeList.forEach(item => {
item.name == 'push' ? (item.isChecked = pushIsOn) : '';
})
//#endif
},
/**
* 添加生物认证选项
*/
initSoterAuthentication() {
// #ifdef APP-PLUS || MP-WEIXIN
let checkAuthModeList = [{
title: '指纹解锁',
name: 'fingerPrint',
event: 'startSoterAuthentication'
}, {
title: '人脸解锁',
name: 'facial',
event: 'startSoterAuthentication'
}];
uni.checkIsSupportSoterAuthentication({
success: (res) => {
res.supportMode.forEach(item => {
this.agreeList.push(checkAuthModeList.find(mode => mode.name == item));
})
},
fail: (err) => {
reject(err);
}
})
// #endif
},
/**
* 开始生物认证
*/
startSoterAuthentication(item) {
// 检查是否开启认证
this.checkIsSoterEnrolledInDevice(item)
.then(()=>{
// 开始认证
uni.startSoterAuthentication({
requestAuthModes: [item.name],
challenge: '123456', // 微信端挑战因子
authContent: `请用${item.title}`,
success(res) {
if(res.errCode == 0){
/**
* 验证成功后开启自己的业务逻辑
*
* app端以此为依据 验证成功
*
* 微信小程序需要再次通过后台验证resultJSON与resultJSONSignature获取最终结果
*/
return uni.showToast({
title: `${item.title}成功`,
icon: 'none'
});
}
uni.showToast({
title: '认证失败请重试',
icon: 'none'
});
},
fail(err) {
uni.showToast({
title: `认证失败:${err.errCode}`,
icon: 'none'
});
}
})
})
},
checkIsSoterEnrolledInDevice(mode){
return new Promise((resolve, reject)=>{
uni.checkIsSoterEnrolledInDevice({
checkAuthMode:mode.name,
success: (res) => {
if(res.isEnrolled){
return resolve(res);
}
uni.showToast({
title: `设备未开启${item.title}`,
icon: 'none'
});
reject(res);
},
fail: (err) => {
uni.showToast({
title: `${item.title}失败`,
icon: 'none'
});
reject(err);
}
})
})
},
clickLogout() {
this.$refs.dialog.open();
},
confirm(){
this.logout();
uni.navigateBack();
},
itemClick(item) {
if (!item.to && item.event) {
this[item.event](item);
}
},
/**
* 打开设置页面
*/
openSetting() {
setting();
}
}
}
</script>
<style>
/* #ifndef APP-NVUE */
page {
flex: 1;
width: 100%;
height: 100%;
}
uni-button:after{
border: none;
border-radius: 0;
}
/* #endif */
.content {
/* #ifndef APP-NVUE */
display: flex;
width: 100%;
height: 100%;
/* #endif */
flex-direction: column;
flex: 1;
}
.bottom-back {
width: 750rpx;
height: 120rpx;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
/* #ifndef APP-NVUE */
border: none;
/* #endif */
border-width: 0;
border-radius: 0;
}
.bottom-back-text {
font-size: 40rpx;
color: #DD524D;
}
</style>
<template>
<view class="content">
<uni-list class="content">
<uni-list-item v-for="(item , index) in agreeList" :key="index" :title="item.title" :to="item.to"
:clickable="true" @click="itemClick(item)" :showSwitch="item.showSwitch"
:switchChecked="item.isChecked"
:link="item.link"></uni-list-item>
</uni-list>
<button class="bottom-back" @click="clickLogout"><text class="bottom-back-text">退出登录</text></button>
</view>
</template>
<script>
import {
isOn,
setting
} from '@/common/dc-push/push.js';
import {
mapMutations
} from 'vuex';
export default {
data() {
return {
agreeList: [{
title: '个人资料',
to: '',
link:true
},
{
title: '修改密码',
to: '',
link:true
}, {
title: '注销用户',
event: '',
link:true
}, {
title: '推送功能',
name: 'push',
event: 'openSetting',
isChecked: false,
showSwitch: true,
},
{
title: "录入指纹",
name: 'fingerprint',
link:true
}, {
title: '清理缓存',
event: '',
link:true
}
]
}
},
onShow() {
let pushIsOn = isOn();
this.agreeList.forEach(item => {
item.name == 'push' ? (item.isChecked = pushIsOn) : '';
})
},
methods: {
...mapMutations({
logout: 'user/logout'
}),
clickLogout() {
this.logout();
uni.navigateBack();
},
itemClick(item) {
if (!item.to && item.event) {
this[item.event]();
}
},
/**
* 打开设置页面
*/
openSetting() {
setting();
}
}
}
</script>
<style>
.content {
width: 750rpx;
display: flex;
flex-direction: column;
/* align-items: center; */
flex: 1;
}
.bottom-back {
width: 750rpx;
height: 120rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border: none;
border-width: 0;
border-radius: 0;
}
.bottom-back-text {
font-size: 40rpx;
color: #DD524D;
}
</style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册