1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-03-01 03:24:14 +08:00

feat: Add the display of details for backup accounts. (#7941)

This commit is contained in:
ssongliu 2025-02-21 10:17:09 +08:00 committed by GitHub
parent 8e645d97b3
commit b80c55c59c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 188 additions and 88 deletions

View File

@ -2,17 +2,6 @@ package dto
import "time"
type SnapshotStatus struct {
BaseData string `json:"baseData"`
AppImage string `json:"appImage"`
PanelData string `json:"panelData"`
BackupData string `json:"backupData"`
Compress string `json:"compress"`
Size string `json:"size"`
Upload string `json:"upload"`
}
type PageSnapshot struct {
PageInfo
Info string `json:"info"`

View File

@ -72,6 +72,7 @@ func Run() {
global.LOG.Errorf("update cronjob %s %s failed, err: %v", cronJobs[i].Type, cronJobs[i].Name, err)
}
}
global.Cron.Start()
}
func syncBeforeStart() {

View File

@ -80,19 +80,6 @@ type PortUpdate struct {
ServerPort uint `json:"serverPort" validate:"required,number,max=65535,min=1"`
}
type SnapshotStatus struct {
Panel string `json:"panel"`
PanelInfo string `json:"panelInfo"`
DaemonJson string `json:"daemonJson"`
AppData string `json:"appData"`
PanelData string `json:"panelData"`
BackupData string `json:"backupData"`
Compress string `json:"compress"`
Size string `json:"size"`
Upload string `json:"upload"`
}
type SnapshotCreate struct {
ID uint `json:"id"`
From string `json:"from" validate:"required"`

View File

@ -198,16 +198,6 @@ export namespace Setting {
Children: Array<DataTree>;
}
export interface SnapshotStatus {
baseData: string;
appImage: string;
panelData: string;
backupData: string;
compress: string;
size: string;
upload: string;
}
export interface UpgradeInfo {
testVersion: string;
newVersion: string;

View File

@ -121,9 +121,6 @@ export const snapshotCreate = (param: Setting.SnapshotCreate) => {
export const snapshotRecreate = (id: number) => {
return http.post(`/settings/snapshot/recreate`, { id: id });
};
export const loadSnapStatus = (id: number) => {
return http.post<Setting.SnapshotStatus>(`/settings/snapshot/status`, { id: id });
};
export const snapshotImport = (param: Setting.SnapshotImport) => {
return http.post(`/settings/snapshot/import`, param);
};

View File

@ -70,7 +70,7 @@ const initCodeMirror = () => {
const defaultTheme = EditorView.theme({
'&.cm-editor': {
minHeight: props.minHeight + 'px',
height: props.height ? props.height + 'px' : 'calc(100vh - ' + props.heightDiff + 'px)',
height: loadHeight(),
},
});
@ -119,6 +119,12 @@ const initCodeMirror = () => {
});
};
const loadHeight = () => {
if (props.height || props.heightDiff) {
return props.height ? props.height + 'px' : 'calc(100vh - ' + props.heightDiff + 'px)';
}
};
watch(
() => content.value,
(newValue) => {

View File

@ -0,0 +1,39 @@
<template>
<DialogPro v-model="visible" :title="$t('app.detail')">
<div class="mt-5">
<el-descriptions border :column="1">
<el-descriptions-item v-for="(item, key) in list" :label="item.label" :key="key">
{{ item.value }}
<CopyButton v-if="!item.hideCopy" :content="item.value" type="icon" />
</el-descriptions-item>
</el-descriptions>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="visible = false">
{{ $t('commons.button.cancel') }}
</el-button>
</span>
</template>
</DialogPro>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const list = ref();
const visible = ref(false);
interface DialogProps {
list: Array<string>;
}
const acceptParams = (props: DialogProps): void => {
visible.value = true;
list.value = props.list;
};
defineExpose({
acceptParams,
});
</script>

View File

@ -1185,14 +1185,15 @@ const message = {
apps: 'App',
websites: 'Website',
containers: 'Container',
files: 'File Manage',
files: 'File',
runtimes: 'Runtime',
process: 'Process',
toolbox: 'Toolbox',
backups: 'Backup / Restore',
tampers: 'Tamper',
xsetting: 'Interface Settings',
logs: 'Panel Logs',
settings: 'Panel Setting',
logs: 'Log',
settings: 'Setting',
cronjobs: 'Cronjob',
databases: 'Database',
},

View File

@ -1122,16 +1122,19 @@ const message = {
detail: {
groups: 'グループ',
hosts: 'ホスト',
apps: 'アプリ',
websites: 'Webサイト',
containers: '容器',
apps: 'アプリケーション',
websites: 'ウェブサイト',
containers: 'コンテナ',
files: 'ファイル管理',
runtimes: 'ランタイム',
process: 'プロセス',
process: 'プロセス管理',
toolbox: 'ツールボックス',
logs: 'パネルログ',
backups: 'バックアップ / 復元',
tampers: '改ざん防止',
xsetting: 'インターフェース設定',
logs: 'ログ監査',
settings: 'パネル設定',
cronjobs: 'クローニョブ',
cronjobs: 'スケジュールされたタスク',
databases: 'データベース',
},
websiteLog: 'ウェブサイトログ',

View File

@ -1114,12 +1114,15 @@ const message = {
websites: '웹사이트',
containers: '컨테이너',
files: '파일 관리',
runtimes: '런타임',
process: '프로세스',
toolbox: '도구상자',
logs: '패널 로그',
runtimes: '실행 환경',
process: '프로세스 관리',
toolbox: '도구 상자',
backups: '백업 / 복원',
tampers: '변조 방지',
xsetting: '인터페이스 설정',
logs: '로그 감사',
settings: '패널 설정',
cronjobs: '크론 작업',
cronjobs: '예약 작업',
databases: '데이터베이스',
},
websiteLog: '웹사이트 로그',

View File

@ -1167,13 +1167,16 @@ const message = {
websites: 'Laman Web',
containers: 'Kontena',
files: 'Pengurusan Fail',
runtimes: 'Runtime',
process: 'Proses',
runtimes: 'Persekitaran Jalankan',
process: 'Pengurusan Proses',
toolbox: 'Kotak Alat',
logs: 'Log Panel',
backups: 'Sandaran / Pulihkan',
tampers: 'Perlindungan daripada Pinda',
xsetting: 'Tetapan Antara Muka',
logs: 'Audit Log',
settings: 'Tetapan Panel',
cronjobs: 'Cronjob',
databases: 'Pangkalan Data',
cronjobs: 'Tugas Terjadual',
databases: 'Pangkalan',
},
websiteLog: 'Log Laman Web',
runLog: 'Log Jalankan',

View File

@ -1145,19 +1145,22 @@ const message = {
deleteLogs: 'Limpar logs',
resource: 'Recurso',
detail: {
groups: 'Grupo',
hosts: 'Host',
apps: 'Aplicativo',
websites: 'Website',
containers: 'Container',
files: 'Gerenciamento de arquivos',
runtimes: 'Ambiente de execução',
process: 'Processo',
toolbox: 'Caixa de ferramentas',
logs: 'Logs do painel',
settings: 'Configurações do painel',
cronjobs: 'Tarefas agendadas',
databases: 'Banco de dados',
groups: 'Grupos',
hosts: 'Hosts',
apps: 'Aplicativos',
websites: 'Sites',
containers: 'Contêineres',
files: 'Gerenciamento de Arquivos',
runtimes: 'Ambientes de Execução',
process: 'Gerenciamento de Processos',
toolbox: 'Caixa de Ferramentas',
backups: 'Backup / Restauração',
tampers: 'Proteção contra Alterações',
xsetting: 'Configurações da Interface',
logs: 'Auditoria de Logs',
settings: 'Configurações do Painel',
cronjobs: 'Tarefas Agendadas',
databases: 'Bancos de Dados',
},
websiteLog: 'Logs do website',
runLog: 'Logs de execução',

View File

@ -1150,19 +1150,22 @@ const message = {
deleteLogs: 'Очистить логи',
resource: 'Ресурс',
detail: {
groups: 'Группа',
hosts: 'Хост',
apps: 'Приложение',
websites: 'Веб-сайт',
containers: 'Контейнер',
groups: 'Группы',
hosts: 'Хосты',
apps: 'Приложения',
websites: 'Вебсайты',
containers: 'Контейнеры',
files: 'Управление файлами',
runtimes: 'Среда выполнения',
process: 'Процесс',
toolbox: 'Инструменты',
logs: 'Логи панели',
runtimes: 'Среды выполнения',
process: 'Управление процессами',
toolbox: 'Инструментальный ящик',
backups: 'Резервное копирование / Восстановление',
tampers: 'Защита от подделки',
xsetting: 'Настройки интерфейса',
logs: 'Аудит журналов',
settings: 'Настройки панели',
cronjobs: 'Cron',
databases: 'База данных',
cronjobs: 'Запланированные задачи',
databases: 'Базы данных',
},
websiteLog: 'Логи веб-сайта',
runLog: 'Логи выполнения',

View File

@ -1123,12 +1123,13 @@ const message = {
runtimes: '運行環境',
process: '進程管理',
toolbox: '工具箱',
backups: '備份 / 還原',
tampers: '防篡改',
xsetting: '面設定',
xsetting: '面設定',
logs: '日誌審計',
settings: '面板設',
cronjobs: '任務',
databases: '數據',
settings: '面板設',
cronjobs: '任務',
databases: '資料',
},
websiteLog: '網站日誌',
runLog: '運行日誌',

View File

@ -1120,6 +1120,7 @@ const message = {
runtimes: '运行环境',
process: '进程管理',
toolbox: '工具箱',
backups: '备份 / 恢复',
tampers: '防篡改',
xsetting: '界面设置',
logs: '日志审计',

View File

@ -280,7 +280,8 @@
v-model="dialogData.rowData!.script"
placeholder="#Define or paste the content of your shell file here"
mode="javascript"
:heightDiff="400"
:heightDiff="0"
:min-height="200"
/>
<el-input
v-if="dialogData.rowData!.scriptMode=== 'select'"

View File

@ -33,7 +33,13 @@
:min-width="80"
prop="name"
show-overflow-tooltip
/>
>
<template #default="{ row }">
<el-text type="primary" class="cursor-pointer" @click="onInspect(row)">
{{ row.name }}
</el-text>
</template>
</el-table-column>
<el-table-column
v-if="globalStore.isProductPro"
:label="$t('setting.scope')"
@ -103,6 +109,7 @@
</LayoutContent>
<Operate ref="dialogRef" @search="search" />
<DetailShow ref="detailRef" />
<OpDialog ref="opRef" @search="search" />
</div>
</template>
@ -111,10 +118,12 @@ import { dateFormat } from '@/utils/util';
import { onMounted, ref } from 'vue';
import { searchBackup, deleteBackup, refreshToken } from '@/api/modules/backup';
import Operate from '@/views/setting/backup-account/operate/index.vue';
import DetailShow from '@/components/detail-show/index.vue';
import { Backup } from '@/api/interface/backup';
import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message';
import { GlobalStore } from '@/store';
import { Base64 } from 'js-base64';
const globalStore = GlobalStore();
const loading = ref();
@ -129,6 +138,7 @@ const paginationConfig = reactive({
});
const opRef = ref();
const dialogRef = ref();
const detailRef = ref();
const search = async () => {
let params = {
@ -143,7 +153,7 @@ const search = async () => {
loading.value = false;
data.value = res.data.items || [];
for (const bac of data.value) {
if (bac.id !== 0) {
if (bac.vars) {
bac.varsJson = JSON.parse(bac.vars);
}
}
@ -192,6 +202,68 @@ const onOpenDialog = async (
dialogRef.value!.acceptParams(params);
};
const onInspect = (row: any) => {
let list = [];
list.push({ label: i18n.global.t('commons.table.name'), value: row.name, hideCopy: true });
list.push({
label: i18n.global.t('commons.table.type'),
value: i18n.global.t('setting.' + row.type),
hideCopy: true,
});
if (row.type === 'S3') {
list.push({ label: i18n.global.t('setting.mode'), value: row.varsJson['mode'] });
}
if (row.type === 'COS' || row.type === 'KODO' || row.type === 'MINIO' || row.type === 'OSS' || row.type === 'S3') {
if (row.rememberAuth) {
list.push({ label: 'Access Key ID', value: Base64.decode(row.accessKey) });
list.push({ label: 'Secret Key', value: Base64.decode(row.credential) });
}
}
if (row.type === 'UPYUN') {
if (row.rememberAuth) {
list.push({ label: i18n.global.t('setting.operator'), value: Base64.decode(row.accessKey) });
list.push({ label: i18n.global.t('commons.login.password'), value: Base64.decode(row.credential) });
}
}
if (row.type === 'WebDAV' || row.type === 'SFTP') {
list.push({ label: i18n.global.t('setting.address'), value: row.varsJson['address'] || '' });
list.push({ label: i18n.global.t('commons.login.username'), value: Base64.decode(row.accessKey) });
}
if (row.type === 'SFTP') {
list.push({ label: i18n.global.t('commons.table.port'), value: row.varsJson['port'] || '' });
if (row.rememberAuth) {
list.push({ label: i18n.global.t('terminal.authMode'), value: row.varsJson['authMode'] });
if (row.varsJson['authMode'] === 'key') {
list.push({ label: i18n.global.t('terminal.key'), value: Base64.decode(row.credential) });
list.push({ label: i18n.global.t('terminal.keyPassword'), value: row.varsJson['passPhrase'] });
} else {
list.push({ label: i18n.global.t('commons.login.password'), value: Base64.decode(row.credential) });
}
}
}
if (row.type === 'COS' || row.type === 'S3') {
list.push({ label: 'Region', value: row.varsJson['region'] || '' });
}
if (row.type === 'COS' || row.type === 'KODO' || row.type === 'MINIO' || row.type === 'OSS' || row.type === 'S3') {
list.push({
label: row.type === 'KODO' ? i18n.global.t('setting.domain') : 'Endpoint',
value: row.varsJson['endpoint'] || '',
});
list.push({ label: 'Bucket', value: row.bucket });
}
if (row.type === 'UPYUN') {
list.push({ label: i18n.global.t('setting.serviceName'), value: row.bucket });
}
if (row.type === 'COS' || row.type === 'OOS' || row.type === 'S3') {
list.push({ label: i18n.global.t('setting.scType'), value: row.varsJson['scType'] });
}
if (row.type === 'KODO') {
list.push({ label: i18n.global.t('cronjob.requestExpirationTime'), value: row.varsJson['timeout'] });
}
list.push({ label: i18n.global.t('setting.backupLabel'), value: row.backupPath });
detailRef.value.acceptParams({ list: list });
};
const refreshItemToken = async (row: any) => {
await refreshToken({ id: row.id, name: row.name, isPublic: row.isPublic });
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));