mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-12-11 21:06:08 +08:00
fix: 计划任务部分 bug 修改
This commit is contained in:
parent
7fdffa6848
commit
4849fde8c9
10 changed files with 102 additions and 62 deletions
|
|
@ -93,4 +93,5 @@ type Record struct {
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
TargetPath string `json:"targetPath"`
|
TargetPath string `json:"targetPath"`
|
||||||
Interval int `json:"interval"`
|
Interval int `json:"interval"`
|
||||||
|
File string `json:"file"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,7 @@ func (u *CronjobRepo) EndRecords(record model.JobRecords, status, message, recor
|
||||||
errMap := make(map[string]interface{})
|
errMap := make(map[string]interface{})
|
||||||
errMap["records"] = records
|
errMap["records"] = records
|
||||||
errMap["status"] = status
|
errMap["status"] = status
|
||||||
|
errMap["file"] = record.File
|
||||||
errMap["message"] = message
|
errMap["message"] = message
|
||||||
errMap["interval"] = time.Since(record.StartTime).Milliseconds()
|
errMap["interval"] = time.Since(record.StartTime).Milliseconds()
|
||||||
if err := global.DB.Model(&model.JobRecords{}).Where("id = ?", record.ID).Updates(errMap).Error; err != nil {
|
if err := global.DB.Model(&model.JobRecords{}).Where("id = ?", record.ID).Updates(errMap).Error; err != nil {
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ func (u *CronjobService) HandleBackup(cronjob *model.Cronjob, startTime time.Tim
|
||||||
}
|
}
|
||||||
fileName = fileName + ".tar.gz"
|
fileName = fileName + ".tar.gz"
|
||||||
default:
|
default:
|
||||||
fileName = fmt.Sprintf("%s.tar.gz", startTime.Format("20060102150405"))
|
fileName = fmt.Sprintf("directory%s_%s.tar.gz", strings.ReplaceAll(cronjob.SourceDir, "/", "_"), startTime.Format("20060102150405"))
|
||||||
backupDir = fmt.Sprintf("%s/%s", cronjob.Type, cronjob.Name)
|
backupDir = fmt.Sprintf("%s/%s", cronjob.Type, cronjob.Name)
|
||||||
global.LOG.Infof("handle tar %s to %s", backupDir, fileName)
|
global.LOG.Infof("handle tar %s to %s", backupDir, fileName)
|
||||||
if err := handleTar(cronjob.SourceDir, baseDir+"/"+backupDir, fileName, cronjob.ExclusionRules); err != nil {
|
if err := handleTar(cronjob.SourceDir, baseDir+"/"+backupDir, fileName, cronjob.ExclusionRules); err != nil {
|
||||||
|
|
@ -214,10 +214,10 @@ func handleTar(sourceDir, targetDir, name, exclusionRules string) error {
|
||||||
if len(exclude) == 0 {
|
if len(exclude) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
excludeRules += (" --exclude" + exclude)
|
excludeRules += (" --exclude " + exclude)
|
||||||
}
|
}
|
||||||
path := ""
|
path := ""
|
||||||
if len(strings.Split(sourceDir, "/")) > 3 {
|
if strings.Contains(sourceDir, "/") {
|
||||||
itemDir := strings.ReplaceAll(sourceDir[strings.LastIndex(sourceDir, "/"):], "/", "")
|
itemDir := strings.ReplaceAll(sourceDir[strings.LastIndex(sourceDir, "/"):], "/", "")
|
||||||
aheadDir := strings.ReplaceAll(sourceDir, itemDir, "")
|
aheadDir := strings.ReplaceAll(sourceDir, itemDir, "")
|
||||||
path += fmt.Sprintf("-C %s %s", aheadDir, itemDir)
|
path += fmt.Sprintf("-C %s %s", aheadDir, itemDir)
|
||||||
|
|
@ -225,6 +225,7 @@ func handleTar(sourceDir, targetDir, name, exclusionRules string) error {
|
||||||
path = sourceDir
|
path = sourceDir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
global.LOG.Debugf("tar zcvf %s %s %s \n", targetDir+"/"+name, excludeRules, path)
|
||||||
stdout, err := cmd.Execf("tar zcvf %s %s %s", targetDir+"/"+name, excludeRules, path)
|
stdout, err := cmd.Execf("tar zcvf %s %s %s", targetDir+"/"+name, excludeRules, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New(string(stdout))
|
return errors.New(string(stdout))
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,19 @@ const checkImageName = (rule: any, value: any, callback: any) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const checkVolumeName = (rule: any, value: any, callback: any) => {
|
||||||
|
if (value === '' || typeof value === 'undefined' || value == null) {
|
||||||
|
callback(new Error(i18n.global.t('commons.rule.volumeName')));
|
||||||
|
} else {
|
||||||
|
const reg = /^[a-zA-Z0-9]{1}[a-z:A-Z0-9_.-]{0,30}$/;
|
||||||
|
if (!reg.test(value) && value !== '') {
|
||||||
|
callback(new Error(i18n.global.t('commons.rule.volumeName')));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const checkLinuxName = (rule: any, value: any, callback: any) => {
|
const checkLinuxName = (rule: any, value: any, callback: any) => {
|
||||||
if (value === '' || typeof value === 'undefined' || value == null) {
|
if (value === '' || typeof value === 'undefined' || value == null) {
|
||||||
callback(new Error(i18n.global.t('commons.rule.linuxName', ['/\\:*?"<>|'])));
|
callback(new Error(i18n.global.t('commons.rule.linuxName', ['/\\:*?"<>|'])));
|
||||||
|
|
@ -128,6 +141,7 @@ interface CommonRule {
|
||||||
simpleName: FormItemRule;
|
simpleName: FormItemRule;
|
||||||
dbName: FormItemRule;
|
dbName: FormItemRule;
|
||||||
imageName: FormItemRule;
|
imageName: FormItemRule;
|
||||||
|
volumeName: FormItemRule;
|
||||||
linuxName: FormItemRule;
|
linuxName: FormItemRule;
|
||||||
password: FormItemRule;
|
password: FormItemRule;
|
||||||
email: FormItemRule;
|
email: FormItemRule;
|
||||||
|
|
@ -172,6 +186,11 @@ export const Rules: CommonRule = {
|
||||||
validator: checkImageName,
|
validator: checkImageName,
|
||||||
trigger: 'blur',
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
|
volumeName: {
|
||||||
|
required: true,
|
||||||
|
validator: checkVolumeName,
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
name: {
|
name: {
|
||||||
required: true,
|
required: true,
|
||||||
validator: checkName,
|
validator: checkName,
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,7 @@ export default {
|
||||||
simpleName: 'Support English, numbers and _ length 1-30',
|
simpleName: 'Support English, numbers and _ length 1-30',
|
||||||
dbName: 'Support English, Chinese, numbers, .-, and _ length 1-16',
|
dbName: 'Support English, Chinese, numbers, .-, and _ length 1-16',
|
||||||
imageName: 'Support English, Chinese, numbers, :.-_, length 1-30',
|
imageName: 'Support English, Chinese, numbers, :.-_, length 1-30',
|
||||||
|
volumeName: 'Support English, numbers, .-_, length 1-30',
|
||||||
complexityPassword:
|
complexityPassword:
|
||||||
'Please enter a password with more than 8 characters and must contain letters, digits, and special symbols',
|
'Please enter a password with more than 8 characters and must contain letters, digits, and special symbols',
|
||||||
commonPassword: 'Please enter a password with more than 6 characters',
|
commonPassword: 'Please enter a password with more than 6 characters',
|
||||||
|
|
@ -526,18 +527,18 @@ export default {
|
||||||
enableMsg: 'The cronjob has been stopped. Enable now?',
|
enableMsg: 'The cronjob has been stopped. Enable now?',
|
||||||
taskType: 'Task type',
|
taskType: 'Task type',
|
||||||
record: 'Records',
|
record: 'Records',
|
||||||
shell: 'shell',
|
shell: 'Shell script',
|
||||||
website: 'website',
|
website: 'Backup website',
|
||||||
rulesHelper: 'Compression exclusion rules (with; Is a delimiter), for example: \n*.log; *.sql',
|
rulesHelper: 'Compression exclusion rules (with; Is a delimiter), for example: \n*.log; *.sql',
|
||||||
lastRecrodTime: 'Last execution time',
|
lastRecrodTime: 'Last execution time',
|
||||||
all: 'All',
|
all: 'All',
|
||||||
failedRecord: 'Failed records',
|
failedRecord: 'Failed records',
|
||||||
successRecord: 'Successful records',
|
successRecord: 'Successful records',
|
||||||
database: 'database',
|
database: 'Backup database',
|
||||||
missBackupAccount: 'The backup account could not be found',
|
missBackupAccount: 'The backup account could not be found',
|
||||||
syncDate: 'Synchronization time ',
|
syncDate: 'Synchronization time ',
|
||||||
releaseMemory: 'Free memory',
|
releaseMemory: 'Free memory',
|
||||||
curl: 'Crul',
|
curl: 'Access URL',
|
||||||
taskName: 'Task name',
|
taskName: 'Task name',
|
||||||
cronSpec: 'Lifecycle',
|
cronSpec: 'Lifecycle',
|
||||||
directory: 'Backup directory',
|
directory: 'Backup directory',
|
||||||
|
|
@ -548,9 +549,9 @@ export default {
|
||||||
target: 'Target',
|
target: 'Target',
|
||||||
retainCopies: 'Retain copies',
|
retainCopies: 'Retain copies',
|
||||||
cronSpecRule: 'Please enter a correct lifecycle',
|
cronSpecRule: 'Please enter a correct lifecycle',
|
||||||
perMonth: 'Per monthly',
|
perMonth: 'Every monthly',
|
||||||
perWeek: 'Per week',
|
perWeek: 'Every week',
|
||||||
perHour: 'Per hour',
|
perHour: 'Every hour',
|
||||||
perNDay: 'Every N days',
|
perNDay: 'Every N days',
|
||||||
perDay: 'Every days',
|
perDay: 'Every days',
|
||||||
perNHour: 'Every N hours',
|
perNHour: 'Every N hours',
|
||||||
|
|
@ -572,6 +573,8 @@ export default {
|
||||||
errRecord: 'Incorrect logging',
|
errRecord: 'Incorrect logging',
|
||||||
errHandle: 'Task execution failure',
|
errHandle: 'Task execution failure',
|
||||||
noRecord: 'The execution did not generate any logs',
|
noRecord: 'The execution did not generate any logs',
|
||||||
|
noLogs: 'No task output yet...',
|
||||||
|
errPath: 'Backup path [{0}] error, cannot download!',
|
||||||
},
|
},
|
||||||
monitor: {
|
monitor: {
|
||||||
avgLoad: 'Average load',
|
avgLoad: 'Average load',
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,7 @@ export default {
|
||||||
simpleName: '支持英文、数字、_,长度1-30',
|
simpleName: '支持英文、数字、_,长度1-30',
|
||||||
dbName: '支持英文、中文、数字、.-_,长度1-16',
|
dbName: '支持英文、中文、数字、.-_,长度1-16',
|
||||||
imageName: '支持英文、中文、数字、:.-_,长度1-30',
|
imageName: '支持英文、中文、数字、:.-_,长度1-30',
|
||||||
|
volumeName: '支持英文、数字、.-和_,长度1-30',
|
||||||
complexityPassword: '请输入 8 位以上、必须含有字母、数字、特殊符号的密码',
|
complexityPassword: '请输入 8 位以上、必须含有字母、数字、特殊符号的密码',
|
||||||
commonPassword: '请输入 6 位以上长度密码',
|
commonPassword: '请输入 6 位以上长度密码',
|
||||||
linuxName: '长度1-30,名称不能含有{0}等符号',
|
linuxName: '长度1-30,名称不能含有{0}等符号',
|
||||||
|
|
@ -581,6 +582,8 @@ export default {
|
||||||
errRecord: '错误的日志记录',
|
errRecord: '错误的日志记录',
|
||||||
errHandle: '任务执行失败',
|
errHandle: '任务执行失败',
|
||||||
noRecord: '当前计划任务暂未产生记录',
|
noRecord: '当前计划任务暂未产生记录',
|
||||||
|
noLogs: '暂无任务输出...',
|
||||||
|
errPath: '备份路径 [{0}] 错误,无法下载!',
|
||||||
},
|
},
|
||||||
monitor: {
|
monitor: {
|
||||||
avgLoad: '平均负载',
|
avgLoad: '平均负载',
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ const search = async () => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
data.value = res.data.items || [];
|
data.value = res.data.items || [];
|
||||||
for (const item of data.value) {
|
for (const item of data.value) {
|
||||||
if (item.targetDir !== '-' || item.targetDir !== '') {
|
if (item.targetDir !== '-' && item.targetDir !== '') {
|
||||||
item.targetDir = i18n.global.t('setting.' + item.targetDir);
|
item.targetDir = i18n.global.t('setting.' + item.targetDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="dialogData.rowData!.type === 'website' || dialogData.rowData!.type === 'directory'"
|
v-if="dialogData.rowData!.type === 'directory'"
|
||||||
:label="$t('cronjob.exclusionRules')"
|
:label="$t('cronjob.exclusionRules')"
|
||||||
prop="exclusionRules"
|
prop="exclusionRules"
|
||||||
>
|
>
|
||||||
|
|
@ -282,7 +282,7 @@ const weekOptions = [
|
||||||
{ label: i18n.global.t('cronjob.sunday'), value: 7 },
|
{ label: i18n.global.t('cronjob.sunday'), value: 7 },
|
||||||
];
|
];
|
||||||
const rules = reactive({
|
const rules = reactive({
|
||||||
name: [Rules.requiredInput, Rules.name],
|
name: [Rules.requiredInput],
|
||||||
type: [Rules.requiredSelect],
|
type: [Rules.requiredSelect],
|
||||||
specType: [Rules.requiredSelect],
|
specType: [Rules.requiredSelect],
|
||||||
spec: [
|
spec: [
|
||||||
|
|
|
||||||
|
|
@ -183,7 +183,7 @@
|
||||||
style="margin-left: 10px"
|
style="margin-left: 10px"
|
||||||
link
|
link
|
||||||
icon="Download"
|
icon="Download"
|
||||||
@click="onDownload(currentRecord!.id, dialogData.rowData!.targetDirID)"
|
@click="onDownload(currentRecord, dialogData.rowData!.targetDirID)"
|
||||||
>
|
>
|
||||||
{{ $t('file.download') }}
|
{{ $t('file.download') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
@ -253,7 +253,7 @@
|
||||||
<codemirror
|
<codemirror
|
||||||
ref="mymirror"
|
ref="mymirror"
|
||||||
:autofocus="true"
|
:autofocus="true"
|
||||||
placeholder="None data"
|
:placeholder="$t('cronjob.noLogs')"
|
||||||
:indent-with-tab="true"
|
:indent-with-tab="true"
|
||||||
:tabSize="4"
|
:tabSize="4"
|
||||||
style="height: 130px; width: 100%; margin-top: 5px"
|
style="height: 130px; width: 100%; margin-top: 5px"
|
||||||
|
|
@ -288,7 +288,7 @@ import { reactive, ref } from 'vue';
|
||||||
import { Cronjob } from '@/api/interface/cronjob';
|
import { Cronjob } from '@/api/interface/cronjob';
|
||||||
import { loadZero } from '@/utils/util';
|
import { loadZero } from '@/utils/util';
|
||||||
import { searchRecords, download, handleOnce, updateStatus } from '@/api/modules/cronjob';
|
import { searchRecords, download, handleOnce, updateStatus } from '@/api/modules/cronjob';
|
||||||
import { dateFormat, dateFormatForName } from '@/utils/util';
|
import { dateFormat } from '@/utils/util';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { ElMessageBox } from 'element-plus';
|
import { ElMessageBox } from 'element-plus';
|
||||||
import { LoadFile } from '@/api/modules/files';
|
import { LoadFile } from '@/api/modules/files';
|
||||||
|
|
@ -296,7 +296,7 @@ import LayoutContent from '@/layout/layout-content.vue';
|
||||||
import { Codemirror } from 'vue-codemirror';
|
import { Codemirror } from 'vue-codemirror';
|
||||||
import { javascript } from '@codemirror/lang-javascript';
|
import { javascript } from '@codemirror/lang-javascript';
|
||||||
import { oneDark } from '@codemirror/theme-one-dark';
|
import { oneDark } from '@codemirror/theme-one-dark';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||||
|
|
||||||
const loading = ref();
|
const loading = ref();
|
||||||
const hasRecords = ref();
|
const hasRecords = ref();
|
||||||
|
|
@ -334,7 +334,7 @@ const acceptParams = async (params: DialogProps): Promise<void> => {
|
||||||
hasRecords.value = true;
|
hasRecords.value = true;
|
||||||
currentRecord.value = records.value[0];
|
currentRecord.value = records.value[0];
|
||||||
currentRecordIndex.value = 0;
|
currentRecordIndex.value = 0;
|
||||||
loadRecord(currentRecord.value.records);
|
loadRecord(currentRecord.value);
|
||||||
searchInfo.recordTotal = res.data.total;
|
searchInfo.recordTotal = res.data.total;
|
||||||
recordShow.value = true;
|
recordShow.value = true;
|
||||||
};
|
};
|
||||||
|
|
@ -446,13 +446,26 @@ const search = async () => {
|
||||||
endTime: searchInfo.endTime,
|
endTime: searchInfo.endTime,
|
||||||
status: searchInfo.status,
|
status: searchInfo.status,
|
||||||
};
|
};
|
||||||
|
records.value = [];
|
||||||
const res = await searchRecords(params);
|
const res = await searchRecords(params);
|
||||||
records.value = res.data.items || [];
|
if (!res.data.items) {
|
||||||
|
hasRecords.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
records.value = res.data.items;
|
||||||
|
hasRecords.value = true;
|
||||||
|
currentRecord.value = records.value[0];
|
||||||
|
currentRecordIndex.value = 0;
|
||||||
|
loadRecord(currentRecord.value);
|
||||||
searchInfo.recordTotal = res.data.total;
|
searchInfo.recordTotal = res.data.total;
|
||||||
};
|
};
|
||||||
const onDownload = async (recordID: number, backupID: number) => {
|
const onDownload = async (record: any, backupID: number) => {
|
||||||
|
if (!record.file || record.file.indexOf('/') === -1) {
|
||||||
|
MsgError(i18n.global.t('cronjob.errPath', [record.file]));
|
||||||
|
return;
|
||||||
|
}
|
||||||
let params = {
|
let params = {
|
||||||
recordID: recordID,
|
recordID: record.id,
|
||||||
backupAccountID: backupID,
|
backupAccountID: backupID,
|
||||||
};
|
};
|
||||||
const res = await download(params);
|
const res = await download(params);
|
||||||
|
|
@ -460,15 +473,9 @@ const onDownload = async (recordID: number, backupID: number) => {
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
a.style.display = 'none';
|
a.style.display = 'none';
|
||||||
a.href = downloadUrl;
|
a.href = downloadUrl;
|
||||||
if (dialogData.value.rowData!.type === 'database') {
|
if (record.file && record.file.indexOf('/') !== -1) {
|
||||||
a.download =
|
let pathItem = record.file.split('/');
|
||||||
dialogData.value.rowData!.dbName + '_' + dateFormatForName(currentRecord.value?.startTime) + '.sql.gz';
|
a.download = pathItem[pathItem.length - 1];
|
||||||
} else if (dialogData.value.rowData!.type === 'website') {
|
|
||||||
a.download =
|
|
||||||
dialogData.value.rowData!.website + '_' + dateFormatForName(currentRecord.value?.startTime) + '.tar.gz';
|
|
||||||
} else {
|
|
||||||
let name = dialogData.value.rowData!.sourceDir.replaceAll('/', '_');
|
|
||||||
a.download = name + '_' + dateFormatForName(currentRecord.value?.startTime) + '.tar.gz';
|
|
||||||
}
|
}
|
||||||
const event = new MouseEvent('click');
|
const event = new MouseEvent('click');
|
||||||
a.dispatchEvent(event);
|
a.dispatchEvent(event);
|
||||||
|
|
@ -484,11 +491,15 @@ const nextPage = async () => {
|
||||||
const forDetail = async (row: Cronjob.Record, index: number) => {
|
const forDetail = async (row: Cronjob.Record, index: number) => {
|
||||||
currentRecord.value = row;
|
currentRecord.value = row;
|
||||||
currentRecordIndex.value = index;
|
currentRecordIndex.value = index;
|
||||||
loadRecord(row.records);
|
loadRecord(row);
|
||||||
};
|
};
|
||||||
const loadRecord = async (path: string) => {
|
const loadRecord = async (row: Cronjob.Record) => {
|
||||||
if (path) {
|
if (row.status === 'Failed') {
|
||||||
const res = await LoadFile({ path: path });
|
currentRecordDetail.value = row.records;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (row.records) {
|
||||||
|
const res = await LoadFile({ path: row.records });
|
||||||
currentRecordDetail.value = res.data;
|
currentRecordDetail.value = res.data;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -521,7 +532,6 @@ defineExpose({
|
||||||
height: 310px;
|
height: 310px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
list-style: none;
|
|
||||||
}
|
}
|
||||||
.infinite-list .infinite-list-item {
|
.infinite-list .infinite-list-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
||||||
|
|
@ -1,52 +1,54 @@
|
||||||
<template>
|
<template>
|
||||||
<el-row>
|
<div>
|
||||||
<el-col :span="22" :offset="1">
|
<el-form label-position="top">
|
||||||
<el-descriptions :column="4" direction="vertical">
|
<el-row type="flex" style="margin-left: 50px" justify="center">
|
||||||
<el-descriptions-item>
|
<el-form-item style="width: 25%">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span class="status-label">{{ $t('nginx.connections') }}</span>
|
<span class="status-label">{{ $t('database.connections') }}</span>
|
||||||
</template>
|
</template>
|
||||||
<span class="status-count">{{ data.active }}</span>
|
<span class="status-count">{{ data.active }}</span>
|
||||||
</el-descriptions-item>
|
</el-form-item>
|
||||||
<el-descriptions-item>
|
<el-form-item style="width: 25%">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span class="status-label">{{ $t('nginx.accepts') }}</span>
|
<span class="status-label">{{ $t('database.accepts') }}</span>
|
||||||
</template>
|
</template>
|
||||||
<span class="status-count">{{ data.accepts }}</span>
|
<span class="status-count">{{ data.accepts }}</span>
|
||||||
</el-descriptions-item>
|
</el-form-item>
|
||||||
<el-descriptions-item>
|
<el-form-item style="width: 25%">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span class="status-label">{{ $t('nginx.handled') }}</span>
|
<span class="status-label">{{ $t('database.handled') }}</span>
|
||||||
</template>
|
</template>
|
||||||
<span class="status-count">{{ data.handled }}</span>
|
<span class="status-count">{{ data.handled }}</span>
|
||||||
</el-descriptions-item>
|
</el-form-item>
|
||||||
<el-descriptions-item>
|
<el-form-item style="width: 25%">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span class="status-label">{{ $t('nginx.requests') }}</span>
|
<span class="status-label">{{ $t('database.requests') }}</span>
|
||||||
</template>
|
</template>
|
||||||
<span class="status-count">{{ data.requests }}</span>
|
<span class="status-count">{{ data.requests }}</span>
|
||||||
</el-descriptions-item>
|
</el-form-item>
|
||||||
<el-descriptions-item>
|
|
||||||
|
<el-form-item style="width: 25%">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span class="status-label">{{ $t('nginx.reading') }}</span>
|
<span class="status-label">{{ $t('database.reading') }}</span>
|
||||||
</template>
|
</template>
|
||||||
<span class="status-count">{{ data.reading }}</span>
|
<span class="status-count">{{ data.reading }}</span>
|
||||||
</el-descriptions-item>
|
</el-form-item>
|
||||||
<el-descriptions-item>
|
<el-form-item style="width: 25%">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span class="status-label">{{ $t('nginx.writing') }}</span>
|
<span class="status-label">{{ $t('database.writing') }}</span>
|
||||||
</template>
|
</template>
|
||||||
<span class="status-count">{{ data.writing }}</span>
|
<span class="status-count">{{ data.writing }}</span>
|
||||||
</el-descriptions-item>
|
</el-form-item>
|
||||||
<el-descriptions-item>
|
<el-form-item style="width: 25%">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span class="status-label">{{ $t('nginx.waiting') }}</span>
|
<span class="status-label">{{ $t('database.waiting') }}</span>
|
||||||
</template>
|
</template>
|
||||||
<span class="status-count">{{ data.waiting }}</span>
|
<span class="status-count">{{ data.waiting }}</span>
|
||||||
</el-descriptions-item>
|
</el-form-item>
|
||||||
</el-descriptions>
|
<el-form-item style="width: 25%" />
|
||||||
</el-col>
|
</el-row>
|
||||||
</el-row>
|
</el-form>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue