1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-19 16:29:17 +08:00

feat: 增加设置默认网站功能

This commit is contained in:
zhengkunwang223 2023-01-03 16:56:36 +08:00 committed by zhengkunwang223
parent 6d290f6a73
commit 869f552cf8
16 changed files with 189 additions and 26 deletions

View File

@ -2,7 +2,7 @@
"formFields": [
{
"type": "password",
"labelZh": "Root用户密码",
"labelZh": "root用户密码",
"labelEn": "RootPassword",
"required": true,
"default": "random",

View File

@ -2,7 +2,7 @@
"formFields": [
{
"type": "password",
"labelZh": "Root用户密码",
"labelZh": "root用户密码",
"labelEn": "RootPassword",
"required": true,
"default": "random",

View File

@ -26,6 +26,15 @@ func (b *BaseApi) PageWebsite(c *gin.Context) {
})
}
func (b *BaseApi) GetWebsites(c *gin.Context) {
websites, err := websiteService.GetWebsites()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, websites)
}
func (b *BaseApi) GetWebsiteOptions(c *gin.Context) {
websites, err := websiteService.GetWebsiteOptions()
if err != nil {
@ -334,3 +343,16 @@ func (b *BaseApi) OpWebsiteLog(c *gin.Context) {
}
helper.SuccessWithData(c, res)
}
func (b *BaseApi) ChangeDefaultServer(c *gin.Context) {
var req request.WebsiteDefaultUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.ChangeDefaultServer(req.ID); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}

View File

@ -122,3 +122,7 @@ type WebsiteLogReq struct {
Operate string `json:"operate" validate:"required"`
LogType string `json:"logType" validate:"required"`
}
type WebsiteDefaultUpdate struct {
ID uint `json:"id" validate:"required"`
}

View File

@ -18,6 +18,7 @@ type Website struct {
Proxy string `gorm:"type:varchar(128);not null" json:"proxy"`
ErrorLog bool `json:"errorLog"`
AccessLog bool `json:"accessLog"`
DefaultServer bool `json:"defaultServer"`
Domains []WebsiteDomain `json:"domains"`
WebsiteSSL WebsiteSSL `json:"webSiteSSL"`
}

View File

@ -14,6 +14,7 @@ type IWebsiteRepo interface {
WithAlias(alias string) DBOption
WithWebsiteSSLID(sslId uint) DBOption
WithGroupID(groupId uint) DBOption
WithDefaultServer() DBOption
Page(page, size int, opts ...DBOption) (int64, []model.Website, error)
List(opts ...DBOption) ([]model.Website, error)
GetFirst(opts ...DBOption) (model.Website, error)
@ -60,6 +61,12 @@ func (w *WebsiteRepo) WithGroupID(groupId uint) DBOption {
}
}
func (w *WebsiteRepo) WithDefaultServer() DBOption {
return func(db *gorm.DB) *gorm.DB {
return db.Where("default_server = 1")
}
}
func (w *WebsiteRepo) Page(page, size int, opts ...DBOption) (int64, []model.Website, error) {
var websites []model.Website
db := getDb(opts...).Model(&model.Website{})

View File

@ -29,6 +29,7 @@ type WebsiteService struct {
type IWebsiteService interface {
PageWebsite(req request.WebsiteSearch) (int64, []response.WebsiteDTO, error)
GetWebsites() ([]response.WebsiteDTO, error)
CreateWebsite(create request.WebsiteCreate) error
OpWebsite(req request.WebsiteOp) error
GetWebsiteOptions() ([]string, error)
@ -81,6 +82,20 @@ func (w WebsiteService) PageWebsite(req request.WebsiteSearch) (int64, []respons
return total, websiteDTOs, nil
}
func (w WebsiteService) GetWebsites() ([]response.WebsiteDTO, error) {
var websiteDTOs []response.WebsiteDTO
websites, err := websiteRepo.List()
if err != nil {
return nil, err
}
for _, web := range websites {
websiteDTOs = append(websiteDTOs, response.WebsiteDTO{
Website: web,
})
}
return websiteDTOs, nil
}
func (w WebsiteService) CreateWebsite(create request.WebsiteCreate) error {
if exist, _ := websiteRepo.GetBy(websiteRepo.WithDomain(create.PrimaryDomain)); len(exist) > 0 {
return buserr.New(constant.ErrNameIsExist)
@ -777,3 +792,25 @@ func (w WebsiteService) OpWebsiteLog(req request.WebsiteLogReq) (*response.Websi
}
return res, nil
}
func (w WebsiteService) ChangeDefaultServer(id uint) error {
defaultWebsite, _ := websiteRepo.GetFirst(websiteRepo.WithDefaultServer())
if defaultWebsite.ID > 0 {
if err := updateNginxConfig(constant.NginxScopeServer, []dto.NginxParam{{Name: "listen", Params: []string{"80"}}}, &defaultWebsite); err != nil {
return err
}
defaultWebsite.DefaultServer = false
if err := websiteRepo.Save(context.Background(), &defaultWebsite); err != nil {
return err
}
}
website, err := websiteRepo.GetFirst(commonRepo.WithByID(id))
if err != nil {
return err
}
if err := updateNginxConfig(constant.NginxScopeServer, []dto.NginxParam{{Name: "listen", Params: []string{"80", "default_server"}}}, &website); err != nil {
return err
}
website.DefaultServer = true
return websiteRepo.Save(context.Background(), &website)
}

View File

@ -314,10 +314,10 @@ func applySSL(website model.Website, websiteSSL model.WebsiteSSL, req request.We
server.RemoveListenByBind("80")
server.RemoveDirective("if", []string{"($scheme"})
case constant.HTTPToHTTPS:
server.UpdateListen("80", false)
server.UpdateListen("80", website.DefaultServer)
server.AddHTTP2HTTPS()
case constant.HTTPAlso:
server.UpdateListen("80", false)
server.UpdateListen("80", website.DefaultServer)
server.RemoveDirective("if", []string{"($scheme"})
}

View File

@ -16,6 +16,7 @@ func (a *WebsiteRouter) InitWebsiteRouter(Router *gin.RouterGroup) {
baseApi := v1.ApiGroupApp.BaseApi
{
groupRouter.POST("/search", baseApi.PageWebsite)
groupRouter.GET("/list", baseApi.GetWebsites)
groupRouter.POST("", baseApi.CreateWebsite)
groupRouter.POST("/operate", baseApi.OpWebsite)
groupRouter.POST("/log", baseApi.OpWebsiteLog)
@ -40,5 +41,6 @@ func (a *WebsiteRouter) InitWebsiteRouter(Router *gin.RouterGroup) {
groupRouter.POST("/waf/config", baseApi.GetWebsiteWafConfig)
groupRouter.POST("/waf/update", baseApi.UpdateWebsiteWafConfig)
groupRouter.POST("/nginx/update", baseApi.UpdateWebsiteNginxConfig)
groupRouter.POST("/default/server", baseApi.ChangeDefaultServer)
}
}

View File

@ -32,23 +32,6 @@ func (b *Block) FindDirectives(directiveName string) []IDirective {
return directives
}
//func (b *Block) UpdateDirectives(directiveName string, directive Directive) {
// directives := b.GetDirectives()
// index := -1
// for i, dir := range directives {
// if dir.GetName() == directiveName {
// index = i
// break
// }
// }
// if index > -1 {
// directives[index] = &directive
// } else {
// directives = append(directives, &directive)
// }
// b.Directives = directives
//}
func (b *Block) UpdateDirective(key string, params []string) {
if key == "" || len(params) == 0 {
return

View File

@ -73,6 +73,19 @@ func (s *Server) UpdateDirective(key string, params []string) {
if key == "" || len(params) == 0 {
return
}
if key == "listen" {
defaultServer := false
if len(params) > 1 && params[1] == "default_server" {
defaultServer = true
}
if len(params) > 2 {
s.UpdateListen(params[0], defaultServer, params[2:]...)
} else {
s.UpdateListen(params[0], defaultServer)
}
return
}
directives := s.Directives
index := -1
for i, dir := range directives {

View File

@ -11,6 +11,7 @@ export namespace Website {
appInstallId?: number;
webSiteGroupId: number;
otherDomains: string;
defaultServer: boolean;
appinstall?: NewAppInstall;
webSiteSSL: SSL;
}
@ -271,4 +272,8 @@ export namespace Website {
id: number;
content: string;
}
export interface DefaultServerUpdate {
id: number;
}
}

View File

@ -7,6 +7,10 @@ export const SearchWebsites = (req: Website.WebSiteSearch) => {
return http.post<ResPage<Website.Website>>(`/websites/search`, req);
};
export const ListWebsites = () => {
return http.get<Website.WebsiteDTO>(`/websites/list`);
};
export const CreateWebsite = (req: Website.WebSiteCreateReq) => {
return http.post<any>(`/websites`, req);
};
@ -174,3 +178,7 @@ export const UpdateWafEnable = (req: Website.WafUpdate) => {
export const UpdateNginxFile = (req: Website.NginxUpdate) => {
return http.post<any>(`/websites/nginx/update`, req);
};
export const ChangeDefaultServer = (req: Website.DefaultServerUpdate) => {
return http.post<any>(`/websites/default/server`, req);
};

View File

@ -959,6 +959,8 @@ export default {
nextYear: '一年后',
allGroup: '所有分组',
noLog: '当前没有日志...',
defaulServer: '默认网站',
noDefaulServer: '当前没有默认网站',
},
nginx: {
serverNamesHashBucketSizeHelper: '服务器名字的hash表大小',

View File

@ -0,0 +1,70 @@
<template>
<el-dialog
v-model="open"
:title="$t('website.defaulServer')"
width="20%"
@close="handleClose"
:close-on-click-modal="false"
>
<div style="text-align: center">
<el-select v-model="defaultId">
<el-option :value="0" :key="-1" :label="$t('website.noDefaulServer')"></el-option>
<el-option
v-for="(website, key) in websites"
:key="key"
:value="website.id"
:label="website.primaryDomain"
></el-option>
</el-select>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
<el-button type="primary" @click="submit()" :disabled="loading">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { Website } from '@/api/interface/Website';
import { ChangeDefaultServer, ListWebsites } from '@/api/modules/website';
import i18n from '@/lang';
import { ElMessage } from 'element-plus';
import { ref } from 'vue';
let open = ref(false);
let websites = ref<any>();
let defaultId = ref(-1);
let loading = ref(false);
const acceptParams = () => {
defaultId.value = 0;
get();
open.value = true;
};
const handleClose = () => {
open.value = false;
};
const get = async () => {
const res = await ListWebsites();
websites.value = res.data;
websites.value.forEach((website: Website.WebsiteDTO) => {
if (website.defaultServer) {
defaultId.value = website.id;
}
});
};
const submit = () => {
ChangeDefaultServer({ id: defaultId.value }).then(() => {
ElMessage.success(i18n.global.t('commons.msg.updateSuccess'));
handleClose();
});
};
defineExpose({ acceptParams });
</script>

View File

@ -16,6 +16,9 @@
<el-button type="primary" plain @click="openGroup">
{{ $t('website.group') }}
</el-button>
<el-button type="primary" plain @click="openDefault">
{{ $t('website.defaulServer') }}
</el-button>
</el-col>
<el-col :span="14">
<div style="float: right">
@ -120,6 +123,7 @@
<WebSiteGroup ref="groupRef"></WebSiteGroup>
<UploadDialog ref="uploadRef" />
<BackupRecords ref="dialogBackupRef" />
<DefaultServer ref="defaultRef" />
</LayoutContent>
</div>
<div v-if="nginxIsExist">
@ -127,7 +131,6 @@
<span style="font-size: 14px">{{ $t('commons.service.serviceNotStarted', ['OpenResty']) }}</span>
</el-card>
</div>
<el-card v-if="openNginxConfig">
<NginxConfig :containerName="containerName" :status="nginxStatus"></NginxConfig>
</el-card>
@ -138,6 +141,7 @@
import LayoutContent from '@/layout/layout-content.vue';
import BackupRecords from '@/views/website/website/backup/index.vue';
import UploadDialog from '@/views/website/website/upload/index.vue';
import DefaultServer from '@/views/website/website/default/index.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import { onMounted, reactive, ref } from '@vue/runtime-core';
import CreateWebSite from './create/index.vue';
@ -181,25 +185,26 @@ let nginxStatus = ref('');
let installPath = ref('');
const uploadRef = ref();
const dialogBackupRef = ref();
const defaultRef = ref();
const data = ref();
let dateRefs: Map<number, any> = new Map();
let groups = ref<Website.Group[]>([]);
const paginationConfig = reactive({
currentPage: 1,
pageSize: 20,
pageSize: 15,
total: 0,
});
let req = reactive({
name: '',
page: paginationConfig.currentPage,
pageSize: paginationConfig.pageSize,
page: 1,
pageSize: 15,
websiteGroupId: 0,
});
const search = async () => {
req.page = paginationConfig.currentPage;
req.pageSize = paginationConfig.currentPage;
req.pageSize = paginationConfig.pageSize;
SearchWebsites(req).then((res) => {
data.value = res.data.items;
paginationConfig.total = res.data.total;
@ -330,6 +335,10 @@ const openGroup = () => {
groupRef.value.acceptParams();
};
const openDefault = () => {
defaultRef.value.acceptParams();
};
const checkExist = (data: App.CheckInstalled) => {
nginxIsExist.value = data.isExist;
containerName.value = data.containerName;