mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-03-14 01:34:47 +08:00
feat: 完成面板设置前端界面效果
This commit is contained in:
parent
6ceb040061
commit
2a1403904f
@ -17,7 +17,7 @@ func (b *BaseApi) GetSettingInfo(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, setting)
|
helper.SuccessWithData(c, setting)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BaseApi) UpdateInfo(c *gin.Context) {
|
func (b *BaseApi) UpdateSetting(c *gin.Context) {
|
||||||
var req dto.SettingUpdate
|
var req dto.SettingUpdate
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
@ -2,10 +2,10 @@ package dto
|
|||||||
|
|
||||||
type SettingInfo struct {
|
type SettingInfo struct {
|
||||||
UserName string `json:"userName"`
|
UserName string `json:"userName"`
|
||||||
Password string `json:"password"`
|
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
|
|
||||||
SessionTimeout string `json:"sessionTimeout"`
|
SessionTimeout string `json:"sessionTimeout"`
|
||||||
|
LocalTime string `json:"localTime"`
|
||||||
|
|
||||||
PanelName string `json:"panelName"`
|
PanelName string `json:"panelName"`
|
||||||
Theme string `json:"theme"`
|
Theme string `json:"theme"`
|
||||||
@ -13,6 +13,7 @@ type SettingInfo struct {
|
|||||||
|
|
||||||
ServerPort string `json:"serverPort"`
|
ServerPort string `json:"serverPort"`
|
||||||
SecurityEntrance string `json:"securityEntrance"`
|
SecurityEntrance string `json:"securityEntrance"`
|
||||||
|
PasswordTimeOut string `json:"passwordTimeOut"`
|
||||||
ComplexityVerification string `json:"complexityVerification"`
|
ComplexityVerification string `json:"complexityVerification"`
|
||||||
MFAStatus string `json:"mfaStatus"`
|
MFAStatus string `json:"mfaStatus"`
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/app/dto"
|
"github.com/1Panel-dev/1Panel/app/dto"
|
||||||
"github.com/1Panel-dev/1Panel/constant"
|
"github.com/1Panel-dev/1Panel/constant"
|
||||||
@ -35,6 +36,7 @@ func (u *SettingService) GetSettingInfo() (*dto.SettingInfo, error) {
|
|||||||
if err := json.Unmarshal(arr, &info); err != nil {
|
if err := json.Unmarshal(arr, &info); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
info.LocalTime = time.Now().Format("2006.01.02 15:04:05")
|
||||||
return &info, err
|
return &info, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package migrations
|
package migrations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/app/model"
|
"github.com/1Panel-dev/1Panel/app/model"
|
||||||
|
|
||||||
"github.com/go-gormigrate/gormigrate/v2"
|
"github.com/go-gormigrate/gormigrate/v2"
|
||||||
@ -90,6 +92,9 @@ var AddTableSetting = &gormigrate.Migration{
|
|||||||
if err := tx.Create(&model.Setting{Key: "SessionTimeout", Value: "86400"}).Error; err != nil {
|
if err := tx.Create(&model.Setting{Key: "SessionTimeout", Value: "86400"}).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := tx.Create(&model.Setting{Key: "LocalTime", Value: ""}).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := tx.Create(&model.Setting{Key: "ServerPort", Value: "4004"}).Error; err != nil {
|
if err := tx.Create(&model.Setting{Key: "ServerPort", Value: "4004"}).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
@ -97,6 +102,9 @@ var AddTableSetting = &gormigrate.Migration{
|
|||||||
if err := tx.Create(&model.Setting{Key: "SecurityEntrance", Value: "/89dc6ae8"}).Error; err != nil {
|
if err := tx.Create(&model.Setting{Key: "SecurityEntrance", Value: "/89dc6ae8"}).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := tx.Create(&model.Setting{Key: "PasswordTimeOut", Value: time.Now().AddDate(0, 0, 10).Format("2016.01.02 15:04:05")}).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := tx.Create(&model.Setting{Key: "ComplexityVerification", Value: "enable"}).Error; err != nil {
|
if err := tx.Create(&model.Setting{Key: "ComplexityVerification", Value: "enable"}).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,10 @@ import (
|
|||||||
type SettingRouter struct{}
|
type SettingRouter struct{}
|
||||||
|
|
||||||
func (s *SettingRouter) InitSettingRouter(Router *gin.RouterGroup) {
|
func (s *SettingRouter) InitSettingRouter(Router *gin.RouterGroup) {
|
||||||
monitorRouter := Router.Group("settings").Use(middleware.JwtAuth()).Use(middleware.SessionAuth())
|
settingRouter := Router.Group("settings").Use(middleware.JwtAuth()).Use(middleware.SessionAuth())
|
||||||
baseApi := v1.ApiGroupApp.BaseApi
|
baseApi := v1.ApiGroupApp.BaseApi
|
||||||
{
|
{
|
||||||
monitorRouter.POST("/search", baseApi.GetSettingInfo)
|
settingRouter.POST("/search", baseApi.GetSettingInfo)
|
||||||
|
settingRouter.PUT("", baseApi.UpdateSetting)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ export namespace Setting {
|
|||||||
email: string;
|
email: string;
|
||||||
|
|
||||||
sessionTimeout: string;
|
sessionTimeout: string;
|
||||||
|
localTime: string;
|
||||||
|
|
||||||
panelName: string;
|
panelName: string;
|
||||||
theme: string;
|
theme: string;
|
||||||
@ -12,6 +13,7 @@ export namespace Setting {
|
|||||||
|
|
||||||
serverPort: string;
|
serverPort: string;
|
||||||
securityEntrance: string;
|
securityEntrance: string;
|
||||||
|
passwordTimeOut: string;
|
||||||
complexityVerification: string;
|
complexityVerification: string;
|
||||||
mfaStatus: string;
|
mfaStatus: string;
|
||||||
|
|
||||||
@ -23,4 +25,13 @@ export namespace Setting {
|
|||||||
weChatVars: string;
|
weChatVars: string;
|
||||||
dingVars: string;
|
dingVars: string;
|
||||||
}
|
}
|
||||||
|
export interface SettingUpdate {
|
||||||
|
key: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
export interface PasswordUpdate {
|
||||||
|
oldPassword: string;
|
||||||
|
newPassword: string;
|
||||||
|
retryPassword: string;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,3 +4,7 @@ import { Setting } from '../interface/setting';
|
|||||||
export const getSettingInfo = () => {
|
export const getSettingInfo = () => {
|
||||||
return http.post<Setting.SettingInfo>(`/settings/search`);
|
return http.post<Setting.SettingInfo>(`/settings/search`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const updateSetting = (param: Setting.SettingUpdate) => {
|
||||||
|
return http.put(`/settings`, param);
|
||||||
|
};
|
||||||
|
@ -18,6 +18,16 @@ export default {
|
|||||||
dateStart: '开始日期',
|
dateStart: '开始日期',
|
||||||
dateEnd: '结束日期',
|
dateEnd: '结束日期',
|
||||||
},
|
},
|
||||||
|
personal: {
|
||||||
|
about: '关于',
|
||||||
|
project_url: '项目地址',
|
||||||
|
issue: '问题反馈',
|
||||||
|
talk: '参与讨论',
|
||||||
|
star: '点亮 Star',
|
||||||
|
version: '版本',
|
||||||
|
ko_introduction:
|
||||||
|
'是一个开源的轻量级 Kubernetes 发行版,专注于帮助企业规划、部署和运营生产级别的 Kubernetes 集群。',
|
||||||
|
},
|
||||||
table: {
|
table: {
|
||||||
name: '名称',
|
name: '名称',
|
||||||
group: '组',
|
group: '组',
|
||||||
@ -47,6 +57,7 @@ export default {
|
|||||||
rule: {
|
rule: {
|
||||||
username: '请输入用户名',
|
username: '请输入用户名',
|
||||||
password: '请输入密码',
|
password: '请输入密码',
|
||||||
|
rePassword: '密码不一致,请检查后重新输入',
|
||||||
requiredInput: '请填写必填项',
|
requiredInput: '请填写必填项',
|
||||||
requiredSelect: '请选择必选项',
|
requiredSelect: '请选择必选项',
|
||||||
commonName: '支持英文、中文、数字、.-_,长度1-30',
|
commonName: '支持英文、中文、数字、.-_,长度1-30',
|
||||||
@ -84,7 +95,10 @@ export default {
|
|||||||
menu: {
|
menu: {
|
||||||
home: '概览',
|
home: '概览',
|
||||||
demo: '样例',
|
demo: '样例',
|
||||||
|
monitor: '监控',
|
||||||
terminal: '终端',
|
terminal: '终端',
|
||||||
|
operations: '操作日志',
|
||||||
|
files: '文件管理',
|
||||||
apps: '应用商店',
|
apps: '应用商店',
|
||||||
website: '网站',
|
website: '网站',
|
||||||
project: '项目',
|
project: '项目',
|
||||||
@ -95,12 +109,8 @@ export default {
|
|||||||
plan: '计划任务',
|
plan: '计划任务',
|
||||||
host: '主机',
|
host: '主机',
|
||||||
security: '安全',
|
security: '安全',
|
||||||
systemConfig: '面板设置',
|
settings: '面板设置',
|
||||||
toolbox: '工具箱',
|
toolbox: '工具箱',
|
||||||
monitor: '监控',
|
|
||||||
operations: '操作记录',
|
|
||||||
files: '文件管理',
|
|
||||||
settings: '系统设置',
|
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
welcome: '欢迎使用',
|
welcome: '欢迎使用',
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
import { Layout } from '@/routers/constant';
|
|
||||||
|
|
||||||
const systemConfigRouter = {
|
|
||||||
sort: 8,
|
|
||||||
path: '/configs',
|
|
||||||
component: Layout,
|
|
||||||
redirect: '/configs',
|
|
||||||
meta: {
|
|
||||||
icon: 'p-config',
|
|
||||||
title: 'menu.systemConfig',
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/configs',
|
|
||||||
name: 'SystemConfig',
|
|
||||||
component: () => import('@/views/system-config/index.vue'),
|
|
||||||
meta: {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
export default systemConfigRouter;
|
|
@ -1,13 +1,13 @@
|
|||||||
import { Layout } from '@/routers/constant';
|
import { Layout } from '@/routers/constant';
|
||||||
|
|
||||||
const settingRouter = {
|
const settingRouter = {
|
||||||
sort: 3,
|
sort: 7,
|
||||||
path: '/settings',
|
path: '/settings',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: '/setting',
|
redirect: '/setting',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'menu.settings',
|
title: 'menu.settings',
|
||||||
icon: 'Setting',
|
icon: 'p-config',
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
@ -114,3 +114,13 @@
|
|||||||
.form-button {
|
.form-button {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-help {
|
||||||
|
font-size: 12px;
|
||||||
|
word-break: break-all;
|
||||||
|
color: #4A4B4D;
|
||||||
|
transform: scale(0.9);
|
||||||
|
transform-origin: left;
|
||||||
|
width: 110%;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
@ -34,7 +34,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<Terminal
|
<Terminal
|
||||||
style="height: calc(100vh - 210px); background-color: #000"
|
style="height: calc(100vh - 150px); background-color: #000"
|
||||||
:ref="'Ref' + item.key"
|
:ref="'Ref' + item.key"
|
||||||
:wsID="item.wsID"
|
:wsID="item.wsID"
|
||||||
:terminalID="item.key"
|
:terminalID="item.key"
|
||||||
@ -106,7 +106,7 @@
|
|||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<div v-if="terminalTabs.length === 0">
|
<div v-if="terminalTabs.length === 0">
|
||||||
<el-empty
|
<el-empty
|
||||||
style="background-color: #000; height: calc(100vh - 210px)"
|
style="background-color: #000; height: calc(100vh - 150px)"
|
||||||
:description="$t('terminal.emptyTerminal')"
|
:description="$t('terminal.emptyTerminal')"
|
||||||
></el-empty>
|
></el-empty>
|
||||||
</div>
|
</div>
|
||||||
@ -182,9 +182,9 @@ import i18n from '@/lang';
|
|||||||
import { ElForm } from 'element-plus';
|
import { ElForm } from 'element-plus';
|
||||||
import { Host } from '@/api/interface/host';
|
import { Host } from '@/api/interface/host';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import Terminal from '@/views/terminal/terminal/index.vue';
|
import Terminal from '@/views/host/terminal/terminal/index.vue';
|
||||||
import HostTab from '@/views/terminal/host/index.vue';
|
import HostTab from '@/views/host/terminal/host/index.vue';
|
||||||
import CommandTab from '@/views/terminal/command/index.vue';
|
import CommandTab from '@/views/host/terminal/command/index.vue';
|
||||||
import type Node from 'element-plus/es/components/tree/src/model/node';
|
import type Node from 'element-plus/es/components/tree/src/model/node';
|
||||||
import { ElTree } from 'element-plus';
|
import { ElTree } from 'element-plus';
|
||||||
import screenfull from 'screenfull';
|
import screenfull from 'screenfull';
|
||||||
|
@ -3,100 +3,45 @@
|
|||||||
<el-card class="topCard">
|
<el-card class="topCard">
|
||||||
<el-radio-group v-model="activeNames">
|
<el-radio-group v-model="activeNames">
|
||||||
<el-radio-button class="topButton" size="large" label="all">全部</el-radio-button>
|
<el-radio-button class="topButton" size="large" label="all">全部</el-radio-button>
|
||||||
<el-radio-button class="topButton" size="large" label="user">用户设置</el-radio-button>
|
<el-radio-button class="topButton" size="large" label="panel">面板</el-radio-button>
|
||||||
<el-radio-button class="topButton" size="large" label="panel">面板设置</el-radio-button>
|
<el-radio-button class="topButton" size="large" label="safe">安全</el-radio-button>
|
||||||
<el-radio-button class="topButton" size="large" label="safe">安全设置</el-radio-button>
|
<el-radio-button class="topButton" size="large" label="backup">备份</el-radio-button>
|
||||||
<el-radio-button class="topButton" size="large" label="backup">备份设置</el-radio-button>
|
<el-radio-button class="topButton" size="large" label="monitor">监控</el-radio-button>
|
||||||
<el-radio-button class="topButton" size="large" label="monitor">监控设置</el-radio-button>
|
<el-radio-button class="topButton" size="large" label="message">通知</el-radio-button>
|
||||||
<el-radio-button class="topButton" size="large" label="message">通知设置</el-radio-button>
|
|
||||||
<el-radio-button class="topButton" size="large" label="about">关于</el-radio-button>
|
<el-radio-button class="topButton" size="large" label="about">关于</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-form :model="form" label-position="left" label-width="120px">
|
<Panel v-if="activeNames === 'all' || activeNames === 'panel'" :settingInfo="form" />
|
||||||
<el-card v-if="activeNames === 'all' || activeNames === 'user'" style="margin-top: 20px">
|
<Safe v-if="activeNames === 'all' || activeNames === 'safe'" :settingInfo="form" />
|
||||||
<template #header>
|
<Backup v-if="activeNames === 'all' || activeNames === 'backup'" :settingInfo="form" />
|
||||||
<div class="card-header">
|
<Monitor v-if="activeNames === 'all' || activeNames === 'monitor'" :settingInfo="form" />
|
||||||
<span>用户设置</span>
|
<Message v-if="activeNames === 'all' || activeNames === 'message'" :settingInfo="form" />
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="1"><br /></el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="用户名">
|
|
||||||
<el-input size="small" clearable v-model="form.userName" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="密码">
|
|
||||||
<el-input type="password" clearable show-password size="small" v-model="form.password" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="主题色">
|
|
||||||
<el-radio-group size="small" v-model="form.theme">
|
|
||||||
<el-radio-button label="black">
|
|
||||||
<el-icon><Moon /></el-icon>黑金
|
|
||||||
</el-radio-button>
|
|
||||||
<el-tooltip
|
|
||||||
effect="dark"
|
|
||||||
placement="top"
|
|
||||||
content="选择自动设置,将会在晚 6 点到次日早 6 点间自动切换到黑金主题。"
|
|
||||||
>
|
|
||||||
<el-radio-button label="auto" icon="Sunny">
|
|
||||||
<el-icon><MagicStick /></el-icon>自动
|
|
||||||
</el-radio-button>
|
|
||||||
</el-tooltip>
|
|
||||||
<el-radio-button label="write">
|
|
||||||
<el-icon><Sunny /></el-icon>白金
|
|
||||||
</el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="系统语言">
|
|
||||||
<el-radio-group size="small" v-model="form.language">
|
|
||||||
<el-radio-button label="ch">中文 </el-radio-button>
|
|
||||||
<el-radio-button label="en">English </el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button size="small" icon="Pointer">更新用户设置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-card>
|
|
||||||
<el-card v-if="activeNames === 'all' || activeNames === 'panel'" style="margin-top: 10px">
|
|
||||||
<template #header>
|
|
||||||
<div class="card-header">
|
|
||||||
<span>面板设置</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="1"><br /></el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="超时时间">
|
|
||||||
<el-input size="small" v-model="form.sessionTimeout" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="同步时间">
|
|
||||||
<el-input size="small" v-model="form.password" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-card>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, onMounted, reactive } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
import { getSettingInfo } from '@/api/modules/setting';
|
import { getSettingInfo } from '@/api/modules/setting';
|
||||||
import { Setting } from '@/api/interface/setting';
|
import { Setting } from '@/api/interface/setting';
|
||||||
|
import Panel from '@/views/setting/tabs/panel.vue';
|
||||||
|
import Safe from '@/views/setting/tabs/safe.vue';
|
||||||
|
import Backup from '@/views/setting/tabs/backup.vue';
|
||||||
|
import Monitor from '@/views/setting/tabs/monitor.vue';
|
||||||
|
import Message from '@/views/setting/tabs/message.vue';
|
||||||
|
|
||||||
const activeNames = ref('all');
|
const activeNames = ref('all');
|
||||||
let form = reactive<Setting.SettingInfo>({
|
let form = ref<Setting.SettingInfo>({
|
||||||
userName: '',
|
userName: '',
|
||||||
password: '',
|
password: '',
|
||||||
email: '',
|
email: '',
|
||||||
sessionTimeout: '',
|
sessionTimeout: '',
|
||||||
|
localTime: '',
|
||||||
panelName: '',
|
panelName: '',
|
||||||
theme: '',
|
theme: '',
|
||||||
language: '',
|
language: '',
|
||||||
serverPort: '',
|
serverPort: '',
|
||||||
securityEntrance: '',
|
securityEntrance: '',
|
||||||
|
passwordTimeOut: '',
|
||||||
complexityVerification: '',
|
complexityVerification: '',
|
||||||
mfaStatus: '',
|
mfaStatus: '',
|
||||||
monitorStatus: '',
|
monitorStatus: '',
|
||||||
@ -109,9 +54,10 @@ let form = reactive<Setting.SettingInfo>({
|
|||||||
|
|
||||||
const search = async () => {
|
const search = async () => {
|
||||||
const res = await getSettingInfo();
|
const res = await getSettingInfo();
|
||||||
console.log(res);
|
form.value = res.data;
|
||||||
form = res.data;
|
form.value.password = '******';
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
search();
|
search();
|
||||||
});
|
});
|
||||||
|
0
frontend/src/views/setting/tabs/about.vue
Normal file
0
frontend/src/views/setting/tabs/about.vue
Normal file
17
frontend/src/views/setting/tabs/backup.vue
Normal file
17
frontend/src/views/setting/tabs/backup.vue
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<template>
|
||||||
|
<el-card style="margin-top: 10px">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>备份</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="1"><br /></el-col>
|
||||||
|
<el-col :span="8"> </el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted } from 'vue';
|
||||||
|
onMounted(() => {});
|
||||||
|
</script>
|
152
frontend/src/views/setting/tabs/message.vue
Normal file
152
frontend/src/views/setting/tabs/message.vue
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
<template>
|
||||||
|
<el-form size="small" :model="form" label-position="left" label-width="120px">
|
||||||
|
<el-card style="margin-top: 10px">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>通知</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="1"><br /></el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="通知方式">
|
||||||
|
<el-radio-group v-model="form.settingInfo.messageType">
|
||||||
|
<el-radio-button label="none">关闭</el-radio-button>
|
||||||
|
<el-radio-button label="email">email</el-radio-button>
|
||||||
|
<el-radio-button label="wechat">企业微信</el-radio-button>
|
||||||
|
<el-radio-button label="dingding">钉钉</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<div v-if="form.settingInfo.messageType === 'none'">
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="SaveSetting()">关闭消息通知</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div v-if="form.settingInfo.messageType === 'email'">
|
||||||
|
<el-form-item label="邮箱服务名称">
|
||||||
|
<el-input clearable v-model="emailVars.serverName" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="邮箱地址">
|
||||||
|
<el-input clearable v-model="emailVars.serverAddr" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="邮箱SMTP授权码">
|
||||||
|
<el-input clearable v-model="emailVars.serverSMTP" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="SaveSetting()">保存并启用</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div v-if="form.settingInfo.messageType === 'wechat'">
|
||||||
|
<el-form-item label="orpid">
|
||||||
|
<el-input clearable v-model="weChatVars.orpid" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="corpsecret">
|
||||||
|
<el-input clearable v-model="weChatVars.corpsecret" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="touser">
|
||||||
|
<el-input clearable v-model="weChatVars.touser" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="agentid">
|
||||||
|
<el-input clearable v-model="weChatVars.agentid" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="SaveSetting()">保存并启用</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div v-if="form.settingInfo.messageType === 'dingding'">
|
||||||
|
<el-form-item label="webhook token">
|
||||||
|
<el-input clearable v-model="dingVars.webhookToken" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="密钥">
|
||||||
|
<el-input clearable v-model="dingVars.secret" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="邮箱 SMTP 授权码">
|
||||||
|
<el-input clearable v-model="emailVars.serverSMTP" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="SaveSetting()">保存并启用</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
import { updateSetting } from '@/api/modules/setting';
|
||||||
|
import i18n from '@/lang';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
settingInfo: any;
|
||||||
|
}
|
||||||
|
const form = withDefaults(defineProps<Props>(), {
|
||||||
|
settingInfo: {
|
||||||
|
messageType: '',
|
||||||
|
emailVars: '',
|
||||||
|
weChatVars: '',
|
||||||
|
dingVars: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emailVars = ref({
|
||||||
|
serverName: '',
|
||||||
|
serverAddr: '',
|
||||||
|
serverSMTP: '',
|
||||||
|
});
|
||||||
|
const weChatVars = ref({
|
||||||
|
orpid: '',
|
||||||
|
corpsecret: '',
|
||||||
|
touser: '',
|
||||||
|
agentid: '',
|
||||||
|
});
|
||||||
|
const dingVars = ref({
|
||||||
|
webhookToken: '',
|
||||||
|
secret: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const SaveSetting = async () => {
|
||||||
|
let settingKey = '';
|
||||||
|
let settingVal = '';
|
||||||
|
switch (form.settingInfo.messageType) {
|
||||||
|
case 'none':
|
||||||
|
settingVal = '';
|
||||||
|
break;
|
||||||
|
case 'email':
|
||||||
|
settingVal = JSON.stringify(emailVars.value);
|
||||||
|
settingKey = 'EmailVars';
|
||||||
|
break;
|
||||||
|
case 'wechat':
|
||||||
|
settingVal = JSON.stringify(emailVars.value);
|
||||||
|
settingKey = 'WeChatVars';
|
||||||
|
break;
|
||||||
|
case 'dingding':
|
||||||
|
settingVal = JSON.stringify(emailVars.value);
|
||||||
|
settingKey = 'DingVars';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let param = {
|
||||||
|
key: settingKey,
|
||||||
|
value: settingVal,
|
||||||
|
};
|
||||||
|
await updateSetting({ key: 'MessageType', value: form.settingInfo.messageType });
|
||||||
|
await updateSetting(param);
|
||||||
|
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
|
||||||
|
};
|
||||||
|
onMounted(() => {
|
||||||
|
switch (form.settingInfo.messageType) {
|
||||||
|
case 'email':
|
||||||
|
emailVars.value = JSON.parse(form.settingInfo.emailVars);
|
||||||
|
console.log(emailVars.value);
|
||||||
|
break;
|
||||||
|
case 'wechat':
|
||||||
|
weChatVars.value = JSON.parse(form.settingInfo.weChatVars);
|
||||||
|
break;
|
||||||
|
case 'dingding':
|
||||||
|
dingVars.value = JSON.parse(form.settingInfo.dingVars);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
64
frontend/src/views/setting/tabs/monitor.vue
Normal file
64
frontend/src/views/setting/tabs/monitor.vue
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<template>
|
||||||
|
<el-form size="small" :model="form" label-position="left" label-width="120px">
|
||||||
|
<el-card style="margin-top: 10px">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>监控</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="1"><br /></el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="开启监控">
|
||||||
|
<el-switch
|
||||||
|
v-model="form.settingInfo.monitorStatus"
|
||||||
|
active-value="enable"
|
||||||
|
inactive-value="disable"
|
||||||
|
@change="SaveSetting('MonitorStatus', form.settingInfo.monitorStatus)"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="过期时间">
|
||||||
|
<el-input clearable v-model="form.settingInfo.monitorStoreDays">
|
||||||
|
<template #append>
|
||||||
|
<el-button
|
||||||
|
@click="SaveSetting('MonitorStoreDays', form.settingInfo.monitorStoreDays)"
|
||||||
|
icon="Collection"
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button icon="Delete"> 清空监控记录 </el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
import { updateSetting } from '@/api/modules/setting';
|
||||||
|
import i18n from '@/lang';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
settingInfo: any;
|
||||||
|
}
|
||||||
|
const form = withDefaults(defineProps<Props>(), {
|
||||||
|
settingInfo: {
|
||||||
|
monitorStatus: '',
|
||||||
|
monitorStoreDays: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const SaveSetting = async (key: string, val: string) => {
|
||||||
|
let param = {
|
||||||
|
key: key,
|
||||||
|
value: val,
|
||||||
|
};
|
||||||
|
await updateSetting(param);
|
||||||
|
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
|
||||||
|
};
|
||||||
|
</script>
|
214
frontend/src/views/setting/tabs/panel.vue
Normal file
214
frontend/src/views/setting/tabs/panel.vue
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
<template>
|
||||||
|
<el-form size="small" :model="form" label-position="left" label-width="120px">
|
||||||
|
<el-card style="margin-top: 20px">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>面板</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="1"><br /></el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="用户名">
|
||||||
|
<el-input clearable v-model="form.settingInfo.userName">
|
||||||
|
<template #append>
|
||||||
|
<el-button
|
||||||
|
@click="SaveSetting('UserName', form.settingInfo.userName)"
|
||||||
|
icon="Collection"
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="密码">
|
||||||
|
<el-input type="password" clearable disabled v-model="form.settingInfo.password">
|
||||||
|
<template #append>
|
||||||
|
<el-button icon="Setting" @click="passwordVisiable = true">设置</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="邮箱">
|
||||||
|
<el-input clearable v-model="form.settingInfo.email">
|
||||||
|
<template #append>
|
||||||
|
<el-button @click="SaveSetting('Email', form.settingInfo.email)" icon="Collection">
|
||||||
|
保存
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
<div><span class="input-help">用于密码找回</span></div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="面板别名">
|
||||||
|
<el-input clearable v-model="form.settingInfo.panelName">
|
||||||
|
<template #append>
|
||||||
|
<el-button
|
||||||
|
@click="SaveSetting('PanelName', form.settingInfo.panelName)"
|
||||||
|
icon="Collection"
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="主题色">
|
||||||
|
<el-radio-group
|
||||||
|
@change="SaveSetting('Theme', form.settingInfo.theme)"
|
||||||
|
v-model="form.settingInfo.theme"
|
||||||
|
>
|
||||||
|
<el-radio-button label="black">
|
||||||
|
<el-icon><Moon /></el-icon>黑金
|
||||||
|
</el-radio-button>
|
||||||
|
<el-radio-button label="auto" icon="Sunny">
|
||||||
|
<el-icon><MagicStick /></el-icon>自动
|
||||||
|
</el-radio-button>
|
||||||
|
<el-radio-button label="write">
|
||||||
|
<el-icon><Sunny /></el-icon>白金
|
||||||
|
</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
<div>
|
||||||
|
<span class="input-help">
|
||||||
|
选择自动设置,将会在晚 6 点到次日早 6 点间自动切换到黑金主题。
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="系统语言">
|
||||||
|
<el-radio-group
|
||||||
|
@change="SaveSetting('Language', form.settingInfo.language)"
|
||||||
|
v-model="form.settingInfo.language"
|
||||||
|
>
|
||||||
|
<el-radio-button label="ch">中文 </el-radio-button>
|
||||||
|
<el-radio-button label="en">English </el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
<div>
|
||||||
|
<span class="input-help">
|
||||||
|
默认跟随浏览器语言,设置后只对当前浏览器生效,更换浏览器后需要重新设置。
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="超时时间">
|
||||||
|
<el-input v-model="form.settingInfo.sessionTimeout">
|
||||||
|
<template #append>
|
||||||
|
<el-button
|
||||||
|
@click="SaveSetting('SessionTimeout', form.settingInfo.sessionTimeout)"
|
||||||
|
icon="Collection"
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
<div>
|
||||||
|
<span class="input-help">如果用户超过 86400秒未操作面板,面板将自动退出登录 </span>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="同步时间">
|
||||||
|
<el-input v-model="form.settingInfo.localTime">
|
||||||
|
<template #append>
|
||||||
|
<el-button icon="Refresh">同步</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
</el-form>
|
||||||
|
<el-dialog v-model="passwordVisiable" title="密码修改" width="30%">
|
||||||
|
<el-form
|
||||||
|
size="small"
|
||||||
|
ref="passFormRef"
|
||||||
|
label-width="80px"
|
||||||
|
label-position="left"
|
||||||
|
:model="passForm"
|
||||||
|
:rules="passRules"
|
||||||
|
>
|
||||||
|
<el-form-item label="原密码" prop="oldPassword">
|
||||||
|
<el-input type="password" show-password clearable v-model="passForm.oldPassword" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="新密码" prop="newPassword">
|
||||||
|
<el-input type="password" show-password clearable v-model="passForm.newPassword" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="确认密码" prop="retryPassword">
|
||||||
|
<el-input type="password" show-password clearable v-model="passForm.retryPassword" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="passwordVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||||
|
<el-button @click="submitChangePassword()">
|
||||||
|
{{ $t('commons.button.confirm') }}
|
||||||
|
</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, reactive } from 'vue';
|
||||||
|
import { ElMessage, ElForm } from 'element-plus';
|
||||||
|
import { updateSetting } from '@/api/modules/setting';
|
||||||
|
import { Setting } from '@/api/interface/setting';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { GlobalStore } from '@/store';
|
||||||
|
import { useTheme } from '@/hooks/use-theme';
|
||||||
|
import { Rules } from '@/global/form-rues';
|
||||||
|
|
||||||
|
const i18n = useI18n();
|
||||||
|
const globalStore = GlobalStore();
|
||||||
|
|
||||||
|
type FormInstance = InstanceType<typeof ElForm>;
|
||||||
|
const passFormRef = ref<FormInstance>();
|
||||||
|
const passRules = reactive({
|
||||||
|
oldPassword: [Rules.requiredInput],
|
||||||
|
newPassword: [Rules.requiredInput],
|
||||||
|
retryPassword: [Rules.requiredInput, { validator: checkPassword, trigger: 'blur' }],
|
||||||
|
});
|
||||||
|
const passwordVisiable = ref<boolean>(false);
|
||||||
|
const passForm = reactive<Setting.PasswordUpdate>({
|
||||||
|
oldPassword: '',
|
||||||
|
newPassword: '',
|
||||||
|
retryPassword: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
settingInfo: any;
|
||||||
|
}
|
||||||
|
const form = withDefaults(defineProps<Props>(), {
|
||||||
|
settingInfo: {
|
||||||
|
userName: '',
|
||||||
|
password: '',
|
||||||
|
email: '',
|
||||||
|
sessionTimeout: '',
|
||||||
|
localTime: '',
|
||||||
|
panelName: '',
|
||||||
|
theme: '',
|
||||||
|
language: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { switchDark } = useTheme();
|
||||||
|
|
||||||
|
const SaveSetting = async (key: string, val: string) => {
|
||||||
|
switch (key) {
|
||||||
|
case 'Language':
|
||||||
|
i18n.locale.value = val;
|
||||||
|
globalStore.updateLanguage(val);
|
||||||
|
break;
|
||||||
|
case 'theme':
|
||||||
|
switchDark();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let param = {
|
||||||
|
key: key,
|
||||||
|
value: val,
|
||||||
|
};
|
||||||
|
await updateSetting(param);
|
||||||
|
ElMessage.success(i18n.t('commons.msg.operationSuccess'));
|
||||||
|
};
|
||||||
|
|
||||||
|
function checkPassword(rule: any, value: any, callback: any) {
|
||||||
|
if (passForm.newPassword !== passForm.retryPassword) {
|
||||||
|
return callback(new Error(i18n.t('commons.rule.rePassword')));
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
function submitChangePassword() {}
|
||||||
|
</script>
|
122
frontend/src/views/setting/tabs/safe.vue
Normal file
122
frontend/src/views/setting/tabs/safe.vue
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
<template>
|
||||||
|
<el-form size="small" :model="form" label-position="left" label-width="120px">
|
||||||
|
<el-card style="margin-top: 10px">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>安全</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="1"><br /></el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="面板端口">
|
||||||
|
<el-input clearable v-model="form.settingInfo.serverPort">
|
||||||
|
<template #append>
|
||||||
|
<el-button
|
||||||
|
@click="SaveSetting('ServerPort', form.settingInfo.serverPort)"
|
||||||
|
icon="Collection"
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
<el-tooltip
|
||||||
|
class="box-item"
|
||||||
|
effect="dark"
|
||||||
|
content="Top Left prompts info"
|
||||||
|
placement="top-start"
|
||||||
|
>
|
||||||
|
<el-icon style="font-size: 14px; margin-top: 8px"><WarningFilled /></el-icon>
|
||||||
|
</el-tooltip>
|
||||||
|
</el-input>
|
||||||
|
<div>
|
||||||
|
<span class="input-help">
|
||||||
|
建议端口范围8888 - 65535,注意:有安全组的服务器请提前在安全组放行新端口
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="安全入口">
|
||||||
|
<el-input clearable v-model="form.settingInfo.securityEntrance">
|
||||||
|
<template #append>
|
||||||
|
<el-button
|
||||||
|
@click="SaveSetting('SecurityEntrance', form.settingInfo.securityEntrance)"
|
||||||
|
icon="Collection"
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
<div>
|
||||||
|
<span class="input-help">
|
||||||
|
面板管理入口,设置后只能通过指定安全入口登录面板,如: /89dc6ae8
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="密码过期时间">
|
||||||
|
<el-input clearable v-model="form.settingInfo.passwordTimeOut">
|
||||||
|
<template #append>
|
||||||
|
<el-button
|
||||||
|
@click="SaveSetting('Password', form.settingInfo.passwordTimeOut)"
|
||||||
|
icon="Collection"
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
<div>
|
||||||
|
<span class="input-help"> 为面板密码设置过期时间,过期后需要重新设置密码 </span>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="密码复杂度验证">
|
||||||
|
<el-switch
|
||||||
|
v-model="form.settingInfo.complexityVerification"
|
||||||
|
active-value="enable"
|
||||||
|
inactive-value="disable"
|
||||||
|
@change="SaveSetting('ComplexityVerification', form.settingInfo.complexityVerification)"
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<span class="input-help">
|
||||||
|
密码必须满足密码长度大于8位且大写字母、小写字母、数字、特殊字符至少3项组合
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="两步验证">
|
||||||
|
<el-switch
|
||||||
|
v-model="form.settingInfo.mfaStatus"
|
||||||
|
active-value="enable"
|
||||||
|
inactive-value="disable"
|
||||||
|
@change="SaveSetting('MFAStatus', form.settingInfo.mfaStatus)"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ElMessage, ElForm } from 'element-plus';
|
||||||
|
import { updateSetting } from '@/api/modules/setting';
|
||||||
|
import i18n from '@/lang';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
settingInfo: any;
|
||||||
|
}
|
||||||
|
const form = withDefaults(defineProps<Props>(), {
|
||||||
|
settingInfo: {
|
||||||
|
serverPort: '',
|
||||||
|
securityEntrance: '',
|
||||||
|
passwordTimeOut: '',
|
||||||
|
complexityVerification: '',
|
||||||
|
mfaStatus: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const SaveSetting = async (key: string, val: string) => {
|
||||||
|
let param = {
|
||||||
|
key: key,
|
||||||
|
value: val,
|
||||||
|
};
|
||||||
|
await updateSetting(param);
|
||||||
|
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
|
||||||
|
};
|
||||||
|
</script>
|
@ -1,7 +0,0 @@
|
|||||||
<template>
|
|
||||||
<LayoutContent></LayoutContent>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import LayoutContent from '@/layout/layout-content.vue';
|
|
||||||
</script>
|
|
Loading…
x
Reference in New Issue
Block a user