mirror of
https://github.com/continew-org/continew-admin-ui.git
synced 2025-09-17 11:01:40 +08:00
refactor: 优化安全设置
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.login-bg {
|
||||
|
@@ -1,45 +0,0 @@
|
||||
<template>
|
||||
<div class="setting" :class="{ 'setting--h5': !isDesktop }">
|
||||
<div class="setting__main">
|
||||
<div class="setting__main__content">
|
||||
<ParentView></ParentView>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useDevice } from '@/hooks'
|
||||
|
||||
defineOptions({ name: 'Setting' })
|
||||
|
||||
const { isDesktop } = useDevice()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.setting {
|
||||
flex: 1;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&__main {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
&__content {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
padding: $margin;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.setting--h5 {
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
@@ -16,8 +16,11 @@
|
||||
</section>
|
||||
<footer>
|
||||
<a-descriptions column="4" size="large">
|
||||
<a-descriptions-item label="性别" :span="4">
|
||||
{{ userInfo.nickname }}
|
||||
<a-descriptions-item :span="4">
|
||||
<template #label> <icon-user /><span style="margin-left: 5px">用户名</span></template>
|
||||
{{ userInfo.username }}
|
||||
<icon-man v-if="userInfo.gender === 1" style="color: #19bbf1" />
|
||||
<icon-woman v-else-if="userInfo.gender === 2" style="color: #fa7fa9" />
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item :span="4">
|
||||
<template #label> <icon-phone /><span style="margin-left: 5px">手机</span></template>
|
||||
@@ -29,11 +32,11 @@
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item :span="4">
|
||||
<template #label> <icon-mind-mapping /><span style="margin-left: 5px">部门</span></template>
|
||||
{{ userInfo.nickname }}
|
||||
{{ userInfo.deptName }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item :span="4">
|
||||
<template #label> <icon-user-group /><span style="margin-left: 5px">角色</span></template>
|
||||
{{ userInfo.nickname }}
|
||||
{{ userInfo.roles.join(',') }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</footer>
|
||||
@@ -47,6 +50,7 @@
|
||||
import { updateUserBaseInfo } from '@/apis'
|
||||
import VerifyModel from '../components/VerifyModel.vue'
|
||||
import { useUserStore } from '@/stores'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const userInfo = computed(() => userStore.userInfo)
|
||||
const verifyModelRef = ref<InstanceType<typeof VerifyModel>>()
|
||||
|
@@ -1,26 +1,25 @@
|
||||
<template>
|
||||
<a-card title="登录方式" bordered class="gradient-card">
|
||||
<div class="mode-list">
|
||||
<div v-for="item in modeList" :key="item.title" class="mode-item">
|
||||
<div class="mode-item-box">
|
||||
<div class="mode-item-box__icon">
|
||||
<GiSvgIcon :name="item.icon" :size="48" />
|
||||
<div v-for="item in modeList" :key="item.title">
|
||||
<div class="item">
|
||||
<div class="icon-wrapper"><GiSvgIcon :name="item.icon" :size="26" /></div>
|
||||
<div class="info">
|
||||
<div class="info-top">
|
||||
<span class="label">{{ item.title }}</span>
|
||||
<span class="bind">
|
||||
<icon-check-circle-fill v-if="item.status" :size="14" class="success" />
|
||||
<icon-exclamation-circle-fill v-else :size="14" class="warning" />
|
||||
<span style="font-size: 12px" :class="item.status ? 'success' : 'warning'">{{
|
||||
item.status ? '已绑定' : '未绑定'
|
||||
}}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="mode-item-box__content">
|
||||
<div class="title">
|
||||
<div>{{ item.title }}</div>
|
||||
<div style="margin-left: 10px">
|
||||
<icon-check-circle-fill v-if="item.status" :size="14" class="success" />
|
||||
<icon-exclamation-circle-fill v-else :size="14" class="warning" />
|
||||
<span style="font-size: 12px" :class="item.status ? 'success' : 'warning'">{{
|
||||
item.status ? '已绑定' : '未绑定'
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mode-item-box__subtitle">{{ item.subtitle }}</div>
|
||||
<div class="info-desc">
|
||||
<span class="value">{{ item.value }}</span>
|
||||
{{ item.subtitle }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="btn-wrapper">
|
||||
<a-button
|
||||
v-if="item.jumpMode == 'modal'"
|
||||
class="btn"
|
||||
@@ -46,7 +45,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { socialAuth, getSocialAccount, unbindSocialAccount } from '@/apis'
|
||||
import type { ModeItem } from './type'
|
||||
import type { ModeItem } from '../type'
|
||||
import { useUserStore } from '@/stores'
|
||||
import VerifyModel from '../components/VerifyModel.vue'
|
||||
|
||||
@@ -62,16 +61,18 @@ const modeList = ref<ModeItem[]>([])
|
||||
modeList.value = [
|
||||
{
|
||||
title: '绑定手机',
|
||||
icon: userInfo.value.phone ? 'tel' : 'tel-unbind',
|
||||
subtitle: `${userInfo.value.phone || '绑定后'},可通过手机验证码快捷登录`,
|
||||
icon: 'phone-color',
|
||||
value: `${userInfo.value.phone + ' ' || '绑定后,'}`,
|
||||
subtitle: `可通过手机验证码快捷登录`,
|
||||
type: 'phone',
|
||||
jumpMode: 'modal',
|
||||
status: !!userInfo.value.phone
|
||||
},
|
||||
{
|
||||
title: '绑定邮箱',
|
||||
icon: userInfo.value.email ? 'mail' : 'mail-unbind',
|
||||
subtitle: `${userInfo.value.email || '绑定后'},可通过邮箱验证码进行登录`,
|
||||
icon: 'email-color',
|
||||
value: `${userInfo.value.email + ' ' || '绑定后,'}`,
|
||||
subtitle: `可通过邮箱验证码进行登录`,
|
||||
type: 'email',
|
||||
jumpMode: 'modal',
|
||||
status: !!userInfo.value.email
|
||||
@@ -79,7 +80,7 @@ modeList.value = [
|
||||
{
|
||||
title: '绑定 Gitee',
|
||||
icon: 'gitee',
|
||||
subtitle: '绑定后,可通过 Gitee 进行登录',
|
||||
subtitle: `${socialList.value.some((el) => el == 'gitee') ? '' : '绑定后,'}可通过 Gitee 进行登录`,
|
||||
jumpMode: 'link',
|
||||
type: 'gitee',
|
||||
status: socialList.value.some((el) => el == 'gitee')
|
||||
@@ -87,7 +88,7 @@ modeList.value = [
|
||||
{
|
||||
title: '绑定 GitHub',
|
||||
icon: 'github',
|
||||
subtitle: '绑定后,可通过 GitHub 进行登录',
|
||||
subtitle: `${socialList.value.some((el) => el == 'gitee') ? '' : '绑定后,'}可通过 GitHub 进行登录`,
|
||||
type: 'github',
|
||||
jumpMode: 'link',
|
||||
status: socialList.value.some((el) => el == 'github')
|
||||
@@ -118,34 +119,4 @@ onMounted(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mode-list {
|
||||
.mode-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
&-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
&__icon {
|
||||
margin-right: 10px;
|
||||
}
|
||||
&__content {
|
||||
div {
|
||||
line-height: 26px;
|
||||
}
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
.btn {
|
||||
height: 28px;
|
||||
margin-left: 10px;
|
||||
width: 56px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
@@ -15,7 +15,7 @@
|
||||
import LeftBox from './LeftBox.vue'
|
||||
import RightBox from './RightBox.vue'
|
||||
|
||||
defineOptions({ name: 'Profile' })
|
||||
defineOptions({ name: 'SettingProfile' })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@@ -1,99 +1,49 @@
|
||||
<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>
|
||||
<a-card title="账号保护" bordered class="gradient-card">
|
||||
<div v-for="item in modeList" :key="item.title">
|
||||
<div class="item">
|
||||
<div class="icon-wrapper"><GiSvgIcon :name="item.icon" :size="26" /></div>
|
||||
<div class="info">
|
||||
<div class="info-top">
|
||||
<span class="label">{{ item.title }}</span>
|
||||
<span class="bind">
|
||||
<icon-check-circle-fill v-if="item.status" :size="14" class="success" />
|
||||
<icon-exclamation-circle-fill v-else :size="14" class="warning" />
|
||||
<span style="font-size: 12px" :class="item.status ? 'success' : 'warning'">{{
|
||||
item.status ? '已开启' : '未开启'
|
||||
}}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="info-desc">
|
||||
{{ item.subtitle }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<a-button disabled>未开放</a-button>
|
||||
<div class="btn-wrapper">
|
||||
<a-switch disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="content_title">
|
||||
<div class="icon"><GiSvgIcon name="login-protect" :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>
|
||||
</div>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Card from '../components/Card.vue'
|
||||
interface ModeItem {
|
||||
title: string
|
||||
icon: string
|
||||
subtitle: string
|
||||
status: boolean
|
||||
}
|
||||
import type { ModeItem } from '../type'
|
||||
|
||||
const modeList = ref<ModeItem[]>([])
|
||||
modeList.value = [
|
||||
{ title: '登录保护', icon: 'login-protect', subtitle: '开启登录保护后,账号登录需进行二次身份验证', status: false }
|
||||
{
|
||||
title: '登录保护',
|
||||
icon: 'protect',
|
||||
subtitle: '开启登录保护后,账号登录需进行二次身份验证',
|
||||
status: false
|
||||
},
|
||||
{
|
||||
title: '操作保护',
|
||||
icon: 'protect',
|
||||
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>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
@@ -1,59 +1,78 @@
|
||||
<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>
|
||||
<a-card title="基本设置" bordered class="gradient-card">
|
||||
<div v-for="item in modeList" :key="item.title">
|
||||
<div class="item">
|
||||
<div class="icon-wrapper"><GiSvgIcon :name="item.icon" :size="26" /></div>
|
||||
<div class="info">
|
||||
<div class="info-top">
|
||||
<span class="label">{{ item.title }}</span>
|
||||
<span class="bind">
|
||||
<icon-check-circle-fill v-if="item.status" :size="14" class="success" />
|
||||
<icon-exclamation-circle-fill v-else :size="14" class="warning" />
|
||||
<span style="font-size: 12px" :class="item.status ? 'success' : 'warning'">{{
|
||||
item.status ? '已绑定' : '未绑定'
|
||||
}}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="info-desc">
|
||||
<span class="value">{{ item.value }}</span>
|
||||
{{ item.subtitle }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<a-button @click="openVerifyModel(item.type)">修改</a-button>
|
||||
<div class="btn-wrapper">
|
||||
<a-button class="btn" :type="item.status ? 'secondary' : 'primary'" @click="onUpdate(item.type)">
|
||||
{{ item.status ? '修改' : '绑定' }}
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Card>
|
||||
</div>
|
||||
</a-card>
|
||||
<VerifyModel ref="verifyModelRef" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Card from '../components/Card.vue'
|
||||
import type { ModeItem } from '../type'
|
||||
import VerifyModel from '../components/VerifyModel.vue'
|
||||
interface ModeItem {
|
||||
title: string
|
||||
icon: string
|
||||
subtitle: string
|
||||
type: 'phone' | 'email'
|
||||
status: boolean
|
||||
}
|
||||
import { useUserStore } from '@/stores'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const userInfo = computed(() => userStore.userInfo)
|
||||
|
||||
const modeList = ref<ModeItem[]>([])
|
||||
modeList.value = [
|
||||
{ title: '绑定手机号', icon: 'tel', subtitle: '+86******88888可通过手机验证码快捷登录', type: 'phone', status: true },
|
||||
{ title: '绑定邮箱', icon: 'mail', subtitle: '邮箱可用于身份验证、密码找回、通知接收', type: 'email', status: true }
|
||||
{
|
||||
title: '安全手机',
|
||||
icon: 'phone-color',
|
||||
value: `${userInfo.value.phone + ' ' || '手机号'}`,
|
||||
subtitle: `可用于身份验证、密码找回、通知接收`,
|
||||
type: 'phone',
|
||||
status: !!userInfo.value.phone
|
||||
},
|
||||
{
|
||||
title: '安全邮箱',
|
||||
icon: 'email-color',
|
||||
value: `${userInfo.value.email + ' ' || '邮箱'}`,
|
||||
subtitle: `可用于身份验证、密码找回、通知接收`,
|
||||
type: 'email',
|
||||
status: !!userInfo.value.email
|
||||
}
|
||||
]
|
||||
|
||||
const verifyModelRef = ref<InstanceType<typeof VerifyModel>>()
|
||||
const openVerifyModel = (type: 'phone' | 'email') => {
|
||||
// 修改
|
||||
const onUpdate = (type: string) => {
|
||||
verifyModelRef.value?.open(type)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mode-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
.mode-item-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.icon {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
@@ -1,61 +1,38 @@
|
||||
<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>
|
||||
<a-card title="密码策略" bordered class="gradient-card">
|
||||
<div class="item">
|
||||
<div class="icon-wrapper"><GiSvgIcon name="password" :size="26" /></div>
|
||||
<div class="info">
|
||||
<div class="info-top">
|
||||
<span class="label">登录密码</span>
|
||||
</div>
|
||||
<div class="info-desc">为了您的账号安全,建议定期修改密码</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 class="btn-wrapper">
|
||||
<a-button class="btn">修改</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</Card>
|
||||
</div>
|
||||
<div class="detail">
|
||||
<div class="sub-text-wrapper">
|
||||
<div class="sub-text">
|
||||
密码至少包含
|
||||
<span class="sub-text-value">大写字母</span>
|
||||
<span class="sub-text-value">大写字母</span>
|
||||
<span class="sub-text-value">小写字母</span>
|
||||
<span class="sub-text-value">数字</span>
|
||||
<span class="sub-text-value">特殊字符</span>3种
|
||||
</div>
|
||||
<div class="sub-text">限制密码长度至少为<span class="sub-text-value">6</span>位</div>
|
||||
<div class="sub-text">未设置密码有效期</div>
|
||||
<div class="sub-text">新密码不能与历史前<span class="sub-text-value">N</span>次密码重复</div>
|
||||
<div class="sub-text">1小时内密码错误可重试<span class="sub-text-value">N</span>次</div>
|
||||
<div class="sub-text">超过错误密码重试次数账号将被锁定<span class="sub-text-value">N</span>分钟</div>
|
||||
<a-link class="link">修改规则(未开放)</a-link>
|
||||
</div>
|
||||
</div>
|
||||
</a-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>
|
||||
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
@@ -1,48 +1,24 @@
|
||||
<template>
|
||||
<Card style="height: 100%">
|
||||
<template #header> 登录会话设置 </template>
|
||||
<template #body>
|
||||
<div class="content_title">
|
||||
<div class="icon"><GiSvgIcon name="login-status" :size="36" /></div>
|
||||
<div>
|
||||
<div style="font-size: 14px; font-weight: 500; line-height: 28px">登录态保持时间设置</div>
|
||||
<div style="font-size: 12px">保持登录状态的限制</div>
|
||||
<a-card title="登录会话设置" bordered class="gradient-card">
|
||||
<div class="item">
|
||||
<div class="icon-wrapper"><GiSvgIcon name="message-color" :size="26" /></div>
|
||||
<div class="info">
|
||||
<div class="info-top">
|
||||
<span class="label">登录态保持时间设置</span>
|
||||
</div>
|
||||
<div class="info-desc">保持登录状态的限制</div>
|
||||
</div>
|
||||
<div class="content_Box">
|
||||
<p>操作登录会话保持120分钟,超时登录会话将失效</p>
|
||||
<p>登录会话最大保持0天,超时登录会话将失效</p>
|
||||
<p class="link_btn">修改规则(未开发)</p>
|
||||
</div>
|
||||
<div class="detail">
|
||||
<div class="sub-text-wrapper">
|
||||
<div class="sub-text">无操作登录会话保持<span class="sub-text-value">30</span>分钟,超时登录会话将失效</div>
|
||||
<div class="sub-text">登录会话最大保持<span class="sub-text-value">0</span>天,超时登录会话将失效</div>
|
||||
<a-link class="link">修改规则(未开放)</a-link class="link">
|
||||
</div>
|
||||
</template>
|
||||
</Card>
|
||||
</div>
|
||||
</a-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>
|
||||
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
@@ -1,21 +1,21 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="flex_box">
|
||||
<div class="flex_item_container">
|
||||
<div class="gi_page">
|
||||
<a-row wrap :gutter="16">
|
||||
<a-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" :xxl="12">
|
||||
<BasicsSetting />
|
||||
</div>
|
||||
<div class="flex_item_container">
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" :xxl="12">
|
||||
<SessionSetting />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box">
|
||||
<div class="flex_item_container">
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row wrap :gutter="16" style="margin-top: 16px">
|
||||
<a-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" :xxl="12">
|
||||
<PasswordPolicy />
|
||||
</div>
|
||||
<div class="flex_item_container">
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" :xxl="12">
|
||||
<AccountProtection />
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -25,20 +25,19 @@ import BasicsSetting from './BasicsSetting.vue'
|
||||
import SessionSetting from './SessionSetting.vue'
|
||||
import PasswordPolicy from './PasswordPolicy.vue'
|
||||
import AccountProtection from './AccountProtection.vue'
|
||||
defineOptions({ name: 'Security' })
|
||||
|
||||
defineOptions({ name: 'SettingSecurity' })
|
||||
|
||||
const route = useRoute()
|
||||
const form = reactive({ name: '' })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
padding: $padding;
|
||||
.gi_page {
|
||||
background-color: var(--color-bg-1);
|
||||
.flex_box {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
height: 100%;
|
||||
.flex_item_container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@@ -2,7 +2,8 @@ export interface ModeItem {
|
||||
title: string
|
||||
icon: string
|
||||
subtitle: string
|
||||
value?: string
|
||||
type: 'phone' | 'email' | 'gitee' | 'github'
|
||||
jumpMode: 'link' | 'modal'
|
||||
jumpMode?: 'link' | 'modal'
|
||||
status: boolean
|
||||
}
|
Reference in New Issue
Block a user