mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2024-11-24 11:09:16 +08:00
style: 增加分页
This commit is contained in:
parent
95b18ebc89
commit
6ceb040061
@ -15,4 +15,5 @@ var (
|
||||
commandService = service.ServiceGroupApp.CommandService
|
||||
operationService = service.ServiceGroupApp.OperationService
|
||||
fileService = service.ServiceGroupApp.FileService
|
||||
settingService = service.ServiceGroupApp.SettingService
|
||||
)
|
||||
|
36
backend/app/api/v1/setting.go
Normal file
36
backend/app/api/v1/setting.go
Normal file
@ -0,0 +1,36 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/constant"
|
||||
"github.com/1Panel-dev/1Panel/global"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func (b *BaseApi) GetSettingInfo(c *gin.Context) {
|
||||
setting, err := settingService.GetSettingInfo()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, setting)
|
||||
}
|
||||
|
||||
func (b *BaseApi) UpdateInfo(c *gin.Context) {
|
||||
var req dto.SettingUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := settingService.Update(req.Key, req.Value); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
31
backend/app/dto/setting.go
Normal file
31
backend/app/dto/setting.go
Normal file
@ -0,0 +1,31 @@
|
||||
package dto
|
||||
|
||||
type SettingInfo struct {
|
||||
UserName string `json:"userName"`
|
||||
Password string `json:"password"`
|
||||
Email string `json:"email"`
|
||||
|
||||
SessionTimeout string `json:"sessionTimeout"`
|
||||
|
||||
PanelName string `json:"panelName"`
|
||||
Theme string `json:"theme"`
|
||||
Language string `json:"language"`
|
||||
|
||||
ServerPort string `json:"serverPort"`
|
||||
SecurityEntrance string `json:"securityEntrance"`
|
||||
ComplexityVerification string `json:"complexityVerification"`
|
||||
MFAStatus string `json:"mfaStatus"`
|
||||
|
||||
MonitorStatus string `json:"monitorStatus"`
|
||||
MonitorStoreDays string `json:"monitorStoreDays"`
|
||||
|
||||
MessageType string `json:"messageType"`
|
||||
EmailVars string `json:"emailVars"`
|
||||
WeChatVars string `json:"weChatVars"`
|
||||
DingVars string `json:"dingVars"`
|
||||
}
|
||||
|
||||
type SettingUpdate struct {
|
||||
Key string `json:"key" validate:"required"`
|
||||
Value string `json:"value"`
|
||||
}
|
10
backend/app/model/setting.go
Normal file
10
backend/app/model/setting.go
Normal file
@ -0,0 +1,10 @@
|
||||
package model
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type Setting struct {
|
||||
gorm.Model
|
||||
Key string `json:"key" gorm:"type:varchar(256);not null;"`
|
||||
Value string `json:"value" gorm:"type:varchar(256)"`
|
||||
About string `json:"about" gorm:"type:longText"`
|
||||
}
|
@ -7,6 +7,7 @@ type RepoGroup struct {
|
||||
CommandRepo
|
||||
OperationRepo
|
||||
CommonRepo
|
||||
SettingRepo
|
||||
}
|
||||
|
||||
var RepoGroupApp = new(RepoGroup)
|
||||
|
31
backend/app/repo/setting.go
Normal file
31
backend/app/repo/setting.go
Normal file
@ -0,0 +1,31 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/app/model"
|
||||
"github.com/1Panel-dev/1Panel/global"
|
||||
)
|
||||
|
||||
type SettingRepo struct{}
|
||||
|
||||
type ISettingRepo interface {
|
||||
Get(opts ...DBOption) ([]model.Setting, error)
|
||||
Update(key, value string) error
|
||||
}
|
||||
|
||||
func NewISettingService() ISettingRepo {
|
||||
return &SettingRepo{}
|
||||
}
|
||||
|
||||
func (u *SettingRepo) Get(opts ...DBOption) ([]model.Setting, error) {
|
||||
var settings []model.Setting
|
||||
db := global.DB.Model(&model.Setting{})
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
err := db.Find(&settings).Error
|
||||
return settings, err
|
||||
}
|
||||
|
||||
func (u *SettingRepo) Update(key, value string) error {
|
||||
return global.DB.Model(&model.Setting{}).Where("key = ?", key).Updates(map[string]interface{}{"value": value}).Error
|
||||
}
|
@ -9,6 +9,7 @@ type ServiceGroup struct {
|
||||
CommandService
|
||||
OperationService
|
||||
FileService
|
||||
SettingService
|
||||
}
|
||||
|
||||
var ServiceGroupApp = new(ServiceGroup)
|
||||
@ -20,4 +21,5 @@ var (
|
||||
commandRepo = repo.RepoGroupApp.CommandRepo
|
||||
operationRepo = repo.RepoGroupApp.OperationRepo
|
||||
commonRepo = repo.RepoGroupApp.CommonRepo
|
||||
settingRepo = repo.RepoGroupApp.SettingRepo
|
||||
)
|
||||
|
43
backend/app/service/setting.go
Normal file
43
backend/app/service/setting.go
Normal file
@ -0,0 +1,43 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/constant"
|
||||
)
|
||||
|
||||
type SettingService struct{}
|
||||
|
||||
type ISettingService interface {
|
||||
GetSettingInfo() (*dto.SettingInfo, error)
|
||||
Update(key, value string) error
|
||||
}
|
||||
|
||||
func NewISettingService() ISettingService {
|
||||
return &SettingService{}
|
||||
}
|
||||
|
||||
func (u *SettingService) GetSettingInfo() (*dto.SettingInfo, error) {
|
||||
setting, err := settingRepo.Get()
|
||||
if err != nil {
|
||||
return nil, constant.ErrRecordNotFound
|
||||
}
|
||||
settingMap := make(map[string]string)
|
||||
for _, set := range setting {
|
||||
settingMap[set.Key] = set.Value
|
||||
}
|
||||
var info dto.SettingInfo
|
||||
arr, err := json.Marshal(settingMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := json.Unmarshal(arr, &info); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &info, err
|
||||
}
|
||||
|
||||
func (u *SettingService) Update(key, value string) error {
|
||||
return settingRepo.Update(key, value)
|
||||
}
|
@ -13,7 +13,8 @@ func Init() {
|
||||
migrations.AddData,
|
||||
migrations.AddTableOperationLog,
|
||||
migrations.AddTableHost,
|
||||
migrations.AddTablemonitor,
|
||||
migrations.AddTableMonitor,
|
||||
migrations.AddTableSetting,
|
||||
})
|
||||
if err := m.Migrate(); err != nil {
|
||||
global.LOG.Error(err)
|
||||
|
@ -54,9 +54,75 @@ var AddTableHost = &gormigrate.Migration{
|
||||
},
|
||||
}
|
||||
|
||||
var AddTablemonitor = &gormigrate.Migration{
|
||||
var AddTableMonitor = &gormigrate.Migration{
|
||||
ID: "20200905-add-table-monitor",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
return tx.AutoMigrate(&model.MonitorBase{}, &model.MonitorIO{}, &model.MonitorNetwork{})
|
||||
},
|
||||
}
|
||||
|
||||
var AddTableSetting = &gormigrate.Migration{
|
||||
ID: "20200908-add-table-setting",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
if err := tx.AutoMigrate(&model.Setting{}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&model.Setting{Key: "UserName", Value: "admin"}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&model.Setting{Key: "Password", Value: "5WYEZ4XcitdomVvAyimt9WwJwBJJSbTTHncZoqyOraQ="}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&model.Setting{Key: "Email", Value: ""}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Create(&model.Setting{Key: "PanelName", Value: "1Panel"}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&model.Setting{Key: "Language", Value: "ch"}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&model.Setting{Key: "Theme", Value: "auto"}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Create(&model.Setting{Key: "SessionTimeout", Value: "86400"}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Create(&model.Setting{Key: "ServerPort", Value: "4004"}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&model.Setting{Key: "SecurityEntrance", Value: "/89dc6ae8"}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&model.Setting{Key: "ComplexityVerification", Value: "enable"}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&model.Setting{Key: "MFAStatus", Value: "disable"}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Create(&model.Setting{Key: "MonitorStatus", Value: "enable"}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&model.Setting{Key: "MonitorStoreDays", Value: "30"}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Create(&model.Setting{Key: "MessageType", Value: "none"}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&model.Setting{Key: "EmailVars", Value: ""}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&model.Setting{Key: "WeChatVars", Value: ""}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&model.Setting{Key: "DingVars", Value: ""}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ func Routers() *gin.Engine {
|
||||
systemRouter.InitMonitorRouter(PrivateGroup)
|
||||
systemRouter.InitOperationLogRouter(PrivateGroup)
|
||||
systemRouter.InitFileRouter(PrivateGroup)
|
||||
systemRouter.InitSettingRouter(PrivateGroup)
|
||||
}
|
||||
|
||||
return Router
|
||||
|
@ -9,6 +9,7 @@ type RouterGroup struct {
|
||||
MonitorRouter
|
||||
OperationLogRouter
|
||||
FileRouter
|
||||
SettingRouter
|
||||
}
|
||||
|
||||
var RouterGroupApp = new(RouterGroup)
|
||||
|
17
backend/router/ro_setting.go
Normal file
17
backend/router/ro_setting.go
Normal file
@ -0,0 +1,17 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
v1 "github.com/1Panel-dev/1Panel/app/api/v1"
|
||||
"github.com/1Panel-dev/1Panel/middleware"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type SettingRouter struct{}
|
||||
|
||||
func (s *SettingRouter) InitSettingRouter(Router *gin.RouterGroup) {
|
||||
monitorRouter := Router.Group("settings").Use(middleware.JwtAuth()).Use(middleware.SessionAuth())
|
||||
baseApi := v1.ApiGroupApp.BaseApi
|
||||
{
|
||||
monitorRouter.POST("/search", baseApi.GetSettingInfo)
|
||||
}
|
||||
}
|
26
frontend/src/api/interface/setting.ts
Normal file
26
frontend/src/api/interface/setting.ts
Normal file
@ -0,0 +1,26 @@
|
||||
export namespace Setting {
|
||||
export interface SettingInfo {
|
||||
userName: string;
|
||||
password: string;
|
||||
email: string;
|
||||
|
||||
sessionTimeout: string;
|
||||
|
||||
panelName: string;
|
||||
theme: string;
|
||||
language: string;
|
||||
|
||||
serverPort: string;
|
||||
securityEntrance: string;
|
||||
complexityVerification: string;
|
||||
mfaStatus: string;
|
||||
|
||||
monitorStatus: string;
|
||||
monitorStoreDays: string;
|
||||
|
||||
messageType: string;
|
||||
emailVars: string;
|
||||
weChatVars: string;
|
||||
dingVars: string;
|
||||
}
|
||||
}
|
6
frontend/src/api/modules/setting.ts
Normal file
6
frontend/src/api/modules/setting.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import http from '@/api';
|
||||
import { Setting } from '../interface/setting';
|
||||
|
||||
export const getSettingInfo = () => {
|
||||
return http.post<Setting.SettingInfo>(`/settings/search`);
|
||||
};
|
@ -100,6 +100,7 @@ export default {
|
||||
monitor: 'Monitor',
|
||||
operations: 'Operation Records',
|
||||
files: 'File Management',
|
||||
settings: 'Setting',
|
||||
},
|
||||
home: {
|
||||
welcome: 'Welcome',
|
||||
|
@ -100,6 +100,7 @@ export default {
|
||||
monitor: '监控',
|
||||
operations: '操作记录',
|
||||
files: '文件管理',
|
||||
settings: '系统设置',
|
||||
},
|
||||
home: {
|
||||
welcome: '欢迎使用',
|
||||
|
25
frontend/src/routers/modules/setting.ts
Normal file
25
frontend/src/routers/modules/setting.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { Layout } from '@/routers/constant';
|
||||
|
||||
const settingRouter = {
|
||||
sort: 3,
|
||||
path: '/settings',
|
||||
component: Layout,
|
||||
redirect: '/setting',
|
||||
meta: {
|
||||
title: 'menu.settings',
|
||||
icon: 'Setting',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/setting',
|
||||
name: 'Setting',
|
||||
component: () => import('@/views/setting/index.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
key: 'Setting',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default settingRouter;
|
150
frontend/src/views/setting/index.vue
Normal file
150
frontend/src/views/setting/index.vue
Normal file
@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<div class="demo-collapse">
|
||||
<el-card class="topCard">
|
||||
<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="user">用户设置</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="backup">备份设置</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="about">关于</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-card>
|
||||
<el-form :model="form" label-position="left" label-width="120px">
|
||||
<el-card v-if="activeNames === 'all' || activeNames === 'user'" 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 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>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, reactive } from 'vue';
|
||||
import { getSettingInfo } from '@/api/modules/setting';
|
||||
import { Setting } from '@/api/interface/setting';
|
||||
|
||||
const activeNames = ref('all');
|
||||
let form = reactive<Setting.SettingInfo>({
|
||||
userName: '',
|
||||
password: '',
|
||||
email: '',
|
||||
sessionTimeout: '',
|
||||
panelName: '',
|
||||
theme: '',
|
||||
language: '',
|
||||
serverPort: '',
|
||||
securityEntrance: '',
|
||||
complexityVerification: '',
|
||||
mfaStatus: '',
|
||||
monitorStatus: '',
|
||||
monitorStoreDays: '',
|
||||
messageType: '',
|
||||
emailVars: '',
|
||||
weChatVars: '',
|
||||
dingVars: '',
|
||||
});
|
||||
|
||||
const search = async () => {
|
||||
const res = await getSettingInfo();
|
||||
console.log(res);
|
||||
form = res.data;
|
||||
};
|
||||
onMounted(() => {
|
||||
search();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.topCard {
|
||||
--el-card-border-color: var(--el-border-color-light);
|
||||
--el-card-border-radius: 4px;
|
||||
--el-card-padding: 0px;
|
||||
--el-card-bg-color: var(--el-fill-color-blank);
|
||||
}
|
||||
.topButton .el-radio-button__inner {
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
background: var(--el-button-bg-color, var(--el-fill-color-blank));
|
||||
border: 0;
|
||||
font-weight: 350;
|
||||
border-left: 0;
|
||||
color: var(--el-button-text-color, var(--el-text-color-regular));
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
outline: 0;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: var(--el-transition-all);
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
padding: 8px 15px;
|
||||
font-size: var(--el-font-size-base);
|
||||
border-radius: 0;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user