mirror of
https://github.com/continew-org/continew-admin-ui.git
synced 2025-10-21 18:59:20 +08:00
refactor: 账号管理功能大体完成,后续优化与细节调整
This commit is contained in:
99
src/views/setting/security/AccountProtection.vue
Normal file
99
src/views/setting/security/AccountProtection.vue
Normal file
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<Card>
|
||||
<template #header> 账号保护 </template>
|
||||
<template #body>
|
||||
<div class="mode-item" v-for="item in modeList" :key="item.title">
|
||||
<div class="mode-item-content">
|
||||
<div class="icon"><GiSvgIcon :name="item.icon" :size="36" /></div>
|
||||
<div>
|
||||
<div style="font-size: 14px; font-weight: 500; line-height: 28px; display: flex; align-items: center">
|
||||
<span>{{ item.title }}</span>
|
||||
<div style="margin-left: 10px">
|
||||
<GiSvgIcon :name="item.status ? 'success' : 'warning'" :size="14" /><span
|
||||
style="margin-left: 5px; font-size: 12px"
|
||||
>{{ item.status ? '已开启' : '未开启' }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div style="font-size: 12px">{{ item.subtitle }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<a-button disabled>未开放</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="content_title">
|
||||
<div class="icon"><GiSvgIcon name="loginProtect" :size="36" /></div>
|
||||
<div>
|
||||
<div style="font-size: 14px; font-weight: 500; line-height: 28px">操作保护</div>
|
||||
<div style="font-size: 12px">进行敏感操作时需进行二次身份校验</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content_Box">
|
||||
<p>可使用<span class="subTitle">手机号</span>进行二次身份验证</p>
|
||||
<p>未设置密码有效期</p>
|
||||
<p>敏感操作二次身份验证后<span class="subTitle">10</span>分钟内不需要再次进行验证</p>
|
||||
<p class="link_btn">修改规则(未开发)</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Card>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import Card from '../components/Card.vue'
|
||||
interface ModeItem {
|
||||
title: string
|
||||
icon: string
|
||||
subtitle: string
|
||||
status: boolean
|
||||
}
|
||||
const modeList = ref<ModeItem[]>([])
|
||||
modeList.value = [
|
||||
{ title: '登录保护', icon: 'loginProtect', subtitle: '开启登录保护后,账号登录需进行二次身份验证', status: false }
|
||||
]
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.mode-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
.mode-item-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.icon {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content_title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.icon {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.content_Box {
|
||||
border-left: 1px solid #ccc;
|
||||
margin-left: 40px;
|
||||
padding-left: 10px;
|
||||
font-size: 12px;
|
||||
margin-top: 20px;
|
||||
& > p {
|
||||
margin: 10px;
|
||||
}
|
||||
}
|
||||
.link_btn {
|
||||
cursor: pointer;
|
||||
color: #007aff;
|
||||
&:hover {
|
||||
color: rgba($color: #007aff, $alpha: 0.8);
|
||||
}
|
||||
}
|
||||
.subTitle {
|
||||
background: var(--color-neutral-2);
|
||||
padding: 1px 5px;
|
||||
margin: 0px 5px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
</style>
|
62
src/views/setting/security/BasicsSetting.vue
Normal file
62
src/views/setting/security/BasicsSetting.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<Card style="height: 100%">
|
||||
<template #header>基本设置</template>
|
||||
<template #body>
|
||||
<div class="mode-item" v-for="item in modeList" :key="item.title">
|
||||
<div class="mode-item-content">
|
||||
<div class="icon"><GiSvgIcon :name="item.icon" :size="36" /></div>
|
||||
<div>
|
||||
<div style="font-size: 14px; font-weight: 500; line-height: 28px; display: flex; align-items: center">
|
||||
<span>{{ item.title }}</span>
|
||||
<div style="margin-left: 10px">
|
||||
<GiSvgIcon :name="item.status ? 'success' : 'warning'" :size="14" /><span
|
||||
style="margin-left: 5px; font-size: 12px"
|
||||
>{{ item.status ? '已开启' : '未开启' }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div style="font-size: 12px">{{ item.subtitle }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<a-button @click="openVerifyModel(item.type)">修改</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Card>
|
||||
<VerifyModel ref="verifyModelRef" />
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import Card from '../components/Card.vue'
|
||||
import VerifyModel from '../components/VerifyModel.vue'
|
||||
interface ModeItem {
|
||||
title: string
|
||||
icon: string
|
||||
subtitle: string
|
||||
type: 'phone' | 'email'
|
||||
status: boolean
|
||||
}
|
||||
const modeList = ref<ModeItem[]>([])
|
||||
modeList.value = [
|
||||
{ title: '绑定手机号', icon: 'Tel', subtitle: '+86******88888可通过手机验证码快捷登录', type: 'phone', status: true },
|
||||
{ title: '绑定邮箱', icon: 'Mail', subtitle: '邮箱可用于身份验证、密码找回、通知接收', type: 'email', status: true }
|
||||
]
|
||||
const verifyModelRef = ref<InstanceType<typeof VerifyModel>>()
|
||||
const openVerifyModel = (type: 'phone' | 'email') => {
|
||||
verifyModelRef.value?.open(type)
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.mode-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
.mode-item-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.icon {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
61
src/views/setting/security/PasswordPolicy.vue
Normal file
61
src/views/setting/security/PasswordPolicy.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<Card>
|
||||
<template #header> 密码策略 </template>
|
||||
<template #body>
|
||||
<div class="content_title">
|
||||
<div class="icon"><GiSvgIcon name="password" :size="36" /></div>
|
||||
<div>
|
||||
<div style="font-size: 14px; font-weight: 500; line-height: 28px">登录密码</div>
|
||||
<div style="font-size: 12px">为了您的账号安全,建议定期修改密码</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content_Box">
|
||||
<p>
|
||||
密码至少包含 <span class="subTitle">大写字母</span><span class="subTitle">小写字母</span
|
||||
><span class="subTitle">数字</span><span class="subTitle">特殊字符</span>3种
|
||||
</p>
|
||||
<p>限制密码长度至少为<span class="subTitle">8</span>位</p>
|
||||
<p>未设置密码有效期</p>
|
||||
<p>新密码不能与历史前<span class="subTitle">3</span>次密码重复</p>
|
||||
<p>1小时内密码错误可重试 <span class="subTitle">5</span>次</p>
|
||||
<p>超过错误密码重试次数账号将被锁定<span class="subTitle">60</span>分钟</p>
|
||||
<p class="link_btn">修改规则(未开发)</p>
|
||||
</div>
|
||||
</template>
|
||||
</Card>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import Card from '../components/Card.vue'
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.content_title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.icon {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.content_Box {
|
||||
border-left: 1px solid #ccc;
|
||||
margin-left: 40px;
|
||||
padding-left: 10px;
|
||||
font-size: 12px;
|
||||
margin-top: 20px;
|
||||
& > p {
|
||||
margin: 10px;
|
||||
}
|
||||
}
|
||||
.link_btn {
|
||||
cursor: pointer;
|
||||
color: #007aff;
|
||||
&:hover {
|
||||
color: rgba($color: #007aff, $alpha: 0.8);
|
||||
}
|
||||
}
|
||||
.subTitle {
|
||||
background: var(--color-neutral-2);
|
||||
padding: 1px 5px;
|
||||
margin: 0px 5px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
</style>
|
48
src/views/setting/security/SessionSetting.vue
Normal file
48
src/views/setting/security/SessionSetting.vue
Normal file
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<Card style="height: 100%">
|
||||
<template #header> 登录会话设置 </template>
|
||||
<template #body>
|
||||
<div class="content_title">
|
||||
<div class="icon"><GiSvgIcon name="loginStatus" :size="36" /></div>
|
||||
<div>
|
||||
<div style="font-size: 14px; font-weight: 500; line-height: 28px">登录态保持时间设置</div>
|
||||
<div style="font-size: 12px">保持登录状态的限制</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content_Box">
|
||||
<p>操作登录会话保持120分钟,超时登录会话将失效</p>
|
||||
<p>登录会话最大保持0天,超时登录会话将失效</p>
|
||||
<p class="link_btn">修改规则(未开发)</p>
|
||||
</div>
|
||||
</template>
|
||||
</Card>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import Card from '../components/Card.vue'
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.content_title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.icon {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.content_Box {
|
||||
border-left: 1px solid #ccc;
|
||||
margin-left: 40px;
|
||||
padding-left: 10px;
|
||||
font-size: 12px;
|
||||
margin-top: 20px;
|
||||
& > p {
|
||||
margin: 10px;
|
||||
}
|
||||
}
|
||||
.link_btn {
|
||||
cursor: pointer;
|
||||
color: #007aff;
|
||||
&:hover {
|
||||
color: rgba($color: #007aff, $alpha: 0.8);
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,10 +1,30 @@
|
||||
<template>
|
||||
<div class="page"></div>
|
||||
<div class="page">
|
||||
<div class="flex_box">
|
||||
<div class="flex_item_container">
|
||||
<BasicsSetting />
|
||||
</div>
|
||||
<div class="flex_item_container">
|
||||
<SessionSetting />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box">
|
||||
<div class="flex_item_container">
|
||||
<PasswordPolicy />
|
||||
</div>
|
||||
<div class="flex_item_container">
|
||||
<AccountProtection />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Message } from '@arco-design/web-vue'
|
||||
|
||||
import BasicsSetting from './BasicsSetting.vue'
|
||||
import SessionSetting from './SessionSetting.vue'
|
||||
import PasswordPolicy from './PasswordPolicy.vue'
|
||||
import AccountProtection from './AccountProtection.vue'
|
||||
defineOptions({ name: 'Security' })
|
||||
|
||||
const route = useRoute()
|
||||
@@ -15,5 +35,17 @@ const form = reactive({ name: '' })
|
||||
.page {
|
||||
padding: $padding;
|
||||
background-color: var(--color-bg-1);
|
||||
.flex_box {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
height: 100%;
|
||||
.flex_item_container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
& .flex_item_container:first-child {
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
Reference in New Issue
Block a user