afc44feb by joe

密码找回

1 parent 0d4ba490
module.exports = {
logout : "/pingan_hklife_webapi/logout",
logout : "/pingan_hklife_webapi/user/logout",
// 是否显示图形验证码接口
stdIsShowImageVcode : "/pingan_hklife_webapi/auth/stdIsShowImageVcode",
// 刷新图形验证码接口
......@@ -14,13 +14,16 @@ module.exports = {
gsLogin : "/pingan_hklife_webapi/auth/gsLogin",
// 注册接口
stdRegister : "/pingan_hklife_webapi/auth/stdRegister",
// 找回密码定位用户信息
gsLocateUserV2 : "/pingan_hklife_webapi/auth/gsLocateUserV2",
// 账户整合忘记密码重置用户密码
gsResetPwd : "/pingan_hklife_webapi/auth/gsResetPwd",
// 账户整合修改密码接口
gsModifyPwd : "/pingan_hklife_webapi/auth/gsModifyPwd",
// 修改密码
changePassword : "/pingan_hklife_webapi/password/change",
// 短信验证码登录
otpLogin : "/pingan_hklife_webapi/otpLogin",
// 找回密码:定位用户信息
locateUserInfo : "/pingan_hklife_webapi/reset/locateUserInfo",
// 找回密码:发送验证码
sendOtp : "/pingan_hklife_webapi/reset/sendOtp",
// 找回密码:校验验证码
checkOtp : "/pingan_hklife_webapi/reset/checkOtp",
// 找回密码:重置密码
resetPwd : "/pingan_hklife_webapi/reset/resetPwd",
}
\ No newline at end of file
......
import axiosIns from 'axios';
import state from '@/store/state.js';
// import {
// Toast
// } from 'vant';
......@@ -15,7 +16,8 @@ function Toast(msg) {
// let base = COM.baseUrl;
let base = "";
const axios = axiosIns.create({
baseURL: process.env.VUE_APP_BASE_URL || "http://localhost:9101",
// baseURL: process.env.VUE_APP_BASE_URL || "http://localhost:9101",
baseURL: "http://localhost:9101",
timeout: 5000
})
......@@ -119,11 +121,20 @@ let formDataHeaders = {
export const httpGet = params => {
let {
url,
data
data,
sid
} = params;
let headers = {};
if (sid) {
headers = {
headers : {
sid : state.userInfo.sid
}
}
}
return axios.get(`${base}${url}`, {
params: data
}).then(res => res.data.content);
}, headers).then(res => res.data.content);
}
/**
......@@ -133,9 +144,18 @@ export const httpGet = params => {
export const httpPost = params => {
let {
url,
data
data,
sid
} = params;
return axios.post(`${base}${url}`, data).then(res => res.data.content);
let headers = {};
if (sid) {
headers = {
headers : {
sid : state.userInfo.sid
}
}
}
return axios.post(`${base}${url}`, data, headers).then(res => res.data.content);
}
......
......@@ -25,7 +25,7 @@ module.exports = {
},
{
name: "modify password",
path: "",
path: "/password/reset",
type: "auth",
value: ""
},
......@@ -136,6 +136,9 @@ module.exports = {
verifyCodePlaceholder: "驗證碼",
verifyCodeGet: "獲取驗證碼",
},
session: {
sidExpire: "長時間未操作,為了您賬戶的安全,請登錄後再操作",
},
register: {
mobileOptions: [{
type: "hk",
......@@ -163,18 +166,33 @@ module.exports = {
newPasswordSurePlaceholder: "輸入登錄密碼",
sure: "確認",
},
passwordCheck: {
error1: "密碼長度不少於8位",
error2: "密碼中必須包含數字、字符以及特殊號碼",
error3: "两次密码不一致,请确认后重新输入",
error4: "密碼修改失敗,請稍後再試,或拨打客服电话95511解决",
error5: "舊密碼不正確,請重新輸入",
success: "密码修改成功"
},
passwordReset: {
oldPwd: "旧密码",
oldPwdPlaceholde: "請輸入舊密碼",
cidExpire: "長時間未操作,為了您賬戶的安全,請重新開始",
type1: {
title: "密碼找回",
t1: "用戶輸入信息",
t1Placeholder: "手機號/一賬通用戶名",
submit: "確認",
error: "您的手機號或證件號輸入錯誤,請核對后重新輸入",
},
type2: {
title: "密碼找回",
t1: "手機短信驗證碼",
t1Placeholder: "請輸入驗證碼",
submit: "確認",
error1: "短信驗證碼輸入錯誤,請核對後重新輸入",
error2: "短信驗證碼已經過期,請重新獲取驗證碼",
error3: "短信验证码发放时间少于1分钟,请稍后再试",
},
type3: {
title: "密碼找回",
......@@ -189,6 +207,8 @@ module.exports = {
t2: "確認密碼",
t2Placeholder: "請重新輸入新密碼",
submit: "確認",
error1: "密碼長度不少於8位",
error2: "密碼中必須包含數字、字符以及特殊號碼",
}
},
infomationImprove: {
......@@ -203,8 +223,8 @@ module.exports = {
t4Placeholder: "",
t5: "證件號碼",
t5Placeholder: "",
submit:"確認",
cancel:"跳過",
submit: "確認",
cancel: "跳過",
},
index: {
news: "新聞資訊",
......
......@@ -25,7 +25,7 @@ module.exports = {
},
{
name: "修改密碼",
path: "",
path: "/password/reset",
type: "auth",
value: ""
},
......@@ -163,18 +163,36 @@ module.exports = {
newPasswordSurePlaceholder: "輸入登錄密碼",
sure: "確認",
},
session: {
sidExpire: "長時間未操作,為了您賬戶的安全,請登錄後再操作",
},
passwordCheck: {
error1: "密碼長度不少於8位",
error2: "密碼中必須包含數字、字符以及特殊號碼",
error3: "兩次密碼不一致,請確認後重新輸入",
error4 : "密碼修改失敗,請稍後再試,或撥打客服電話95511解決",
error5 : "舊密碼不正確,請重新輸入",
success: "密碼修改成功"
},
passwordReset: {
oldPwd : "舊密碼",
oldPwdPlaceholde : "請輸入舊密碼",
cidExpire: "長時間未操作,為了您賬戶的安全,請重新開始",
type1: {
title: "密碼找回",
t1: "用戶輸入信息",
t1Placeholder: "手機號/一賬通用戶名",
t1Placeholder: "手機號/證件號",
submit: "確認",
error: "您的手機號或證件號輸入錯誤,請核對后重新輸入",
},
type2: {
title: "密碼找回",
t1: "手機短信驗證碼",
t1Placeholder: "請輸入驗證碼",
submit: "確認",
error1: "短信驗證碼輸入錯誤,請核對後重新輸入",
error2: "短信驗證碼已經過期,請重新獲取驗證碼",
error3: "短信驗證碼發放時間少於1分鐘,請稍後再試",
},
type3: {
title: "密碼找回",
......@@ -203,8 +221,8 @@ module.exports = {
t4Placeholder: "",
t5: "證件號碼",
t5Placeholder: "",
submit:"確認",
cancel:"跳過",
submit: "確認",
cancel: "跳過",
},
index: {
news: "新聞資訊",
......
......@@ -25,7 +25,7 @@ module.exports = {
},
{
name: "修改密码",
path: "",
path: "/password/reset",
type: "auth",
value: ""
},
......@@ -136,6 +136,9 @@ module.exports = {
verifyCodePlaceholder: "验证码",
verifyCodeGet: "获取验证码",
},
session: {
sidExpire: "长时间未操作,为了您的账户安全,请登录后再操作",
},
register: {
mobileOptions: [{
type: "hk",
......@@ -163,18 +166,33 @@ module.exports = {
newPasswordSurePlaceholder: "输入登录密码",
sure: "确认",
},
passwordCheck: {
error1: "密码长度不少于8位",
error2: "密码中必须包含数字、字符以及特殊号码",
error3: "两次密码不一致,请确认后重新输入",
error4: "密码修改失败,请稍后再试,或拨打客服电话95511解决",
error5 : "旧密码不正确,请重新输入",
success: "密码修改成功"
},
passwordReset: {
oldPwd : "旧密码",
oldPwdPlaceholde : "请输入旧密码",
cidExpire: "长时间未操作,为了您的账户安全,请重新开始",
type1: {
title: "密码找回",
t1: "用户输入信息",
t1Placeholder: "手机号/一账通用户名",
t1Placeholder: "手机号/证件号",
submit: "确认",
error: "您的手机号或证件号输入错误,请核对后重新输入",
},
type2: {
title: "密码找回",
t1: "手机短信验证码",
t1Placeholder: "请输入验证码",
submit: "确认",
error1: "短信验证码输入错误,请核对后重新输入",
error2: "短信验证码已经过期,请重新获取验证码",
error3: "短信验证码发放时间少于1分钟,请稍后再试",
},
type3: {
title: "密码找回",
......@@ -203,8 +221,8 @@ module.exports = {
t4Placeholder: "",
t5: "证件号码",
t5Placeholder: "",
submit:"确认",
cancel:"跳过",
submit: "确认",
cancel: "跳过",
},
index: {
news: "新闻资讯",
......
......@@ -45,7 +45,7 @@ export default {
// 是否显示取消按钮
showCancel: {
type: Boolean,
default: true,
default: false,
},
// 是否显示遮罩层
overlayShow: {
......
......@@ -7,8 +7,9 @@ import {
httpPost
} from '@/api/fetch-api.js'
let PK = 'B5FE03847F02046C47292AF0FF2DE88977241483DD40C123046EB39CBE4C48167B120096CFF12CD16559322884A3C56FA92B07B89AB51FC8C91A75127622151DDD730DFF1F993D5A290CEAC0BBA7FC88285D8994ACBAFF50101EDE9A0925AD5DFFAFE96D53C370E9C5B37DF2F871F81C4D7CA6B7EC37FF459C07975AD9A74A95';
let E = '10001';
import { passwordEncrypt } from '@/utils/encrypt.js';
export default {
data() {
......@@ -45,8 +46,6 @@ export default {
showImageCode: false,
agreeProtocol: false
},
PK: process.env.VUE_APP_RSA_PUBLIC_KEY || PK,
E: process.env.VUE_APP_RSA_KEY_INDEX || E,
}
},
components: {},
......@@ -76,10 +75,12 @@ export default {
onRegisterHandler() {
this.$router.push({
path: "/register"
})
});
},
onForgetHandler() {
this.$router.push({
path: "/password/find"
});
},
onLoginTypeHandler(val) {
this.type = val;
......@@ -131,7 +132,7 @@ export default {
data: {
deviceId: this.values.deviceId,
loginName: this.loginForm.userId,
loginPwd: this._passwordEncrypt(this.loginForm.password)
loginPwd: passwordEncrypt(this.loginForm.password)
}
}).then(response => {
this._handlerLoginResponse(response);
......@@ -316,13 +317,6 @@ export default {
}
return this.values.deviceId
},
_passwordEncrypt(rawPwd) {
let rsa = new RSAKey();
rsa.setPublic(this.PK, this.E);
let res = rsa.encrypt(rawPwd);
if (res == null) return rawPwd;
return res;
}
},
watch: {
type() {
......
import api from '@/api/api'
import {
httpGet,
httpPost
} from '@/api/fetch-api.js'
import modalComp from '@/components/modal-comp/modal-comp.vue';
import { passwordEncrypt } from '@/utils/encrypt.js';
export default {
data() {
return {
key: 'value',
type: 1, // 1:输入用户信息 2:找回密码 3:核对信息 4.重置密码
values: {
cid: "",
},
times: {
interval: 0, // 索引
remain: 0, // 剩余时间
tip: "" // 显示的文字
},
modalVisiable: false,
modal: {
icon: "succ",
content: "",
},
step1: {
userId: "",
error: ""
},
step2: {
idNo: ""
},
step3: {
otp: "",
error: ""
},
step4: {
pwd: "",
error1: "",
pwdRepeat: "",
error2: "",
success: false
}
}
},
components: {},
methods: {
initData() { },
i18n() {
let i18n = this.$i18n.messages[this.$i18n.locale] || {};
return i18n;
},
showModal(content, icon) {
icon = !icon || typeof icon === "undefined" ? "succ" : "succ";
this.modalIcon = icon;
this.modalContent = content;
this.modalVisiable = true;
},
locateUserInfo() {
// 定位用户信息
if (!this.step1.userId) {
this.step1.error = this.i18n().passwordReset.type1.error;
return;
}
httpPost({
url: api.locateUserInfo,
data: {
uid: this.step1.userId
}
}).then(response => {
if (response.resultCode !== "0") {
this.step1.error = this.i18n().passwordReset.type1.error;
} else {
this.values.cid = response.data.cid;
this.step2.idNo = response.data.idNo;
if (typeof this.step2.idNo == "undefined") {
this.type = 3;
} else {
this.type = 2;
}
}
});
},
sureIdNo() {
this.type = 3;
},
sendOtp() {
if (this.times.remain > 0) {
return;
}
// 定位用户
httpPost({
url: api.sendOtp,
data: {
cid: this.values.cid
}
}).then(response => {
if (this.responseHandler(response)) {
switch (response.resultCode) {
case "COMMON_ERROR_E3":
this.step2.error = this.i18n().passwordReset.type2.error3;
return;
default:
this.startTimeClick();
return;
}
}
})
},
checkOtp() {
// 发送验证码
if (!this.step3.otp) {
this.step3.error = this.i18n().passwordReset.type2.error1;
return;
}
// 定位用户
httpPost({
url: api.checkOtp,
data: {
cid: this.values.cid,
otp: this.step3.otp
}
}).then(response => {
if (this.responseHandler(response)) {
switch (response.resultCode) {
case "0":
this.type = 4;
return;
default:
// 提示驗證碼錯誤
this.step3.error = this.i18n().passwordReset.type2.error1;
return;
}
}
})
},
resetPwd() {
let c1 = this.checkPassword(this.step4.pwd);
if (c1) {
this.$set(this.step, 'error1', c1);
return;
}
if (this.step4.pwdRepeat != this.step4.pwd) {
this.step4.error2 = this.i18n().passwordCheck.error3;
return;
}
let pwd = passwordEncrypt(this.step4.pwd);
// 定位用户
httpPost({
url: api.resetPwd,
data: {
cid: this.values.cid,
password: pwd
}
}).then(response => {
if (this.responseHandler(response)) {
let message = this.i18n().passwordCheck.success;
this.step4.success = true;
switch (response.resultCode) {
case "0":
this.showModal(message, "succ");
break
default:
message = this.i18n().passwordCheck.error4;
this.showModal(message, "succ");
break;
}
}
})
},
checkPassword(password) {
if (password.length < 8) {
return this.i18n().passwordCheck.error1;
}
// 匹配字母
let m1 = /([a-z])+/.test(password);
let m2 = /([A-Z])+/.test(password);
// 匹配数字
let m3 = /([0-9])+/.test(password);
// 匹配特殊字符
let m4 = /[^a-zA-Z0-9]+/.test(password);
console.log(m1, m2, m3, m4)
if ((m1 | m2) & m3 & m4) {
return "";
} else {
return this.i18n().passwordCheck.error2
}
},
startTimeClick() {
// 開始倒計時
this.times.remain = 120;
let _this = this;
let i18n = this.$i18n.messages[this.$i18n.locale] || {};
let msg = i18n.register.coutTips;
_this.times.tip = msg.replace("{second}", _this.times.remain);
this.times.interval = setInterval(function () {
if (_this.times.remain <= 0) {
clearInterval(_this.times.interval);
_this.times.interval = 0;
_this.times.remain = 0;
return;
}
_this.times.remain--;
_this.times.tip = msg.replace("{second}", _this.times.remain);
_this.$set(_this, 'times', _this.times);
}, 1000);
},
responseHandler(response) {
switch (response.resultCode) {
case "COMMON_ERROR_E2":
// 身份过期了,请重新登录
this.values.cid = "";
this.showModal(this.i18n().passwordReset.cidExpire);
this.step2.idNo = "";
this.step3.otp = "";
this.step3.error = "";
this.step4.pwd = "";
this.step4.pwdRepeat = "";
this.step4.error1 = "";
this.step4.error2 = "";
this.step4.success = false;
this.type = 1;
return false;
default:
return true;
}
},
modalCallback() {
this.modalVisiable = false;
if (this.step4.success) {
this.$router.push({
path: "/login"
})
} else {
}
}
},
watch: {
'step1.userId': function () {
this.step1.error = "";
},
'step3.otp': function () {
this.step3.error = "";
},
'step4.pwd': function () {
console.log(this.checkPassword(this.step4.pwd));
this.$set(this.step4, 'error1', this.checkPassword(this.step4.pwd));
},
'step4.pwdRepeat': function () {
if (this.step4.pwdRepeat != this.step4.pwd) {
this.$set(this.step4, 'error2', this.i18n().passwordCheck.error3);
} else {
this.$set(this.step4, 'error2', '');
}
},
},
mounted() { },
created() { },
components: {
modalComp
}
}
@import '@/styles/_support';
.content {
position: relative;
padding-bottom: 2.25rem;
}
.top-space {
height: 2.25rem;
}
.box {
position: relative;
}
.ebg {
position: absolute;
bottom: 0;
left: 0;
right: 0;
img {
max-width: 100%;
}
}
.step {
@extend .fcc;
margin-bottom: 3rem;
}
.login {
color: #4c4948;
@extend .bb;
padding: 1.416667rem 5rem 0;
border-bottom: solid .666667rem #006441;
margin: auto;
max-width: 40.25rem;
height: 31rem;
border-radius: .75rem;
box-shadow: 0 0 1.5rem 0 rgba(255, 87, 0, 0.15);
background-color: #ffffff;
&-tit {
color: #f05a23;
text-align: center;
font-size: 18px;
font-weight: bold;
letter-spacing: .2rem;
text-shadow: 3px 5.2px 9px rgba(236, 100, 41, 0.27);
}
&-tit-space-1 {
height: 5.25rem;
}
&-tit-space-4 {
height: 3rem;
}
&-nav {
margin: 2.25rem 0 auto;
display: flex;
justify-content: center;
align-items: center;
&-v-line {
width: .2rem;
height: 1.25rem;
background-color: #4c4948;
margin: 0 2.25rem;
}
&-tit {
flex: 1;
font-size: 18px;
font-weight: bold;
color: #4c4948;
}
.active {
color: #f05a23;
text-shadow: 3px 5.2px 9px rgba(236, 100, 41, 0.27);
}
}
&-protocol {
margin: 2.5rem auto 0;
display: flex;
align-items: center;
padding-left: 1rem;
.check {
height: 1rem;
margin-right: .6rem;
}
.protocol {
color: #f05a23;
}
}
&-submit {
@include btc2(13.5rem, 4rem, 16px);
margin: 4.166667rem auto 0;
letter-spacing: 1.6px;
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
bottom: 2.25rem;
}
&-func {
margin: 1.5rem auto 0;
display: flex;
justify-content: center;
&-btn {
margin: 0 1.25rem;
text-decoration: underline;
}
}
}
.form {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.vcode {
background-color: transparent !important;
padding: 0 !important;
overflow: hidden;
img {
width: 100%;
height: 100%;
}
}
input {
font-size: 1.166667rem;
letter-spacing: .1rem;
}
&-item {
position: relative;
margin-bottom: 2.25rem;
.label {
font-size: 18px;
font-weight: bold;
color: #f05a23;
display: flex;
align-items: center;
margin-bottom: 1.25rem;
img {
height: 1.5rem;
margin-right: .8rem;
}
}
.ipt-wrap {
position: relative;
display: flex;
justify-content: space-between;
// input和下拉
.ipt {
@extend .bb;
width: 100%;
height: 3.5rem;
border: solid 1px #dcdddd;
background-color: #ffffff;
border-radius: 3.5rem;
padding: 0 1.75rem;
flex: 1;
}
// 长文本
.textarea {
min-height: 8.75rem;
border-radius: 1rem;
}
.down-arrow {
position: absolute;
top: 1.6rem;
right: 2rem;
}
.verify-btn {
@extend .fcc;
// font-family: Arial;
font-size: 18px;
width: 8.5rem;
border: solid 1px #dcdddd;
background-color: #f2f2f2;
flex: none;
margin-left: 1.5rem;
color: #4c4948;
}
// 框内按钮
.ipt2 {
display: flex;
justify-content: space-between;
align-items: center;
.ipt-tel {
flex: 1;
padding-left: 1.75rem;
}
.ipt-code {
flex: 1;
padding-right: 1.75rem;
}
.region-tel {}
.veri-btn {
color: #f05a23;
text-decoration: underline;
}
.veri-btn-default {
color: #aaaaaa;
}
}
}
.validator {
color: $cOrange;
margin-top: 0.5rem;
position: absolute;
right: .5rem;
display: flex;
align-items: center;
img {
display: inline-block;
margin-right: 0.4rem;
}
}
}
}
@media (max-width: 950px) {
.box {
width: 96%;
}
.login {
padding: 2rem 1rem 3.5rem;
}
}
.disable {
background-color: #dcdddd !important;
// color: $cFontGray;
color: #4c4948;
}
<template>
<div class="content">
<modal-comp :visible="modalVisiable" :show-confirm="false" :icon="modalIcon" :content="modalContent" :confirm="modalCallback" :overlay="modalCallback"></modal-comp>
<div class="ebg">
<img src="@/assets/images/password-reset/password-reset-bg.png">
</div>
<div class="top-space"></div>
<div class="box">
<!-- 输入用户信息 -->
<div v-if="type == 1" class="login">
<div class="login-tit">{{$t('passwordReset.type1.title')}}</div>
<div class="login-tit-space-1"></div>
<div class="gird-g form">
<div class="pure-u-1 form-item">
<div class="label">
<img src="@/assets/images/register/icon-register-phone.png"> {{$t('passwordReset.type1.t1')}}
</div>
<div class="ipt-wrap">
<input :placeholder="$t('passwordReset.type1.t1Placeholder')" class="ipt" type="text" v-model="step1.userId">
</div>
<div class="validator" v-if="step1.error.length > 0 ">
<img src="@/assets/images/common/icon-notice.png" alt=""> {{step1.error}}
</div>
</div>
</div>
<div @click="locateUserInfo()" class="login-submit pointer">{{$t('passwordReset.type1.submit')}}</div>
</div>
<!-- 核对信息 -->
<div v-if="type == 2" class="login">
<div class="login-tit">{{$t('passwordReset.type3.title')}}</div>
<div class="login-tit-space-1"></div>
<div class="gird-g form">
<div class="pure-u-1 form-item">
<div class="label">
<img src="@/assets/images/register/icon-register-phone.png"> {{$t('passwordReset.type3.t1')}}
</div>
<div class="ipt-wrap">
<input class="ipt disable" type="text" v-model="step2.idNo">
</div>
</div>
</div>
<div @click="sureIdNo()" class="login-submit pointer">{{$t('passwordReset.type3.submit')}}</div>
</div>
<!-- 找回密码 -->
<div v-if="type == 3" class="login">
<div class="login-tit">{{$t('passwordReset.type2.title')}}</div>
<div class="login-tit-space-1"></div>
<div class="gird-g form">
<div class="pure-u-1 form-item">
<div class="label">
<img src="@/assets/images/register/icon-register-phone.png"> {{$t('passwordReset.type2.t1Placeholder')}}
</div>
<div class="ipt-wrap">
<div class="ipt ipt2">
<input :placeholder="$t('passwordReset.type2.t1Placeholder')" type="text" v-model="step3.otp">
<div v-if="times.remain == 0" class="veri-btn pointer" @click="sendOtp" >{{$t('register.verifyCodeGet')}}</div>
<div v-else class="veri-btn-default">{{times.tip}}</div>
</div>
</div>
<div class="validator" v-if="step3.error.length > 0 ">
<img src="@/assets/images/common/icon-notice.png" alt=""> {{step3.error}}
</div>
</div>
</div>
<div @click="checkOtp()" class="login-submit pointer">{{$t('passwordReset.type2.submit')}}</div>
</div>
<!-- 重置密码 -->
<div v-if="type == 4" class="login">
<div class="login-tit">{{$t('passwordReset.type4.title')}}</div>
<div class="login-tit-space-4"></div>
<div class="gird-g form">
<div class="pure-u-1 form-item">
<div class="label">
<img src="@/assets/images/register/icon-register-lock.png"> {{$t('passwordReset.type4.t1')}}
</div>
<div class="ipt-wrap">
<input :placeholder="$t('passwordReset.type4.t1Placeholder')" class="ipt" type="password" v-model="step4.pwd">
</div>
<div class="validator" v-if="step4.error1.length > 0 ">
<img src="@/assets/images/common/icon-notice.png" alt=""> {{step4.error1}}
</div>
</div>
<div class="pure-u-1 form-item">
<div class="label">
<img src="@/assets/images/register/icon-register-lock.png"> {{$t('passwordReset.type4.t2')}}
</div>
<div class="ipt-wrap">
<input :placeholder="$t('passwordReset.type4.t2Placeholder')" class="ipt" type="password" v-model="step4.pwdRepeat">
</div>
<div class="validator" v-if="step4.error2.length > 0 ">
<img src="@/assets/images/common/icon-notice.png" alt=""> {{step4.error2}}
</div>
</div>
</div>
<div @click="resetPwd()" class="login-submit pointer">{{$t('passwordReset.type4.submit')}}</div>
</div>
</div>
</div>
</template>
<script src="./password-find.js"></script>
<style lang="scss" scoped>
@import "./password-find.scss";
</style>
import { mapGetters, mapActions, mapState } from "vuex";
import api from '@/api/api'
import {
httpGet,
httpPost
} from '@/api/fetch-api.js'
import modalComp from '@/components/modal-comp/modal-comp.vue';
import { passwordEncrypt } from '@/utils/encrypt.js';
export default {
data() {
return {
key: 'value',
type: 4, // 1:输入用户信息 2:找回密码 3:核对信息 4.重置密码
values: {
// 返回的token,串连整个流程,后台安全校验使用
vcodeuuid: "",
token: "",
deviceId: "",
imageBase64: "",
password: "",
passwordRepeat: ""
cid: "",
oldPwd: "",
pwd: "",
pwdRepeat: ""
},
}
step: {
error0: "",
error1: "",
error2: "",
},
components: {},
computed: {
locale() {
return this.$i18n.locale || 'tc';
times: {
interval: 0, // 索引
remain: 0, // 剩余时间
tip: "" // 显示的文字
},
i18n() {
return this.$i18n.messages && this.$i18n.locale ? this.$i18n.messages[this.$i18n.locale] : {};
modalVisiable: false,
targetPath: "",
modalIcon: "succ",
modalContent: ""
}
},
methods: {
initData() {}
initData() { },
i18n() {
let i18n = this.$i18n.messages[this.$i18n.locale] || {};
return i18n;
},
showModal(content, icon) {
icon = !icon || typeof icon === "undefined" ? "succ" : "succ";
this.modalIcon = icon;
this.modalContent = content;
this.modalVisiable = true;
},
resetPwd() {
if (!this.values.oldPwd) {
this.step.error0 = this.i18n().passwordReset.oldPwdPlaceholde;
return;
}
let c1 = this.checkPassword(this.values.pwd);
if (c1) {
this.$set(this.step, 'error1', c1);
return;
}
if (this.values.pwdRepeat != this.values.pwd) {
this.step.error2 = this.i18n().passwordCheck.error3;
return;
}
let newPwd = passwordEncrypt(this.values.pwd);
let oldPwd = passwordEncrypt(this.values.oldPwd);
httpPost({
url: api.changePassword,
data: {
oldPwd: oldPwd,
newPwd: newPwd
},
sid: true
}).then(response => {
this.targetPath = "";
let message = this.i18n().passwordCheck.success;
switch (response.resultCode) {
case "0":
this.targetPath = "";
this.showModal(message, "succ");
break
case "COMMON_ERROR_E0":
message = this.i18n().session.sidExpire;
this.targetPath = "/login?callback=/password/reset";
this.showModal(message, "info");
break;
default:
this.step.error0 = this.i18n().passwordCheck.error5;
break;
}
}).catch(err => {
let message = this.i18n().session.sidExpire;
this.targetPath = "/login?callback=/password/reset";
this.showModal(message, "info");
});
},
checkPassword(password) {
if (password.length < 8) {
return this.i18n().passwordCheck.error1;
}
// 匹配字母
let m1 = /([a-z])+/.test(password);
let m2 = /([A-Z])+/.test(password);
// 匹配数字
let m3 = /([0-9])+/.test(password);
// 匹配特殊字符
let m4 = /[^a-zA-Z0-9]+/.test(password);
if ((m1 | m2) & m3 & m4) {
return "";
} else {
return this.i18n().passwordCheck.error2
}
},
modalCallback() {
this.modalVisiable = false;
if (this.targetPath) {
this.$router.push({
"path": this.targetPath
});
}
}
},
watch: {
'values.oldPwd': function () {
this.$set(this.step, 'error0', '');
},
mounted() {},
created() {}
'values.pwd': function () {
this.$set(this.step, 'error1', this.checkPassword(this.values.pwd));
},
'values.pwdRepeat': function () {
if (this.values.pwdRepeat != this.values.pwd) {
this.$set(this.step, 'error2', this.i18n().passwordCheck.error3);
} else {
this.$set(this.step, 'error2', '');
}
},
},
mounted() { },
created() { },
components: {
modalComp
}
}
......
......@@ -37,7 +37,7 @@
margin: auto;
max-width: 40.25rem;
height: 31rem;
height: 41rem;
border-radius: .75rem;
box-shadow: 0 0 1.5rem 0 rgba(255, 87, 0, 0.15);
......
<template>
<div class="content">
<modal-comp :visible="modalVisiable" :show-confirm="false" :icon="modalIcon" :content="modalContent" :confirm="modalCallback" :overlay="modalCallback"></modal-comp>
<div class="ebg">
<img src="@/assets/images/password-reset/password-reset-bg.png">
</div>
<div class="top-space"></div>
<div class="box">
<!-- 输入用户信息 -->
<div v-if="type == 1" class="login">
<div class="login-tit">{{$t('passwordReset.type1.title')}}</div>
<div class="login-tit-space-1"></div>
<div class="gird-g form">
<div class="pure-u-1 form-item">
<div class="label">
<img src="@/assets/images/register/icon-register-phone.png"> {{$t('passwordReset.type1.t1')}}
</div>
<div class="ipt-wrap">
<input :placeholder="$t('passwordReset.type1.t1Placeholder')" class="ipt" type="password" v-model="values.password">
</div>
<div class="validator">
<img src="@/assets/images/common/icon-notice.png" alt=""> 验证提示
</div>
</div>
</div>
<div @click="onRegisterHandler()" class="login-submit pointer">{{$t('passwordReset.type1.submit')}}</div>
</div>
<!-- 找回密码 -->
<div v-if="type == 2" class="login">
<div class="login-tit">{{$t('passwordReset.type2.title')}}</div>
<div class="login-tit-space-1"></div>
<div class="gird-g form">
<div class="pure-u-1 form-item">
<div class="label">
<img src="@/assets/images/register/icon-register-phone.png"> {{$t('passwordReset.type2.t1Placeholder')}}
</div>
<div class="ipt-wrap">
<input :placeholder="$t('passwordReset.type2.t1Placeholder')" class="ipt" type="password" v-model="values.password">
</div>
<div class="validator">
<img src="@/assets/images/common/icon-notice.png" alt=""> 验证提示
</div>
</div>
</div>
<div @click="onRegisterHandler()" class="login-submit pointer">{{$t('passwordReset.type2.submit')}}</div>
</div>
<!-- 核对信息 -->
<div v-if="type == 3" class="login">
<div class="login-tit">{{$t('passwordReset.type3.title')}}</div>
<div class="login-tit-space-1"></div>
<div class="login">
<div class="login-tit">{{$t('passwordReset.type4.title')}}</div>
<div class="login-tit-space-4"></div>
<div class="gird-g form">
<div class="pure-u-1 form-item">
<div class="label">
<img src="@/assets/images/register/icon-register-phone.png"> {{$t('passwordReset.type3.t1')}}
<img src="@/assets/images/register/icon-register-lock.png"> {{$t('passwordReset.oldPwd')}}
</div>
<div class="ipt-wrap">
<input class="ipt disable" type="password" v-model="values.password">
<input :placeholder="$t('passwordReset.oldPwdPlaceholde')" class="ipt" type="password" v-model="values.oldPwd">
</div>
<div class="validator" v-if="step.error0.length > 0 ">
<img src="@/assets/images/common/icon-notice.png" alt=""> {{step.error0}}
</div>
</div>
<div @click="onRegisterHandler()" class="login-submit pointer">{{$t('passwordReset.type3.submit')}}</div>
</div>
<!-- 重置密码 -->
<div v-if="type == 4" class="login">
<div class="login-tit">{{$t('passwordReset.type4.title')}}</div>
<div class="login-tit-space-4"></div>
<div class="gird-g form">
<div class="pure-u-1 form-item">
<div class="label">
<img src="@/assets/images/register/icon-register-lock.png"> {{$t('passwordReset.type4.t1')}}
</div>
<div class="ipt-wrap">
<input :placeholder="$t('passwordReset.type4.t1Placeholder')" class="ipt" type="password" v-model="values.password">
<input :placeholder="$t('passwordReset.type4.t1Placeholder')" class="ipt" type="password" v-model="values.pwd">
</div>
<div class="validator">
<img src="@/assets/images/common/icon-notice.png" alt=""> 验证提示
<div class="validator" v-if="step.error1.length > 0 ">
<img src="@/assets/images/common/icon-notice.png" alt=""> {{step.error1}}
</div>
</div>
<div class="pure-u-1 form-item">
......@@ -85,14 +38,14 @@
<img src="@/assets/images/register/icon-register-lock.png"> {{$t('passwordReset.type4.t2')}}
</div>
<div class="ipt-wrap">
<input :placeholder="$t('passwordReset.type4.t2Placeholder')" class="ipt" type="password" v-model="values.passwordRepeat">
<input :placeholder="$t('passwordReset.type4.t2Placeholder')" class="ipt" type="password" v-model="values.pwdRepeat">
</div>
<div class="validator">
<img src="@/assets/images/common/icon-notice.png" alt=""> 验证提示
<div class="validator" v-if="step.error2.length > 0 ">
<img src="@/assets/images/common/icon-notice.png" alt=""> {{step.error2}}
</div>
</div>
</div>
<div @click="onRegisterHandler()" class="login-submit pointer">{{$t('passwordReset.type4.submit')}}</div>
<div @click="resetPwd()" class="login-submit pointer">{{$t('passwordReset.type4.submit')}}</div>
</div>
</div>
</div>
......
......@@ -4,14 +4,13 @@ import {
httpPost
} from '@/api/fetch-api.js'
let PK = 'B5FE03847F02046C47292AF0FF2DE88977241483DD40C123046EB39CBE4C48167B120096CFF12CD16559322884A3C56FA92B07B89AB51FC8C91A75127622151DDD730DFF1F993D5A290CEAC0BBA7FC88285D8994ACBAFF50101EDE9A0925AD5DFFAFE96D53C370E9C5B37DF2F871F81C4D7CA6B7EC37FF459C07975AD9A74A95';
let E = '10001';
import { passwordEncrypt } from '@/utils/encrypt.js';
export default {
data() {
return {
key: 'value',
type: 2, // 1:手机验证 2:输入密码
type: 1, // 1:手机验证 2:输入密码
mobileNoType: "hk",// 选择的手机好类型
mobileTip: {},
mobileOptions: [],
......@@ -39,8 +38,6 @@ export default {
remain: 0, // 剩余时间
tip: "" // 显示的文字
},
PK: process.env.VUE_APP_RSA_PUBLIC_KEY || PK,
E: process.env.VUE_APP_RSA_KEY_INDEX || E,
}
},
components: {},
......@@ -271,7 +268,7 @@ export default {
let data = {
token: this.values.token,
mobileNo: this.registerForm.mobileNo,
loginPwd: this._passwordEncrypt(this.values.password)
loginPwd: passwordEncrypt(this.values.password)
};
httpPost({
url: api.stdRegister,
......@@ -378,13 +375,6 @@ export default {
onLoginTypeHandler(val) {
},
_passwordEncrypt(rawPwd) {
let rsa = new RSAKey();
rsa.setPublic(this.PK, this.E);
let res = rsa.encrypt(rawPwd);
if (res == null) return rawPwd;
return res;
},
initData() {
let i18n = this.$i18n.messages[this.$i18n.locale] || {};
let mobileOptions = JSON.parse(JSON.stringify(i18n.register.mobileOptions));
......
......@@ -39,6 +39,14 @@ const routes = [
}
},
{
path: '/password/find',
name: 'passwordFind',
component: () => import('./pages/password-find/password-find.vue'),
meta: {
title: ''
}
},
{
path: '/password/reset',
name: 'passwordReset',
component: () => import('./pages/password-reset/password-reset.vue'),
......
let PK = 'B5FE03847F02046C47292AF0FF2DE88977241483DD40C123046EB39CBE4C48167B120096CFF12CD16559322884A3C56FA92B07B89AB51FC8C91A75127622151DDD730DFF1F993D5A290CEAC0BBA7FC88285D8994ACBAFF50101EDE9A0925AD5DFFAFE96D53C370E9C5B37DF2F871F81C4D7CA6B7EC37FF459C07975AD9A74A95';
let E = '10001';
PK = process.env.VUE_APP_RSA_PUBLIC_KEY || PK;
E = process.env.VUE_APP_RSA_KEY_INDEX || E;
function passwordEncrypt(rawPwd) {
let rsa = new RSAKey();
// console.log("rsa === ", rsa);
rsa.setPublic(PK, E);
let res = rsa.encrypt(rawPwd);
// console.log("res === ", res);
if (res == null) return rawPwd;
return res;
}
module.exports = {
passwordEncrypt: passwordEncrypt
}
\ No newline at end of file