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
bd8d96be4d
commit
d900b52a50
@ -648,3 +648,47 @@ func (b *BaseApi) UpdateSiteDirPermission(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
helper.SuccessWithOutData(c)
|
helper.SuccessWithOutData(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Website
|
||||||
|
// @Summary Get proxy conf
|
||||||
|
// @Description 获取反向代理配置
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsiteProxyReq true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /websites/proxies [post]
|
||||||
|
func (b *BaseApi) GetProxyConfig(c *gin.Context) {
|
||||||
|
var req request.WebsiteProxyReq
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := websiteService.GetProxies(req.ID)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Website
|
||||||
|
// @Summary Update proxy conf
|
||||||
|
// @Description 修改反向代理配置
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsiteProxyConfig true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /websites/proxies/update [post]
|
||||||
|
func (b *BaseApi) UpdateProxyConfig(c *gin.Context) {
|
||||||
|
var req request.WebsiteProxyConfig
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := websiteService.OperateProxy(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, nil)
|
||||||
|
}
|
||||||
|
@ -34,7 +34,9 @@ const (
|
|||||||
Index NginxKey = "index"
|
Index NginxKey = "index"
|
||||||
LimitConn NginxKey = "limit-conn"
|
LimitConn NginxKey = "limit-conn"
|
||||||
SSL NginxKey = "ssl"
|
SSL NginxKey = "ssl"
|
||||||
|
CACHE NginxKey = "cache"
|
||||||
HttpPer NginxKey = "http-per"
|
HttpPer NginxKey = "http-per"
|
||||||
|
ProxyCache NginxKey = "proxy-cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ScopeKeyMap = map[NginxKey][]string{
|
var ScopeKeyMap = map[NginxKey][]string{
|
||||||
@ -47,4 +49,6 @@ var ScopeKeyMap = map[NginxKey][]string{
|
|||||||
var StaticFileKeyMap = map[NginxKey]struct {
|
var StaticFileKeyMap = map[NginxKey]struct {
|
||||||
}{
|
}{
|
||||||
SSL: {},
|
SSL: {},
|
||||||
|
CACHE: {},
|
||||||
|
ProxyCache: {},
|
||||||
}
|
}
|
||||||
|
@ -156,3 +156,23 @@ type WebsiteUpdateDirPermission struct {
|
|||||||
User string `json:"user" validate:"required"`
|
User string `json:"user" validate:"required"`
|
||||||
Group string `json:"group" validate:"required"`
|
Group string `json:"group" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebsiteProxyReq struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
}
|
||||||
|
@ -161,6 +161,10 @@ func getNginxParamsFromStaticFile(scope dto.NginxKey, newParams []dto.NginxParam
|
|||||||
switch scope {
|
switch scope {
|
||||||
case dto.SSL:
|
case dto.SSL:
|
||||||
newConfig = parser.NewStringParser(string(nginx_conf.SSL)).Parse()
|
newConfig = parser.NewStringParser(string(nginx_conf.SSL)).Parse()
|
||||||
|
case dto.CACHE:
|
||||||
|
newConfig = parser.NewStringParser(string(nginx_conf.Cache)).Parse()
|
||||||
|
case dto.ProxyCache:
|
||||||
|
newConfig = parser.NewStringParser(string(nginx_conf.ProxyCache)).Parse()
|
||||||
}
|
}
|
||||||
for _, dir := range newConfig.GetDirectives() {
|
for _, dir := range newConfig.GetDirectives() {
|
||||||
addParam := dto.NginxParam{
|
addParam := dto.NginxParam{
|
||||||
|
@ -10,12 +10,16 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/nginx"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/nginx/components"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/nginx/parser"
|
||||||
"github.com/1Panel-dev/1Panel/cmd/server/nginx_conf"
|
"github.com/1Panel-dev/1Panel/cmd/server/nginx_conf"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -64,6 +68,8 @@ type IWebsiteService interface {
|
|||||||
UpdateRewriteConfig(req request.NginxRewriteUpdate) error
|
UpdateRewriteConfig(req request.NginxRewriteUpdate) error
|
||||||
UpdateSiteDir(req request.WebsiteUpdateDir) error
|
UpdateSiteDir(req request.WebsiteUpdateDir) error
|
||||||
UpdateSitePermission(req request.WebsiteUpdateDirPermission) error
|
UpdateSitePermission(req request.WebsiteUpdateDirPermission) error
|
||||||
|
OperateProxy(req request.WebsiteProxyConfig) (err error)
|
||||||
|
GetProxies(id uint) (res []request.WebsiteProxyConfig, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIWebsiteService() IWebsiteService {
|
func NewIWebsiteService() IWebsiteService {
|
||||||
@ -1105,3 +1111,169 @@ func (w WebsiteService) UpdateSitePermission(req request.WebsiteUpdateDirPermiss
|
|||||||
website.Group = req.Group
|
website.Group = req.Group
|
||||||
return websiteRepo.Save(context.Background(), &website)
|
return websiteRepo.Save(context.Background(), &website)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w WebsiteService) OperateProxy(req request.WebsiteProxyConfig) (err error) {
|
||||||
|
var (
|
||||||
|
website model.Website
|
||||||
|
params []response.NginxParam
|
||||||
|
nginxInstall model.AppInstall
|
||||||
|
par *parser.Parser
|
||||||
|
oldContent []byte
|
||||||
|
)
|
||||||
|
|
||||||
|
website, err = websiteRepo.GetFirst(commonRepo.WithByID(req.ID))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
params, err = getNginxParamsByKeys(constant.NginxScopeHttp, []string{"proxy_cache"}, &website)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
nginxInstall, err = getAppInstallByKey(constant.AppOpenresty)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fileOp := files.NewFileOp()
|
||||||
|
if len(params) == 0 || len(params[0].Params) == 0 {
|
||||||
|
commonDir := path.Join(nginxInstall.GetPath(), "www", "common", "proxy")
|
||||||
|
proxyTempPath := path.Join(commonDir, "proxy_temp_dir")
|
||||||
|
if !fileOp.Stat(proxyTempPath) {
|
||||||
|
_ = fileOp.CreateDir(proxyTempPath, 0755)
|
||||||
|
}
|
||||||
|
proxyCacheDir := path.Join(commonDir, "proxy_temp_dir")
|
||||||
|
if !fileOp.Stat(proxyCacheDir) {
|
||||||
|
_ = fileOp.CreateDir(proxyCacheDir, 0755)
|
||||||
|
}
|
||||||
|
nginxParams := getNginxParamsFromStaticFile(dto.CACHE, nil)
|
||||||
|
if err = updateNginxConfig(constant.NginxScopeHttp, nginxParams, &website); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
includeDir := path.Join(nginxInstall.GetPath(), "www", "sites", website.Alias, "proxy")
|
||||||
|
if !fileOp.Stat(includeDir) {
|
||||||
|
_ = fileOp.CreateDir(includeDir, 0755)
|
||||||
|
}
|
||||||
|
fileName := fmt.Sprintf("%s.conf", req.Name)
|
||||||
|
includePath := path.Join(includeDir, fileName)
|
||||||
|
if !fileOp.Stat(includePath) {
|
||||||
|
_ = fileOp.CreateFile(includePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
switch req.Operate {
|
||||||
|
case "create":
|
||||||
|
_ = fileOp.DeleteFile(includePath)
|
||||||
|
case "update":
|
||||||
|
_ = fileOp.WriteFile(includePath, bytes.NewReader(oldContent), 0755)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
var config *components.Config
|
||||||
|
|
||||||
|
switch req.Operate {
|
||||||
|
case "create":
|
||||||
|
config = parser.NewStringParser(string(nginx_conf.Proxy)).Parse()
|
||||||
|
case "update":
|
||||||
|
par, err = parser.NewParser(includePath)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
config = par.Parse()
|
||||||
|
oldContent, err = fileOp.GetContent(includePath)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case "delete":
|
||||||
|
_ = fileOp.DeleteFile(includePath)
|
||||||
|
return updateNginxConfig(constant.NginxScopeServer, nil, &website)
|
||||||
|
case "disable":
|
||||||
|
backName := fmt.Sprintf("%s.bak", req.Name)
|
||||||
|
backPath := path.Join(includeDir, backName)
|
||||||
|
_ = fileOp.Rename(includePath, backPath)
|
||||||
|
return updateNginxConfig(constant.NginxScopeServer, nil, &website)
|
||||||
|
}
|
||||||
|
config.FilePath = includePath
|
||||||
|
directives := config.Directives
|
||||||
|
location, ok := directives[0].(*components.Location)
|
||||||
|
if !ok {
|
||||||
|
err = errors.New("error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
location.UpdateDirective("proxy_pass", []string{req.ProxyPass})
|
||||||
|
location.UpdateDirective("proxy_set_header", []string{"Host", req.ProxyHost})
|
||||||
|
location.ChangePath(req.Modifier, req.Match)
|
||||||
|
if req.Cache {
|
||||||
|
location.AddCache(strconv.Itoa(req.CacheTime) + req.CacheUnit)
|
||||||
|
} else {
|
||||||
|
location.RemoveCache()
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
||||||
|
return buserr.WithErr(constant.ErrUpdateBuWebsite, err)
|
||||||
|
}
|
||||||
|
nginxInclude := path.Join("www", "sites", website.Alias, "proxy", "*.conf")
|
||||||
|
if err = updateNginxConfig(constant.NginxScopeServer, []dto.NginxParam{{Name: "include", Params: []string{nginxInclude}}}, &website); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WebsiteService) GetProxies(id uint) (res []request.WebsiteProxyConfig, err error) {
|
||||||
|
var (
|
||||||
|
website model.Website
|
||||||
|
nginxInstall model.AppInstall
|
||||||
|
fileList response.FileInfo
|
||||||
|
)
|
||||||
|
website, err = websiteRepo.GetFirst(commonRepo.WithByID(id))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
nginxInstall, err = getAppInstallByKey(constant.AppOpenresty)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
includeDir := path.Join(nginxInstall.GetPath(), "www", "sites", website.Alias, "proxy")
|
||||||
|
fileOp := files.NewFileOp()
|
||||||
|
if !fileOp.Stat(includeDir) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fileList, err = NewIFileService().GetFileList(request.FileOption{FileOption: files.FileOption{Path: includeDir, Expand: true, Page: 1, PageSize: 100}})
|
||||||
|
if len(fileList.Items) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
content []byte
|
||||||
|
config *components.Config
|
||||||
|
)
|
||||||
|
for _, configFile := range fileList.Items {
|
||||||
|
proxyConfig := request.WebsiteProxyConfig{}
|
||||||
|
parts := strings.Split(configFile.Name, ".")
|
||||||
|
proxyConfig.Name = parts[0]
|
||||||
|
if parts[1] == "conf" {
|
||||||
|
proxyConfig.Enable = true
|
||||||
|
} else {
|
||||||
|
proxyConfig.Enable = false
|
||||||
|
}
|
||||||
|
proxyConfig.FilePath = configFile.Path
|
||||||
|
content, err = fileOp.GetContent(configFile.Path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
config = parser.NewStringParser(string(content)).Parse()
|
||||||
|
directives := config.GetDirectives()
|
||||||
|
|
||||||
|
location, ok := directives[0].(*components.Location)
|
||||||
|
if !ok {
|
||||||
|
err = errors.New("error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
proxyConfig.ProxyPass = location.ProxyPass
|
||||||
|
proxyConfig.Cache = location.Cache
|
||||||
|
//proxyConfig.CacheTime = location.CacheTime
|
||||||
|
proxyConfig.Match = location.Match
|
||||||
|
res = append(res, proxyConfig)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@ const (
|
|||||||
|
|
||||||
NginxReload = "reload"
|
NginxReload = "reload"
|
||||||
NginxCheck = "check"
|
NginxCheck = "check"
|
||||||
|
NginxRestart = "restart"
|
||||||
|
|
||||||
ConfigNew = "add"
|
ConfigNew = "add"
|
||||||
ConfigUpdate = "update"
|
ConfigUpdate = "update"
|
||||||
|
@ -51,5 +51,8 @@ func (a *WebsiteRouter) InitWebsiteRouter(Router *gin.RouterGroup) {
|
|||||||
|
|
||||||
groupRouter.POST("/dir/update", baseApi.UpdateSiteDir)
|
groupRouter.POST("/dir/update", baseApi.UpdateSiteDir)
|
||||||
groupRouter.POST("/dir/permission", baseApi.UpdateSiteDirPermission)
|
groupRouter.POST("/dir/permission", baseApi.UpdateSiteDirPermission)
|
||||||
|
|
||||||
|
groupRouter.POST("/proxies", baseApi.GetProxyConfig)
|
||||||
|
groupRouter.POST("/proxies/update", baseApi.UpdateProxyConfig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,41 +62,6 @@ func (b *Block) UpdateDirective(key string, params []string) {
|
|||||||
b.Directives = directives
|
b.Directives = directives
|
||||||
}
|
}
|
||||||
|
|
||||||
//func (b *Block) UpdateDirectiveBySecondKey(name string, key string, directive Directive) {
|
|
||||||
//
|
|
||||||
// directives := b.GetDirectives()
|
|
||||||
//
|
|
||||||
// index := -1
|
|
||||||
// for i, dir := range directives {
|
|
||||||
// if dir.GetName() == name && dir.GetParameters()[0] == key {
|
|
||||||
// index = i
|
|
||||||
// break
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if index > -1 {
|
|
||||||
// directives[index] = &directive
|
|
||||||
// } else {
|
|
||||||
// directives = append(directives, &directive)
|
|
||||||
// }
|
|
||||||
// b.Directives = directives
|
|
||||||
//}
|
|
||||||
|
|
||||||
//func (b *Block) RemoveDirectives(names []string) {
|
|
||||||
// nameMaps := make(map[string]struct{}, len(names))
|
|
||||||
// for _, name := range names {
|
|
||||||
// nameMaps[name] = struct{}{}
|
|
||||||
// }
|
|
||||||
// directives := b.GetDirectives()
|
|
||||||
// var newDirectives []IDirective
|
|
||||||
// for _, dir := range directives {
|
|
||||||
// if _, ok := nameMaps[dir.GetName()]; ok {
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// newDirectives = append(newDirectives, dir)
|
|
||||||
// }
|
|
||||||
// b.Directives = newDirectives
|
|
||||||
//}
|
|
||||||
|
|
||||||
func (b *Block) RemoveDirective(key string, params []string) {
|
func (b *Block) RemoveDirective(key string, params []string) {
|
||||||
directives := b.GetDirectives()
|
directives := b.GetDirectives()
|
||||||
var newDirectives []IDirective
|
var newDirectives []IDirective
|
||||||
|
@ -1,32 +1,196 @@
|
|||||||
package components
|
package components
|
||||||
|
|
||||||
type Location struct {
|
type Location struct {
|
||||||
*Directive
|
|
||||||
Modifier string
|
Modifier string
|
||||||
Match string
|
Match string
|
||||||
|
Cache bool
|
||||||
|
ProxyPass string
|
||||||
|
Host string
|
||||||
|
CacheTime string
|
||||||
|
|
||||||
|
Comment string
|
||||||
|
Directives []IDirective
|
||||||
|
Line int
|
||||||
|
Parameters []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLocation(directive *Directive) *Location {
|
func NewLocation(directive IDirective) *Location {
|
||||||
location := &Location{
|
location := &Location{
|
||||||
Modifier: "",
|
Modifier: "",
|
||||||
Match: "",
|
Match: "",
|
||||||
Directive: directive,
|
|
||||||
}
|
}
|
||||||
if directive.GetBlock() != nil {
|
directives := make([]IDirective, 0)
|
||||||
directive.Comment = directive.GetBlock().GetComment()
|
if len(directive.GetParameters()) == 0 {
|
||||||
}
|
|
||||||
|
|
||||||
if len(directive.Parameters) == 0 {
|
|
||||||
panic("no enough parameter for location")
|
panic("no enough parameter for location")
|
||||||
}
|
}
|
||||||
|
for _, dir := range directive.GetBlock().GetDirectives() {
|
||||||
if len(directive.Parameters) == 1 {
|
directives = append(directives, dir)
|
||||||
location.Match = directive.Parameters[0]
|
params := dir.GetParameters()
|
||||||
return location
|
switch dir.GetName() {
|
||||||
} else if len(directive.Parameters) == 2 {
|
case "proxy_pass":
|
||||||
location.Match = directive.Parameters[1]
|
location.ProxyPass = params[0]
|
||||||
location.Modifier = directive.Parameters[0]
|
case "proxy_set_header":
|
||||||
return location
|
if params[0] == "Host" {
|
||||||
|
location.Host = params[1]
|
||||||
}
|
}
|
||||||
return nil
|
case "proxy_cache":
|
||||||
|
location.Cache = true
|
||||||
|
case "if":
|
||||||
|
if params[0] == "(" && params[1] == "$uri" && params[2] == "~*" {
|
||||||
|
dirs := dir.GetBlock().GetDirectives()
|
||||||
|
for _, di := range dirs {
|
||||||
|
if di.GetName() == "expires" {
|
||||||
|
location.CacheTime = di.GetParameters()[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
params := directive.GetParameters()
|
||||||
|
if len(params) == 1 {
|
||||||
|
location.Match = params[0]
|
||||||
|
} else if len(params) == 2 {
|
||||||
|
location.Match = params[1]
|
||||||
|
location.Modifier = params[0]
|
||||||
|
}
|
||||||
|
location.Parameters = directive.GetParameters()
|
||||||
|
location.Line = directive.GetLine()
|
||||||
|
location.Comment = directive.GetComment()
|
||||||
|
location.Directives = directives
|
||||||
|
return location
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) GetName() string {
|
||||||
|
return "location"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) GetParameters() []string {
|
||||||
|
return l.Parameters
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) GetBlock() IBlock {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) GetComment() string {
|
||||||
|
return l.Comment
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) GetLine() int {
|
||||||
|
return l.Line
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) GetDirectives() []IDirective {
|
||||||
|
return l.Directives
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) FindDirectives(directiveName string) []IDirective {
|
||||||
|
directives := make([]IDirective, 0)
|
||||||
|
for _, directive := range l.Directives {
|
||||||
|
if directive.GetName() == directiveName {
|
||||||
|
directives = append(directives, directive)
|
||||||
|
}
|
||||||
|
if directive.GetBlock() != nil {
|
||||||
|
directives = append(directives, directive.GetBlock().FindDirectives(directiveName)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return directives
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) UpdateDirective(key string, params []string) {
|
||||||
|
if key == "" || len(params) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
directives := l.Directives
|
||||||
|
index := -1
|
||||||
|
for i, dir := range directives {
|
||||||
|
if dir.GetName() == key {
|
||||||
|
if IsRepeatKey(key) {
|
||||||
|
oldParams := dir.GetParameters()
|
||||||
|
if !(len(oldParams) > 0 && oldParams[0] == params[0]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newDirective := &Directive{
|
||||||
|
Name: key,
|
||||||
|
Parameters: params,
|
||||||
|
}
|
||||||
|
if index > -1 {
|
||||||
|
directives[index] = newDirective
|
||||||
|
} else {
|
||||||
|
directives = append(directives, newDirective)
|
||||||
|
}
|
||||||
|
l.Directives = directives
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) RemoveDirective(key string, params []string) {
|
||||||
|
directives := l.Directives
|
||||||
|
var newDirectives []IDirective
|
||||||
|
for _, dir := range directives {
|
||||||
|
if dir.GetName() == key {
|
||||||
|
if len(params) > 0 {
|
||||||
|
oldParams := dir.GetParameters()
|
||||||
|
if oldParams[0] == params[0] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newDirectives = append(newDirectives, dir)
|
||||||
|
}
|
||||||
|
l.Directives = newDirectives
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) ChangePath(Modifier string, Match string) {
|
||||||
|
if Match != "" && Modifier != "" {
|
||||||
|
l.Parameters = []string{Modifier, Match}
|
||||||
|
}
|
||||||
|
if Match != "" && Modifier == "" {
|
||||||
|
l.Parameters = []string{Match}
|
||||||
|
}
|
||||||
|
l.Modifier = Modifier
|
||||||
|
l.Match = Match
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) AddCache(cacheTime string) {
|
||||||
|
l.RemoveDirective("add_header", []string{"Cache-Control", "no-cache"})
|
||||||
|
directives := l.GetDirectives()
|
||||||
|
newDir := &Directive{
|
||||||
|
Name: "if",
|
||||||
|
Parameters: []string{"(", "$uri", "~*", `"\.(gif|png|jpg|css|js|woff|woff2)$"`, ")"},
|
||||||
|
Block: &Block{},
|
||||||
|
}
|
||||||
|
block := &Block{}
|
||||||
|
block.Directives = append(block.Directives, &Directive{
|
||||||
|
Name: "expires",
|
||||||
|
Parameters: []string{cacheTime},
|
||||||
|
})
|
||||||
|
newDir.Block = block
|
||||||
|
directives = append(directives, newDir)
|
||||||
|
l.Directives = directives
|
||||||
|
l.UpdateDirective("proxy_ignore_headers", []string{"Set-Cookie", "Cache-Control", "expires"})
|
||||||
|
l.UpdateDirective("proxy_cache", []string{"proxy_cache_panel"})
|
||||||
|
l.UpdateDirective("proxy_cache_key", []string{"$host$uri$is_args$args"})
|
||||||
|
l.UpdateDirective("proxy_cache_valid", []string{"200", "304", "301", "302", "10m"})
|
||||||
|
l.Cache = true
|
||||||
|
l.CacheTime = cacheTime
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) RemoveCache() {
|
||||||
|
l.RemoveDirective("if", []string{"(", "$uri", "~*", `"\.(gif|png|jpg|css|js|woff|woff2)$"`, ")"})
|
||||||
|
l.RemoveDirective("proxy_ignore_headers", []string{"Set-Cookie"})
|
||||||
|
l.RemoveDirective("proxy_cache", []string{"proxy_cache_panel"})
|
||||||
|
l.RemoveDirective("proxy_cache_key", []string{"$host$uri$is_args$args"})
|
||||||
|
l.RemoveDirective("proxy_cache_valid", []string{"200"})
|
||||||
|
|
||||||
|
l.UpdateDirective("add_header", []string{"Cache-Control", "no-cache"})
|
||||||
|
|
||||||
|
l.CacheTime = ""
|
||||||
|
l.Cache = false
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
type Server struct {
|
type Server struct {
|
||||||
Comment string
|
Comment string
|
||||||
Listens []*ServerListen
|
Listens []*ServerListen
|
||||||
|
//Locations []*Location
|
||||||
Directives []IDirective
|
Directives []IDirective
|
||||||
Line int
|
Line int
|
||||||
}
|
}
|
||||||
@ -21,6 +22,15 @@ func NewServer(directive IDirective) (*Server, error) {
|
|||||||
switch dir.GetName() {
|
switch dir.GetName() {
|
||||||
case "listen":
|
case "listen":
|
||||||
server.Listens = append(server.Listens, NewServerListen(dir.GetParameters(), dir.GetLine()))
|
server.Listens = append(server.Listens, NewServerListen(dir.GetParameters(), dir.GetLine()))
|
||||||
|
//case "location":
|
||||||
|
// locationDirective := &Directive{
|
||||||
|
// Name: "location",
|
||||||
|
// Parameters: dir.GetParameters(),
|
||||||
|
// Block: dir.GetBlock(),
|
||||||
|
// Line: dir.GetLine(),
|
||||||
|
// Comment: dir.GetComment(),
|
||||||
|
// }
|
||||||
|
// server.Locations = append(server.Locations, NewLocation(locationDirective))
|
||||||
default:
|
default:
|
||||||
server.Directives = append(server.Directives, dir)
|
server.Directives = append(server.Directives, dir)
|
||||||
}
|
}
|
||||||
@ -51,6 +61,9 @@ func (s *Server) GetDirectives() []IDirective {
|
|||||||
for _, ls := range s.Listens {
|
for _, ls := range s.Listens {
|
||||||
directives = append(directives, ls)
|
directives = append(directives, ls)
|
||||||
}
|
}
|
||||||
|
//for _, la := range s.Locations {
|
||||||
|
// directives = append(directives, la)
|
||||||
|
//}
|
||||||
directives = append(directives, s.Directives...)
|
directives = append(directives, s.Directives...)
|
||||||
return directives
|
return directives
|
||||||
}
|
}
|
||||||
@ -116,13 +129,6 @@ func (s *Server) RemoveDirective(key string, params []string) {
|
|||||||
directives := s.Directives
|
directives := s.Directives
|
||||||
var newDirectives []IDirective
|
var newDirectives []IDirective
|
||||||
for _, dir := range directives {
|
for _, dir := range directives {
|
||||||
if key == "location" {
|
|
||||||
if location, ok := dir.(*Location); ok {
|
|
||||||
if len(params) == 2 && location.Match == params[1] && location.Modifier == params[0] {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if dir.GetName() == key {
|
if dir.GetName() == key {
|
||||||
if len(params) > 0 {
|
if len(params) > 0 {
|
||||||
oldParams := dir.GetParameters()
|
oldParams := dir.GetParameters()
|
||||||
@ -133,7 +139,6 @@ func (s *Server) RemoveDirective(key string, params []string) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
newDirectives = append(newDirectives, dir)
|
newDirectives = append(newDirectives, dir)
|
||||||
}
|
}
|
||||||
s.Directives = newDirectives
|
s.Directives = newDirectives
|
||||||
|
@ -74,7 +74,6 @@ func DumpBlock(b components.IBlock, style *Style, startLine int) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
directives := b.GetDirectives()
|
directives := b.GetDirectives()
|
||||||
|
|
||||||
for i, directive := range directives {
|
for i, directive := range directives {
|
||||||
|
|
||||||
if directive.GetLine() > line {
|
if directive.GetLine() > line {
|
||||||
|
@ -84,7 +84,6 @@ func (p *Parser) Parse() *components.Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) parseBlock() *components.Block {
|
func (p *Parser) parseBlock() *components.Block {
|
||||||
|
|
||||||
context := &components.Block{
|
context := &components.Block{
|
||||||
Comment: "",
|
Comment: "",
|
||||||
Directives: make([]components.IDirective, 0),
|
Directives: make([]components.IDirective, 0),
|
||||||
|
12
cmd/server/nginx_conf/cache.conf
Normal file
12
cmd/server/nginx_conf/cache.conf
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
proxy_temp_path /www/common/proxy/proxy_temp_dir;
|
||||||
|
proxy_cache_path /www/common/proxy/proxy_cache_dir levels=1:2 keys_zone=proxy_cache_panel:20m inactive=1d max_size=5g;
|
||||||
|
client_body_buffer_size 512k;
|
||||||
|
proxy_connect_timeout 60;
|
||||||
|
proxy_read_timeout 60;
|
||||||
|
proxy_send_timeout 60;
|
||||||
|
proxy_buffer_size 32k;
|
||||||
|
proxy_buffers 4 64k;
|
||||||
|
proxy_busy_buffers_size 128k;
|
||||||
|
proxy_temp_file_write_size 128k;
|
||||||
|
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
|
||||||
|
proxy_cache proxy_cache_panel;
|
@ -19,3 +19,12 @@ var IndexPHP []byte
|
|||||||
|
|
||||||
//go:embed rewrite/*
|
//go:embed rewrite/*
|
||||||
var Rewrites embed.FS
|
var Rewrites embed.FS
|
||||||
|
|
||||||
|
//go:embed cache.conf
|
||||||
|
var Cache []byte
|
||||||
|
|
||||||
|
//go:embed proxy.conf
|
||||||
|
var Proxy []byte
|
||||||
|
|
||||||
|
//go:embed proxy_cache.conf
|
||||||
|
var ProxyCache []byte
|
||||||
|
12
cmd/server/nginx_conf/proxy.conf
Normal file
12
cmd/server/nginx_conf/proxy.conf
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
location ^~ /test {
|
||||||
|
proxy_pass http://1panel.cloud/;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header REMOTE-HOST $remote_addr;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
|
add_header X-Cache $upstream_cache_status;
|
||||||
|
}
|
4
cmd/server/nginx_conf/proxy_cache.conf
Normal file
4
cmd/server/nginx_conf/proxy_cache.conf
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
proxy_ignore_headers Set-Cookie Cache-Control expires;
|
||||||
|
proxy_cache cache_one;
|
||||||
|
proxy_cache_key $host$uri$is_args$args;
|
||||||
|
proxy_cache_valid 200 304 301 302 10m;
|
10
cmd/server/nginx_conf/proxy_no_cache.conf
Normal file
10
cmd/server/nginx_conf/proxy_no_cache.conf
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
set $static_fileg 0;
|
||||||
|
if ( $uri ~* "\.(gif|png|jpg|css|js|woff|woff2)$" )
|
||||||
|
{
|
||||||
|
set $static_fileg 1;
|
||||||
|
expires 1m;
|
||||||
|
}
|
||||||
|
if ( $static_fileg = 0 )
|
||||||
|
{
|
||||||
|
add_header Cache-Control no-cache;
|
||||||
|
}
|
@ -307,4 +307,28 @@ export namespace Website {
|
|||||||
user: string;
|
user: string;
|
||||||
group: string;
|
group: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ProxyReq {
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProxyConfig {
|
||||||
|
id: number;
|
||||||
|
operate: string;
|
||||||
|
enable: boolean;
|
||||||
|
cache: boolean;
|
||||||
|
cacheTime: number;
|
||||||
|
cacheUnit: string;
|
||||||
|
name: string;
|
||||||
|
modifier: string;
|
||||||
|
match: string;
|
||||||
|
proxyPass: string;
|
||||||
|
proxyHost: string;
|
||||||
|
filePath?: string;
|
||||||
|
replaces?: ProxReplace;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ProxReplace {
|
||||||
|
[key: string]: string;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import http from '@/api';
|
import http from '@/api';
|
||||||
import { ReqPage, ResPage } from '../interface';
|
import { ReqPage, ResPage } from '../interface';
|
||||||
import { Website } from '../interface/Website';
|
import { Website } from '../interface/website';
|
||||||
import { File } from '../interface/file';
|
import { File } from '../interface/file';
|
||||||
|
|
||||||
export const SearchWebsites = (req: Website.WebSiteSearch) => {
|
export const SearchWebsites = (req: Website.WebSiteSearch) => {
|
||||||
@ -186,3 +186,11 @@ export const UpdateWebsiteDir = (req: Website.DirUpdate) => {
|
|||||||
export const UpdateWebsiteDirPermission = (req: Website.DirPermissionUpdate) => {
|
export const UpdateWebsiteDirPermission = (req: Website.DirPermissionUpdate) => {
|
||||||
return http.post<any>(`/websites/dir/permission`, req);
|
return http.post<any>(`/websites/dir/permission`, req);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const GetProxyConfig = (req: Website.ProxyReq) => {
|
||||||
|
return http.post<Website.ProxyConfig[]>(`/websites/proxies`, req);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CreateProxyConfig = (req: Website.ProxyReq) => {
|
||||||
|
return http.post<any>(`/websites/proxies/update`, req);
|
||||||
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { CompressType } from '@/enums/files';
|
import { CompressType } from '@/enums/files';
|
||||||
|
import i18n from '@/lang';
|
||||||
|
|
||||||
export const Mimetypes = new Map([
|
export const Mimetypes = new Map([
|
||||||
['application/zip', CompressType.Zip],
|
['application/zip', CompressType.Zip],
|
||||||
@ -110,3 +111,13 @@ export const Rewrites = [
|
|||||||
'shopex',
|
'shopex',
|
||||||
'zblog',
|
'zblog',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const Units = [
|
||||||
|
{ label: i18n.global.t('commons.units.second'), value: 's' },
|
||||||
|
{ label: i18n.global.t('commons.units.miniute'), value: 'm' },
|
||||||
|
{ label: i18n.global.t('commons.units.hour'), value: 'h' },
|
||||||
|
{ label: i18n.global.t('commons.units.day'), value: 'd' },
|
||||||
|
{ label: i18n.global.t('commons.units.week'), value: 'w' },
|
||||||
|
{ label: i18n.global.t('commons.units.month'), value: 'M' },
|
||||||
|
{ label: i18n.global.t('commons.units.year'), value: 'Y' },
|
||||||
|
];
|
||||||
|
@ -201,6 +201,15 @@ const message = {
|
|||||||
normal: '正常',
|
normal: '正常',
|
||||||
building: '制作镜像中',
|
building: '制作镜像中',
|
||||||
},
|
},
|
||||||
|
units: {
|
||||||
|
second: '秒',
|
||||||
|
miniute: '分钟',
|
||||||
|
hour: '小时',
|
||||||
|
day: '天',
|
||||||
|
week: '周',
|
||||||
|
month: '月',
|
||||||
|
year: '年',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
menu: {
|
menu: {
|
||||||
home: '概览',
|
home: '概览',
|
||||||
@ -1174,6 +1183,17 @@ const message = {
|
|||||||
userGroup: '运行用户/组',
|
userGroup: '运行用户/组',
|
||||||
user: '用户',
|
user: '用户',
|
||||||
uGroup: '用户组',
|
uGroup: '用户组',
|
||||||
|
addProxy: '添加反向代理',
|
||||||
|
proxyPath: '代理目录',
|
||||||
|
proxyPass: '目标URL',
|
||||||
|
cache: '缓存',
|
||||||
|
status: '状态',
|
||||||
|
createProxy: '创建反向代理',
|
||||||
|
editProxy: '编辑反向代理',
|
||||||
|
cacheTime: '缓存时间',
|
||||||
|
enableCache: '开启缓存',
|
||||||
|
proxyHost: '发送域名',
|
||||||
|
disabled: '已停止',
|
||||||
},
|
},
|
||||||
php: {
|
php: {
|
||||||
short_open_tag: '短标签支持',
|
short_open_tag: '短标签支持',
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Website } from '@/api/interface/Website';
|
import { Website } from '@/api/interface/website';
|
||||||
import { RenewSSL } from '@/api/modules/website';
|
import { RenewSSL } from '@/api/modules/website';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgSuccess } from '@/utils/message';
|
||||||
|
@ -12,14 +12,17 @@
|
|||||||
<el-tab-pane :label="$t('website.rate')">
|
<el-tab-pane :label="$t('website.rate')">
|
||||||
<LimitConn :id="id" v-if="tabIndex == '3'"></LimitConn>
|
<LimitConn :id="id" v-if="tabIndex == '3'"></LimitConn>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
<el-tab-pane :label="$t('website.proxy')">
|
||||||
|
<Proxy :id="id" v-if="tabIndex == '4'"></Proxy>
|
||||||
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="'HTTPS'">
|
<el-tab-pane :label="'HTTPS'">
|
||||||
<HTTPS :id="id" v-if="tabIndex == '4'"></HTTPS>
|
<HTTPS :id="id" v-if="tabIndex == '5'"></HTTPS>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('website.rewrite')">
|
<el-tab-pane :label="$t('website.rewrite')">
|
||||||
<Rewrite :id="id" v-if="tabIndex == '5'"></Rewrite>
|
<Rewrite :id="id" v-if="tabIndex == '6'"></Rewrite>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('website.other')">
|
<el-tab-pane :label="$t('website.other')">
|
||||||
<Other :id="id" v-if="tabIndex == '6'"></Other>
|
<Other :id="id" v-if="tabIndex == '7'"></Other>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</template>
|
</template>
|
||||||
@ -34,6 +37,7 @@ import Other from './other/index.vue';
|
|||||||
import HTTPS from './https/index.vue';
|
import HTTPS from './https/index.vue';
|
||||||
import SitePath from './site-folder/index.vue';
|
import SitePath from './site-folder/index.vue';
|
||||||
import Rewrite from './rewrite/index.vue';
|
import Rewrite from './rewrite/index.vue';
|
||||||
|
import Proxy from './proxy/index.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
@ -41,11 +45,9 @@ const props = defineProps({
|
|||||||
default: -1,
|
default: -1,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const id = computed(() => {
|
const id = computed(() => {
|
||||||
return props.id;
|
return props.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
const tabIndex = ref('0');
|
const tabIndex = ref('0');
|
||||||
|
|
||||||
onMounted(() => {});
|
onMounted(() => {});
|
||||||
|
@ -0,0 +1,130 @@
|
|||||||
|
<template>
|
||||||
|
<el-drawer v-model="open" :close-on-click-modal="false" size="40%" :before-close="handleClose">
|
||||||
|
<template #header>
|
||||||
|
<DrawerHeader :header="$t('website.createProxy')" :back="handleClose" />
|
||||||
|
</template>
|
||||||
|
<el-row v-loading="loading">
|
||||||
|
<el-col :span="22" :offset="1">
|
||||||
|
<el-form ref="proxyForm" label-position="top" :model="proxy" :rules="rules">
|
||||||
|
<el-form-item :label="$t('commons.table.name')" prop="name">
|
||||||
|
<el-input v-model.trim="proxy.name"></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>
|
||||||
|
<el-form-item :label="$t('website.enableCache')" prop="cache">
|
||||||
|
<el-switch v-model="proxy.cache"></el-switch>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t('website.cacheTime')" prop="cacheTime" v-if="proxy.cache">
|
||||||
|
<el-input v-model.number="proxy.cacheTime" maxlength="15">
|
||||||
|
<template #append>
|
||||||
|
<el-select v-model="proxy.cacheUnit" style="width: 80px">
|
||||||
|
<el-option
|
||||||
|
v-for="(unit, index) in Units"
|
||||||
|
:key="index"
|
||||||
|
:label="unit.label"
|
||||||
|
:value="unit.value"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-row :gutter="10">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('website.proxyPass')" prop="proxyPass">
|
||||||
|
<el-input v-model.trim="proxy.proxyPass"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('website.proxyHost')" prop="proxyHost">
|
||||||
|
<el-input v-model.trim="proxy.proxyHost"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</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(proxyForm)" :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 { CreateProxyConfig } 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 { Website } from '@/api/interface/website';
|
||||||
|
import { Units } from '@/global/mimetype';
|
||||||
|
// import { Website } from '@/api/interface/website';
|
||||||
|
|
||||||
|
const proxyForm = ref<FormInstance>();
|
||||||
|
const rules = ref({
|
||||||
|
name: [Rules.requiredInput, Rules.appName],
|
||||||
|
match: [Rules.requiredInput],
|
||||||
|
cacheTime: [Rules.requiredInput, checkNumberRange(1, 65535)],
|
||||||
|
proxyPass: [Rules.requiredInput],
|
||||||
|
proxyHost: [Rules.requiredInput],
|
||||||
|
});
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
const initData = (): Website.ProxyConfig => ({
|
||||||
|
id: 0,
|
||||||
|
operate: 'create',
|
||||||
|
enable: true,
|
||||||
|
cache: false,
|
||||||
|
cacheTime: 1,
|
||||||
|
cacheUnit: 'm',
|
||||||
|
name: '',
|
||||||
|
modifier: '^~',
|
||||||
|
match: '/',
|
||||||
|
proxyPass: 'http://',
|
||||||
|
proxyHost: '$host',
|
||||||
|
filePath: '',
|
||||||
|
});
|
||||||
|
let proxy = ref(initData());
|
||||||
|
|
||||||
|
const em = defineEmits(['close']);
|
||||||
|
const handleClose = () => {
|
||||||
|
proxyForm.value?.resetFields();
|
||||||
|
open.value = false;
|
||||||
|
em('close', false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const acceptParams = async (proxyParam: Website.ProxyConfig) => {
|
||||||
|
proxy.value = proxyParam;
|
||||||
|
open.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const submit = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
await formEl.validate((valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loading.value = true;
|
||||||
|
CreateProxyConfig(proxy.value)
|
||||||
|
.then(() => {
|
||||||
|
MsgSuccess(i18n.global.t('commons.msg.createSuccess'));
|
||||||
|
handleClose();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
acceptParams,
|
||||||
|
});
|
||||||
|
</script>
|
@ -0,0 +1,79 @@
|
|||||||
|
<template>
|
||||||
|
<ComplexTable :data="data" @search="search" v-loading="loading">
|
||||||
|
<template #toolbar>
|
||||||
|
<el-button type="primary" plain @click="openCreate">{{ $t('website.addProxy') }}</el-button>
|
||||||
|
</template>
|
||||||
|
<el-table-column :label="$t('commons.table.name')" prop="name"></el-table-column>
|
||||||
|
<el-table-column :label="$t('website.proxyPath')" prop="match"></el-table-column>
|
||||||
|
<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"></el-switch>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :label="$t('commons.table.status')" prop="enable">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button v-if="row.enable" link type="success" :icon="VideoPlay">
|
||||||
|
{{ $t('commons.status.running') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button v-else link type="danger" :icon="VideoPause">
|
||||||
|
{{ $t('commons.status.stopped') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</ComplexTable>
|
||||||
|
<Create ref="createRef" @close="search()" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup name="proxy">
|
||||||
|
import { Website } from '@/api/interface/website';
|
||||||
|
import { GetProxyConfig } from '@/api/modules/website';
|
||||||
|
import { computed, onMounted, ref } from 'vue';
|
||||||
|
import Create from './create/index.vue';
|
||||||
|
import { VideoPlay, VideoPause } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const id = computed(() => {
|
||||||
|
return props.id;
|
||||||
|
});
|
||||||
|
const loading = ref(false);
|
||||||
|
const data = ref();
|
||||||
|
const createRef = ref();
|
||||||
|
|
||||||
|
const initData = (id: number): Website.ProxyConfig => ({
|
||||||
|
id: id,
|
||||||
|
operate: 'create',
|
||||||
|
enable: true,
|
||||||
|
cache: false,
|
||||||
|
cacheTime: 1,
|
||||||
|
cacheUnit: 'm',
|
||||||
|
name: '',
|
||||||
|
modifier: '^~',
|
||||||
|
match: '/',
|
||||||
|
proxyPass: 'http://',
|
||||||
|
proxyHost: '$host',
|
||||||
|
});
|
||||||
|
|
||||||
|
const openCreate = () => {
|
||||||
|
createRef.value.acceptParams(initData(id.value));
|
||||||
|
};
|
||||||
|
const search = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const res = await GetProxyConfig({ id: id.value });
|
||||||
|
data.value = res.data || [];
|
||||||
|
} catch (error) {
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
search();
|
||||||
|
});
|
||||||
|
</script>
|
@ -38,7 +38,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<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 { Website } from '@/api/interface/Website';
|
import { Website } from '@/api/interface/website';
|
||||||
import { ChangeDefaultServer, ListWebsites } from '@/api/modules/website';
|
import { ChangeDefaultServer, ListWebsites } from '@/api/modules/website';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user