mrr.sj.front/pages/settings/password.vue

331 lines
8.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="editPassword">
<!-- 顶部导航栏 -->
<custom-navbar title="设置密码" :showBack="true" borderBottom="none" backgroundColor="transparent"></custom-navbar>
<view class="password-title">
<text>设置新密码</text>
</view>
<view class="password-tip">
<text>登录密码用于美融融plus登录密码<text style="color: #E8101E;">至少6个字符不能全是字母或者数字</text></text>
</view>
<!-- 新密码输入区域 -->
<view class="newPassword">
<view class="password-text">新密码</view>
<view class="input-item">
<input type="text" v-model="newPassword" placeholder="请输入密码" :password="!showNewPassword" maxlength="20"
class="input-text" @input="checkPwdError" />
<image src="/static/images/icons/noLook.png" mode="widthFix" class="look-icon" v-if="!showNewPassword"
@click.stop="showNewPassword = true"></image>
<image src="/static/images//icons/look.png" mode="widthFix" class="look-icon"
@click.stop="showNewPassword = false" v-else></image>
</view>
<!-- 密码错误提示 -->
<text class="pwd-error" v-if="pwdErrorMsg">{{pwdErrorMsg}}</text>
</view>
<!-- 确认密码输入区域 -->
<view class="surePassword">
<view class="password-text">确认密码</view>
<view class="input-item">
<input type="text" v-model="surePassword" placeholder="请输入密码" maxlength="20"
:password="!showSurePassword" class="input-text" @input="checkPwdError" />
<image src="/static/images/icons/noLook.png" mode="widthFix" class="look-icon" v-if="!showSurePassword"
@click.stop="showSurePassword = true"></image>
<image src="/static/images//icons/look.png" mode="widthFix" class="look-icon"
@click.stop="showSurePassword = false" v-else></image>
</view>
<!-- 两次密码不一致提示 -->
<text class="pwd-error"
v-if="!pwdErrorMsg && newPassword && surePassword && newPassword !== surePassword">两次输入的密码不一致</text>
</view>
<!-- 确认按钮 -->
<view class="select-serve-footer">
<view class="select-serve-footer__btn" :class="{active: canSubmit}" @click="submit">确认</view>
</view>
</view>
</template>
<script>
import request from '../../utils/request';
export default {
data() {
return {
showNewPassword: false,
newPassword: "",
showSurePassword: false,
surePassword: "",
pwdErrorMsg: "", // 密码错误提示信息
phone: uni.getStorageSync('loginAccount') // 登录账号/手机号(从全局缓存或路由参数获取)
}
},
computed: {
// 判断是否可提交:密码合法 + 两次密码一致 + 均有值
canSubmit() {
return !this.pwdErrorMsg && this.newPassword && this.surePassword && this.newPassword === this
.surePassword;
}
},
onLoad() {
// 获取登录账号/手机号(从缓存中获取,需与登录页的存储逻辑一致)
this.phone = uni.getStorageSync('loginAccount') || '';
// 若从路由参数传递可使用this.phone = this.$route.query.phone || '';
},
methods: {
/**
* 密码校验总函数
* @param {String} pwd - 待校验的密码
* @returns {Object} { valid: 布尔值, msg: 错误提示 }
*/
validatePassword(pwd) {
// 1. 长度校验6-20位
if (pwd.length < 6 || pwd.length > 20) {
return {
valid: false,
msg: '密码长度需在6-20位之间'
};
}
// 修复后的禁用字符正则:
// 去掉易兼容出错的\p{Emoji}改用具体的Emoji Unicode范围
// 匹配:空格(\s)、中文(\u4e00-\u9fa5)、全角字符(\uFF00-\uFFEF)、常见Emoji(\u{1F600}-\u{1F64F}等)
const forbiddenReg =
/[\s\u4e00-\u9fa5\uFF00-\uFFEF\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{1F1E0}-\u{1F1FF}]/gu;
if (forbiddenReg.test(pwd)) {
return {
valid: false,
msg: '密码不可包含空格、中文或特殊表情'
};
}
// 3. // 正则说明:
// (?=.*[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}$/;
if (!reg.test(pwd)) {
return {
valid: false,
msg: '密码需包含数字+字母/符号组合'
};
}
// 4. 禁止包含手机号/账号
if (this.phone && pwd.includes(this.phone)) {
return {
valid: false,
msg: '密码不可包含账号/手机号,存在安全风险'
};
}
// 所有校验通过
return {
valid: true,
msg: ''
};
},
/**
* 实时检查密码错误
*/
checkPwdError() {
if (!this.newPassword) {
this.pwdErrorMsg = '';
return;
}
const {
valid,
msg
} = this.validatePassword(this.newPassword);
this.pwdErrorMsg = valid ? '' : msg;
},
/**
* 提交设置密码
*/
submit() {
let that = this;
// 1. 再次校验密码(防止实时校验被绕过)
const {
valid,
msg
} = this.validatePassword(this.newPassword);
if (!valid) {
uni.showToast({
title: msg,
icon: 'none'
});
return;
}
// 2. 校验两次密码是否一致
if (this.newPassword !== this.surePassword) {
uni.showToast({
title: '两次输入的密码不一致',
icon: 'none'
});
return;
}
// 3. 调用设置密码接口注意原接口是sendcode需替换为实际的设置密码接口
request.post('/user/passwordSet', { // 建议替换为实际接口名
account: that.phone,
password: that.surePassword
}).then(result => {
console.log(1111111,result)
if (result.code == 200) {
uni.showToast({
title: '密码设置成功',
icon: 'success'
});
// 密码设置成功后返回上一页
setTimeout(() => {
uni.navigateBack();
}, 1500);
} else {
uni.showToast({
title: result.msg,
icon: 'none'
});
}
}).catch(err => {
uni.showToast({
title: err.msg,
icon: 'none'
});
});
}
}
}
</script>
<style lang="scss" scoped>
.editPassword {
background-image: url("/static/images/background/editPassword.png");
background-position: top;
background-repeat: no-repeat;
background-size: 100%;
background-color: #fff;
min-height: 100vh;
padding: 0 60rpx;
position: relative; // 为底部固定按钮做兼容
.password-title {
margin-top: 82rpx;
font-weight: 500;
font-size: 46rpx;
color: #333333;
line-height: 65rpx;
text-align: left;
font-style: normal;
}
.password-tip {
margin-top: 20rpx;
font-size: 28rpx;
color: #666;
line-height: 40rpx;
}
.newPassword,
.surePassword {
margin-top: 100rpx;
}
.surePassword {
margin-top: 40rpx;
}
.password-text {
font-weight: 400;
font-size: 32rpx;
color: #333333;
line-height: 45rpx;
text-align: left;
font-style: normal;
}
.input-item {
display: flex;
align-items: center;
box-sizing: border-box;
width: 630rpx;
height: 98rpx;
background: #F5F5F5;
border-radius: 49rpx;
padding: 28rpx 24rpx 28rpx 30rpx;
margin-bottom: 10rpx; // 减少底部间距,给错误提示留空间
position: relative;
margin-top: 19rpx;
.look-icon {
width: 37rpx;
position: absolute;
top: 50%;
right: 30rpx;
transform: translateY(-50%);
}
.input-text {
flex: 1;
font-size: 30rpx;
height: 40rpx;
color: #333;
}
}
// 密码错误提示样式
.pwd-error {
display: block;
font-size: 24rpx;
color: #E8101E;
margin-left: 30rpx;
margin-top: 10rpx;
line-height: 1.2;
}
.select-serve-footer {
background-color: #fff;
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 40rpx 60rpx;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05); // 增加阴影提升质感
&__btn {
width: 630rpx;
height: 98rpx;
background: rgba(232, 16, 30, 0.4);
border-radius: 798rpx;
display: flex;
align-items: center;
justify-content: center;
font-weight: 500;
font-size: 30rpx;
color: #ffffff;
line-height: 39rpx;
text-align: center;
font-style: normal;
transition: background-color 0.2s ease; // 增加过渡动画
}
.active {
background: #E8101E;
&:active {
opacity: 0.9; // 点击反馈
}
}
}
}
</style>