1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-31 22:18:07 +08:00

feat: 反向代理增加编辑源文功能

This commit is contained in:
zhengkunwang223 2023-04-24 17:48:22 +08:00 committed by zhengkunwang223
parent 2dd88364f8
commit acf64dcf25
14 changed files with 355 additions and 25 deletions

View File

@ -679,6 +679,7 @@ func (b *BaseApi) GetProxyConfig(c *gin.Context) {
// @Success 200 // @Success 200
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Router /websites/proxies/update [post] // @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) { func (b *BaseApi) UpdateProxyConfig(c *gin.Context) {
var req request.WebsiteProxyConfig var req request.WebsiteProxyConfig
if err := c.ShouldBindJSON(&req); err != nil { 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) helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return 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)
} }

View File

@ -30,3 +30,9 @@ type NginxRewriteUpdate struct {
Name string `json:"name" validate:"required"` Name string `json:"name" validate:"required"`
Content string `json:"content" 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"`
}

View File

@ -158,19 +158,20 @@ type WebsiteUpdateDirPermission struct {
} }
type WebsiteProxyConfig struct { type WebsiteProxyConfig struct {
ID uint `json:"id" validate:"required"` ID uint `json:"id" validate:"required"`
Operate string `json:"operate" validate:"required"` Operate string `json:"operate" validate:"required"`
Enable bool `json:"enable" validate:"required"` Enable bool `json:"enable" validate:"required"`
Cache bool `json:"cache" validate:"required"` Cache bool `json:"cache" validate:"required"`
CacheTime int `json:"cacheTime" validate:"required"` CacheTime int `json:"cacheTime" validate:"required"`
CacheUnit string `json:"cacheUnit" validate:"required"` CacheUnit string `json:"cacheUnit" validate:"required"`
Name string `json:"name" validate:"required"` Name string `json:"name" validate:"required"`
Modifier string `json:"modifier" validate:"required"` Modifier string `json:"modifier" validate:"required"`
Match string `json:"match" validate:"required"` Match string `json:"match" validate:"required"`
ProxyPass string `json:"proxyPass" validate:"required"` ProxyPass string `json:"proxyPass" validate:"required"`
ProxyHost string `json:"proxyHost" validate:"required"` ProxyHost string `json:"proxyHost" validate:"required"`
FilePath string `json:"filePath"` Content string `json:"content"`
Replaces []map[string]string `json:"replaces"` FilePath string `json:"filePath"`
Replaces map[string]string `json:"replaces"`
} }
type WebsiteProxyReq struct { type WebsiteProxyReq struct {

View File

@ -69,6 +69,7 @@ type IWebsiteService interface {
UpdateSitePermission(req request.WebsiteUpdateDirPermission) error UpdateSitePermission(req request.WebsiteUpdateDirPermission) error
OperateProxy(req request.WebsiteProxyConfig) (err error) OperateProxy(req request.WebsiteProxyConfig) (err error)
GetProxies(id uint) (res []request.WebsiteProxyConfig, err error) GetProxies(id uint) (res []request.WebsiteProxyConfig, err error)
UpdateProxyFile(req request.NginxProxyUpdate) (err error)
} }
func NewIWebsiteService() IWebsiteService { func NewIWebsiteService() IWebsiteService {
@ -1213,6 +1214,11 @@ func (w WebsiteService) OperateProxy(req request.WebsiteProxyConfig) (err error)
} else { } else {
location.RemoveCache() location.RemoveCache()
} }
if len(req.Replaces) > 0 {
location.AddSubFilter(req.Replaces)
} else {
location.RemoveSubFilter()
}
if err = nginx.WriteConfig(config, nginx.IndentedStyle); err != nil { if err = nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
return buserr.WithErr(constant.ErrUpdateBuWebsite, err) return buserr.WithErr(constant.ErrUpdateBuWebsite, err)
} }
@ -1266,6 +1272,7 @@ func (w WebsiteService) GetProxies(id uint) (res []request.WebsiteProxyConfig, e
if err != nil { if err != nil {
return return
} }
proxyConfig.Content = string(content)
config = parser.NewStringParser(string(content)).Parse() config = parser.NewStringParser(string(content)).Parse()
directives := config.GetDirectives() directives := config.GetDirectives()
@ -1283,7 +1290,40 @@ func (w WebsiteService) GetProxies(id uint) (res []request.WebsiteProxyConfig, e
proxyConfig.Match = location.Match proxyConfig.Match = location.Match
proxyConfig.Modifier = location.Modifier proxyConfig.Modifier = location.Modifier
proxyConfig.ProxyHost = location.Host proxyConfig.ProxyHost = location.Host
proxyConfig.Replaces = location.Replaces
res = append(res, proxyConfig) res = append(res, proxyConfig)
} }
return 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)
}

View File

@ -54,5 +54,6 @@ func (a *WebsiteRouter) InitWebsiteRouter(Router *gin.RouterGroup) {
groupRouter.POST("/proxies", baseApi.GetProxyConfig) groupRouter.POST("/proxies", baseApi.GetProxyConfig)
groupRouter.POST("/proxies/update", baseApi.UpdateProxyConfig) groupRouter.POST("/proxies/update", baseApi.UpdateProxyConfig)
groupRouter.POST("/proxies/file", baseApi.UpdateProxyConfigFile)
} }
} }

View File

@ -46,6 +46,7 @@ var repeatKeys = map[string]struct {
"proxy_set_header": {}, "proxy_set_header": {},
"location": {}, "location": {},
"include": {}, "include": {},
"sub_filter": {},
} }
func IsRepeatKey(key string) bool { func IsRepeatKey(key string) bool {

View File

@ -1,8 +1,10 @@
package components package components
import ( import (
"fmt"
"regexp" "regexp"
"strconv" "strconv"
"strings"
) )
type Location struct { type Location struct {
@ -17,6 +19,7 @@ type Location struct {
Directives []IDirective Directives []IDirective
Line int Line int
Parameters []string Parameters []string
Replaces map[string]string
} }
func NewLocation(directive IDirective) *Location { 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) { func (l *Location) AddCache(cacheTime int, cacheUint string) {
l.RemoveDirective("add_header", []string{"Cache-Control", "no-cache"}) l.RemoveDirective("add_header", []string{"Cache-Control", "no-cache"})
l.RemoveDirective("if", []string{"(", "$uri", "~*", `"\.(gif|png|jpg|css|js|woff|woff2)$"`, ")"})
directives := l.GetDirectives() directives := l.GetDirectives()
newDir := &Directive{ newDir := &Directive{
Name: "if", Name: "if",
@ -212,3 +221,20 @@ func (l *Location) RemoveCache() {
l.CacheUint = "" l.CacheUint = ""
l.Cache = false 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
}

View File

@ -326,9 +326,16 @@ export namespace Website {
proxyHost: string; proxyHost: string;
filePath?: string; filePath?: string;
replaces?: ProxReplace; replaces?: ProxReplace;
content?: string;
} }
interface ProxReplace { export interface ProxReplace {
[key: string]: string; [key: string]: string;
} }
export interface ProxyFileUpdate {
websiteID: number;
name: string;
content: string;
}
} }

View File

@ -191,6 +191,10 @@ export const GetProxyConfig = (req: Website.ProxyReq) => {
return http.post<Website.ProxyConfig[]>(`/websites/proxies`, req); 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); return http.post<any>(`/websites/proxies/update`, req);
}; };
export const UpdateProxyConfigFile = (req: Website.ProxyFileUpdate) => {
return http.post<any>(`/websites/proxies/file`, req);
};

View File

@ -1193,6 +1193,24 @@ const message = {
disabled: 'Stopped', disabled: 'Stopped',
startProxy: 'Start Reverse proxy', startProxy: 'Start Reverse proxy',
stopProxy: 'Stop the 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: { php: {
short_open_tag: 'Short tag support', short_open_tag: 'Short tag support',

View File

@ -1195,6 +1195,20 @@ const message = {
disabled: '已停止', disabled: '已停止',
startProxy: '开启反向代理', startProxy: '开启反向代理',
stopProxy: '关闭反向代理', stopProxy: '关闭反向代理',
proxyFile: '源文',
proxyHelper1: '代理目录访问这个目录时将会把目标URL的内容返回并显示',
proxyPassHelper: '目标URL可以填写你需要代理的站点目标URL必须为可正常访问的URL否则将返回错误',
proxyHostHelper:
'发送域名将域名添加到请求头传递到代理服务器默认为目标URL域名若设置不当可能导致代理无法正常运行',
replacementHelper: '内容替换最多可以添加3条替换内容,如果不需要替换请留空',
modifier: '路径匹配',
modifierHelper: '路径匹配= 精确匹配~ 正则匹配^~ 匹配路径开头 ',
replace: '内容替换',
addReplace: '添加内容替换',
replaced: '被替换的文本,不能为空',
replaceText: '替换的文本可为空',
replacedErr: '被替换的文本不能为空',
replacedErr2: '被替换的文本不能重复',
}, },
php: { php: {
short_open_tag: '短标签支持', short_open_tag: '短标签支持',

View File

@ -9,6 +9,9 @@
<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="proxy.name" :disabled="proxy.operate === 'edit'"></el-input> <el-input v-model.trim="proxy.name" :disabled="proxy.operate === 'edit'"></el-input>
</el-form-item> </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-form-item :label="$t('website.proxyPath')" prop="match">
<el-input v-model.trim="proxy.match"></el-input> <el-input v-model.trim="proxy.match"></el-input>
</el-form-item> </el-form-item>
@ -41,7 +44,40 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </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-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-col>
</el-row> </el-row>
<template #footer> <template #footer>
@ -57,12 +93,12 @@
<script lang="ts" setup> <script lang="ts" setup>
import DrawerHeader from '@/components/drawer-header/index.vue'; 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 { checkNumberRange, Rules } from '@/global/form-rules';
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 { MsgError, MsgSuccess } from '@/utils/message';
import { Website } from '@/api/interface/website'; import { Website } from '@/api/interface/website';
import { Units } from '@/global/mimetype'; import { Units } from '@/global/mimetype';
@ -70,6 +106,7 @@ const proxyForm = ref<FormInstance>();
const rules = ref({ const rules = ref({
name: [Rules.requiredInput, Rules.appName], name: [Rules.requiredInput, Rules.appName],
match: [Rules.requiredInput], match: [Rules.requiredInput],
modifier: [Rules.requiredInput],
cacheTime: [Rules.requiredInput, checkNumberRange(1, 65535)], cacheTime: [Rules.requiredInput, checkNumberRange(1, 65535)],
proxyPass: [Rules.requiredInput], proxyPass: [Rules.requiredInput],
proxyHost: [Rules.requiredInput], proxyHost: [Rules.requiredInput],
@ -90,9 +127,10 @@ const initData = (): Website.ProxyConfig => ({
proxyPass: 'http://', proxyPass: 'http://',
proxyHost: '$host', proxyHost: '$host',
filePath: '', filePath: '',
replaces: {},
}); });
let proxy = ref(initData()); let proxy = ref(initData());
const replaces = ref<any>([]);
const em = defineEmits(['close']); const em = defineEmits(['close']);
const handleClose = () => { const handleClose = () => {
proxyForm.value?.resetFields(); proxyForm.value?.resetFields();
@ -100,10 +138,15 @@ const handleClose = () => {
em('close', false); em('close', false);
}; };
const acceptParams = async (proxyParam: Website.ProxyConfig) => { const acceptParams = (proxyParam: Website.ProxyConfig) => {
replaces.value = [];
proxy.value = proxyParam; proxy.value = proxyParam;
console.log(proxy.value);
open.value = true; 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) => { 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) => { const submit = async (formEl: FormInstance | undefined) => {
if (!formEl) return; if (!formEl) return;
await formEl.validate((valid) => { await formEl.validate((valid) => {
if (!valid) { if (!valid) {
return; 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; loading.value = true;
CreateProxyConfig(proxy.value) OperateProxyConfig(proxy.value)
.then(() => { .then(() => {
if (proxy.value.operate == 'create') { if (proxy.value.operate == 'create') {
MsgSuccess(i18n.global.t('commons.msg.createSuccess')); MsgSuccess(i18n.global.t('commons.msg.createSuccess'));

View File

@ -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>

View File

@ -8,7 +8,7 @@
<el-table-column :label="$t('website.proxyPass')" prop="proxyPass"></el-table-column> <el-table-column :label="$t('website.proxyPass')" prop="proxyPass"></el-table-column>
<el-table-column :label="$t('website.cache')" prop="cache"> <el-table-column :label="$t('website.cache')" prop="cache">
<template #default="{ row }"> <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> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="enable"> <el-table-column :label="$t('commons.table.status')" prop="enable">
@ -31,16 +31,20 @@
/> />
</ComplexTable> </ComplexTable>
<Create ref="createRef" @close="search()" /> <Create ref="createRef" @close="search()" />
<File ref="fileRef" @close="search()" />
</template> </template>
<script lang="ts" setup name="proxy"> <script lang="ts" setup name="proxy">
import { Website } from '@/api/interface/website'; 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 { computed, onMounted, ref } from 'vue';
import Create from './create/index.vue'; import Create from './create/index.vue';
import File from './file/index.vue';
import { VideoPlay, VideoPause } from '@element-plus/icons-vue'; import { VideoPlay, VideoPause } from '@element-plus/icons-vue';
import i18n from '@/lang'; import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { useDeleteData } from '@/hooks/use-delete-data';
import { ElMessageBox } from 'element-plus';
const props = defineProps({ const props = defineProps({
id: { id: {
@ -54,13 +58,32 @@ const id = computed(() => {
const loading = ref(false); const loading = ref(false);
const data = ref(); const data = ref();
const createRef = ref(); const createRef = ref();
const fileRef = ref();
const buttons = [ 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'), label: i18n.global.t('commons.button.edit'),
click: function (row: Website.ProxyConfig) { click: function (row: Website.ProxyConfig) {
openEdit(row); 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: '/', match: '/',
proxyPass: 'http://', proxyPass: 'http://',
proxyHost: '$host', proxyHost: '$host',
replaces: {},
}); });
const openCreate = () => { const openCreate = () => {
@ -85,9 +109,22 @@ const openCreate = () => {
const openEdit = (proxyConfig: Website.ProxyConfig) => { const openEdit = (proxyConfig: Website.ProxyConfig) => {
let proxy = JSON.parse(JSON.stringify(proxyConfig)); let proxy = JSON.parse(JSON.stringify(proxyConfig));
proxy.operate = 'edit'; proxy.operate = 'edit';
if (proxy.replaces == null) {
proxy.replaces = {};
}
createRef.value.acceptParams(proxy); 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) => { const changeCache = (proxyConfig: Website.ProxyConfig) => {
proxyConfig.operate = 'edit'; proxyConfig.operate = 'edit';
if (proxyConfig.cache) { if (proxyConfig.cache) {
@ -99,7 +136,7 @@ const changeCache = (proxyConfig: Website.ProxyConfig) => {
const submit = async (proxyConfig: Website.ProxyConfig) => { const submit = async (proxyConfig: Website.ProxyConfig) => {
loading.value = true; loading.value = true;
CreateProxyConfig(proxyConfig) OperateProxyConfig(proxyConfig)
.then(() => { .then(() => {
MsgSuccess(i18n.global.t('commons.msg.updateSuccess')); MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
search(); search();