mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-11-06 17:58:30 +08:00
feat: PHP 运行环境增加配置修改 (#6384)
Some checks failed
sync2gitee / repo-sync (push) Failing after -8m44s
Some checks failed
sync2gitee / repo-sync (push) Failing after -8m44s
This commit is contained in:
parent
44336c2ea2
commit
1af83c1aeb
25 changed files with 496 additions and 538 deletions
|
|
@ -297,3 +297,89 @@ func (b *BaseApi) UnInstallPHPExtension(c *gin.Context) {
|
|||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Runtime
|
||||
// @Summary Load php runtime conf
|
||||
// @Description 获取 php 运行环境配置
|
||||
// @Accept json
|
||||
// @Param id path integer true "request"
|
||||
// @Success 200 {object} response.PHPConfig
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /runtimes/php/config/:id [get]
|
||||
func (b *BaseApi) GetPHPConfig(c *gin.Context) {
|
||||
id, err := helper.GetParamID(c)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
|
||||
return
|
||||
}
|
||||
data, err := runtimeService.GetPHPConfig(id)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags Runtime
|
||||
// @Summary Update runtime php conf
|
||||
// @Description 更新运行环境 PHP 配置
|
||||
// @Accept json
|
||||
// @Param request body request.PHPConfigUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /runtimes/php/config [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"[domain] PHP 配置修改","formatEN":"[domain] PHP conf update"}
|
||||
func (b *BaseApi) UpdatePHPConfig(c *gin.Context) {
|
||||
var req request.PHPConfigUpdate
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if err := runtimeService.UpdatePHPConfig(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Runtime
|
||||
// @Summary Update php conf file
|
||||
// @Description 更新 php 配置文件
|
||||
// @Accept json
|
||||
// @Param request body request.WebsitePHPFileUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /runtimes/php/update [post]
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"php 配置修改 [domain]","formatEN":"Nginx conf update [domain]"}
|
||||
func (b *BaseApi) UpdatePHPFile(c *gin.Context) {
|
||||
var req request.PHPFileUpdate
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if err := runtimeService.UpdatePHPConfigFile(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// 写一个调用 GetPHPConfigFile 的方法
|
||||
// @Tags Runtime
|
||||
// @Summary Get php conf file
|
||||
// @Description 获取 php 配置文件
|
||||
// @Accept json
|
||||
// @Param request body request.PHPFileReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /runtimes/php/file [post]
|
||||
func (b *BaseApi) GetPHPConfigFile(c *gin.Context) {
|
||||
var req request.PHPFileReq
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
data, err := runtimeService.GetPHPConfigFile(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -373,70 +373,6 @@ func (b *BaseApi) ChangeDefaultServer(c *gin.Context) {
|
|||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Load website php conf
|
||||
// @Description 获取网站 php 配置
|
||||
// @Accept json
|
||||
// @Param id path integer true "request"
|
||||
// @Success 200 {object} response.PHPConfig
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/php/config/:id [get]
|
||||
func (b *BaseApi) GetWebsitePHPConfig(c *gin.Context) {
|
||||
id, err := helper.GetParamID(c)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
|
||||
return
|
||||
}
|
||||
data, err := websiteService.GetPHPConfig(id)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags Website PHP
|
||||
// @Summary Update website php conf
|
||||
// @Description 更新 网站 PHP 配置
|
||||
// @Accept json
|
||||
// @Param request body request.WebsitePHPConfigUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/php/config [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"[domain] PHP 配置修改","formatEN":"[domain] PHP conf update"}
|
||||
func (b *BaseApi) UpdateWebsitePHPConfig(c *gin.Context) {
|
||||
var req request.WebsitePHPConfigUpdate
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if err := websiteService.UpdatePHPConfig(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Website PHP
|
||||
// @Summary Update php conf
|
||||
// @Description 更新 php 配置文件
|
||||
// @Accept json
|
||||
// @Param request body request.WebsitePHPFileUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/php/update [post]
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"php 配置修改 [domain]","formatEN":"Nginx conf update [domain]"}
|
||||
func (b *BaseApi) UpdatePHPFile(c *gin.Context) {
|
||||
var req request.WebsitePHPFileUpdate
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if err := websiteService.UpdatePHPConfigFile(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Website PHP
|
||||
// @Summary Update php version
|
||||
// @Description 变更 php 版本
|
||||
|
|
|
|||
|
|
@ -76,3 +76,22 @@ type PHPExtensionInstallReq struct {
|
|||
Name string `json:"name" validate:"required"`
|
||||
TaskID string `json:"taskID"`
|
||||
}
|
||||
|
||||
type PHPConfigUpdate struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Params map[string]string `json:"params"`
|
||||
Scope string `json:"scope" validate:"required"`
|
||||
DisableFunctions []string `json:"disableFunctions"`
|
||||
UploadMaxSize string `json:"uploadMaxSize"`
|
||||
}
|
||||
|
||||
type PHPFileUpdate struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
}
|
||||
|
||||
type PHPFileReq struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -181,20 +181,6 @@ type WebsiteDefaultUpdate struct {
|
|||
ID uint `json:"id"`
|
||||
}
|
||||
|
||||
type WebsitePHPConfigUpdate struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Params map[string]string `json:"params"`
|
||||
Scope string `json:"scope" validate:"required"`
|
||||
DisableFunctions []string `json:"disableFunctions"`
|
||||
UploadMaxSize string `json:"uploadMaxSize"`
|
||||
}
|
||||
|
||||
type WebsitePHPFileUpdate struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsitePHPVersionReq struct {
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
RuntimeID uint `json:"runtimeID" validate:"required"`
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/task"
|
||||
"github.com/1Panel-dev/1Panel/agent/cmd/server/nginx_conf"
|
||||
"gopkg.in/ini.v1"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
|
@ -51,6 +53,10 @@ type IRuntimeService interface {
|
|||
GetPHPExtensions(runtimeID uint) (response.PHPExtensionRes, error)
|
||||
InstallPHPExtension(req request.PHPExtensionInstallReq) error
|
||||
UnInstallPHPExtension(req request.PHPExtensionInstallReq) error
|
||||
GetPHPConfig(id uint) (*response.PHPConfig, error)
|
||||
UpdatePHPConfig(req request.PHPConfigUpdate) (err error)
|
||||
UpdatePHPConfigFile(req request.PHPFileUpdate) error
|
||||
GetPHPConfigFile(req request.PHPFileReq) (*response.FileInfo, error)
|
||||
}
|
||||
|
||||
func NewRuntimeService() IRuntimeService {
|
||||
|
|
@ -744,3 +750,163 @@ func (r *RuntimeService) UnInstallPHPExtension(req request.PHPExtensionInstallRe
|
|||
}
|
||||
return runtimeRepo.Save(runtime)
|
||||
}
|
||||
|
||||
func (r *RuntimeService) GetPHPConfig(id uint) (*response.PHPConfig, error) {
|
||||
runtime, err := runtimeRepo.GetFirst(commonRepo.WithByID(id))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
phpConfigPath := path.Join(runtime.GetPath(), "conf", "php.ini")
|
||||
fileOp := files.NewFileOp()
|
||||
if !fileOp.Stat(phpConfigPath) {
|
||||
return nil, buserr.WithName("ErrFileNotFound", "php.ini")
|
||||
}
|
||||
params := make(map[string]string)
|
||||
configFile, err := fileOp.OpenFile(phpConfigPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer configFile.Close()
|
||||
scanner := bufio.NewScanner(configFile)
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
if strings.HasPrefix(line, ";") {
|
||||
continue
|
||||
}
|
||||
matches := regexp.MustCompile(`^\s*([a-z_]+)\s*=\s*(.*)$`).FindStringSubmatch(line)
|
||||
if len(matches) == 3 {
|
||||
params[matches[1]] = matches[2]
|
||||
}
|
||||
}
|
||||
cfg, err := ini.Load(phpConfigPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
phpConfig, err := cfg.GetSection("PHP")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
disableFunctionStr := phpConfig.Key("disable_functions").Value()
|
||||
res := &response.PHPConfig{Params: params}
|
||||
if disableFunctionStr != "" {
|
||||
disableFunctions := strings.Split(disableFunctionStr, ",")
|
||||
if len(disableFunctions) > 0 {
|
||||
res.DisableFunctions = disableFunctions
|
||||
}
|
||||
}
|
||||
uploadMaxSize := phpConfig.Key("upload_max_filesize").Value()
|
||||
if uploadMaxSize != "" {
|
||||
res.UploadMaxSize = uploadMaxSize
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (r *RuntimeService) UpdatePHPConfig(req request.PHPConfigUpdate) (err error) {
|
||||
runtime, err := runtimeRepo.GetFirst(commonRepo.WithByID(req.ID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
phpConfigPath := path.Join(runtime.GetPath(), "conf", "php.ini")
|
||||
fileOp := files.NewFileOp()
|
||||
if !fileOp.Stat(phpConfigPath) {
|
||||
return buserr.WithMap("ErrFileNotFound", map[string]interface{}{"name": "php.ini"}, nil)
|
||||
}
|
||||
configFile, err := fileOp.OpenFile(phpConfigPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer configFile.Close()
|
||||
|
||||
contentBytes, err := fileOp.GetContent(phpConfigPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
content := string(contentBytes)
|
||||
lines := strings.Split(content, "\n")
|
||||
for i, line := range lines {
|
||||
if strings.HasPrefix(line, ";") {
|
||||
continue
|
||||
}
|
||||
switch req.Scope {
|
||||
case "params":
|
||||
for key, value := range req.Params {
|
||||
pattern := "^" + regexp.QuoteMeta(key) + "\\s*=\\s*.*$"
|
||||
if matched, _ := regexp.MatchString(pattern, line); matched {
|
||||
lines[i] = key + " = " + value
|
||||
}
|
||||
}
|
||||
case "disable_functions":
|
||||
pattern := "^" + regexp.QuoteMeta("disable_functions") + "\\s*=\\s*.*$"
|
||||
if matched, _ := regexp.MatchString(pattern, line); matched {
|
||||
lines[i] = "disable_functions" + " = " + strings.Join(req.DisableFunctions, ",")
|
||||
break
|
||||
}
|
||||
case "upload_max_filesize":
|
||||
pattern := "^" + regexp.QuoteMeta("post_max_size") + "\\s*=\\s*.*$"
|
||||
if matched, _ := regexp.MatchString(pattern, line); matched {
|
||||
lines[i] = "post_max_size" + " = " + req.UploadMaxSize
|
||||
}
|
||||
patternUpload := "^" + regexp.QuoteMeta("upload_max_filesize") + "\\s*=\\s*.*$"
|
||||
if matched, _ := regexp.MatchString(patternUpload, line); matched {
|
||||
lines[i] = "upload_max_filesize" + " = " + req.UploadMaxSize
|
||||
}
|
||||
}
|
||||
}
|
||||
updatedContent := strings.Join(lines, "\n")
|
||||
if err := fileOp.WriteFile(phpConfigPath, strings.NewReader(updatedContent), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = r.OperateRuntime(request.RuntimeOperate{
|
||||
Operate: constant.RuntimeRestart,
|
||||
ID: req.ID,
|
||||
})
|
||||
if err != nil {
|
||||
_ = fileOp.WriteFile(phpConfigPath, strings.NewReader(string(contentBytes)), 0755)
|
||||
return err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *RuntimeService) GetPHPConfigFile(req request.PHPFileReq) (*response.FileInfo, error) {
|
||||
runtime, err := runtimeRepo.GetFirst(commonRepo.WithByID(req.ID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
configPath := ""
|
||||
switch req.Type {
|
||||
case constant.ConfigFPM:
|
||||
configPath = path.Join(runtime.GetPath(), "conf", "php-fpm.conf")
|
||||
case constant.ConfigPHP:
|
||||
configPath = path.Join(runtime.GetPath(), "conf", "php.ini")
|
||||
}
|
||||
info, err := files.NewFileInfo(files.FileOption{
|
||||
Path: configPath,
|
||||
Expand: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &response.FileInfo{FileInfo: *info}, nil
|
||||
}
|
||||
|
||||
func (r *RuntimeService) UpdatePHPConfigFile(req request.PHPFileUpdate) error {
|
||||
runtime, err := runtimeRepo.GetFirst(commonRepo.WithByID(req.ID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
configPath := ""
|
||||
if req.Type == constant.ConfigFPM {
|
||||
configPath = path.Join(runtime.GetPath(), "conf", "php-fpm.conf")
|
||||
} else {
|
||||
configPath = path.Join(runtime.GetPath(), "conf", "php.ini")
|
||||
}
|
||||
if err := files.NewFileOp().WriteFile(configPath, strings.NewReader(req.Content), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := compose.Restart(runtime.GetComposePath()); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,23 +31,21 @@ import (
|
|||
"github.com/1Panel-dev/1Panel/agent/utils/env"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto/response"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/agent/buserr"
|
||||
"github.com/1Panel-dev/1Panel/agent/cmd/server/nginx_conf"
|
||||
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||
"github.com/1Panel-dev/1Panel/agent/global"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/files"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/nginx"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/nginx/components"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/nginx/parser"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gopkg.in/ini.v1"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/files"
|
||||
)
|
||||
|
||||
type WebsiteService struct {
|
||||
|
|
@ -78,9 +76,6 @@ type IWebsiteService interface {
|
|||
ChangeDefaultServer(id uint) error
|
||||
PreInstallCheck(req request.WebsiteInstallCheckReq) ([]response.WebsitePreInstallCheck, error)
|
||||
|
||||
GetPHPConfig(id uint) (*response.PHPConfig, error)
|
||||
UpdatePHPConfig(req request.WebsitePHPConfigUpdate) error
|
||||
UpdatePHPConfigFile(req request.WebsitePHPFileUpdate) error
|
||||
ChangePHPVersion(req request.WebsitePHPVersionReq) error
|
||||
|
||||
GetRewriteConfig(req request.NginxRewriteReq) (*response.NginxRewriteRes, error)
|
||||
|
|
@ -1319,167 +1314,6 @@ func (w WebsiteService) ChangeDefaultServer(id uint) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (w WebsiteService) GetPHPConfig(id uint) (*response.PHPConfig, error) {
|
||||
website, err := websiteRepo.GetFirst(commonRepo.WithByID(id))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
phpConfigPath := path.Join(appInstall.GetPath(), "conf", "php.ini")
|
||||
fileOp := files.NewFileOp()
|
||||
if !fileOp.Stat(phpConfigPath) {
|
||||
return nil, buserr.WithMap("ErrFileNotFound", map[string]interface{}{"name": "php.ini"}, nil)
|
||||
}
|
||||
params := make(map[string]string)
|
||||
configFile, err := fileOp.OpenFile(phpConfigPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer configFile.Close()
|
||||
scanner := bufio.NewScanner(configFile)
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
if strings.HasPrefix(line, ";") {
|
||||
continue
|
||||
}
|
||||
matches := regexp.MustCompile(`^\s*([a-z_]+)\s*=\s*(.*)$`).FindStringSubmatch(line)
|
||||
if len(matches) == 3 {
|
||||
params[matches[1]] = matches[2]
|
||||
}
|
||||
}
|
||||
cfg, err := ini.Load(phpConfigPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
phpConfig, err := cfg.GetSection("PHP")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
disableFunctionStr := phpConfig.Key("disable_functions").Value()
|
||||
res := &response.PHPConfig{Params: params}
|
||||
if disableFunctionStr != "" {
|
||||
disableFunctions := strings.Split(disableFunctionStr, ",")
|
||||
if len(disableFunctions) > 0 {
|
||||
res.DisableFunctions = disableFunctions
|
||||
}
|
||||
}
|
||||
uploadMaxSize := phpConfig.Key("upload_max_filesize").Value()
|
||||
if uploadMaxSize != "" {
|
||||
res.UploadMaxSize = uploadMaxSize
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (w WebsiteService) UpdatePHPConfig(req request.WebsitePHPConfigUpdate) (err error) {
|
||||
website, err := websiteRepo.GetFirst(commonRepo.WithByID(req.ID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
phpConfigPath := path.Join(appInstall.GetPath(), "conf", "php.ini")
|
||||
fileOp := files.NewFileOp()
|
||||
if !fileOp.Stat(phpConfigPath) {
|
||||
return buserr.WithMap("ErrFileNotFound", map[string]interface{}{"name": "php.ini"}, nil)
|
||||
}
|
||||
configFile, err := fileOp.OpenFile(phpConfigPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer configFile.Close()
|
||||
|
||||
contentBytes, err := fileOp.GetContent(phpConfigPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
content := string(contentBytes)
|
||||
lines := strings.Split(content, "\n")
|
||||
for i, line := range lines {
|
||||
if strings.HasPrefix(line, ";") {
|
||||
continue
|
||||
}
|
||||
switch req.Scope {
|
||||
case "params":
|
||||
for key, value := range req.Params {
|
||||
pattern := "^" + regexp.QuoteMeta(key) + "\\s*=\\s*.*$"
|
||||
if matched, _ := regexp.MatchString(pattern, line); matched {
|
||||
lines[i] = key + " = " + value
|
||||
}
|
||||
}
|
||||
case "disable_functions":
|
||||
pattern := "^" + regexp.QuoteMeta("disable_functions") + "\\s*=\\s*.*$"
|
||||
if matched, _ := regexp.MatchString(pattern, line); matched {
|
||||
lines[i] = "disable_functions" + " = " + strings.Join(req.DisableFunctions, ",")
|
||||
break
|
||||
}
|
||||
case "upload_max_filesize":
|
||||
pattern := "^" + regexp.QuoteMeta("post_max_size") + "\\s*=\\s*.*$"
|
||||
if matched, _ := regexp.MatchString(pattern, line); matched {
|
||||
lines[i] = "post_max_size" + " = " + req.UploadMaxSize
|
||||
}
|
||||
patternUpload := "^" + regexp.QuoteMeta("upload_max_filesize") + "\\s*=\\s*.*$"
|
||||
if matched, _ := regexp.MatchString(patternUpload, line); matched {
|
||||
lines[i] = "upload_max_filesize" + " = " + req.UploadMaxSize
|
||||
}
|
||||
}
|
||||
}
|
||||
updatedContent := strings.Join(lines, "\n")
|
||||
if err := fileOp.WriteFile(phpConfigPath, strings.NewReader(updatedContent), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
appInstallReq := request.AppInstalledOperate{
|
||||
InstallId: appInstall.ID,
|
||||
Operate: constant.Restart,
|
||||
}
|
||||
if err = NewIAppInstalledService().Operate(appInstallReq); err != nil {
|
||||
_ = fileOp.WriteFile(phpConfigPath, strings.NewReader(string(contentBytes)), 0755)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w WebsiteService) UpdatePHPConfigFile(req request.WebsitePHPFileUpdate) error {
|
||||
website, err := websiteRepo.GetFirst(commonRepo.WithByID(req.ID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if website.Type != constant.Runtime {
|
||||
return nil
|
||||
}
|
||||
runtime, err := runtimeRepo.GetFirst(commonRepo.WithByID(website.RuntimeID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if runtime.Resource != constant.ResourceAppstore {
|
||||
return nil
|
||||
}
|
||||
runtimeInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
configPath := ""
|
||||
if req.Type == constant.ConfigFPM {
|
||||
configPath = path.Join(runtimeInstall.GetPath(), "conf", "php-fpm.conf")
|
||||
} else {
|
||||
configPath = path.Join(runtimeInstall.GetPath(), "conf", "php.ini")
|
||||
}
|
||||
if err := files.NewFileOp().WriteFile(configPath, strings.NewReader(req.Content), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := compose.Restart(runtimeInstall.GetComposePath()); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w WebsiteService) ChangePHPVersion(req request.WebsitePHPVersionReq) error {
|
||||
website, err := websiteRepo.GetFirst(commonRepo.WithByID(req.WebsiteID))
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,11 @@ func (r *RuntimeRouter) InitRouter(Router *gin.RouterGroup) {
|
|||
groupRouter.GET("/php/:id/extensions", baseApi.GetRuntimeExtension)
|
||||
groupRouter.POST("/php/extensions/install", baseApi.InstallPHPExtension)
|
||||
groupRouter.POST("/php/extensions/uninstall", baseApi.UnInstallPHPExtension)
|
||||
|
||||
groupRouter.GET("/php/config/:id", baseApi.GetPHPConfig)
|
||||
groupRouter.POST("/php/config", baseApi.UpdatePHPConfig)
|
||||
groupRouter.POST("/php/update", baseApi.UpdatePHPFile)
|
||||
groupRouter.POST("/php/file", baseApi.GetPHPConfigFile)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,11 +39,6 @@ func (a *WebsiteRouter) InitRouter(Router *gin.RouterGroup) {
|
|||
websiteRouter.GET("/:id/https", baseApi.GetHTTPSConfig)
|
||||
websiteRouter.POST("/:id/https", baseApi.UpdateHTTPSConfig)
|
||||
|
||||
websiteRouter.GET("/php/config/:id", baseApi.GetWebsitePHPConfig)
|
||||
websiteRouter.POST("/php/config", baseApi.UpdateWebsitePHPConfig)
|
||||
websiteRouter.POST("/php/update", baseApi.UpdatePHPFile)
|
||||
websiteRouter.POST("/php/version", baseApi.ChangePHPVersion)
|
||||
|
||||
websiteRouter.POST("/rewrite", baseApi.GetRewriteConfig)
|
||||
websiteRouter.POST("/rewrite/update", baseApi.UpdateRewriteConfig)
|
||||
|
||||
|
|
|
|||
|
|
@ -141,4 +141,29 @@ export namespace Runtime {
|
|||
id: number;
|
||||
taskID?: string;
|
||||
}
|
||||
|
||||
export interface PHPConfig {
|
||||
params: any;
|
||||
disableFunctions: string[];
|
||||
uploadMaxSize: string;
|
||||
}
|
||||
|
||||
export interface PHPConfigUpdate {
|
||||
id: number;
|
||||
params?: any;
|
||||
disableFunctions?: string[];
|
||||
scope: string;
|
||||
uploadMaxSize?: string;
|
||||
}
|
||||
|
||||
export interface PHPUpdate {
|
||||
id: number;
|
||||
content: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface PHPFileReq {
|
||||
id: number;
|
||||
type: string;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -331,27 +331,6 @@ export namespace Website {
|
|||
export interface DefaultServerUpdate {
|
||||
id: number;
|
||||
}
|
||||
|
||||
export interface PHPConfig {
|
||||
params: any;
|
||||
disableFunctions: string[];
|
||||
uploadMaxSize: string;
|
||||
}
|
||||
|
||||
export interface PHPConfigUpdate {
|
||||
id: number;
|
||||
params?: any;
|
||||
disableFunctions?: string[];
|
||||
scope: string;
|
||||
uploadMaxSize?: string;
|
||||
}
|
||||
|
||||
export interface PHPUpdate {
|
||||
id: number;
|
||||
content: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface RewriteReq {
|
||||
websiteID: number;
|
||||
name: string;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { ResPage, ReqPage } from '../interface';
|
|||
import { Runtime } from '../interface/runtime';
|
||||
import { TimeoutEnum } from '@/enums/http-enum';
|
||||
import { App } from '@/api/interface/app';
|
||||
import { File } from '../interface/file';
|
||||
|
||||
export const SearchRuntimes = (req: Runtime.RuntimeReq) => {
|
||||
return http.post<ResPage<Runtime.RuntimeDTO>>(`/runtimes/search`, req);
|
||||
|
|
@ -79,3 +80,19 @@ export const InstallPHPExtension = (req: Runtime.PHPExtensionInstall) => {
|
|||
export const UnInstallPHPExtension = (req: Runtime.PHPExtensionInstall) => {
|
||||
return http.post(`/runtimes/php/extensions/uninstall`, req);
|
||||
};
|
||||
|
||||
export const GetPHPConfig = (id: number) => {
|
||||
return http.get<Runtime.PHPConfig>(`/runtimes/php/config/${id}`);
|
||||
};
|
||||
|
||||
export const UpdatePHPConfig = (req: Runtime.PHPConfigUpdate) => {
|
||||
return http.post<any>(`/runtimes/php/config/`, req);
|
||||
};
|
||||
|
||||
export const UpdatePHPFile = (req: Runtime.PHPUpdate) => {
|
||||
return http.post<any>(`/runtimes/php/update`, req);
|
||||
};
|
||||
|
||||
export const GetPHPConfigFile = (req: Runtime.PHPFileReq) => {
|
||||
return http.post<File.File>(`/runtimes/php/file`, req);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -162,18 +162,6 @@ export const ChangeDefaultServer = (req: Website.DefaultServerUpdate) => {
|
|||
return http.post<any>(`/websites/default/server`, req);
|
||||
};
|
||||
|
||||
export const GetPHPConfig = (id: number) => {
|
||||
return http.get<Website.PHPConfig>(`/websites/php/config/${id}`);
|
||||
};
|
||||
|
||||
export const UpdatePHPConfig = (req: Website.PHPConfigUpdate) => {
|
||||
return http.post<any>(`/websites/php/config/`, req);
|
||||
};
|
||||
|
||||
export const UpdatePHPFile = (req: Website.PHPUpdate) => {
|
||||
return http.post<any>(`/websites/php/update`, req);
|
||||
};
|
||||
|
||||
export const GetRewriteConfig = (req: Website.RewriteReq) => {
|
||||
return http.post<Website.RewriteRes>(`/websites/rewrite`, req);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2440,6 +2440,9 @@ const message = {
|
|||
installExtension: 'Do you confirm to install the extension {0}',
|
||||
loadedExtension: 'Loaded Extension',
|
||||
popularExtension: 'Popular Extension',
|
||||
uninstallExtension: 'Are you sure you want to uninstall the extension {0}',
|
||||
phpConfigHelper:
|
||||
'Modifying the configuration requires restarting the operating environment, do you want to continue',
|
||||
},
|
||||
process: {
|
||||
pid: 'Process ID',
|
||||
|
|
|
|||
|
|
@ -2264,6 +2264,8 @@ const message = {
|
|||
installExtension: '是否確認安裝擴充功能 {0}',
|
||||
loadedExtension: '已載入擴充功能',
|
||||
popularExtension: '常用擴充',
|
||||
uninstallExtension: '是否確認卸載擴充功能 {0}',
|
||||
phpConfigHelper: '修改配置需要重新啟動運行環境,是否繼續',
|
||||
},
|
||||
process: {
|
||||
pid: '進程ID',
|
||||
|
|
|
|||
|
|
@ -2267,6 +2267,7 @@ const message = {
|
|||
loadedExtension: '已加载扩展',
|
||||
popularExtension: '常用扩展',
|
||||
uninstallExtension: '是否确认卸载扩展 {0}',
|
||||
phpConfigHelper: '修改配置需要重启运行环境,是否继续',
|
||||
},
|
||||
process: {
|
||||
pid: '进程ID',
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ const webSiteRouter = {
|
|||
},
|
||||
{
|
||||
path: '/websites/runtimes/node',
|
||||
name: 'Node',
|
||||
name: 'node',
|
||||
hidden: true,
|
||||
component: () => import('@/views/website/runtime/node/index.vue'),
|
||||
meta: {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
<div v-loading="loading">
|
||||
<el-form :model="form" :rules="variablesRules" ref="phpFormRef" label-position="top">
|
||||
<el-row v-loading="loading">
|
||||
<el-col :span="1"><br /></el-col>
|
||||
<el-col :span="9">
|
||||
<el-col :span="11" :offset="1">
|
||||
<el-form-item label="short_open_tag" prop="short_open_tag">
|
||||
<el-select v-model="form.short_open_tag">
|
||||
<el-option :label="$t('website.isOff')" :value="'Off'"></el-option>
|
||||
|
|
@ -48,7 +47,7 @@
|
|||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="1"><br /></el-col>
|
||||
<el-col :span="9">
|
||||
<el-col :span="11">
|
||||
<el-form-item label="default_socket_timeout" prop="default_socket_timeout">
|
||||
<el-input clearable v-model.number="form.default_socket_timeout" maxlength="15">
|
||||
<template #append>{{ $t('commons.units.second') }}</template>
|
||||
|
|
@ -81,18 +80,16 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<ConfirmDialog ref="confirmDialogRef" @confirm="submit"></ConfirmDialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { GetPHPConfig, UpdatePHPConfig } from '@/api/modules/website';
|
||||
import { GetPHPConfig, UpdatePHPConfig } from '@/api/modules/runtime';
|
||||
import { checkNumberRange, Rules } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { computed, onMounted, reactive, ref } from 'vue';
|
||||
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
|
|
@ -106,7 +103,6 @@ const id = computed(() => {
|
|||
});
|
||||
const loading = ref(false);
|
||||
const phpFormRef = ref();
|
||||
const confirmDialogRef = ref();
|
||||
let form = reactive({
|
||||
short_open_tag: 'Off',
|
||||
max_execution_time: 50,
|
||||
|
|
@ -160,12 +156,19 @@ const onSaveStart = async (formEl: FormInstance | undefined) => {
|
|||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
let params = {
|
||||
header: i18n.global.t('database.confChange'),
|
||||
operationInfo: i18n.global.t('database.restartNowHelper'),
|
||||
submitInputInfo: i18n.global.t('database.restartNow'),
|
||||
};
|
||||
confirmDialogRef.value!.acceptParams(params);
|
||||
const action = await ElMessageBox.confirm(
|
||||
i18n.global.t('runtime.phpConfigHelper'),
|
||||
i18n.global.t('database.confChange'),
|
||||
{
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
type: 'info',
|
||||
},
|
||||
);
|
||||
if (action === 'confirm') {
|
||||
loading.value = true;
|
||||
submit();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -1,39 +1,36 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :xs="20" :sm="12" :md="10" :lg="10" :xl="8" :offset="1">
|
||||
<el-form :model="form" :rules="rules" ref="formRef">
|
||||
<el-form-item prop="funcs">
|
||||
<el-input
|
||||
type="text"
|
||||
v-model="form.funcs"
|
||||
label="value"
|
||||
:placeholder="$t('php.disableFunctionHelper')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<ComplexTable :data="data" v-loading="loading">
|
||||
<template #toolbar>
|
||||
<el-button type="primary" icon="Plus" @click="openCreate(formRef)">
|
||||
{{ $t('commons.button.add') }}
|
||||
<el-row>
|
||||
<el-col :span="22" :offset="1">
|
||||
<el-form :model="form" :rules="rules" ref="formRef">
|
||||
<el-form-item prop="funcs">
|
||||
<el-input
|
||||
type="text"
|
||||
v-model="form.funcs"
|
||||
label="value"
|
||||
:placeholder="$t('php.disableFunctionHelper')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<ComplexTable :data="data" v-loading="loading">
|
||||
<template #toolbar>
|
||||
<el-button type="primary" icon="Plus" @click="openCreate(formRef)">
|
||||
{{ $t('commons.button.add') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<el-table-column :label="$t('commons.table.name')" prop="func"></el-table-column>
|
||||
<el-table-column :label="$t('commons.table.operate')">
|
||||
<template #default="{ $index }">
|
||||
<el-button link type="primary" @click="remove($index)">
|
||||
{{ $t('commons.button.delete') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<el-table-column :label="$t('commons.table.name')" prop="func"></el-table-column>
|
||||
<el-table-column :label="$t('commons.table.operate')">
|
||||
<template #default="{ $index }">
|
||||
<el-button link type="primary" @click="remove($index)">
|
||||
{{ $t('commons.button.delete') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ComplexTable>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<ConfirmDialog ref="confirmDialogRef" @confirm="submit(false, [''])"></ConfirmDialog>
|
||||
</div>
|
||||
</el-table-column>
|
||||
</ComplexTable>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { GetPHPConfig, UpdatePHPConfig } from '@/api/modules/website';
|
||||
import { GetPHPConfig, UpdatePHPConfig } from '@/api/modules/runtime';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
|
|
@ -61,7 +58,6 @@ const form = ref({
|
|||
funcs: '',
|
||||
});
|
||||
const data = ref([]);
|
||||
const confirmDialogRef = ref();
|
||||
|
||||
const search = () => {
|
||||
loading.value = true;
|
||||
|
|
@ -85,12 +81,19 @@ const openCreate = async (formEl: FormInstance | undefined) => {
|
|||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
let params = {
|
||||
header: i18n.global.t('database.confChange'),
|
||||
operationInfo: i18n.global.t('database.restartNowHelper'),
|
||||
submitInputInfo: i18n.global.t('database.restartNow'),
|
||||
};
|
||||
confirmDialogRef.value!.acceptParams(params);
|
||||
const action = await ElMessageBox.confirm(
|
||||
i18n.global.t('database.restartNowHelper'),
|
||||
i18n.global.t('database.confChange'),
|
||||
{
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
type: 'info',
|
||||
},
|
||||
);
|
||||
if (action === 'confirm') {
|
||||
loading.value = true;
|
||||
submit(false, ['']);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
54
frontend/src/views/website/runtime/php/config/index.vue
Normal file
54
frontend/src/views/website/runtime/php/config/index.vue
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<template>
|
||||
<DrawerPro v-model="open" :header="$t('runtime.runtime')" size="large" :resource="runtime.name" :back="handleClose">
|
||||
<template #content>
|
||||
<el-tabs tab-position="left" v-model="index">
|
||||
<el-tab-pane :label="$t('website.updateConfig')" name="0">
|
||||
<Config :id="runtime.id" v-if="index == '0'"></Config>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('php.disableFunction')" name="1">
|
||||
<Function :id="runtime.id" v-if="index == '1'"></Function>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('php.uploadMaxSize')" name="2">
|
||||
<Upload :id="runtime.id" v-if="index == '2'"></Upload>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'php-fpm'" name="3">
|
||||
<PHP :id="runtime.id" v-if="index == '3'" :type="'fpm'"></PHP>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'php'" name="4">
|
||||
<PHP :id="runtime.id" v-if="index == '4'" :type="'php'"></PHP>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
</DrawerPro>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import Config from './config/index.vue';
|
||||
import Function from './function/index.vue';
|
||||
import Upload from './upload/index.vue';
|
||||
import { Runtime } from '@/api/interface/runtime';
|
||||
import PHP from './php-fpm/index.vue';
|
||||
|
||||
const index = ref('0');
|
||||
const open = ref(false);
|
||||
const runtime = ref({
|
||||
name: '',
|
||||
id: 0,
|
||||
});
|
||||
|
||||
const handleClose = () => {
|
||||
open.value = false;
|
||||
};
|
||||
|
||||
const acceptParams = async (req: Runtime.Runtime) => {
|
||||
runtime.value = req;
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
onMounted(() => {});
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
|
|
@ -4,16 +4,14 @@
|
|||
<el-button type="primary" @click="openUpdate()" class="mt-2.5">
|
||||
{{ $t('nginx.saveAndReload') }}
|
||||
</el-button>
|
||||
<ConfirmDialog ref="confirmDialogRef" @confirm="submit()"></ConfirmDialog>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { GetWebsiteConfig, UpdatePHPFile } from '@/api/modules/website';
|
||||
import { GetPHPConfigFile, UpdatePHPFile } from '@/api/modules/runtime';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { File } from '@/api/interface/file';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
|
|
@ -24,10 +22,6 @@ const props = defineProps({
|
|||
type: String,
|
||||
default: 'fpm',
|
||||
},
|
||||
installId: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const id = computed(() => {
|
||||
|
|
@ -37,11 +31,10 @@ const id = computed(() => {
|
|||
const data = ref<File.File>();
|
||||
const loading = ref(false);
|
||||
const content = ref('');
|
||||
const confirmDialogRef = ref();
|
||||
|
||||
const get = () => {
|
||||
loading.value = true;
|
||||
GetWebsiteConfig(id.value, props.type)
|
||||
GetPHPConfigFile({ id: id.value, type: props.type })
|
||||
.then((res) => {
|
||||
data.value = res.data;
|
||||
content.value = data.value.content;
|
||||
|
|
@ -52,11 +45,19 @@ const get = () => {
|
|||
};
|
||||
|
||||
const openUpdate = async () => {
|
||||
confirmDialogRef.value!.acceptParams({
|
||||
header: i18n.global.t('database.confChange'),
|
||||
operationInfo: i18n.global.t('database.restartNowHelper'),
|
||||
submitInputInfo: i18n.global.t('database.restartNow'),
|
||||
});
|
||||
const action = await ElMessageBox.confirm(
|
||||
i18n.global.t('database.restartNowHelper'),
|
||||
i18n.global.t('database.confChange'),
|
||||
{
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
type: 'info',
|
||||
},
|
||||
);
|
||||
if (action === 'confirm') {
|
||||
loading.value = true;
|
||||
submit();
|
||||
}
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
|
|
@ -14,14 +14,12 @@
|
|||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<ConfirmDialog ref="confirmDialogRef" @confirm="submit"></ConfirmDialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { GetPHPConfig, UpdatePHPConfig } from '@/api/modules/website';
|
||||
import { GetPHPConfig, UpdatePHPConfig } from '@/api/modules/runtime';
|
||||
import { Rules, checkNumberRange } from '@/global/form-rules';
|
||||
import { computed, onMounted, reactive } from 'vue';
|
||||
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
||||
import { ref } from 'vue';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import i18n from '@/lang';
|
||||
|
|
@ -40,7 +38,6 @@ const rules = reactive({
|
|||
uploadSize: [Rules.requiredInput, checkNumberRange(0, 999999999)],
|
||||
});
|
||||
const phpFormRef = ref();
|
||||
const confirmDialogRef = ref();
|
||||
const loading = ref(false);
|
||||
const form = ref({
|
||||
uploadSize: 0,
|
||||
|
|
@ -61,12 +58,19 @@ const openCreate = async (formEl: FormInstance | undefined) => {
|
|||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
let params = {
|
||||
header: i18n.global.t('database.confChange'),
|
||||
operationInfo: i18n.global.t('database.restartNowHelper'),
|
||||
submitInputInfo: i18n.global.t('database.restartNow'),
|
||||
};
|
||||
confirmDialogRef.value!.acceptParams(params);
|
||||
const action = await ElMessageBox.confirm(
|
||||
i18n.global.t('database.restartNowHelper'),
|
||||
i18n.global.t('database.confChange'),
|
||||
{
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
type: 'info',
|
||||
},
|
||||
);
|
||||
if (action === 'confirm') {
|
||||
loading.value = true;
|
||||
submit();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -93,7 +93,7 @@
|
|||
fix
|
||||
/>
|
||||
<fu-table-operations
|
||||
:ellipsis="10"
|
||||
:ellipsis="5"
|
||||
width="300px"
|
||||
:buttons="buttons"
|
||||
:label="$t('commons.table.operate')"
|
||||
|
|
@ -111,6 +111,7 @@
|
|||
<AppResources ref="checkRef" @close="search" />
|
||||
<ExtManagement ref="extManagementRef" @close="search" />
|
||||
<ComposeLogs ref="composeLogRef" />
|
||||
<Config ref="configRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -131,6 +132,7 @@ import Status from '@/components/status/index.vue';
|
|||
import RouterMenu from '../index.vue';
|
||||
import Log from '@/components/log-dialog/index.vue';
|
||||
import ComposeLogs from '@/components/compose-log/index.vue';
|
||||
import Config from '@/views/website/runtime/php/config/index.vue';
|
||||
|
||||
const paginationConfig = reactive({
|
||||
cacheSizeKey: 'runtime-page-size',
|
||||
|
|
@ -154,6 +156,7 @@ const createRef = ref();
|
|||
const loading = ref(false);
|
||||
const items = ref<Runtime.RuntimeDTO[]>([]);
|
||||
const composeLogRef = ref();
|
||||
const configRef = ref();
|
||||
|
||||
const buttons = [
|
||||
{
|
||||
|
|
@ -171,7 +174,7 @@ const buttons = [
|
|||
operateRuntime('down', row.id);
|
||||
},
|
||||
disabled: function (row: Runtime.Runtime) {
|
||||
return row.status === 'recreating' || row.status === 'stopped';
|
||||
return row.status === 'recreating' || row.status === 'stopped' || row.status === 'building';
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -180,7 +183,12 @@ const buttons = [
|
|||
operateRuntime('up', row.id);
|
||||
},
|
||||
disabled: function (row: Runtime.Runtime) {
|
||||
return row.status === 'starting' || row.status === 'recreating' || row.status === 'running';
|
||||
return (
|
||||
row.status === 'starting' ||
|
||||
row.status === 'recreating' ||
|
||||
row.status === 'running' ||
|
||||
row.status === 'building'
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -189,7 +197,7 @@ const buttons = [
|
|||
operateRuntime('restart', row.id);
|
||||
},
|
||||
disabled: function (row: Runtime.Runtime) {
|
||||
return row.status === 'recreating';
|
||||
return row.status === 'recreating' || row.status === 'building';
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -201,6 +209,15 @@ const buttons = [
|
|||
return row.status === 'building';
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('menu.config'),
|
||||
click: function (row: Runtime.Runtime) {
|
||||
openConfig(row);
|
||||
},
|
||||
disabled: function (row: Runtime.Runtime) {
|
||||
return row.status === 'building';
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('commons.button.delete'),
|
||||
disabled: function (row: Runtime.Runtime) {
|
||||
|
|
@ -234,6 +251,10 @@ const openDetail = (row: Runtime.Runtime) => {
|
|||
createRef.value.acceptParams({ type: row.type, mode: 'edit', id: row.id, appID: row.appID });
|
||||
};
|
||||
|
||||
const openConfig = (row: Runtime.Runtime) => {
|
||||
configRef.value.acceptParams(row);
|
||||
};
|
||||
|
||||
const openLog = (row: Runtime.RuntimeDTO) => {
|
||||
if (row.status == 'running') {
|
||||
composeLogRef.value.acceptParams({ compose: row.path + '/docker-compose.yml', resource: row.name });
|
||||
|
|
|
|||
|
|
@ -1,58 +0,0 @@
|
|||
<template>
|
||||
<el-tabs tab-position="left" v-model="index">
|
||||
<el-tab-pane :label="$t('website.updateConfig')" name="0">
|
||||
<Config :id="id" v-if="index == '0'"></Config>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('php.disableFunction')" name="1">
|
||||
<Function :id="id" v-if="index == '1'"></Function>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('php.uploadMaxSize')" name="2">
|
||||
<Upload :id="id" v-if="index == '2'"></Upload>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('runtime.version')" name="3">
|
||||
<Version :id="id" :runtimeID="runtimeID" v-if="index == '3'"></Version>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { GetRuntime } from '@/api/modules/runtime';
|
||||
import { GetWebsite } from '@/api/modules/website';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import Config from './config/index.vue';
|
||||
import Function from './function/index.vue';
|
||||
import Upload from './upload/index.vue';
|
||||
import Version from './version/index.vue';
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const id = computed(() => {
|
||||
return props.id;
|
||||
});
|
||||
|
||||
const index = ref('0');
|
||||
const configPHP = ref(false);
|
||||
const installId = ref(0);
|
||||
const runtimeID = ref(0);
|
||||
|
||||
const getWebsiteDetail = async () => {
|
||||
const res = await GetWebsite(props.id);
|
||||
if (res.data.type === 'runtime') {
|
||||
runtimeID.value = res.data.runtimeID;
|
||||
installId.value = res.data.appInstallId;
|
||||
const runRes = await GetRuntime(res.data.runtimeID);
|
||||
if (runRes.data.resource === 'appstore') {
|
||||
configPHP.value = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getWebsiteDetail();
|
||||
});
|
||||
</script>
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-row>
|
||||
<el-col :xs="20" :sm="12" :md="10" :lg="10" :xl="8" :offset="1">
|
||||
<el-form>
|
||||
<el-form-item :label="$t('runtime.version')">
|
||||
<el-select v-model="versionReq.runtimeID" style="width: 100%">
|
||||
<el-option
|
||||
v-for="(item, index) in versions"
|
||||
:key="index"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="versionReq.retainConfig" :label="'保留PHP配置文件'" />
|
||||
<span class="input-help">
|
||||
{{ $t('website.retainConfig') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button type="primary" @click="submit()" :disabled="versionReq.runtimeID === oldRuntimeID">
|
||||
{{ $t('commons.button.save') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SearchRuntimes } from '@/api/modules/runtime';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { Runtime } from '@/api/interface/runtime';
|
||||
import { Website } from '@/api/interface/website';
|
||||
import { ChangePHPVersion } from '@/api/modules/website';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
runtimeID: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const runtimeReq = reactive<Runtime.RuntimeReq>({ page: 1, pageSize: 200, type: 'php' });
|
||||
const versionReq = reactive<Website.PHPVersionChange>({
|
||||
websiteID: undefined,
|
||||
runtimeID: undefined,
|
||||
retainConfig: true,
|
||||
});
|
||||
const versions = ref([]);
|
||||
const loading = ref(false);
|
||||
const oldRuntimeID = ref(0);
|
||||
|
||||
const getRuntimes = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
const res = await SearchRuntimes(runtimeReq);
|
||||
const items = res.data.items || [];
|
||||
for (const item of items) {
|
||||
versions.value.push({
|
||||
value: item.id,
|
||||
label:
|
||||
item.name +
|
||||
'(' +
|
||||
i18n.global.t('runtime.version') +
|
||||
':' +
|
||||
item.version +
|
||||
+' ' +
|
||||
i18n.global.t('runtime.image') +
|
||||
':' +
|
||||
item.image +
|
||||
')',
|
||||
});
|
||||
}
|
||||
} catch (error) {}
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
try {
|
||||
ElMessageBox.confirm(i18n.global.t('website.changePHPVersionWarn'), i18n.global.t('website.changeVersion'), {
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
}).then(async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
await ChangePHPVersion(versionReq);
|
||||
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
||||
} catch (error) {}
|
||||
loading.value = false;
|
||||
});
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
versionReq.runtimeID = props.runtimeID;
|
||||
versionReq.websiteID = props.id;
|
||||
oldRuntimeID.value = props.runtimeID;
|
||||
getRuntimes();
|
||||
});
|
||||
</script>
|
||||
|
|
@ -3,12 +3,7 @@
|
|||
<el-tab-pane :label="'OpenResty'" name="0">
|
||||
<Nginx :id="id" v-if="index == '0'"></Nginx>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'FPM'" name="1" v-if="configPHP">
|
||||
<PHP :id="id" v-if="index == '1'" :installId="installId" :type="'fpm'"></PHP>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'PHP'" name="2" v-if="configPHP">
|
||||
<PHP :id="id" v-if="index == '2'" :installId="installId" :type="'php'"></PHP>
|
||||
</el-tab-pane>
|
||||
|
||||
</el-tabs>
|
||||
</template>
|
||||
|
||||
|
|
@ -17,7 +12,7 @@ import { GetRuntime } from '@/api/modules/runtime';
|
|||
import { GetWebsite } from '@/api/modules/website';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import Nginx from './nginx/index.vue';
|
||||
import PHP from './php-fpm/index.vue';
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue