Greasy Fork

保存个人说明历史

保存幼儿园个人说明历史

// ==UserScript==
// @name         保存个人说明历史
// @namespace    https://github.com/lifegpc/userscript
// @version      0.0.1
// @description  保存幼儿园个人说明历史
// @author       lifegpc
// @match        https://u2.dmhy.org/usercp.php?action=personal*
// @icon         https://u2.dmhy.org/favicon.ico
// @license      MIT
// ==/UserScript==
/**@type {IDBDatabase} */
let db = undefined;
let need_reinit = false;
let storage = navigator.storage || globalThis['WorkerNavigator']['storage'];
async function make_storage_persist() {
    let persisted = await storage.persisted();
    if (!persisted) {
        persisted = await storage.persist();
    }
    return persisted;
}
function init() {
    return new Promise((resolve, reject) => {
        make_storage_persist().then(() => {
            if (db !== undefined && !need_reinit) {
                resolve();
                return;
            }
            let indexedReq = indexedDB.open('u2_history', 1);
            /**@param {IDBVersionChangeEvent} event*/
            indexedReq.onupgradeneeded = function (event) {
                let db = this.result;
                console.log(`upgrade u2_history from ${event.oldVersion} to ${event.newVersion}`);
                /*No version or version < 1 -> v1 */
                if (isNaN(event.oldVersion) || event.oldVersion < 1) {
                    db.createObjectStore('info', { keyPath: 'time' });
                }
            }
            indexedReq.onsuccess = () => {
                db = indexedReq.result;
                resolve();
            }
            indexedReq.onerror = () => {
                need_reinit = true;
                reject(indexedReq.error);
            }
        }).catch(reject);
    })
}
/**
 * @template T
 * @param {(tx: IDBDatabase) => IDBRequest<T>} callback
 * @returns {Promise<T>}
 */
function db_handle(callback) {
    return new Promise((resolve, reject) => {
        init().then(() => {
            let req = callback(db);
            req.onsuccess = () => {
                let re = req.result;
                resolve(re);
            }
            req.onerror = () => {
                need_reinit = true;
                reject(req.error);
            }
        }).catch(reject);
    })
}
async function get_all_info_keys() {
    return await db_handle(db => db.transaction('info').objectStore('info').getAllKeys());
}
async function get_info(time) {
    let info = await db_handle(db => db.transaction('info').objectStore('info').get(time));
    return info ? info.info : undefined;
}
async function delete_info(time) {
    await db_handle(db => db.transaction('info', 'readwrite').objectStore('info').delete(time));
}
async function save_info(time, info) {
    return await db_handle(db => db.transaction('info', 'readwrite').objectStore('info').put({ time, info }));
}
async function render_page() {}
(async function() {
let times = await get_all_info_keys();
let textarea = document.querySelector('textarea[name="info"]');
let submit = document.querySelector('input[type="submit"]');
if (!times.length) {
    let info = textarea.value;
    if (info) {
        times.push(await save_info(new Date, info));
    }
}
console.log(times)
if (times.length) {
    times.sort((a, b) => b.getTime() - a.getTime())
    let details = document.createElement('details');
    let summary = document.createElement('summary');
    summary.innerText = '历史记录';
    details.append(summary);
    let body = document.createElement('div');
    details.append(body);
    textarea.parentElement.append(details);
    let page = 0;
    const count_per_page = 10;
    /**
     * @param {Date} time
     * @param {string} info
     */
    function render_info(time, info) {
        const details = document.createElement('details');
        const summary = document.createElement('summary');
        summary.innerText = time.toLocaleString();
        details.append(summary);
        const form = document.createElement('form');
        form.target = '_blank';
        form.action = "/tags.php";
        form.method = "post";
        details.append(form);
        const ntextarea = document.createElement('textarea');
        ntextarea.readOnly = true;
        ntextarea.name = "test";
        ntextarea.value = info;
        ntextarea.style.width = textarea.style.width;
        ntextarea.rows = textarea.rows;
        form.append(ntextarea);
        const line = document.createElement('div');
        form.append(line);
        const use = document.createElement('input');
        use.type = "button";
        use.value = "使用";
        use.addEventListener('click', () => {
            textarea.value = info;
        })
        line.append(use);
        const preview = document.createElement('input');
        preview.type = "submit";
        preview.value = "预览";
        line.append(preview);
        const del = document.createElement('input');
        del.type = "button";
        del.value = "删除";
        del.addEventListener('click', async () => {
            await delete_info(time);
            times = await get_all_info_keys();
            times.sort((a, b) => b.getTime() - a.getTime());
            await render_page();
        })
        line.append(del);
        body.append(details);
    }
    async function render_page() {
        body.innerHTML = '';
        const total_page = Math.ceil(times.length / count_per_page);
        if (page < 0) page = 0;
        if (page >= total_page) page = total_page - 1;
        const max = Math.min((page + 1) * count_per_page, times.length);
        for (let i = page * count_per_page; i < max; i++) {
            const time = times[i];
            const info = await get_info(time);
            render_info(time, info);
        }
        const line = document.createElement('div');
        body.append(line);
        const pagei = document.createElement('input');
        pagei.type = 'number';
        pagei.min = '1';
        pagei.max = `${total_page}`;
        pagei.value = `${page + 1}`;
        pagei.addEventListener('change', () => {
            page = pagei.valueAsNumber - 1;
            render_page();
        })
        line.append(pagei);
        line.append(`/${total_page}页`);
        if (page > 0) {
            const first = document.createElement('input');
            first.type = 'button';
            first.value = '首页';
            first.addEventListener('click', () => {
                page = 0;
                render_page();
            })
            line.append(first);
            const prev = document.createElement('input');
            prev.type = 'button';
            prev.value = '上一页';
            prev.addEventListener('click', () => {
                page--;
                render_page();
            })
            line.append(prev);
        }
        if (page < total_page - 1) {
            const next = document.createElement('input');
            next.type = 'button';
            next.value = '下一页';
            next.addEventListener('click', () => {
                page++;
                render_page();
            })
            line.append(next);
            const last = document.createElement('input');
            last.type = 'button';
            last.value = '尾页';
            last.addEventListener('click', () => {
                page = total_page - 1;
                render_page();
            })
            line.append(last);
        }
    }
    await render_page();
} else {
    let div = document.createElement('div');
    div.innerText = "无历史记录";
    textarea.parentElement.append(div);
}
submit.addEventListener('click', async () => {
    const last_time = new Date(Math.max(...times));
    const info_db = await get_info(last_time);
    const info = textarea.value;
    if (info != info_db) {
        await save_info(new Date, info);
    }
})
})();