您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
一款简洁大气的待办事项管理工具,支持添加、编辑、删除和展示待办事项,并提供搜索和历史记录功能。适用于任何网站,帮助您高效管理日常任务。
// ==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(); })();