mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 14:08:06 +08:00
feat: 反向代理增加编辑源文功能
This commit is contained in:
parent
2dd88364f8
commit
acf64dcf25
@ -679,6 +679,7 @@ func (b *BaseApi) GetProxyConfig(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/proxies/update [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"修改网站 [domain] 反向代理配置 ","formatEN":"Update domain [domain] proxy config"}
|
||||
func (b *BaseApi) UpdateProxyConfig(c *gin.Context) {
|
||||
var req request.WebsiteProxyConfig
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@ -690,5 +691,27 @@ func (b *BaseApi) UpdateProxyConfig(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Update proxy file
|
||||
// @Description 更新反向代理文件
|
||||
// @Accept json
|
||||
// @Param request body request.NginxProxyUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/proxy/file [post]
|
||||
// @x-panel-log {"bodyKeys":["websiteID"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"websiteID","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"更新反向代理文件 [domain]","formatEN":"Nginx conf proxy file update [domain]"}
|
||||
func (b *BaseApi) UpdateProxyConfigFile(c *gin.Context) {
|
||||
var req request.NginxProxyUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := websiteService.UpdateProxyFile(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
@ -30,3 +30,9 @@ type NginxRewriteUpdate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
}
|
||||
|
||||
type NginxProxyUpdate struct {
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
}
|
||||
|
@ -158,19 +158,20 @@ type WebsiteUpdateDirPermission struct {
|
||||
}
|
||||
|
||||
type WebsiteProxyConfig struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Operate string `json:"operate" validate:"required"`
|
||||
Enable bool `json:"enable" validate:"required"`
|
||||
Cache bool `json:"cache" validate:"required"`
|
||||
CacheTime int `json:"cacheTime" validate:"required"`
|
||||
CacheUnit string `json:"cacheUnit" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Modifier string `json:"modifier" validate:"required"`
|
||||
Match string `json:"match" validate:"required"`
|
||||
ProxyPass string `json:"proxyPass" validate:"required"`
|
||||
ProxyHost string `json:"proxyHost" validate:"required"`
|
||||
FilePath string `json:"filePath"`
|
||||
Replaces []map[string]string `json:"replaces"`
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Operate string `json:"operate" validate:"required"`
|
||||
Enable bool `json:"enable" validate:"required"`
|
||||
Cache bool `json:"cache" validate:"required"`
|
||||
CacheTime int `json:"cacheTime" validate:"required"`
|
||||
CacheUnit string `json:"cacheUnit" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Modifier string `json:"modifier" validate:"required"`
|
||||
Match string `json:"match" validate:"required"`
|
||||
ProxyPass string `json:"proxyPass" validate:"required"`
|
||||
ProxyHost string `json:"proxyHost" validate:"required"`
|
||||
Content string `json:"content"`
|
||||
FilePath string `json:"filePath"`
|
||||
Replaces map[string]string `json:"replaces"`
|
||||
}
|
||||
|
||||
type WebsiteProxyReq struct {
|
||||
|
@ -69,6 +69,7 @@ type IWebsiteService interface {
|
||||
UpdateSitePermission(req request.WebsiteUpdateDirPermission) error
|
||||
OperateProxy(req request.WebsiteProxyConfig) (err error)
|
||||
GetProxies(id uint) (res []request.WebsiteProxyConfig, err error)
|
||||
UpdateProxyFile(req request.NginxProxyUpdate) (err error)
|
||||
}
|
||||
|
||||
func NewIWebsiteService() IWebsiteService {
|
||||
@ -1213,6 +1214,11 @@ func (w WebsiteService) OperateProxy(req request.WebsiteProxyConfig) (err error)
|
||||
} else {
|
||||
location.RemoveCache()
|
||||
}
|
||||
if len(req.Replaces) > 0 {
|
||||
location.AddSubFilter(req.Replaces)
|
||||
} else {
|
||||
location.RemoveSubFilter()
|
||||
}
|
||||
if err = nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
||||
return buserr.WithErr(constant.ErrUpdateBuWebsite, err)
|
||||
}
|
||||
@ -1266,6 +1272,7 @@ func (w WebsiteService) GetProxies(id uint) (res []request.WebsiteProxyConfig, e
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
proxyConfig.Content = string(content)
|
||||
config = parser.NewStringParser(string(content)).Parse()
|
||||
directives := config.GetDirectives()
|
||||
|
||||
@ -1283,7 +1290,40 @@ func (w WebsiteService) GetProxies(id uint) (res []request.WebsiteProxyConfig, e
|
||||
proxyConfig.Match = location.Match
|
||||
proxyConfig.Modifier = location.Modifier
|
||||
proxyConfig.ProxyHost = location.Host
|
||||
proxyConfig.Replaces = location.Replaces
|
||||
res = append(res, proxyConfig)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (w WebsiteService) UpdateProxyFile(req request.NginxProxyUpdate) (err error) {
|
||||
var (
|
||||
website model.Website
|
||||
nginxFull dto.NginxFull
|
||||
oldRewriteContent []byte
|
||||
)
|
||||
website, err = websiteRepo.GetFirst(commonRepo.WithByID(req.WebsiteID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nginxFull, err = getNginxFull(&website)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
includePath := fmt.Sprintf("/www/sites/%s/proxy/%s.conf", website.Alias, req.Name)
|
||||
absolutePath := path.Join(nginxFull.Install.GetPath(), includePath)
|
||||
fileOp := files.NewFileOp()
|
||||
oldRewriteContent, err = fileOp.GetContent(absolutePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = fileOp.WriteFile(absolutePath, strings.NewReader(req.Content), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = fileOp.WriteFile(absolutePath, bytes.NewReader(oldRewriteContent), 0755)
|
||||
}
|
||||
}()
|
||||
return updateNginxConfig(constant.NginxScopeServer, nil, &website)
|
||||
}
|
||||
|
@ -54,5 +54,6 @@ func (a *WebsiteRouter) InitWebsiteRouter(Router *gin.RouterGroup) {
|
||||
|
||||
groupRouter.POST("/proxies", baseApi.GetProxyConfig)
|
||||
groupRouter.POST("/proxies/update", baseApi.UpdateProxyConfig)
|
||||
groupRouter.POST("/proxies/file", baseApi.UpdateProxyConfigFile)
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ var repeatKeys = map[string]struct {
|
||||
"proxy_set_header": {},
|
||||
"location": {},
|
||||
"include": {},
|
||||
"sub_filter": {},
|
||||
}
|
||||
|
||||
func IsRepeatKey(key string) bool {
|
||||
|
@ -1,8 +1,10 @@
|
||||
package components
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Location struct {
|
||||
@ -17,6 +19,7 @@ type Location struct {
|
||||
Directives []IDirective
|
||||
Line int
|
||||
Parameters []string
|
||||
Replaces map[string]string
|
||||
}
|
||||
|
||||
func NewLocation(directive IDirective) *Location {
|
||||
@ -60,6 +63,11 @@ func NewLocation(directive IDirective) *Location {
|
||||
}
|
||||
}
|
||||
}
|
||||
case "sub_filter":
|
||||
if location.Replaces == nil {
|
||||
location.Replaces = make(map[string]string, 0)
|
||||
}
|
||||
location.Replaces[strings.Trim(params[0], "\"")] = strings.Trim(params[1], "\"")
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,6 +184,7 @@ func (l *Location) ChangePath(Modifier string, Match string) {
|
||||
|
||||
func (l *Location) AddCache(cacheTime int, cacheUint string) {
|
||||
l.RemoveDirective("add_header", []string{"Cache-Control", "no-cache"})
|
||||
l.RemoveDirective("if", []string{"(", "$uri", "~*", `"\.(gif|png|jpg|css|js|woff|woff2)$"`, ")"})
|
||||
directives := l.GetDirectives()
|
||||
newDir := &Directive{
|
||||
Name: "if",
|
||||
@ -212,3 +221,20 @@ func (l *Location) RemoveCache() {
|
||||
l.CacheUint = ""
|
||||
l.Cache = false
|
||||
}
|
||||
|
||||
func (l *Location) AddSubFilter(subFilters map[string]string) {
|
||||
l.RemoveDirective("sub_filter", []string{})
|
||||
l.Replaces = subFilters
|
||||
for k, v := range subFilters {
|
||||
l.UpdateDirective("sub_filter", []string{fmt.Sprintf(`"%s"`, k), fmt.Sprintf(`"%s"`, v)})
|
||||
}
|
||||
l.UpdateDirective("proxy_set_header", []string{"Accept-Encoding", `""`})
|
||||
l.UpdateDirective("sub_filter_once", []string{"off"})
|
||||
}
|
||||
|
||||
func (l *Location) RemoveSubFilter() {
|
||||
l.RemoveDirective("sub_filter", []string{})
|
||||
l.RemoveDirective("proxy_set_header", []string{"Accept-Encoding", `""`})
|
||||
l.RemoveDirective("sub_filter_once", []string{"off"})
|
||||
l.Replaces = nil
|
||||
}
|
||||
|
@ -326,9 +326,16 @@ export namespace Website {
|
||||
proxyHost: string;
|
||||
filePath?: string;
|
||||
replaces?: ProxReplace;
|
||||
content?: string;
|
||||
}
|
||||
|
||||
interface ProxReplace {
|
||||
export interface ProxReplace {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export interface ProxyFileUpdate {
|
||||
websiteID: number;
|
||||
name: string;
|
||||
content: string;
|
||||
}
|
||||
}
|
||||
|
@ -191,6 +191,10 @@ export const GetProxyConfig = (req: Website.ProxyReq) => {
|
||||
return http.post<Website.ProxyConfig[]>(`/websites/proxies`, req);
|
||||
};
|
||||
|
||||
export const CreateProxyConfig = (req: Website.ProxyReq) => {
|
||||
export const OperateProxyConfig = (req: Website.ProxyReq) => {
|
||||
return http.post<any>(`/websites/proxies/update`, req);
|
||||
};
|
||||
|
||||
export const UpdateProxyConfigFile = (req: Website.ProxyFileUpdate) => {
|
||||
return http.post<any>(`/websites/proxies/file`, req);
|
||||
};
|
||||
|
@ -1193,6 +1193,24 @@ const message = {
|
||||
disabled: 'Stopped',
|
||||
startProxy: 'Start Reverse proxy',
|
||||
stopProxy: 'Stop the Reverse proxy',
|
||||
proxyFile: 'Source',
|
||||
proxyHelper1:
|
||||
'Proxy directory: when accessing this directory, the content of the target URL will be returned and displayed',
|
||||
proxyPassHelper:
|
||||
'Target URL: You can fill in the site you need to proxy, the target URL must be a URL that can be accessed normally, otherwise an error will be returned',
|
||||
proxyHostHelper:
|
||||
'Send domain name: Add the domain name to the request header and pass it to the proxy server. The default is the target URL domain name. If it is not set properly, the proxy may not work properly',
|
||||
replacementHelper:
|
||||
'Content replacement: you can add up to 3 replacement content, if you do not need to replace, please leave blank',
|
||||
modifier: 'Path Match',
|
||||
modifierHelper:
|
||||
'Path matching: Example: = exact match, ~ regular match, ^~ match the beginning of the path, etc',
|
||||
replace: 'Content Replacement',
|
||||
addReplace: 'Add content to replace',
|
||||
replaced: 'The replaced text cannot be empty',
|
||||
replaceText: 'Replacement text, can be empty',
|
||||
replacedErr: 'The replaced text cannot be empty',
|
||||
replacedErr2: 'The replaced text cannot be repeated',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: 'Short tag support',
|
||||
|
@ -1195,6 +1195,20 @@ const message = {
|
||||
disabled: '已停止',
|
||||
startProxy: '开启反向代理',
|
||||
stopProxy: '关闭反向代理',
|
||||
proxyFile: '源文',
|
||||
proxyHelper1: '代理目录:访问这个目录时将会把目标URL的内容返回并显示',
|
||||
proxyPassHelper: '目标URL:可以填写你需要代理的站点,目标URL必须为可正常访问的URL,否则将返回错误',
|
||||
proxyHostHelper:
|
||||
'发送域名:将域名添加到请求头传递到代理服务器,默认为目标URL域名,若设置不当可能导致代理无法正常运行',
|
||||
replacementHelper: '内容替换:最多可以添加3条替换内容,如果不需要替换请留空',
|
||||
modifier: '路径匹配',
|
||||
modifierHelper: '路径匹配:例:= 精确匹配,~ 正则匹配,^~ 匹配路径开头 等',
|
||||
replace: '内容替换',
|
||||
addReplace: '添加内容替换',
|
||||
replaced: '被替换的文本,不能为空',
|
||||
replaceText: '替换的文本,可为空',
|
||||
replacedErr: '被替换的文本不能为空',
|
||||
replacedErr2: '被替换的文本不能重复',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: '短标签支持',
|
||||
|
@ -9,6 +9,9 @@
|
||||
<el-form-item :label="$t('commons.table.name')" prop="name">
|
||||
<el-input v-model.trim="proxy.name" :disabled="proxy.operate === 'edit'"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('website.modifier')" prop="modifier">
|
||||
<el-input v-model.trim="proxy.modifier"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('website.proxyPath')" prop="match">
|
||||
<el-input v-model.trim="proxy.match"></el-input>
|
||||
</el-form-item>
|
||||
@ -41,7 +44,40 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item :label="$t('website.replace')">
|
||||
<div style="width: 100%" v-for="(replace, index) in replaces" :key="index">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="10">
|
||||
<el-input
|
||||
v-model.trim="replace.key"
|
||||
:placeholder="$t('website.replaced')"
|
||||
></el-input>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-input
|
||||
v-model.trim="replace.value"
|
||||
:placeholder="$t('website.replaceText')"
|
||||
></el-input>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-button link @click="removeReplace(index)" type="danger">
|
||||
{{ $t('commons.button.delete') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="addReplaces" :disabled="replaces.length >= 3">
|
||||
{{ $t('website.addReplace') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-alert :title="$t('website.modifierHelper')" type="info" :closable="false" />
|
||||
<el-alert :title="$t('website.proxyHelper1')" type="info" :closable="false" />
|
||||
<el-alert :title="$t('website.proxyPassHelper')" type="info" :closable="false" />
|
||||
<el-alert :title="$t('website.proxyHostHelper')" type="info" :closable="false" />
|
||||
<el-alert :title="$t('website.replacementHelper')" type="info" :closable="false" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<template #footer>
|
||||
@ -57,12 +93,12 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { CreateProxyConfig } from '@/api/modules/website';
|
||||
import { OperateProxyConfig } from '@/api/modules/website';
|
||||
import { checkNumberRange, Rules } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { ref } from 'vue';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||
import { Website } from '@/api/interface/website';
|
||||
import { Units } from '@/global/mimetype';
|
||||
|
||||
@ -70,6 +106,7 @@ const proxyForm = ref<FormInstance>();
|
||||
const rules = ref({
|
||||
name: [Rules.requiredInput, Rules.appName],
|
||||
match: [Rules.requiredInput],
|
||||
modifier: [Rules.requiredInput],
|
||||
cacheTime: [Rules.requiredInput, checkNumberRange(1, 65535)],
|
||||
proxyPass: [Rules.requiredInput],
|
||||
proxyHost: [Rules.requiredInput],
|
||||
@ -90,9 +127,10 @@ const initData = (): Website.ProxyConfig => ({
|
||||
proxyPass: 'http://',
|
||||
proxyHost: '$host',
|
||||
filePath: '',
|
||||
replaces: {},
|
||||
});
|
||||
let proxy = ref(initData());
|
||||
|
||||
const replaces = ref<any>([]);
|
||||
const em = defineEmits(['close']);
|
||||
const handleClose = () => {
|
||||
proxyForm.value?.resetFields();
|
||||
@ -100,10 +138,15 @@ const handleClose = () => {
|
||||
em('close', false);
|
||||
};
|
||||
|
||||
const acceptParams = async (proxyParam: Website.ProxyConfig) => {
|
||||
const acceptParams = (proxyParam: Website.ProxyConfig) => {
|
||||
replaces.value = [];
|
||||
proxy.value = proxyParam;
|
||||
console.log(proxy.value);
|
||||
open.value = true;
|
||||
if (proxy.value.replaces) {
|
||||
for (const key in proxy.value.replaces) {
|
||||
replaces.value.push({ key: key, value: proxy.value.replaces[key] });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const changeCache = (cache: boolean) => {
|
||||
@ -116,14 +159,39 @@ const changeCache = (cache: boolean) => {
|
||||
}
|
||||
};
|
||||
|
||||
const addReplaces = () => {
|
||||
replaces.value.push({ key: '', value: '' });
|
||||
};
|
||||
|
||||
const removeReplace = (index: number) => {
|
||||
replaces.value.splice(index, 1);
|
||||
};
|
||||
|
||||
const submit = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
proxy.value.replaces = {};
|
||||
if (replaces.value.length > 0) {
|
||||
let keyMap = new Map();
|
||||
for (const rep of replaces.value) {
|
||||
if (keyMap.get(rep.key) != undefined) {
|
||||
MsgError(i18n.global.t('website.replacedErr2'));
|
||||
return;
|
||||
}
|
||||
keyMap.set(rep.key, '');
|
||||
if (rep.key === '') {
|
||||
MsgError(i18n.global.t('website.replacedErr'));
|
||||
return;
|
||||
}
|
||||
proxy.value.replaces[rep.key] = rep.value;
|
||||
}
|
||||
}
|
||||
loading.value = true;
|
||||
CreateProxyConfig(proxy.value)
|
||||
OperateProxyConfig(proxy.value)
|
||||
.then(() => {
|
||||
if (proxy.value.operate == 'create') {
|
||||
MsgSuccess(i18n.global.t('commons.msg.createSuccess'));
|
||||
|
@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<el-drawer v-model="open" :close-on-click-modal="false" size="40%" :before-close="handleClose">
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('website.proxyFile')" :back="handleClose" />
|
||||
</template>
|
||||
<el-row v-loading="loading">
|
||||
<el-col :span="22" :offset="1">
|
||||
<codemirror
|
||||
:autofocus="true"
|
||||
placeholder=""
|
||||
:indent-with-tab="true"
|
||||
:tabSize="4"
|
||||
style="margin-top: 10px; height: 600px; width: 100%"
|
||||
:lineWrapping="true"
|
||||
:matchBrackets="true"
|
||||
theme="cobalt"
|
||||
:styleActiveLine="true"
|
||||
:extensions="extensions"
|
||||
v-model="req.content"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<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-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import i18n from '@/lang';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { Codemirror } from 'vue-codemirror';
|
||||
import { UpdateProxyConfigFile } from '@/api/modules/website';
|
||||
import { StreamLanguage } from '@codemirror/language';
|
||||
import { nginx } from '@codemirror/legacy-modes/mode/nginx';
|
||||
import { oneDark } from '@codemirror/theme-one-dark';
|
||||
|
||||
const extensions = [StreamLanguage.define(nginx), oneDark];
|
||||
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 (proxyreq: any) => {
|
||||
req.name = proxyreq.name;
|
||||
req.websiteID = proxyreq.websiteID;
|
||||
req.content = proxyreq.content;
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
loading.value = true;
|
||||
UpdateProxyConfigFile(req)
|
||||
.then(() => {
|
||||
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
||||
handleClose();
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
@ -8,7 +8,7 @@
|
||||
<el-table-column :label="$t('website.proxyPass')" prop="proxyPass"></el-table-column>
|
||||
<el-table-column :label="$t('website.cache')" prop="cache">
|
||||
<template #default="{ row }">
|
||||
<el-switch v-model="row.cache" @change="changeCache(row)"></el-switch>
|
||||
<el-switch v-model="row.cache" @change="changeCache(row)" :disabled="!row.enable"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.table.status')" prop="enable">
|
||||
@ -31,16 +31,20 @@
|
||||
/>
|
||||
</ComplexTable>
|
||||
<Create ref="createRef" @close="search()" />
|
||||
<File ref="fileRef" @close="search()" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="proxy">
|
||||
import { Website } from '@/api/interface/website';
|
||||
import { CreateProxyConfig, GetProxyConfig } from '@/api/modules/website';
|
||||
import { OperateProxyConfig, GetProxyConfig } from '@/api/modules/website';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import Create from './create/index.vue';
|
||||
import File from './file/index.vue';
|
||||
import { VideoPlay, VideoPause } from '@element-plus/icons-vue';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { useDeleteData } from '@/hooks/use-delete-data';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
@ -54,13 +58,32 @@ const id = computed(() => {
|
||||
const loading = ref(false);
|
||||
const data = ref();
|
||||
const createRef = ref();
|
||||
const fileRef = ref();
|
||||
|
||||
const buttons = [
|
||||
{
|
||||
label: i18n.global.t('website.proxyFile'),
|
||||
click: function (row: Website.ProxyConfig) {
|
||||
openEditFile(row);
|
||||
},
|
||||
disabled: (row: Website.ProxyConfig) => {
|
||||
return !row.enable;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('commons.button.edit'),
|
||||
click: function (row: Website.ProxyConfig) {
|
||||
openEdit(row);
|
||||
},
|
||||
disabled: (row: Website.ProxyConfig) => {
|
||||
return !row.enable;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('commons.button.delete'),
|
||||
click: function (row: Website.ProxyConfig) {
|
||||
deleteProxy(row);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@ -76,6 +99,7 @@ const initData = (id: number): Website.ProxyConfig => ({
|
||||
match: '/',
|
||||
proxyPass: 'http://',
|
||||
proxyHost: '$host',
|
||||
replaces: {},
|
||||
});
|
||||
|
||||
const openCreate = () => {
|
||||
@ -85,9 +109,22 @@ const openCreate = () => {
|
||||
const openEdit = (proxyConfig: Website.ProxyConfig) => {
|
||||
let proxy = JSON.parse(JSON.stringify(proxyConfig));
|
||||
proxy.operate = 'edit';
|
||||
if (proxy.replaces == null) {
|
||||
proxy.replaces = {};
|
||||
}
|
||||
createRef.value.acceptParams(proxy);
|
||||
};
|
||||
|
||||
const openEditFile = (proxyConfig: Website.ProxyConfig) => {
|
||||
fileRef.value.acceptParams({ name: proxyConfig.name, content: proxyConfig.content, websiteID: proxyConfig.id });
|
||||
};
|
||||
|
||||
const deleteProxy = async (proxyConfig: Website.ProxyConfig) => {
|
||||
proxyConfig.operate = 'delete';
|
||||
await useDeleteData(OperateProxyConfig, proxyConfig, 'commons.msg.delete');
|
||||
search();
|
||||
};
|
||||
|
||||
const changeCache = (proxyConfig: Website.ProxyConfig) => {
|
||||
proxyConfig.operate = 'edit';
|
||||
if (proxyConfig.cache) {
|
||||
@ -99,7 +136,7 @@ const changeCache = (proxyConfig: Website.ProxyConfig) => {
|
||||
|
||||
const submit = async (proxyConfig: Website.ProxyConfig) => {
|
||||
loading.value = true;
|
||||
CreateProxyConfig(proxyConfig)
|
||||
OperateProxyConfig(proxyConfig)
|
||||
.then(() => {
|
||||
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
||||
search();
|
||||
|
Loading…
x
Reference in New Issue
Block a user