// ==UserScript==
// @name 我的代办工具软件
// @namespace http://tampermonkey.net/
// @version 2.2.6
// @description 一款简洁大气的待办事项管理工具,支持添加、编辑、删除和展示待办事项,并提供搜索和历史记录功能。适用于任何网站,帮助您高效管理日常任务。
// @author wll
// @match *://*/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @grant GM_addStyle
// @license AGPL-3.0-or-later
// ==/UserScript==
/*
### 软件特点:
1. **简洁大气**:强调了工具的设计风格,吸引用户。
2. **功能全面**:列出了主要功能,包括添加、编辑、删除、展示、搜索和历史记录。
3. **适用性广**:明确指出适用于任何网站,增加了工具的通用性和吸引力。
4. **高效管理**:强调了工具的实用性,帮助用户高效管理日常任务。
*/
(function() {
'use strict';
function loadExternalResource(url, type) {
return new Promise((resolve, reject) => {
let tag;
if (type === 'css') {
tag = document.createElement('link');
tag.rel = 'stylesheet';
tag.href = url;
} else if (type === 'js') {
tag = document.createElement('script');
tag.src = url;
} else {
reject(new Error('Invalid resource type'));
return;
}
tag.onload = () => resolve();
tag.onerror = () => reject(new Error(`Failed to load resource: ${url}`));
document.head.appendChild(tag);
});
}
async function initialize() {
try {
await loadExternalResource('https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.js', 'js');
await loadExternalResource('https://cdn.bootcdn.net/ajax/libs/bootstrap/5.1.3/css/bootstrap.min.css', 'css');
await loadExternalResource('https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.3/js/bootstrap.bundle.min.js', 'js');
main();
} catch (error) {
console.error('Failed to load external resources', error);
}
}
function main() {
$(document).ready(function() {
function loadTodoList() {
return JSON.parse(GM_getValue('todoList', '[]'));
}
function saveTodoList(todoList) {
todoList.sort((a, b) => new Date(a.deadline) - new Date(b.deadline));
GM_setValue('todoList', JSON.stringify(todoList));
}
function loadHistoryList() {
return JSON.parse(GM_getValue('historyList', '[]'));
}
function saveHistoryList(historyList) {
GM_setValue('historyList', JSON.stringify(historyList));
}
function addTodoItem(task, deadline, reminderFrequency) {
const todoList = loadTodoList();
todoList.unshift({ task, deadline, reminderFrequency, done: false });
saveTodoList(todoList);
displayTodoList();
}
function deleteTodoItem(index) {
const todoList = loadTodoList();
todoList.splice(index, 1);
saveTodoList(todoList);
displayTodoList();
}
function editTodoItem(index, newTask, newDeadline, newReminder) {
const todoList = loadTodoList();
const todoItem = todoList[index];
todoItem.task = newTask;
todoItem.deadline = newDeadline;
todoItem.reminderFrequency = newReminder;
saveTodoList(todoList);
displayTodoList();
}
function showMessage(message) {
const messageElement = $('<div>').text(message).addClass('alert alert-warning position-fixed top-0 start-50 translate-middle-x');
$('body').append(messageElement);
setTimeout(() => messageElement.remove(), 3000);
}
function initializePresetTodoItems() {
const todoList = loadTodoList();
if (todoList.length === 0) {
addTodoItem('完成油猴脚本示例', '2023-12-31T23:59', '每天');
addTodoItem('开会', '2023-11-30T14:00', '每周');
addTodoItem('提交报告', '2023-12-15T17:00', '一次');
}
}
function displayTodoList() {
const todoList = loadTodoList();
const todoListElement = $('#todoList');
todoListElement.empty();
$.each(todoList, (index, todoItem) => {
const listItem = $('<tr>').html(`
<td>${index + 1}</td>
<td><input type="checkbox" ${todoItem.done ? 'checked' : ''}></td>
<td>${todoItem.task}</td>
<td>${todoItem.deadline}</td>
<td>${todoItem.reminderFrequency}</td>
<td>
<button class="btn btn-primary btn-sm edit-btn">编辑</button>
<button class="btn btn-danger btn-sm delete-btn">删除</button>
</td>
`);
listItem.find('input[type="checkbox"]').on('change', function() {
toggleDone(index, this.checked);
});
listItem.find('.edit-btn').on('click', function() {
makeTodoItemEditable(index, listItem);
});
listItem.find('.delete-btn').on('click', function() {
deleteTodoItem(index);
});
todoListElement.append(listItem);
});
}
function displayHistoryList() {
const historyList = loadHistoryList();
const historyListElement = $('#historyList');
historyListElement.empty();
$.each(historyList, (index, historyItem) => {
const listItem = $('<tr>').html(`
<td>${index + 1}</td>
<td><input type="checkbox" ${historyItem.done ? 'checked' : ''}></td>
<td>${historyItem.task}</td>
<td>${historyItem.deadline}</td>
<td>${historyItem.reminderFrequency}</td>
<td>
<button class="btn btn-primary btn-sm edit-history-btn">编辑</button>
<button class="btn btn-danger btn-sm delete-history-btn">删除</button>
</td>
`);
listItem.find('input[type="checkbox"]').on('change', function() {
toggleHistoryDone(index, this.checked);
});
listItem.find('.edit-history-btn').on('click', function() {
makeHistoryItemEditable(index, listItem);
});
listItem.find('.delete-history-btn').on('click', function() {
deleteHistoryItem(index);
});
historyListElement.append(listItem);
});
}
function toggleDone(index, done) {
const todoList = loadTodoList();
const historyList = loadHistoryList();
const [todoItem] = todoList.splice(index, 1);
todoItem.done = done;
if (done) {
historyList.unshift(todoItem);
} else {
todoList.unshift(todoItem);
}
saveTodoList(todoList);
saveHistoryList(historyList);
displayTodoList();
displayHistoryList();
}
function toggleHistoryDone(index, done) {
const historyList = loadHistoryList();
const todoList = loadTodoList();
const [historyItem] = historyList.splice(index, 1);
historyItem.done = done;
if (done) {
historyList.unshift(historyItem);
} else {
todoList.unshift(historyItem);
}
saveTodoList(todoList);
saveHistoryList(historyList);
displayTodoList();
displayHistoryList();
}
function makeTodoItemEditable(index, listItem) {
const todoList = loadTodoList();
const todoItem = todoList[index];
listItem.html(`
<td>${index + 1}</td>
<td><input type="checkbox" ${todoItem.done ? 'checked' : ''}></td>
<td><input type="text" class="form-control" value="${todoItem.task}"></td>
<td><input type="datetime-local" class="form-control" value="${todoItem.deadline}"></td>
<td>
<select class="form-control reminder-select">
<option value="每天" ${todoItem.reminderFrequency === '每天' ? 'selected' : ''}>每天</option>
<option value="每周" ${todoItem.reminderFrequency === '每周' ? 'selected' : ''}>每周</option>
<option value="每月" ${todoItem.reminderFrequency === '每月' ? 'selected' : ''}>每月</option>
<option value="每年" ${todoItem.reminderFrequency === '每年' ? 'selected' : ''}>每年</option>
<option value="一次" ${todoItem.reminderFrequency === '一次' ? 'selected' : ''}>一次</option>
</select>
</td>
<td>
<button class="btn btn-success btn-sm save-btn">保存</button>
<button class="btn btn-secondary btn-sm cancel-btn">取消</button>
</td>
`);
listItem.find('.save-btn').on('click', function() {
const newTask = listItem.find('input').eq(1).val();
const newDeadline = listItem.find('input').eq(2).val();
const newReminder = listItem.find('.reminder-select').val();
editTodoItem(index, newTask, newDeadline, newReminder);
showMessage('编辑成功');
});
listItem.find('.cancel-btn').on('click', function() {
displayTodoList();
});
}
function makeHistoryItemEditable(index, listItem) {
const historyList = loadHistoryList();
const historyItem = historyList[index];
listItem.html(`
<td>${index + 1}</td>
<td><input type="checkbox" ${historyItem.done ? 'checked' : ''}></td>
<td><input type="text" class="form-control" value="${historyItem.task}"></td>
<td><input type="datetime-local" class="form-control" value="${historyItem.deadline}"></td>
<td>
<select class="form-control reminder-select">
<option value="每天" ${historyItem.reminderFrequency === '每天' ? 'selected' : ''}>每天</option>
<option value="每周" ${historyItem.reminderFrequency === '每周' ? 'selected' : ''}>每周</option>
<option value="每月" ${historyItem.reminderFrequency === '每月' ? 'selected' : ''}>每月</option>
<option value="每年" ${historyItem.reminderFrequency === '每年' ? 'selected' : ''}>每年</option>
<option value="一次" ${historyItem.reminderFrequency === '一次' ? 'selected' : ''}>一次</option>
</select>
</td>
<td>
<button class="btn btn-success btn-sm save-btn">保存</button>
<button class="btn btn-secondary btn-sm cancel-btn">取消</button>
</td>
`);
listItem.find('.save-btn').on('click', function() {
historyItem.task = listItem.find('input').eq(1).val();
historyItem.deadline = listItem.find('input').eq(2).val();
historyItem.reminderFrequency = listItem.find('.reminder-select').val();
saveHistoryList(historyList);
displayHistoryList();
showMessage('编辑成功');
});
listItem.find('.cancel-btn').on('click', function() {
displayHistoryList();
});
}
function deleteHistoryItem(index) {
const historyList = loadHistoryList();
historyList.splice(index, 1);
saveHistoryList(historyList);
displayHistoryList();
}
function createTodoManagerPage() {
$('#todoManagerPanel').remove();
const pageContent = `
<div id="todoManagerPanel" class="container" style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; border: 1px solid black; padding: 20px; width: 700px; box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);">
<div class="d-flex justify-content-between align-items-center mb-3">
<h1 class="flex-grow-1 text-center">代办事项管理</h1>
<button id="closeBtn" class="btn btn-danger btn-sm">X</button>
</div>
<div class="mb-3">
<input type="text" id="taskInput" placeholder="任务名称" class="form-control mb-2" style="display: inline-block; width: 30%;">
<input type="datetime-local" id="deadlineInput" class="form-control mb-2" style="display: inline-block; width: 30%;">
<select id="reminderInput" class="form-control mb-2" style="display: inline-block; width: 30%;">
<option value="每天">每天</option>
<option value="每周">每周</option>
<option value="每月">每月</option>
<option value="每年">每年</option>
<option value="一次" selected>一次</option>
</select>
<button id="addBtn" class="btn btn-primary btn-block">添加</button>
</div>
<div class="mb-3 d-flex">
<input type="text" id="searchInput" placeholder="搜索任务..." class="form-control me-2">
<button id="clearSearchBtn" class="btn btn-secondary">清除</button>
</div>
<div class="mb-3">
<h2>待办事项</h2>
<table class="table table-striped">
<thead>
<tr>
<th>序号</th>
<th>状态</th>
<th>任务名称</th>
<th>截止日期</th>
<th>提醒频率</th>
<th>操作</th>
</tr>
</thead>
<tbody id="todoList"></tbody>
</table>
</div>
<div>
<h2>历史事项</h2>
<table class="table table-striped">
<thead>
<tr>
<th>序号</th>
<th>状态</th>
<th>任务名称</th>
<th>截止日期</th>
<th>提醒频率</th>
<th>操作</th>
</tr>
</thead>
<tbody id="historyList"></tbody>
</table>
</div>
</div>
`;
$('body').append(pageContent);
$('#addBtn').on('click', addTodo);
$('#closeBtn').on('click', closeTodoManager);
$('#searchInput').on('input', filterTodoList);
$('#clearSearchBtn').on('click', clearSearch);
displayTodoList();
displayHistoryList();
}
function addTodo() {
const task = $('#taskInput').val().trim();
const deadline = $('#deadlineInput').val().trim();
const reminderFrequency = $('#reminderInput').val().trim();
if (task && deadline && reminderFrequency) {
addTodoItem(task, deadline, reminderFrequency);
$('#taskInput').val('');
$('#deadlineInput').val('');
$('#reminderInput').val('一次');
showMessage('添加成功');
} else {
showMessage('请输入有效的代办事项信息');
}
}
function clearSearch() {
$('#searchInput').val('');
filterTodoList();
}
function filterTodoList() {
const searchInput = $('#searchInput').val().toLowerCase();
const todoList = loadTodoList();
const historyList = loadHistoryList();
const filteredTodoList = todoList.filter(item => item.task.toLowerCase().includes(searchInput));
const filteredHistoryList = historyList.filter(item => item.task.toLowerCase().includes(searchInput));
displayFilteredTodoList(filteredTodoList);
displayFilteredHistoryList(filteredHistoryList);
}
function displayFilteredTodoList(filteredTodoList) {
const todoListElement = $('#todoList');
todoListElement.empty();
$.each(filteredTodoList, (index, todoItem) => {
const listItem = $('<tr>').html(`
<td>${index + 1}</td>
<td><input type="checkbox" ${todoItem.done ? 'checked' : ''}></td>
<td>${todoItem.task}</td>
<td>${todoItem.deadline}</td>
<td>${todoItem.reminderFrequency}</td>
<td>
<button class="btn btn-primary btn-sm edit-btn">编辑</button>
<button class="btn btn-danger btn-sm delete-btn">删除</button>
</td>
`);
listItem.find('input[type="checkbox"]').on('change', function() {
toggleDone(index, this.checked);
});
listItem.find('.edit-btn').on('click', function() {
makeTodoItemEditable(index, listItem);
});
listItem.find('.delete-btn').on('click', function() {
deleteTodoItem(index);
});
todoListElement.append(listItem);
});
}
function displayFilteredHistoryList(filteredHistoryList) {
const historyListElement = $('#historyList');
historyListElement.empty();
$.each(filteredHistoryList, (index, historyItem) => {
const listItem = $('<tr>').html(`
<td>${index + 1}</td>
<td><input type="checkbox" ${historyItem.done ? 'checked' : ''}></td>
<td>${historyItem.task}</td>
<td>${historyItem.deadline}</td>
<td>${historyItem.reminderFrequency}</td>
<td>
<button class="btn btn-primary btn-sm edit-history-btn">编辑</button>
<button class="btn btn-danger btn-sm delete-history-btn">删除</button>
</td>
`);
listItem.find('input[type="checkbox"]').on('change', function() {
toggleHistoryDone(index, this.checked);
});
listItem.find('.edit-history-btn').on('click', function() {
makeHistoryItemEditable(index, listItem);
});
listItem.find('.delete-history-btn').on('click', function() {
deleteHistoryItem(index);
});
historyListElement.append(listItem);
});
}
function closeTodoManager() {
$('#todoManagerPanel').remove();
}
GM_registerMenuCommand('代办管理', function() {
createTodoManagerPage();
});
initializePresetTodoItems();
});
}
initialize();
})();