mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-02-08 09:30:06 +08:00
feat: Support for modifying host information (#7816)
This commit is contained in:
parent
88684c7cf0
commit
6cd72f1a56
@ -266,8 +266,8 @@ func (u *HostService) Create(req dto.HostOperate) (*dto.HostInfo, error) {
|
|||||||
req.GroupID = group.ID
|
req.GroupID = group.ID
|
||||||
}
|
}
|
||||||
var sameHostID uint
|
var sameHostID uint
|
||||||
if req.Addr == "127.0.0.1" {
|
if req.Name == "local" {
|
||||||
hostSame, _ := hostRepo.Get(hostRepo.WithByAddr(req.Addr))
|
hostSame, _ := hostRepo.Get(repo.WithByName("local"))
|
||||||
sameHostID = hostSame.ID
|
sameHostID = hostSame.ID
|
||||||
} else {
|
} else {
|
||||||
hostSame, _ := hostRepo.Get(hostRepo.WithByAddr(req.Addr), hostRepo.WithByUser(req.User), hostRepo.WithByPort(req.Port))
|
hostSame, _ := hostRepo.Get(hostRepo.WithByAddr(req.Addr), hostRepo.WithByUser(req.User), hostRepo.WithByPort(req.Port))
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
system:
|
base:
|
||||||
db_core_file: core.db
|
install_dir: /opt
|
||||||
base_dir: /opt
|
|
||||||
mode: dev
|
mode: dev
|
||||||
repo_url: https://resource.fit2cloud.com/1panel/package
|
|
||||||
app_repo: https://apps-assets.fit2cloud.com
|
|
||||||
is_demo: false
|
is_demo: false
|
||||||
is_intl: false
|
is_intl: false
|
||||||
port: 9999
|
port: 9999
|
||||||
username: admin
|
username: admin
|
||||||
password: admin123
|
password: admin123
|
||||||
|
version: v2.0.0
|
||||||
|
|
||||||
|
remote_url:
|
||||||
|
repo_url: https://resource.fit2cloud.com/1panel/package
|
||||||
|
app_repo: https://apps-assets.fit2cloud.com
|
||||||
|
|
||||||
log:
|
log:
|
||||||
level: debug
|
level: debug
|
||||||
|
@ -37,7 +37,6 @@ type ApiInterface struct {
|
|||||||
|
|
||||||
type RemoteURL struct {
|
type RemoteURL struct {
|
||||||
RepoUrl string `mapstructure:"repo_url"`
|
RepoUrl string `mapstructure:"repo_url"`
|
||||||
ResourceUrl string `mapstructure:"resource_url"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type LogConfig struct {
|
type LogConfig struct {
|
||||||
|
@ -20,6 +20,7 @@ func Init() {
|
|||||||
migrations.AddTaskDB,
|
migrations.AddTaskDB,
|
||||||
migrations.UpdateSettingStatus,
|
migrations.UpdateSettingStatus,
|
||||||
migrations.RemoveLocalBackup,
|
migrations.RemoveLocalBackup,
|
||||||
|
migrations.AddMFAInterval,
|
||||||
})
|
})
|
||||||
if err := m.Migrate(); err != nil {
|
if err := m.Migrate(); err != nil {
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
|
@ -297,3 +297,13 @@ var RemoveLocalBackup = &gormigrate.Migration{
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var AddMFAInterval = &gormigrate.Migration{
|
||||||
|
ID: "20250207-add-mfa-interval",
|
||||||
|
Migrate: func(tx *gorm.DB) error {
|
||||||
|
if err := tx.Create(&model.Setting{Key: "MFAInterval", Value: "30"}).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/lang-json": "^6.0.1",
|
"@codemirror/lang-json": "^6.0.1",
|
||||||
|
"@codemirror/lang-html": "^6.4.9",
|
||||||
|
"@codemirror/lang-php": "^6.0.1",
|
||||||
"@codemirror/language": "^6.10.2",
|
"@codemirror/language": "^6.10.2",
|
||||||
"@codemirror/legacy-modes": "^6.4.0",
|
"@codemirror/legacy-modes": "^6.4.0",
|
||||||
"@codemirror/theme-one-dark": "^6.1.2",
|
"@codemirror/theme-one-dark": "^6.1.2",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<DrawerPro v-model="open" :header="$t('commons.table.group')" size="large" :back="handleClose">
|
<DrawerPro v-model="open" :header="$t('commons.table.group')" size="large" :back="handleClose">
|
||||||
<template #content>
|
<template #content>
|
||||||
<ComplexTable :data="data" @search="search()">
|
<ComplexTable :data="data" @search="search()">
|
||||||
<template #leftToolBar>
|
<template #toolbar>
|
||||||
<el-button type="primary" @click="openCreate">{{ $t('website.createGroup') }}</el-button>
|
<el-button type="primary" @click="openCreate">{{ $t('website.createGroup') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
<el-table-column :label="$t('commons.table.name')" prop="name">
|
<el-table-column :label="$t('commons.table.name')" prop="name">
|
||||||
|
@ -65,7 +65,7 @@
|
|||||||
v-model:selects="selects"
|
v-model:selects="selects"
|
||||||
:data="data"
|
:data="data"
|
||||||
>
|
>
|
||||||
<template #leftToolBar>
|
<template #toolbar>
|
||||||
<el-button
|
<el-button
|
||||||
class="ml-2.5"
|
class="ml-2.5"
|
||||||
plain
|
plain
|
||||||
|
@ -594,10 +594,14 @@ const message = {
|
|||||||
operatorHelper: '{0} will be performed on the following container, Do you want to continue?',
|
operatorHelper: '{0} will be performed on the following container, Do you want to continue?',
|
||||||
operatorAppHelper:
|
operatorAppHelper:
|
||||||
'The {0} operation will be performed on the following containers,\n some of which are from the App Store. This operation may affect the normal use of the service. \nDo you want to continue?',
|
'The {0} operation will be performed on the following containers,\n some of which are from the App Store. This operation may affect the normal use of the service. \nDo you want to continue?',
|
||||||
|
start: 'Start',
|
||||||
|
stop: 'Stop',
|
||||||
|
restart: 'Restart',
|
||||||
kill: 'Kill',
|
kill: 'Kill',
|
||||||
pause: 'Pause',
|
pause: 'Pause',
|
||||||
unpause: 'Unpause',
|
unpause: 'Unpause',
|
||||||
rename: 'Rename',
|
rename: 'Rename',
|
||||||
|
remove: 'Remove',
|
||||||
removeAll: 'Remove All',
|
removeAll: 'Remove All',
|
||||||
containerPrune: 'Prune',
|
containerPrune: 'Prune',
|
||||||
containerPruneHelper1: 'Cleaning containers will delete all containers that are in a stopped state.',
|
containerPruneHelper1: 'Cleaning containers will delete all containers that are in a stopped state.',
|
||||||
@ -1108,6 +1112,7 @@ const message = {
|
|||||||
},
|
},
|
||||||
ftp: {
|
ftp: {
|
||||||
ftp: 'FTP Account',
|
ftp: 'FTP Account',
|
||||||
|
notStart: 'FTP service is currently not running, please start it first!',
|
||||||
noFtp: 'FTP (pure-ftpd) service not detected, please refer to the official documentation for installation!',
|
noFtp: 'FTP (pure-ftpd) service not detected, please refer to the official documentation for installation!',
|
||||||
operation: 'Perform [{0}] operation on FTP service, continue?',
|
operation: 'Perform [{0}] operation on FTP service, continue?',
|
||||||
noPasswdMsg: 'Can not get the current FTP account password, please set the password and try again! ',
|
noPasswdMsg: 'Can not get the current FTP account password, please set the password and try again! ',
|
||||||
|
@ -580,10 +580,14 @@ const message = {
|
|||||||
operatorHelper: '{0}は次のコンテナで実行されます、続行しますか?',
|
operatorHelper: '{0}は次のコンテナで実行されます、続行しますか?',
|
||||||
operatorAppHelper:
|
operatorAppHelper:
|
||||||
'「{0}」操作は次のコンテナで実行され、実行中のサービスに影響を与える可能性があります。続けたいですか?',
|
'「{0}」操作は次のコンテナで実行され、実行中のサービスに影響を与える可能性があります。続けたいですか?',
|
||||||
|
start: '始める',
|
||||||
|
stop: '停止',
|
||||||
|
restart: '再起動',
|
||||||
kill: '殺す',
|
kill: '殺す',
|
||||||
pause: '一時停止',
|
pause: '一時停止',
|
||||||
unpause: '再開する',
|
unpause: '再開する',
|
||||||
rename: '名前を変更します',
|
rename: '名前を変更します',
|
||||||
|
remove: '取り除く',
|
||||||
removeAll: 'すべてを削除します',
|
removeAll: 'すべてを削除します',
|
||||||
containerPrune: 'プルーン',
|
containerPrune: 'プルーン',
|
||||||
containerPruneHelper1: 'これにより、停止状態にあるすべてのコンテナが削除されます。',
|
containerPruneHelper1: 'これにより、停止状態にあるすべてのコンテナが削除されます。',
|
||||||
@ -1049,6 +1053,7 @@ const message = {
|
|||||||
},
|
},
|
||||||
ftp: {
|
ftp: {
|
||||||
ftp: 'FTPアカウント|FTPアカウント',
|
ftp: 'FTPアカウント|FTPアカウント',
|
||||||
|
notStart: 'FTP Serviceは現在実行されていません。最初に開始してください!',
|
||||||
noFtp: `FTP(Pure-FTPD)サービスは検出されません。インストールする公式ドキュメントを参照してください。`,
|
noFtp: `FTP(Pure-FTPD)サービスは検出されません。インストールする公式ドキュメントを参照してください。`,
|
||||||
operation: 'これにより、FTPサービスで「{0}」操作が実行されます。続けたいですか?',
|
operation: 'これにより、FTPサービスで「{0}」操作が実行されます。続けたいですか?',
|
||||||
noPasswdMsg: '現在のFTPアカウントパスワードを取得できません。パスワードを設定して再試行してください!',
|
noPasswdMsg: '現在のFTPアカウントパスワードを取得できません。パスワードを設定して再試行してください!',
|
||||||
|
@ -575,10 +575,14 @@ const message = {
|
|||||||
operatorHelper: '{0} 작업이 다음 컨테이너에서 수행됩니다. 계속하시겠습니까?',
|
operatorHelper: '{0} 작업이 다음 컨테이너에서 수행됩니다. 계속하시겠습니까?',
|
||||||
operatorAppHelper:
|
operatorAppHelper:
|
||||||
'"{0}" 작업이 다음 컨테이너에서 수행되며, 실행 중인 서비스에 영향을 미칠 수 있습니다. 계속하시겠습니까?',
|
'"{0}" 작업이 다음 컨테이너에서 수행되며, 실행 중인 서비스에 영향을 미칠 수 있습니다. 계속하시겠습니까?',
|
||||||
|
start: '시작',
|
||||||
|
stop: '중지',
|
||||||
|
restart: '재시작',
|
||||||
kill: '강제 종료',
|
kill: '강제 종료',
|
||||||
pause: '일시 정지',
|
pause: '일시 정지',
|
||||||
unpause: '재개',
|
unpause: '재개',
|
||||||
rename: '이름 변경',
|
rename: '이름 변경',
|
||||||
|
remove: '제거',
|
||||||
removeAll: '모두 제거',
|
removeAll: '모두 제거',
|
||||||
containerPrune: '정리',
|
containerPrune: '정리',
|
||||||
containerPruneHelper1: '이 작업은 중지된 모든 컨테이너를 삭제합니다.',
|
containerPruneHelper1: '이 작업은 중지된 모든 컨테이너를 삭제합니다.',
|
||||||
@ -1040,6 +1044,7 @@ const message = {
|
|||||||
},
|
},
|
||||||
ftp: {
|
ftp: {
|
||||||
ftp: 'FTP 계정 | FTP 계정들',
|
ftp: 'FTP 계정 | FTP 계정들',
|
||||||
|
notStart: 'FTP 서비스가 현재 실행 중이 아닙니다. 먼저 시작하세요!',
|
||||||
noFtp: `FTP (pure-ftpd) 서비스가 감지되지 않았습니다. 공식 문서를 참조하여 설치하세요.`,
|
noFtp: `FTP (pure-ftpd) 서비스가 감지되지 않았습니다. 공식 문서를 참조하여 설치하세요.`,
|
||||||
operation: 'FTP 서비스에서 "{0}" 작업을 수행합니다. 계속하시겠습니까?',
|
operation: 'FTP 서비스에서 "{0}" 작업을 수행합니다. 계속하시겠습니까?',
|
||||||
noPasswdMsg: '현재 FTP 계정의 비밀번호를 가져올 수 없습니다. 비밀번호를 설정한 후 다시 시도하세요!',
|
noPasswdMsg: '현재 FTP 계정의 비밀번호를 가져올 수 없습니다. 비밀번호를 설정한 후 다시 시도하세요!',
|
||||||
|
@ -592,10 +592,14 @@ const message = {
|
|||||||
operatorHelper: '{0} akan dilakukan pada kontena berikut. Adakah anda mahu meneruskan?',
|
operatorHelper: '{0} akan dilakukan pada kontena berikut. Adakah anda mahu meneruskan?',
|
||||||
operatorAppHelper:
|
operatorAppHelper:
|
||||||
'Operasi "{0}" akan dilakukan pada kontena berikut dan mungkin mempengaruhi perkhidmatan yang sedang berjalan. Adakah anda mahu meneruskan?',
|
'Operasi "{0}" akan dilakukan pada kontena berikut dan mungkin mempengaruhi perkhidmatan yang sedang berjalan. Adakah anda mahu meneruskan?',
|
||||||
|
start: 'Mulakan',
|
||||||
|
stop: 'Hentikan',
|
||||||
|
restart: 'Mulakan semula',
|
||||||
kill: 'Hentikan paksa',
|
kill: 'Hentikan paksa',
|
||||||
pause: 'Jeda',
|
pause: 'Jeda',
|
||||||
unpause: 'Sambung semula',
|
unpause: 'Sambung semula',
|
||||||
rename: 'Tukar nama',
|
rename: 'Tukar nama',
|
||||||
|
remove: 'Buang',
|
||||||
removeAll: 'Buang semua',
|
removeAll: 'Buang semua',
|
||||||
containerPrune: 'Prune',
|
containerPrune: 'Prune',
|
||||||
containerPruneHelper1: 'Ini akan memadam semua kontena yang berada dalam keadaan dihentikan.',
|
containerPruneHelper1: 'Ini akan memadam semua kontena yang berada dalam keadaan dihentikan.',
|
||||||
@ -1086,6 +1090,7 @@ const message = {
|
|||||||
},
|
},
|
||||||
ftp: {
|
ftp: {
|
||||||
ftp: 'Akaun FTP | Akaun FTP',
|
ftp: 'Akaun FTP | Akaun FTP',
|
||||||
|
notStart: 'Perkhidmatan FTP tidak berjalan pada masa ini, sila mulakan dahulu!',
|
||||||
noFtp: 'Perkhidmatan FTP (pure-ftpd) tidak dikesan. Rujuk dokumen rasmi untuk memasang.',
|
noFtp: 'Perkhidmatan FTP (pure-ftpd) tidak dikesan. Rujuk dokumen rasmi untuk memasang.',
|
||||||
operation: 'Ini akan melaksanakan operasi "{0}" pada perkhidmatan FTP. Adakah anda mahu meneruskan?',
|
operation: 'Ini akan melaksanakan operasi "{0}" pada perkhidmatan FTP. Adakah anda mahu meneruskan?',
|
||||||
noPasswdMsg:
|
noPasswdMsg:
|
||||||
|
@ -590,10 +590,14 @@ const message = {
|
|||||||
operatorHelper: '{0} será realizado no seguinte contêiner. Deseja continuar?',
|
operatorHelper: '{0} será realizado no seguinte contêiner. Deseja continuar?',
|
||||||
operatorAppHelper:
|
operatorAppHelper:
|
||||||
'A operação "{0}" será realizada no(s) seguinte(s) contêiner(es) e pode afetar os serviços em execução. Deseja continuar?',
|
'A operação "{0}" será realizada no(s) seguinte(s) contêiner(es) e pode afetar os serviços em execução. Deseja continuar?',
|
||||||
|
start: 'Iniciar',
|
||||||
|
stop: 'Parar',
|
||||||
|
restart: 'Reiniciar',
|
||||||
kill: 'Finalizar',
|
kill: 'Finalizar',
|
||||||
pause: 'Pausar',
|
pause: 'Pausar',
|
||||||
unpause: 'Retomar',
|
unpause: 'Retomar',
|
||||||
rename: 'Renomear',
|
rename: 'Renomear',
|
||||||
|
remove: 'Remover',
|
||||||
removeAll: 'Remover todos',
|
removeAll: 'Remover todos',
|
||||||
containerPrune: 'Limpar',
|
containerPrune: 'Limpar',
|
||||||
containerPruneHelper1: 'Isso excluirá todos os contêineres que estão no estado parado.',
|
containerPruneHelper1: 'Isso excluirá todos os contêineres que estão no estado parado.',
|
||||||
@ -1074,6 +1078,7 @@ const message = {
|
|||||||
},
|
},
|
||||||
ftp: {
|
ftp: {
|
||||||
ftp: 'Conta FTP | Contas FTP',
|
ftp: 'Conta FTP | Contas FTP',
|
||||||
|
notStart: 'O serviço FTP não está em execução, por favor, inicie-o primeiro!',
|
||||||
noFtp: `O serviço FTP (pure-ftpd) não foi detectado. Consulte a documentação oficial para instalá-lo.`,
|
noFtp: `O serviço FTP (pure-ftpd) não foi detectado. Consulte a documentação oficial para instalá-lo.`,
|
||||||
operation: 'Isso realizará a operação "{0}" no serviço FTP. Deseja continuar?',
|
operation: 'Isso realizará a operação "{0}" no serviço FTP. Deseja continuar?',
|
||||||
noPasswdMsg: 'Não foi possível obter a senha atual da conta FTP, por favor, defina a senha e tente novamente!',
|
noPasswdMsg: 'Não foi possível obter a senha atual da conta FTP, por favor, defina a senha e tente novamente!',
|
||||||
|
@ -588,10 +588,14 @@ const message = {
|
|||||||
operatorHelper: 'Действие {0} будет выполнено для следующего контейнера. Хотите продолжить?',
|
operatorHelper: 'Действие {0} будет выполнено для следующего контейнера. Хотите продолжить?',
|
||||||
operatorAppHelper:
|
operatorAppHelper:
|
||||||
'Операция "{0}" будет выполнена для следующего(-их) контейнера(-ов) и может повлиять на работающие сервисы. Хотите продолжить?',
|
'Операция "{0}" будет выполнена для следующего(-их) контейнера(-ов) и может повлиять на работающие сервисы. Хотите продолжить?',
|
||||||
|
start: 'Запустить',
|
||||||
|
stop: 'Остановить',
|
||||||
|
restart: 'Перезапустить',
|
||||||
kill: 'Завершить',
|
kill: 'Завершить',
|
||||||
pause: 'Приостановить',
|
pause: 'Приостановить',
|
||||||
unpause: 'Возобновить',
|
unpause: 'Возобновить',
|
||||||
rename: 'Переименовать',
|
rename: 'Переименовать',
|
||||||
|
remove: 'Удалить',
|
||||||
removeAll: 'Удалить все',
|
removeAll: 'Удалить все',
|
||||||
containerPrune: 'Очистить',
|
containerPrune: 'Очистить',
|
||||||
containerPruneHelper1: 'Это удалит все контейнеры, которые находятся в остановленном состоянии.',
|
containerPruneHelper1: 'Это удалит все контейнеры, которые находятся в остановленном состоянии.',
|
||||||
@ -1078,6 +1082,7 @@ const message = {
|
|||||||
},
|
},
|
||||||
ftp: {
|
ftp: {
|
||||||
ftp: 'FTP аккаунт | FTP аккаунты',
|
ftp: 'FTP аккаунт | FTP аккаунты',
|
||||||
|
notStart: 'Служба FTP в настоящее время не запущена, пожалуйста, сначала запустите её!',
|
||||||
noFtp: 'Служба FTP (pure-ftpd) не обнаружена. Обратитесь к официальной документации для установки.',
|
noFtp: 'Служба FTP (pure-ftpd) не обнаружена. Обратитесь к официальной документации для установки.',
|
||||||
operation: 'Это выполнит операцию "{0}" над службой FTP. Хотите продолжить?',
|
operation: 'Это выполнит операцию "{0}" над службой FTP. Хотите продолжить?',
|
||||||
noPasswdMsg:
|
noPasswdMsg:
|
||||||
|
@ -572,10 +572,14 @@ const message = {
|
|||||||
operatorHelper: '將對以下容器進行 {0} 操作,是否繼續?',
|
operatorHelper: '將對以下容器進行 {0} 操作,是否繼續?',
|
||||||
operatorAppHelper:
|
operatorAppHelper:
|
||||||
'將對以下容器進行 {0} 操作,\n其中部分來源於應用商店,該操作可能會影響到該服務的正常使用。\n是否確認?',
|
'將對以下容器進行 {0} 操作,\n其中部分來源於應用商店,該操作可能會影響到該服務的正常使用。\n是否確認?',
|
||||||
|
start: '啟動',
|
||||||
|
stop: '停止',
|
||||||
|
restart: '重啟',
|
||||||
kill: '強製停止',
|
kill: '強製停止',
|
||||||
pause: '暫停',
|
pause: '暫停',
|
||||||
unpause: '恢復',
|
unpause: '恢復',
|
||||||
rename: '重命名',
|
rename: '重命名',
|
||||||
|
remove: '刪除',
|
||||||
removeAll: '删除所有',
|
removeAll: '删除所有',
|
||||||
containerPrune: '清理容器',
|
containerPrune: '清理容器',
|
||||||
containerPruneHelper1: '清理容器 將刪除所有處於停止狀態的容器。',
|
containerPruneHelper1: '清理容器 將刪除所有處於停止狀態的容器。',
|
||||||
@ -1047,6 +1051,7 @@ const message = {
|
|||||||
},
|
},
|
||||||
ftp: {
|
ftp: {
|
||||||
ftp: 'FTP 帳戶',
|
ftp: 'FTP 帳戶',
|
||||||
|
notStart: '當前未 FTP 服務,請先開啟!',
|
||||||
noFtp: '未檢測到 FTP (pure-ftpd) 服務,請參考官方文檔進行安裝!',
|
noFtp: '未檢測到 FTP (pure-ftpd) 服務,請參考官方文檔進行安裝!',
|
||||||
operation: '對 FTP 服務進行 [{0}] 操作,是否繼續?',
|
operation: '對 FTP 服務進行 [{0}] 操作,是否繼續?',
|
||||||
noPasswdMsg: '無法獲取當前 FTP 賬號密碼,請先設置密碼後重試!',
|
noPasswdMsg: '無法獲取當前 FTP 賬號密碼,請先設置密碼後重試!',
|
||||||
|
@ -570,10 +570,14 @@ const message = {
|
|||||||
operatorHelper: '将对以下容器进行 {0} 操作,是否继续?',
|
operatorHelper: '将对以下容器进行 {0} 操作,是否继续?',
|
||||||
operatorAppHelper:
|
operatorAppHelper:
|
||||||
'将对以下容器进行 {0} 操作,\n其中部分来源于应用商店,该操作可能会影响到该服务的正常使用。\n是否继续?',
|
'将对以下容器进行 {0} 操作,\n其中部分来源于应用商店,该操作可能会影响到该服务的正常使用。\n是否继续?',
|
||||||
|
start: '启动',
|
||||||
|
stop: '停止',
|
||||||
|
restart: '重启',
|
||||||
kill: '强制停止',
|
kill: '强制停止',
|
||||||
pause: '暂停',
|
pause: '暂停',
|
||||||
unpause: '恢复',
|
unpause: '恢复',
|
||||||
rename: '重命名',
|
rename: '重命名',
|
||||||
|
remove: '删除',
|
||||||
removeAll: '删除所有',
|
removeAll: '删除所有',
|
||||||
containerPrune: '清理容器',
|
containerPrune: '清理容器',
|
||||||
containerPruneHelper1: '清理容器 将删除所有处于停止状态的容器。',
|
containerPruneHelper1: '清理容器 将删除所有处于停止状态的容器。',
|
||||||
@ -1044,6 +1048,7 @@ const message = {
|
|||||||
},
|
},
|
||||||
ftp: {
|
ftp: {
|
||||||
ftp: 'FTP 账户',
|
ftp: 'FTP 账户',
|
||||||
|
notStart: '当前未开启 FTP 服务,请先开启!',
|
||||||
noFtp: '未检测到 FTP (pure-ftpd) 服务,请参考官方文档进行安装!',
|
noFtp: '未检测到 FTP (pure-ftpd) 服务,请参考官方文档进行安装!',
|
||||||
operation: '对 FTP 服务进行 [{0}] 操作,是否继续?',
|
operation: '对 FTP 服务进行 [{0}] 操作,是否继续?',
|
||||||
noPasswdMsg: '无法获取当前 FTP 账号密码,请先设置密码后重试!',
|
noPasswdMsg: '无法获取当前 FTP 账号密码,请先设置密码后重试!',
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
<el-card style="margin-top: 20px">
|
<el-card style="margin-top: 20px">
|
||||||
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" @search="search" :data="data">
|
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" @search="search" :data="data">
|
||||||
<template #leftToolBar>
|
<template #toolbar>
|
||||||
<el-button type="primary" @click="onBackup">{{ $t('commons.button.backup') }}</el-button>
|
<el-button type="primary" @click="onBackup">{{ $t('commons.button.backup') }}</el-button>
|
||||||
<el-button type="primary" plain :disabled="selects.length === 0" @click="onBatchDelete(null)">
|
<el-button type="primary" plain :disabled="selects.length === 0" @click="onBatchDelete(null)">
|
||||||
{{ $t('commons.button.delete') }}
|
{{ $t('commons.button.delete') }}
|
||||||
|
@ -19,8 +19,13 @@
|
|||||||
<el-select v-model="group" @change="search()" clearable class="p-w-200 mr-2.5">
|
<el-select v-model="group" @change="search()" clearable class="p-w-200 mr-2.5">
|
||||||
<template #prefix>{{ $t('commons.table.group') }}</template>
|
<template #prefix>{{ $t('commons.table.group') }}</template>
|
||||||
<el-option :label="$t('commons.table.all')" value=""></el-option>
|
<el-option :label="$t('commons.table.all')" value=""></el-option>
|
||||||
<div v-for="item in groupList" :key="item.name">
|
<div v-for="item in groupList" :key="item.id">
|
||||||
<el-option :value="item.id" :label="item.name" />
|
<el-option
|
||||||
|
v-if="item.name === 'default'"
|
||||||
|
:label="$t('commons.table.default')"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
<el-option v-else :label="item.name" :value="item.id" />
|
||||||
</div>
|
</div>
|
||||||
</el-select>
|
</el-select>
|
||||||
<TableSearch @search="search()" v-model:searchName="info" />
|
<TableSearch @search="search()" v-model:searchName="info" />
|
||||||
@ -56,7 +61,23 @@
|
|||||||
min-width="100"
|
min-width="100"
|
||||||
prop="groupBelong"
|
prop="groupBelong"
|
||||||
fix
|
fix
|
||||||
|
>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<fu-select-rw-switch v-model="row.groupID" @change="updateGroup(row)">
|
||||||
|
<template #read>
|
||||||
|
{{ row.groupBelong === 'default' ? $t('commons.table.default') : row.groupBelong }}
|
||||||
|
</template>
|
||||||
|
<div v-for="item in groupList" :key="item.id">
|
||||||
|
<el-option
|
||||||
|
v-if="item.name === 'default'"
|
||||||
|
:label="$t('commons.table.default')"
|
||||||
|
:value="item.id"
|
||||||
/>
|
/>
|
||||||
|
<el-option v-else :label="item.name" :value="item.id" />
|
||||||
|
</div>
|
||||||
|
</fu-select-rw-switch>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<fu-table-operations width="200px" :buttons="buttons" :label="$t('commons.table.operate')" fix />
|
<fu-table-operations width="200px" :buttons="buttons" :label="$t('commons.table.operate')" fix />
|
||||||
</ComplexTable>
|
</ComplexTable>
|
||||||
</template>
|
</template>
|
||||||
@ -81,7 +102,12 @@
|
|||||||
<el-form-item :label="$t('commons.table.group')" prop="name">
|
<el-form-item :label="$t('commons.table.group')" prop="name">
|
||||||
<el-select filterable v-model="commandInfo.groupID" clearable style="width: 100%">
|
<el-select filterable v-model="commandInfo.groupID" clearable style="width: 100%">
|
||||||
<div v-for="item in groupList" :key="item.id">
|
<div v-for="item in groupList" :key="item.id">
|
||||||
<el-option :label="item.name" :value="item.id" />
|
<el-option
|
||||||
|
v-if="item.name === 'default'"
|
||||||
|
:label="$t('commons.table.default')"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
<el-option v-else :label="item.name" :value="item.id" />
|
||||||
</div>
|
</div>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -101,14 +127,12 @@
|
|||||||
|
|
||||||
<OpDialog ref="opRef" @search="search" />
|
<OpDialog ref="opRef" @search="search" />
|
||||||
<GroupDialog @search="loadGroups" ref="dialogGroupRef" />
|
<GroupDialog @search="loadGroups" ref="dialogGroupRef" />
|
||||||
<GroupChangeDialog @search="search" @change="onChangeGroup" ref="dialogGroupChangeRef" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Command } from '@/api/interface/command';
|
import { Command } from '@/api/interface/command';
|
||||||
import GroupDialog from '@/components/group/index.vue';
|
import GroupDialog from '@/components/group/index.vue';
|
||||||
import GroupChangeDialog from '@/components/group/change.vue';
|
|
||||||
import { addCommand, editCommand, deleteCommand, getCommandPage } from '@/api/modules/command';
|
import { addCommand, editCommand, deleteCommand, getCommandPage } from '@/api/modules/command';
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import type { ElForm } from 'element-plus';
|
import type { ElForm } from 'element-plus';
|
||||||
@ -131,7 +155,6 @@ const paginationConfig = reactive({
|
|||||||
});
|
});
|
||||||
const info = ref();
|
const info = ref();
|
||||||
const group = ref<string>('');
|
const group = ref<string>('');
|
||||||
const dialogGroupChangeRef = ref();
|
|
||||||
|
|
||||||
const opRef = ref();
|
const opRef = ref();
|
||||||
|
|
||||||
@ -203,9 +226,8 @@ const submitAddCommand = (formEl: FormInstance | undefined) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onChangeGroup = async (groupID: number) => {
|
const updateGroup = async (row: any) => {
|
||||||
commandInfo.groupID = groupID;
|
await editCommand(row);
|
||||||
await editCommand(commandInfo);
|
|
||||||
search();
|
search();
|
||||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||||
};
|
};
|
||||||
@ -235,16 +257,6 @@ const batchDelete = async (row: Command.CommandInfo | null) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const buttons = [
|
const buttons = [
|
||||||
{
|
|
||||||
label: i18n.global.t('terminal.groupChange'),
|
|
||||||
click: (row: any) => {
|
|
||||||
commandInfo = row;
|
|
||||||
dialogGroupChangeRef.value!.acceptParams({
|
|
||||||
group: row.groupBelong,
|
|
||||||
groupType: 'command',
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: i18n.global.t('commons.button.edit'),
|
label: i18n.global.t('commons.button.edit'),
|
||||||
icon: 'Edit',
|
icon: 'Edit',
|
||||||
|
@ -1,100 +0,0 @@
|
|||||||
<template>
|
|
||||||
<DrawerPro v-model="drawerVisible" :header="$t('terminal.groupChange')" :back="handleClose" size="small">
|
|
||||||
<el-form
|
|
||||||
@submit.prevent
|
|
||||||
ref="hostInfoRef"
|
|
||||||
label-position="top"
|
|
||||||
:model="dialogData"
|
|
||||||
:rules="rules"
|
|
||||||
v-loading="loading"
|
|
||||||
>
|
|
||||||
<el-form-item :label="$t('commons.table.group')" prop="group">
|
|
||||||
<el-select filterable v-model="dialogData.groupID" clearable class="w-full">
|
|
||||||
<div v-for="item in groupList" :key="item.id">
|
|
||||||
<el-option :label="item.name" :value="item.id" />
|
|
||||||
</div>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<template #footer>
|
|
||||||
<span class="dialog-footer">
|
|
||||||
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
|
|
||||||
<el-button type="primary" @click="onSubmit(hostInfoRef)">
|
|
||||||
{{ $t('commons.button.confirm') }}
|
|
||||||
</el-button>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</DrawerPro>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref, reactive } from 'vue';
|
|
||||||
import type { ElForm } from 'element-plus';
|
|
||||||
import { Rules } from '@/global/form-rules';
|
|
||||||
import { editHostGroup } from '@/api/modules/terminal';
|
|
||||||
import { getGroupList } from '@/api/modules/group';
|
|
||||||
import i18n from '@/lang';
|
|
||||||
import { MsgSuccess } from '@/utils/message';
|
|
||||||
|
|
||||||
const loading = ref();
|
|
||||||
interface DialogProps {
|
|
||||||
id: number;
|
|
||||||
group: string;
|
|
||||||
}
|
|
||||||
const drawerVisible = ref(false);
|
|
||||||
const dialogData = ref({
|
|
||||||
id: 0,
|
|
||||||
groupID: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
const groupList = ref();
|
|
||||||
const acceptParams = (params: DialogProps): void => {
|
|
||||||
dialogData.value.id = params.id;
|
|
||||||
loadGroups(params.group);
|
|
||||||
drawerVisible.value = true;
|
|
||||||
};
|
|
||||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
|
||||||
|
|
||||||
const handleClose = () => {
|
|
||||||
drawerVisible.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
type FormInstance = InstanceType<typeof ElForm>;
|
|
||||||
const hostInfoRef = ref<FormInstance>();
|
|
||||||
const rules = reactive({
|
|
||||||
groupID: [Rules.requiredSelect],
|
|
||||||
});
|
|
||||||
|
|
||||||
const loadGroups = async (groupName: string) => {
|
|
||||||
const res = await getGroupList('host');
|
|
||||||
groupList.value = res.data;
|
|
||||||
for (const group of groupList.value) {
|
|
||||||
if (group.name === groupName) {
|
|
||||||
dialogData.value.groupID = group.id;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSubmit = (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
formEl.validate(async (valid) => {
|
|
||||||
if (!valid) return;
|
|
||||||
loading.value = true;
|
|
||||||
await editHostGroup(dialogData.value)
|
|
||||||
.then(() => {
|
|
||||||
loading.value = false;
|
|
||||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
|
||||||
drawerVisible.value = false;
|
|
||||||
emit('search');
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
acceptParams,
|
|
||||||
});
|
|
||||||
</script>
|
|
@ -16,8 +16,13 @@
|
|||||||
<el-select v-model="group" @change="search()" clearable class="p-w-200 mr-5">
|
<el-select v-model="group" @change="search()" clearable class="p-w-200 mr-5">
|
||||||
<template #prefix>{{ $t('commons.table.group') }}</template>
|
<template #prefix>{{ $t('commons.table.group') }}</template>
|
||||||
<el-option :label="$t('commons.table.all')" value=""></el-option>
|
<el-option :label="$t('commons.table.all')" value=""></el-option>
|
||||||
<div v-for="item in groupList" :key="item.name">
|
<div v-for="item in groupList" :key="item.id">
|
||||||
<el-option :value="item.id" :label="item.name" />
|
<el-option
|
||||||
|
v-if="item.name === 'default'"
|
||||||
|
:label="$t('commons.table.default')"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
<el-option v-else :label="item.name" :value="item.id" />
|
||||||
</div>
|
</div>
|
||||||
</el-select>
|
</el-select>
|
||||||
<TableSearch @search="search()" v-model:searchName="info" />
|
<TableSearch @search="search()" v-model:searchName="info" />
|
||||||
@ -33,10 +38,26 @@
|
|||||||
<el-table-column :label="$t('terminal.ip')" prop="addr" fix />
|
<el-table-column :label="$t('terminal.ip')" prop="addr" fix />
|
||||||
<el-table-column :label="$t('commons.login.username')" show-overflow-tooltip prop="user" />
|
<el-table-column :label="$t('commons.login.username')" show-overflow-tooltip prop="user" />
|
||||||
<el-table-column :label="$t('commons.table.port')" prop="port" />
|
<el-table-column :label="$t('commons.table.port')" prop="port" />
|
||||||
<el-table-column :label="$t('commons.table.group')" show-overflow-tooltip prop="groupBelong">
|
<el-table-column
|
||||||
|
:label="$t('commons.table.group')"
|
||||||
|
prop="description"
|
||||||
|
min-width="80"
|
||||||
|
show-overflow-tooltip
|
||||||
|
>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span v-if="row.groupBelong === 'default'">{{ $t('commons.table.default') }}</span>
|
<fu-select-rw-switch v-model="row.groupID" @change="updateGroup(row)">
|
||||||
<span v-else>{{ row.groupBelong }}</span>
|
<template #read>
|
||||||
|
{{ row.groupBelong === 'default' ? $t('commons.table.default') : row.groupBelong }}
|
||||||
|
</template>
|
||||||
|
<div v-for="item in groupList" :key="item.id">
|
||||||
|
<el-option
|
||||||
|
v-if="item.name === 'default'"
|
||||||
|
:label="$t('commons.table.default')"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
<el-option v-else :label="item.name" :value="item.id" />
|
||||||
|
</div>
|
||||||
|
</fu-select-rw-switch>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="$t('commons.table.title')" show-overflow-tooltip prop="name" />
|
<el-table-column :label="$t('commons.table.title')" show-overflow-tooltip prop="name" />
|
||||||
@ -53,13 +74,11 @@
|
|||||||
<OpDialog ref="opRef" @search="search" />
|
<OpDialog ref="opRef" @search="search" />
|
||||||
<OperateDialog @search="search" ref="dialogRef" />
|
<OperateDialog @search="search" ref="dialogRef" />
|
||||||
<GroupDialog @search="search" ref="dialogGroupRef" />
|
<GroupDialog @search="search" ref="dialogGroupRef" />
|
||||||
<GroupChangeDialog @search="search" @change="onChangeGroup" ref="dialogGroupChangeRef" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import GroupDialog from '@/components/group/index.vue';
|
import GroupDialog from '@/components/group/index.vue';
|
||||||
import GroupChangeDialog from '@/components/group/change.vue';
|
|
||||||
import OperateDialog from '@/views/terminal/host/operate/index.vue';
|
import OperateDialog from '@/views/terminal/host/operate/index.vue';
|
||||||
import { deleteHost, editHostGroup, searchHosts } from '@/api/modules/terminal';
|
import { deleteHost, editHostGroup, searchHosts } from '@/api/modules/terminal';
|
||||||
import { getGroupList } from '@/api/modules/group';
|
import { getGroupList } from '@/api/modules/group';
|
||||||
@ -80,8 +99,6 @@ const paginationConfig = reactive({
|
|||||||
});
|
});
|
||||||
const info = ref();
|
const info = ref();
|
||||||
const group = ref<string>('');
|
const group = ref<string>('');
|
||||||
const dialogGroupChangeRef = ref();
|
|
||||||
const currentID = ref();
|
|
||||||
|
|
||||||
const opRef = ref();
|
const opRef = ref();
|
||||||
|
|
||||||
@ -142,24 +159,13 @@ const loadGroups = async () => {
|
|||||||
groupList.value = res.data;
|
groupList.value = res.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onChangeGroup = async (groupID: number) => {
|
const updateGroup = async (row: any) => {
|
||||||
let param = {
|
await editHostGroup({ id: row.id, groupID: row.groupID });
|
||||||
id: currentID.value,
|
|
||||||
groupID: groupID,
|
|
||||||
};
|
|
||||||
await editHostGroup(param);
|
|
||||||
search();
|
search();
|
||||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||||
};
|
};
|
||||||
|
|
||||||
const buttons = [
|
const buttons = [
|
||||||
{
|
|
||||||
label: i18n.global.t('terminal.groupChange'),
|
|
||||||
click: (row: any) => {
|
|
||||||
currentID.value = row.id;
|
|
||||||
dialogGroupChangeRef.value!.acceptParams({ group: row.groupBelong, groupType: 'host' });
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: i18n.global.t('commons.button.edit'),
|
label: i18n.global.t('commons.button.edit'),
|
||||||
click: (row: any) => {
|
click: (row: any) => {
|
||||||
|
@ -61,7 +61,8 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('commons.table.name')" prop="name">
|
<el-form-item :label="$t('commons.table.name')" prop="name">
|
||||||
<el-input :disabled="itemName === 'local'" clearable v-model="dialogData.rowData!.name" />
|
<el-tag v-if="itemName === 'local'">local</el-tag>
|
||||||
|
<el-input v-else clearable v-model="dialogData.rowData!.name" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('commons.table.description')" prop="description">
|
<el-form-item :label="$t('commons.table.description')" prop="description">
|
||||||
<el-input clearable type="textarea" v-model="dialogData.rowData!.description" />
|
<el-input clearable type="textarea" v-model="dialogData.rowData!.description" />
|
||||||
@ -107,6 +108,7 @@ const itemName = ref();
|
|||||||
const groupList = ref();
|
const groupList = ref();
|
||||||
const acceptParams = (params: DialogProps): void => {
|
const acceptParams = (params: DialogProps): void => {
|
||||||
dialogData.value = params;
|
dialogData.value = params;
|
||||||
|
itemName.value = params.rowData.name;
|
||||||
title.value = i18n.global.t('commons.button.' + dialogData.value.title);
|
title.value = i18n.global.t('commons.button.' + dialogData.value.title);
|
||||||
drawerVisible.value = true;
|
drawerVisible.value = true;
|
||||||
loadGroups();
|
loadGroups();
|
||||||
|
@ -119,7 +119,7 @@ interface DialogProps {
|
|||||||
}
|
}
|
||||||
const acceptParams = (props: DialogProps) => {
|
const acceptParams = (props: DialogProps) => {
|
||||||
hostInfo.addr = '';
|
hostInfo.addr = '';
|
||||||
hostInfo.name = '';
|
hostInfo.name = 'local';
|
||||||
hostInfo.groupID = 0;
|
hostInfo.groupID = 0;
|
||||||
hostInfo.addr = '';
|
hostInfo.addr = '';
|
||||||
hostInfo.port = 22;
|
hostInfo.port = 22;
|
||||||
|
@ -215,7 +215,7 @@ const acceptParams = async () => {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (let i = 0; i < hostTree.value[gIndex].children.length; i++) {
|
for (let i = 0; i < hostTree.value[gIndex].children.length; i++) {
|
||||||
if (hostTree.value[gIndex].children[i].label.indexOf('@127.0.0.1:') !== -1) {
|
if (hostTree.value[gIndex].children[i].label.startsWith('local - ')) {
|
||||||
localHostID.value = hostTree.value[gIndex].children[i].id;
|
localHostID.value = hostTree.value[gIndex].children[i].id;
|
||||||
hostTree.value[gIndex].children.splice(i, 1);
|
hostTree.value[gIndex].children.splice(i, 1);
|
||||||
if (hostTree.value[gIndex].children.length === 0) {
|
if (hostTree.value[gIndex].children.length === 0) {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #main>
|
<template #main>
|
||||||
<el-row class="mt-5 mb-5">
|
<el-row class="mt-5 mb-5">
|
||||||
<el-col :xs="24" :sm="20" :md="20" :lg="10" :xl="10">
|
<el-col :xs="22" :sm="20" :md="20" :lg="10" :xl="10" :offset="1">
|
||||||
<div v-if="scanStatus !== 'scanned'">
|
<div v-if="scanStatus !== 'scanned'">
|
||||||
<div v-if="scanStatus === 'beforeScan'">
|
<div v-if="scanStatus === 'beforeScan'">
|
||||||
<div v-if="form.lastCleanTime">
|
<div v-if="form.lastCleanTime">
|
||||||
|
@ -23,15 +23,15 @@
|
|||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="form.isExist">
|
<div v-if="form.isExist">
|
||||||
<LayoutContent v-loading="loading" title="FTP">
|
<LayoutContent v-loading="loading" title="FTP" :class="{ mask: !form.isActive }">
|
||||||
<template #leftToolBar>
|
<template #leftToolBar>
|
||||||
<el-button type="primary" :disabled="!form.isActive" @click="onOpenDialog('add')">
|
<el-button type="primary" @click="onOpenDialog('add')">
|
||||||
{{ $t('commons.button.add') }} FTP
|
{{ $t('commons.button.add') }} FTP
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button @click="onSync()" :disabled="!form.isActive">
|
<el-button @click="onSync()">
|
||||||
{{ $t('commons.button.sync') }}
|
{{ $t('commons.button.sync') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button plain :disabled="selects.length === 0 || !form.isActive" @click="onDelete(null)">
|
<el-button plain :disabled="selects.length === 0" @click="onDelete(null)">
|
||||||
{{ $t('commons.button.delete') }}
|
{{ $t('commons.button.delete') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
@ -124,6 +124,10 @@
|
|||||||
</ComplexTable>
|
</ComplexTable>
|
||||||
</template>
|
</template>
|
||||||
</LayoutContent>
|
</LayoutContent>
|
||||||
|
|
||||||
|
<el-card v-if="form.isExist && !form.isActive" class="mask-prompt">
|
||||||
|
<span>{{ $t('toolbox.ftp.notStart') }}</span>
|
||||||
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<LayoutContent title="FTP" :divider="true">
|
<LayoutContent title="FTP" :divider="true">
|
||||||
|
@ -41,12 +41,14 @@
|
|||||||
>
|
>
|
||||||
<template #prefix>{{ $t('commons.table.group') }}</template>
|
<template #prefix>{{ $t('commons.table.group') }}</template>
|
||||||
<el-option :label="$t('commons.table.all')" :value="0"></el-option>
|
<el-option :label="$t('commons.table.all')" :value="0"></el-option>
|
||||||
|
<div v-for="item in groups" :key="item.id">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="(group, index) in groups"
|
v-if="item.name === 'default'"
|
||||||
:key="index"
|
:label="$t('commons.table.default')"
|
||||||
:label="group.name"
|
:value="item.id"
|
||||||
:value="group.id"
|
/>
|
||||||
></el-option>
|
<el-option v-else :label="item.name" :value="item.id" />
|
||||||
|
</div>
|
||||||
</el-select>
|
</el-select>
|
||||||
<TableSearch @search="search()" v-model:searchName="req.name" />
|
<TableSearch @search="search()" v-model:searchName="req.name" />
|
||||||
<div class="!ml-2.5">
|
<div class="!ml-2.5">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user