mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-10-07 22:16:16 +08:00
parent
7313f3d591
commit
789d451ea2
12 changed files with 125 additions and 126 deletions
|
@ -59,44 +59,12 @@ func (u *BackupService) MysqlRecover(req dto.CommonRecover) error {
|
|||
}
|
||||
|
||||
func (u *BackupService) MysqlRecoverByUpload(req dto.CommonRecover) error {
|
||||
file := req.File
|
||||
fileName := path.Base(req.File)
|
||||
if strings.HasSuffix(fileName, ".tar.gz") {
|
||||
fileNameItem := time.Now().Format(constant.DateTimeSlimLayout)
|
||||
dstDir := fmt.Sprintf("%s/%s", path.Dir(req.File), fileNameItem)
|
||||
fileOp := files.NewFileOp()
|
||||
if !fileOp.Stat(dstDir) {
|
||||
if err := fileOp.CreateDir(dstDir, os.ModePerm); err != nil {
|
||||
return fmt.Errorf("mkdir %s failed, err: %v", dstDir, err)
|
||||
}
|
||||
}
|
||||
if err := fileOp.TarGzExtractPro(req.File, dstDir, ""); err != nil {
|
||||
_ = os.RemoveAll(dstDir)
|
||||
return err
|
||||
}
|
||||
global.LOG.Infof("decompress file %s successful, now start to check test.sql is exist", req.File)
|
||||
hasTestSql := false
|
||||
_ = filepath.Walk(dstDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if !info.IsDir() && info.Name() == "test.sql" {
|
||||
hasTestSql = true
|
||||
file = path
|
||||
fileName = "test.sql"
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if !hasTestSql {
|
||||
_ = os.RemoveAll(dstDir)
|
||||
return fmt.Errorf("no such file named test.sql in %s", fileName)
|
||||
}
|
||||
defer func() {
|
||||
_ = os.RemoveAll(dstDir)
|
||||
}()
|
||||
recoveFile, err := loadSqlFile(req.File)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.File = path.Dir(file) + "/" + fileName
|
||||
req.File = recoveFile
|
||||
defer os.RemoveAll(path.Dir(recoveFile))
|
||||
if err := handleMysqlRecover(req, nil, false, req.TaskID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -243,3 +211,55 @@ func doMysqlBackup(db DatabaseHelper, targetDir, fileName string) error {
|
|||
}
|
||||
return cli.Backup(backupInfo)
|
||||
}
|
||||
|
||||
func loadSqlFile(file string) (string, error) {
|
||||
if !strings.HasSuffix(file, ".tar.gz") && !strings.HasSuffix(file, ".zip") {
|
||||
return file, nil
|
||||
}
|
||||
fileName := path.Base(file)
|
||||
fileDir := path.Dir(file)
|
||||
fileNameItem := time.Now().Format(constant.DateTimeSlimLayout)
|
||||
dstDir := fmt.Sprintf("%s/%s", fileDir, fileNameItem)
|
||||
_ = os.Mkdir(dstDir, constant.DirPerm)
|
||||
if strings.HasSuffix(fileName, ".tar.gz") {
|
||||
fileOp := files.NewFileOp()
|
||||
if err := fileOp.TarGzExtractPro(file, dstDir, ""); err != nil {
|
||||
_ = os.RemoveAll(dstDir)
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
if strings.HasSuffix(fileName, ".zip") {
|
||||
archiver, err := files.NewShellArchiver(files.Zip)
|
||||
if err != nil {
|
||||
_ = os.RemoveAll(dstDir)
|
||||
return "", err
|
||||
}
|
||||
if err := archiver.Extract(file, dstDir, ""); err != nil {
|
||||
_ = os.RemoveAll(dstDir)
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
global.LOG.Infof("decompress file %s successful, now start to check test.sql is exist", file)
|
||||
var sqlFiles []string
|
||||
hasTestSql := false
|
||||
_ = filepath.Walk(dstDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if !info.IsDir() && strings.HasSuffix(info.Name(), ".sql") {
|
||||
sqlFiles = append(sqlFiles, path)
|
||||
if info.Name() == "test.sql" {
|
||||
hasTestSql = true
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if len(sqlFiles) == 1 {
|
||||
return sqlFiles[0], nil
|
||||
}
|
||||
if !hasTestSql {
|
||||
_ = os.RemoveAll(dstDir)
|
||||
return "", fmt.Errorf("no such file named test.sql in %s", fileName)
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
|
|
@ -4,8 +4,6 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
||||
|
@ -59,44 +57,12 @@ func (u *BackupService) PostgresqlRecover(req dto.CommonRecover) error {
|
|||
}
|
||||
|
||||
func (u *BackupService) PostgresqlRecoverByUpload(req dto.CommonRecover) error {
|
||||
file := req.File
|
||||
fileName := path.Base(req.File)
|
||||
if strings.HasSuffix(fileName, ".tar.gz") {
|
||||
fileNameItem := time.Now().Format(constant.DateTimeSlimLayout)
|
||||
dstDir := fmt.Sprintf("%s/%s", path.Dir(req.File), fileNameItem)
|
||||
fileOp := files.NewFileOp()
|
||||
if !fileOp.Stat(dstDir) {
|
||||
if err := fileOp.CreateDir(dstDir, os.ModePerm); err != nil {
|
||||
return fmt.Errorf("mkdir %s failed, err: %v", dstDir, err)
|
||||
}
|
||||
}
|
||||
if err := fileOp.TarGzExtractPro(req.File, dstDir, ""); err != nil {
|
||||
_ = os.RemoveAll(dstDir)
|
||||
return err
|
||||
}
|
||||
global.LOG.Infof("decompress file %s successful, now start to check test.sql is exist", req.File)
|
||||
hasTestSql := false
|
||||
_ = filepath.Walk(dstDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if !info.IsDir() && info.Name() == "test.sql" {
|
||||
hasTestSql = true
|
||||
file = path
|
||||
fileName = "test.sql"
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if !hasTestSql {
|
||||
_ = os.RemoveAll(dstDir)
|
||||
return fmt.Errorf("no such file named test.sql in %s", fileName)
|
||||
}
|
||||
defer func() {
|
||||
_ = os.RemoveAll(dstDir)
|
||||
}()
|
||||
recoveFile, err := loadSqlFile(req.File)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.File = path.Dir(file) + "/" + fileName
|
||||
req.File = recoveFile
|
||||
defer os.RemoveAll(path.Dir(recoveFile))
|
||||
if err := handlePostgresqlRecover(req, nil, false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -16,15 +16,9 @@
|
|||
<li v-if="type === 'mysql' || type === 'mariadb'">
|
||||
{{ $t('database.formatHelper', [remark]) }}
|
||||
</li>
|
||||
<li v-if="type === 'website'">{{ $t('website.websiteBackupWarn') }}</li>
|
||||
<span v-if="isDb()">
|
||||
<li>{{ $t('database.supportUpType') }}</li>
|
||||
<li>{{ $t('database.zipFormat') }}</li>
|
||||
</span>
|
||||
<span v-else>
|
||||
<li>{{ $t('website.supportUpType') }}</li>
|
||||
<li>{{ $t('website.zipFormat', [type + '.json']) }}</li>
|
||||
</span>
|
||||
<li v-if="isDb()">{{ $t('database.supportUpType') }}</li>
|
||||
<li v-if="!isDb()">{{ $t('website.websiteBackupWarn') }}</li>
|
||||
<li v-if="!isDb()">{{ $t('website.supportUpType', [type]) }}</li>
|
||||
</ul>
|
||||
</template>
|
||||
</el-alert>
|
||||
|
@ -42,7 +36,7 @@
|
|||
:limit="1"
|
||||
class="float-left"
|
||||
ref="uploadRef"
|
||||
accept=".tar.gz,.sql,.sql.gz"
|
||||
accept=".tar.gz,.sql,.gz,.zip"
|
||||
:show-file-list="false"
|
||||
:on-exceed="handleExceed"
|
||||
:on-change="fileOnChange"
|
||||
|
@ -156,7 +150,7 @@ const paginationConfig = reactive({
|
|||
total: 0,
|
||||
});
|
||||
const uploadOpen = ref(false);
|
||||
const type = ref();
|
||||
const type = ref('mysql');
|
||||
const name = ref();
|
||||
const detailName = ref();
|
||||
const remark = ref();
|
||||
|
@ -208,15 +202,38 @@ const search = async () => {
|
|||
paginationConfig.total = res.data.total;
|
||||
};
|
||||
|
||||
const beforeUpload = (fileName: string) => {
|
||||
const itemName = fileName.toLowerCase();
|
||||
let reg = /^[a-zA-Z0-9\u4e00-\u9fa5]{1}[a-z:A-Z0-9_.\u4e00-\u9fa5-]{0,256}$/;
|
||||
if (!reg.test(itemName)) {
|
||||
MsgError(i18n.global.t('commons.msg.fileNameErr'));
|
||||
return false;
|
||||
}
|
||||
if (isDb()) {
|
||||
const allowedExtensions = ['.sql', '.sql.gz', '.tar.gz', '.zip'];
|
||||
const isValidFile = allowedExtensions.some((ext) => itemName.endsWith(ext));
|
||||
if (!isValidFile) {
|
||||
MsgError(i18n.global.t('database.supportUpType'));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const allowedExtensions = ['.tar.gz'];
|
||||
const isValidFile = allowedExtensions.some((ext) => itemName.endsWith(ext));
|
||||
if (!isValidFile) {
|
||||
MsgError(i18n.global.t('website.supportUpType'));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const loadFile = async (path: string) => {
|
||||
let filaName = path.split('/').pop();
|
||||
if (!filaName) {
|
||||
MsgError(i18n.global.t('commons.msg.fileNameErr'));
|
||||
return;
|
||||
}
|
||||
let reg = /^[a-zA-Z0-9\u4e00-\u9fa5]{1}[a-z:A-Z0-9_.\u4e00-\u9fa5-]{0,256}$/;
|
||||
if (!reg.test(filaName)) {
|
||||
MsgError(i18n.global.t('commons.msg.fileNameErr'));
|
||||
if (!beforeUpload(filaName)) {
|
||||
return;
|
||||
}
|
||||
ElMessageBox.confirm(i18n.global.t('database.selectHelper', [path]), i18n.global.t('database.loadBackup'), {
|
||||
|
@ -297,6 +314,9 @@ const fileOnChange = (_uploadFile: UploadFile, uploadFiles: UploadFiles) => {
|
|||
MsgError(i18n.global.t('commons.msg.fileNameErr'));
|
||||
return;
|
||||
}
|
||||
if (!beforeUpload(file.raw.name)) {
|
||||
return;
|
||||
}
|
||||
ElMessageBox.confirm(
|
||||
i18n.global.t('database.selectHelper', [file.raw.name]),
|
||||
i18n.global.t('database.loadBackup'),
|
||||
|
|
|
@ -521,8 +521,8 @@ const message = {
|
|||
selectFile: 'Select file',
|
||||
dropHelper: 'You can drag and drop the uploaded file here or',
|
||||
clickHelper: 'click to upload',
|
||||
supportUpType: 'Only sql, sql.gz, and tar.gz files are supported',
|
||||
zipFormat: 'tar.gz compressed package structure: test.tar.gz compressed package must contain test.sql',
|
||||
supportUpType:
|
||||
'Only supports sql, sql.gz, tar.gz, .zip file formats. The imported compressed file must contain only one .sql file or include test.sql',
|
||||
|
||||
currentStatus: 'Current state',
|
||||
baseParam: 'Basic parameter',
|
||||
|
@ -2211,8 +2211,7 @@ const message = {
|
|||
otherDomains: 'Other domains',
|
||||
static: 'Static',
|
||||
deployment: 'Deployment',
|
||||
supportUpType: 'Only .tar.gz files are supported',
|
||||
zipFormat: '.tar.gz compressed package structure: test.tar.gz compressed package must contain {0} file',
|
||||
supportUpType: 'Only .tar.gz file format is supported, and the compressed package must contain {0}.json file',
|
||||
proxy: 'Reverse proxy',
|
||||
alias: 'Alias',
|
||||
ftpUser: 'FTP account',
|
||||
|
|
|
@ -509,8 +509,8 @@ const message = {
|
|||
selectFile: '[ファイル]を選択します',
|
||||
dropHelper: 'ここでアップロードされたファイルをドラッグアンドドロップするか、',
|
||||
clickHelper: 'クリックしてアップロードします',
|
||||
supportUpType: 'SQL、SQL.GZ、およびTAR.GZファイルのみがサポートされています',
|
||||
zipFormat: 'tar.gz圧縮パッケージ構造:test.tar.gz圧縮パッケージにはtest.sqlが含まれている必要があります',
|
||||
supportUpType:
|
||||
'sql、sql.gz、tar.gz、.zip ファイル形式のみサポートしています。インポートする圧縮ファイルには、1つの.sqlファイルのみ、またはtest.sqlが含まれている必要があります',
|
||||
|
||||
currentStatus: '現在の状態',
|
||||
baseParam: '基本パラメーター',
|
||||
|
@ -2125,8 +2125,8 @@ const message = {
|
|||
otherDomains: '他のドメイン',
|
||||
static: '静的',
|
||||
deployment: '展開',
|
||||
supportUpType: '.tar.gzファイルのみがサポートされています',
|
||||
zipFormat: '.tar.gz圧縮パッケージ構造:test.tar.gz圧縮パッケージは{0}ファイルを含める必要があります',
|
||||
supportUpType:
|
||||
'.tar.gz ファイル形式のみサポートされており、圧縮パッケージには {0}.json ファイルが含まれている必要があります',
|
||||
proxy: '逆プロキシ',
|
||||
alias: 'エイリアス',
|
||||
ftpUser: 'FTPアカウント',
|
||||
|
|
|
@ -507,8 +507,8 @@ const message = {
|
|||
selectFile: '파일 선택',
|
||||
dropHelper: '여기에 업로드한 파일을 드래그 앤 드롭하거나',
|
||||
clickHelper: '클릭하여 업로드',
|
||||
supportUpType: 'sql, sql.gz, tar.gz 파일만 지원됩니다.',
|
||||
zipFormat: 'tar.gz 압축 패키지 구조: test.tar.gz 압축 패키지에는 test.sql이 포함되어야 합니다.',
|
||||
supportUpType:
|
||||
'sql, sql.gz, tar.gz, .zip 파일 형식만 지원합니다. 가져오는 압축 파일에는 하나의 .sql 파일만 있거나 test.sql이 포함되어 있어야 합니다',
|
||||
|
||||
currentStatus: '현재 상태',
|
||||
baseParam: '기본 파라미터',
|
||||
|
@ -2090,8 +2090,7 @@ const message = {
|
|||
otherDomains: '기타 도메인',
|
||||
static: '정적',
|
||||
deployment: '배포',
|
||||
supportUpType: '지원되는 파일 형식: .tar.gz',
|
||||
zipFormat: '.tar.gz 압축 패키지 구조: test.tar.gz 패키지에는 반드시 {0} 파일이 포함되어야 합니다.',
|
||||
supportUpType: '.tar.gz 파일 형식만 지원되며, 압축 패키지에는 {0}.json 파일이 포함되어야 합니다',
|
||||
proxy: '리버스 프록시',
|
||||
alias: '별칭',
|
||||
ftpUser: 'FTP 계정',
|
||||
|
|
|
@ -521,8 +521,8 @@ const message = {
|
|||
selectFile: 'Pilih fail',
|
||||
dropHelper: 'Anda boleh seret dan lepaskan fail yang ingin dimuat naik di sini atau',
|
||||
clickHelper: 'klik untuk memuat naik',
|
||||
supportUpType: 'Hanya fail sql, sql.gz, dan tar.gz yang disokong',
|
||||
zipFormat: 'Struktur pakej mampatan tar.gz: Pakej mampatan test.tar.gz mesti mengandungi test.sql',
|
||||
supportUpType:
|
||||
'Hanya menyokong format fail sql, sql.gz, tar.gz, .zip. Fail termampat yang diimport mesti mengandungi hanya satu fail .sql atau termasuk test.sql',
|
||||
|
||||
currentStatus: 'Keadaan semasa',
|
||||
baseParam: 'Parameter asas',
|
||||
|
@ -2181,8 +2181,7 @@ const message = {
|
|||
otherDomains: 'Domain Lain',
|
||||
static: 'Statik',
|
||||
deployment: 'Penerapan',
|
||||
supportUpType: 'Hanya fail .tar.gz disokong',
|
||||
zipFormat: 'Struktur fail .tar.gz: fail test.tar.gz mesti mengandungi fail {0}',
|
||||
supportUpType: 'Hanya format fail .tar.gz yang disokong, dan pakej termampat mesti mengandungi fail {0}.json',
|
||||
proxy: 'Proksi Terbalik',
|
||||
alias: 'Alias',
|
||||
ftpUser: 'Akaun FTP',
|
||||
|
|
|
@ -519,8 +519,8 @@ const message = {
|
|||
selectFile: 'Selecionar arquivo',
|
||||
dropHelper: 'Você pode arrastar e soltar o arquivo carregado aqui ou',
|
||||
clickHelper: 'clicar para fazer upload',
|
||||
supportUpType: 'Apenas arquivos sql, sql.gz e tar.gz são suportados',
|
||||
zipFormat: 'Estrutura do pacote comprimido tar.gz: o pacote comprimido test.tar.gz deve conter test.sql',
|
||||
supportUpType:
|
||||
'Suporta apenas os formatos de arquivo sql, sql.gz, tar.gz, .zip. O arquivo compactado importado deve conter apenas um arquivo .sql ou incluir test.sql',
|
||||
|
||||
currentStatus: 'Estado atual',
|
||||
baseParam: 'Parâmetro básico',
|
||||
|
@ -2178,8 +2178,8 @@ const message = {
|
|||
otherDomains: 'Outros domínios',
|
||||
static: 'Estático',
|
||||
deployment: 'Implantação',
|
||||
supportUpType: 'Somente arquivos .tar.gz são suportados',
|
||||
zipFormat: 'Estrutura de pacote comprimido .tar.gz: o pacote comprimido test.tar.gz deve conter o arquivo {0}',
|
||||
supportUpType:
|
||||
'Apenas o formato de arquivo .tar.gz é suportado, e o pacote compactado deve conter o arquivo {0}.json',
|
||||
proxy: 'Proxy reverso',
|
||||
alias: 'Alias',
|
||||
ftpUser: 'Conta FTP',
|
||||
|
|
|
@ -513,8 +513,8 @@ const message = {
|
|||
selectFile: 'Выбрать файл',
|
||||
dropHelper: 'Вы можете перетащить загружаемый файл сюда или',
|
||||
clickHelper: 'нажмите для загрузки',
|
||||
supportUpType: 'Поддерживаются только файлы sql, sql.gz и tar.gz',
|
||||
zipFormat: 'Структура архива tar.gz: архив test.tar.gz должен содержать файл test.sql',
|
||||
supportUpType:
|
||||
'Поддерживаются только форматы файлов sql, sql.gz, tar.gz, .zip. Импортируемый сжатый файл должен содержать только один файл .sql или включать test.sql',
|
||||
|
||||
currentStatus: 'Текущее состояние',
|
||||
baseParam: 'Базовые параметры',
|
||||
|
@ -2174,8 +2174,7 @@ const message = {
|
|||
otherDomains: 'Другие домены',
|
||||
static: 'Статический',
|
||||
deployment: 'Развертывание',
|
||||
supportUpType: 'Поддерживаются только файлы .tar.gz',
|
||||
zipFormat: 'Структура архива .tar.gz: архив test.tar.gz должен содержать файл {0}',
|
||||
supportUpType: 'Поддерживается только формат файла .tar.gz, и сжатый пакет должен содержать файл {0}.json',
|
||||
proxy: 'Обратный прокси',
|
||||
alias: 'Псевдоним',
|
||||
ftpUser: 'FTP аккаунт',
|
||||
|
|
|
@ -528,8 +528,8 @@ const message = {
|
|||
selectFile: 'Dosya seç',
|
||||
dropHelper: 'Yüklenen dosyayı buraya sürükleyip bırakabilir veya',
|
||||
clickHelper: 'yüklemek için tıklayın',
|
||||
supportUpType: 'Yalnızca sql, sql.gz ve tar.gz dosyaları desteklenir',
|
||||
zipFormat: 'tar.gz sıkıştırılmış paket yapısı: test.tar.gz sıkıştırılmış paketi test.sql içermelidir',
|
||||
supportUpType:
|
||||
'Yalnızca sql, sql.gz, tar.gz, .zip dosya formatlarını destekler. İçe aktarılan sıkıştırılmış dosya yalnızca bir .sql dosyası içermeli veya test.sql içermelidir',
|
||||
|
||||
currentStatus: 'Mevcut durum',
|
||||
baseParam: 'Temel parametre',
|
||||
|
@ -2237,8 +2237,7 @@ const message = {
|
|||
otherDomains: 'Diğer alan adları',
|
||||
static: 'Statik',
|
||||
deployment: 'Dağıtım',
|
||||
supportUpType: 'Yalnızca .tar.gz dosyaları desteklenir',
|
||||
zipFormat: '.tar.gz sıkıştırılmış paket yapısı: test.tar.gz sıkıştırılmış paket {0} dosyasını içermelidir',
|
||||
supportUpType: 'Yalnızca .tar.gz dosya formatı desteklenir ve sıkıştırılmış paket {0}.json dosyası içermelidir',
|
||||
proxy: 'Ters vekil',
|
||||
alias: 'Takma ad',
|
||||
ftpUser: 'FTP hesabı',
|
||||
|
|
|
@ -503,8 +503,8 @@ const message = {
|
|||
selectFile: '選擇文件',
|
||||
dropHelper: '將上傳文件拖拽到此處,或者',
|
||||
clickHelper: '點擊上傳',
|
||||
supportUpType: '僅支持 sql、sql.gz、tar.gz 文件',
|
||||
zipFormat: 'tar.gz 壓縮包結構:test.tar.gz 壓縮包內,必需包含 test.sql',
|
||||
supportUpType:
|
||||
'僅支持 sql、sql.gz、tar.gz、.zip 文件格式,導入的壓縮文件必須保證只有一個 .sql 文件或者包含 test.sql',
|
||||
|
||||
currentStatus: '當前狀態',
|
||||
baseParam: '基礎參數',
|
||||
|
@ -2059,8 +2059,7 @@ const message = {
|
|||
otherDomains: '其他域名',
|
||||
static: '靜態網站',
|
||||
deployment: '一鍵部署',
|
||||
supportUpType: '僅支持 .tar.gz 文件',
|
||||
zipFormat: '.tar.gz 壓縮包結構:test.tar.gz 壓縮包內,必需包含 {0} 文件',
|
||||
supportUpType: '僅支持 .tar.gz 文件格式,且壓縮包內必須包含 {0}.json 文件',
|
||||
proxy: '反向代理',
|
||||
alias: '代號',
|
||||
ftpUser: 'FTP 帳號',
|
||||
|
|
|
@ -501,8 +501,8 @@ const message = {
|
|||
selectFile: '选择文件',
|
||||
dropHelper: '将上传文件拖拽到此处,或者',
|
||||
clickHelper: '点击上传',
|
||||
supportUpType: '仅支持 sql、sql.gz、tar.gz 文件',
|
||||
zipFormat: 'tar.gz 压缩包结构:test.tar.gz 压缩包内,必需包含 test.sql',
|
||||
supportUpType:
|
||||
'仅支持 sql、sql.gz、tar.gz、.zip 文件格式,导入的压缩文件必须保证只有一个 .sql 文件或者包含 test.sql',
|
||||
|
||||
currentStatus: '当前状态',
|
||||
baseParam: '基础参数',
|
||||
|
@ -2049,8 +2049,7 @@ const message = {
|
|||
otherDomains: '其他域名',
|
||||
static: '静态网站',
|
||||
deployment: '一键部署',
|
||||
supportUpType: '仅支持 .tar.gz 文件',
|
||||
zipFormat: '.tar.gz 压缩包结构:test.tar.gz 压缩包内,必需包含 {0} 文件',
|
||||
supportUpType: '仅支持 .tar.gz 文件格式,且压缩包内必须包含 {0}.json 文件',
|
||||
proxy: '反向代理',
|
||||
alias: '代号',
|
||||
ftpUser: 'FTP 账号',
|
||||
|
|
Loading…
Add table
Reference in a new issue