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

fix: 容器端口跳转样式调整 (#1533)

This commit is contained in:
ssongliu 2023-07-05 10:20:13 +08:00 committed by GitHub
parent 3cbaa052c8
commit bd2facebee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 131 additions and 55 deletions

View File

@ -144,10 +144,11 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro
var ports []string var ports []string
for _, port := range item.Ports { for _, port := range item.Ports {
if port.IP == "::" || port.PublicPort == 0 { itemPortStr := fmt.Sprintf("%v/%s", port.PrivatePort, port.Type)
continue if port.PublicPort != 0 {
itemPortStr = fmt.Sprintf("%s:%v->%v/%s", port.IP, port.PublicPort, port.PrivatePort, port.Type)
} }
ports = append(ports, fmt.Sprintf("%v:%v/%s", port.PublicPort, port.PrivatePort, port.Type)) ports = append(ports, itemPortStr)
} }
cpu, mem := loadCpuAndMem(client, item.ID) cpu, mem := loadCpuAndMem(client, item.ID)
backDatas[i] = dto.ContainerInfo{ backDatas[i] = dto.ContainerInfo{

View File

@ -0,0 +1,55 @@
<template>
<div>
<el-dialog
v-model="dialogVisiable"
:title="$t('app.checkTitle')"
width="30%"
:close-on-click-modal="false"
:destroy-on-close="true"
>
<el-alert :closable="false" :title="$t('setting.systemIPWarning')" type="info">
<el-link icon="Position" @click="goRouter('/settings/panel')" type="primary">
{{ $t('firewall.quickJump') }}
</el-link>
</el-alert>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { getSettingInfo } from '@/api/modules/setting';
import i18n from '@/lang';
import { MsgError } from '@/utils/message';
import { useRouter } from 'vue-router';
const router = useRouter();
const dialogVisiable = ref();
interface DialogProps {
port: any;
}
const acceptParams = async (params: DialogProps): Promise<void> => {
if (Number(params.port) === 0) {
MsgError(i18n.global.t('setting.errPort'));
return;
}
const res = await getSettingInfo();
if (!res.data.systemIP) {
dialogVisiable.value = true;
return;
}
window.open(`http://${res.data.systemIP}:${params.port}`, '_blank');
};
const goRouter = async (path: string) => {
router.push({ path: path });
};
defineExpose({ acceptParams });
</script>

View File

@ -468,6 +468,7 @@ const message = {
cleanSuccessWithSpace: cleanSuccessWithSpace:
'The operation is successful. The number of disks cleared this time is {0}. The disk space freed is {1}!', 'The operation is successful. The number of disks cleared this time is {0}. The disk space freed is {1}!',
container: 'Container', container: 'Container',
unExposedPort: 'The current port mapping address is 127.0.0.1, which cannot enable external access.',
upTime: 'UpTime', upTime: 'UpTime',
all: 'All', all: 'All',
fetch: 'Fetch', fetch: 'Fetch',
@ -937,7 +938,7 @@ const message = {
sessionTimeoutHelper: sessionTimeoutHelper:
'If you do not operate the panel for more than {0} seconds, the panel automatically logs out', 'If you do not operate the panel for more than {0} seconds, the panel automatically logs out',
systemIP: 'System IP', systemIP: 'System IP',
systemIPWarning: 'Please set the system IP in the panel settings first.', systemIPWarning: 'The server IP is not currently set. Please set it in the control panel first!',
syncTime: 'Server time', syncTime: 'Server time',
timeZone: 'Time Zone', timeZone: 'Time Zone',
timeZoneChangeHelper: 'Changing the time zone requires restarting the service. Do you want to continue?', timeZoneChangeHelper: 'Changing the time zone requires restarting the service. Do you want to continue?',

View File

@ -432,7 +432,8 @@ const message = {
localIP: '本機 IP', localIP: '本機 IP',
}, },
container: { container: {
createContainer: '創建容器', create: '創建容器',
edit: '編輯容器',
updateContaienrHelper: '容器編輯需要重建容器任何未持久化的數據將會丟失是否繼續', updateContaienrHelper: '容器編輯需要重建容器任何未持久化的數據將會丟失是否繼續',
containerList: '容器列表', containerList: '容器列表',
operatorHelper: '將對選中容器進行 {0} 操作是否繼續', operatorHelper: '將對選中容器進行 {0} 操作是否繼續',
@ -459,6 +460,7 @@ const message = {
cleanSuccess: '操作成功本次清理數量: {0} ', cleanSuccess: '操作成功本次清理數量: {0} ',
cleanSuccessWithSpace: '操作成功本次清理數量: {0} 釋放磁盤空間: {1}', cleanSuccessWithSpace: '操作成功本次清理數量: {0} 釋放磁盤空間: {1}',
container: '容器', container: '容器',
unExposedPort: '當前端口映射地址為 127.0.0.1無法實現外部訪問',
upTime: '運行時長', upTime: '運行時長',
all: '全部', all: '全部',
fetch: '過濾', fetch: '過濾',
@ -621,6 +623,8 @@ const message = {
startIn: '中開啟', startIn: '中開啟',
}, },
cronjob: { cronjob: {
create: '創建計劃任務',
edit: '編輯計劃任務',
cronTask: '計劃任務', cronTask: '計劃任務',
changeStatus: '狀態修改', changeStatus: '狀態修改',
disableMsg: '停止計劃任務會導致該任務不再自動執行是否繼續', disableMsg: '停止計劃任務會導致該任務不再自動執行是否繼續',
@ -898,7 +902,7 @@ const message = {
sessionTimeoutError: '最小超時時間為 300 ', sessionTimeoutError: '最小超時時間為 300 ',
sessionTimeoutHelper: '如果用戶超過 {0} 秒未操作面板面板將自動退出登錄', sessionTimeoutHelper: '如果用戶超過 {0} 秒未操作面板面板將自動退出登錄',
systemIP: '服務器 IP', systemIP: '服務器 IP',
systemIPWarning: '請先在面板設置中設置服務器 IP', systemIPWarning: '當前未設置服務器 IP請先在面板設置中設置',
syncTime: '服務器時間', syncTime: '服務器時間',
timeZone: '系統時區', timeZone: '系統時區',
timeZoneChangeHelper: '系統時區修改需要重啟服務是否繼續', timeZoneChangeHelper: '系統時區修改需要重啟服務是否繼續',
@ -1406,6 +1410,8 @@ const message = {
acmeHelper: 'Acme 賬戶用於申請免費證書', acmeHelper: 'Acme 賬戶用於申請免費證書',
}, },
firewall: { firewall: {
create: '創建規則',
edit: '編輯規則',
notSupport: '未檢測到系統防火墻firewalld 或者 ufw請參考官方文檔進行安裝', notSupport: '未檢測到系統防火墻firewalld 或者 ufw請參考官方文檔進行安裝',
ccDeny: 'CC 防護', ccDeny: 'CC 防護',
ipWhiteList: 'IP 白名單', ipWhiteList: 'IP 白名單',

View File

@ -432,7 +432,8 @@ const message = {
localIP: '本机 IP', localIP: '本机 IP',
}, },
container: { container: {
createContainer: '创建容器', create: '创建容器',
edit: '编辑容器',
updateContaienrHelper: '容器编辑需要重建容器任何未持久化的数据将会丢失是否继续', updateContaienrHelper: '容器编辑需要重建容器任何未持久化的数据将会丢失是否继续',
containerList: '容器列表', containerList: '容器列表',
operatorHelper: '将对选中容器进行 {0} 操作是否继续', operatorHelper: '将对选中容器进行 {0} 操作是否继续',
@ -459,6 +460,7 @@ const message = {
cleanSuccess: '操作成功本次清理数量: {0} ', cleanSuccess: '操作成功本次清理数量: {0} ',
cleanSuccessWithSpace: '操作成功本次清理数量: {0} 释放磁盘空间: {1}', cleanSuccessWithSpace: '操作成功本次清理数量: {0} 释放磁盘空间: {1}',
container: '容器', container: '容器',
unExposedPort: '当前端口映射地址为 127.0.0.1无法实现外部访问',
upTime: '运行时长', upTime: '运行时长',
all: '全部', all: '全部',
fetch: '过滤', fetch: '过滤',
@ -621,6 +623,8 @@ const message = {
startIn: '中开启', startIn: '中开启',
}, },
cronjob: { cronjob: {
create: '创建计划任务',
edit: '编辑计划任务',
cronTask: '计划任务', cronTask: '计划任务',
changeStatus: '状态修改', changeStatus: '状态修改',
disableMsg: '停止计划任务会导致该任务不再自动执行是否继续', disableMsg: '停止计划任务会导致该任务不再自动执行是否继续',
@ -904,7 +908,7 @@ const message = {
sessionTimeoutError: '最小超时时间为 300 ', sessionTimeoutError: '最小超时时间为 300 ',
sessionTimeoutHelper: '如果用户超过 {0} 秒未操作面板面板将自动退出登录', sessionTimeoutHelper: '如果用户超过 {0} 秒未操作面板面板将自动退出登录',
systemIP: '服务器 IP', systemIP: '服务器 IP',
systemIPWarning: '请先在面板设置中设置服务器 IP', systemIPWarning: '当前未设置服务器 IP请先在面板设置中设置',
syncTime: '服务器时间', syncTime: '服务器时间',
timeZone: '系统时区', timeZone: '系统时区',
timeZoneChangeHelper: '系统时区修改需要重启服务是否继续', timeZoneChangeHelper: '系统时区修改需要重启服务是否继续',
@ -1412,6 +1416,8 @@ const message = {
acmeHelper: 'Acme 账户用于申请免费证书', acmeHelper: 'Acme 账户用于申请免费证书',
}, },
firewall: { firewall: {
create: '创建规则',
edit: '编辑规则',
notSupport: '未检测到系统防火墙firewalld 或者 ufw请参考官方文档进行安装', notSupport: '未检测到系统防火墙firewalld 或者 ufw请参考官方文档进行安装',
ccDeny: 'CC 防护', ccDeny: 'CC 防护',
ipWhiteList: 'IP 白名单', ipWhiteList: 'IP 白名单',

View File

@ -1,6 +1,4 @@
import { getSettingInfo } from '@/api/modules/setting';
import i18n from '@/lang'; import i18n from '@/lang';
import { MsgError } from './message';
export function deepCopy<T>(obj: any): T { export function deepCopy<T>(obj: any): T {
let newObj: any; let newObj: any;
@ -258,16 +256,3 @@ export function downloadFile(filePath: string) {
let url = `${import.meta.env.VITE_API_URL as string}/files/download?`; let url = `${import.meta.env.VITE_API_URL as string}/files/download?`;
window.open(url + 'path=' + filePath, '_blank'); window.open(url + 'path=' + filePath, '_blank');
} }
export async function JumpDashboard(port: any) {
if (Number(port) === 0) {
MsgError(i18n.global.t('setting.errPort'));
return;
}
const res = await getSettingInfo();
if (!res.data.systemIP) {
MsgError(i18n.global.t('setting.systemIPWarning'));
return;
}
window.open(`http://${res.data.systemIP}:${port}`, '_blank');
}

View File

@ -193,7 +193,7 @@
<el-tag <el-tag
class="middle-center" class="middle-center"
v-if="installed.httpPort > 0" v-if="installed.httpPort > 0"
@click="JumpDashboard(installed.httpPort)" @click="goDashboard(installed.httpPort)"
> >
<el-icon class="middle-center"><Position /></el-icon> <el-icon class="middle-center"><Position /></el-icon>
{{ $t('app.busPort') }}{{ installed.httpPort }} {{ $t('app.busPort') }}{{ installed.httpPort }}
@ -239,6 +239,8 @@
<AppDelete ref="deleteRef" @close="search" /> <AppDelete ref="deleteRef" @close="search" />
<AppParams ref="appParamRef" /> <AppParams ref="appParamRef" />
<AppUpgrade ref="upgradeRef" @close="search" /> <AppUpgrade ref="upgradeRef" @close="search" />
<PortJumpDialog ref="dialogPortJumpRef" />
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -254,6 +256,7 @@ import i18n from '@/lang';
import { ElMessageBox } from 'element-plus'; import { ElMessageBox } from 'element-plus';
import Backups from '@/components/backup/index.vue'; import Backups from '@/components/backup/index.vue';
import Uploads from '@/components/upload/index.vue'; import Uploads from '@/components/upload/index.vue';
import PortJumpDialog from '@/components/port-jump/index.vue';
import AppResources from './check/index.vue'; import AppResources from './check/index.vue';
import AppDelete from './delete/index.vue'; import AppDelete from './delete/index.vue';
import AppParams from './detail/index.vue'; import AppParams from './detail/index.vue';
@ -264,7 +267,6 @@ import { getAge } from '@/utils/util';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { toFolder } from '@/global/business'; import { toFolder } from '@/global/business';
import { JumpDashboard } from '@/utils/util';
const data = ref<any>(); const data = ref<any>();
const loading = ref(false); const loading = ref(false);
@ -287,6 +289,7 @@ const checkRef = ref();
const deleteRef = ref(); const deleteRef = ref();
const appParamRef = ref(); const appParamRef = ref();
const upgradeRef = ref(); const upgradeRef = ref();
const dialogPortJumpRef = ref();
const tags = ref<App.Tag[]>([]); const tags = ref<App.Tag[]>([]);
const activeTag = ref('all'); const activeTag = ref('all');
const searchReq = reactive({ const searchReq = reactive({
@ -338,6 +341,10 @@ const search = () => {
}); });
}; };
const goDashboard = async (port: any) => {
dialogPortJumpRef.value.acceptParams({ port: port });
};
const openOperate = (row: any, op: string) => { const openOperate = (row: any, op: string) => {
operateReq.installId = row.id; operateReq.installId = row.id;
operateReq.operate = op; operateReq.operate = op;

View File

@ -10,7 +10,7 @@
<el-row> <el-row>
<el-col :xs="24" :sm="16" :md="16" :lg="16" :xl="16"> <el-col :xs="24" :sm="16" :md="16" :lg="16" :xl="16">
<el-button type="primary" @click="onOpenDialog('create')"> <el-button type="primary" @click="onOpenDialog('create')">
{{ $t('container.createContainer') }} {{ $t('container.create') }}
</el-button> </el-button>
<el-button type="primary" plain @click="onClean()"> <el-button type="primary" plain @click="onClean()">
{{ $t('container.containerPrune') }} {{ $t('container.containerPrune') }}
@ -80,18 +80,19 @@
<Status :key="row.state" :status="row.state"></Status> <Status :key="row.state" :status="row.state"></Status>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('container.source')" show-overflow-tooltip min-width="125" fix> <el-table-column :label="$t('container.source')" show-overflow-tooltip min-width="75" fix>
<template #default="{ row }"> <template #default="{ row }">
CPU: {{ row.cpuPercent.toFixed(2) }}% {{ $t('monitor.memory') }}: <div>CPU: {{ row.cpuPercent.toFixed(2) }}%</div>
{{ row.memoryPercent.toFixed(2) }}% <div>{{ $t('monitor.memory') }}: {{ row.memoryPercent.toFixed(2) }}%</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('commons.table.port')" min-width="80" prop="ports" fix> <el-table-column :label="$t('commons.table.port')" min-width="120" prop="ports" fix>
<template #default="{ row }"> <template #default="{ row }">
<div v-if="row.ports"> <div v-if="row.ports">
<div v-for="(item, index) in row.ports" :key="index"> <div v-for="(item, index) in row.ports" :key="index">
<div v-if="row.expand || (!row.expand && index < 3)"> <div v-if="row.expand || (!row.expand && index < 3)">
<el-button <el-button
v-if="item.indexOf('->') !== -1"
@click="goDashboard(item)" @click="goDashboard(item)"
class="tagMargin" class="tagMargin"
icon="Position" icon="Position"
@ -101,6 +102,9 @@
> >
{{ item }} {{ item }}
</el-button> </el-button>
<el-button v-else class="tagMargin" type="primary" plain size="small">
{{ item }}
</el-button>
</div> </div>
</div> </div>
<div v-if="!row.expand && row.ports.length > 3"> <div v-if="!row.expand && row.ports.length > 3">
@ -137,6 +141,8 @@
<UpgraeDialog @search="search" ref="dialogUpgradeRef" /> <UpgraeDialog @search="search" ref="dialogUpgradeRef" />
<MonitorDialog ref="dialogMonitorRef" /> <MonitorDialog ref="dialogMonitorRef" />
<TerminalDialog ref="dialogTerminalRef" /> <TerminalDialog ref="dialogTerminalRef" />
<PortJumpDialog ref="dialogPortJumpRef" />
</div> </div>
</template> </template>
@ -150,6 +156,7 @@ import MonitorDialog from '@/views/container/container/monitor/index.vue';
import ContainerLogDialog from '@/views/container/container/log/index.vue'; import ContainerLogDialog from '@/views/container/container/log/index.vue';
import TerminalDialog from '@/views/container/container/terminal/index.vue'; import TerminalDialog from '@/views/container/container/terminal/index.vue';
import CodemirrorDialog from '@/components/codemirror-dialog/index.vue'; import CodemirrorDialog from '@/components/codemirror-dialog/index.vue';
import PortJumpDialog from '@/components/port-jump/index.vue';
import Status from '@/components/status/index.vue'; import Status from '@/components/status/index.vue';
import { reactive, onMounted, ref } from 'vue'; import { reactive, onMounted, ref } from 'vue';
import { import {
@ -164,8 +171,8 @@ import { Container } from '@/api/interface/container';
import { ElMessageBox } from 'element-plus'; import { ElMessageBox } from 'element-plus';
import i18n from '@/lang'; import i18n from '@/lang';
import router from '@/routers'; import router from '@/routers';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess, MsgWarning } from '@/utils/message';
import { JumpDashboard, computeSize } from '@/utils/util'; import { computeSize } from '@/utils/util';
const loading = ref(); const loading = ref();
const data = ref(); const data = ref();
@ -177,6 +184,7 @@ const paginationConfig = reactive({
}); });
const searchName = ref(); const searchName = ref();
const dialogUpgradeRef = ref(); const dialogUpgradeRef = ref();
const dialogPortJumpRef = ref();
const dockerStatus = ref('Running'); const dockerStatus = ref('Running');
const loadStatus = async () => { const loadStatus = async () => {
@ -196,11 +204,16 @@ const loadStatus = async () => {
}; };
const goDashboard = async (port: any) => { const goDashboard = async (port: any) => {
if (!port || port.indexOf(':') === -1) { if (port.indexOf('127.0.0.1') !== -1) {
MsgWarning(i18n.global.t('container.unExposedPort'));
return; return;
} }
let portEx = port.split(':')[0]; if (!port || port.indexOf(':') === -1 || port.indexOf('->') === -1) {
JumpDashboard(portEx); MsgWarning(i18n.global.t('commons.msg.errPort'));
return;
}
let portEx = port.match(/:(\d+)/)[1];
dialogPortJumpRef.value.acceptParams({ port: portEx });
}; };
const goSetting = async () => { const goSetting = async () => {

View File

@ -1,7 +1,7 @@
<template> <template>
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%"> <el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header> <template #header>
<DrawerHeader :header="$t('container.createContainer')" :back="handleClose" /> <DrawerHeader :header="title" :back="handleClose" />
</template> </template>
<el-form <el-form
ref="formRef" ref="formRef"
@ -242,7 +242,7 @@ const dialogData = ref<DialogProps>({
}); });
const acceptParams = (params: DialogProps): void => { const acceptParams = (params: DialogProps): void => {
dialogData.value = params; dialogData.value = params;
title.value = i18n.global.t('commons.button.' + dialogData.value.title); title.value = i18n.global.t('container.' + dialogData.value.title);
if (params.title === 'edit') { if (params.title === 'edit') {
dialogData.value.rowData.memoryItem = Number((dialogData.value.rowData.memory / 1024 / 1024).toFixed(2)); dialogData.value.rowData.memoryItem = Number((dialogData.value.rowData.memory / 1024 / 1024).toFixed(2));
let itemCmd = ''; let itemCmd = '';
@ -277,7 +277,7 @@ const handleClose = () => {
}; };
const rules = reactive({ const rules = reactive({
cpuShares: [Rules.number, checkNumberRange(2, 262144)], cpuShares: [Rules.number, checkNumberRange(0, 262144)],
name: [Rules.requiredInput, Rules.name], name: [Rules.requiredInput, Rules.name],
image: [Rules.requiredSelect], image: [Rules.requiredSelect],
nanoCPUs: [Rules.number], nanoCPUs: [Rules.number],

View File

@ -1,7 +1,7 @@
<template> <template>
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%"> <el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header> <template #header>
<DrawerHeader :header="$t('cronjob.cronTask')" :resource="dialogData.rowData?.name" :back="handleClose" /> <DrawerHeader :header="title" :resource="dialogData.rowData?.name" :back="handleClose" />
</template> </template>
<el-form ref="formRef" label-position="top" :model="dialogData.rowData" :rules="rules"> <el-form ref="formRef" label-position="top" :model="dialogData.rowData" :rules="rules">
<el-row type="flex" justify="center"> <el-row type="flex" justify="center">
@ -238,7 +238,7 @@ const acceptParams = (params: DialogProps): void => {
if (dialogData.value.title === 'create') { if (dialogData.value.title === 'create') {
changeType(); changeType();
} }
title.value = i18n.global.t('commons.button.' + dialogData.value.title); title.value = i18n.global.t('cronjob.' + dialogData.value.title);
if (dialogData.value?.rowData?.exclusionRules) { if (dialogData.value?.rowData?.exclusionRules) {
dialogData.value.rowData.exclusionRules = dialogData.value.rowData.exclusionRules.replaceAll(',', '\n'); dialogData.value.rowData.exclusionRules = dialogData.value.rowData.exclusionRules.replaceAll(',', '\n');
} }

View File

@ -141,6 +141,8 @@
<AppResources ref="checkRef"></AppResources> <AppResources ref="checkRef"></AppResources>
<DeleteDialog ref="deleteRef" @search="search" /> <DeleteDialog ref="deleteRef" @search="search" />
<PortJumpDialog ref="dialogPortJumpRef" />
</div> </div>
</template> </template>
@ -155,7 +157,8 @@ import Setting from '@/views/database/mysql/setting/index.vue';
import AppStatus from '@/components/app-status/index.vue'; import AppStatus from '@/components/app-status/index.vue';
import Backups from '@/components/backup/index.vue'; import Backups from '@/components/backup/index.vue';
import UploadDialog from '@/components/upload/index.vue'; import UploadDialog from '@/components/upload/index.vue';
import { JumpDashboard, dateFormat } from '@/utils/util'; import PortJumpDialog from '@/components/port-jump/index.vue';
import { dateFormat } from '@/utils/util';
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import { deleteCheckMysqlDB, loadRemoteAccess, searchMysqlDBs, updateMysqlDescription } from '@/api/modules/database'; import { deleteCheckMysqlDB, loadRemoteAccess, searchMysqlDBs, updateMysqlDescription } from '@/api/modules/database';
import i18n from '@/lang'; import i18n from '@/lang';
@ -179,6 +182,8 @@ const deleteRef = ref();
const phpadminPort = ref(); const phpadminPort = ref();
const phpVisiable = ref(false); const phpVisiable = ref(false);
const dialogPortJumpRef = ref();
const data = ref(); const data = ref();
const paginationConfig = reactive({ const paginationConfig = reactive({
currentPage: 1, currentPage: 1,
@ -264,7 +269,7 @@ const goDashboard = async () => {
phpVisiable.value = true; phpVisiable.value = true;
return; return;
} }
JumpDashboard(phpadminPort.value); dialogPortJumpRef.value.acceptParams({ port: phpadminPort.value });
}; };
const getAppDetail = (key: string) => { const getAppDetail = (key: string) => {

View File

@ -53,6 +53,8 @@
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
<PortJumpDialog ref="dialogPortJumpRef" />
</div> </div>
</template> </template>
@ -61,13 +63,11 @@ import Setting from '@/views/database/redis/setting/index.vue';
import Password from '@/views/database/redis/password/index.vue'; import Password from '@/views/database/redis/password/index.vue';
import Terminal from '@/components/terminal/index.vue'; import Terminal from '@/components/terminal/index.vue';
import AppStatus from '@/components/app-status/index.vue'; import AppStatus from '@/components/app-status/index.vue';
import PortJumpDialog from '@/components/port-jump/index.vue';
import { nextTick, onBeforeUnmount, ref } from 'vue'; import { nextTick, onBeforeUnmount, ref } from 'vue';
import { App } from '@/api/interface/app'; import { App } from '@/api/interface/app';
import { GetAppPort } from '@/api/modules/app'; import { GetAppPort } from '@/api/modules/app';
import router from '@/routers'; import router from '@/routers';
import { MsgError } from '@/utils/message';
import { getSettingInfo } from '@/api/modules/setting';
import i18n from '@/lang';
const loading = ref(false); const loading = ref(false);
const maskShow = ref(true); const maskShow = ref(true);
@ -83,6 +83,8 @@ const terminalShow = ref(false);
const redisCommandPort = ref(); const redisCommandPort = ref();
const commandVisiable = ref(false); const commandVisiable = ref(false);
const dialogPortJumpRef = ref();
const isRefresh = ref(); const isRefresh = ref();
const onSetting = async () => { const onSetting = async () => {
@ -97,12 +99,7 @@ const goDashboard = async () => {
commandVisiable.value = true; commandVisiable.value = true;
return; return;
} }
const res = await getSettingInfo(); dialogPortJumpRef.value.acceptParams({ port: redisCommandPort.value });
if (!res.data.systemIP) {
MsgError(i18n.global.t('setting.systemIPWarning'));
return;
}
window.open(`http://${res.data.systemIP}:${redisCommandPort.value}`, '_blank');
}; };
const getAppDetail = (key: string) => { const getAppDetail = (key: string) => {
router.push({ name: 'AppDetail', params: { appKey: key } }); router.push({ name: 'AppDetail', params: { appKey: key } });

View File

@ -1,7 +1,7 @@
<template> <template>
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%"> <el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header> <template #header>
<DrawerHeader :header="$t('firewall.ipRule')" :back="handleClose" /> <DrawerHeader :header="title" :back="handleClose" />
</template> </template>
<div v-loading="loading"> <div v-loading="loading">
<el-form ref="formRef" label-position="top" :model="dialogData.rowData" :rules="rules"> <el-form ref="formRef" label-position="top" :model="dialogData.rowData" :rules="rules">
@ -68,7 +68,7 @@ const acceptParams = (params: DialogProps): void => {
if (dialogData.value.title === 'edit') { if (dialogData.value.title === 'edit') {
oldRule.value = deepCopy(params.rowData); oldRule.value = deepCopy(params.rowData);
} }
title.value = i18n.global.t('commons.button.' + dialogData.value.title); title.value = i18n.global.t('firewall.' + dialogData.value.title);
drawerVisiable.value = true; drawerVisiable.value = true;
}; };
const emit = defineEmits<{ (e: 'search'): void }>(); const emit = defineEmits<{ (e: 'search'): void }>();

View File

@ -1,7 +1,7 @@
<template> <template>
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%"> <el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header> <template #header>
<DrawerHeader :header="$t('firewall.portRule')" :back="handleClose" /> <DrawerHeader :header="title" :back="handleClose" />
</template> </template>
<div v-loading="loading"> <div v-loading="loading">
<el-form ref="formRef" label-position="top" :model="dialogData.rowData" :rules="rules"> <el-form ref="formRef" label-position="top" :model="dialogData.rowData" :rules="rules">
@ -98,7 +98,7 @@ const acceptParams = (params: DialogProps): void => {
} }
oldRule.value = deepCopy(params.rowData); oldRule.value = deepCopy(params.rowData);
} }
title.value = i18n.global.t('commons.button.' + dialogData.value.title); title.value = i18n.global.t('firewall.' + dialogData.value.title);
drawerVisiable.value = true; drawerVisiable.value = true;
}; };
const emit = defineEmits<{ (e: 'search'): void }>(); const emit = defineEmits<{ (e: 'search'): void }>();