mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 14:08:06 +08:00
feat: PHP 运行环境增加扩展模版 (#3502)
Refs https://github.com/1Panel-dev/1Panel/issues/1636
This commit is contained in:
parent
a8e10d0d71
commit
b8a89d86a0
@ -21,10 +21,10 @@ var (
|
|||||||
imageService = service.NewIImageService()
|
imageService = service.NewIImageService()
|
||||||
dockerService = service.NewIDockerService()
|
dockerService = service.NewIDockerService()
|
||||||
|
|
||||||
mysqlService = service.NewIMysqlService()
|
mysqlService = service.NewIMysqlService()
|
||||||
postgresqlService = service.NewIPostgresqlService()
|
postgresqlService = service.NewIPostgresqlService()
|
||||||
databaseService = service.NewIDatabaseService()
|
databaseService = service.NewIDatabaseService()
|
||||||
redisService = service.NewIRedisService()
|
redisService = service.NewIRedisService()
|
||||||
|
|
||||||
cronjobService = service.NewICronjobService()
|
cronjobService = service.NewICronjobService()
|
||||||
|
|
||||||
@ -53,8 +53,9 @@ var (
|
|||||||
snapshotService = service.NewISnapshotService()
|
snapshotService = service.NewISnapshotService()
|
||||||
upgradeService = service.NewIUpgradeService()
|
upgradeService = service.NewIUpgradeService()
|
||||||
|
|
||||||
runtimeService = service.NewRuntimeService()
|
runtimeService = service.NewRuntimeService()
|
||||||
processService = service.NewIProcessService()
|
processService = service.NewIProcessService()
|
||||||
|
phpExtensionsService = service.NewIPHPExtensionsService()
|
||||||
|
|
||||||
hostToolService = service.NewIHostToolService()
|
hostToolService = service.NewIHostToolService()
|
||||||
|
|
||||||
|
103
backend/app/api/v1/php_extensions.go
Normal file
103
backend/app/api/v1/php_extensions.go
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @Tags PHP Extensions
|
||||||
|
// @Summary Page Extensions
|
||||||
|
// @Description Page Extensions
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.PHPExtensionsSearch true "request"
|
||||||
|
// @Success 200 {array} response.PHPExtensionsDTO
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /runtimes/php/extensions/search [post]
|
||||||
|
func (b *BaseApi) PagePHPExtensions(c *gin.Context) {
|
||||||
|
var req request.PHPExtensionsSearch
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req.All {
|
||||||
|
list, err := phpExtensionsService.List()
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, list)
|
||||||
|
} else {
|
||||||
|
total, list, err := phpExtensionsService.Page(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, dto.PageResult{
|
||||||
|
Total: total,
|
||||||
|
Items: list,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags PHP Extensions
|
||||||
|
// @Summary Create Extensions
|
||||||
|
// @Description Create Extensions
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.PHPExtensionsCreate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /runtimes/php/extensions [post]
|
||||||
|
func (b *BaseApi) CreatePHPExtensions(c *gin.Context) {
|
||||||
|
var req request.PHPExtensionsCreate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := phpExtensionsService.Create(req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithOutData(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags PHP Extensions
|
||||||
|
// @Summary Update Extensions
|
||||||
|
// @Description Update Extensions
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.PHPExtensionsUpdate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /runtimes/php/extensions/update [post]
|
||||||
|
func (b *BaseApi) UpdatePHPExtensions(c *gin.Context) {
|
||||||
|
var req request.PHPExtensionsUpdate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := phpExtensionsService.Update(req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithOutData(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags PHP Extensions
|
||||||
|
// @Summary Delete Extensions
|
||||||
|
// @Description Delete Extensions
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.PHPExtensionsDelete true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /runtimes/php/extensions/del [post]
|
||||||
|
func (b *BaseApi) DeletePHPExtensions(c *gin.Context) {
|
||||||
|
var req request.PHPExtensionsDelete
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := phpExtensionsService.Delete(req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithOutData(c)
|
||||||
|
}
|
22
backend/app/dto/request/php_extensions.go
Normal file
22
backend/app/dto/request/php_extensions.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package request
|
||||||
|
|
||||||
|
import "github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
|
|
||||||
|
type PHPExtensionsSearch struct {
|
||||||
|
dto.PageInfo
|
||||||
|
All bool `json:"all"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PHPExtensionsCreate struct {
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
Extensions string `json:"extensions" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PHPExtensionsUpdate struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
Extensions string `json:"extensions" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PHPExtensionsDelete struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
}
|
7
backend/app/dto/response/php_extensions.go
Normal file
7
backend/app/dto/response/php_extensions.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package response
|
||||||
|
|
||||||
|
import "github.com/1Panel-dev/1Panel/backend/app/model"
|
||||||
|
|
||||||
|
type PHPExtensionsDTO struct {
|
||||||
|
model.PHPExtensions
|
||||||
|
}
|
7
backend/app/model/php_extensions.go
Normal file
7
backend/app/model/php_extensions.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type PHPExtensions struct {
|
||||||
|
BaseModel
|
||||||
|
Name string ` json:"name" gorm:"not null"`
|
||||||
|
Extensions string `json:"extensions" gorm:"not null"`
|
||||||
|
}
|
59
backend/app/repo/php_extensions.go
Normal file
59
backend/app/repo/php_extensions.go
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PHPExtensionsRepo struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type IPHPExtensionsRepo interface {
|
||||||
|
Page(page, size int, opts ...DBOption) (int64, []model.PHPExtensions, error)
|
||||||
|
Save(extension *model.PHPExtensions) error
|
||||||
|
Create(extension *model.PHPExtensions) error
|
||||||
|
GetFirst(opts ...DBOption) (model.PHPExtensions, error)
|
||||||
|
DeleteBy(opts ...DBOption) error
|
||||||
|
List() ([]model.PHPExtensions, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewIPHPExtensionsRepo() IPHPExtensionsRepo {
|
||||||
|
return &PHPExtensionsRepo{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PHPExtensionsRepo) Page(page, size int, opts ...DBOption) (int64, []model.PHPExtensions, error) {
|
||||||
|
var (
|
||||||
|
phpExtensions []model.PHPExtensions
|
||||||
|
)
|
||||||
|
db := getDb(opts...).Model(&model.PHPExtensions{})
|
||||||
|
count := int64(0)
|
||||||
|
db = db.Count(&count)
|
||||||
|
err := db.Limit(size).Offset(size * (page - 1)).Find(&phpExtensions).Error
|
||||||
|
return count, phpExtensions, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PHPExtensionsRepo) List() ([]model.PHPExtensions, error) {
|
||||||
|
var (
|
||||||
|
phpExtensions []model.PHPExtensions
|
||||||
|
)
|
||||||
|
err := getDb().Model(&model.PHPExtensions{}).Find(&phpExtensions).Error
|
||||||
|
return phpExtensions, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PHPExtensionsRepo) Save(extension *model.PHPExtensions) error {
|
||||||
|
return getDb().Save(&extension).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PHPExtensionsRepo) Create(extension *model.PHPExtensions) error {
|
||||||
|
return getDb().Create(&extension).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PHPExtensionsRepo) GetFirst(opts ...DBOption) (model.PHPExtensions, error) {
|
||||||
|
var extension model.PHPExtensions
|
||||||
|
db := getDb(opts...).Model(&model.PHPExtensions{})
|
||||||
|
err := db.First(&extension).Error
|
||||||
|
return extension, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PHPExtensionsRepo) DeleteBy(opts ...DBOption) error {
|
||||||
|
return getDb(opts...).Delete(&model.PHPExtensions{}).Error
|
||||||
|
}
|
@ -12,9 +12,9 @@ var (
|
|||||||
appInstallRepo = repo.NewIAppInstallRepo()
|
appInstallRepo = repo.NewIAppInstallRepo()
|
||||||
appInstallResourceRepo = repo.NewIAppInstallResourceRpo()
|
appInstallResourceRepo = repo.NewIAppInstallResourceRpo()
|
||||||
|
|
||||||
mysqlRepo = repo.NewIMysqlRepo()
|
mysqlRepo = repo.NewIMysqlRepo()
|
||||||
postgresqlRepo = repo.NewIPostgresqlRepo()
|
postgresqlRepo = repo.NewIPostgresqlRepo()
|
||||||
databaseRepo = repo.NewIDatabaseRepo()
|
databaseRepo = repo.NewIDatabaseRepo()
|
||||||
|
|
||||||
imageRepoRepo = repo.NewIImageRepoRepo()
|
imageRepoRepo = repo.NewIImageRepoRepo()
|
||||||
composeRepo = repo.NewIComposeTemplateRepo()
|
composeRepo = repo.NewIComposeTemplateRepo()
|
||||||
@ -38,7 +38,8 @@ var (
|
|||||||
logRepo = repo.NewILogRepo()
|
logRepo = repo.NewILogRepo()
|
||||||
snapshotRepo = repo.NewISnapshotRepo()
|
snapshotRepo = repo.NewISnapshotRepo()
|
||||||
|
|
||||||
runtimeRepo = repo.NewIRunTimeRepo()
|
runtimeRepo = repo.NewIRunTimeRepo()
|
||||||
|
phpExtensionsRepo = repo.NewIPHPExtensionsRepo()
|
||||||
|
|
||||||
favoriteRepo = repo.NewIFavoriteRepo()
|
favoriteRepo = repo.NewIFavoriteRepo()
|
||||||
)
|
)
|
||||||
|
86
backend/app/service/php_extensions.go
Normal file
86
backend/app/service/php_extensions.go
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/app/dto/response"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PHPExtensionsService struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type IPHPExtensionsService interface {
|
||||||
|
Page(req request.PHPExtensionsSearch) (int64, []response.PHPExtensionsDTO, error)
|
||||||
|
List() ([]response.PHPExtensionsDTO, error)
|
||||||
|
Create(req request.PHPExtensionsCreate) error
|
||||||
|
Update(req request.PHPExtensionsUpdate) error
|
||||||
|
Delete(req request.PHPExtensionsDelete) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewIPHPExtensionsService() IPHPExtensionsService {
|
||||||
|
return &PHPExtensionsService{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p PHPExtensionsService) Page(req request.PHPExtensionsSearch) (int64, []response.PHPExtensionsDTO, error) {
|
||||||
|
var (
|
||||||
|
total int64
|
||||||
|
extensions []model.PHPExtensions
|
||||||
|
err error
|
||||||
|
result []response.PHPExtensionsDTO
|
||||||
|
)
|
||||||
|
total, extensions, err = phpExtensionsRepo.Page(req.Page, req.PageSize)
|
||||||
|
if err != nil {
|
||||||
|
return 0, nil, err
|
||||||
|
}
|
||||||
|
for _, extension := range extensions {
|
||||||
|
result = append(result, response.PHPExtensionsDTO{
|
||||||
|
PHPExtensions: extension,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return total, result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p PHPExtensionsService) List() ([]response.PHPExtensionsDTO, error) {
|
||||||
|
var (
|
||||||
|
extensions []model.PHPExtensions
|
||||||
|
err error
|
||||||
|
result []response.PHPExtensionsDTO
|
||||||
|
)
|
||||||
|
extensions, err = phpExtensionsRepo.List()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, extension := range extensions {
|
||||||
|
result = append(result, response.PHPExtensionsDTO{
|
||||||
|
PHPExtensions: extension,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p PHPExtensionsService) Create(req request.PHPExtensionsCreate) error {
|
||||||
|
exist, _ := phpExtensionsRepo.GetFirst(commonRepo.WithByName(req.Name))
|
||||||
|
if exist.ID == 0 {
|
||||||
|
return buserr.New(constant.ErrNameIsExist)
|
||||||
|
}
|
||||||
|
extension := model.PHPExtensions{
|
||||||
|
Name: req.Name,
|
||||||
|
Extensions: req.Extensions,
|
||||||
|
}
|
||||||
|
return phpExtensionsRepo.Create(&extension)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p PHPExtensionsService) Update(req request.PHPExtensionsUpdate) error {
|
||||||
|
exist, err := phpExtensionsRepo.GetFirst(commonRepo.WithByID(req.ID))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
exist.Extensions = req.Extensions
|
||||||
|
return phpExtensionsRepo.Save(&exist)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p PHPExtensionsService) Delete(req request.PHPExtensionsDelete) error {
|
||||||
|
return phpExtensionsRepo.DeleteBy(commonRepo.WithByID(req.ID))
|
||||||
|
}
|
@ -62,6 +62,8 @@ func Init() {
|
|||||||
migrations.AddDefaultCA,
|
migrations.AddDefaultCA,
|
||||||
migrations.AddSettingRecycleBin,
|
migrations.AddSettingRecycleBin,
|
||||||
migrations.UpdateWebsiteBackupRecord,
|
migrations.UpdateWebsiteBackupRecord,
|
||||||
|
|
||||||
|
migrations.AddTablePHPExtensions,
|
||||||
})
|
})
|
||||||
if err := m.Migrate(); err != nil {
|
if err := m.Migrate(); err != nil {
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
|
@ -103,3 +103,16 @@ var UpdateWebsiteBackupRecord = &gormigrate.Migration{
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var AddTablePHPExtensions = &gormigrate.Migration{
|
||||||
|
ID: "20240102-add-php-extensions",
|
||||||
|
Migrate: func(tx *gorm.DB) error {
|
||||||
|
if err := tx.AutoMigrate(&model.PHPExtensions{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := tx.Create(&model.PHPExtensions{Name: "默认", Extensions: "bcmath,gd,gettext,intl,pcntl,shmop,soap,sockets,sysvsem,xmlrpc,zip"}).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -20,10 +20,16 @@ func (r *RuntimeRouter) InitRouter(Router *gin.RouterGroup) {
|
|||||||
groupRouter.POST("/del", baseApi.DeleteRuntime)
|
groupRouter.POST("/del", baseApi.DeleteRuntime)
|
||||||
groupRouter.POST("/update", baseApi.UpdateRuntime)
|
groupRouter.POST("/update", baseApi.UpdateRuntime)
|
||||||
groupRouter.GET("/:id", baseApi.GetRuntime)
|
groupRouter.GET("/:id", baseApi.GetRuntime)
|
||||||
|
|
||||||
groupRouter.POST("/node/package", baseApi.GetNodePackageRunScript)
|
groupRouter.POST("/node/package", baseApi.GetNodePackageRunScript)
|
||||||
groupRouter.POST("/operate", baseApi.OperateRuntime)
|
groupRouter.POST("/operate", baseApi.OperateRuntime)
|
||||||
groupRouter.POST("/node/modules", baseApi.GetNodeModules)
|
groupRouter.POST("/node/modules", baseApi.GetNodeModules)
|
||||||
groupRouter.POST("/node/modules/operate", baseApi.OperateNodeModules)
|
groupRouter.POST("/node/modules/operate", baseApi.OperateNodeModules)
|
||||||
|
|
||||||
|
groupRouter.POST("/php/extensions/search", baseApi.PagePHPExtensions)
|
||||||
|
groupRouter.POST("/php/extensions", baseApi.CreatePHPExtensions)
|
||||||
|
groupRouter.POST("/php/extensions/update", baseApi.UpdatePHPExtensions)
|
||||||
|
groupRouter.POST("/php/extensions/del", baseApi.DeletePHPExtensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8995,6 +8995,144 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/runtimes/php/extensions": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Create Extensions",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"PHP Extensions"
|
||||||
|
],
|
||||||
|
"summary": "Create Extensions",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.PHPExtensionsCreate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/runtimes/php/extensions/del": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Delete Extensions",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"PHP Extensions"
|
||||||
|
],
|
||||||
|
"summary": "Delete Extensions",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.PHPExtensionsDelete"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/runtimes/php/extensions/search": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Page Extensions",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"PHP Extensions"
|
||||||
|
],
|
||||||
|
"summary": "Page Extensions",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.PHPExtensionsSearch"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/response.PHPExtensionsDTO"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/runtimes/php/extensions/update": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Update Extensions",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"PHP Extensions"
|
||||||
|
],
|
||||||
|
"summary": "Update Extensions",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.PHPExtensionsUpdate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/runtimes/search": {
|
"/runtimes/search": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@ -19390,6 +19528,65 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"request.PHPExtensionsCreate": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"extensions",
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"extensions": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"request.PHPExtensionsDelete": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"request.PHPExtensionsSearch": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"page",
|
||||||
|
"pageSize"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"all": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"page": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"pageSize": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"request.PHPExtensionsUpdate": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"extensions",
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"extensions": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"request.PortUpdate": {
|
"request.PortUpdate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -20915,6 +21112,26 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"response.PHPExtensionsDTO": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"createdAt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"extensions": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"updatedAt": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"response.WebsiteAcmeAccountDTO": {
|
"response.WebsiteAcmeAccountDTO": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -8988,6 +8988,144 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/runtimes/php/extensions": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Create Extensions",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"PHP Extensions"
|
||||||
|
],
|
||||||
|
"summary": "Create Extensions",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.PHPExtensionsCreate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/runtimes/php/extensions/del": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Delete Extensions",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"PHP Extensions"
|
||||||
|
],
|
||||||
|
"summary": "Delete Extensions",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.PHPExtensionsDelete"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/runtimes/php/extensions/search": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Page Extensions",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"PHP Extensions"
|
||||||
|
],
|
||||||
|
"summary": "Page Extensions",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.PHPExtensionsSearch"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/response.PHPExtensionsDTO"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/runtimes/php/extensions/update": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Update Extensions",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"PHP Extensions"
|
||||||
|
],
|
||||||
|
"summary": "Update Extensions",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.PHPExtensionsUpdate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/runtimes/search": {
|
"/runtimes/search": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@ -19383,6 +19521,65 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"request.PHPExtensionsCreate": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"extensions",
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"extensions": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"request.PHPExtensionsDelete": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"request.PHPExtensionsSearch": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"page",
|
||||||
|
"pageSize"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"all": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"page": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"pageSize": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"request.PHPExtensionsUpdate": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"extensions",
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"extensions": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"request.PortUpdate": {
|
"request.PortUpdate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -20908,6 +21105,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"response.PHPExtensionsDTO": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"createdAt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"extensions": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"updatedAt": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"response.WebsiteAcmeAccountDTO": {
|
"response.WebsiteAcmeAccountDTO": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -3706,6 +3706,45 @@ definitions:
|
|||||||
codeDir:
|
codeDir:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
|
request.PHPExtensionsCreate:
|
||||||
|
properties:
|
||||||
|
extensions:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- extensions
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
|
request.PHPExtensionsDelete:
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
type: object
|
||||||
|
request.PHPExtensionsSearch:
|
||||||
|
properties:
|
||||||
|
all:
|
||||||
|
type: boolean
|
||||||
|
page:
|
||||||
|
type: integer
|
||||||
|
pageSize:
|
||||||
|
type: integer
|
||||||
|
required:
|
||||||
|
- page
|
||||||
|
- pageSize
|
||||||
|
type: object
|
||||||
|
request.PHPExtensionsUpdate:
|
||||||
|
properties:
|
||||||
|
extensions:
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
required:
|
||||||
|
- extensions
|
||||||
|
- id
|
||||||
|
type: object
|
||||||
request.PortUpdate:
|
request.PortUpdate:
|
||||||
properties:
|
properties:
|
||||||
key:
|
key:
|
||||||
@ -4732,6 +4771,19 @@ definitions:
|
|||||||
uploadMaxSize:
|
uploadMaxSize:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
|
response.PHPExtensionsDTO:
|
||||||
|
properties:
|
||||||
|
createdAt:
|
||||||
|
type: string
|
||||||
|
extensions:
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
updatedAt:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
response.WebsiteAcmeAccountDTO:
|
response.WebsiteAcmeAccountDTO:
|
||||||
properties:
|
properties:
|
||||||
createdAt:
|
createdAt:
|
||||||
@ -10612,6 +10664,90 @@ paths:
|
|||||||
formatEN: Operate runtime [name]
|
formatEN: Operate runtime [name]
|
||||||
formatZH: 操作运行环境 [name]
|
formatZH: 操作运行环境 [name]
|
||||||
paramKeys: []
|
paramKeys: []
|
||||||
|
/runtimes/php/extensions:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Create Extensions
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/request.PHPExtensionsCreate'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Create Extensions
|
||||||
|
tags:
|
||||||
|
- PHP Extensions
|
||||||
|
/runtimes/php/extensions/del:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Delete Extensions
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/request.PHPExtensionsDelete'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Delete Extensions
|
||||||
|
tags:
|
||||||
|
- PHP Extensions
|
||||||
|
/runtimes/php/extensions/search:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Page Extensions
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/request.PHPExtensionsSearch'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/response.PHPExtensionsDTO'
|
||||||
|
type: array
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Page Extensions
|
||||||
|
tags:
|
||||||
|
- PHP Extensions
|
||||||
|
/runtimes/php/extensions/update:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Update Extensions
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/request.PHPExtensionsUpdate'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Update Extensions
|
||||||
|
tags:
|
||||||
|
- PHP Extensions
|
||||||
/runtimes/search:
|
/runtimes/search:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
|
@ -97,4 +97,29 @@ export namespace Runtime {
|
|||||||
Module?: string;
|
Module?: string;
|
||||||
PkgManager?: string;
|
PkgManager?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PHPExtensions extends CommonModel {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
extensions: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PHPExtensionsList extends ReqPage {
|
||||||
|
all: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PHPExtensionsCreate {
|
||||||
|
name: string;
|
||||||
|
extensions: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PHPExtensionsUpdate {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
extensions: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PHPExtensionsDelete {
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import http from '@/api';
|
import http from '@/api';
|
||||||
import { ResPage } from '../interface';
|
import { ResPage, ReqPage } from '../interface';
|
||||||
import { Runtime } from '../interface/runtime';
|
import { Runtime } from '../interface/runtime';
|
||||||
import { TimeoutEnum } from '@/enums/http-enum';
|
import { TimeoutEnum } from '@/enums/http-enum';
|
||||||
|
|
||||||
@ -38,3 +38,23 @@ export const GetNodeModules = (req: Runtime.NodeModuleReq) => {
|
|||||||
export const OperateNodeModule = (req: Runtime.NodeModuleReq) => {
|
export const OperateNodeModule = (req: Runtime.NodeModuleReq) => {
|
||||||
return http.post<any>(`/runtimes/node/modules/operate`, req, TimeoutEnum.T_10M);
|
return http.post<any>(`/runtimes/node/modules/operate`, req, TimeoutEnum.T_10M);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const SearchPHPExtensions = (req: ReqPage) => {
|
||||||
|
return http.post<ResPage<Runtime.PHPExtensions>>(`/runtimes/php/extensions/search`, req);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ListPHPExtensions = (req: Runtime.PHPExtensionsList) => {
|
||||||
|
return http.post<Runtime.PHPExtensions[]>(`/runtimes/php/extensions/search`, req);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CreatePHPExtensions = (req: Runtime.PHPExtensionsCreate) => {
|
||||||
|
return http.post<any>(`/runtimes/php/extensions`, req);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const UpdatePHPExtensions = (req: Runtime.PHPExtensionsUpdate) => {
|
||||||
|
return http.post<any>(`/runtimes/php/extensions/update`, req);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DeletePHPExtensions = (req: Runtime.PHPExtensionsDelete) => {
|
||||||
|
return http.post<any>(`/runtimes/php/extensions/del`, req);
|
||||||
|
};
|
||||||
|
@ -474,6 +474,19 @@ const checkFilePermission = (rule, value, callback) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const checkPHPExtensions = (rule, value, callback) => {
|
||||||
|
if (value === '' || typeof value === 'undefined' || value == null) {
|
||||||
|
callback(new Error(i18n.global.t('commons.rule.phpExtension')));
|
||||||
|
} else {
|
||||||
|
const reg = /^[a-z0-9,_]{3,300}$/;
|
||||||
|
if (!reg.test(value)) {
|
||||||
|
callback(new Error(i18n.global.t('commons.rule.phpExtension')));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
interface CommonRule {
|
interface CommonRule {
|
||||||
requiredInput: FormItemRule;
|
requiredInput: FormItemRule;
|
||||||
requiredSelect: FormItemRule;
|
requiredSelect: FormItemRule;
|
||||||
@ -507,6 +520,7 @@ interface CommonRule {
|
|||||||
leechExts: FormItemRule;
|
leechExts: FormItemRule;
|
||||||
domainWithPort: FormItemRule;
|
domainWithPort: FormItemRule;
|
||||||
filePermission: FormItemRule;
|
filePermission: FormItemRule;
|
||||||
|
phpExtensions: FormItemRule;
|
||||||
|
|
||||||
paramCommon: FormItemRule;
|
paramCommon: FormItemRule;
|
||||||
paramComplexity: FormItemRule;
|
paramComplexity: FormItemRule;
|
||||||
@ -711,4 +725,9 @@ export const Rules: CommonRule = {
|
|||||||
validator: checkFilePermission,
|
validator: checkFilePermission,
|
||||||
trigger: 'blur',
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
|
phpExtensions: {
|
||||||
|
required: true,
|
||||||
|
validator: checkPHPExtensions,
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
@ -191,6 +191,7 @@ const message = {
|
|||||||
paramSimple: 'Support lowercase letters and numbers, length 1-128',
|
paramSimple: 'Support lowercase letters and numbers, length 1-128',
|
||||||
filePermission: 'File Permission Error',
|
filePermission: 'File Permission Error',
|
||||||
formatErr: 'Format error, please check and retry',
|
formatErr: 'Format error, please check and retry',
|
||||||
|
phpExtension: 'Only supports , _ lowercase English and numbers',
|
||||||
},
|
},
|
||||||
res: {
|
res: {
|
||||||
paramError: 'The request failed, please try again later!',
|
paramError: 'The request failed, please try again later!',
|
||||||
@ -1839,6 +1840,10 @@ const message = {
|
|||||||
uploadMaxSize: 'Upload limit',
|
uploadMaxSize: 'Upload limit',
|
||||||
indexHelper:
|
indexHelper:
|
||||||
'In order to ensure the normal operation of the PHP website, please place the code in the index directory and avoid renaming',
|
'In order to ensure the normal operation of the PHP website, please place the code in the index directory and avoid renaming',
|
||||||
|
extensions: 'Extension template',
|
||||||
|
extension: 'Extension',
|
||||||
|
extensionHelper: 'Please use multiple extensions, split',
|
||||||
|
toExtensionsList: 'View extension list',
|
||||||
},
|
},
|
||||||
nginx: {
|
nginx: {
|
||||||
serverNamesHashBucketSizeHelper: 'The hash table size of the server name',
|
serverNamesHashBucketSizeHelper: 'The hash table size of the server name',
|
||||||
|
@ -190,6 +190,7 @@ const message = {
|
|||||||
paramSimple: '支持小寫字母和數字,長度 1-128',
|
paramSimple: '支持小寫字母和數字,長度 1-128',
|
||||||
filePermission: '權限錯誤',
|
filePermission: '權限錯誤',
|
||||||
formatErr: '格式錯誤,檢查後重試',
|
formatErr: '格式錯誤,檢查後重試',
|
||||||
|
phpExtension: '僅支持 , _ 小寫英文和數字',
|
||||||
},
|
},
|
||||||
res: {
|
res: {
|
||||||
paramError: '請求失敗,請稍後重試!',
|
paramError: '請求失敗,請稍後重試!',
|
||||||
@ -1725,6 +1726,10 @@ const message = {
|
|||||||
disableFunctionHelper: '輸入要禁用的函數,例如exec,多個請用,分割',
|
disableFunctionHelper: '輸入要禁用的函數,例如exec,多個請用,分割',
|
||||||
uploadMaxSize: '上傳限製',
|
uploadMaxSize: '上傳限製',
|
||||||
indexHelper: '為保障PHP網站正常運行,請將代碼放置於 index 目錄,並避免重命名',
|
indexHelper: '為保障PHP網站正常運行,請將代碼放置於 index 目錄,並避免重命名',
|
||||||
|
extensions: '擴充範本',
|
||||||
|
extension: '擴充',
|
||||||
|
extensionHelper: '多個擴充功能,分割',
|
||||||
|
toExtensionsList: '檢視擴充清單',
|
||||||
},
|
},
|
||||||
nginx: {
|
nginx: {
|
||||||
serverNamesHashBucketSizeHelper: '服務器名字的hash表大小',
|
serverNamesHashBucketSizeHelper: '服務器名字的hash表大小',
|
||||||
|
@ -190,6 +190,7 @@ const message = {
|
|||||||
paramSimple: '支持小写字母和数字,长度1-128',
|
paramSimple: '支持小写字母和数字,长度1-128',
|
||||||
filePermission: '权限错误',
|
filePermission: '权限错误',
|
||||||
formatErr: '格式错误,检查后重试',
|
formatErr: '格式错误,检查后重试',
|
||||||
|
phpExtension: '仅支持 , _ 小写英文和数字',
|
||||||
},
|
},
|
||||||
res: {
|
res: {
|
||||||
paramError: '请求失败,请稍后重试!',
|
paramError: '请求失败,请稍后重试!',
|
||||||
@ -1725,6 +1726,10 @@ const message = {
|
|||||||
disableFunctionHelper: '输入要禁用的函数,例如exec,多个请用,分割',
|
disableFunctionHelper: '输入要禁用的函数,例如exec,多个请用,分割',
|
||||||
uploadMaxSize: '上传限制',
|
uploadMaxSize: '上传限制',
|
||||||
indexHelper: '为保障 PHP 网站正常运行,请将代码放置于主目录下的 index 目录,并避免重命名',
|
indexHelper: '为保障 PHP 网站正常运行,请将代码放置于主目录下的 index 目录,并避免重命名',
|
||||||
|
extensions: '扩展模版',
|
||||||
|
extension: '扩展',
|
||||||
|
extensionsHelper: '多个扩展请用,分割',
|
||||||
|
toExtensionsList: '查看扩展列表',
|
||||||
},
|
},
|
||||||
nginx: {
|
nginx: {
|
||||||
serverNamesHashBucketSizeHelper: '服务器名字的hash表大小',
|
serverNamesHashBucketSizeHelper: '服务器名字的hash表大小',
|
||||||
|
@ -81,7 +81,16 @@
|
|||||||
{{ $t('runtime.phpsourceHelper') }}
|
{{ $t('runtime.phpsourceHelper') }}
|
||||||
</span>
|
</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t('php.extensions')">
|
||||||
|
<el-select v-model="extensions" @change="changePHPExtension()">
|
||||||
|
<el-option
|
||||||
|
v-for="(extension, index) in phpExtensions"
|
||||||
|
:key="index"
|
||||||
|
:label="extension.name"
|
||||||
|
:value="extension.extensions"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
<Params
|
<Params
|
||||||
v-if="mode === 'create'"
|
v-if="mode === 'create'"
|
||||||
v-model:form="runtime.params"
|
v-model:form="runtime.params"
|
||||||
@ -146,7 +155,7 @@
|
|||||||
import { App } from '@/api/interface/app';
|
import { App } from '@/api/interface/app';
|
||||||
import { Runtime } from '@/api/interface/runtime';
|
import { Runtime } from '@/api/interface/runtime';
|
||||||
import { GetApp, GetAppDetail, SearchApp } from '@/api/modules/app';
|
import { GetApp, GetAppDetail, SearchApp } from '@/api/modules/app';
|
||||||
import { CreateRuntime, GetRuntime, UpdateRuntime } from '@/api/modules/runtime';
|
import { CreateRuntime, GetRuntime, ListPHPExtensions, UpdateRuntime } from '@/api/modules/runtime';
|
||||||
import { Rules } from '@/global/form-rules';
|
import { Rules } from '@/global/form-rules';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgSuccess } from '@/utils/message';
|
||||||
@ -172,6 +181,7 @@ const mode = ref('create');
|
|||||||
const appParams = ref<App.AppParams>();
|
const appParams = ref<App.AppParams>();
|
||||||
const editParams = ref<App.InstallParams[]>();
|
const editParams = ref<App.InstallParams[]>();
|
||||||
const appVersions = ref<string[]>([]);
|
const appVersions = ref<string[]>([]);
|
||||||
|
const phpExtensions = ref([]);
|
||||||
const appReq = reactive({
|
const appReq = reactive({
|
||||||
type: 'php',
|
type: 'php',
|
||||||
page: 1,
|
page: 1,
|
||||||
@ -187,6 +197,7 @@ const initData = (type: string) => ({
|
|||||||
rebuild: false,
|
rebuild: false,
|
||||||
source: 'mirrors.ustc.edu.cn',
|
source: 'mirrors.ustc.edu.cn',
|
||||||
});
|
});
|
||||||
|
const extensions = ref();
|
||||||
|
|
||||||
let runtime = reactive<Runtime.RuntimeCreate>(initData('php'));
|
let runtime = reactive<Runtime.RuntimeCreate>(initData('php'));
|
||||||
|
|
||||||
@ -364,6 +375,21 @@ const getRuntime = async (id: number) => {
|
|||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const listPHPExtensions = async () => {
|
||||||
|
try {
|
||||||
|
const res = await ListPHPExtensions({
|
||||||
|
all: true,
|
||||||
|
page: 1,
|
||||||
|
pageSize: 100,
|
||||||
|
});
|
||||||
|
phpExtensions.value = res.data;
|
||||||
|
} catch (error) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
const changePHPExtension = () => {
|
||||||
|
runtime.params['PHP_EXTENSIONS'] = extensions.value.split(',');
|
||||||
|
};
|
||||||
|
|
||||||
const acceptParams = async (props: OperateRrops) => {
|
const acceptParams = async (props: OperateRrops) => {
|
||||||
mode.value = props.mode;
|
mode.value = props.mode;
|
||||||
initParam.value = false;
|
initParam.value = false;
|
||||||
@ -374,6 +400,8 @@ const acceptParams = async (props: OperateRrops) => {
|
|||||||
searchApp(props.appID);
|
searchApp(props.appID);
|
||||||
getRuntime(props.id);
|
getRuntime(props.id);
|
||||||
}
|
}
|
||||||
|
extensions.value = '';
|
||||||
|
listPHPExtensions();
|
||||||
open.value = true;
|
open.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
101
frontend/src/views/website/runtime/php/extensions/index.vue
Normal file
101
frontend/src/views/website/runtime/php/extensions/index.vue
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<template>
|
||||||
|
<el-drawer :close-on-click-modal="false" v-model="open" size="50%" :before-close="handleClose">
|
||||||
|
<template #header>
|
||||||
|
<DrawerHeader :header="$t('php.extensions')" :back="handleClose" />
|
||||||
|
</template>
|
||||||
|
<ComplexTable :data="data" @search="search()" :pagination-config="paginationConfig">
|
||||||
|
<template #toolbar>
|
||||||
|
<el-button type="primary" @click="openCreate">{{ $t('commons.button.create') }}</el-button>
|
||||||
|
</template>
|
||||||
|
<el-table-column :label="$t('commons.table.name')" width="150px" prop="name"></el-table-column>
|
||||||
|
<el-table-column :label="$t('php.extension')" fix prop="extensions"></el-table-column>
|
||||||
|
<fu-table-operations
|
||||||
|
:ellipsis="10"
|
||||||
|
width="120px"
|
||||||
|
:buttons="buttons"
|
||||||
|
:label="$t('commons.table.operate')"
|
||||||
|
fixed="right"
|
||||||
|
fix
|
||||||
|
/>
|
||||||
|
</ComplexTable>
|
||||||
|
<Create ref="createRef" @close="search()" />
|
||||||
|
<OpDialog ref="opRef" @search="search" />
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { DeletePHPExtensions, SearchPHPExtensions } from '@/api/modules/runtime';
|
||||||
|
import { reactive, ref } from 'vue';
|
||||||
|
import Create from './operate/index.vue';
|
||||||
|
import { Runtime } from '@/api/interface/runtime';
|
||||||
|
import i18n from '@/lang';
|
||||||
|
|
||||||
|
const open = ref(false);
|
||||||
|
const data = ref();
|
||||||
|
const createRef = ref();
|
||||||
|
const opRef = ref();
|
||||||
|
|
||||||
|
const paginationConfig = reactive({
|
||||||
|
cacheSizeKey: 'website-page-size',
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: Number(localStorage.getItem('website-page-size')) || 10,
|
||||||
|
total: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const buttons = [
|
||||||
|
{
|
||||||
|
label: i18n.global.t('commons.button.edit'),
|
||||||
|
click: function (row: Runtime.PHPExtensions) {
|
||||||
|
openUpdate(row);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: i18n.global.t('commons.button.delete'),
|
||||||
|
click: function (row: Runtime.PHPExtensions) {
|
||||||
|
openDelete(row);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
open.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const acceptParams = (): void => {
|
||||||
|
open.value = true;
|
||||||
|
search();
|
||||||
|
};
|
||||||
|
|
||||||
|
const openCreate = () => {
|
||||||
|
createRef.value.acceptParams('create');
|
||||||
|
};
|
||||||
|
|
||||||
|
const search = async () => {
|
||||||
|
try {
|
||||||
|
const res = await SearchPHPExtensions({
|
||||||
|
page: paginationConfig.currentPage,
|
||||||
|
pageSize: paginationConfig.pageSize,
|
||||||
|
});
|
||||||
|
data.value = res.data.items;
|
||||||
|
paginationConfig.total = res.data.total;
|
||||||
|
} catch (error) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
const openDelete = async (row: Runtime.PHPExtensions) => {
|
||||||
|
opRef.value.acceptParams({
|
||||||
|
title: i18n.global.t('commons.msg.deleteTitle'),
|
||||||
|
names: [row.name],
|
||||||
|
msg: i18n.global.t('commons.msg.operatorHelper', [
|
||||||
|
i18n.global.t('php.extensions'),
|
||||||
|
i18n.global.t('commons.button.delete'),
|
||||||
|
]),
|
||||||
|
api: DeletePHPExtensions,
|
||||||
|
params: { id: row.id },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const openUpdate = async (row: Runtime.PHPExtensions) => {
|
||||||
|
createRef.value.acceptParams('edit', row);
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({ acceptParams });
|
||||||
|
</script>
|
@ -0,0 +1,121 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
v-model="open"
|
||||||
|
:title="$t('commons.button.' + operate) + $t('php.extensions')"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
width="30%"
|
||||||
|
:before-close="handleClose"
|
||||||
|
>
|
||||||
|
<el-row v-loading="loading">
|
||||||
|
<el-col :span="22" :offset="1">
|
||||||
|
<el-form @submit.prevent ref="extensionsForm" label-position="top" :model="extensions" :rules="rules">
|
||||||
|
<el-form-item :label="$t('commons.table.name')" prop="name">
|
||||||
|
<el-input v-model.trim="extensions.name" :disabled="operate == 'edit'"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t('php.extension')" prop="extensions">
|
||||||
|
<el-input
|
||||||
|
type="textarea"
|
||||||
|
:placeholder="$t('php.extensionsHelper')"
|
||||||
|
:autosize="{ minRows: 3, maxRows: 10 }"
|
||||||
|
v-model="extensions.extensions"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<a target="“_blank”" href="https://1panel.cn/docs/user_manual/websites/php/#php_1">
|
||||||
|
{{ $t('php.toExtensionsList') }}
|
||||||
|
</a>
|
||||||
|
</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(extensionsForm)" :disabled="loading">
|
||||||
|
{{ $t('commons.button.confirm') }}
|
||||||
|
</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { Rules } from '@/global/form-rules';
|
||||||
|
import { FormInstance } from 'element-plus';
|
||||||
|
import { MsgSuccess } from '@/utils/message';
|
||||||
|
import { CreatePHPExtensions, UpdatePHPExtensions } from '@/api/modules/runtime';
|
||||||
|
import i18n from '@/lang';
|
||||||
|
import { Runtime } from '@/api/interface/runtime';
|
||||||
|
|
||||||
|
const open = ref(false);
|
||||||
|
const operate = ref('create');
|
||||||
|
const loading = ref(false);
|
||||||
|
const updateID = ref(0);
|
||||||
|
const extensionsForm = ref<FormInstance>();
|
||||||
|
const rules = ref({
|
||||||
|
name: [Rules.requiredInput],
|
||||||
|
extensions: [Rules.requiredInput, Rules.phpExtensions],
|
||||||
|
});
|
||||||
|
const em = defineEmits(['close']);
|
||||||
|
|
||||||
|
const initData = () => ({
|
||||||
|
name: '',
|
||||||
|
extensions: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const extensions = ref(initData());
|
||||||
|
|
||||||
|
const acceptParams = (op: string, extend: Runtime.PHPExtensions) => {
|
||||||
|
operate.value = op;
|
||||||
|
open.value = true;
|
||||||
|
extensions.value = initData();
|
||||||
|
if (operate.value == 'edit') {
|
||||||
|
extensions.value = extend;
|
||||||
|
updateID.value = extend.id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
open.value = false;
|
||||||
|
extensionsForm.value?.resetFields();
|
||||||
|
em('close', false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const submit = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
await formEl.validate((valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loading.value = true;
|
||||||
|
if (operate.value == 'create') {
|
||||||
|
CreatePHPExtensions(extensions.value)
|
||||||
|
.then(() => {
|
||||||
|
MsgSuccess(i18n.global.t('commons.msg.createSuccess'));
|
||||||
|
handleClose();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
UpdatePHPExtensions({
|
||||||
|
id: updateID.value,
|
||||||
|
name: extensions.value.name,
|
||||||
|
extensions: extensions.value.extensions,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
||||||
|
handleClose();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
acceptParams,
|
||||||
|
});
|
||||||
|
</script>
|
@ -13,6 +13,10 @@
|
|||||||
<el-button type="primary" @click="openCreate">
|
<el-button type="primary" @click="openCreate">
|
||||||
{{ $t('runtime.create') }}
|
{{ $t('runtime.create') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
|
<el-button @click="openExtensions">
|
||||||
|
{{ $t('php.extensions') }}
|
||||||
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<template #main>
|
<template #main>
|
||||||
<ComplexTable :pagination-config="paginationConfig" :data="items" @search="search()">
|
<ComplexTable :pagination-config="paginationConfig" :data="items" @search="search()">
|
||||||
@ -74,6 +78,7 @@
|
|||||||
<CreateRuntime ref="createRef" @close="search" @submit="openCreateLog" />
|
<CreateRuntime ref="createRef" @close="search" @submit="openCreateLog" />
|
||||||
<OpDialog ref="opRef" @search="search" />
|
<OpDialog ref="opRef" @search="search" />
|
||||||
<Log ref="logRef" @close="search" />
|
<Log ref="logRef" @close="search" />
|
||||||
|
<Extensions ref="extensionsRef" @close="search" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -88,6 +93,7 @@ import Status from '@/components/status/index.vue';
|
|||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import RouterMenu from '../index.vue';
|
import RouterMenu from '../index.vue';
|
||||||
import Log from '@/components/log-dialog/index.vue';
|
import Log from '@/components/log-dialog/index.vue';
|
||||||
|
import Extensions from './extensions/index.vue';
|
||||||
|
|
||||||
const paginationConfig = reactive({
|
const paginationConfig = reactive({
|
||||||
cacheSizeKey: 'runtime-page-size',
|
cacheSizeKey: 'runtime-page-size',
|
||||||
@ -104,6 +110,7 @@ let req = reactive<Runtime.RuntimeReq>({
|
|||||||
let timer: NodeJS.Timer | null = null;
|
let timer: NodeJS.Timer | null = null;
|
||||||
const opRef = ref();
|
const opRef = ref();
|
||||||
const logRef = ref();
|
const logRef = ref();
|
||||||
|
const extensionsRef = ref();
|
||||||
|
|
||||||
const buttons = [
|
const buttons = [
|
||||||
{
|
{
|
||||||
@ -156,13 +163,17 @@ const openCreateLog = (id: number) => {
|
|||||||
logRef.value.acceptParams({ id: id, type: 'php', tail: true });
|
logRef.value.acceptParams({ id: id, type: 'php', tail: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openExtensions = () => {
|
||||||
|
extensionsRef.value.acceptParams();
|
||||||
|
};
|
||||||
|
|
||||||
const openDelete = async (row: Runtime.Runtime) => {
|
const openDelete = async (row: Runtime.Runtime) => {
|
||||||
opRef.value.acceptParams({
|
opRef.value.acceptParams({
|
||||||
title: i18n.global.t('commons.msg.deleteTitle'),
|
title: i18n.global.t('commons.msg.deleteTitle'),
|
||||||
names: [row.name],
|
names: [row.name],
|
||||||
msg: i18n.global.t('commons.msg.operatorHelper', [
|
msg: i18n.global.t('commons.msg.operatorHelper', [
|
||||||
i18n.global.t('website.runtime'),
|
i18n.global.t('website.runtime'),
|
||||||
i18n.global.t('commons.msg.delete'),
|
i18n.global.t('commons.button.delete'),
|
||||||
]),
|
]),
|
||||||
api: DeleteRuntime,
|
api: DeleteRuntime,
|
||||||
params: { id: row.id, forceDelete: true },
|
params: { id: row.id, forceDelete: true },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user