forked from github/dataease
perf: 允许社区版修改admin密码
This commit is contained in:
parent
412b2e589b
commit
4e46148ba7
@ -10,6 +10,8 @@ import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import AboutPage from '@/views/about/index.vue'
|
||||
import LangSelector from './LangSelector.vue'
|
||||
import router from '@/router'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
const { wsCache } = useCache()
|
||||
const userStore = useUserStoreWithOut()
|
||||
const { t } = useI18n()
|
||||
|
||||
@ -30,6 +32,16 @@ const linkLoaded = items => {
|
||||
items.forEach(item => linkList.value.push(item))
|
||||
linkList.value.sort(compare('id'))
|
||||
}
|
||||
const xpackLinkLoaded = items => {
|
||||
let len = linkList.value.length
|
||||
while (len--) {
|
||||
if (linkList.value[len]?.id === 2 && linkList.value[len]?.link === '/modify-pwd/index') {
|
||||
linkList.value.splice(len, 1)
|
||||
}
|
||||
}
|
||||
items.forEach(item => linkList.value.push(item))
|
||||
linkList.value.sort(compare('id'))
|
||||
}
|
||||
|
||||
const compare = (property: string) => {
|
||||
return (a, b) => a[property] - b[property]
|
||||
@ -68,6 +80,10 @@ const openPopover = () => {
|
||||
|
||||
if (uid.value === '1') {
|
||||
linkLoaded([{ id: 4, link: '/sys-setting/parameter', label: t('commons.system_setting') }])
|
||||
const desktop = wsCache.get('app.desktop')
|
||||
if (!desktop) {
|
||||
linkLoaded([{ id: 2, link: '/modify-pwd/index', label: t('user.change_password') }])
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -138,7 +154,7 @@ if (uid.value === '1') {
|
||||
</el-popover>
|
||||
|
||||
<AboutPage />
|
||||
<XpackComponent jsname="dWNlbnRlci1oYW5kbGVy" @loaded="linkLoaded" />
|
||||
<XpackComponent jsname="dWNlbnRlci1oYW5kbGVy" @loaded="xpackLinkLoaded" />
|
||||
</template>
|
||||
|
||||
<style lang="less">
|
||||
|
@ -96,6 +96,22 @@ export const routes: AppRouteRecordRaw[] = [
|
||||
hidden: true,
|
||||
meta: {},
|
||||
component: () => import('@/custom-component/rich-text/DeRichTextView.vue')
|
||||
},
|
||||
{
|
||||
path: '/modify-pwd',
|
||||
name: 'modify-pwd',
|
||||
hidden: true,
|
||||
meta: {},
|
||||
component: () => import('@/layout/index.vue'),
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
name: 'mpi',
|
||||
hidden: true,
|
||||
component: () => import('@/views/system/modify-pwd/index.vue'),
|
||||
meta: { hidden: true }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
|
140
core/core-frontend/src/views/system/modify-pwd/UpdatePwd.vue
Normal file
140
core/core-frontend/src/views/system/modify-pwd/UpdatePwd.vue
Normal file
@ -0,0 +1,140 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import request from '@/config/axios'
|
||||
import { rsaEncryp } from '@/utils/encryption'
|
||||
import { ElMessage } from 'element-plus-secondary'
|
||||
import { logoutHandler } from '@/utils/logout'
|
||||
import { CustomPassword } from '@/components/custom-password'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const defaultForm = {
|
||||
pwd: '',
|
||||
newPwd: '',
|
||||
confirm: ''
|
||||
}
|
||||
const pwdForm = reactive(cloneDeep(defaultForm))
|
||||
|
||||
const validatePwd = (_: any, value: any, callback: any) => {
|
||||
if (value === pwdForm.pwd) {
|
||||
callback(new Error('新旧密码不能相同'))
|
||||
}
|
||||
const pattern =
|
||||
/^.*(?=.{6,20})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[~!@#$%^&*()_+\-\={}|":<>?`[\];',.\/])[a-zA-Z0-9~!@#$%^&*()_+\-\={}|":<>?`[\];',.\/]*$/
|
||||
const regep = new RegExp(pattern)
|
||||
if (!regep.test(value)) {
|
||||
const msg = t('user.pwd_pattern_error')
|
||||
callback(new Error(msg))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
const validateConfirmPwd = (_: any, value: any, callback: any) => {
|
||||
if (value !== pwdForm.newPwd) {
|
||||
callback(new Error('两次输入的密码不一致'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
const rule = {
|
||||
pwd: [
|
||||
{
|
||||
required: true,
|
||||
message: t('common.require'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 20,
|
||||
message: t('commons.input_limit', [6, 20]),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
newPwd: [
|
||||
{
|
||||
required: true,
|
||||
message: t('common.require'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{ validator: validatePwd, trigger: 'blur' }
|
||||
],
|
||||
confirm: [
|
||||
{
|
||||
required: true,
|
||||
message: t('common.require'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 20,
|
||||
message: t('commons.input_limit', [6, 20]),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{ validator: validateConfirmPwd, trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
const updatePwdForm = ref()
|
||||
|
||||
const save = () => {
|
||||
updatePwdForm.value.validate(val => {
|
||||
if (val) {
|
||||
const pwd = rsaEncryp(pwdForm.pwd)
|
||||
const newPwd = rsaEncryp(pwdForm.newPwd)
|
||||
request.post({ url: '/user/modifyPwd', data: { pwd, newPwd } }).then(() => {
|
||||
ElMessage.success('修改成功,请重新登录')
|
||||
logoutHandler()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-form
|
||||
ref="updatePwdForm"
|
||||
require-asterisk-position="right"
|
||||
:model="pwdForm"
|
||||
:rules="rule"
|
||||
class="mt16"
|
||||
label-width="80px"
|
||||
label-position="top"
|
||||
>
|
||||
<el-form-item label="原始密码" prop="pwd">
|
||||
<CustomPassword
|
||||
v-model="pwdForm.pwd"
|
||||
show-password
|
||||
type="password"
|
||||
placeholder="请输入原始密码"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newPwd">
|
||||
<CustomPassword
|
||||
v-model="pwdForm.newPwd"
|
||||
show-password
|
||||
type="password"
|
||||
placeholder="请输入新密码"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="confirm">
|
||||
<CustomPassword
|
||||
v-model="pwdForm.confirm"
|
||||
show-password
|
||||
type="password"
|
||||
placeholder="请输入确认密码"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-button style="margin-top: 12px" @click="save" type="primary">
|
||||
{{ t('common.save') }}
|
||||
</el-button>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.mt16 {
|
||||
margin-top: 16px;
|
||||
}
|
||||
</style>
|
198
core/core-frontend/src/views/system/modify-pwd/index.vue
Normal file
198
core/core-frontend/src/views/system/modify-pwd/index.vue
Normal file
@ -0,0 +1,198 @@
|
||||
<template>
|
||||
<div class="user-center flex-align-center">
|
||||
<div class="user-center-container">
|
||||
<div class="user-tabs">
|
||||
<div class="tabs-title flex-align-center">用户中心</div>
|
||||
<el-divider />
|
||||
<div class="list-item_primary active">
|
||||
{{ t('user.change_password') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<div class="base-info">
|
||||
<div class="info-title flex-align-center">
|
||||
<span class="title">
|
||||
{{ t('user.change_password') }}
|
||||
</span>
|
||||
</div>
|
||||
<update-pwd />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import UpdatePwd from './UpdatePwd.vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.user-center {
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
padding-top: 24px;
|
||||
.user-center-container {
|
||||
display: flex;
|
||||
font-family: PingFang SC;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.user-tabs {
|
||||
width: 200px;
|
||||
height: 201px;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
padding: 16px;
|
||||
.list-item_primary {
|
||||
padding: 9px 8px;
|
||||
}
|
||||
|
||||
.ed-divider {
|
||||
margin: 4px 0;
|
||||
border-color: rgba(31, 35, 41, 0.15);
|
||||
}
|
||||
|
||||
.tabs-title {
|
||||
padding-left: 8px;
|
||||
color: #8d9199;
|
||||
font-family: PingFang SC;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 22px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
.user-info {
|
||||
margin-left: 16px;
|
||||
width: 864px;
|
||||
height: 326px;
|
||||
|
||||
.base-info {
|
||||
& + .base-info {
|
||||
margin-top: 12px;
|
||||
.bind-info {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 16px 24px 16px 24px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #dee0e3;
|
||||
.bind {
|
||||
font-size: 48px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.info {
|
||||
font-family: PingFang SC;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
width: 80%;
|
||||
|
||||
.name {
|
||||
color: #1f2329;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
font-weight: 500;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tip {
|
||||
color: #646a73;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
max-width: 600px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.delete {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
padding: 20px 24px 24px 24px;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
.role {
|
||||
& + .role {
|
||||
margin-left: 4px;
|
||||
}
|
||||
display: inline-flex;
|
||||
height: 20px;
|
||||
padding: 0 6px;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
color: #2b5fd9;
|
||||
border-radius: 2px;
|
||||
background: rgba(51, 112, 255, 0.2);
|
||||
}
|
||||
.info-title {
|
||||
.ed-button {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #1f2329;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.base-info-item {
|
||||
margin-top: 16px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
width: 100%;
|
||||
.label {
|
||||
color: #646a73;
|
||||
}
|
||||
.value {
|
||||
margin-top: 4px;
|
||||
color: #1f2329;
|
||||
}
|
||||
}
|
||||
.mr12 {
|
||||
margin-top: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="less">
|
||||
.qr-code-dialog {
|
||||
font-family: PingFang SC;
|
||||
font-style: normal;
|
||||
.ed-dialog__body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.qr-code-img {
|
||||
margin-top: 16px;
|
||||
display: inline-block;
|
||||
padding: 8px 12px;
|
||||
img {
|
||||
width: 184px;
|
||||
height: 184px;
|
||||
}
|
||||
border-radius: 8px;
|
||||
border: 1px solid #bbbfc4;
|
||||
}
|
||||
|
||||
.refresh-login {
|
||||
margin: 0 auto;
|
||||
margin-top: 9px;
|
||||
color: #646a73;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
|
||||
.ed-icon {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
2
de-xpack
2
de-xpack
@ -1 +1 @@
|
||||
Subproject commit dfef649cb7d7d2490891ba7acb0ecfb342673a7b
|
||||
Subproject commit 08ae0222ed43c0b19caab179e0ef5a96c4a69f94
|
Loading…
Reference in New Issue
Block a user