<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
>
<channel>
<title><![CDATA[IT 知新集 - 计算机技术学习与培训文档分享]]></title> 
<atom:link href="https://docu.org.cn/rss.php" rel="self" type="application/rss+xml" />
<description><![CDATA[专注于 计算机技术学习与培训文档分享]]></description>
<link>https://docu.org.cn/</link>
<language>zh-cn</language>
<generator>www.emlog.net</generator>
<item>
    <title>朗诵必备声音大词典</title>
    <link>https://docu.org.cn/?post=58</link>
    <description><![CDATA[<head>
    <meta charset="UTF-8">
    <!-- PDF.js库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.min.js"></script>
    <style>
        /* 原有样式保持不变 */
        .pdf-container {
            display: flex;
            flex-direction: column;
            height: auto;
        }

        .pdf-controls {
            padding: 10px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
            display: flex;
            align-items: center;
            gap: 15px;
        }

        button {
            padding: 8px 15px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: background 0.3s;
        }

        button:hover {
            background: #0056b3;
        }

        button:disabled {
            background: #6c757d;
            cursor: not-allowed;
        }

        .page-jump input {
            width: 60px;
            padding: 5px;
            margin-right: 5px;
            border: 1px solid #ddd;
            border-radius: 3px;
        }

        #pdfViewer {
            overflow: auto;
            background: black;
            position: relative;
        }

        canvas {
            display: block;
            margin: 0 auto;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }

        .fullscreen #pdfViewer {
            height: auto;
        }

        .fullscreen-btn {
            margin-left: auto;
            background: #28a745;
        }

        .fullscreen-btn:hover {
            background: #218838;
        }
    </style>
</head>
<body>
    <div class="pdf-container" id="pdfContainer">
        <div class="pdf-controls">
            <button id="prevPage">上页</button>
            <span id="currentPage">1</span>/
            <span id="totalPages">1</span>
            <button id="nextPage">下页</button>
            <div class="page-jump">
                <input type="number" id="pageInput" placeholder="页数" min="1">
                <button id="jumpButton">跳转</button>
            </div>
            <button onclick="refreshPage()">刷新</button>
            <button id="fullscreenBtn" class="fullscreen-btn" title="全屏">全屏</button>
        </div>
        <div id="pdfViewer"></div>
    </div>
    <script>
        // 安全防护（保持不变）
        document.addEventListener('contextmenu', e => e.preventDefault());
        document.addEventListener('keydown', e => {
            if (e.ctrlKey && (e.key === 's' || e.key === 'p')) e.preventDefault();
        });

        // 全屏控制（保持不变）
        function toggleFullscreen() {
            const container = document.getElementById('pdfContainer');

            if (!document.fullscreenElement) {
                container.requestFullscreen?.() ||
                container.webkitRequestFullscreen?.() ||
                container.mozRequestFullScreen?.();
            } else {
                document.exitFullscreen?.() ||
                document.webkitExitFullscreen?.() ||
                document.mozCancelFullScreen?.();
            }
        }

        // 全屏按钮状态更新（保持不变）
        function updateFullscreenButton() {
            const btn = document.getElementById('fullscreenBtn');
            btn.textContent = document.fullscreenElement ? "退出全屏" : "全屏";
        }

        // 全屏事件监听（保持不变）
        document.getElementById('fullscreenBtn').addEventListener('click', toggleFullscreen);
        ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange'].forEach(event => {
            document.addEventListener(event, updateFullscreenButton);
        });

        // PDF控制变量（保持不变）
        let currentPage = 1;
        let totalPages = 1;
        let pdfInstance = null;
        const pageCache = new Map();
        const pdfUrl = 'content/uploadfile/202512/88141766201128.pdf';
        const dbName = 'pdfCacheDB';
        const storeName = 'pdfFiles';

        // IndexedDB初始化（保持不变）
        const initDB = () => {
            return new Promise((resolve, reject) => {
                const request = indexedDB.open(dbName, 1);
                request.onupgradeneeded = (e) => {
                    const db = e.target.result;
                    if (!db.objectStoreNames.contains(storeName)) {
                        db.createObjectStore(storeName);
                    }
                };
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => reject(request.error);
            });
        };

        // 缓存操作函数（新增删除功能）
        const getCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readonly');
                const store = transaction.objectStore(storeName);
                const request = store.get(pdfUrl);
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => resolve(null);
            });
        };

        const savePDFToCache = async (db, data) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                store.put(data, pdfUrl);
                transaction.oncomplete = () => resolve();
            });
        };

        const deleteCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                const request = store.delete(pdfUrl);
                request.onsuccess = () => resolve();
                request.onerror = () => resolve();
            });
        };

        // PDF加载核心逻辑（增加autoRender参数）
        const loadPDF = async (autoRender = true) => {
            try {
                const db = await initDB();
                const cachedData = await getCachedPDF(db);

                if (cachedData) {
                    pdfInstance = await pdfjsLib.getDocument({
                        data: cachedData,
                        disableAutoFetch: true,
                        disableStream: true
                    }).promise;
                } else {
                    const loadingTask = pdfjsLib.getDocument({
                        url: pdfUrl,
                        disableAutoFetch: true,
                        disableStream: true
                    });

                    loadingTask.onProgress = (progress) => {
                        if (progress.loaded >= progress.total) {
                            loadingTask.promise.then(async (pdf) => {
                                const data = await pdf.getData();
                                await savePDFToCache(db, data);
                            });
                        }
                    };

                    pdfInstance = await loadingTask.promise;
                }

                totalPages = pdfInstance.numPages;
                document.getElementById('totalPages').textContent = totalPages;
                document.getElementById('pageInput').max = totalPages;

                if (autoRender) {
                    renderPage(currentPage);
                    preloadPages(2, Math.min(5, totalPages));
                }
            } catch (error) {
                console.error('PDF加载失败:', error);
            }
        };

        // 页面渲染（保持不变）
        async function renderPage(pageNum) {
            const container = document.getElementById('pdfViewer');
            container.innerHTML = '';

            let page = pageCache.get(pageNum) || await pdfInstance.getPage(pageNum);
            if (!pageCache.has(pageNum)) pageCache.set(pageNum, page);

            const canvas = document.createElement('canvas');
            container.appendChild(canvas);

            const viewport = page.getViewport({ scale: 1.5 });
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            await page.render({
                canvasContext: canvas.getContext('2d'),
                viewport: viewport
            });

            document.getElementById('currentPage').textContent = pageNum;
            updateButtonState();
        }

        // 预加载和按钮控制（保持不变）
        async function preloadPages(start, end) {
            const promises = [];
            for (let pageNum = start; pageNum <= end; pageNum++) {
                if (!pageCache.has(pageNum)) {
                    promises.push(
                        pdfInstance.getPage(pageNum)
                            .then(page => pageCache.set(pageNum, page))
                            .catch(console.error)
                    );
                }
            }
            await Promise.all(promises);
        }

        function updateButtonState() {
            document.getElementById('prevPage').disabled = currentPage === 1;
            document.getElementById('nextPage').disabled = currentPage === totalPages;
        }

        // 事件监听（保持不变）
        document.getElementById('prevPage').addEventListener('click', () => {
            if (currentPage > 1) renderPage(--currentPage);
        });

        document.getElementById('nextPage').addEventListener('click', () => {
            if (currentPage < totalPages) {
                renderPage(++currentPage);
                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            }
        });

        document.getElementById('jumpButton').addEventListener('click', () => {
            const inputPage = parseInt(document.getElementById('pageInput').value);
            if (!isNaN(inputPage) && inputPage > 0 && inputPage <= totalPages) {
                currentPage = inputPage;
                document.getElementById('pageInput').value = '';
                renderPage(currentPage);
            } else {
                alert(`请输入1到${totalPages}之间的有效页码`);
            }
        });

        document.getElementById('pageInput').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') document.getElementById('jumpButton').click();
        });

        // 新版刷新功能
        async function refreshPage() {
            try {
                const oldPage = currentPage;
                const db = await initDB();
                await deleteCachedPDF(db);
                pageCache.clear();

                await loadPDF(false); // 不自动渲染
                currentPage = Math.min(oldPage, totalPages);
                await renderPage(currentPage);

                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            } catch (error) {
                console.error('刷新失败:', error);
                alert('刷新失败，请检查网络连接');
            }
        }

        // 初始化加载
        loadPDF();
    </script>
</body>]]></description>
    <pubDate>Sat, 20 Dec 2025 11:25:44 +0800</pubDate>
    <dc:creator>Anglei</dc:creator>
    <guid>https://docu.org.cn/?post=58</guid>
</item>
<item>
    <title>DDOS攻击Deepseek防御实战</title>
    <link>https://docu.org.cn/?post=57</link>
    <description><![CDATA[<head>
    <meta charset="UTF-8">
    <!-- PDF.js库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.min.js"></script>
    <style>
        /* 原有样式保持不变 */
        .pdf-container {
            display: flex;
            flex-direction: column;
            height: auto;
        }

        .pdf-controls {
            padding: 10px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
            display: flex;
            align-items: center;
            gap: 15px;
        }

        button {
            padding: 8px 15px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: background 0.3s;
        }

        button:hover {
            background: #0056b3;
        }

        button:disabled {
            background: #6c757d;
            cursor: not-allowed;
        }

        .page-jump input {
            width: 60px;
            padding: 5px;
            margin-right: 5px;
            border: 1px solid #ddd;
            border-radius: 3px;
        }

        #pdfViewer {
            overflow: auto;
            background: black;
            position: relative;
        }

        canvas {
            display: block;
            margin: 0 auto;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }

        .fullscreen #pdfViewer {
            height: auto;
        }

        .fullscreen-btn {
            margin-left: auto;
            background: #28a745;
        }

        .fullscreen-btn:hover {
            background: #218838;
        }
    </style>
</head>
<body>
    <div class="pdf-container" id="pdfContainer">
        <div class="pdf-controls">
            <button id="prevPage">上页</button>
            <span id="currentPage">1</span>/
            <span id="totalPages">1</span>
            <button id="nextPage">下页</button>
            <div class="page-jump">
                <input type="number" id="pageInput" placeholder="页数" min="1">
                <button id="jumpButton">跳转</button>
            </div>
            <button onclick="refreshPage()">刷新</button>
            <button id="fullscreenBtn" class="fullscreen-btn" title="全屏">全屏</button>
        </div>
        <div id="pdfViewer"></div>
    </div>
    <script>
        // 安全防护（保持不变）
        document.addEventListener('contextmenu', e => e.preventDefault());
        document.addEventListener('keydown', e => {
            if (e.ctrlKey && (e.key === 's' || e.key === 'p')) e.preventDefault();
        });

        // 全屏控制（保持不变）
        function toggleFullscreen() {
            const container = document.getElementById('pdfContainer');

            if (!document.fullscreenElement) {
                container.requestFullscreen?.() ||
                container.webkitRequestFullscreen?.() ||
                container.mozRequestFullScreen?.();
            } else {
                document.exitFullscreen?.() ||
                document.webkitExitFullscreen?.() ||
                document.mozCancelFullScreen?.();
            }
        }

        // 全屏按钮状态更新（保持不变）
        function updateFullscreenButton() {
            const btn = document.getElementById('fullscreenBtn');
            btn.textContent = document.fullscreenElement ? "退出全屏" : "全屏";
        }

        // 全屏事件监听（保持不变）
        document.getElementById('fullscreenBtn').addEventListener('click', toggleFullscreen);
        ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange'].forEach(event => {
            document.addEventListener(event, updateFullscreenButton);
        });

        // PDF控制变量（保持不变）
        let currentPage = 1;
        let totalPages = 1;
        let pdfInstance = null;
        const pageCache = new Map();
        const pdfUrl = 'content/uploadfile/202503/9b471742313119.pdf';
        const dbName = 'pdfCacheDB';
        const storeName = 'pdfFiles';

        // IndexedDB初始化（保持不变）
        const initDB = () => {
            return new Promise((resolve, reject) => {
                const request = indexedDB.open(dbName, 1);
                request.onupgradeneeded = (e) => {
                    const db = e.target.result;
                    if (!db.objectStoreNames.contains(storeName)) {
                        db.createObjectStore(storeName);
                    }
                };
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => reject(request.error);
            });
        };

        // 缓存操作函数（新增删除功能）
        const getCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readonly');
                const store = transaction.objectStore(storeName);
                const request = store.get(pdfUrl);
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => resolve(null);
            });
        };

        const savePDFToCache = async (db, data) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                store.put(data, pdfUrl);
                transaction.oncomplete = () => resolve();
            });
        };

        const deleteCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                const request = store.delete(pdfUrl);
                request.onsuccess = () => resolve();
                request.onerror = () => resolve();
            });
        };

        // PDF加载核心逻辑（增加autoRender参数）
        const loadPDF = async (autoRender = true) => {
            try {
                const db = await initDB();
                const cachedData = await getCachedPDF(db);

                if (cachedData) {
                    pdfInstance = await pdfjsLib.getDocument({
                        data: cachedData,
                        disableAutoFetch: true,
                        disableStream: true
                    }).promise;
                } else {
                    const loadingTask = pdfjsLib.getDocument({
                        url: pdfUrl,
                        disableAutoFetch: true,
                        disableStream: true
                    });

                    loadingTask.onProgress = (progress) => {
                        if (progress.loaded >= progress.total) {
                            loadingTask.promise.then(async (pdf) => {
                                const data = await pdf.getData();
                                await savePDFToCache(db, data);
                            });
                        }
                    };

                    pdfInstance = await loadingTask.promise;
                }

                totalPages = pdfInstance.numPages;
                document.getElementById('totalPages').textContent = totalPages;
                document.getElementById('pageInput').max = totalPages;

                if (autoRender) {
                    renderPage(currentPage);
                    preloadPages(2, Math.min(5, totalPages));
                }
            } catch (error) {
                console.error('PDF加载失败:', error);
            }
        };

        // 页面渲染（保持不变）
        async function renderPage(pageNum) {
            const container = document.getElementById('pdfViewer');
            container.innerHTML = '';

            let page = pageCache.get(pageNum) || await pdfInstance.getPage(pageNum);
            if (!pageCache.has(pageNum)) pageCache.set(pageNum, page);

            const canvas = document.createElement('canvas');
            container.appendChild(canvas);

            const viewport = page.getViewport({ scale: 1.5 });
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            await page.render({
                canvasContext: canvas.getContext('2d'),
                viewport: viewport
            });

            document.getElementById('currentPage').textContent = pageNum;
            updateButtonState();
        }

        // 预加载和按钮控制（保持不变）
        async function preloadPages(start, end) {
            const promises = [];
            for (let pageNum = start; pageNum <= end; pageNum++) {
                if (!pageCache.has(pageNum)) {
                    promises.push(
                        pdfInstance.getPage(pageNum)
                            .then(page => pageCache.set(pageNum, page))
                            .catch(console.error)
                    );
                }
            }
            await Promise.all(promises);
        }

        function updateButtonState() {
            document.getElementById('prevPage').disabled = currentPage === 1;
            document.getElementById('nextPage').disabled = currentPage === totalPages;
        }

        // 事件监听（保持不变）
        document.getElementById('prevPage').addEventListener('click', () => {
            if (currentPage > 1) renderPage(--currentPage);
        });

        document.getElementById('nextPage').addEventListener('click', () => {
            if (currentPage < totalPages) {
                renderPage(++currentPage);
                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            }
        });

        document.getElementById('jumpButton').addEventListener('click', () => {
            const inputPage = parseInt(document.getElementById('pageInput').value);
            if (!isNaN(inputPage) && inputPage > 0 && inputPage <= totalPages) {
                currentPage = inputPage;
                document.getElementById('pageInput').value = '';
                renderPage(currentPage);
            } else {
                alert(`请输入1到${totalPages}之间的有效页码`);
            }
        });

        document.getElementById('pageInput').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') document.getElementById('jumpButton').click();
        });

        // 新版刷新功能
        async function refreshPage() {
            try {
                const oldPage = currentPage;
                const db = await initDB();
                await deleteCachedPDF(db);
                pageCache.clear();

                await loadPDF(false); // 不自动渲染
                currentPage = Math.min(oldPage, totalPages);
                await renderPage(currentPage);

                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            } catch (error) {
                console.error('刷新失败:', error);
                alert('刷新失败，请检查网络连接');
            }
        }

        // 初始化加载
        loadPDF();
    </script>
</body>]]></description>
    <pubDate>Tue, 18 Mar 2025 23:51:37 +0800</pubDate>
    <dc:creator>Anglei</dc:creator>
    <guid>https://docu.org.cn/?post=57</guid>
</item>
<item>
    <title>OpenEuler部署与Deepseek实战</title>
    <link>https://docu.org.cn/?post=55</link>
    <description><![CDATA[<head>
    <meta charset="UTF-8">
    <!-- PDF.js库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.min.js"></script>
    <style>
        /* 原有样式保持不变 */
        .pdf-container {
            display: flex;
            flex-direction: column;
            height: auto;
        }

        .pdf-controls {
            padding: 10px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
            display: flex;
            align-items: center;
            gap: 15px;
        }

        button {
            padding: 8px 15px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: background 0.3s;
        }

        button:hover {
            background: #0056b3;
        }

        button:disabled {
            background: #6c757d;
            cursor: not-allowed;
        }

        .page-jump input {
            width: 60px;
            padding: 5px;
            margin-right: 5px;
            border: 1px solid #ddd;
            border-radius: 3px;
        }

        #pdfViewer {
            overflow: auto;
            background: black;
            position: relative;
        }

        canvas {
            display: block;
            margin: 0 auto;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }

        .fullscreen #pdfViewer {
            height: auto;
        }

        .fullscreen-btn {
            margin-left: auto;
            background: #28a745;
        }

        .fullscreen-btn:hover {
            background: #218838;
        }
    </style>
</head>
<body>
    <div class="pdf-container" id="pdfContainer">
        <div class="pdf-controls">
            <button id="prevPage">上页</button>
            <span id="currentPage">1</span>/
            <span id="totalPages">1</span>
            <button id="nextPage">下页</button>
            <div class="page-jump">
                <input type="number" id="pageInput" placeholder="页数" min="1">
                <button id="jumpButton">跳转</button>
            </div>
            <button onclick="refreshPage()">刷新</button>
            <button id="fullscreenBtn" class="fullscreen-btn" title="全屏">全屏</button>
        </div>
        <div id="pdfViewer"></div>
    </div>
    <script>
        // 安全防护（保持不变）
        document.addEventListener('contextmenu', e => e.preventDefault());
        document.addEventListener('keydown', e => {
            if (e.ctrlKey && (e.key === 's' || e.key === 'p')) e.preventDefault();
        });

        // 全屏控制（保持不变）
        function toggleFullscreen() {
            const container = document.getElementById('pdfContainer');

            if (!document.fullscreenElement) {
                container.requestFullscreen?.() ||
                container.webkitRequestFullscreen?.() ||
                container.mozRequestFullScreen?.();
            } else {
                document.exitFullscreen?.() ||
                document.webkitExitFullscreen?.() ||
                document.mozCancelFullScreen?.();
            }
        }

        // 全屏按钮状态更新（保持不变）
        function updateFullscreenButton() {
            const btn = document.getElementById('fullscreenBtn');
            btn.textContent = document.fullscreenElement ? "退出全屏" : "全屏";
        }

        // 全屏事件监听（保持不变）
        document.getElementById('fullscreenBtn').addEventListener('click', toggleFullscreen);
        ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange'].forEach(event => {
            document.addEventListener(event, updateFullscreenButton);
        });

        // PDF控制变量（保持不变）
        let currentPage = 1;
        let totalPages = 1;
        let pdfInstance = null;
        const pageCache = new Map();
        const pdfUrl = 'content/uploadfile/202503/f5e31742293304.pdf';
        const dbName = 'pdfCacheDB';
        const storeName = 'pdfFiles';

        // IndexedDB初始化（保持不变）
        const initDB = () => {
            return new Promise((resolve, reject) => {
                const request = indexedDB.open(dbName, 1);
                request.onupgradeneeded = (e) => {
                    const db = e.target.result;
                    if (!db.objectStoreNames.contains(storeName)) {
                        db.createObjectStore(storeName);
                    }
                };
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => reject(request.error);
            });
        };

        // 缓存操作函数（新增删除功能）
        const getCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readonly');
                const store = transaction.objectStore(storeName);
                const request = store.get(pdfUrl);
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => resolve(null);
            });
        };

        const savePDFToCache = async (db, data) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                store.put(data, pdfUrl);
                transaction.oncomplete = () => resolve();
            });
        };

        const deleteCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                const request = store.delete(pdfUrl);
                request.onsuccess = () => resolve();
                request.onerror = () => resolve();
            });
        };

        // PDF加载核心逻辑（增加autoRender参数）
        const loadPDF = async (autoRender = true) => {
            try {
                const db = await initDB();
                const cachedData = await getCachedPDF(db);

                if (cachedData) {
                    pdfInstance = await pdfjsLib.getDocument({
                        data: cachedData,
                        disableAutoFetch: true,
                        disableStream: true
                    }).promise;
                } else {
                    const loadingTask = pdfjsLib.getDocument({
                        url: pdfUrl,
                        disableAutoFetch: true,
                        disableStream: true
                    });

                    loadingTask.onProgress = (progress) => {
                        if (progress.loaded >= progress.total) {
                            loadingTask.promise.then(async (pdf) => {
                                const data = await pdf.getData();
                                await savePDFToCache(db, data);
                            });
                        }
                    };

                    pdfInstance = await loadingTask.promise;
                }

                totalPages = pdfInstance.numPages;
                document.getElementById('totalPages').textContent = totalPages;
                document.getElementById('pageInput').max = totalPages;

                if (autoRender) {
                    renderPage(currentPage);
                    preloadPages(2, Math.min(5, totalPages));
                }
            } catch (error) {
                console.error('PDF加载失败:', error);
            }
        };

        // 页面渲染（保持不变）
        async function renderPage(pageNum) {
            const container = document.getElementById('pdfViewer');
            container.innerHTML = '';

            let page = pageCache.get(pageNum) || await pdfInstance.getPage(pageNum);
            if (!pageCache.has(pageNum)) pageCache.set(pageNum, page);

            const canvas = document.createElement('canvas');
            container.appendChild(canvas);

            const viewport = page.getViewport({ scale: 1.5 });
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            await page.render({
                canvasContext: canvas.getContext('2d'),
                viewport: viewport
            });

            document.getElementById('currentPage').textContent = pageNum;
            updateButtonState();
        }

        // 预加载和按钮控制（保持不变）
        async function preloadPages(start, end) {
            const promises = [];
            for (let pageNum = start; pageNum <= end; pageNum++) {
                if (!pageCache.has(pageNum)) {
                    promises.push(
                        pdfInstance.getPage(pageNum)
                            .then(page => pageCache.set(pageNum, page))
                            .catch(console.error)
                    );
                }
            }
            await Promise.all(promises);
        }

        function updateButtonState() {
            document.getElementById('prevPage').disabled = currentPage === 1;
            document.getElementById('nextPage').disabled = currentPage === totalPages;
        }

        // 事件监听（保持不变）
        document.getElementById('prevPage').addEventListener('click', () => {
            if (currentPage > 1) renderPage(--currentPage);
        });

        document.getElementById('nextPage').addEventListener('click', () => {
            if (currentPage < totalPages) {
                renderPage(++currentPage);
                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            }
        });

        document.getElementById('jumpButton').addEventListener('click', () => {
            const inputPage = parseInt(document.getElementById('pageInput').value);
            if (!isNaN(inputPage) && inputPage > 0 && inputPage <= totalPages) {
                currentPage = inputPage;
                document.getElementById('pageInput').value = '';
                renderPage(currentPage);
            } else {
                alert(`请输入1到${totalPages}之间的有效页码`);
            }
        });

        document.getElementById('pageInput').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') document.getElementById('jumpButton').click();
        });

        // 新版刷新功能
        async function refreshPage() {
            try {
                const oldPage = currentPage;
                const db = await initDB();
                await deleteCachedPDF(db);
                pageCache.clear();

                await loadPDF(false); // 不自动渲染
                currentPage = Math.min(oldPage, totalPages);
                await renderPage(currentPage);

                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            } catch (error) {
                console.error('刷新失败:', error);
                alert('刷新失败，请检查网络连接');
            }
        }

        // 初始化加载
        loadPDF();
    </script>
</body>]]></description>
    <pubDate>Tue, 18 Mar 2025 18:21:24 +0800</pubDate>
    <dc:creator>Anglei</dc:creator>
    <guid>https://docu.org.cn/?post=55</guid>
</item>
<item>
    <title>k8s中文指南-韩先超</title>
    <link>https://docu.org.cn/?post=54</link>
    <description><![CDATA[<head>
    <meta charset="UTF-8">
    <!-- PDF.js库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.min.js"></script>
    <style>
        /* 原有样式保持不变 */
        .pdf-container {
            display: flex;
            flex-direction: column;
            height: auto;
        }

        .pdf-controls {
            padding: 10px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
            display: flex;
            align-items: center;
            gap: 15px;
        }

        button {
            padding: 8px 15px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: background 0.3s;
        }

        button:hover {
            background: #0056b3;
        }

        button:disabled {
            background: #6c757d;
            cursor: not-allowed;
        }

        .page-jump input {
            width: 60px;
            padding: 5px;
            margin-right: 5px;
            border: 1px solid #ddd;
            border-radius: 3px;
        }

        #pdfViewer {
            overflow: auto;
            background: black;
            position: relative;
        }

        canvas {
            display: block;
            margin: 0 auto;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }

        .fullscreen #pdfViewer {
            height: auto;
        }

        .fullscreen-btn {
            margin-left: auto;
            background: #28a745;
        }

        .fullscreen-btn:hover {
            background: #218838;
        }
    </style>
</head>
<body>
    <div class="pdf-container" id="pdfContainer">
        <div class="pdf-controls">
            <button id="prevPage">上页</button>
            <span id="currentPage">1</span>/
            <span id="totalPages">1</span>
            <button id="nextPage">下页</button>
            <div class="page-jump">
                <input type="number" id="pageInput" placeholder="页数" min="1">
                <button id="jumpButton">跳转</button>
            </div>
            <button onclick="refreshPage()">刷新</button>
            <button id="fullscreenBtn" class="fullscreen-btn" title="全屏">全屏</button>
        </div>
        <div id="pdfViewer"></div>
    </div>
    <script>
        // 安全防护（保持不变）
        document.addEventListener('contextmenu', e => e.preventDefault());
        document.addEventListener('keydown', e => {
            if (e.ctrlKey && (e.key === 's' || e.key === 'p')) e.preventDefault();
        });

        // 全屏控制（保持不变）
        function toggleFullscreen() {
            const container = document.getElementById('pdfContainer');

            if (!document.fullscreenElement) {
                container.requestFullscreen?.() ||
                container.webkitRequestFullscreen?.() ||
                container.mozRequestFullScreen?.();
            } else {
                document.exitFullscreen?.() ||
                document.webkitExitFullscreen?.() ||
                document.mozCancelFullScreen?.();
            }
        }

        // 全屏按钮状态更新（保持不变）
        function updateFullscreenButton() {
            const btn = document.getElementById('fullscreenBtn');
            btn.textContent = document.fullscreenElement ? "退出全屏" : "全屏";
        }

        // 全屏事件监听（保持不变）
        document.getElementById('fullscreenBtn').addEventListener('click', toggleFullscreen);
        ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange'].forEach(event => {
            document.addEventListener(event, updateFullscreenButton);
        });

        // PDF控制变量（保持不变）
        let currentPage = 1;
        let totalPages = 1;
        let pdfInstance = null;
        const pageCache = new Map();
        const pdfUrl = 'content/uploadfile/202503/2cbc1742292751.pdf';
        const dbName = 'pdfCacheDB';
        const storeName = 'pdfFiles';

        // IndexedDB初始化（保持不变）
        const initDB = () => {
            return new Promise((resolve, reject) => {
                const request = indexedDB.open(dbName, 1);
                request.onupgradeneeded = (e) => {
                    const db = e.target.result;
                    if (!db.objectStoreNames.contains(storeName)) {
                        db.createObjectStore(storeName);
                    }
                };
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => reject(request.error);
            });
        };

        // 缓存操作函数（新增删除功能）
        const getCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readonly');
                const store = transaction.objectStore(storeName);
                const request = store.get(pdfUrl);
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => resolve(null);
            });
        };

        const savePDFToCache = async (db, data) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                store.put(data, pdfUrl);
                transaction.oncomplete = () => resolve();
            });
        };

        const deleteCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                const request = store.delete(pdfUrl);
                request.onsuccess = () => resolve();
                request.onerror = () => resolve();
            });
        };

        // PDF加载核心逻辑（增加autoRender参数）
        const loadPDF = async (autoRender = true) => {
            try {
                const db = await initDB();
                const cachedData = await getCachedPDF(db);

                if (cachedData) {
                    pdfInstance = await pdfjsLib.getDocument({
                        data: cachedData,
                        disableAutoFetch: true,
                        disableStream: true
                    }).promise;
                } else {
                    const loadingTask = pdfjsLib.getDocument({
                        url: pdfUrl,
                        disableAutoFetch: true,
                        disableStream: true
                    });

                    loadingTask.onProgress = (progress) => {
                        if (progress.loaded >= progress.total) {
                            loadingTask.promise.then(async (pdf) => {
                                const data = await pdf.getData();
                                await savePDFToCache(db, data);
                            });
                        }
                    };

                    pdfInstance = await loadingTask.promise;
                }

                totalPages = pdfInstance.numPages;
                document.getElementById('totalPages').textContent = totalPages;
                document.getElementById('pageInput').max = totalPages;

                if (autoRender) {
                    renderPage(currentPage);
                    preloadPages(2, Math.min(5, totalPages));
                }
            } catch (error) {
                console.error('PDF加载失败:', error);
            }
        };

        // 页面渲染（保持不变）
        async function renderPage(pageNum) {
            const container = document.getElementById('pdfViewer');
            container.innerHTML = '';

            let page = pageCache.get(pageNum) || await pdfInstance.getPage(pageNum);
            if (!pageCache.has(pageNum)) pageCache.set(pageNum, page);

            const canvas = document.createElement('canvas');
            container.appendChild(canvas);

            const viewport = page.getViewport({ scale: 1.5 });
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            await page.render({
                canvasContext: canvas.getContext('2d'),
                viewport: viewport
            });

            document.getElementById('currentPage').textContent = pageNum;
            updateButtonState();
        }

        // 预加载和按钮控制（保持不变）
        async function preloadPages(start, end) {
            const promises = [];
            for (let pageNum = start; pageNum <= end; pageNum++) {
                if (!pageCache.has(pageNum)) {
                    promises.push(
                        pdfInstance.getPage(pageNum)
                            .then(page => pageCache.set(pageNum, page))
                            .catch(console.error)
                    );
                }
            }
            await Promise.all(promises);
        }

        function updateButtonState() {
            document.getElementById('prevPage').disabled = currentPage === 1;
            document.getElementById('nextPage').disabled = currentPage === totalPages;
        }

        // 事件监听（保持不变）
        document.getElementById('prevPage').addEventListener('click', () => {
            if (currentPage > 1) renderPage(--currentPage);
        });

        document.getElementById('nextPage').addEventListener('click', () => {
            if (currentPage < totalPages) {
                renderPage(++currentPage);
                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            }
        });

        document.getElementById('jumpButton').addEventListener('click', () => {
            const inputPage = parseInt(document.getElementById('pageInput').value);
            if (!isNaN(inputPage) && inputPage > 0 && inputPage <= totalPages) {
                currentPage = inputPage;
                document.getElementById('pageInput').value = '';
                renderPage(currentPage);
            } else {
                alert(`请输入1到${totalPages}之间的有效页码`);
            }
        });

        document.getElementById('pageInput').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') document.getElementById('jumpButton').click();
        });

        // 新版刷新功能
        async function refreshPage() {
            try {
                const oldPage = currentPage;
                const db = await initDB();
                await deleteCachedPDF(db);
                pageCache.clear();

                await loadPDF(false); // 不自动渲染
                currentPage = Math.min(oldPage, totalPages);
                await renderPage(currentPage);

                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            } catch (error) {
                console.error('刷新失败:', error);
                alert('刷新失败，请检查网络连接');
            }
        }

        // 初始化加载
        loadPDF();
    </script>
</body>]]></description>
    <pubDate>Tue, 18 Mar 2025 18:12:10 +0800</pubDate>
    <dc:creator>Anglei</dc:creator>
    <guid>https://docu.org.cn/?post=54</guid>
</item>
<item>
    <title>基于Jenkins+K8S构建DevOps</title>
    <link>https://docu.org.cn/?post=53</link>
    <description><![CDATA[<head>
    <meta charset="UTF-8">
    <!-- PDF.js库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.min.js"></script>
    <style>
        /* 原有样式保持不变 */
        .pdf-container {
            display: flex;
            flex-direction: column;
            height: auto;
        }

        .pdf-controls {
            padding: 10px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
            display: flex;
            align-items: center;
            gap: 15px;
        }

        button {
            padding: 8px 15px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: background 0.3s;
        }

        button:hover {
            background: #0056b3;
        }

        button:disabled {
            background: #6c757d;
            cursor: not-allowed;
        }

        .page-jump input {
            width: 60px;
            padding: 5px;
            margin-right: 5px;
            border: 1px solid #ddd;
            border-radius: 3px;
        }

        #pdfViewer {
            overflow: auto;
            background: black;
            position: relative;
        }

        canvas {
            display: block;
            margin: 0 auto;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }

        .fullscreen #pdfViewer {
            height: auto;
        }

        .fullscreen-btn {
            margin-left: auto;
            background: #28a745;
        }

        .fullscreen-btn:hover {
            background: #218838;
        }
    </style>
</head>
<body>
    <div class="pdf-container" id="pdfContainer">
        <div class="pdf-controls">
            <button id="prevPage">上页</button>
            <span id="currentPage">1</span>/
            <span id="totalPages">1</span>
            <button id="nextPage">下页</button>
            <div class="page-jump">
                <input type="number" id="pageInput" placeholder="页数" min="1">
                <button id="jumpButton">跳转</button>
            </div>
            <button onclick="refreshPage()">刷新</button>
            <button id="fullscreenBtn" class="fullscreen-btn" title="全屏">全屏</button>
        </div>
        <div id="pdfViewer"></div>
    </div>
    <script>
        // 安全防护（保持不变）
        document.addEventListener('contextmenu', e => e.preventDefault());
        document.addEventListener('keydown', e => {
            if (e.ctrlKey && (e.key === 's' || e.key === 'p')) e.preventDefault();
        });

        // 全屏控制（保持不变）
        function toggleFullscreen() {
            const container = document.getElementById('pdfContainer');

            if (!document.fullscreenElement) {
                container.requestFullscreen?.() ||
                container.webkitRequestFullscreen?.() ||
                container.mozRequestFullScreen?.();
            } else {
                document.exitFullscreen?.() ||
                document.webkitExitFullscreen?.() ||
                document.mozCancelFullScreen?.();
            }
        }

        // 全屏按钮状态更新（保持不变）
        function updateFullscreenButton() {
            const btn = document.getElementById('fullscreenBtn');
            btn.textContent = document.fullscreenElement ? "退出全屏" : "全屏";
        }

        // 全屏事件监听（保持不变）
        document.getElementById('fullscreenBtn').addEventListener('click', toggleFullscreen);
        ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange'].forEach(event => {
            document.addEventListener(event, updateFullscreenButton);
        });

        // PDF控制变量（保持不变）
        let currentPage = 1;
        let totalPages = 1;
        let pdfInstance = null;
        const pageCache = new Map();
        const pdfUrl = 'content/uploadfile/202503/b2c51742292680.pdf';
        const dbName = 'pdfCacheDB';
        const storeName = 'pdfFiles';

        // IndexedDB初始化（保持不变）
        const initDB = () => {
            return new Promise((resolve, reject) => {
                const request = indexedDB.open(dbName, 1);
                request.onupgradeneeded = (e) => {
                    const db = e.target.result;
                    if (!db.objectStoreNames.contains(storeName)) {
                        db.createObjectStore(storeName);
                    }
                };
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => reject(request.error);
            });
        };

        // 缓存操作函数（新增删除功能）
        const getCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readonly');
                const store = transaction.objectStore(storeName);
                const request = store.get(pdfUrl);
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => resolve(null);
            });
        };

        const savePDFToCache = async (db, data) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                store.put(data, pdfUrl);
                transaction.oncomplete = () => resolve();
            });
        };

        const deleteCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                const request = store.delete(pdfUrl);
                request.onsuccess = () => resolve();
                request.onerror = () => resolve();
            });
        };

        // PDF加载核心逻辑（增加autoRender参数）
        const loadPDF = async (autoRender = true) => {
            try {
                const db = await initDB();
                const cachedData = await getCachedPDF(db);

                if (cachedData) {
                    pdfInstance = await pdfjsLib.getDocument({
                        data: cachedData,
                        disableAutoFetch: true,
                        disableStream: true
                    }).promise;
                } else {
                    const loadingTask = pdfjsLib.getDocument({
                        url: pdfUrl,
                        disableAutoFetch: true,
                        disableStream: true
                    });

                    loadingTask.onProgress = (progress) => {
                        if (progress.loaded >= progress.total) {
                            loadingTask.promise.then(async (pdf) => {
                                const data = await pdf.getData();
                                await savePDFToCache(db, data);
                            });
                        }
                    };

                    pdfInstance = await loadingTask.promise;
                }

                totalPages = pdfInstance.numPages;
                document.getElementById('totalPages').textContent = totalPages;
                document.getElementById('pageInput').max = totalPages;

                if (autoRender) {
                    renderPage(currentPage);
                    preloadPages(2, Math.min(5, totalPages));
                }
            } catch (error) {
                console.error('PDF加载失败:', error);
            }
        };

        // 页面渲染（保持不变）
        async function renderPage(pageNum) {
            const container = document.getElementById('pdfViewer');
            container.innerHTML = '';

            let page = pageCache.get(pageNum) || await pdfInstance.getPage(pageNum);
            if (!pageCache.has(pageNum)) pageCache.set(pageNum, page);

            const canvas = document.createElement('canvas');
            container.appendChild(canvas);

            const viewport = page.getViewport({ scale: 1.5 });
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            await page.render({
                canvasContext: canvas.getContext('2d'),
                viewport: viewport
            });

            document.getElementById('currentPage').textContent = pageNum;
            updateButtonState();
        }

        // 预加载和按钮控制（保持不变）
        async function preloadPages(start, end) {
            const promises = [];
            for (let pageNum = start; pageNum <= end; pageNum++) {
                if (!pageCache.has(pageNum)) {
                    promises.push(
                        pdfInstance.getPage(pageNum)
                            .then(page => pageCache.set(pageNum, page))
                            .catch(console.error)
                    );
                }
            }
            await Promise.all(promises);
        }

        function updateButtonState() {
            document.getElementById('prevPage').disabled = currentPage === 1;
            document.getElementById('nextPage').disabled = currentPage === totalPages;
        }

        // 事件监听（保持不变）
        document.getElementById('prevPage').addEventListener('click', () => {
            if (currentPage > 1) renderPage(--currentPage);
        });

        document.getElementById('nextPage').addEventListener('click', () => {
            if (currentPage < totalPages) {
                renderPage(++currentPage);
                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            }
        });

        document.getElementById('jumpButton').addEventListener('click', () => {
            const inputPage = parseInt(document.getElementById('pageInput').value);
            if (!isNaN(inputPage) && inputPage > 0 && inputPage <= totalPages) {
                currentPage = inputPage;
                document.getElementById('pageInput').value = '';
                renderPage(currentPage);
            } else {
                alert(`请输入1到${totalPages}之间的有效页码`);
            }
        });

        document.getElementById('pageInput').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') document.getElementById('jumpButton').click();
        });

        // 新版刷新功能
        async function refreshPage() {
            try {
                const oldPage = currentPage;
                const db = await initDB();
                await deleteCachedPDF(db);
                pageCache.clear();

                await loadPDF(false); // 不自动渲染
                currentPage = Math.min(oldPage, totalPages);
                await renderPage(currentPage);

                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            } catch (error) {
                console.error('刷新失败:', error);
                alert('刷新失败，请检查网络连接');
            }
        }

        // 初始化加载
        loadPDF();
    </script>
</body>]]></description>
    <pubDate>Tue, 18 Mar 2025 18:10:54 +0800</pubDate>
    <dc:creator>Anglei</dc:creator>
    <guid>https://docu.org.cn/?post=53</guid>
</item>
<item>
    <title>基于K8S的Prometheus监控告警</title>
    <link>https://docu.org.cn/?post=51</link>
    <description><![CDATA[<head>
    <meta charset="UTF-8">
    <!-- PDF.js库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.min.js"></script>
    <style>
        /* 原有样式保持不变 */
        .pdf-container {
            display: flex;
            flex-direction: column;
            height: auto;
        }

        .pdf-controls {
            padding: 10px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
            display: flex;
            align-items: center;
            gap: 15px;
        }

        button {
            padding: 8px 15px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: background 0.3s;
        }

        button:hover {
            background: #0056b3;
        }

        button:disabled {
            background: #6c757d;
            cursor: not-allowed;
        }

        .page-jump input {
            width: 60px;
            padding: 5px;
            margin-right: 5px;
            border: 1px solid #ddd;
            border-radius: 3px;
        }

        #pdfViewer {
            overflow: auto;
            background: black;
            position: relative;
        }

        canvas {
            display: block;
            margin: 0 auto;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }

        .fullscreen #pdfViewer {
            height: auto;
        }

        .fullscreen-btn {
            margin-left: auto;
            background: #28a745;
        }

        .fullscreen-btn:hover {
            background: #218838;
        }
    </style>
</head>
<body>
    <div class="pdf-container" id="pdfContainer">
        <div class="pdf-controls">
            <button id="prevPage">上页</button>
            <span id="currentPage">1</span>/
            <span id="totalPages">1</span>
            <button id="nextPage">下页</button>
            <div class="page-jump">
                <input type="number" id="pageInput" placeholder="页数" min="1">
                <button id="jumpButton">跳转</button>
            </div>
            <button onclick="refreshPage()">刷新</button>
            <button id="fullscreenBtn" class="fullscreen-btn" title="全屏">全屏</button>
        </div>
        <div id="pdfViewer"></div>
    </div>
    <script>
        // 安全防护（保持不变）
        document.addEventListener('contextmenu', e => e.preventDefault());
        document.addEventListener('keydown', e => {
            if (e.ctrlKey && (e.key === 's' || e.key === 'p')) e.preventDefault();
        });

        // 全屏控制（保持不变）
        function toggleFullscreen() {
            const container = document.getElementById('pdfContainer');

            if (!document.fullscreenElement) {
                container.requestFullscreen?.() ||
                container.webkitRequestFullscreen?.() ||
                container.mozRequestFullScreen?.();
            } else {
                document.exitFullscreen?.() ||
                document.webkitExitFullscreen?.() ||
                document.mozCancelFullScreen?.();
            }
        }

        // 全屏按钮状态更新（保持不变）
        function updateFullscreenButton() {
            const btn = document.getElementById('fullscreenBtn');
            btn.textContent = document.fullscreenElement ? "退出全屏" : "全屏";
        }

        // 全屏事件监听（保持不变）
        document.getElementById('fullscreenBtn').addEventListener('click', toggleFullscreen);
        ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange'].forEach(event => {
            document.addEventListener(event, updateFullscreenButton);
        });

        // PDF控制变量（保持不变）
        let currentPage = 1;
        let totalPages = 1;
        let pdfInstance = null;
        const pageCache = new Map();
        const pdfUrl = 'content/uploadfile/202503/772d1742292600.pdf';
        const dbName = 'pdfCacheDB';
        const storeName = 'pdfFiles';

        // IndexedDB初始化（保持不变）
        const initDB = () => {
            return new Promise((resolve, reject) => {
                const request = indexedDB.open(dbName, 1);
                request.onupgradeneeded = (e) => {
                    const db = e.target.result;
                    if (!db.objectStoreNames.contains(storeName)) {
                        db.createObjectStore(storeName);
                    }
                };
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => reject(request.error);
            });
        };

        // 缓存操作函数（新增删除功能）
        const getCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readonly');
                const store = transaction.objectStore(storeName);
                const request = store.get(pdfUrl);
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => resolve(null);
            });
        };

        const savePDFToCache = async (db, data) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                store.put(data, pdfUrl);
                transaction.oncomplete = () => resolve();
            });
        };

        const deleteCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                const request = store.delete(pdfUrl);
                request.onsuccess = () => resolve();
                request.onerror = () => resolve();
            });
        };

        // PDF加载核心逻辑（增加autoRender参数）
        const loadPDF = async (autoRender = true) => {
            try {
                const db = await initDB();
                const cachedData = await getCachedPDF(db);

                if (cachedData) {
                    pdfInstance = await pdfjsLib.getDocument({
                        data: cachedData,
                        disableAutoFetch: true,
                        disableStream: true
                    }).promise;
                } else {
                    const loadingTask = pdfjsLib.getDocument({
                        url: pdfUrl,
                        disableAutoFetch: true,
                        disableStream: true
                    });

                    loadingTask.onProgress = (progress) => {
                        if (progress.loaded >= progress.total) {
                            loadingTask.promise.then(async (pdf) => {
                                const data = await pdf.getData();
                                await savePDFToCache(db, data);
                            });
                        }
                    };

                    pdfInstance = await loadingTask.promise;
                }

                totalPages = pdfInstance.numPages;
                document.getElementById('totalPages').textContent = totalPages;
                document.getElementById('pageInput').max = totalPages;

                if (autoRender) {
                    renderPage(currentPage);
                    preloadPages(2, Math.min(5, totalPages));
                }
            } catch (error) {
                console.error('PDF加载失败:', error);
            }
        };

        // 页面渲染（保持不变）
        async function renderPage(pageNum) {
            const container = document.getElementById('pdfViewer');
            container.innerHTML = '';

            let page = pageCache.get(pageNum) || await pdfInstance.getPage(pageNum);
            if (!pageCache.has(pageNum)) pageCache.set(pageNum, page);

            const canvas = document.createElement('canvas');
            container.appendChild(canvas);

            const viewport = page.getViewport({ scale: 1.5 });
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            await page.render({
                canvasContext: canvas.getContext('2d'),
                viewport: viewport
            });

            document.getElementById('currentPage').textContent = pageNum;
            updateButtonState();
        }

        // 预加载和按钮控制（保持不变）
        async function preloadPages(start, end) {
            const promises = [];
            for (let pageNum = start; pageNum <= end; pageNum++) {
                if (!pageCache.has(pageNum)) {
                    promises.push(
                        pdfInstance.getPage(pageNum)
                            .then(page => pageCache.set(pageNum, page))
                            .catch(console.error)
                    );
                }
            }
            await Promise.all(promises);
        }

        function updateButtonState() {
            document.getElementById('prevPage').disabled = currentPage === 1;
            document.getElementById('nextPage').disabled = currentPage === totalPages;
        }

        // 事件监听（保持不变）
        document.getElementById('prevPage').addEventListener('click', () => {
            if (currentPage > 1) renderPage(--currentPage);
        });

        document.getElementById('nextPage').addEventListener('click', () => {
            if (currentPage < totalPages) {
                renderPage(++currentPage);
                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            }
        });

        document.getElementById('jumpButton').addEventListener('click', () => {
            const inputPage = parseInt(document.getElementById('pageInput').value);
            if (!isNaN(inputPage) && inputPage > 0 && inputPage <= totalPages) {
                currentPage = inputPage;
                document.getElementById('pageInput').value = '';
                renderPage(currentPage);
            } else {
                alert(`请输入1到${totalPages}之间的有效页码`);
            }
        });

        document.getElementById('pageInput').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') document.getElementById('jumpButton').click();
        });

        // 新版刷新功能
        async function refreshPage() {
            try {
                const oldPage = currentPage;
                const db = await initDB();
                await deleteCachedPDF(db);
                pageCache.clear();

                await loadPDF(false); // 不自动渲染
                currentPage = Math.min(oldPage, totalPages);
                await renderPage(currentPage);

                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            } catch (error) {
                console.error('刷新失败:', error);
                alert('刷新失败，请检查网络连接');
            }
        }

        // 初始化加载
        loadPDF();
    </script>
</body>]]></description>
    <pubDate>Tue, 18 Mar 2025 18:09:34 +0800</pubDate>
    <dc:creator>Anglei</dc:creator>
    <guid>https://docu.org.cn/?post=51</guid>
</item>
<item>
    <title>openstack云计算问题解决大全</title>
    <link>https://docu.org.cn/?post=50</link>
    <description><![CDATA[<head>
    <meta charset="UTF-8">
    <!-- PDF.js库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.min.js"></script>
    <style>
        /* 原有样式保持不变 */
        .pdf-container {
            display: flex;
            flex-direction: column;
            height: auto;
        }

        .pdf-controls {
            padding: 10px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
            display: flex;
            align-items: center;
            gap: 15px;
        }

        button {
            padding: 8px 15px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: background 0.3s;
        }

        button:hover {
            background: #0056b3;
        }

        button:disabled {
            background: #6c757d;
            cursor: not-allowed;
        }

        .page-jump input {
            width: 60px;
            padding: 5px;
            margin-right: 5px;
            border: 1px solid #ddd;
            border-radius: 3px;
        }

        #pdfViewer {
            overflow: auto;
            background: black;
            position: relative;
        }

        canvas {
            display: block;
            margin: 0 auto;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }

        .fullscreen #pdfViewer {
            height: auto;
        }

        .fullscreen-btn {
            margin-left: auto;
            background: #28a745;
        }

        .fullscreen-btn:hover {
            background: #218838;
        }
    </style>
</head>
<body>
    <div class="pdf-container" id="pdfContainer">
        <div class="pdf-controls">
            <button id="prevPage">上页</button>
            <span id="currentPage">1</span>/
            <span id="totalPages">1</span>
            <button id="nextPage">下页</button>
            <div class="page-jump">
                <input type="number" id="pageInput" placeholder="页数" min="1">
                <button id="jumpButton">跳转</button>
            </div>
            <button onclick="refreshPage()">刷新</button>
            <button id="fullscreenBtn" class="fullscreen-btn" title="全屏">全屏</button>
        </div>
        <div id="pdfViewer"></div>
    </div>
    <script>
        // 安全防护（保持不变）
        document.addEventListener('contextmenu', e => e.preventDefault());
        document.addEventListener('keydown', e => {
            if (e.ctrlKey && (e.key === 's' || e.key === 'p')) e.preventDefault();
        });

        // 全屏控制（保持不变）
        function toggleFullscreen() {
            const container = document.getElementById('pdfContainer');

            if (!document.fullscreenElement) {
                container.requestFullscreen?.() ||
                container.webkitRequestFullscreen?.() ||
                container.mozRequestFullScreen?.();
            } else {
                document.exitFullscreen?.() ||
                document.webkitExitFullscreen?.() ||
                document.mozCancelFullScreen?.();
            }
        }

        // 全屏按钮状态更新（保持不变）
        function updateFullscreenButton() {
            const btn = document.getElementById('fullscreenBtn');
            btn.textContent = document.fullscreenElement ? "退出全屏" : "全屏";
        }

        // 全屏事件监听（保持不变）
        document.getElementById('fullscreenBtn').addEventListener('click', toggleFullscreen);
        ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange'].forEach(event => {
            document.addEventListener(event, updateFullscreenButton);
        });

        // PDF控制变量（保持不变）
        let currentPage = 1;
        let totalPages = 1;
        let pdfInstance = null;
        const pageCache = new Map();
        const pdfUrl = 'content/uploadfile/202503/c7571742292450.pdf';
        const dbName = 'pdfCacheDB';
        const storeName = 'pdfFiles';

        // IndexedDB初始化（保持不变）
        const initDB = () => {
            return new Promise((resolve, reject) => {
                const request = indexedDB.open(dbName, 1);
                request.onupgradeneeded = (e) => {
                    const db = e.target.result;
                    if (!db.objectStoreNames.contains(storeName)) {
                        db.createObjectStore(storeName);
                    }
                };
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => reject(request.error);
            });
        };

        // 缓存操作函数（新增删除功能）
        const getCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readonly');
                const store = transaction.objectStore(storeName);
                const request = store.get(pdfUrl);
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => resolve(null);
            });
        };

        const savePDFToCache = async (db, data) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                store.put(data, pdfUrl);
                transaction.oncomplete = () => resolve();
            });
        };

        const deleteCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                const request = store.delete(pdfUrl);
                request.onsuccess = () => resolve();
                request.onerror = () => resolve();
            });
        };

        // PDF加载核心逻辑（增加autoRender参数）
        const loadPDF = async (autoRender = true) => {
            try {
                const db = await initDB();
                const cachedData = await getCachedPDF(db);

                if (cachedData) {
                    pdfInstance = await pdfjsLib.getDocument({
                        data: cachedData,
                        disableAutoFetch: true,
                        disableStream: true
                    }).promise;
                } else {
                    const loadingTask = pdfjsLib.getDocument({
                        url: pdfUrl,
                        disableAutoFetch: true,
                        disableStream: true
                    });

                    loadingTask.onProgress = (progress) => {
                        if (progress.loaded >= progress.total) {
                            loadingTask.promise.then(async (pdf) => {
                                const data = await pdf.getData();
                                await savePDFToCache(db, data);
                            });
                        }
                    };

                    pdfInstance = await loadingTask.promise;
                }

                totalPages = pdfInstance.numPages;
                document.getElementById('totalPages').textContent = totalPages;
                document.getElementById('pageInput').max = totalPages;

                if (autoRender) {
                    renderPage(currentPage);
                    preloadPages(2, Math.min(5, totalPages));
                }
            } catch (error) {
                console.error('PDF加载失败:', error);
            }
        };

        // 页面渲染（保持不变）
        async function renderPage(pageNum) {
            const container = document.getElementById('pdfViewer');
            container.innerHTML = '';

            let page = pageCache.get(pageNum) || await pdfInstance.getPage(pageNum);
            if (!pageCache.has(pageNum)) pageCache.set(pageNum, page);

            const canvas = document.createElement('canvas');
            container.appendChild(canvas);

            const viewport = page.getViewport({ scale: 1.5 });
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            await page.render({
                canvasContext: canvas.getContext('2d'),
                viewport: viewport
            });

            document.getElementById('currentPage').textContent = pageNum;
            updateButtonState();
        }

        // 预加载和按钮控制（保持不变）
        async function preloadPages(start, end) {
            const promises = [];
            for (let pageNum = start; pageNum <= end; pageNum++) {
                if (!pageCache.has(pageNum)) {
                    promises.push(
                        pdfInstance.getPage(pageNum)
                            .then(page => pageCache.set(pageNum, page))
                            .catch(console.error)
                    );
                }
            }
            await Promise.all(promises);
        }

        function updateButtonState() {
            document.getElementById('prevPage').disabled = currentPage === 1;
            document.getElementById('nextPage').disabled = currentPage === totalPages;
        }

        // 事件监听（保持不变）
        document.getElementById('prevPage').addEventListener('click', () => {
            if (currentPage > 1) renderPage(--currentPage);
        });

        document.getElementById('nextPage').addEventListener('click', () => {
            if (currentPage < totalPages) {
                renderPage(++currentPage);
                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            }
        });

        document.getElementById('jumpButton').addEventListener('click', () => {
            const inputPage = parseInt(document.getElementById('pageInput').value);
            if (!isNaN(inputPage) && inputPage > 0 && inputPage <= totalPages) {
                currentPage = inputPage;
                document.getElementById('pageInput').value = '';
                renderPage(currentPage);
            } else {
                alert(`请输入1到${totalPages}之间的有效页码`);
            }
        });

        document.getElementById('pageInput').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') document.getElementById('jumpButton').click();
        });

        // 新版刷新功能
        async function refreshPage() {
            try {
                const oldPage = currentPage;
                const db = await initDB();
                await deleteCachedPDF(db);
                pageCache.clear();

                await loadPDF(false); // 不自动渲染
                currentPage = Math.min(oldPage, totalPages);
                await renderPage(currentPage);

                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            } catch (error) {
                console.error('刷新失败:', error);
                alert('刷新失败，请检查网络连接');
            }
        }

        // 初始化加载
        loadPDF();
    </script>
</body>]]></description>
    <pubDate>Tue, 18 Mar 2025 18:07:08 +0800</pubDate>
    <dc:creator>Anglei</dc:creator>
    <guid>https://docu.org.cn/?post=50</guid>
</item>
<item>
    <title>数据中心网络技术红宝书</title>
    <link>https://docu.org.cn/?post=49</link>
    <description><![CDATA[<head>
    <meta charset="UTF-8">
    <!-- PDF.js库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.min.js"></script>
    <style>
        /* 原有样式保持不变 */
        .pdf-container {
            display: flex;
            flex-direction: column;
            height: auto;
        }

        .pdf-controls {
            padding: 10px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
            display: flex;
            align-items: center;
            gap: 15px;
        }

        button {
            padding: 8px 15px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: background 0.3s;
        }

        button:hover {
            background: #0056b3;
        }

        button:disabled {
            background: #6c757d;
            cursor: not-allowed;
        }

        .page-jump input {
            width: 60px;
            padding: 5px;
            margin-right: 5px;
            border: 1px solid #ddd;
            border-radius: 3px;
        }

        #pdfViewer {
            overflow: auto;
            background: black;
            position: relative;
        }

        canvas {
            display: block;
            margin: 0 auto;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }

        .fullscreen #pdfViewer {
            height: auto;
        }

        .fullscreen-btn {
            margin-left: auto;
            background: #28a745;
        }

        .fullscreen-btn:hover {
            background: #218838;
        }
    </style>
</head>
<body>
    <div class="pdf-container" id="pdfContainer">
        <div class="pdf-controls">
            <button id="prevPage">上页</button>
            <span id="currentPage">1</span>/
            <span id="totalPages">1</span>
            <button id="nextPage">下页</button>
            <div class="page-jump">
                <input type="number" id="pageInput" placeholder="页数" min="1">
                <button id="jumpButton">跳转</button>
            </div>
            <button onclick="refreshPage()">刷新</button>
            <button id="fullscreenBtn" class="fullscreen-btn" title="全屏">全屏</button>
        </div>
        <div id="pdfViewer"></div>
    </div>
    <script>
        // 安全防护（保持不变）
        document.addEventListener('contextmenu', e => e.preventDefault());
        document.addEventListener('keydown', e => {
            if (e.ctrlKey && (e.key === 's' || e.key === 'p')) e.preventDefault();
        });

        // 全屏控制（保持不变）
        function toggleFullscreen() {
            const container = document.getElementById('pdfContainer');

            if (!document.fullscreenElement) {
                container.requestFullscreen?.() ||
                container.webkitRequestFullscreen?.() ||
                container.mozRequestFullScreen?.();
            } else {
                document.exitFullscreen?.() ||
                document.webkitExitFullscreen?.() ||
                document.mozCancelFullScreen?.();
            }
        }

        // 全屏按钮状态更新（保持不变）
        function updateFullscreenButton() {
            const btn = document.getElementById('fullscreenBtn');
            btn.textContent = document.fullscreenElement ? "退出全屏" : "全屏";
        }

        // 全屏事件监听（保持不变）
        document.getElementById('fullscreenBtn').addEventListener('click', toggleFullscreen);
        ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange'].forEach(event => {
            document.addEventListener(event, updateFullscreenButton);
        });

        // PDF控制变量（保持不变）
        let currentPage = 1;
        let totalPages = 1;
        let pdfInstance = null;
        const pageCache = new Map();
        const pdfUrl = 'content/uploadfile/202503/015f1742292266.pdf';
        const dbName = 'pdfCacheDB';
        const storeName = 'pdfFiles';

        // IndexedDB初始化（保持不变）
        const initDB = () => {
            return new Promise((resolve, reject) => {
                const request = indexedDB.open(dbName, 1);
                request.onupgradeneeded = (e) => {
                    const db = e.target.result;
                    if (!db.objectStoreNames.contains(storeName)) {
                        db.createObjectStore(storeName);
                    }
                };
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => reject(request.error);
            });
        };

        // 缓存操作函数（新增删除功能）
        const getCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readonly');
                const store = transaction.objectStore(storeName);
                const request = store.get(pdfUrl);
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => resolve(null);
            });
        };

        const savePDFToCache = async (db, data) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                store.put(data, pdfUrl);
                transaction.oncomplete = () => resolve();
            });
        };

        const deleteCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                const request = store.delete(pdfUrl);
                request.onsuccess = () => resolve();
                request.onerror = () => resolve();
            });
        };

        // PDF加载核心逻辑（增加autoRender参数）
        const loadPDF = async (autoRender = true) => {
            try {
                const db = await initDB();
                const cachedData = await getCachedPDF(db);

                if (cachedData) {
                    pdfInstance = await pdfjsLib.getDocument({
                        data: cachedData,
                        disableAutoFetch: true,
                        disableStream: true
                    }).promise;
                } else {
                    const loadingTask = pdfjsLib.getDocument({
                        url: pdfUrl,
                        disableAutoFetch: true,
                        disableStream: true
                    });

                    loadingTask.onProgress = (progress) => {
                        if (progress.loaded >= progress.total) {
                            loadingTask.promise.then(async (pdf) => {
                                const data = await pdf.getData();
                                await savePDFToCache(db, data);
                            });
                        }
                    };

                    pdfInstance = await loadingTask.promise;
                }

                totalPages = pdfInstance.numPages;
                document.getElementById('totalPages').textContent = totalPages;
                document.getElementById('pageInput').max = totalPages;

                if (autoRender) {
                    renderPage(currentPage);
                    preloadPages(2, Math.min(5, totalPages));
                }
            } catch (error) {
                console.error('PDF加载失败:', error);
            }
        };

        // 页面渲染（保持不变）
        async function renderPage(pageNum) {
            const container = document.getElementById('pdfViewer');
            container.innerHTML = '';

            let page = pageCache.get(pageNum) || await pdfInstance.getPage(pageNum);
            if (!pageCache.has(pageNum)) pageCache.set(pageNum, page);

            const canvas = document.createElement('canvas');
            container.appendChild(canvas);

            const viewport = page.getViewport({ scale: 1.5 });
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            await page.render({
                canvasContext: canvas.getContext('2d'),
                viewport: viewport
            });

            document.getElementById('currentPage').textContent = pageNum;
            updateButtonState();
        }

        // 预加载和按钮控制（保持不变）
        async function preloadPages(start, end) {
            const promises = [];
            for (let pageNum = start; pageNum <= end; pageNum++) {
                if (!pageCache.has(pageNum)) {
                    promises.push(
                        pdfInstance.getPage(pageNum)
                            .then(page => pageCache.set(pageNum, page))
                            .catch(console.error)
                    );
                }
            }
            await Promise.all(promises);
        }

        function updateButtonState() {
            document.getElementById('prevPage').disabled = currentPage === 1;
            document.getElementById('nextPage').disabled = currentPage === totalPages;
        }

        // 事件监听（保持不变）
        document.getElementById('prevPage').addEventListener('click', () => {
            if (currentPage > 1) renderPage(--currentPage);
        });

        document.getElementById('nextPage').addEventListener('click', () => {
            if (currentPage < totalPages) {
                renderPage(++currentPage);
                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            }
        });

        document.getElementById('jumpButton').addEventListener('click', () => {
            const inputPage = parseInt(document.getElementById('pageInput').value);
            if (!isNaN(inputPage) && inputPage > 0 && inputPage <= totalPages) {
                currentPage = inputPage;
                document.getElementById('pageInput').value = '';
                renderPage(currentPage);
            } else {
                alert(`请输入1到${totalPages}之间的有效页码`);
            }
        });

        document.getElementById('pageInput').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') document.getElementById('jumpButton').click();
        });

        // 新版刷新功能
        async function refreshPage() {
            try {
                const oldPage = currentPage;
                const db = await initDB();
                await deleteCachedPDF(db);
                pageCache.clear();

                await loadPDF(false); // 不自动渲染
                currentPage = Math.min(oldPage, totalPages);
                await renderPage(currentPage);

                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            } catch (error) {
                console.error('刷新失败:', error);
                alert('刷新失败，请检查网络连接');
            }
        }

        // 初始化加载
        loadPDF();
    </script>
</body>]]></description>
    <pubDate>Tue, 18 Mar 2025 18:03:58 +0800</pubDate>
    <dc:creator>Anglei</dc:creator>
    <guid>https://docu.org.cn/?post=49</guid>
</item>
<item>
    <title>Shell编程三剑客对日志实战分析</title>
    <link>https://docu.org.cn/?post=48</link>
    <description><![CDATA[<head>
    <meta charset="UTF-8">
    <!-- PDF.js库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.min.js"></script>
    <style>
        /* 原有样式保持不变 */
        .pdf-container {
            display: flex;
            flex-direction: column;
            height: auto;
        }

        .pdf-controls {
            padding: 10px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
            display: flex;
            align-items: center;
            gap: 15px;
        }

        button {
            padding: 8px 15px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: background 0.3s;
        }

        button:hover {
            background: #0056b3;
        }

        button:disabled {
            background: #6c757d;
            cursor: not-allowed;
        }

        .page-jump input {
            width: 60px;
            padding: 5px;
            margin-right: 5px;
            border: 1px solid #ddd;
            border-radius: 3px;
        }

        #pdfViewer {
            overflow: auto;
            background: black;
            position: relative;
        }

        canvas {
            display: block;
            margin: 0 auto;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }

        .fullscreen #pdfViewer {
            height: auto;
        }

        .fullscreen-btn {
            margin-left: auto;
            background: #28a745;
        }

        .fullscreen-btn:hover {
            background: #218838;
        }
    </style>
</head>
<body>
    <div class="pdf-container" id="pdfContainer">
        <div class="pdf-controls">
            <button id="prevPage">上页</button>
            <span id="currentPage">1</span>/
            <span id="totalPages">1</span>
            <button id="nextPage">下页</button>
            <div class="page-jump">
                <input type="number" id="pageInput" placeholder="页数" min="1">
                <button id="jumpButton">跳转</button>
            </div>
            <button onclick="refreshPage()">刷新</button>
            <button id="fullscreenBtn" class="fullscreen-btn" title="全屏">全屏</button>
        </div>
        <div id="pdfViewer"></div>
    </div>
    <script>
        // 安全防护（保持不变）
        document.addEventListener('contextmenu', e => e.preventDefault());
        document.addEventListener('keydown', e => {
            if (e.ctrlKey && (e.key === 's' || e.key === 'p')) e.preventDefault();
        });

        // 全屏控制（保持不变）
        function toggleFullscreen() {
            const container = document.getElementById('pdfContainer');

            if (!document.fullscreenElement) {
                container.requestFullscreen?.() ||
                container.webkitRequestFullscreen?.() ||
                container.mozRequestFullScreen?.();
            } else {
                document.exitFullscreen?.() ||
                document.webkitExitFullscreen?.() ||
                document.mozCancelFullScreen?.();
            }
        }

        // 全屏按钮状态更新（保持不变）
        function updateFullscreenButton() {
            const btn = document.getElementById('fullscreenBtn');
            btn.textContent = document.fullscreenElement ? "退出全屏" : "全屏";
        }

        // 全屏事件监听（保持不变）
        document.getElementById('fullscreenBtn').addEventListener('click', toggleFullscreen);
        ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange'].forEach(event => {
            document.addEventListener(event, updateFullscreenButton);
        });

        // PDF控制变量（保持不变）
        let currentPage = 1;
        let totalPages = 1;
        let pdfInstance = null;
        const pageCache = new Map();
        const pdfUrl = 'content/uploadfile/202503/34671742263197.pdf';
        const dbName = 'pdfCacheDB';
        const storeName = 'pdfFiles';

        // IndexedDB初始化（保持不变）
        const initDB = () => {
            return new Promise((resolve, reject) => {
                const request = indexedDB.open(dbName, 1);
                request.onupgradeneeded = (e) => {
                    const db = e.target.result;
                    if (!db.objectStoreNames.contains(storeName)) {
                        db.createObjectStore(storeName);
                    }
                };
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => reject(request.error);
            });
        };

        // 缓存操作函数（新增删除功能）
        const getCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readonly');
                const store = transaction.objectStore(storeName);
                const request = store.get(pdfUrl);
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => resolve(null);
            });
        };

        const savePDFToCache = async (db, data) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                store.put(data, pdfUrl);
                transaction.oncomplete = () => resolve();
            });
        };

        const deleteCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                const request = store.delete(pdfUrl);
                request.onsuccess = () => resolve();
                request.onerror = () => resolve();
            });
        };

        // PDF加载核心逻辑（增加autoRender参数）
        const loadPDF = async (autoRender = true) => {
            try {
                const db = await initDB();
                const cachedData = await getCachedPDF(db);

                if (cachedData) {
                    pdfInstance = await pdfjsLib.getDocument({
                        data: cachedData,
                        disableAutoFetch: true,
                        disableStream: true
                    }).promise;
                } else {
                    const loadingTask = pdfjsLib.getDocument({
                        url: pdfUrl,
                        disableAutoFetch: true,
                        disableStream: true
                    });

                    loadingTask.onProgress = (progress) => {
                        if (progress.loaded >= progress.total) {
                            loadingTask.promise.then(async (pdf) => {
                                const data = await pdf.getData();
                                await savePDFToCache(db, data);
                            });
                        }
                    };

                    pdfInstance = await loadingTask.promise;
                }

                totalPages = pdfInstance.numPages;
                document.getElementById('totalPages').textContent = totalPages;
                document.getElementById('pageInput').max = totalPages;

                if (autoRender) {
                    renderPage(currentPage);
                    preloadPages(2, Math.min(5, totalPages));
                }
            } catch (error) {
                console.error('PDF加载失败:', error);
            }
        };

        // 页面渲染（保持不变）
        async function renderPage(pageNum) {
            const container = document.getElementById('pdfViewer');
            container.innerHTML = '';

            let page = pageCache.get(pageNum) || await pdfInstance.getPage(pageNum);
            if (!pageCache.has(pageNum)) pageCache.set(pageNum, page);

            const canvas = document.createElement('canvas');
            container.appendChild(canvas);

            const viewport = page.getViewport({ scale: 1.5 });
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            await page.render({
                canvasContext: canvas.getContext('2d'),
                viewport: viewport
            });

            document.getElementById('currentPage').textContent = pageNum;
            updateButtonState();
        }

        // 预加载和按钮控制（保持不变）
        async function preloadPages(start, end) {
            const promises = [];
            for (let pageNum = start; pageNum <= end; pageNum++) {
                if (!pageCache.has(pageNum)) {
                    promises.push(
                        pdfInstance.getPage(pageNum)
                            .then(page => pageCache.set(pageNum, page))
                            .catch(console.error)
                    );
                }
            }
            await Promise.all(promises);
        }

        function updateButtonState() {
            document.getElementById('prevPage').disabled = currentPage === 1;
            document.getElementById('nextPage').disabled = currentPage === totalPages;
        }

        // 事件监听（保持不变）
        document.getElementById('prevPage').addEventListener('click', () => {
            if (currentPage > 1) renderPage(--currentPage);
        });

        document.getElementById('nextPage').addEventListener('click', () => {
            if (currentPage < totalPages) {
                renderPage(++currentPage);
                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            }
        });

        document.getElementById('jumpButton').addEventListener('click', () => {
            const inputPage = parseInt(document.getElementById('pageInput').value);
            if (!isNaN(inputPage) && inputPage > 0 && inputPage <= totalPages) {
                currentPage = inputPage;
                document.getElementById('pageInput').value = '';
                renderPage(currentPage);
            } else {
                alert(`请输入1到${totalPages}之间的有效页码`);
            }
        });

        document.getElementById('pageInput').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') document.getElementById('jumpButton').click();
        });

        // 新版刷新功能
        async function refreshPage() {
            try {
                const oldPage = currentPage;
                const db = await initDB();
                await deleteCachedPDF(db);
                pageCache.clear();

                await loadPDF(false); // 不自动渲染
                currentPage = Math.min(oldPage, totalPages);
                await renderPage(currentPage);

                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            } catch (error) {
                console.error('刷新失败:', error);
                alert('刷新失败，请检查网络连接');
            }
        }

        // 初始化加载
        loadPDF();
    </script>
</body>]]></description>
    <pubDate>Tue, 18 Mar 2025 09:59:07 +0800</pubDate>
    <dc:creator>Anglei</dc:creator>
    <guid>https://docu.org.cn/?post=48</guid>
</item>
<item>
    <title>280个开箱即用的shell脚本-马哥</title>
    <link>https://docu.org.cn/?post=47</link>
    <description><![CDATA[<head>
    <meta charset="UTF-8">
    <!-- PDF.js库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.min.js"></script>
    <style>
        /* 原有样式保持不变 */
        .pdf-container {
            display: flex;
            flex-direction: column;
            height: auto;
        }

        .pdf-controls {
            padding: 10px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
            display: flex;
            align-items: center;
            gap: 15px;
        }

        button {
            padding: 8px 15px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: background 0.3s;
        }

        button:hover {
            background: #0056b3;
        }

        button:disabled {
            background: #6c757d;
            cursor: not-allowed;
        }

        .page-jump input {
            width: 60px;
            padding: 5px;
            margin-right: 5px;
            border: 1px solid #ddd;
            border-radius: 3px;
        }

        #pdfViewer {
            overflow: auto;
            background: black;
            position: relative;
        }

        canvas {
            display: block;
            margin: 0 auto;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }

        .fullscreen #pdfViewer {
            height: auto;
        }

        .fullscreen-btn {
            margin-left: auto;
            background: #28a745;
        }

        .fullscreen-btn:hover {
            background: #218838;
        }
    </style>
</head>
<body>
    <div class="pdf-container" id="pdfContainer">
        <div class="pdf-controls">
            <button id="prevPage">上页</button>
            <span id="currentPage">1</span>/
            <span id="totalPages">1</span>
            <button id="nextPage">下页</button>
            <div class="page-jump">
                <input type="number" id="pageInput" placeholder="页数" min="1">
                <button id="jumpButton">跳转</button>
            </div>
            <button onclick="refreshPage()">刷新</button>
            <button id="fullscreenBtn" class="fullscreen-btn" title="全屏">全屏</button>
        </div>
        <div id="pdfViewer"></div>
    </div>
    <script>
        // 安全防护（保持不变）
        document.addEventListener('contextmenu', e => e.preventDefault());
        document.addEventListener('keydown', e => {
            if (e.ctrlKey && (e.key === 's' || e.key === 'p')) e.preventDefault();
        });

        // 全屏控制（保持不变）
        function toggleFullscreen() {
            const container = document.getElementById('pdfContainer');

            if (!document.fullscreenElement) {
                container.requestFullscreen?.() ||
                container.webkitRequestFullscreen?.() ||
                container.mozRequestFullScreen?.();
            } else {
                document.exitFullscreen?.() ||
                document.webkitExitFullscreen?.() ||
                document.mozCancelFullScreen?.();
            }
        }

        // 全屏按钮状态更新（保持不变）
        function updateFullscreenButton() {
            const btn = document.getElementById('fullscreenBtn');
            btn.textContent = document.fullscreenElement ? "退出全屏" : "全屏";
        }

        // 全屏事件监听（保持不变）
        document.getElementById('fullscreenBtn').addEventListener('click', toggleFullscreen);
        ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange'].forEach(event => {
            document.addEventListener(event, updateFullscreenButton);
        });

        // PDF控制变量（保持不变）
        let currentPage = 1;
        let totalPages = 1;
        let pdfInstance = null;
        const pageCache = new Map();
        const pdfUrl = 'content/uploadfile/202503/58f51742229122.pdf';
        const dbName = 'pdfCacheDB';
        const storeName = 'pdfFiles';

        // IndexedDB初始化（保持不变）
        const initDB = () => {
            return new Promise((resolve, reject) => {
                const request = indexedDB.open(dbName, 1);
                request.onupgradeneeded = (e) => {
                    const db = e.target.result;
                    if (!db.objectStoreNames.contains(storeName)) {
                        db.createObjectStore(storeName);
                    }
                };
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => reject(request.error);
            });
        };

        // 缓存操作函数（新增删除功能）
        const getCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readonly');
                const store = transaction.objectStore(storeName);
                const request = store.get(pdfUrl);
                request.onsuccess = () => resolve(request.result);
                request.onerror = () => resolve(null);
            });
        };

        const savePDFToCache = async (db, data) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                store.put(data, pdfUrl);
                transaction.oncomplete = () => resolve();
            });
        };

        const deleteCachedPDF = async (db) => {
            return new Promise((resolve) => {
                const transaction = db.transaction(storeName, 'readwrite');
                const store = transaction.objectStore(storeName);
                const request = store.delete(pdfUrl);
                request.onsuccess = () => resolve();
                request.onerror = () => resolve();
            });
        };

        // PDF加载核心逻辑（增加autoRender参数）
        const loadPDF = async (autoRender = true) => {
            try {
                const db = await initDB();
                const cachedData = await getCachedPDF(db);

                if (cachedData) {
                    pdfInstance = await pdfjsLib.getDocument({
                        data: cachedData,
                        disableAutoFetch: true,
                        disableStream: true
                    }).promise;
                } else {
                    const loadingTask = pdfjsLib.getDocument({
                        url: pdfUrl,
                        disableAutoFetch: true,
                        disableStream: true
                    });

                    loadingTask.onProgress = (progress) => {
                        if (progress.loaded >= progress.total) {
                            loadingTask.promise.then(async (pdf) => {
                                const data = await pdf.getData();
                                await savePDFToCache(db, data);
                            });
                        }
                    };

                    pdfInstance = await loadingTask.promise;
                }

                totalPages = pdfInstance.numPages;
                document.getElementById('totalPages').textContent = totalPages;
                document.getElementById('pageInput').max = totalPages;

                if (autoRender) {
                    renderPage(currentPage);
                    preloadPages(2, Math.min(5, totalPages));
                }
            } catch (error) {
                console.error('PDF加载失败:', error);
            }
        };

        // 页面渲染（保持不变）
        async function renderPage(pageNum) {
            const container = document.getElementById('pdfViewer');
            container.innerHTML = '';

            let page = pageCache.get(pageNum) || await pdfInstance.getPage(pageNum);
            if (!pageCache.has(pageNum)) pageCache.set(pageNum, page);

            const canvas = document.createElement('canvas');
            container.appendChild(canvas);

            const viewport = page.getViewport({ scale: 1.5 });
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            await page.render({
                canvasContext: canvas.getContext('2d'),
                viewport: viewport
            });

            document.getElementById('currentPage').textContent = pageNum;
            updateButtonState();
        }

        // 预加载和按钮控制（保持不变）
        async function preloadPages(start, end) {
            const promises = [];
            for (let pageNum = start; pageNum <= end; pageNum++) {
                if (!pageCache.has(pageNum)) {
                    promises.push(
                        pdfInstance.getPage(pageNum)
                            .then(page => pageCache.set(pageNum, page))
                            .catch(console.error)
                    );
                }
            }
            await Promise.all(promises);
        }

        function updateButtonState() {
            document.getElementById('prevPage').disabled = currentPage === 1;
            document.getElementById('nextPage').disabled = currentPage === totalPages;
        }

        // 事件监听（保持不变）
        document.getElementById('prevPage').addEventListener('click', () => {
            if (currentPage > 1) renderPage(--currentPage);
        });

        document.getElementById('nextPage').addEventListener('click', () => {
            if (currentPage < totalPages) {
                renderPage(++currentPage);
                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            }
        });

        document.getElementById('jumpButton').addEventListener('click', () => {
            const inputPage = parseInt(document.getElementById('pageInput').value);
            if (!isNaN(inputPage) && inputPage > 0 && inputPage <= totalPages) {
                currentPage = inputPage;
                document.getElementById('pageInput').value = '';
                renderPage(currentPage);
            } else {
                alert(`请输入1到${totalPages}之间的有效页码`);
            }
        });

        document.getElementById('pageInput').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') document.getElementById('jumpButton').click();
        });

        // 新版刷新功能
        async function refreshPage() {
            try {
                const oldPage = currentPage;
                const db = await initDB();
                await deleteCachedPDF(db);
                pageCache.clear();

                await loadPDF(false); // 不自动渲染
                currentPage = Math.min(oldPage, totalPages);
                await renderPage(currentPage);

                const preloadEnd = Math.min(currentPage + 5, totalPages);
                preloadPages(currentPage + 1, preloadEnd);
            } catch (error) {
                console.error('刷新失败:', error);
                alert('刷新失败，请检查网络连接');
            }
        }

        // 初始化加载
        loadPDF();
    </script>
</body>]]></description>
    <pubDate>Mon, 17 Mar 2025 23:53:21 +0800</pubDate>
    <dc:creator>Anglei</dc:creator>
    <guid>https://docu.org.cn/?post=47</guid>
</item></channel>
</rss>