html
复制代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Cron 表达式参考</title>
<link rel="stylesheet" href="/lib/layui-v2.10.2/css/layui.css">
<style>
body {
background: #f2f2f2;
padding: 20px;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
.header {
background: white;
padding: 5px 0px;
border-radius: 10px;
margin-bottom: 20px;
box-shadow: 0 4px 12px rgba(0,0,0,0.05);
text-align: center;
}
.header h1 {
color: #333;
margin-bottom: 10px;
font-size: 20px;
font-weight: 600;
}
.header .desc {
color: #666;
font-size: 14px;
line-height: 1.6;
}
.main-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
gap: 18px;
margin-top: 20px;
}
.expression-card {
background: white;
border-radius: 10px;
padding: 10px;
box-shadow: 0 3px 10px rgba(0,0,0,0.06);
border: 1px solid #f0f0f0;
transition: all 0.3s ease;
position: relative;
}
.expression-card:hover {
box-shadow: 0 5px 15px rgba(0,0,0,0.08);
transform: translateY(-2px);
border-color: #e6f7ff;
}
.cron-code {
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
font-size: 16px;
font-weight: 600;
color: #1890ff;
background: #f0f9ff;
padding: 10px 10px;
border-radius: 6px;
/* border-left: 3px solid #1890ff; */
margin-bottom: 12px;
word-break: break-all;
display: flex;
justify-content: space-between;
align-items: center;
}
.copy-btn {
background: #1890ff;
color: white;
border: none;
border-radius: 4px;
padding: 5px 12px;
font-size: 12px;
cursor: pointer;
transition: all 0.2s;
}
.copy-btn:hover {
background: #40a9ff;
transform: scale(1.05);
}
.copy-btn.copied {
background: #52c41a;
}
.expression-info {
/* margin-top: 8px; */
}
.expression-name {
font-weight: 600;
color: #333;
font-size: 15px;
margin-bottom: 5px;
}
.expression-desc {
color: #666;
font-size: 13px;
line-height: 1.5;
}
.time-tag {
position: absolute;
top: 15px;
right: 15px;
background: #f6ffed;
color: #52c41a;
font-size: 11px;
padding: 2px 8px;
border-radius: 10px;
border: 1px solid #b7eb8f;
}
.minute-tag {
background: #f0f9ff;
color: #1890ff;
border-color: #91d5ff;
}
.stats-bar {
background: white;
padding: 15px 20px;
border-radius: 10px;
margin-top: 20px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 2px 8px rgba(0,0,0,0.04);
}
.total-count {
color: #666;
font-size: 14px;
}
.total-count span {
color: #1890ff;
font-weight: bold;
font-size: 18px;
}
.action-buttons {
display: flex;
gap: 10px;
}
.json-modal pre {
background: #f8f9fa;
padding: 20px;
border-radius: 6px;
max-height: 400px;
overflow: auto;
font-family: 'Consolas', 'Monaco', monospace;
font-size: 13px;
}
.search-box {
margin: 15px 0;
}
.search-box input {
width: 80%;
padding: 12px 15px;
border: 1px solid #ddd;
border-radius: 6px;
font-size: 14px;
transition: all 0.3s;
}
.search-box input:focus {
outline: none;
border-color: #1890ff;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.1);
}
/* 动画效果 */
@keyframes copySuccess {
0% { transform: scale(1); }
50% { transform: scale(1.1); }
100% { transform: scale(1); }
}
.copy-animation {
animation: copySuccess 0.3s ease;
}
/* 加载动画 */
.loading {
text-align: center;
padding: 40px;
color: #999;
}
.empty-result {
text-align: center;
padding: 40px;
color: #999;
grid-column: 1 / -1;
}
</style>
</head>
<body>
<div class="container">
<!-- 页面头部 -->
<div class="header">
<h1>📅 Quartz Cron 表达式参考表</h1>
<!-- <div class="desc">
包含每分钟执行和每天1-24点整点执行的表达式,点击复制按钮可直接使用
</div> -->
<!-- 搜索框 -->
<div class="search-box">
<input type="text" id="searchInput" placeholder="搜索表达式或说明... (支持模糊搜索)"
onkeyup="searchExpressions()">
</div>
</div>
<!-- 表达式网格 -->
<div class="main-grid" id="expressionGrid">
<!-- 这里通过JS动态生成 -->
<div class="loading">加载中...</div>
</div>
<!-- 统计和操作栏 -->
<div class="stats-bar">
<div class="total-count">
共 <span id="displayCount">0</span> 个表达式
</div>
<div class="action-buttons">
<button class="layui-btn layui-btn-primary layui-btn-sm" onclick="copyAllExpressions()">
<i class="layui-icon layui-icon-copy"></i> 复制全部
</button>
<button class="layui-btn layui-btn-sm" onclick="showJsonModal()">
<i class="layui-icon layui-icon-template-1"></i> JSON数据
</button>
<button class="layui-btn layui-btn-sm layui-btn-normal" onclick="exportToFile()">
<i class="layui-icon layui-icon-download-circle"></i> 导出
</button>
</div>
</div>
</div>
<!-- 引入 LayUI -->
<script src="/lib/layui-v2.10.2/layui.js"></script>
<script>
// JSON 数据
const cronData = {
"expressions": [
{
"id": "minute",
"name": "每分钟执行",
"cron": "0 */1 * * * ?",
"description": "每分钟的第0秒执行一次",
"type": "minute"
},
{
"id": "hourly_1",
"name": "凌晨1点",
"cron": "0 0 1 * * ?",
"description": "每天凌晨1点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_2",
"name": "凌晨2点",
"cron": "0 0 2 * * ?",
"description": "每天凌晨2点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_3",
"name": "凌晨3点",
"cron": "0 0 3 * * ?",
"description": "每天凌晨3点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_4",
"name": "凌晨4点",
"cron": "0 0 4 * * ?",
"description": "每天凌晨4点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_5",
"name": "凌晨5点",
"cron": "0 0 5 * * ?",
"description": "每天凌晨5点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_6",
"name": "早上6点",
"cron": "0 0 6 * * ?",
"description": "每天早上6点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_7",
"name": "早上7点",
"cron": "0 0 7 * * ?",
"description": "每天早上7点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_8",
"name": "早上8点",
"cron": "0 0 8 * * ?",
"description": "每天早上8点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_9",
"name": "上午9点",
"cron": "0 0 9 * * ?",
"description": "每天上午9点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_10",
"name": "上午10点",
"cron": "0 0 10 * * ?",
"description": "每天上午10点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_11",
"name": "上午11点",
"cron": "0 0 11 * * ?",
"description": "每天上午11点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_12",
"name": "中午12点",
"cron": "0 0 12 * * ?",
"description": "每天中午12点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_13",
"name": "下午1点",
"cron": "0 0 13 * * ?",
"description": "每天下午1点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_14",
"name": "下午2点",
"cron": "0 0 14 * * ?",
"description": "每天下午2点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_15",
"name": "下午3点",
"cron": "0 0 15 * * ?",
"description": "每天下午3点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_16",
"name": "下午4点",
"cron": "0 0 16 * * ?",
"description": "每天下午4点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_17",
"name": "下午5点",
"cron": "0 0 17 * * ?",
"description": "每天下午5点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_18",
"name": "晚上6点",
"cron": "0 0 18 * * ?",
"description": "每天晚上6点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_19",
"name": "晚上7点",
"cron": "0 0 19 * * ?",
"description": "每天晚上7点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_20",
"name": "晚上8点",
"cron": "0 0 20 * * ?",
"description": "每天晚上8点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_21",
"name": "晚上9点",
"cron": "0 0 21 * * ?",
"description": "每天晚上9点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_22",
"name": "晚上10点",
"cron": "0 0 22 * * ?",
"description": "每天晚上10点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_23",
"name": "晚上11点",
"cron": "0 0 23 * * ?",
"description": "每天晚上11点0分0秒执行",
"type": "hourly"
},
{
"id": "hourly_24",
"name": "晚上12点",
"cron": "0 0 24 * * ?",
"description": "每天晚上12点0分0秒执行",
"type": "hourly"
}
]
};
// 全局变量
let currentExpressions = [...cronData.expressions];
// 初始化页面
layui.use(['layer', 'util'], function() {
var layer = layui.layer;
var util = layui.util;
// 渲染表达式列表
renderExpressionCards();
// 初始化固定条
util.fixbar({
// bar1: '',
// bar2: '',
bgcolor: '#1890ff',
click: function(type){
// if(type === 'bar1'){
// copyAllExpressions();
// } else if(type === 'bar2'){
// window.scrollTo(0, 0);
// }
}
});
// 设置搜索框焦点
setTimeout(() => {
document.getElementById('searchInput').focus();
}, 300);
});
// 渲染表达式卡片
function renderExpressionCards() {
const grid = document.getElementById('expressionGrid');
if (currentExpressions.length === 0) {
grid.innerHTML = '<div class="empty-result">未找到匹配的表达式</div>';
updateCount();
return;
}
let html = '';
currentExpressions.forEach(expr => {
const timeTag = expr.type === 'minute' ?
'<span class="time-tag minute-tag">每分钟</span>' :
`<span class="time-tag">${expr.name}</span>`;
// html += `
// <div class="expression-card">
// ${timeTag}
// <div class="cron-code">
// <span>${expr.cron}</span>
// <button class="copy-btn" onclick="copyExpression('${expr.cron}', this)">
// 复制
// </button>
// </div>
// <div class="expression-info">
// <div class="expression-name">${expr.name}</div>
// <div class="expression-desc">${expr.description}</div>
// </div>
// </div>
// `;
html += `
<div class="expression-card">
<div class="cron-code">
<span>${expr.cron}</span>
<button class="copy-btn" onclick="copyExpression('${expr.cron}', this)">
复制
</button>
</div>
<div class="expression-info">
<div class="expression-name">${expr.name}</div>
</div>
</div>
`;
});
grid.innerHTML = html;
updateCount();
}
// 更新显示计数
function updateCount() {
document.getElementById('displayCount').textContent = currentExpressions.length;
}
// 搜索表达式
function searchExpressions() {
const searchTerm = document.getElementById('searchInput').value.toLowerCase().trim();
if (!searchTerm) {
currentExpressions = [...cronData.expressions];
} else {
currentExpressions = cronData.expressions.filter(expr => {
return expr.cron.toLowerCase().includes(searchTerm) ||
expr.name.toLowerCase().includes(searchTerm) ||
expr.description.toLowerCase().includes(searchTerm);
});
}
renderExpressionCards();
}
// 复制单个表达式
function copyExpression(cron, button) {
// 创建临时输入框
const textarea = document.createElement('textarea');
textarea.value = cron;
document.body.appendChild(textarea);
textarea.select();
try {
const successful = document.execCommand('copy');
if (successful) {
// 添加动画效果
button.classList.add('copy-animation');
button.classList.add('copied');
button.textContent = '已复制';
setTimeout(() => {
button.classList.remove('copy-animation');
button.classList.remove('copied');
button.textContent = '复制';
}, 1500);
// 显示小提示
layui.use('layer', function() {
layui.layer.msg(`已复制: ${cron}`, {
time: 1000,
offset: 't'
});
});
}
} catch (err) {
console.error('复制失败:', err);
layui.use('layer', function() {
layui.layer.msg('复制失败,请手动复制', { icon: 2 });
});
}
document.body.removeChild(textarea);
}
// 复制所有表达式
function copyAllExpressions() {
let allText = '';
currentExpressions.forEach(expr => {
allText += `${expr.cron}\t${expr.name}\t${expr.description}\n`;
});
// 创建临时输入框
const textarea = document.createElement('textarea');
textarea.value = allText;
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
layui.use('layer', function() {
layui.layer.msg(`已复制 ${currentExpressions.length} 个表达式到剪贴板`, {
icon: 1,
time: 2000
});
});
} catch (err) {
console.error('复制失败:', err);
layui.use('layer', function() {
layui.layer.msg('复制失败,请手动复制', { icon: 2 });
});
}
document.body.removeChild(textarea);
}
// 显示JSON数据模态框
function showJsonModal() {
const jsonStr = JSON.stringify(cronData, null, 2);
layui.use('layer', function() {
var layer = layui.layer;
layer.open({
type: 1,
title: 'JSON 数据源',
area: ['90%', '80%'],
content: '<div class="json-modal"><pre>' + jsonStr + '</pre></div>',
btn: ['复制JSON', '关闭'],
yes: function(index, layero) {
const textarea = document.createElement('textarea');
textarea.value = jsonStr;
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
layer.msg('JSON已复制到剪贴板', { icon: 1 });
}
});
});
}
// 导出为文件
function exportToFile() {
let content = 'Quartz Cron 表达式参考\n';
content += '生成时间: ' + new Date().toLocaleString() + '\n';
content += '========================================\n\n';
currentExpressions.forEach(expr => {
content += `表达式: ${expr.cron}\n`;
content += `名称: ${expr.name}\n`;
content += `说明: ${expr.description}\n`;
content += `类型: ${expr.type === 'minute' ? '每分钟执行' : '整点执行'}\n`;
content += '----------------------------------------\n';
});
const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `cron-expressions-${new Date().toISOString().slice(0,10)}.txt`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
layui.use('layer', function() {
layui.layer.msg('文件导出成功', { icon: 1 });
});
}
</script>
</body>
</html>