mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-09-12 17:46:20 +08:00
feat: The application installation jumps to the script library (#8317)
This commit is contained in:
parent
fdf95297a5
commit
949e3c25a7
18 changed files with 69 additions and 154 deletions
|
@ -48,8 +48,9 @@ func (u *FirewallService) LoadBaseInfo() (dto.FirewallBaseInfo, error) {
|
|||
baseInfo.Name = "-"
|
||||
client, err := firewall.NewFirewallClient()
|
||||
if err != nil {
|
||||
global.LOG.Errorf("load firewall failed, err: %v", err)
|
||||
baseInfo.IsExist = false
|
||||
return baseInfo, err
|
||||
return baseInfo, nil
|
||||
}
|
||||
baseInfo.IsExist = true
|
||||
baseInfo.Name = client.Name()
|
||||
|
|
|
@ -199,10 +199,6 @@ ErrConfigDirNotFound: 'The running directory does not exist'
|
|||
ErrConfigAlreadyExist: 'A configuration file with the same name already exists'
|
||||
ErrUserFindErr: 'User {{ .name }} search failed {{ .err }}'
|
||||
|
||||
#ssh
|
||||
ErrFirewallNone: 'No system firewalld or ufw service detected, please check and try again!'
|
||||
ErrFirewallBoth: 'It is detected that the system has both firewalld and ufw services. To avoid conflicts, please uninstall and try again!'
|
||||
|
||||
#cronjob
|
||||
ErrCutWebsiteLog: '{{ .name }} website log cutting failed, error {{ .err }}'
|
||||
CutWebsiteLogSuccess: '{{ .name }} website log cut successfully, backup path {{ .path }}'
|
||||
|
|
|
@ -199,10 +199,6 @@ ErrConfigDirNotFound: '実行ディレクトリが存在しません'
|
|||
ErrConfigAlreadyExist: '同じ名前の設定ファイルがすでに存在します'
|
||||
ErrUserFindErr: 'ユーザー {{ .name }} の検索に失敗しました {{ .err }}'
|
||||
|
||||
#ssh
|
||||
ErrFirewallNone: 'システムのファイアウォールまたは ufw サービスが検出されませんでした。確認してもう一度お試しください。'
|
||||
ErrFirewallBoth: 'システムにfirewalldとufwの両方のサービスがあることが検出されました。競合を避けるため、アンインストールしてもう一度お試しください。'
|
||||
|
||||
#cronjob
|
||||
ErrCutWebsiteLog: '{{ .name }} ウェブサイトのログの切り取りに失敗しました。エラー {{ .err }}'
|
||||
CutWebsiteLogSuccess: '{{ .name }} ウェブサイトのログが正常にカットされました。バックアップ パス {{ .path }}'
|
||||
|
|
|
@ -199,10 +199,6 @@ ErrConfigDirNotFound: '실행 디렉토리가 존재하지 않습니다'
|
|||
ErrConfigAlreadyExist: '같은 이름의 구성 파일이 이미 존재합니다'
|
||||
ErrUserFindErr: '사용자 {{ .name }} 검색에 실패했습니다 {{ .err }}'
|
||||
|
||||
#ssh
|
||||
ErrFirewallNone: '시스템 방화벽이나 ufw 서비스가 감지되지 않았습니다. 확인하고 다시 시도하세요!'
|
||||
ErrFirewallBoth: '시스템에 방화벽과 ufw 서비스가 모두 있는 것으로 감지되었습니다. 충돌을 피하려면 제거한 후 다시 시도하세요!'
|
||||
|
||||
#크론잡
|
||||
ErrCutWebsiteLog: '{{ .name }} 웹사이트 로그 잘라내기에 실패했습니다. 오류 {{ .err }}'
|
||||
CutWebsiteLogSuccess: '{{ .name }} 웹사이트 로그가 성공적으로 잘렸습니다. 백업 경로 {{ .path }}'
|
||||
|
|
|
@ -199,10 +199,6 @@ ErrConfigDirNotFound: 'Direktori berjalan tidak wujud'
|
|||
ErrConfigAlreadyExist: 'Fail konfigurasi dengan nama yang sama sudah wujud'
|
||||
ErrUserFindErr: 'Pengguna {{ .name }} carian gagal {{ .err }}'
|
||||
|
||||
#ssh
|
||||
ErrFirewallNone: 'Tiada sistem firewalld atau perkhidmatan ufw dikesan, sila semak dan cuba lagi!'
|
||||
ErrFirewallBoth: 'Telah dikesan bahawa sistem mempunyai perkhidmatan firewalld dan ufw. Untuk mengelakkan konflik, sila nyahpasang dan cuba lagi!'
|
||||
|
||||
#cronjob
|
||||
ErrCutWebsiteLog: '{{ .name }} pemotongan log tapak web gagal, ralat {{ .err }}'
|
||||
CutWebsiteLogSuccess: '{{ .name }} log tapak web berjaya dipotong, laluan sandaran {{ .path }}'
|
||||
|
|
|
@ -199,10 +199,6 @@ ErrConfigDirNotFound: 'O diretório de execução não existe'
|
|||
ErrConfigAlreadyExist: 'Um arquivo de configuração com o mesmo nome já existe'
|
||||
ErrUserFindErr: 'Falha na pesquisa do usuário {{ .name }} {{ .err }}'
|
||||
|
||||
#ssh
|
||||
ErrFirewallNone: 'Nenhum firewall de sistema ou serviço ufw detectado, verifique e tente novamente!'
|
||||
ErrFirewallBoth: 'Foi detectado que o sistema possui serviços firewalld e ufw. Para evitar conflitos, desinstale e tente novamente!'
|
||||
|
||||
#cronjob
|
||||
ErrCutWebsiteLog: '{{ .name }} falha ao cortar o log do site, erro {{ .err }}'
|
||||
CutWebsiteLogSuccess: '{{ .name }} registro do site cortado com sucesso, caminho de backup {{ .path }}'
|
||||
|
|
|
@ -199,10 +199,6 @@ ErrConfigDirNotFound: 'Рабочий каталог не существует'
|
|||
ErrConfigAlreadyExist: 'Файл конфигурации с таким именем уже существует'
|
||||
ErrUserFindErr: 'Поиск пользователя {{ .name }} не удался {{ .err }}'
|
||||
|
||||
#ссш
|
||||
ErrFirewallNone: 'Системные службы firewalld или ufw не обнаружены. Проверьте и повторите попытку!'
|
||||
ErrFirewallBoth: 'Обнаружено, что в системе есть службы firewalld и ufw. Чтобы избежать конфликтов, удалите их и повторите попытку!'
|
||||
|
||||
#cronjob
|
||||
ErrCutWebsiteLog: '{{ .name }} не удалось вырезать журнал веб-сайта, ошибка {{ .err }}'
|
||||
CutWebsiteLogSuccess: 'Журнал веб-сайта {{ .name }} успешно вырезан, путь к резервной копии {{ .path }}'
|
||||
|
|
|
@ -199,10 +199,6 @@ ErrConfigDirNotFound: '運行目錄不存在'
|
|||
ErrConfigAlreadyExist: '已存在同名設定檔'
|
||||
ErrUserFindErr: '使用者{{ .name }} 尋找失敗{{ .err }}'
|
||||
|
||||
#ssh
|
||||
ErrFirewallNone: '未偵測到系統firewalld 或ufw 服務,請檢查後重試!'
|
||||
ErrFirewallBoth: '偵測到系統同時存在firewalld 或ufw 服務,為避免衝突,請卸載後重試!'
|
||||
|
||||
#cronjob
|
||||
ErrCutWebsiteLog: '{{ .name }} 網站日誌切割失敗,錯誤{{ .err }}'
|
||||
CutWebsiteLogSuccess: '{{ .name }} 網站日誌切割成功,備份路徑{{ .path }}'
|
||||
|
|
|
@ -200,10 +200,6 @@ ErrConfigDirNotFound: "运行目录不存在"
|
|||
ErrConfigAlreadyExist: "已存在同名配置文件"
|
||||
ErrUserFindErr: "用户 {{ .name }} 查找失败 {{ .err }}"
|
||||
|
||||
#ssh
|
||||
ErrFirewallNone: "未检测到系统 firewalld 或 ufw 服务,请检查后重试!"
|
||||
ErrFirewallBoth: "检测到系统同时存在 firewalld 或 ufw 服务,为避免冲突,请卸载后重试!"
|
||||
|
||||
#cronjob
|
||||
ErrCutWebsiteLog: "{{ .name }} 网站日志切割失败,错误 {{ .err }}"
|
||||
CutWebsiteLogSuccess: "{{ .name }} 网站日志切割成功,备份路径 {{ .path }}"
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package firewall
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/agent/buserr"
|
||||
"errors"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/firewall/client"
|
||||
)
|
||||
|
@ -12,7 +13,7 @@ type FirewallClient interface {
|
|||
Stop() error
|
||||
Restart() error
|
||||
Reload() error
|
||||
Status() (bool, error) // running not running
|
||||
Status() (bool, error)
|
||||
Version() (string, error)
|
||||
|
||||
ListPort() ([]client.FireInfo, error)
|
||||
|
@ -31,7 +32,7 @@ func NewFirewallClient() (FirewallClient, error) {
|
|||
ufw := cmd.Which("ufw")
|
||||
|
||||
if firewalld && ufw {
|
||||
return nil, buserr.New("ErrFirewallBoth")
|
||||
return nil, errors.New("It is detected that the system has both firewalld and ufw services. To avoid conflicts, please uninstall and try again!")
|
||||
}
|
||||
|
||||
if firewalld {
|
||||
|
@ -40,5 +41,5 @@ func NewFirewallClient() (FirewallClient, error) {
|
|||
if ufw {
|
||||
return client.NewUfw()
|
||||
}
|
||||
return nil, buserr.New("ErrFirewallNone")
|
||||
return nil, errors.New("No system firewalld or ufw service detected, please check and try again!")
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
<div v-loading="loading">
|
||||
<FireStatus
|
||||
v-show="fireName !== '-'"
|
||||
ref="fireStatusRef"
|
||||
@search="search"
|
||||
v-model:loading="loading"
|
||||
|
@ -55,24 +54,6 @@
|
|||
</template>
|
||||
</LayoutContent>
|
||||
</div>
|
||||
<div v-else>
|
||||
<LayoutContent :title="$t('menu.firewall')" :divider="true">
|
||||
<template #main>
|
||||
<div class="app-warn">
|
||||
<div class="flex flex-col gap-2 items-center justify-center w-full sm:flex-row">
|
||||
<span>{{ $t('firewall.notSupport') }}</span>
|
||||
<span @click="toDoc" class="flex items-center justify-center gap-0.5">
|
||||
<el-icon><Position /></el-icon>
|
||||
{{ $t('firewall.quickJump') }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<img src="@/assets/images/no_app.svg" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</LayoutContent>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<OpDialog ref="opRef" @search="search" @submit="onSubmitDelete()">
|
||||
|
@ -99,9 +80,7 @@ import { onMounted, reactive, ref } from 'vue';
|
|||
import { operateForwardRule, searchFireRule } from '@/api/modules/host';
|
||||
import { Host } from '@/api/interface/host';
|
||||
import i18n from '@/lang';
|
||||
import { GlobalStore } from '@/store';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
const loading = ref();
|
||||
const activeTag = ref('forward');
|
||||
|
@ -170,9 +149,6 @@ const onOpenDialog = async (
|
|||
};
|
||||
dialogRef.value!.acceptParams(params);
|
||||
};
|
||||
const toDoc = () => {
|
||||
window.open(globalStore.docsUrl + '/user_manual/hosts/firewall/', '_blank', 'noopener,noreferrer');
|
||||
};
|
||||
const onDelete = async (row: Host.RuleForward | null) => {
|
||||
let names = [];
|
||||
let rules = [];
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
<div v-loading="loading">
|
||||
<FireStatus
|
||||
v-show="fireName !== '-'"
|
||||
ref="fireStatusRef"
|
||||
@search="search"
|
||||
v-model:loading="loading"
|
||||
|
@ -89,24 +88,6 @@
|
|||
</template>
|
||||
</LayoutContent>
|
||||
</div>
|
||||
<div v-else>
|
||||
<LayoutContent :title="$t('menu.firewall')" :divider="true">
|
||||
<template #main>
|
||||
<div class="app-warn">
|
||||
<div class="flex flex-col gap-2 items-center justify-center w-full sm:flex-row">
|
||||
<span>{{ $t('firewall.notSupport') }}</span>
|
||||
<span @click="toDoc" class="flex items-center justify-center gap-0.5">
|
||||
<el-icon><Position /></el-icon>
|
||||
{{ $t('firewall.quickJump') }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<img src="@/assets/images/no_app.svg" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</LayoutContent>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<OpDialog ref="opRef" @search="search" />
|
||||
|
@ -124,8 +105,6 @@ import { Host } from '@/api/interface/host';
|
|||
import { ElMessageBox } from 'element-plus';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { GlobalStore } from '@/store';
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
const loading = ref();
|
||||
const activeTag = ref('address');
|
||||
|
@ -189,10 +168,6 @@ const onOpenDialog = async (
|
|||
dialogRef.value!.acceptParams(params);
|
||||
};
|
||||
|
||||
const toDoc = () => {
|
||||
window.open(globalStore.docsUrl + '/user_manual/hosts/firewall/', '_blank', 'noopener,noreferrer');
|
||||
};
|
||||
|
||||
const onChange = async (info: any) => {
|
||||
info.type = 'address';
|
||||
await updateFirewallDescription(info);
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
<div v-loading="loading">
|
||||
<FireStatus
|
||||
v-show="fireName !== '-'"
|
||||
ref="fireStatusRef"
|
||||
@search="search"
|
||||
v-model:loading="loading"
|
||||
|
@ -139,24 +138,6 @@
|
|||
</template>
|
||||
</LayoutContent>
|
||||
</div>
|
||||
<div v-else>
|
||||
<LayoutContent :title="$t('menu.firewall')" :divider="true">
|
||||
<template #main>
|
||||
<div class="app-warn">
|
||||
<div class="flex flex-col gap-2 items-center justify-center w-full sm:flex-row">
|
||||
<span>{{ $t('firewall.notSupport') }}</span>
|
||||
<span @click="toDoc" class="flex items-center justify-center gap-0.5">
|
||||
<el-icon><Position /></el-icon>
|
||||
{{ $t('firewall.quickJump') }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<img src="@/assets/images/no_app.svg" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</LayoutContent>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<OpDialog ref="opRef" @search="search" />
|
||||
|
@ -175,8 +156,6 @@ import i18n from '@/lang';
|
|||
import { MsgSuccess } from '@/utils/message';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import router from '@/routers';
|
||||
import { GlobalStore } from '@/store';
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
const loading = ref();
|
||||
const activeTag = ref('port');
|
||||
|
@ -249,9 +228,6 @@ const onOpenDialog = async (
|
|||
const quickJump = () => {
|
||||
router.push({ name: 'AppInstalled' });
|
||||
};
|
||||
const toDoc = () => {
|
||||
window.open(globalStore.docsUrl + '/user_manual/hosts/firewall/', '_blank', 'noopener,noreferrer');
|
||||
};
|
||||
|
||||
const onChangeStatus = async (row: Host.RuleInfo, status: string) => {
|
||||
let operation =
|
||||
|
|
|
@ -1,40 +1,56 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="app-status" style="margin-top: 20px">
|
||||
<el-card>
|
||||
<div class="flex w-full flex-col gap-4 md:flex-row">
|
||||
<div class="flex flex-wrap gap-4">
|
||||
<el-tag effect="dark" type="success">{{ baseInfo.name }}</el-tag>
|
||||
<Status class="mt-0.5" :status="baseInfo.isActive ? 'enable' : 'disable'" />
|
||||
<el-tag>{{ $t('app.version') }}: {{ baseInfo.version }}</el-tag>
|
||||
</div>
|
||||
<div class="mt-0.5">
|
||||
<el-button type="primary" v-if="baseInfo.isActive" @click="onOperate('stop')" link>
|
||||
{{ $t('commons.button.stop') }}
|
||||
</el-button>
|
||||
<el-button type="primary" v-if="!baseInfo.isActive" @click="onOperate('start')" link>
|
||||
{{ $t('commons.button.start') }}
|
||||
</el-button>
|
||||
<div class="app-status" style="margin-top: 20px" v-if="baseInfo.isExist">
|
||||
<el-card>
|
||||
<div class="flex w-full flex-col gap-4 md:flex-row">
|
||||
<div class="flex flex-wrap gap-4">
|
||||
<el-tag effect="dark" type="success">{{ baseInfo.name }}</el-tag>
|
||||
<Status class="mt-0.5" :status="baseInfo.isActive ? 'enable' : 'disable'" />
|
||||
<el-tag>{{ $t('app.version') }}: {{ baseInfo.version }}</el-tag>
|
||||
</div>
|
||||
<div class="mt-0.5">
|
||||
<el-button type="primary" v-if="baseInfo.isActive" @click="onOperate('stop')" link>
|
||||
{{ $t('commons.button.stop') }}
|
||||
</el-button>
|
||||
<el-button type="primary" v-if="!baseInfo.isActive" @click="onOperate('start')" link>
|
||||
{{ $t('commons.button.start') }}
|
||||
</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button type="primary" @click="onOperate('restart')" link>
|
||||
{{ $t('commons.button.restart') }}
|
||||
</el-button>
|
||||
<span v-if="onPing !== 'None'">
|
||||
<el-divider direction="vertical" />
|
||||
<el-button type="primary" @click="onOperate('restart')" link>
|
||||
{{ $t('commons.button.restart') }}
|
||||
</el-button>
|
||||
<span v-if="onPing !== 'None'">
|
||||
<el-divider direction="vertical" />
|
||||
<el-button type="primary" link>{{ $t('firewall.noPing') }}</el-button>
|
||||
<el-switch
|
||||
size="small"
|
||||
class="ml-2"
|
||||
inactive-value="Disable"
|
||||
active-value="Enable"
|
||||
@change="onPingOperate"
|
||||
v-model="onPing"
|
||||
/>
|
||||
<el-button type="primary" link>{{ $t('firewall.noPing') }}</el-button>
|
||||
<el-switch
|
||||
size="small"
|
||||
class="ml-2"
|
||||
inactive-value="Disable"
|
||||
active-value="Enable"
|
||||
@change="onPingOperate"
|
||||
v-model="onPing"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
<div v-if="!baseInfo.isExist">
|
||||
<LayoutContent :title="$t('menu.firewall')" :divider="true">
|
||||
<template #main>
|
||||
<div class="app-warn">
|
||||
<div class="flex flex-col gap-2 items-center justify-center w-full sm:flex-row">
|
||||
<span>{{ $t('firewall.notSupport') }}</span>
|
||||
<span @click="toDoc" class="flex items-center justify-center gap-0.5">
|
||||
<el-icon><Position /></el-icon>
|
||||
{{ $t('firewall.quickJump') }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<img src="@/assets/images/no_app.svg" />
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
</LayoutContent>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -42,6 +58,7 @@
|
|||
import { Host } from '@/api/interface/host';
|
||||
import { loadFireBaseInfo, operateFire } from '@/api/modules/host';
|
||||
import i18n from '@/lang';
|
||||
import router from '@/routers';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { ref } from 'vue';
|
||||
|
@ -55,6 +72,10 @@ const acceptParams = (): void => {
|
|||
};
|
||||
const emit = defineEmits(['search', 'update:is-active', 'update:loading', 'update:maskShow', 'update:name']);
|
||||
|
||||
const toDoc = () => {
|
||||
router.push({ name: 'Library' });
|
||||
};
|
||||
|
||||
const loadBaseInfo = async (search: boolean) => {
|
||||
await loadFireBaseInfo()
|
||||
.then((res) => {
|
||||
|
|
|
@ -240,8 +240,9 @@ const getStatus = (status: any) => {
|
|||
const toFolder = (folder: string) => {
|
||||
router.push({ path: '/hosts/files', query: { path: folder } });
|
||||
};
|
||||
const toDoc = async () => {
|
||||
window.open(globalStore.docsUrl + '/user_manual/toolbox/clam/', '_blank', 'noopener,noreferrer');
|
||||
|
||||
const toDoc = () => {
|
||||
router.push({ name: 'Library' });
|
||||
};
|
||||
|
||||
const onChange = async (row: any) => {
|
||||
|
|
|
@ -173,8 +173,7 @@ import { MsgSuccess } from '@/utils/message';
|
|||
import { getFail2banConf, getFail2banBase, operateFail2ban, updateFail2banByFile } from '@/api/modules/toolbox';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { transTimeUnit } from '@/utils/util';
|
||||
import { GlobalStore } from '@/store';
|
||||
const globalStore = GlobalStore();
|
||||
import router from '@/routers';
|
||||
|
||||
const loading = ref(false);
|
||||
const formRef = ref();
|
||||
|
@ -212,7 +211,7 @@ const onLoadList = async (type: string) => {
|
|||
};
|
||||
|
||||
const toDoc = () => {
|
||||
window.open(globalStore.docsUrl + '/user_manual/toolbox/fail2ban/', '_blank', 'noopener,noreferrer');
|
||||
router.push({ name: 'Library' });
|
||||
};
|
||||
|
||||
const onSaveFile = async () => {
|
||||
|
|
|
@ -163,8 +163,6 @@ import OperateDialog from '@/views/toolbox/ftp/operate/index.vue';
|
|||
import LogDialog from '@/views/toolbox/ftp/log/index.vue';
|
||||
import { Toolbox } from '@/api/interface/toolbox';
|
||||
import router from '@/routers';
|
||||
import { GlobalStore } from '@/store';
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
const loading = ref();
|
||||
const selects = ref<any>([]);
|
||||
|
@ -219,7 +217,7 @@ const search = async (column?: any) => {
|
|||
};
|
||||
|
||||
const toDoc = () => {
|
||||
window.open(globalStore.docsUrl + '/user_manual/toolbox/ftp/', '_blank', 'noopener,noreferrer');
|
||||
router.push({ name: 'Library' });
|
||||
};
|
||||
|
||||
const toFolder = (folder: string) => {
|
||||
|
|
|
@ -71,8 +71,7 @@ import i18n from '@/lang';
|
|||
import { MsgSuccess } from '@/utils/message';
|
||||
import { HostTool } from '@/api/interface/host-tool';
|
||||
import InitPage from './init/index.vue';
|
||||
import { GlobalStore } from '@/store';
|
||||
const globalStore = GlobalStore();
|
||||
import router from '@/routers';
|
||||
|
||||
let operateReq = reactive({
|
||||
installId: 0,
|
||||
|
@ -96,8 +95,8 @@ const setting = () => {
|
|||
em('setting', true);
|
||||
};
|
||||
|
||||
const toDoc = async () => {
|
||||
window.open(globalStore.docsUrl + '/user_manual/toolbox/supervisor/', '_blank', 'noopener,noreferrer');
|
||||
const toDoc = () => {
|
||||
router.push({ name: 'Library' });
|
||||
};
|
||||
|
||||
const init = async () => {
|
||||
|
|
Loading…
Add table
Reference in a new issue