feat: 修改密码
This commit is contained in:
parent
b24569fe4b
commit
a0b23df39d
|
@ -1,6 +1,7 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
|
||||||
const mycourseApi = {
|
const mycourseApi = {
|
||||||
|
changePassword: '/sys/user/changePwd',
|
||||||
mycourseList: 'myCourse/getMyCourseList', // 我的课程列表,课程搜索
|
mycourseList: 'myCourse/getMyCourseList', // 我的课程列表,课程搜索
|
||||||
addMyCourse: 'myCourse/addMyCourse', // 添加课程
|
addMyCourse: 'myCourse/addMyCourse', // 添加课程
|
||||||
centerList: 'focused/training/list', // 集中培训列表
|
centerList: 'focused/training/list', // 集中培训列表
|
||||||
|
@ -20,6 +21,14 @@ const mycourseApi = {
|
||||||
getMyCourseList: 'studyStatistics/getMyCourseList' // 课程学习统计
|
getMyCourseList: 'studyStatistics/getMyCourseList' // 课程学习统计
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function reqChangePassword (data) {
|
||||||
|
return request({
|
||||||
|
url: mycourseApi.changePassword,
|
||||||
|
method: 'get',
|
||||||
|
params: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export function reqCenterJoin (data) {
|
export function reqCenterJoin (data) {
|
||||||
return request({
|
return request({
|
||||||
url: mycourseApi.centerJoin,
|
url: mycourseApi.centerJoin,
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<a-dropdown v-if="currentUser && currentUser.name" placement="bottomRight">
|
<div>
|
||||||
<span class="ant-pro-account-avatar">
|
<a-dropdown v-if="currentUser && currentUser.name" placement="bottomRight">
|
||||||
<a-avatar size="small" src="https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png" class="antd-pro-global-header-index-avatar" />
|
<span class="ant-pro-account-avatar">
|
||||||
<span>{{ currentUser.name }}</span>
|
<a-avatar
|
||||||
</span>
|
size="small"
|
||||||
<template v-slot:overlay>
|
src="https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png"
|
||||||
<a-menu class="ant-pro-drop-down menu" :selected-keys="[]">
|
class="antd-pro-global-header-index-avatar"
|
||||||
<!-- <a-menu-item v-if="menu" key="center" @click="handleToCenter">
|
/>
|
||||||
|
<span>{{ currentUser.name }}</span>
|
||||||
|
</span>
|
||||||
|
<template v-slot:overlay>
|
||||||
|
<a-menu class="ant-pro-drop-down menu" :selected-keys="[]">
|
||||||
|
<!-- <a-menu-item v-if="menu" key="center" @click="handleToCenter">
|
||||||
<a-icon type="user" />
|
<a-icon type="user" />
|
||||||
个人中心
|
个人中心
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
|
@ -15,23 +20,31 @@
|
||||||
个人设置
|
个人设置
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
<a-menu-divider v-if="menu" />-->
|
<a-menu-divider v-if="menu" />-->
|
||||||
<a-menu-item key="logout" @click="handleLogout">
|
<a-menu-item key="password" @click="handlerChangePassword">
|
||||||
<a-icon type="logout" />
|
<a-icon type="lock" />
|
||||||
退出登录
|
修改密码
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
</a-menu>
|
<a-menu-item key="logout" @click="handleLogout">
|
||||||
</template>
|
<a-icon type="logout" />
|
||||||
</a-dropdown>
|
退出登录
|
||||||
<span v-else>
|
</a-menu-item>
|
||||||
<a-spin size="small" :style="{ marginLeft: 8, marginRight: 8 }" />
|
</a-menu>
|
||||||
</span>
|
</template>
|
||||||
|
</a-dropdown>
|
||||||
|
<span v-else>
|
||||||
|
<a-spin size="small" :style="{ marginLeft: 8, marginRight: 8 }" />
|
||||||
|
</span>
|
||||||
|
<ChangePassword ref="changePassword"></ChangePassword>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Modal } from 'ant-design-vue'
|
import { Modal } from 'ant-design-vue'
|
||||||
|
import ChangePassword from '@/components/GlobalHeader/ChangePassword.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AvatarDropdown',
|
name: 'AvatarDropdown',
|
||||||
|
components: { ChangePassword },
|
||||||
props: {
|
props: {
|
||||||
currentUser: {
|
currentUser: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -43,6 +56,10 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 修改密码
|
||||||
|
handlerChangePassword () {
|
||||||
|
this.$refs.changePassword.show()
|
||||||
|
},
|
||||||
handleToCenter () {
|
handleToCenter () {
|
||||||
this.$router.push({ path: '/account/center' })
|
this.$router.push({ path: '/account/center' })
|
||||||
},
|
},
|
||||||
|
@ -54,14 +71,11 @@ export default {
|
||||||
title: this.$t('layouts.usermenu.dialog.title'),
|
title: this.$t('layouts.usermenu.dialog.title'),
|
||||||
content: this.$t('layouts.usermenu.dialog.content'),
|
content: this.$t('layouts.usermenu.dialog.content'),
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
// return new Promise((resolve, reject) => {
|
|
||||||
// setTimeout(Math.random() > 0.5 ? resolve : reject, 1500)
|
|
||||||
// }).catch(() => console.log('Oops errors!'))
|
|
||||||
return this.$store.dispatch('Logout').then(() => {
|
return this.$store.dispatch('Logout').then(() => {
|
||||||
this.$router.push({ name: 'login' })
|
this.$router.push({ name: 'login' })
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
onCancel () { }
|
onCancel () {}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,280 @@
|
||||||
|
<!-- 作者:cgd 邮箱:349008059@qq.com 时间:2022年02月24日 16:54:58 -->
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
title="修改密码"
|
||||||
|
:width="500"
|
||||||
|
v-model="visible"
|
||||||
|
:confirmLoading="confirmLoading"
|
||||||
|
:footer="null"
|
||||||
|
>
|
||||||
|
<a-form ref="formRegister" :form="form" id="formRegister">
|
||||||
|
<a-form-item>
|
||||||
|
<a-input
|
||||||
|
size="large"
|
||||||
|
type="text"
|
||||||
|
placeholder="用户名"
|
||||||
|
:value="$store.state.user.person.userName"
|
||||||
|
disabled
|
||||||
|
></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item>
|
||||||
|
<a-input
|
||||||
|
size="large"
|
||||||
|
type="password"
|
||||||
|
placeholder="请输入密码"
|
||||||
|
v-decorator="[
|
||||||
|
'oldPassword',
|
||||||
|
{
|
||||||
|
rules: [{ required: true, message: '请输入密码' }],
|
||||||
|
validateTrigger: ['change', 'blur'],
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-popover
|
||||||
|
placement="rightTop"
|
||||||
|
:trigger="['focus', 'click']"
|
||||||
|
:getPopupContainer="trigger => trigger.parentElement"
|
||||||
|
v-model="state.passwordLevelChecked"
|
||||||
|
>
|
||||||
|
<template slot="content">
|
||||||
|
<div :style="{ width: '240px' }">
|
||||||
|
<div :class="['user-register', passwordLevelClass]">
|
||||||
|
强度:
|
||||||
|
<span>{{ passwordLevelName }}</span>
|
||||||
|
</div>
|
||||||
|
<a-progress
|
||||||
|
:percent="state.percent"
|
||||||
|
:showInfo="false"
|
||||||
|
:strokeColor="passwordLevelColor"
|
||||||
|
/>
|
||||||
|
<div style="margin-top: 10px;">
|
||||||
|
<span>请输入至少包括大写、小写、数字、特殊符号中的三种,密码长度至少为8位。</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<a-form-item>
|
||||||
|
<a-input-password
|
||||||
|
size="large"
|
||||||
|
@click="handlePasswordInputClick"
|
||||||
|
placeholder="请输入新密码"
|
||||||
|
v-decorator="[
|
||||||
|
'password',
|
||||||
|
{
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message:
|
||||||
|
'请输入至少包括大写、小写、数字、特殊符号中的三种,密码长度至少为8位。',
|
||||||
|
},
|
||||||
|
{ validator: this.handlePasswordLevel },
|
||||||
|
],
|
||||||
|
validateTrigger: ['change', 'blur'],
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
></a-input-password>
|
||||||
|
</a-form-item>
|
||||||
|
</a-popover>
|
||||||
|
<a-form-item>
|
||||||
|
<a-input-password
|
||||||
|
size="large"
|
||||||
|
placeholder="请在此输入新的密码"
|
||||||
|
v-decorator="[
|
||||||
|
'password2',
|
||||||
|
{
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入至少包括大写、小写、数字、特殊符号中的三种,密码长度至少为8位。',
|
||||||
|
},
|
||||||
|
{ validator: this.handlePasswordCheck },
|
||||||
|
],
|
||||||
|
validateTrigger: ['change', 'blur'],
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
></a-input-password>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item style="text-align: center;">
|
||||||
|
<a-button
|
||||||
|
:loading="btnLoading"
|
||||||
|
@click.stop.prevent="handleSubmit"
|
||||||
|
size="large"
|
||||||
|
type="primary"
|
||||||
|
htmlType="submit"
|
||||||
|
class="register-button"
|
||||||
|
>
|
||||||
|
修改密码
|
||||||
|
</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const levelNames = {
|
||||||
|
0: '低',
|
||||||
|
1: '低',
|
||||||
|
2: '中',
|
||||||
|
3: '强',
|
||||||
|
4: '极强'
|
||||||
|
}
|
||||||
|
const levelClass = {
|
||||||
|
0: 'error',
|
||||||
|
1: 'error',
|
||||||
|
2: 'warning',
|
||||||
|
3: 'success'
|
||||||
|
}
|
||||||
|
const levelColor = {
|
||||||
|
0: '#ff0000',
|
||||||
|
1: '#ff0000',
|
||||||
|
2: '#ff7e05',
|
||||||
|
3: '#52c41a'
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
btnLoading: false,
|
||||||
|
form: this.$form.createForm(this),
|
||||||
|
state: {
|
||||||
|
time: 60,
|
||||||
|
smsSendBtn: false,
|
||||||
|
passwordLevel: 0,
|
||||||
|
passwordLevelChecked: false,
|
||||||
|
percent: 10,
|
||||||
|
progressColor: '#FF0000'
|
||||||
|
},
|
||||||
|
visible: false,
|
||||||
|
confirmLoading: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
passwordLevelClass () {
|
||||||
|
return levelClass[this.state.passwordLevel]
|
||||||
|
},
|
||||||
|
passwordLevelName () {
|
||||||
|
return levelNames[this.state.passwordLevel]
|
||||||
|
},
|
||||||
|
passwordLevelColor () {
|
||||||
|
return levelColor[this.state.passwordLevel]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {},
|
||||||
|
methods: {
|
||||||
|
show () {
|
||||||
|
this.visible = true
|
||||||
|
},
|
||||||
|
handlePasswordLevel (rule, value, callback) {
|
||||||
|
let level = 0
|
||||||
|
|
||||||
|
// 判断这个字符串中有没有数字
|
||||||
|
if (/[0-9]/.test(value)) {
|
||||||
|
level++
|
||||||
|
}
|
||||||
|
if (/[a-z]/.test(value)) {
|
||||||
|
level++
|
||||||
|
}
|
||||||
|
if (/[A-Z]/.test(value)) {
|
||||||
|
level++
|
||||||
|
}
|
||||||
|
// 判断字符串中有没有特殊符号
|
||||||
|
if (/[^0-9a-zA-Z]/.test(value)) {
|
||||||
|
level++
|
||||||
|
}
|
||||||
|
this.state.passwordLevel = level
|
||||||
|
this.state.percent = level * 25
|
||||||
|
if (level >= 3) {
|
||||||
|
if (level >= 4) {
|
||||||
|
this.state.percent = 100
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
} else {
|
||||||
|
if (level === 0) {
|
||||||
|
this.state.percent = 10
|
||||||
|
}
|
||||||
|
callback(new Error('密码强度不够'))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handlePasswordCheck (rule, value, callback) {
|
||||||
|
const password = this.form.getFieldValue('password')
|
||||||
|
console.log('value', value)
|
||||||
|
if (value === undefined) {
|
||||||
|
callback(new Error('请输入密码'))
|
||||||
|
}
|
||||||
|
if (value && password && value.trim() !== password.trim()) {
|
||||||
|
callback(new Error('两次密码不一致'))
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
},
|
||||||
|
handlePasswordInputClick () {
|
||||||
|
this.state.passwordLevelChecked = false
|
||||||
|
},
|
||||||
|
handleSubmit () {
|
||||||
|
const {
|
||||||
|
form: { validateFields },
|
||||||
|
state
|
||||||
|
} = this
|
||||||
|
validateFields({ force: true }, (err, values) => {
|
||||||
|
if (!err) {
|
||||||
|
this.btnLoading = true
|
||||||
|
state.passwordLevelChecked = false
|
||||||
|
this.$store.dispatch('ChangePassword', values).then(res => {
|
||||||
|
this.btnLoading = false
|
||||||
|
this.$message.success('修改密码成功')
|
||||||
|
this.$store.dispatch('Logout').then(() => {
|
||||||
|
this.$router.push({ name: 'login' })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="less">
|
||||||
|
.user-register {
|
||||||
|
&.error {
|
||||||
|
color: #ff0000;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
color: #ff7e05;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.success {
|
||||||
|
color: #52c41a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-layout-register {
|
||||||
|
.ant-input-group-addon:first-child {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.user-layout-register {
|
||||||
|
& > h3 {
|
||||||
|
font-size: 16px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.getCaptcha {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.register-button {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login {
|
||||||
|
float: right;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,5 +1,6 @@
|
||||||
import storage from 'store'
|
import storage from 'store'
|
||||||
import { login, getLoginUser, logout } from '@/api/login'
|
import { login, getLoginUser, logout } from '@/api/login'
|
||||||
|
import { reqChangePassword } from '@/api/mycourse/index'
|
||||||
import { ACCESS_TOKEN } from '@/store/mutation-types'
|
import { ACCESS_TOKEN } from '@/store/mutation-types'
|
||||||
import { welcome } from '@/utils/util'
|
import { welcome } from '@/utils/util'
|
||||||
|
|
||||||
|
@ -81,7 +82,21 @@ const user = {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
// 修改密码
|
||||||
|
ChangePassword ({ state }, data) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
reqChangePassword({
|
||||||
|
oldPassword: data.oldPassword,
|
||||||
|
password: data.password
|
||||||
|
}).then(res => {
|
||||||
|
resolve(res)
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
reject(error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
// 登出
|
// 登出
|
||||||
Logout ({ commit, state }) {
|
Logout ({ commit, state }) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
|
|
@ -116,7 +116,6 @@ export default {
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
form: this.$form.createForm(this),
|
form: this.$form.createForm(this),
|
||||||
|
|
||||||
state: {
|
state: {
|
||||||
time: 60,
|
time: 60,
|
||||||
smsSendBtn: false,
|
smsSendBtn: false,
|
||||||
|
|
Loading…
Reference in New Issue