update 实现修改密码. 并对一些用户填写的格式进行了验证
This commit is contained in:
@@ -2801,6 +2801,71 @@
|
|||||||
<param name="refreshToken"></param>
|
<param name="refreshToken"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="T:Ewide.Core.SysDictDataSeedData">
|
||||||
|
<summary>
|
||||||
|
系统字典值种子数据
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:Ewide.Core.SysDictDataSeedData.HasData(Microsoft.EntityFrameworkCore.DbContext,System.Type)">
|
||||||
|
<summary>
|
||||||
|
种子数据
|
||||||
|
</summary>
|
||||||
|
<param name="dbContext"></param>
|
||||||
|
<param name="dbContextLocator"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="T:Ewide.Core.SysDictTypeSeedData">
|
||||||
|
<summary>
|
||||||
|
系统字典类型种子数据
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:Ewide.Core.SysDictTypeSeedData.HasData(Microsoft.EntityFrameworkCore.DbContext,System.Type)">
|
||||||
|
<summary>
|
||||||
|
种子数据
|
||||||
|
</summary>
|
||||||
|
<param name="dbContext"></param>
|
||||||
|
<param name="dbContextLocator"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="T:Ewide.Core.SysMenuSeedData">
|
||||||
|
<summary>
|
||||||
|
系统菜单表种子数据
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:Ewide.Core.SysMenuSeedData.HasData(Microsoft.EntityFrameworkCore.DbContext,System.Type)">
|
||||||
|
<summary>
|
||||||
|
种子数据
|
||||||
|
</summary>
|
||||||
|
<param name="dbContext"></param>
|
||||||
|
<param name="dbContextLocator"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="T:Ewide.Core.SysTimerSeedData">
|
||||||
|
<summary>
|
||||||
|
系统任务调度表种子数据
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:Ewide.Core.SysTimerSeedData.HasData(Microsoft.EntityFrameworkCore.DbContext,System.Type)">
|
||||||
|
<summary>
|
||||||
|
种子数据
|
||||||
|
</summary>
|
||||||
|
<param name="dbContext"></param>
|
||||||
|
<param name="dbContextLocator"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="T:Ewide.Core.SysUserSeedData">
|
||||||
|
<summary>
|
||||||
|
系统用户表种子数据
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:Ewide.Core.SysUserSeedData.HasData(Microsoft.EntityFrameworkCore.DbContext,System.Type)">
|
||||||
|
<summary>
|
||||||
|
种子数据
|
||||||
|
</summary>
|
||||||
|
<param name="dbContext"></param>
|
||||||
|
<param name="dbContextLocator"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="T:Ewide.Core.Service.AppInput">
|
<member name="T:Ewide.Core.Service.AppInput">
|
||||||
<summary>
|
<summary>
|
||||||
系统应用参数
|
系统应用参数
|
||||||
@@ -6604,11 +6669,6 @@
|
|||||||
用户Id
|
用户Id
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="P:Ewide.Core.Service.ChangePasswordUserInput.Id">
|
|
||||||
<summary>
|
|
||||||
用户Id
|
|
||||||
</summary>
|
|
||||||
</member>
|
|
||||||
<member name="P:Ewide.Core.Service.ChangePasswordUserInput.Password">
|
<member name="P:Ewide.Core.Service.ChangePasswordUserInput.Password">
|
||||||
<summary>
|
<summary>
|
||||||
密码
|
密码
|
||||||
|
|||||||
@@ -115,6 +115,15 @@ namespace Ewide.Core.Service
|
|||||||
var httpContext = App.GetService<IHttpContextAccessor>().HttpContext;
|
var httpContext = App.GetService<IHttpContextAccessor>().HttpContext;
|
||||||
var loginOutput = user.Adapt<LoginOutput>();
|
var loginOutput = user.Adapt<LoginOutput>();
|
||||||
|
|
||||||
|
// 隐藏手机号/邮箱中间几位
|
||||||
|
loginOutput.Phone = String.IsNullOrEmpty(loginOutput.Phone) ? loginOutput.Phone
|
||||||
|
: loginOutput.Phone.Substring(0, 3) + "****" + loginOutput.Phone.Substring(7, 4);
|
||||||
|
loginOutput.Email = String.IsNullOrEmpty(loginOutput.Email) ? loginOutput.Email
|
||||||
|
: String.Join("@", loginOutput.Email.Split('@').Select((p, i) =>
|
||||||
|
{
|
||||||
|
return i == 0 ? (p.Length > 3 ? p.Substring(0, 3).PadRight(p.Length, '*') : "".PadRight(3, '*')) : p;
|
||||||
|
}));
|
||||||
|
|
||||||
loginOutput.LastLoginTime = user.LastLoginTime = DateTime.Now;
|
loginOutput.LastLoginTime = user.LastLoginTime = DateTime.Now;
|
||||||
var ip = httpContext.Request.Headers["X-Real-IP"].FirstOrDefault();
|
var ip = httpContext.Request.Headers["X-Real-IP"].FirstOrDefault();
|
||||||
loginOutput.LastLoginIp = user.LastLoginIp = string.IsNullOrEmpty(user.LastLoginIp) ? httpContext.GetRemoteIpAddressToIPv4() : ip;
|
loginOutput.LastLoginIp = user.LastLoginIp = string.IsNullOrEmpty(user.LastLoginIp) ? httpContext.GetRemoteIpAddressToIPv4() : ip;
|
||||||
@@ -153,18 +162,18 @@ namespace Ewide.Core.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 增加登录日志
|
// 增加登录日志
|
||||||
await new SysLogVis
|
//await new SysLogVis
|
||||||
{
|
//{
|
||||||
Name = "登录",
|
// Name = "登录",
|
||||||
Success = true,
|
// Success = true,
|
||||||
Message = "登录成功",
|
// Message = "登录成功",
|
||||||
Ip = loginOutput.LastLoginIp,
|
// Ip = loginOutput.LastLoginIp,
|
||||||
Browser = loginOutput.LastLoginBrowser,
|
// Browser = loginOutput.LastLoginBrowser,
|
||||||
Os = loginOutput.LastLoginOs,
|
// Os = loginOutput.LastLoginOs,
|
||||||
VisType = 1,
|
// VisType = 1,
|
||||||
VisTime = loginOutput.LastLoginTime,
|
// VisTime = loginOutput.LastLoginTime,
|
||||||
Account = loginOutput.Account
|
// Account = loginOutput.Account
|
||||||
}.InsertAsync();
|
//}.InsertAsync();
|
||||||
|
|
||||||
return loginOutput;
|
return loginOutput;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,11 +46,13 @@ namespace Ewide.Core.Service
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 邮箱
|
/// 邮箱
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[RegularExpression(@"^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$", ErrorMessage = "邮箱格式不正确")]
|
||||||
public virtual string Email { get; set; }
|
public virtual string Email { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 手机
|
/// 手机
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[RegularExpression(@"^((13[0-9])|(14[5,7])|(15[^4,\\D])|(17[0,1,3,6-8])|(18[0-9])|(19[8,9])|(166))[0-9]{8}$", ErrorMessage = "手机号格式不正确")]
|
||||||
public virtual string Phone { get; set; }
|
public virtual string Phone { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -120,12 +122,6 @@ namespace Ewide.Core.Service
|
|||||||
|
|
||||||
public class ChangePasswordUserInput
|
public class ChangePasswordUserInput
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 用户Id
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "用户Id不能为空")]
|
|
||||||
public string Id { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 密码
|
/// 密码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ namespace Ewide.Core.Service
|
|||||||
nameof(SysUser.Password),
|
nameof(SysUser.Password),
|
||||||
nameof(SysUser.AdminType),
|
nameof(SysUser.AdminType),
|
||||||
nameof(SysUser.Status),
|
nameof(SysUser.Status),
|
||||||
// 邮箱和手机号作为可能登录的方式,不能在此处直接进行修改
|
// 邮箱和手机号作为安全验证的方式,不能在此处直接进行修改
|
||||||
nameof(SysUser.Phone),
|
nameof(SysUser.Phone),
|
||||||
nameof(SysUser.Email)
|
nameof(SysUser.Email)
|
||||||
}, true);
|
}, true);
|
||||||
@@ -253,7 +253,7 @@ namespace Ewide.Core.Service
|
|||||||
[HttpPost("/sysUser/updatePwd")]
|
[HttpPost("/sysUser/updatePwd")]
|
||||||
public async Task UpdateUserPwd(ChangePasswordUserInput input)
|
public async Task UpdateUserPwd(ChangePasswordUserInput input)
|
||||||
{
|
{
|
||||||
var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == input.Id);
|
var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == _userManager.UserId);
|
||||||
if (MD5Encryption.Encrypt(input.Password) != user.Password)
|
if (MD5Encryption.Encrypt(input.Password) != user.Password)
|
||||||
throw Oops.Oh(ErrorCode.D1004);
|
throw Oops.Oh(ErrorCode.D1004);
|
||||||
if (MD5Encryption.Encrypt(input.NewPassword).Equals(user.Password))
|
if (MD5Encryption.Encrypt(input.NewPassword).Equals(user.Password))
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
"sysFileInfo:upload",
|
"sysFileInfo:upload",
|
||||||
"sysFileInfo:download",
|
"sysFileInfo:download",
|
||||||
"sysFileInfo:preview",
|
"sysFileInfo:preview",
|
||||||
"sysUser:updateInfo"
|
"sysUser:updateInfo",
|
||||||
|
"sysUser:updatePwd"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
@import './lib/container.less';
|
@import './lib/container.less';
|
||||||
@import './lib/align.less';
|
@import './lib/align.less';
|
||||||
@import './lib/font-size.less';
|
@import './lib/font-size.less';
|
||||||
|
@import './lib/text-color.less';
|
||||||
@import './lib/margin.less';
|
@import './lib/margin.less';
|
||||||
@import './lib/width-height.less';
|
@import './lib/width-height.less';
|
||||||
@import './lib/scrollbar.less';
|
@import './lib/scrollbar.less';
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
.yo-nav-theme--light {
|
.yo-nav-theme--light {
|
||||||
.light();
|
.light();
|
||||||
}
|
}
|
||||||
|
@import './lib/button.less';
|
||||||
@import './lib/card.less';
|
@import './lib/card.less';
|
||||||
@import './lib/table.less';
|
@import './lib/table.less';
|
||||||
@import './lib/list.less';
|
@import './lib/list.less';
|
||||||
|
|||||||
5
Web/src/assets/style/lib/button.less
Normal file
5
Web/src/assets/style/lib/button.less
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
@import (reference) '~@/assets/style/extend.less';
|
||||||
|
@btn-default-border: @border-color-split;
|
||||||
|
.ant-btn {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
@@ -4,25 +4,17 @@
|
|||||||
width: 660px;
|
width: 660px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
h1,
|
|
||||||
.h1,
|
.h1,
|
||||||
h2,
|
|
||||||
.h2,
|
.h2,
|
||||||
h3,
|
|
||||||
.h3,
|
.h3,
|
||||||
h4,
|
|
||||||
.h4,
|
.h4,
|
||||||
h5,
|
|
||||||
.h5,
|
.h5,
|
||||||
h6,
|
|
||||||
.h6 {
|
.h6 {
|
||||||
color: darken(@white, 40%);
|
color: darken(@white, 40%);
|
||||||
}
|
}
|
||||||
h3,
|
|
||||||
.h3 {
|
.h3 {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
h4,
|
|
||||||
.h4 {
|
.h4 {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
@import (reference) '~@/assets/style/extend.less';
|
@import (reference) '~@/assets/style/extend.less';
|
||||||
|
.ant-list-bordered {
|
||||||
|
border-color: @border-color-split;
|
||||||
|
background-color: @white;
|
||||||
|
}
|
||||||
.yo-list {
|
.yo-list {
|
||||||
&-content--h {
|
&-content--h {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
32
Web/src/assets/style/lib/text-color.less
Normal file
32
Web/src/assets/style/lib/text-color.less
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
@import (reference) '~@/assets/style/extend.less';
|
||||||
|
.text-primary {
|
||||||
|
color: @primary-color;
|
||||||
|
}
|
||||||
|
.text-info {
|
||||||
|
color: @info-color;
|
||||||
|
}
|
||||||
|
.text-success {
|
||||||
|
color: @success-color;
|
||||||
|
}
|
||||||
|
.text-processing {
|
||||||
|
color: @processing-color;
|
||||||
|
}
|
||||||
|
.text-error,
|
||||||
|
.text-danger {
|
||||||
|
color: @error-color;
|
||||||
|
}
|
||||||
|
.text-highlight {
|
||||||
|
color: @highlight-color;
|
||||||
|
}
|
||||||
|
.text-warning {
|
||||||
|
color: @warning-color;
|
||||||
|
}
|
||||||
|
.text-normal {
|
||||||
|
color: @normal-color;
|
||||||
|
}
|
||||||
|
.text-white {
|
||||||
|
color: @white;
|
||||||
|
}
|
||||||
|
.text-black {
|
||||||
|
color: @black;
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ axios.defaults.baseURL = '/api'
|
|||||||
* api.getItemGroupType(parmas).then(...)
|
* api.getItemGroupType(parmas).then(...)
|
||||||
*/
|
*/
|
||||||
import urls from './requests'
|
import urls from './requests'
|
||||||
|
import { settings } from 'nprogress'
|
||||||
|
|
||||||
const initInstance = (options) => {
|
const initInstance = (options) => {
|
||||||
const instance = axios
|
const instance = axios
|
||||||
@@ -45,10 +46,12 @@ const errorNotification = ({ code, message }) => {
|
|||||||
switch (message.constructor) {
|
switch (message.constructor) {
|
||||||
case Array:
|
case Array:
|
||||||
message.map(p => {
|
message.map(p => {
|
||||||
app.$notification.error({
|
setTimeout(() => {
|
||||||
duration: 30,
|
app.$notification.error({
|
||||||
message: p.field,
|
duration: 30,
|
||||||
description: p.messages.join('/'),
|
message: p.field,
|
||||||
|
description: p.messages.join('/'),
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ export default {
|
|||||||
},
|
},
|
||||||
action: {
|
action: {
|
||||||
type: Function
|
type: Function
|
||||||
|
},
|
||||||
|
successMessage: {
|
||||||
|
type: String
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -124,7 +127,7 @@ export default {
|
|||||||
&& this.action(data)
|
&& this.action(data)
|
||||||
.then(({ success }) => {
|
.then(({ success }) => {
|
||||||
if (success) {
|
if (success) {
|
||||||
this.$message.success('保存成功');
|
this.$message.success(this.successMessage || '保存成功');
|
||||||
this.onClose();
|
this.onClose();
|
||||||
this.$emit('ok');
|
this.$emit('ok');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<container>
|
<container>
|
||||||
<br />
|
|
||||||
<a-anchor
|
<a-anchor
|
||||||
:get-container="()=> $el.parentNode"
|
:get-container="()=> $el.parentNode"
|
||||||
:offset-top="16"
|
:offset-top="16"
|
||||||
:wrapper-style="{ backgroundColor: 'transparent' }"
|
@click.prevent
|
||||||
|
class="yo-account--anchor"
|
||||||
>
|
>
|
||||||
<a-anchor-link
|
<a-anchor-link
|
||||||
:href="`#account-${key}`"
|
:href="`#account-${key}`"
|
||||||
@@ -13,12 +13,27 @@
|
|||||||
v-for="(nav, key) in navs"
|
v-for="(nav, key) in navs"
|
||||||
/>
|
/>
|
||||||
</a-anchor>
|
</a-anchor>
|
||||||
|
<br />
|
||||||
<section :id="`account-${key}`" :key="key" v-for="(nav, key) in navs">
|
<section :id="`account-${key}`" :key="key" v-for="(nav, key) in navs">
|
||||||
<component :is="nav.component" v-if="nav.component" />
|
<component :is="nav.component" v-if="nav.component" />
|
||||||
</section>
|
</section>
|
||||||
</container>
|
</container>
|
||||||
</template>
|
</template>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
@import (reference) '~@/assets/style/extend.less';
|
||||||
|
.yo-account--anchor {
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
width: 200px;
|
||||||
|
/deep/.ant-anchor-wrapper {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
/deep/.ant-anchor-ink {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
@@ -28,6 +43,10 @@ export default {
|
|||||||
title: '我的信息',
|
title: '我的信息',
|
||||||
component: () => import('./setting/info'),
|
component: () => import('./setting/info'),
|
||||||
},
|
},
|
||||||
|
1: {
|
||||||
|
title: '安全设置',
|
||||||
|
component: () => import('./setting/safety'),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<container mode="container-xxs">
|
<container mode="container-xxs">
|
||||||
<a-form-model class="yo-form">
|
<a-form-model class="yo-form">
|
||||||
<h4>我的信息</h4>
|
<h4 class="h4">我的信息</h4>
|
||||||
<div class="yo-avatar-info">
|
<div class="yo-avatar-info">
|
||||||
<yo-image :id="form.avatar" :size="128" icon="user" type="avatar" />
|
<yo-image :id="form.avatar" :size="128" icon="user" type="avatar" />
|
||||||
<div @click="avatar.cropper = true" class="yo-avatar-info--cover">
|
<div @click="avatar.cropper = true" class="yo-avatar-info--cover">
|
||||||
@@ -99,6 +99,7 @@
|
|||||||
|
|
||||||
<a-button :loading="saving" @click="onSaveInfo" block>更新个人信息</a-button>
|
<a-button :loading="saving" @click="onSaveInfo" block>更新个人信息</a-button>
|
||||||
</a-form-model>
|
</a-form-model>
|
||||||
|
<br />
|
||||||
</container>
|
</container>
|
||||||
</template>
|
</template>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
143
Web/src/pages/system/account/setting/safety/index.vue
Normal file
143
Web/src/pages/system/account/setting/safety/index.vue
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
<template>
|
||||||
|
<container mode="container-xxs">
|
||||||
|
<div class="yo-form">
|
||||||
|
<h4 class="h4">安全设置</h4>
|
||||||
|
<a-progress
|
||||||
|
:percent="15"
|
||||||
|
:stroke-color="{
|
||||||
|
from: '#108ee9',
|
||||||
|
to: '#87d068',
|
||||||
|
}"
|
||||||
|
:stroke-width="15"
|
||||||
|
class="mb-md"
|
||||||
|
status="active"
|
||||||
|
stroke-linecap="square"
|
||||||
|
>
|
||||||
|
<span slot="format">
|
||||||
|
帐号安全级别:
|
||||||
|
<span v-html="safetyLevel"></span>
|
||||||
|
</span>
|
||||||
|
</a-progress>
|
||||||
|
<a-list :data-source="data" bordered item-layout="vertical">
|
||||||
|
<a-list-item slot="renderItem" slot-scope="item">
|
||||||
|
<template v-if="item.done">
|
||||||
|
<span class="text-success" slot="actions">
|
||||||
|
<a-icon class="mr-xxs" type="check-circle" />已设置
|
||||||
|
</span>
|
||||||
|
<a @click="item.action" slot="actions">修改</a>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<span class="text-warning" slot="actions">
|
||||||
|
<a-icon class="mr-xxs" type="exclamation-circle" />未设置
|
||||||
|
</span>
|
||||||
|
<a @click="item.action" slot="actions">设置</a>
|
||||||
|
</template>
|
||||||
|
<a-list-item-meta :description="item.description" :title="item.title" />
|
||||||
|
<span>{{ item.content }}</span>
|
||||||
|
</a-list-item>
|
||||||
|
</a-list>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<yo-modal-form
|
||||||
|
:action="$api.sysUserUpdatePwd"
|
||||||
|
@ok="onSetPasswordSuccess"
|
||||||
|
ref="password-form"
|
||||||
|
success-message="密码修改成功"
|
||||||
|
title="修改密码"
|
||||||
|
>
|
||||||
|
<password />
|
||||||
|
</yo-modal-form>
|
||||||
|
</container>
|
||||||
|
</template>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
@import (reference) '~@/assets/style/app.less';
|
||||||
|
.ant-progress {
|
||||||
|
width: 400px;
|
||||||
|
/deep/.ant-progress-inner {
|
||||||
|
border-radius: @border-radius-base;
|
||||||
|
background-color: @white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
import { doLogout } from '@/common/login';
|
||||||
|
|
||||||
|
import Password from './password';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Password,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
safetyLevel() {
|
||||||
|
// 计算帐号安全级别
|
||||||
|
return '<span class="text-error">弱</span>';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
const info = this.$root.global.info;
|
||||||
|
|
||||||
|
// 登录密码
|
||||||
|
this.data.push({
|
||||||
|
title: '登录密码',
|
||||||
|
description:
|
||||||
|
'安全性高的密码可以使帐号更安全。建议您定期更换密码,设置一个包含字母,符号或数字中至少两项且长度超过6位的密码。',
|
||||||
|
content: '当前密码强度:弱(不保存密码明文,需要在数据库以字段形式存储)',
|
||||||
|
done: true,
|
||||||
|
action: () => {
|
||||||
|
this.$refs['password-form'].onOpen({});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 手机绑定
|
||||||
|
this.data.push({
|
||||||
|
title: '手机绑定(发送验证码到手机,未实现)',
|
||||||
|
description: (
|
||||||
|
<div>
|
||||||
|
手机号可以直接用于登录、找回密码等。
|
||||||
|
{info.phone && (
|
||||||
|
<span>
|
||||||
|
您已绑定了手机<b>{info.phone}</b>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
done: !!info.phone,
|
||||||
|
action: () => {},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 邮箱绑定
|
||||||
|
this.data.push({
|
||||||
|
title: '安全邮箱(发送验证码到邮箱,未实现)',
|
||||||
|
description: (
|
||||||
|
<div>
|
||||||
|
安全邮箱可以直接用于登录、找回密码等。
|
||||||
|
{info.email && (
|
||||||
|
<span>
|
||||||
|
您已绑定了邮箱<b>{info.email}</b>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
done: !!info.email,
|
||||||
|
action: () => {},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onSetPasswordSuccess() {
|
||||||
|
doLogout();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
126
Web/src/pages/system/account/setting/safety/password.vue
Normal file
126
Web/src/pages/system/account/setting/safety/password.vue
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<template>
|
||||||
|
<!--
|
||||||
|
普通编辑窗体
|
||||||
|
v 1.2
|
||||||
|
2021-04-30
|
||||||
|
Lufthafen
|
||||||
|
-->
|
||||||
|
<a-form-model :model="form" :rules="rules" class="yo-form" ref="form">
|
||||||
|
<a-spin :spinning="loading">
|
||||||
|
<a-icon slot="indicator" spin type="loading" />
|
||||||
|
<div class="yo-form-group">
|
||||||
|
<!-- 表单控件 -->
|
||||||
|
<!-- ... -->
|
||||||
|
<a-form-model-item label="旧密码" prop="password">
|
||||||
|
<a-input-password placeholder="请输入旧密码" v-model="form.password" />
|
||||||
|
</a-form-model-item>
|
||||||
|
<a-form-model-item label="新密码" prop="newPassword">
|
||||||
|
<a-input-password placeholder="请输入新密码" v-model="form.newPassword" />
|
||||||
|
</a-form-model-item>
|
||||||
|
<a-form-model-item label="确认新密码" prop="confirm">
|
||||||
|
<a-input-password placeholder="请确认新密码" v-model="form.confirm" />
|
||||||
|
</a-form-model-item>
|
||||||
|
</div>
|
||||||
|
</a-spin>
|
||||||
|
</a-form-model>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
/* 表单内容默认值 */
|
||||||
|
const defaultForm = {
|
||||||
|
/* ... */
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
/** 表单数据 */
|
||||||
|
form: {},
|
||||||
|
/** 验证格式 */
|
||||||
|
rules: {
|
||||||
|
/* ... */
|
||||||
|
password: [{ required: true, message: '请输入旧密码' }],
|
||||||
|
newPassword: [{ required: true, message: '请输入新密码' }],
|
||||||
|
confirm: [{ required: true, message: '请确认新密码' }],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 加载异步数据状态 */
|
||||||
|
loading: false,
|
||||||
|
|
||||||
|
/** 其他成员属性 */
|
||||||
|
/* ... */
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 必要的方法
|
||||||
|
* 在打开编辑页时允许填充数据
|
||||||
|
*/
|
||||||
|
onFillData(params) {
|
||||||
|
/** 将默认数据覆盖到form */
|
||||||
|
this.form = this.$_.cloneDeep({
|
||||||
|
...defaultForm,
|
||||||
|
...params.record,
|
||||||
|
/** 在此处添加其他默认数据转换 */
|
||||||
|
/* ... */
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 必要方法
|
||||||
|
* 验证表单并获取表单数据
|
||||||
|
*/
|
||||||
|
onGetData() {
|
||||||
|
return new Promise((reslove, reject) => {
|
||||||
|
this.$refs.form.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
const record = this.$_.cloneDeep(this.form);
|
||||||
|
|
||||||
|
/** 验证通过后可以对数据进行转换得到想要提交的格式 */
|
||||||
|
/* ... */
|
||||||
|
|
||||||
|
reslove(record);
|
||||||
|
} else {
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 必要的方法
|
||||||
|
* 在外部窗口进行保存时调用表单验证
|
||||||
|
*/
|
||||||
|
onValidate(callback) {
|
||||||
|
this.$refs.form.validate(callback);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 必要的方法
|
||||||
|
* 在外部窗口关闭或重置时对表单验证进行初始化
|
||||||
|
*/
|
||||||
|
onResetFields() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$refs.form.resetFields();
|
||||||
|
|
||||||
|
/** 在这里可以初始化当前组件中其他属性 */
|
||||||
|
/* ... */
|
||||||
|
}, 300);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 必要方法
|
||||||
|
* 加载当前表单中所需要的异步数据
|
||||||
|
*/
|
||||||
|
async onInit(params) {
|
||||||
|
this.loading = true;
|
||||||
|
/** 可以在这里await获取一些异步数据 */
|
||||||
|
/* ... */
|
||||||
|
this.loading = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 当前组件的其他方法 */
|
||||||
|
/* ... */
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -79,6 +79,7 @@
|
|||||||
:get-container="()=> $el.parentNode"
|
:get-container="()=> $el.parentNode"
|
||||||
:offset-top="24"
|
:offset-top="24"
|
||||||
:wrapper-style="{ backgroundColor: 'transparent' }"
|
:wrapper-style="{ backgroundColor: 'transparent' }"
|
||||||
|
@click.prevent
|
||||||
>
|
>
|
||||||
<a-anchor-link
|
<a-anchor-link
|
||||||
:href="`#doc-${index}`"
|
:href="`#doc-${index}`"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<a-icon slot="indicator" spin type="loading" />
|
<a-icon slot="indicator" spin type="loading" />
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :span="10">
|
<a-col :span="10">
|
||||||
<h3>基本信息</h3>
|
<h3 class="h3">基本信息</h3>
|
||||||
<div class="yo-form-group">
|
<div class="yo-form-group">
|
||||||
<a-form-model-item label="账号" prop="account">
|
<a-form-model-item label="账号" prop="account">
|
||||||
<a-input placeholder="请输入账号" v-model="form.account" />
|
<a-input placeholder="请输入账号" v-model="form.account" />
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="14">
|
<a-col :span="14">
|
||||||
<h3>员工信息</h3>
|
<h3 class="h3">员工信息</h3>
|
||||||
<div class="yo-form-group">
|
<div class="yo-form-group">
|
||||||
<a-form-model-item label="所属组织机构" prop="sysEmpParam.orgId">
|
<a-form-model-item label="所属组织机构" prop="sysEmpParam.orgId">
|
||||||
<a-tree-select
|
<a-tree-select
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
</a-select>
|
</a-select>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
</div>
|
</div>
|
||||||
<h4>附加信息</h4>
|
<h4 class="h4">附加信息</h4>
|
||||||
<a-table
|
<a-table
|
||||||
:columns="extColumns"
|
:columns="extColumns"
|
||||||
:data-source="form.sysEmpParam.extIds"
|
:data-source="form.sysEmpParam.extIds"
|
||||||
@@ -136,15 +136,27 @@ export default {
|
|||||||
sysEmpParam: {},
|
sysEmpParam: {},
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
account: [{ required: true, min: 5, message: '请输入至少五个字符的账号' }],
|
account: [{ required: true, min: 5, message: '请输入至少五个字符的账号', trigger: 'blur' }],
|
||||||
name: [{ required: true, message: '请输入姓名' }],
|
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
||||||
password: [
|
password: [
|
||||||
{ required: true, min: 5, message: '请输入至少五个字符的密码' },
|
{ required: true, min: 5, message: '请输入至少五个字符的密码', trigger: 'blur' },
|
||||||
{ validator: validateToNextPassword },
|
{ validator: validateToNextPassword, trigger: 'blur' },
|
||||||
|
],
|
||||||
|
confirm: [
|
||||||
|
{ required: true, message: '请确认密码', trigger: 'blur' },
|
||||||
|
{ validator: compareToFirstPassword, trigger: 'blur' },
|
||||||
],
|
],
|
||||||
confirm: [{ required: true, message: '请确认密码' }, { validator: compareToFirstPassword }],
|
|
||||||
sex: [{ required: true, message: '请选择性别' }],
|
sex: [{ required: true, message: '请选择性别' }],
|
||||||
phone: [{ required: true, message: '请输入手机号' }],
|
phone: [
|
||||||
|
{
|
||||||
|
pattern: /^((13[0-9])|(14[5,7])|(15[^4,\\D])|(17[0,1,3,6-8])|(18[0-9])|(19[8,9])|(166))[0-9]{8}$/,
|
||||||
|
message: '手机号格式不正确',
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
email: [
|
||||||
|
{ pattern: /^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/, message: '邮箱格式不正确', trigger: 'blur' },
|
||||||
|
],
|
||||||
'sysEmpParam.orgId': [{ required: true, message: '请选择所属组织机构' }],
|
'sysEmpParam.orgId': [{ required: true, message: '请选择所属组织机构' }],
|
||||||
'sysEmpParam.posIdList': [{ required: true, message: '请选择职位信息' }],
|
'sysEmpParam.posIdList': [{ required: true, message: '请选择职位信息' }],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export default {
|
|||||||
key: 'account-home',
|
key: 'account-home',
|
||||||
title: '个人中心',
|
title: '个人中心',
|
||||||
icon: 'user',
|
icon: 'user',
|
||||||
path: '/account'
|
path: '/system/account'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user