mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-03-14 01:34:47 +08:00
feat: 负载均衡增加源文编辑 (#6153)
This commit is contained in:
parent
bf82fe743c
commit
7fb42d7b47
@ -917,3 +917,43 @@ func (b *BaseApi) DeleteLoadBalance(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
helper.SuccessWithOutData(c)
|
helper.SuccessWithOutData(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Website
|
||||||
|
// @Summary Update website upstream
|
||||||
|
// @Description 更新网站 upstream
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsiteLBUpdate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /websites/lbs/update [post]
|
||||||
|
func (b *BaseApi) UpdateLoadBalance(c *gin.Context) {
|
||||||
|
var req request.WebsiteLBUpdate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := websiteService.UpdateLoadBalance(req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithOutData(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Website
|
||||||
|
// @Summary Update website upstream file
|
||||||
|
// @Description 更新网站 upstream 文件
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsiteLBUpdateFile true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /websites/lbs/file [post]
|
||||||
|
func (b *BaseApi) UpdateLoadBalanceFile(c *gin.Context) {
|
||||||
|
var req request.WebsiteLBUpdateFile
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := websiteService.UpdateLoadBalanceFile(req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithOutData(c)
|
||||||
|
}
|
||||||
|
@ -69,6 +69,7 @@ type NginxUpstream struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Algorithm string `json:"algorithm"`
|
Algorithm string `json:"algorithm"`
|
||||||
Servers []NginxUpstreamServer `json:"servers"`
|
Servers []NginxUpstreamServer `json:"servers"`
|
||||||
|
Content string `json:"content"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NginxUpstreamServer struct {
|
type NginxUpstreamServer struct {
|
||||||
|
@ -264,7 +264,20 @@ type WebsiteLBCreate struct {
|
|||||||
Servers []dto.NginxUpstreamServer `json:"servers"`
|
Servers []dto.NginxUpstreamServer `json:"servers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WebsiteLBUpdate struct {
|
||||||
|
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
Algorithm string `json:"algorithm"`
|
||||||
|
Servers []dto.NginxUpstreamServer `json:"servers"`
|
||||||
|
}
|
||||||
|
|
||||||
type WebsiteLBDelete struct {
|
type WebsiteLBDelete struct {
|
||||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WebsiteLBUpdateFile struct {
|
||||||
|
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
Content string `json:"content" validate:"required"`
|
||||||
|
}
|
||||||
|
@ -112,6 +112,8 @@ type IWebsiteService interface {
|
|||||||
GetLoadBalances(id uint) ([]dto.NginxUpstream, error)
|
GetLoadBalances(id uint) ([]dto.NginxUpstream, error)
|
||||||
CreateLoadBalance(req request.WebsiteLBCreate) error
|
CreateLoadBalance(req request.WebsiteLBCreate) error
|
||||||
DeleteLoadBalance(req request.WebsiteLBDelete) error
|
DeleteLoadBalance(req request.WebsiteLBDelete) error
|
||||||
|
UpdateLoadBalance(req request.WebsiteLBUpdate) error
|
||||||
|
UpdateLoadBalanceFile(req request.WebsiteLBUpdateFile) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIWebsiteService() IWebsiteService {
|
func NewIWebsiteService() IWebsiteService {
|
||||||
@ -2934,6 +2936,11 @@ func (w WebsiteService) GetLoadBalances(id uint) ([]dto.NginxUpstream, error) {
|
|||||||
Name: upstreamName,
|
Name: upstreamName,
|
||||||
}
|
}
|
||||||
upstreamPath := path.Join(includeDir, name)
|
upstreamPath := path.Join(includeDir, name)
|
||||||
|
content, err := fileOp.GetContent(upstreamPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
upstream.Content = string(content)
|
||||||
nginxParser, err := parser.NewParser(upstreamPath)
|
nginxParser, err := parser.NewParser(upstreamPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -3019,6 +3026,9 @@ func (w WebsiteService) CreateLoadBalance(req request.WebsiteLBCreate) error {
|
|||||||
upstream := components.Upstream{
|
upstream := components.Upstream{
|
||||||
UpstreamName: req.Name,
|
UpstreamName: req.Name,
|
||||||
}
|
}
|
||||||
|
if req.Algorithm != "default" {
|
||||||
|
upstream.UpdateDirective(req.Algorithm, []string{})
|
||||||
|
}
|
||||||
|
|
||||||
servers := make([]*components.UpstreamServer, 0)
|
servers := make([]*components.UpstreamServer, 0)
|
||||||
|
|
||||||
@ -3064,6 +3074,78 @@ func (w WebsiteService) CreateLoadBalance(req request.WebsiteLBCreate) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w WebsiteService) UpdateLoadBalance(req request.WebsiteLBUpdate) error {
|
||||||
|
website, err := websiteRepo.GetFirst(commonRepo.WithByID(req.WebsiteID))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
includeDir := path.Join(nginxInstall.GetPath(), "www", "sites", website.Alias, "upstream")
|
||||||
|
fileOp := files.NewFileOp()
|
||||||
|
filePath := path.Join(includeDir, fmt.Sprintf("%s.conf", req.Name))
|
||||||
|
if !fileOp.Stat(filePath) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
parser, err := parser.NewParser(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
config, err := parser.Parse()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
upstreams := config.FindUpstreams()
|
||||||
|
for _, up := range upstreams {
|
||||||
|
if up.UpstreamName == req.Name {
|
||||||
|
directives := up.GetDirectives()
|
||||||
|
for _, d := range directives {
|
||||||
|
dName := d.GetName()
|
||||||
|
if _, ok := dto.LBAlgorithms[dName]; ok {
|
||||||
|
up.RemoveDirective(dName, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if req.Algorithm != "default" {
|
||||||
|
up.UpdateDirective(req.Algorithm, []string{})
|
||||||
|
}
|
||||||
|
var servers []*components.UpstreamServer
|
||||||
|
for _, server := range req.Servers {
|
||||||
|
upstreamServer := &components.UpstreamServer{
|
||||||
|
Address: server.Server,
|
||||||
|
}
|
||||||
|
parameters := make(map[string]string)
|
||||||
|
if server.Weight > 0 {
|
||||||
|
parameters["weight"] = strconv.Itoa(server.Weight)
|
||||||
|
}
|
||||||
|
if server.MaxFails > 0 {
|
||||||
|
parameters["max_fails"] = strconv.Itoa(server.MaxFails)
|
||||||
|
}
|
||||||
|
if server.FailTimeout != "" {
|
||||||
|
parameters["fail_timeout"] = server.FailTimeout
|
||||||
|
}
|
||||||
|
if server.MaxConns > 0 {
|
||||||
|
parameters["max_conns"] = strconv.Itoa(server.MaxConns)
|
||||||
|
}
|
||||||
|
if server.Flag != "" {
|
||||||
|
upstreamServer.Flags = []string{server.Flag}
|
||||||
|
}
|
||||||
|
upstreamServer.Parameters = parameters
|
||||||
|
servers = append(servers, upstreamServer)
|
||||||
|
}
|
||||||
|
up.UpstreamServers = servers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err = nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
||||||
|
return buserr.WithErr(constant.ErrUpdateBuWebsite, err)
|
||||||
|
}
|
||||||
|
if err = opNginx(nginxInstall.ContainerName, constant.NginxReload); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (w WebsiteService) DeleteLoadBalance(req request.WebsiteLBDelete) error {
|
func (w WebsiteService) DeleteLoadBalance(req request.WebsiteLBDelete) error {
|
||||||
website, err := websiteRepo.GetFirst(commonRepo.WithByID(req.WebsiteID))
|
website, err := websiteRepo.GetFirst(commonRepo.WithByID(req.WebsiteID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -3082,8 +3164,32 @@ func (w WebsiteService) DeleteLoadBalance(req request.WebsiteLBDelete) error {
|
|||||||
if err = fileOp.DeleteFile(filePath); err != nil {
|
if err = fileOp.DeleteFile(filePath); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err = opNginx(nginxInstall.ContainerName, constant.NginxReload); err != nil {
|
return opNginx(nginxInstall.ContainerName, constant.NginxReload)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WebsiteService) UpdateLoadBalanceFile(req request.WebsiteLBUpdateFile) error {
|
||||||
|
website, err := websiteRepo.GetFirst(commonRepo.WithByID(req.WebsiteID))
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
includeDir := path.Join(nginxInstall.GetPath(), "www", "sites", website.Alias, "upstream")
|
||||||
|
filePath := path.Join(includeDir, fmt.Sprintf("%s.conf", req.Name))
|
||||||
|
fileOp := files.NewFileOp()
|
||||||
|
oldContent, err := fileOp.GetContent(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = fileOp.WriteFile(filePath, strings.NewReader(req.Content), 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
_ = fileOp.WriteFile(filePath, bytes.NewReader(oldContent), 0755)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return opNginx(nginxInstall.ContainerName, constant.NginxReload)
|
||||||
}
|
}
|
||||||
|
@ -72,5 +72,7 @@ func (a *WebsiteRouter) InitRouter(Router *gin.RouterGroup) {
|
|||||||
websiteRouter.GET("/:id/lbs", baseApi.GetLoadBalances)
|
websiteRouter.GET("/:id/lbs", baseApi.GetLoadBalances)
|
||||||
websiteRouter.POST("/lbs/create", baseApi.CreateLoadBalance)
|
websiteRouter.POST("/lbs/create", baseApi.CreateLoadBalance)
|
||||||
websiteRouter.POST("/lbs/del", baseApi.DeleteLoadBalance)
|
websiteRouter.POST("/lbs/del", baseApi.DeleteLoadBalance)
|
||||||
|
websiteRouter.POST("/lbs/update", baseApi.UpdateLoadBalance)
|
||||||
|
websiteRouter.POST("/lbs/file", baseApi.UpdateLoadBalanceFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,10 +82,10 @@ func (us *Upstream) FindDirectives(directiveName string) []IDirective {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (us *Upstream) UpdateDirective(key string, params []string) {
|
func (us *Upstream) UpdateDirective(key string, params []string) {
|
||||||
if key == "" || len(params) == 0 {
|
if key == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
directives := us.GetDirectives()
|
directives := us.Directives
|
||||||
index := -1
|
index := -1
|
||||||
for i, dir := range directives {
|
for i, dir := range directives {
|
||||||
if dir.GetName() == key {
|
if dir.GetName() == key {
|
||||||
@ -112,7 +112,7 @@ func (us *Upstream) UpdateDirective(key string, params []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (us *Upstream) RemoveDirective(key string, params []string) {
|
func (us *Upstream) RemoveDirective(key string, params []string) {
|
||||||
directives := us.GetDirectives()
|
directives := us.Directives
|
||||||
var newDirectives []IDirective
|
var newDirectives []IDirective
|
||||||
for _, dir := range directives {
|
for _, dir := range directives {
|
||||||
if dir.GetName() == key {
|
if dir.GetName() == key {
|
||||||
|
@ -573,6 +573,14 @@ export namespace Website {
|
|||||||
name: string;
|
name: string;
|
||||||
algorithm: string;
|
algorithm: string;
|
||||||
servers: NginxUpstreamServer[];
|
servers: NginxUpstreamServer[];
|
||||||
|
content?: string;
|
||||||
|
websiteID?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NginxUpstreamFile {
|
||||||
|
name: string;
|
||||||
|
content: string;
|
||||||
|
websiteID: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LoadBalanceReq {
|
export interface LoadBalanceReq {
|
||||||
@ -595,4 +603,10 @@ export namespace Website {
|
|||||||
websiteID: number;
|
websiteID: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface WebsiteLBUpdateFile {
|
||||||
|
websiteID: number;
|
||||||
|
name: string;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,3 +307,11 @@ export const CreateLoadBalance = (req: Website.LoadBalanceReq) => {
|
|||||||
export const DeleteLoadBalance = (req: Website.LoadBalanceDel) => {
|
export const DeleteLoadBalance = (req: Website.LoadBalanceDel) => {
|
||||||
return http.post(`/websites/lbs/del`, req);
|
return http.post(`/websites/lbs/del`, req);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const UpdateLoadBalance = (req: Website.LoadBalanceReq) => {
|
||||||
|
return http.post(`/websites/lbs/update`, req);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const UpdateLoadBalanceFile = (req: Website.WebsiteLBUpdateFile) => {
|
||||||
|
return http.post(`/websites/lbs/file`, req);
|
||||||
|
};
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
<template>
|
||||||
|
<DrawerPro v-model="open" :header="$t('website.proxyFile')" :back="handleClose" :size="mobile ? 'full' : 'normal'">
|
||||||
|
<CodemirrorPro v-model="req.content" mode="nginx"></CodemirrorPro>
|
||||||
|
<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>
|
||||||
|
</DrawerPro>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import i18n from '@/lang';
|
||||||
|
import { FormInstance } from 'element-plus';
|
||||||
|
import { computed, reactive, ref } from 'vue';
|
||||||
|
import { MsgSuccess } from '@/utils/message';
|
||||||
|
import { UpdateLoadBalanceFile } from '@/api/modules/website';
|
||||||
|
import { GlobalStore } from '@/store';
|
||||||
|
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
|
||||||
|
import { Website } from '@/api/interface/website';
|
||||||
|
const globalStore = GlobalStore();
|
||||||
|
|
||||||
|
const mobile = computed(() => {
|
||||||
|
return globalStore.isMobile();
|
||||||
|
});
|
||||||
|
|
||||||
|
const proxyForm = ref<FormInstance>();
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(false);
|
||||||
|
const em = defineEmits(['close']);
|
||||||
|
const handleClose = () => {
|
||||||
|
proxyForm.value?.resetFields();
|
||||||
|
open.value = false;
|
||||||
|
em('close', false);
|
||||||
|
};
|
||||||
|
const req = reactive({
|
||||||
|
name: '',
|
||||||
|
websiteID: 0,
|
||||||
|
content: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const acceptParams = async (ups: Website.NginxUpstreamFile) => {
|
||||||
|
req.name = ups.name;
|
||||||
|
req.websiteID = ups.websiteID;
|
||||||
|
req.content = ups.content;
|
||||||
|
open.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const submit = async () => {
|
||||||
|
loading.value = true;
|
||||||
|
UpdateLoadBalanceFile(req)
|
||||||
|
.then(() => {
|
||||||
|
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
||||||
|
handleClose();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
acceptParams,
|
||||||
|
});
|
||||||
|
</script>
|
@ -7,7 +7,11 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<el-table-column :label="$t('commons.table.name')" prop="name"></el-table-column>
|
<el-table-column :label="$t('commons.table.name')" prop="name"></el-table-column>
|
||||||
<el-table-column :label="$t('website.algorithm')" prop="algorithm"></el-table-column>
|
<el-table-column :label="$t('website.algorithm')" prop="algorithm">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ getAlgorithm(row.algorithm) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column :label="$t('website.server')" prop="servers" minWidth="400px">
|
<el-table-column :label="$t('website.server')" prop="servers" minWidth="400px">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<table>
|
<table>
|
||||||
@ -45,8 +49,9 @@
|
|||||||
/>
|
/>
|
||||||
</ComplexTable>
|
</ComplexTable>
|
||||||
</div>
|
</div>
|
||||||
<Operate ref="operateRef" @search="search()"></Operate>
|
<Operate ref="operateRef" @close="search()" />
|
||||||
<OpDialog ref="delRef" @search="search()" />
|
<OpDialog ref="delRef" @search="search()" />
|
||||||
|
<File ref="fileRef" @search="search()" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -55,6 +60,8 @@ import { defineProps, onMounted, ref } from 'vue';
|
|||||||
import Operate from './operate/index.vue';
|
import Operate from './operate/index.vue';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { Website } from '@/api/interface/website';
|
import { Website } from '@/api/interface/website';
|
||||||
|
import { Algorithms } from '@/global/mimetype';
|
||||||
|
import File from './file/index.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
@ -67,8 +74,21 @@ const data = ref([]);
|
|||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const operateRef = ref();
|
const operateRef = ref();
|
||||||
const delRef = ref();
|
const delRef = ref();
|
||||||
|
const fileRef = ref();
|
||||||
|
|
||||||
const buttons = [
|
const buttons = [
|
||||||
|
{
|
||||||
|
label: i18n.global.t('website.proxyFile'),
|
||||||
|
click: function (row: any) {
|
||||||
|
openEditFile(row);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: i18n.global.t('commons.button.edit'),
|
||||||
|
click: (row: any) => {
|
||||||
|
update(row);
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: i18n.global.t('commons.button.delete'),
|
label: i18n.global.t('commons.button.delete'),
|
||||||
click: (row: any) => {
|
click: (row: any) => {
|
||||||
@ -83,6 +103,19 @@ const search = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getAlgorithm = (key: string) => {
|
||||||
|
let label = '';
|
||||||
|
Algorithms.forEach((algorithm) => {
|
||||||
|
if (algorithm.value === key) {
|
||||||
|
label = algorithm.label;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (label === '') {
|
||||||
|
return i18n.global.t('commons.table.default');
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
};
|
||||||
|
|
||||||
const deleteLb = async (row: Website.NginxUpstream) => {
|
const deleteLb = async (row: Website.NginxUpstream) => {
|
||||||
delRef.value.acceptParams({
|
delRef.value.acceptParams({
|
||||||
title: i18n.global.t('commons.msg.deleteTitle'),
|
title: i18n.global.t('commons.msg.deleteTitle'),
|
||||||
@ -97,7 +130,26 @@ const deleteLb = async (row: Website.NginxUpstream) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const create = () => {
|
const create = () => {
|
||||||
operateRef.value.acceptParams(props.id);
|
operateRef.value.acceptParams({
|
||||||
|
websiteID: props.id,
|
||||||
|
operate: 'create',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const update = (row: Website.NginxUpstream) => {
|
||||||
|
operateRef.value.acceptParams({
|
||||||
|
websiteID: props.id,
|
||||||
|
operate: 'edit',
|
||||||
|
upstream: row,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const openEditFile = (row: Website.NginxUpstream) => {
|
||||||
|
fileRef.value.acceptParams({
|
||||||
|
websiteID: props.id,
|
||||||
|
name: row.name,
|
||||||
|
content: row.content,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<DrawerPro v-model="open" :header="$t('website.addDomain')" :back="handleClose" size="large">
|
<DrawerPro
|
||||||
|
v-model="open"
|
||||||
|
:back="handleClose"
|
||||||
|
size="large"
|
||||||
|
:header="$t('commons.button.' + item.operate) + $t('website.loadBalance')"
|
||||||
|
:resource="item.operate == 'create' ? '' : item.name"
|
||||||
|
>
|
||||||
<el-form ref="lbForm" label-position="top" :model="item" :rules="rules">
|
<el-form ref="lbForm" label-position="top" :model="item" :rules="rules">
|
||||||
<el-form-item :label="$t('commons.table.name')" prop="name">
|
<el-form-item :label="$t('commons.table.name')" prop="name">
|
||||||
<el-input v-model.trim="item.name" :disabled="item.operate === 'edit'"></el-input>
|
<el-input v-model.trim="item.name" :disabled="item.operate === 'edit'"></el-input>
|
||||||
@ -100,13 +106,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { CreateLoadBalance } from '@/api/modules/website';
|
import { CreateLoadBalance, UpdateLoadBalance } from '@/api/modules/website';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { FormInstance } from 'element-plus';
|
import { FormInstance } from 'element-plus';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgSuccess } from '@/utils/message';
|
||||||
import { Rules, checkNumberRange } from '@/global/form-rules';
|
import { Rules, checkNumberRange } from '@/global/form-rules';
|
||||||
import { Algorithms, StatusStrategy } from '@/global/mimetype';
|
import { Algorithms, StatusStrategy } from '@/global/mimetype';
|
||||||
|
import { Website } from '@/api/interface/website';
|
||||||
|
|
||||||
const rules = ref<any>({
|
const rules = ref<any>({
|
||||||
name: [Rules.linuxName],
|
name: [Rules.linuxName],
|
||||||
@ -120,6 +127,12 @@ const rules = ref<any>({
|
|||||||
maxConns: [checkNumberRange(1, 1000)],
|
maxConns: [checkNumberRange(1, 1000)],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
interface LoadBalanceOperate {
|
||||||
|
websiteID: number;
|
||||||
|
operate: string;
|
||||||
|
upstream?: Website.NginxUpstream;
|
||||||
|
}
|
||||||
|
|
||||||
const lbForm = ref<FormInstance>();
|
const lbForm = ref<FormInstance>();
|
||||||
|
|
||||||
const initServer = () => ({
|
const initServer = () => ({
|
||||||
@ -163,27 +176,51 @@ const removeServer = (index: number) => {
|
|||||||
item.value.servers.splice(index, 1);
|
item.value.servers.splice(index, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const acceptParams = async (websiteId: number) => {
|
const acceptParams = async (req: LoadBalanceOperate) => {
|
||||||
item.value.websiteID = Number(websiteId);
|
item.value.websiteID = req.websiteID;
|
||||||
item.value.servers = [initServer()];
|
if (req.operate == 'edit') {
|
||||||
|
item.value.operate = 'edit';
|
||||||
|
item.value.name = req.upstream?.name || '';
|
||||||
|
item.value.algorithm = req.upstream?.algorithm || 'default';
|
||||||
|
let servers = [];
|
||||||
|
req.upstream?.servers?.forEach((server) => {
|
||||||
|
const weight = server.weight == 0 ? undefined : server.weight;
|
||||||
|
const maxFails = server.maxFails == 0 ? undefined : server.maxFails;
|
||||||
|
const maxConns = server.maxConns == 0 ? undefined : server.maxConns;
|
||||||
|
servers.push({
|
||||||
|
server: server.server,
|
||||||
|
weight: weight,
|
||||||
|
maxFails: maxFails,
|
||||||
|
maxConns: maxConns,
|
||||||
|
flag: server.flag,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
item.value.servers = servers;
|
||||||
|
} else {
|
||||||
|
item.value.servers = [initServer()];
|
||||||
|
}
|
||||||
open.value = true;
|
open.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const submit = async (formEl: FormInstance | undefined) => {
|
const submit = async (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return;
|
if (!formEl) return;
|
||||||
await formEl.validate((valid) => {
|
await formEl.validate(async (valid) => {
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
CreateLoadBalance(item.value)
|
try {
|
||||||
.then(() => {
|
if (item.value.operate === 'edit') {
|
||||||
|
await UpdateLoadBalance(item.value);
|
||||||
|
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
||||||
|
} else {
|
||||||
|
await CreateLoadBalance(item.value);
|
||||||
MsgSuccess(i18n.global.t('commons.msg.createSuccess'));
|
MsgSuccess(i18n.global.t('commons.msg.createSuccess'));
|
||||||
handleClose();
|
}
|
||||||
})
|
handleClose();
|
||||||
.finally(() => {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user