加入修改单位密码功能;

加入登录背景图;
修改部分细节
This commit is contained in:
471615499@qq.com 2024-10-30 20:37:38 +08:00
parent 34563b19e6
commit a3f2edf6a9
7 changed files with 361 additions and 140 deletions

View File

@ -31,4 +31,17 @@ export function delMeetingUto (parameter) {
})
}
/**
* 更改单位密码
* @param parameter
* @returns {AxiosPromise}
*/
export function changePswd(parameter) {
return axios({
url: '/admin/mr/changePswd',
method: 'post',
data: parameter
})
}
export const meetingUtoExport = api.meetingUto + '/export'

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 KiB

View File

@ -6,7 +6,7 @@
</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-menu-item v-if="menu" key="center" @click="handleToCenter" style='display: none'>
<a-icon type="user" />{{ i18nRender('menu.account.center') }}
</a-menu-item>
<a-menu-item v-if="menu" key="settings" @click="handleToSettings">

View File

@ -0,0 +1,176 @@
<template>
<div class="account-settings-info-view">
<a-row :gutter="16">
<a-col :md="24" :lg="16">
<a-form @submit="handleSubmit" :form="form" layout="vertical">
<a-form-item>
<a-input-password placeholder="单位帐号" v-decorator="['loginName', {rules: [{ required: true, message: '请选录入旧密码' }]}]"/>
</a-form-item>
<a-form-item>
<a-input-password placeholder="旧密码" v-decorator="['password', {rules: [{ required: true, message: '请选录入旧密码' }]}]"/>
</a-form-item>
<a-popover
placement="rightTop"
:trigger="['focus']"
: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>请至少输入 6 个字符请不要使用容易被猜到的密码</span>
</div>
</div>
</template>
<a-form-item>
<a-input-password
@click="handlePasswordInputClick"
placeholder="新密码至少6位密码区分大小写"
v-decorator="['newPassword', {rules: [{ required: true, message: '新密码至少6位密码区分大小写'}, { validator: this.handlePasswordLevel }], validateTrigger: ['change', 'blur']}]"
></a-input-password>
</a-form-item>
</a-popover>
<a-form-item>
<a-input-password
placeholder="重复新密码"
v-decorator="['rePassword', {rules: [{ required: true, message: '新密码至少6位密码区分大小写' }, { validator: this.handlePasswordCheck }], validateTrigger: ['change', 'blur']}]"
></a-input-password>
</a-form-item>
<a-form-item>
<a-button htmlType="submit" type="primary">修改密码</a-button>
</a-form-item>
</a-form>
</a-col>
</a-row>
</div>
</template>
<script>
import { changePswd } from '@/api/admin/meeting/uto'
const levelNames = {
0: '低',
1: '低',
2: '中',
3: '强'
}
const levelClass = {
0: 'error',
1: 'error',
2: 'warning',
3: 'success'
}
const levelColor = {
0: '#ff0000',
1: '#ff0000',
2: '#ff7e05',
3: '#52c41a'
}
export default {
data () {
return {
state: {
passwordLevel: 0,
passwordLevelChecked: false,
percent: 10
},
form: this.$form.createForm(this)
}
},
computed: {
passwordLevelClass () {
return levelClass[this.state.passwordLevel]
},
passwordLevelName () {
return levelNames[this.state.passwordLevel]
},
passwordLevelColor () {
return levelColor[this.state.passwordLevel]
}
},
methods: {
handlePasswordLevel (rule, value, callback) {
let level = 0
//
if (/[0-9]/.test(value)) {
level++
}
//
if (/[a-zA-Z]/.test(value)) {
level++
}
//
if (/[^0-9a-zA-Z_]/.test(value)) {
level++
}
this.state.passwordLevel = level
this.state.percent = level * 30
if (level >= 2) {
if (level >= 3) {
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('newPassword')
if (value === undefined) {
callback(new Error('请输入密码'))
}
if (value && password && value.trim() !== password.trim()) {
callback(new Error('两次密码不一致'))
}
callback()
},
handlePasswordInputClick () {
if (!this.isMobile) {
this.state.passwordLevelChecked = true
return
}
this.state.passwordLevelChecked = false
},
// handler
handleSubmit (e) {
e.preventDefault()
this.form.validateFields((err, values) => {
if (!err) {
// eslint-disable-next-line no-console
console.log('Received values of form: ', values)
changePswd(values).then(res => {
if (res.code === 0) {
this.$message.success('修改成功')
this.$emit('ok')
this.visible = false
} else {
this.$message.error('修改错误,请检查帐号或密码!')
}
}).catch(() => {
this.$message.error('系统错误,请稍后再试')
}).finally(() => {
this.confirmLoading = false
})
}
})
},
watch: {
'state.passwordLevel' (val) {
console.log(val)
}
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,44 +1,49 @@
<template>
<div class="page-header-index-wide">
<a-card :bordered="false" :bodyStyle="{ padding: '16px 0', height: '100%' }" :style="{ height: '100%' }">
<div class="account-settings-info-main" :class="{ 'mobile': isMobile }">
<div class="account-settings-info-left">
<div class='page-header-index-wide'>
<a-card :bordered='false' :bodyStyle="{ padding: '16px 0', height: '100%' }" :style="{ height: '100%' }">
<div class='account-settings-info-main' :class="{ 'mobile': isMobile }">
<div class='account-settings-info-left'>
<a-menu
:mode="isMobile ? 'horizontal' : 'inline'"
:style="{ border: '0', width: isMobile ? '560px' : 'auto'}"
:selectedKeys="selectedKeys"
type="inner"
@openChange="onOpenChange"
:selectedKeys='selectedKeys'
type='inner'
@openChange='onOpenChange'
>
<!-- <a-menu-item key="/account/settings/base">-->
<!-- <router-link :to="{ name: 'base' }">-->
<!-- {{ i18nRender('menu.account.settings.base') }}-->
<!-- </router-link>-->
<!-- </a-menu-item>-->
<a-menu-item key="/account/settings/security">
<!-- <a-menu-item key="/account/settings/base">-->
<!-- <router-link :to="{ name: 'base' }">-->
<!-- {{ i18nRender('menu.account.settings.base') }}-->
<!-- </router-link>-->
<!-- </a-menu-item>-->
<a-menu-item key='/account/settings/security' v-if='changePwd'>
<router-link :to="{ name: 'security' }">
{{ i18nRender('menu.account.settings.security') }}
登录密码修改
</router-link>
</a-menu-item>
<!-- <a-menu-item key="/account/settings/custom">-->
<!-- <router-link :to="{ name: 'custom' }">-->
<!-- {{ i18nRender('menu.account.settings.custom') }}-->
<!-- </router-link>-->
<!-- </a-menu-item>-->
<!-- <a-menu-item key="/account/settings/binding">-->
<!-- <router-link :to="{ name: 'binding' }">-->
<!-- {{ i18nRender('menu.account.settings.binding') }}-->
<!-- </router-link>-->
<!-- </a-menu-item>-->
<!-- <a-menu-item key="/account/settings/notification">-->
<!-- <router-link :to="{ name: 'notification' }">-->
<!-- {{ i18nRender('menu.account.settings.notification') }}-->
<!-- </router-link>-->
<!-- </a-menu-item>-->
<a-menu-item key='/account/settings/depPwd'>
<router-link :to="{ path: '/account/settings/depPwd' }">
单位密码修改
</router-link>
</a-menu-item>
<!-- <a-menu-item key="/account/settings/custom">-->
<!-- <router-link :to="{ name: 'custom' }">-->
<!-- {{ i18nRender('menu.account.settings.custom') }}-->
<!-- </router-link>-->
<!-- </a-menu-item>-->
<!-- <a-menu-item key="/account/settings/binding">-->
<!-- <router-link :to="{ name: 'binding' }">-->
<!-- {{ i18nRender('menu.account.settings.binding') }}-->
<!-- </router-link>-->
<!-- </a-menu-item>-->
<!-- <a-menu-item key="/account/settings/notification">-->
<!-- <router-link :to="{ name: 'notification' }">-->
<!-- {{ i18nRender('menu.account.settings.notification') }}-->
<!-- </router-link>-->
<!-- </a-menu-item>-->
</a-menu>
</div>
<div class="account-settings-info-right">
<div class="account-settings-info-title">
<div class='account-settings-info-right'>
<div class='account-settings-info-title'>
<span>{{ i18nRender($route.meta.title) }}</span>
</div>
<route-view></route-view>
@ -52,6 +57,7 @@
import { RouteView } from '@/layouts'
import { baseMixin } from '@/store/app-mixin'
import { i18nRender } from '@/locales'
import { checkPermission } from '@/utils/permissions'
export default {
components: {
@ -59,7 +65,7 @@ export default {
i18nRender
},
mixins: [baseMixin],
data () {
data() {
return {
// horizontal inline
mode: 'inline',
@ -86,122 +92,127 @@ export default {
},
pageTitle: '',
base: 'base'
base: 'base',
changePwd: checkPermission('system:profile:password')
}
},
mounted () {
mounted() {
this.updateMenu()
},
methods: {
onOpenChange (openKeys) {
onOpenChange(openKeys) {
this.openKeys = openKeys
},
updateMenu () {
updateMenu() {
const routes = this.$route.matched.concat()
this.selectedKeys = [ routes.pop().path ]
this.selectedKeys = [routes.pop().path]
// console.log('selectedKeys', this.selectedKeys)
},
i18nRender (key) {
i18nRender(key) {
return i18nRender(key)
}
},
watch: {
'$route' (val) {
'$route'(val) {
this.updateMenu()
}
}
}
</script>
<style lang="less" scoped>
.account-settings-info-main {
width: 100%;
display: flex;
height: 100%;
overflow: auto;
<style lang='less' scoped>
.account-settings-info-main {
width: 100%;
display: flex;
height: 100%;
overflow: auto;
&.mobile {
display: block;
.account-settings-info-left {
border-right: unset;
border-bottom: 1px solid #e8e8e8;
width: 100%;
height: 50px;
overflow-x: auto;
overflow-y: scroll;
}
.account-settings-info-right {
padding: 20px 40px;
}
}
&.mobile {
display: block;
.account-settings-info-left {
border-right: 1px solid #e8e8e8;
width: 224px;
border-right: unset;
border-bottom: 1px solid #e8e8e8;
width: 100%;
height: 50px;
overflow-x: auto;
overflow-y: scroll;
}
.account-settings-info-right {
flex: 1 1;
padding: 8px 40px;
.account-settings-info-title {
color: rgba(0, 0, 0, 0.85);
font-size: 20px;
font-weight: 500;
line-height: 28px;
margin-bottom: 12px;
}
.account-settings-info-view {
padding-top: 12px;
}
padding: 20px 40px;
}
}
</style>
<style lang="less" scoped>
.account-settings-info-main {
width: 100%;
display: flex;
height: 100%;
overflow: auto;
.account-settings-info-left {
border-right: 1px solid #e8e8e8;
width: 224px;
}
&.mobile {
display: block;
.account-settings-info-right {
flex: 1 1;
padding: 8px 40px;
.account-settings-info-left {
border-right: unset;
border-bottom: 1px solid #e8e8e8;
width: 100%;
height: 50px;
overflow-x: auto;
overflow-y: scroll;
}
.account-settings-info-right {
padding: 20px 40px;
}
.account-settings-info-title {
color: rgba(0, 0, 0, 0.85);
font-size: 20px;
font-weight: 500;
line-height: 28px;
margin-bottom: 12px;
}
.account-settings-info-view {
padding-top: 12px;
}
}
}
</style>
<style lang='less' scoped>
.account-settings-info-main {
width: 100%;
display: flex;
height: 100%;
overflow: auto;
&.mobile {
display: block;
.account-settings-info-left {
border-right: 1px solid #e8e8e8;
width: 224px;
border-right: unset;
border-bottom: 1px solid #e8e8e8;
width: 100%;
height: 50px;
overflow-x: auto;
overflow-y: scroll;
}
.account-settings-info-right {
flex: 1 1;
padding: 8px 40px;
.account-settings-info-title {
color: rgba(0,0,0,.85);
font-size: 20px;
font-weight: 500;
line-height: 28px;
margin-bottom: 12px;
}
.account-settings-info-view {
padding-top: 12px;
}
padding: 20px 40px;
}
}
.account-settings-info-left {
border-right: 1px solid #e8e8e8;
width: 224px;
}
.account-settings-info-right {
flex: 1 1;
padding: 8px 40px;
.account-settings-info-title {
color: rgba(0, 0, 0, .85);
font-size: 20px;
font-weight: 500;
line-height: 28px;
margin-bottom: 12px;
}
.account-settings-info-view {
padding-top: 12px;
}
}
}
</style>

View File

@ -1,29 +1,30 @@
<template>
<div class="account-settings-info-view">
<a-row :gutter="16">
<a-col :md="24" :lg="16">
<a-form @submit="handleSubmit" :form="form" layout="vertical">
<div class='account-settings-info-view'>
<a-row :gutter='16'>
<a-col :md='24' :lg='16'>
<a-form @submit='handleSubmit' :form='form' layout='vertical'>
<a-form-item>
<a-input-password placeholder="旧密码" v-decorator="['password', {rules: [{ required: true, message: '请选录入旧密码' }]}]"/>
<a-input-password placeholder='旧密码'
v-decorator="['password', {rules: [{ required: true, message: '请选录入旧密码' }]}]" />
</a-form-item>
<a-popover
placement="rightTop"
placement='rightTop'
:trigger="['focus']"
:getPopupContainer="(trigger) => trigger.parentElement"
v-model="state.passwordLevelChecked">
<template slot="content">
<div :style="{ width: '240px' }" >
: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;">
<a-progress :percent='state.percent' :showInfo='false' :strokeColor=' passwordLevelColor ' />
<div style='margin-top: 10px;'>
<span>请至少输入 6 个字符请不要使用容易被猜到的密码</span>
</div>
</div>
</template>
<a-form-item>
<a-input-password
@click="handlePasswordInputClick"
placeholder="新密码至少6位密码区分大小写"
@click='handlePasswordInputClick'
placeholder='新密码至少6位密码区分大小写'
v-decorator="['newPassword', {rules: [{ required: true, message: '新密码至少6位密码区分大小写'}, { validator: this.handlePasswordLevel }], validateTrigger: ['change', 'blur']}]"
></a-input-password>
</a-form-item>
@ -31,12 +32,12 @@
<a-form-item>
<a-input-password
placeholder="重复新密码"
placeholder='重复新密码'
v-decorator="['rePassword', {rules: [{ required: true, message: '新密码至少6位密码区分大小写' }, { validator: this.handlePasswordCheck }], validateTrigger: ['change', 'blur']}]"
></a-input-password>
</a-form-item>
<a-form-item>
<a-button htmlType="submit" type="primary">修改密码</a-button>
<a-button htmlType='submit' type='primary'>修改密码</a-button>
</a-form-item>
</a-form>
</a-col>
@ -46,6 +47,7 @@
<script>
import { updataPassword } from '@/api/system'
import { checkPermission } from '@/utils/permissions'
const levelNames = {
0: '低',
@ -67,29 +69,35 @@ const levelColor = {
}
export default {
data () {
data() {
return {
state: {
passwordLevel: 0,
passwordLevelChecked: false,
percent: 10
},
form: this.$form.createForm(this)
form: this.$form.createForm(this),
changePwd: checkPermission('system:profile:password')
}
},
mounted() {
if (!this.changePwd) {
this.$router.push({ path: '/account/settings/depPwd' })
}
},
computed: {
passwordLevelClass () {
passwordLevelClass() {
return levelClass[this.state.passwordLevel]
},
passwordLevelName () {
passwordLevelName() {
return levelNames[this.state.passwordLevel]
},
passwordLevelColor () {
passwordLevelColor() {
return levelColor[this.state.passwordLevel]
}
},
methods: {
handlePasswordLevel (rule, value, callback) {
handlePasswordLevel(rule, value, callback) {
let level = 0
//
@ -118,7 +126,7 @@ export default {
callback(new Error('密码强度不够'))
}
},
handlePasswordCheck (rule, value, callback) {
handlePasswordCheck(rule, value, callback) {
const password = this.form.getFieldValue('newPassword')
if (value === undefined) {
callback(new Error('请输入密码'))
@ -128,7 +136,7 @@ export default {
}
callback()
},
handlePasswordInputClick () {
handlePasswordInputClick() {
if (!this.isMobile) {
this.state.passwordLevelChecked = true
return
@ -136,7 +144,7 @@ export default {
this.state.passwordLevelChecked = false
},
// handler
handleSubmit (e) {
handleSubmit(e) {
e.preventDefault()
this.form.validateFields((err, values) => {
if (!err) {
@ -159,7 +167,7 @@ export default {
})
},
watch: {
'state.passwordLevel' (val) {
'state.passwordLevel'(val) {
console.log(val)
}
}

View File

@ -1,8 +1,8 @@
<template>
<div class='main' style='text-align: center'>
<vue-qr v-if='!isLogin'
<vue-qr style='margin-top: 40px' v-if='!isLogin'
:text='loginUrl'
:size='250'
:size='200'
></vue-qr>
<a-button v-if='isLogin' @click='goIndex()' type="primary" style='margin-top: 20px'>
访问系统
@ -74,4 +74,17 @@ export default {
}
}
</script>
<style>
#app {
/* 加载背景图 */
background-image: url(~@/assets/login-code-bg.jpg);
/* 背景图垂直、水平均居中 */
background-position: center center;
/* 背景图不平铺 */
background-repeat: no-repeat;
/* 当内容高度大于图片高度时背景图像的位置相对于viewport固定 */
background-attachment: fixed;
/* 让背景图基于容器大小伸缩 */
background-size: cover;
}
</style>