<!DOCTYPE html>
|
<html lang="zh-CN">
|
<head>
|
<meta charset="UTF-8">
|
<title>日志流水清理</title>
|
<meta name="renderer" content="webkit">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
<link rel="stylesheet" href="../../static/vue/element/element.css">
|
<link rel="stylesheet" href="../../static/css/cool.css">
|
<style>
|
[v-cloak] { display: none; }
|
html, body {
|
margin: 0;
|
min-height: 100%;
|
color: #243447;
|
font-family: "Avenir Next", "PingFang SC", "Microsoft YaHei", sans-serif;
|
background:
|
radial-gradient(1000px 420px at 0% -10%, rgba(44, 107, 193, 0.12), transparent 56%),
|
radial-gradient(900px 400px at 100% 0%, rgba(28, 150, 126, 0.10), transparent 58%),
|
linear-gradient(180deg, #f2f6fb 0%, #f8fafc 100%);
|
}
|
.page-shell {
|
max-width: 1380px;
|
margin: 0 auto;
|
padding: 14px;
|
box-sizing: border-box;
|
}
|
.card-shell {
|
border-radius: 24px;
|
border: 1px solid rgba(216, 226, 238, 0.95);
|
background: rgba(255, 255, 255, 0.94);
|
box-shadow: 0 16px 32px rgba(44, 67, 96, 0.08);
|
overflow: hidden;
|
}
|
.section-head {
|
padding: 18px 20px 10px;
|
border-bottom: 1px solid rgba(222, 230, 239, 0.92);
|
}
|
.section-title {
|
margin: 0;
|
font-size: 22px;
|
font-weight: 700;
|
}
|
.section-subtitle {
|
margin-top: 8px;
|
font-size: 13px;
|
color: #6c7d90;
|
}
|
.content-wrap {
|
padding: 18px 20px 20px;
|
}
|
.config-card,
|
.result-card {
|
border: 1px solid rgba(220, 229, 239, 0.96);
|
border-radius: 20px;
|
background: rgba(255, 255, 255, 0.96);
|
padding: 18px;
|
}
|
.result-card {
|
margin-top: 16px;
|
}
|
.inline-tip {
|
font-size: 12px;
|
color: #6f7d8c;
|
margin-left: 10px;
|
}
|
.table-tag-list {
|
display: flex;
|
flex-wrap: wrap;
|
gap: 8px;
|
}
|
@media (max-width: 900px) {
|
.page-shell {
|
padding: 10px;
|
}
|
.content-wrap,
|
.section-head {
|
padding-left: 14px;
|
padding-right: 14px;
|
}
|
}
|
</style>
|
</head>
|
<body>
|
<div id="app" class="page-shell" v-cloak>
|
<section class="card-shell">
|
<div class="section-head">
|
<h1 class="section-title">日志流水清理</h1>
|
<div class="section-subtitle">系统固定每天 23:00 自动清理过期日志。手动清理需要先在系统配置中获取最高权限授权。</div>
|
</div>
|
<div class="content-wrap" v-loading="loading">
|
<div class="config-card">
|
<el-alert
|
title="手动清理会按当前保留天数删除过期数据,不会删除保留期内日志。"
|
type="warning"
|
:closable="false"
|
show-icon
|
style="margin-bottom: 18px;">
|
</el-alert>
|
<el-form label-width="120px" size="small">
|
<el-form-item label="保留天数">
|
<el-input-number v-model="form.expireDays" :min="1" :step="1" controls-position="right"></el-input-number>
|
<span class="inline-tip">常用值:180、360</span>
|
</el-form-item>
|
<el-form-item label="自动清理时间">
|
<el-tag type="info">每日 23:00</el-tag>
|
</el-form-item>
|
<el-form-item label="手动清理模式">
|
<el-radio-group v-model="form.mode">
|
<el-radio label="all">所有日志表</el-radio>
|
<el-radio label="selected">指定日志表</el-radio>
|
</el-radio-group>
|
</el-form-item>
|
<el-form-item v-if="form.mode === 'selected'" label="日志表选择">
|
<el-select
|
v-model="form.tables"
|
multiple
|
collapse-tags
|
clearable
|
filterable
|
placeholder="请选择要清理的日志表"
|
style="width: 100%;">
|
<el-option
|
v-for="item in tableOptions"
|
:key="item.value"
|
:label="item.label + ' (' + item.value + ')'"
|
:value="item.value">
|
</el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" :loading="saving" @click="saveConfig">保存配置</el-button>
|
<el-button type="danger" plain :loading="running" @click="runCleanup">手动清理</el-button>
|
</el-form-item>
|
</el-form>
|
</div>
|
|
<div v-if="result" class="result-card">
|
<el-descriptions title="最近一次手动清理结果" :column="3" border size="small">
|
<el-descriptions-item label="清理模式">{{ result.mode === 'selected' ? '指定日志表' : '所有日志表' }}</el-descriptions-item>
|
<el-descriptions-item label="保留天数">{{ result.expireDays }}</el-descriptions-item>
|
<el-descriptions-item label="删除总数">{{ result.totalDeleted }}</el-descriptions-item>
|
</el-descriptions>
|
<div style="margin-top: 16px;" class="table-tag-list">
|
<el-tag
|
v-for="item in resultDetails"
|
:key="item.table"
|
type="success"
|
effect="plain">
|
{{ item.label }}: {{ item.count }}
|
</el-tag>
|
</div>
|
</div>
|
</div>
|
</section>
|
</div>
|
|
<script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
|
<script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script>
|
<script type="text/javascript" src="../../static/vue/js/vue.min.js"></script>
|
<script type="text/javascript" src="../../static/vue/element/element.js"></script>
|
<script type="text/javascript" src="../../static/js/logCleanup/logCleanup.js" charset="utf-8"></script>
|
</body>
|
</html>
|