mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 07:57:21 +08:00
feat: PHP环境支持管理
This commit is contained in:
@@ -491,7 +491,7 @@ func (r *websiteRepo) Update(req *request.WebsiteUpdate) error {
|
||||
Cert: certPath,
|
||||
Key: keyPath,
|
||||
Protocols: lo.If(len(req.SSLProtocols) > 0, req.SSLProtocols).Else([]string{"TLSv1.2", "TLSv1.3"}),
|
||||
Ciphers: lo.If(req.SSLCiphers != "", req.SSLCiphers).Else("HIGH:!aNULL:!MD5"),
|
||||
Ciphers: lo.If(req.SSLCiphers != "", req.SSLCiphers).Else("ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305"),
|
||||
HSTS: req.HSTS,
|
||||
OCSP: req.OCSP,
|
||||
HTTPRedirect: req.HTTPRedirect,
|
||||
|
||||
@@ -147,7 +147,7 @@ func (v *baseVhost) Listen() []types.Listen {
|
||||
// Apache 的监听配置通常在 VirtualHost 的参数中
|
||||
// 例如: <VirtualHost *:80> 或 <VirtualHost 192.168.1.1:443>
|
||||
for _, arg := range v.vhost.Args {
|
||||
listen := types.Listen{Address: arg}
|
||||
listen := types.Listen{Address: arg, Args: []string{}}
|
||||
result = append(result, listen)
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,6 @@ func parseProxyFile(filePath string) (*types.Proxy, error) {
|
||||
if rm := resolverPattern.FindStringSubmatch(blockContent); rm != nil {
|
||||
parts := strings.Fields(rm[1])
|
||||
proxy.Resolver = parts
|
||||
proxy.AutoRefresh = true // 有 resolver 通常意味着需要自动刷新
|
||||
}
|
||||
|
||||
// 解析 resolver_timeout
|
||||
@@ -218,19 +217,16 @@ func generateProxyConfig(proxy types.Proxy) string {
|
||||
|
||||
sb.WriteString(fmt.Sprintf("location %s {\n", location))
|
||||
|
||||
// resolver 配置(如果启用自动刷新)
|
||||
if proxy.AutoRefresh && len(proxy.Resolver) > 0 {
|
||||
// resolver 配置
|
||||
if len(proxy.Resolver) > 0 {
|
||||
sb.WriteString(fmt.Sprintf(" resolver %s;\n", strings.Join(proxy.Resolver, " ")))
|
||||
if proxy.ResolverTimeout > 0 {
|
||||
sb.WriteString(fmt.Sprintf(" resolver_timeout %ds;\n", int(proxy.ResolverTimeout.Seconds())))
|
||||
}
|
||||
// 使用变量实现动态解析
|
||||
sb.WriteString(fmt.Sprintf(" set $backend \"%s\";\n", proxy.Pass))
|
||||
sb.WriteString(" proxy_pass $backend;\n")
|
||||
} else {
|
||||
sb.WriteString(fmt.Sprintf(" proxy_pass %s;\n", proxy.Pass))
|
||||
}
|
||||
|
||||
sb.WriteString(fmt.Sprintf(" proxy_pass %s;\n", proxy.Pass))
|
||||
|
||||
// Host 头
|
||||
if proxy.Host != "" {
|
||||
sb.WriteString(fmt.Sprintf(" proxy_set_header Host \"%s\";\n", proxy.Host))
|
||||
|
||||
@@ -158,7 +158,7 @@ func (v *baseVhost) Listen() []types.Listen {
|
||||
var result []types.Listen
|
||||
for _, dir := range directives {
|
||||
l := v.parser.parameters2Slices(dir.GetParameters())
|
||||
listen := types.Listen{Address: l[0]}
|
||||
listen := types.Listen{Address: l[0], Args: []string{}}
|
||||
for i := 1; i < len(l); i++ {
|
||||
listen.Args = append(listen.Args, l[i])
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import "time"
|
||||
// Proxy 反向代理配置
|
||||
type Proxy struct {
|
||||
Location string `form:"location" json:"location" validate:"required"` // 匹配路径,如: "/", "/api", "~ ^/api/v[0-9]+/"
|
||||
AutoRefresh bool `form:"auto_refresh" json:"auto_refresh"` // 是否自动刷新解析
|
||||
Pass string `form:"pass" json:"pass" validate:"required"` // 代理地址,如: "http://example.com", "http://backend"
|
||||
Host string `form:"host" json:"host"` // 代理 Host,如: "example.com"
|
||||
SNI string `form:"sni" json:"sni"` // 代理 SNI,如: "example.com"
|
||||
@@ -18,7 +17,7 @@ type Proxy struct {
|
||||
|
||||
// Upstream 上游服务器配置
|
||||
type Upstream struct {
|
||||
Servers map[string]string `form:"servers" json:"servers" validate:"required"` // 上游服务器及权重,如: map["server1"] = "weight=5"
|
||||
Servers map[string]string `form:"servers" json:"servers" validate:"required"` // 上游服务器及配置,如: map["server1"] = "weight=5 resolve"
|
||||
Algo string `form:"algo" json:"algo"` // 负载均衡算法,如: "least_conn", "ip_hash"
|
||||
Keepalive int `form:"keepalive" json:"keepalive"` // 保持连接数,如: 32
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"github.com/acepanel/panel/pkg/webserver/types"
|
||||
)
|
||||
|
||||
// NewStaticVhost 创建纯静态虚拟主机实例
|
||||
func NewStaticVhost(serverType Type, configDir string) (types.StaticVhost, error) {
|
||||
switch serverType {
|
||||
case TypeNginx:
|
||||
@@ -20,7 +19,6 @@ func NewStaticVhost(serverType Type, configDir string) (types.StaticVhost, error
|
||||
}
|
||||
}
|
||||
|
||||
// NewPHPVhost 创建 PHP 虚拟主机实例
|
||||
func NewPHPVhost(serverType Type, configDir string) (types.PHPVhost, error) {
|
||||
switch serverType {
|
||||
case TypeNginx:
|
||||
@@ -32,7 +30,6 @@ func NewPHPVhost(serverType Type, configDir string) (types.PHPVhost, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// NewProxyVhost 创建反向代理虚拟主机实例
|
||||
func NewProxyVhost(serverType Type, configDir string) (types.ProxyVhost, error) {
|
||||
switch serverType {
|
||||
case TypeNginx:
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
import { http } from '@/utils'
|
||||
|
||||
export default {
|
||||
// 设为 CLI 版本
|
||||
setCli: (version: number): any => http.Post(`/apps/php${version}/set_cli`),
|
||||
// 获取配置
|
||||
config: (version: number): any => http.Get(`/apps/php${version}/config`),
|
||||
// 保存配置
|
||||
saveConfig: (version: number, config: string): any =>
|
||||
http.Post(`/apps/php${version}/config`, { config }),
|
||||
// 获取FPM配置
|
||||
fpmConfig: (version: number): any => http.Get(`/apps/php${version}/fpm_config`),
|
||||
// 保存FPM配置
|
||||
saveFPMConfig: (version: number, config: string): any =>
|
||||
http.Post(`/apps/php${version}/fpm_config`, { config }),
|
||||
// 负载状态
|
||||
load: (version: number): any => http.Get(`/apps/php${version}/load`),
|
||||
// 获取日志
|
||||
log: (version: number): any => http.Get(`/apps/php${version}/log`),
|
||||
// 清空日志
|
||||
clearLog: (version: number): any => http.Post(`/apps/php${version}/clear_log`),
|
||||
// 获取慢日志
|
||||
slowLog: (version: number): any => http.Get(`/apps/php${version}/slow_log`),
|
||||
// 清空慢日志
|
||||
clearSlowLog: (version: number): any => http.Post(`/apps/php${version}/clear_slow_log`),
|
||||
// 拓展列表
|
||||
extensions: (version: number): any => http.Get(`/apps/php${version}/extensions`),
|
||||
// 安装拓展
|
||||
installExtension: (version: number, slug: string): any =>
|
||||
http.Post(`/apps/php${version}/extensions`, { slug }),
|
||||
// 卸载拓展
|
||||
uninstallExtension: (version: number, slug: string): any =>
|
||||
http.Delete(`/apps/php${version}/extensions`, { slug })
|
||||
}
|
||||
34
web/src/api/panel/environment/php/index.ts
Normal file
34
web/src/api/panel/environment/php/index.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { http } from '@/utils'
|
||||
|
||||
export default {
|
||||
// 设为 CLI 版本
|
||||
setCli: (slug: number): any => http.Post(`/environment/php/${slug}/set_cli`),
|
||||
// 获取配置
|
||||
config: (slug: number): any => http.Get(`/environment/php/${slug}/config`),
|
||||
// 保存配置
|
||||
saveConfig: (slug: number, config: string): any =>
|
||||
http.Post(`/environment/php/${slug}/config`, { config }),
|
||||
// 获取FPM配置
|
||||
fpmConfig: (slug: number): any => http.Get(`/environment/php/${slug}/fpm_config`),
|
||||
// 保存FPM配置
|
||||
saveFPMConfig: (slug: number, config: string): any =>
|
||||
http.Post(`/environment/php/${slug}/fpm_config`, { config }),
|
||||
// 负载状态
|
||||
load: (slug: number): any => http.Get(`/environment/php/${slug}/load`),
|
||||
// 获取日志
|
||||
log: (slug: number): any => http.Get(`/environment/php/${slug}/log`),
|
||||
// 清空日志
|
||||
clearLog: (slug: number): any => http.Post(`/environment/php/${slug}/clear_log`),
|
||||
// 获取慢日志
|
||||
slowLog: (slug: number): any => http.Get(`/environment/php/${slug}/slow_log`),
|
||||
// 清空慢日志
|
||||
clearSlowLog: (slug: number): any => http.Post(`/environment/php/${slug}/clear_slow_log`),
|
||||
// 拓展列表
|
||||
modules: (slug: number): any => http.Get(`/environment/php/${slug}/modules`),
|
||||
// 安装拓展
|
||||
installModule: (slug: number, module: string): any =>
|
||||
http.Post(`/environment/php/${slug}/modules`, { slug: module }),
|
||||
// 卸载拓展
|
||||
uninstallModule: (slug: number, module: string): any =>
|
||||
http.Delete(`/environment/php/${slug}/modules`, { slug: module })
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import environment from '@/api/panel/environment'
|
||||
import { router } from '@/router'
|
||||
import { renderLocalIcon } from '@/utils'
|
||||
import { NButton, NDataTable, NFlex, NPopconfirm, NTag } from 'naive-ui'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
@@ -86,8 +87,8 @@ const columns: any = [
|
||||
NButton,
|
||||
{
|
||||
size: 'small',
|
||||
type: 'info'
|
||||
//onClick: () => handleManage(row.slug)
|
||||
type: 'info',
|
||||
onClick: () => handleManage(row.type, row.slug)
|
||||
},
|
||||
{
|
||||
default: () => $gettext('Manage')
|
||||
@@ -195,6 +196,10 @@ const handleUninstall = (type: string, slug: string) => {
|
||||
})
|
||||
}
|
||||
|
||||
const handleManage = (type: string, slug: string) => {
|
||||
router.push({ name: 'environment-' + type, params: { slug } })
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
refresh()
|
||||
})
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
defineOptions({
|
||||
name: 'apps-php74-index'
|
||||
})
|
||||
|
||||
import PhpView from '@/views/apps/php/PhpView.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<php-view :version="74" />
|
||||
</template>
|
||||
@@ -1,22 +0,0 @@
|
||||
import type { RouteType } from '~/types/router'
|
||||
|
||||
const Layout = () => import('@/layout/IndexView.vue')
|
||||
|
||||
export default {
|
||||
name: 'php74',
|
||||
path: '/apps/php74',
|
||||
component: Layout,
|
||||
isHidden: true,
|
||||
children: [
|
||||
{
|
||||
name: 'apps-php74-index',
|
||||
path: '',
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'PHP 7.4',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
}
|
||||
]
|
||||
} as RouteType
|
||||
@@ -1,11 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
defineOptions({
|
||||
name: 'apps-php80-index'
|
||||
})
|
||||
|
||||
import PhpView from '@/views/apps/php/PhpView.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<php-view :version="80" />
|
||||
</template>
|
||||
@@ -1,11 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
defineOptions({
|
||||
name: 'apps-php81-index'
|
||||
})
|
||||
|
||||
import PhpView from '@/views/apps/php/PhpView.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<php-view :version="81" />
|
||||
</template>
|
||||
@@ -1,22 +0,0 @@
|
||||
import type { RouteType } from '~/types/router'
|
||||
|
||||
const Layout = () => import('@/layout/IndexView.vue')
|
||||
|
||||
export default {
|
||||
name: 'php81',
|
||||
path: '/apps/php81',
|
||||
component: Layout,
|
||||
isHidden: true,
|
||||
children: [
|
||||
{
|
||||
name: 'apps-php81-index',
|
||||
path: '',
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'PHP 8.1',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
}
|
||||
]
|
||||
} as RouteType
|
||||
@@ -1,11 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
defineOptions({
|
||||
name: 'apps-php82-index'
|
||||
})
|
||||
|
||||
import PhpView from '@/views/apps/php/PhpView.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<php-view :version="82" />
|
||||
</template>
|
||||
@@ -1,22 +0,0 @@
|
||||
import type { RouteType } from '~/types/router'
|
||||
|
||||
const Layout = () => import('@/layout/IndexView.vue')
|
||||
|
||||
export default {
|
||||
name: 'php82',
|
||||
path: '/apps/php82',
|
||||
component: Layout,
|
||||
isHidden: true,
|
||||
children: [
|
||||
{
|
||||
name: 'apps-php82-index',
|
||||
path: '',
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'PHP 8.2',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
}
|
||||
]
|
||||
} as RouteType
|
||||
@@ -1,11 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
defineOptions({
|
||||
name: 'apps-php83-index'
|
||||
})
|
||||
|
||||
import PhpView from '@/views/apps/php/PhpView.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<php-view :version="83" />
|
||||
</template>
|
||||
@@ -1,22 +0,0 @@
|
||||
import type { RouteType } from '~/types/router'
|
||||
|
||||
const Layout = () => import('@/layout/IndexView.vue')
|
||||
|
||||
export default {
|
||||
name: 'php83',
|
||||
path: '/apps/php83',
|
||||
component: Layout,
|
||||
isHidden: true,
|
||||
children: [
|
||||
{
|
||||
name: 'apps-php83-index',
|
||||
path: '',
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'PHP 8.3',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
}
|
||||
]
|
||||
} as RouteType
|
||||
@@ -1,11 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
defineOptions({
|
||||
name: 'apps-php84-index'
|
||||
})
|
||||
|
||||
import PhpView from '@/views/apps/php/PhpView.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<php-view :version="84" />
|
||||
</template>
|
||||
@@ -1,22 +0,0 @@
|
||||
import type { RouteType } from '~/types/router'
|
||||
|
||||
const Layout = () => import('@/layout/IndexView.vue')
|
||||
|
||||
export default {
|
||||
name: 'php84',
|
||||
path: '/apps/php84',
|
||||
component: Layout,
|
||||
isHidden: true,
|
||||
children: [
|
||||
{
|
||||
name: 'apps-php84-index',
|
||||
path: '',
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'PHP 8.4',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
}
|
||||
]
|
||||
} as RouteType
|
||||
@@ -1,44 +1,39 @@
|
||||
<script setup lang="ts">
|
||||
import ServiceStatus from '@/components/common/ServiceStatus.vue'
|
||||
import { NButton, NDataTable, NPopconfirm } from 'naive-ui'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
|
||||
import php from '@/api/apps/php'
|
||||
import ServiceStatus from '@/components/common/ServiceStatus.vue'
|
||||
import php from '@/api/panel/environment/php'
|
||||
|
||||
const route = useRoute()
|
||||
const slug = Number(route.params.slug)
|
||||
|
||||
const { $gettext } = useGettext()
|
||||
const props = defineProps({
|
||||
version: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const { version } = toRefs(props)
|
||||
|
||||
const currentTab = ref('status')
|
||||
|
||||
const { data: config } = useRequest(php.config(version.value), {
|
||||
const { data: config } = useRequest(php.config(slug), {
|
||||
initialData: ''
|
||||
})
|
||||
const { data: fpmConfig } = useRequest(php.fpmConfig(version.value), {
|
||||
const { data: fpmConfig } = useRequest(php.fpmConfig(slug), {
|
||||
initialData: ''
|
||||
})
|
||||
const { data: log } = useRequest(php.log(version.value), {
|
||||
const { data: log } = useRequest(php.log(slug), {
|
||||
initialData: ''
|
||||
})
|
||||
const { data: slowLog } = useRequest(php.slowLog(version.value), {
|
||||
const { data: slowLog } = useRequest(php.slowLog(slug), {
|
||||
initialData: ''
|
||||
})
|
||||
const { data: load } = useRequest(php.load(version.value), {
|
||||
const { data: load } = useRequest(php.load(slug), {
|
||||
initialData: []
|
||||
})
|
||||
const { data: extensions } = useRequest(php.extensions(version.value), {
|
||||
const { data: modules } = useRequest(php.modules(slug), {
|
||||
initialData: []
|
||||
})
|
||||
|
||||
const extensionColumns: any = [
|
||||
const moduleColumns: any = [
|
||||
{
|
||||
title: $gettext('Extension Name'),
|
||||
title: $gettext('Module Name'),
|
||||
key: 'name',
|
||||
minWidth: 250,
|
||||
resizable: true,
|
||||
@@ -62,7 +57,7 @@ const extensionColumns: any = [
|
||||
? h(
|
||||
NPopconfirm,
|
||||
{
|
||||
onPositiveClick: () => handleInstallExtension(row.slug)
|
||||
onPositiveClick: () => handleInstallModule(row.slug)
|
||||
},
|
||||
{
|
||||
default: () => {
|
||||
@@ -87,7 +82,7 @@ const extensionColumns: any = [
|
||||
? h(
|
||||
NPopconfirm,
|
||||
{
|
||||
onPositiveClick: () => handleUninstallExtension(row.slug)
|
||||
onPositiveClick: () => handleUninstallModule(row.slug)
|
||||
},
|
||||
{
|
||||
default: () => {
|
||||
@@ -132,43 +127,43 @@ const loadColumns: any = [
|
||||
]
|
||||
|
||||
const handleSetCli = async () => {
|
||||
useRequest(php.setCli(version.value)).onSuccess(() => {
|
||||
useRequest(php.setCli(slug)).onSuccess(() => {
|
||||
window.$message.success($gettext('Set successfully'))
|
||||
})
|
||||
}
|
||||
|
||||
const handleSaveConfig = async () => {
|
||||
useRequest(php.saveConfig(version.value, config.value)).onSuccess(() => {
|
||||
useRequest(php.saveConfig(slug, config.value)).onSuccess(() => {
|
||||
window.$message.success($gettext('Saved successfully'))
|
||||
})
|
||||
}
|
||||
|
||||
const handleSaveFPMConfig = async () => {
|
||||
useRequest(php.saveFPMConfig(version.value, fpmConfig.value)).onSuccess(() => {
|
||||
useRequest(php.saveFPMConfig(slug, fpmConfig.value)).onSuccess(() => {
|
||||
window.$message.success($gettext('Saved successfully'))
|
||||
})
|
||||
}
|
||||
|
||||
const handleClearLog = async () => {
|
||||
useRequest(php.clearLog(version.value)).onSuccess(() => {
|
||||
useRequest(php.clearLog(slug)).onSuccess(() => {
|
||||
window.$message.success($gettext('Cleared successfully'))
|
||||
})
|
||||
}
|
||||
|
||||
const handleClearSlowLog = async () => {
|
||||
useRequest(php.clearSlowLog(version.value)).onSuccess(() => {
|
||||
useRequest(php.clearSlowLog(slug)).onSuccess(() => {
|
||||
window.$message.success($gettext('Cleared successfully'))
|
||||
})
|
||||
}
|
||||
|
||||
const handleInstallExtension = async (slug: string) => {
|
||||
useRequest(php.installExtension(version.value, slug)).onSuccess(() => {
|
||||
const handleInstallModule = async (module: string) => {
|
||||
useRequest(php.installModule(slug, module)).onSuccess(() => {
|
||||
window.$message.success($gettext('Task submitted, please check progress in background tasks'))
|
||||
})
|
||||
}
|
||||
|
||||
const handleUninstallExtension = async (name: string) => {
|
||||
useRequest(php.uninstallExtension(version.value, name)).onSuccess(() => {
|
||||
const handleUninstallModule = async (module: string) => {
|
||||
useRequest(php.uninstallModule(slug, module)).onSuccess(() => {
|
||||
window.$message.success($gettext('Task submitted, please check progress in background tasks'))
|
||||
})
|
||||
}
|
||||
@@ -179,21 +174,22 @@ const handleUninstallExtension = async (name: string) => {
|
||||
<n-tabs v-model:value="currentTab" type="line" animated>
|
||||
<n-tab-pane name="status" :tab="$gettext('Running Status')">
|
||||
<n-flex vertical>
|
||||
<service-status :service="`php-fpm-${version}`" show-reload />
|
||||
<n-card> PHP {{ slug }} </n-card>
|
||||
<service-status :service="`php-fpm-${slug}`" show-reload />
|
||||
<n-button type="info" @click="handleSetCli">
|
||||
{{ $gettext('Set as CLI Default Version') }}
|
||||
</n-button>
|
||||
</n-flex>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="extensions" :tab="$gettext('Extension Management')">
|
||||
<n-tab-pane name="modules" :tab="$gettext('Module Management')">
|
||||
<n-flex vertical>
|
||||
<n-data-table
|
||||
striped
|
||||
remote
|
||||
:scroll-x="1000"
|
||||
:loading="false"
|
||||
:columns="extensionColumns"
|
||||
:data="extensions"
|
||||
:columns="moduleColumns"
|
||||
:data="modules"
|
||||
:row-key="(row: any) => row.slug"
|
||||
/>
|
||||
</n-flex>
|
||||
@@ -204,7 +200,7 @@ const handleUninstallExtension = async (name: string) => {
|
||||
{{
|
||||
$gettext(
|
||||
'This modifies the PHP %{ version } main configuration file. If you do not understand the meaning of each parameter, please do not modify it randomly!',
|
||||
{ version: version }
|
||||
{ version: slug }
|
||||
)
|
||||
}}
|
||||
</n-alert>
|
||||
@@ -222,7 +218,7 @@ const handleUninstallExtension = async (name: string) => {
|
||||
{{
|
||||
$gettext(
|
||||
'This modifies the PHP %{ version } FPM configuration file. If you do not understand the meaning of each parameter, please do not modify it randomly!',
|
||||
{ version: version }
|
||||
{ version: slug }
|
||||
)
|
||||
}}
|
||||
</n-alert>
|
||||
@@ -245,7 +241,7 @@ const handleUninstallExtension = async (name: string) => {
|
||||
/>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="run-log" :tab="$gettext('Runtime Logs')">
|
||||
<realtime-log :service="'php-fpm-' + version" />
|
||||
<realtime-log :service="'php-fpm-' + slug" />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="log" :tab="$gettext('Error Logs')">
|
||||
<n-flex vertical>
|
||||
@@ -270,3 +266,5 @@ const handleUninstallExtension = async (name: string) => {
|
||||
</n-tabs>
|
||||
</common-page>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@@ -3,17 +3,19 @@ import type { RouteType } from '~/types/router'
|
||||
const Layout = () => import('@/layout/IndexView.vue')
|
||||
|
||||
export default {
|
||||
name: 'php80',
|
||||
path: '/apps/php80',
|
||||
component: Layout,
|
||||
name: 'environment',
|
||||
path: '/environment',
|
||||
isHidden: true,
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
name: 'apps-php80-index',
|
||||
path: '',
|
||||
component: () => import('./IndexView.vue'),
|
||||
name: 'environment-php',
|
||||
path: 'php/:slug',
|
||||
isHidden: true,
|
||||
component: () => import('./PHPView.vue'),
|
||||
meta: {
|
||||
title: 'PHP 8.0',
|
||||
title: 'PHP',
|
||||
icon: 'mdi:language-php',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
@@ -24,8 +24,8 @@ export default {
|
||||
{
|
||||
name: 'home-update',
|
||||
path: 'update',
|
||||
component: () => import('./UpdateView.vue'),
|
||||
isHidden: true,
|
||||
component: () => import('./UpdateView.vue'),
|
||||
meta: {
|
||||
title: 'Update',
|
||||
icon: 'mdi:archive-arrow-up-outline',
|
||||
|
||||
Reference in New Issue
Block a user