首先说下做这个的目的,因为在工作中各种项目杂事太多,需要经常有个人提醒 事情的进度和完成时间,但又不是可以请秘书的职位,网上项目管理的软件又大设置也麻烦,本地的又不能能过微信或其他方式在线提醒,所以我就想着用AI软件自己试着生成一个任务提醒功能的小页面,并且能通过像server酱,TG这一类的消息提醒服务推送提醒。第一步前端的任务页面做了,但到了对接微信提醒服务的时候,搞不定了,有没大佬指教下,谢谢!图标库用的在线公共库的,所以显示有点慢。
测试网址如下:https://dm.848521.xyz/
代码如下:
<!DOCTYPE html>
<html lang=“zh-CN”>
<head>
<meta charset=“UTF-8”>
<title>智能桌面提醒工具</title>
<link href=“https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0/css/bootstrap.min.css” rel=“stylesheet”>
<link rel=“stylesheet” href=“https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css”>
<style>
.task-card {
transition: all 0.3s;
border-left: 4px solid transparent;
}
.task-card:hover {
transform: translateY(-3px);
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
border-left-color: #0d6efd;
}
.completed {
background-color: #f8f9fa;
opacity: 0.6;
border-left-color: #6c757d !important;
}
.countdown {
font-size: 0.9em;
color: #666;
display: inline-flex;
align-items: center;
gap: 5px;
}
.urgent {
color: #dc3545;
font-weight: bold;
animation: pulse 1s infinite;
}
@keyframes pulse {
0% { opacity: 1; }
50% { opacity: 0.5; }
100% { opacity: 1; }
}
.input-icon {
background-color: #f8f9fa;
border-right: none;
min-width: 45px;
}
</style>
</head>
<body class=“container py-4”>
<h1 class=“mb-4”><i class=“bi bi-alarm”></i> 智能任务提醒工具</h1>
<!-- 添加任务表单 -->
<form id="taskForm" class="mb-4 card p-3">
<div class="row g-3">
<div class="col-md-4">
<div class="input-group">
<span class="input-group-text input-icon">
<i class="bi bi-card-text"></i>
</span>
<input type="text" class="form-control" id="taskName" placeholder="任务名称" required>
</div>
</div>
<div class="col-md-3">
<div class="input-group">
<span class="input-group-text input-icon">
<i class="bi bi-clock"></i>
</span>
<input type="datetime-local" class="form-control" id="taskTime" required>
</div>
</div>
<div class="col-md-2">
<div class="input-group">
<span class="input-group-text input-icon">
<i class="bi bi-arrow-repeat"></i>
</span>
<select class="form-select" id="taskCycle">
<option value="none">无周期</option>
<option value="daily">每天</option>
<option value="weekly">每周</option>
<option value="monthly">每月</option>
</select>
</div>
</div>
<div class="col-md-2">
<div class="input-group">
<span class="input-group-text input-icon">
<i class="bi bi-person"></i>
</span>
<input type="text" class="form-control" id="taskOwner" placeholder="责任人">
</div>
</div>
<div class="col-md-1">
<button type="submit" class="btn btn-primary w-100">
<i class="bi bi-plus-lg"></i> 添加
</button>
</div>
</div>
</form>
<!-- 任务列表 -->
<div id="taskList" class="mb-4"></div>
<!-- 控制按钮 -->
<div class="d-flex gap-2">
<button onclick="clearCompleted()" class="btn btn-danger">
<i class="bi bi-trash"></i> 清除已完成
</button>
<button onclick="exportHTML()" class="btn btn-success">
<i class="bi bi-download"></i> 导出备份
</button>
</div>
<!-- 提醒弹窗 -->
<div id="reminderModal" class="modal fade" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><i class="bi bi-bell"></i> 任务提醒</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body" id="reminderContent"></div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
<i class="bi bi-clock-history"></i> 稍后提醒
</button>
<button type="button" class="btn btn-primary" onclick="completeFromModal()">
<i class="bi bi-check2"></i> 标记完成
</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
<script>
let tasks = JSON.parse(localStorage.getItem('tasks')) || [];
let currentReminderTask = null;
// 初始化
function init() {
renderTasks();
setInterval(() => {
checkReminders();
updateAllCountdowns();
}, 1000);
}
// 表单提交
document.getElementById('taskForm').addEventListener('submit', e => {
e.preventDefault();
const task = {
id: Date.now(),
name: document.getElementById('taskName').value,
time: new Date(document.getElementById('taskTime').value).getTime(),
cycle: document.getElementById('taskCycle').value,
owner: document.getElementById('taskOwner').value || '未指定',
completed: false,
notified: false
};
tasks.push(task);
saveTasks();
renderTasks();
e.target.reset();
});
// 渲染任务列表
function renderTasks() {
const taskList = document.getElementById('taskList');
taskList.innerHTML = tasks.sort((a, b) => a.time - b.time).map(task => `
<div class="card mb-2 task-card ${task.completed ? 'completed' : ''}" id="task-${task.id}">
<div class="card-body">
<div class="d-flex align-items-center justify-content-between">
<div class="flex-grow-1">
<h5><i class="bi ${task.completed ? 'bi-check2-circle' : 'bi-list-task'}"></i> ${task.name}</h5>
<div class="text-muted">
<div class="d-flex gap-3 flex-wrap">
<span><i class="bi bi-clock"></i> ${new Date(task.time).toLocaleString()}</span>
<span><i class="bi bi-person"></i> ${task.owner}</span>
<span><i class="bi bi-arrow-repeat"></i> ${task.cycle.toUpperCase()}</span>
</div>
</div>
<div class="countdown mt-2" id="countdown-${task.id}"></div>
</div>
<div class="btn-group ms-3 flex-nowrap">
<button class="btn btn-sm ${task.completed ? 'btn-secondary' : 'btn-success'}"
onclick="completeTask(${task.id})">
<i class="bi ${task.completed ? 'bi-arrow-counterclockwise' : 'bi-check2'}"></i>
${task.completed ? '恢复任务' : '完成'}
</button>
<button class="btn btn-sm btn-danger" onclick="deleteTask(${task.id})">
<i class="bi bi-trash"></i>
</button>
</div>
</div>
</div>
</div>
`).join('');
updateAllCountdowns();
}
// 更新倒计时
function updateCountdown(taskId) {
const task = tasks.find(t => t.id === taskId);
if (!task) return;
const now = Date.now();
const diff = task.time - now;
const countdownElement = document.getElementById(`countdown-${taskId}`);
if (diff <= 0 && !task.completed) {
countdownElement.innerHTML = `<i class="bi bi-exclamation-triangle"></i> <span class="urgent">任务已过期!</span>`;
return;
}
if (diff > 0 && !task.completed) {
const hours = Math.floor(diff / 3600000);
const minutes = Math.floor((diff % 3600000) / 60000);
const seconds = Math.floor((diff % 60000) / 1000);
countdownElement.innerHTML = `
<i class="bi bi-hourglass-split"></i>
<span class="${hours < 1 ? 'urgent' : ''}">
${hours.toString().padStart(2, '0')}小时
${minutes.toString().padStart(2, '0')}分
${seconds.toString().padStart(2, '0')}秒
</span>
`;
}
}
function updateAllCountdowns() {
tasks.forEach(task => !task.completed && updateCountdown(task.id));
}
// 任务操作函数
function completeTask(id) {
tasks = tasks.map(task =>
task.id === id ? {...task, completed: !task.completed} : task
);
saveTasks();
renderTasks();
}
function deleteTask(id) {
tasks = tasks.filter(task => task.id !== id);
saveTasks();
renderTasks();
}
function clearCompleted() {
tasks = tasks.filter(task => !task.completed);
saveTasks();
renderTasks();
}
// 提醒功能
function checkReminders() {
const now = Date.now();
tasks.forEach(task => {
if (!task.completed && !task.notified && task.time <= now) {
showReminder(task);
task.notified = true;
saveTasks();
}
});
}
function showReminder(task) {
currentReminderTask = task;
document.getElementById('reminderContent').innerHTML = `
<p><i class="bi bi-list-task"></i> ${task.name}</p>
<p><i class="bi bi-clock"></i> ${new Date(task.time).toLocaleString()}</p>
<p><i class="bi bi-person"></i> ${task.owner}</p>
`;
new bootstrap.Modal(document.getElementById('reminderModal')).show();
}
function completeFromModal() {
if (currentReminderTask) {
completeTask(currentReminderTask.id);
new bootstrap.Modal(document.getElementById('reminderModal')).hide();
}
}
// 数据持久化
function saveTasks() {
localStorage.setItem('tasks', JSON.stringify(tasks));
}
// 导出功能
function exportHTML() {
const blob = new Blob([document.documentElement.outerHTML], {type: 'text/html'});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'task-reminder.html';
a.click();
}
init();
</script>
</body>
</html>