Featured image of post 自建图库

自建图库

   
文章摘要
新的一天,有没有变得更好呢……😋

效果展示

Demo

image-20250109122119761

主要配置

静态网页,用于展示

网站结构

image-20250109122454001

index.html

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="icon" type="image/x-icon" href="/favicon.ico">
    <title>个人自用图片资源</title>
    <style>
        :root {
            --primary-color: #ffffff;
            --text-color: #ffffff;
            --border-color: #303030;
            --hover-color: #2c2c2c;
            --shadow-color: rgba(0, 0, 0, 0.3);
            --background-color: #0f0f0f;
            --surface-color: #212121;
            --secondary-text: #aaaaaa;
        }

        /* 浅色主题变量 */
        :root[data-theme="light"] {
            --primary-color: #000000;
            --text-color: #000000;
            --border-color: #e0e0e0;
            --hover-color: #f5f5f5;
            --shadow-color: rgba(0, 0, 0, 0.1);
            --background-color: #ffffff;
            --surface-color: #f8f8f8;
            --secondary-text: #666666;
        }

        body {
            margin: 0;
            padding: 5px;
            min-height: 100vh;
            background: var(--background-color);
            color: var(--text-color);
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
        }

        .container {
            max-width: 1600px;
            margin: 0 auto;
            padding: 0px;
        }

        h1 {
            text-align: center;
            margin-bottom: 20px;
            margin-top: 10px;
            font-size: 2em;
            color: var(--text-color);
            cursor: pointer;
            transition: opacity 0.3s ease;
        }

        h1:hover {
            opacity: 0.8;
        }

        .image-grid {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            gap: 20px;
            padding: 20px;
            opacity: 1;
            transition: opacity 0.3s ease;
        }

        .image-grid.loading {
            opacity: 0.6;
        }

        .image-item {
            position: relative;
            border-radius: 8px;
            background: var(--surface-color);
            transition: transform 0.3s ease, opacity 0.3s ease;
            cursor: pointer;
            display: flex;
            flex-direction: column;
            overflow: hidden;
            opacity: 0;
            animation: fadeIn 0.3s ease forwards;
        }

        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: translateY(10px);
            }

            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        .image-container {
            position: relative;
            aspect-ratio: 1;
            overflow: hidden;
        }

        .image-container img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            transition: transform 0.3s ease;
        }

        .image-item:hover .image-container img {
            transform: scale(1.05);
        }

        .image-info {
            padding: 15px;
            background: var(--surface-color);
            color: var(--text-color);
            font-size: 0.9em;
            line-height: 1.4;
            display: flex;
            flex-direction: column;
        }

        .image-info h3 {
            margin: 0 0 8px 0;
            font-size: 1.1em;
            color: var(--primary-color);
        }

        .image-info p {
            margin: 4px 0;
            color: var(--secondary-text);
        }

        .source-link {
            display: flex;
            align-items: center;
            padding: 6px 8px;
            background: var(--hover-color);
            border-radius: 4px;
            transition: background 0.2s ease;
            gap: 8px;
        }

        .source-link:hover {
            background: var(--border-color);
        }

        .source-name {
            font-weight: bold;
            color: var(--primary-color);
            min-width: 80px;
        }

        .source-url {
            color: var(--secondary-text);
            word-break: break-all;
            flex: 1;
            text-decoration: none;
        }

        .source-url:hover {
            color: var(--primary-color);
            text-decoration: underline;
        }

        .copy-icon {
            padding: 4px 8px;
            border-radius: 4px;
            color: var(--primary-color);
            cursor: pointer;
            background: var(--surface-color);
            transition: background 0.2s ease;
        }

        .copy-icon:hover {
            background: var(--border-color);
        }

        .copy-tooltip {
            position: fixed;
            top: 20px;
            left: 20px;
            background: #4CAF50;
            color: white;
            padding: 12px 24px;
            border-radius: 8px;
            font-size: 16px;
            font-weight: 500;
            pointer-events: none;
            opacity: 0;
            transform: translateY(-20px);
            transition: all 0.3s ease;
            z-index: 2001;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
            display: flex;
            align-items: center;
            gap: 8px;
            min-width: 200px;
        }

        .copy-tooltip::before {
            content: "✓";
            font-weight: bold;
            font-size: 18px;
        }

        .copy-tooltip.show {
            opacity: 1;
            transform: translateY(0);
        }

        /* 加载动画 */
        .loading {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: var(--background-color);
            display: none;
            justify-content: center;
            align-items: center;
            z-index: 1000;
            opacity: 0;
            transition: opacity 0.3s ease;
        }

        .loading.active {
            opacity: 1;
            display: flex;
        }

        .loading-spinner {
            width: 50px;
            height: 50px;
            border: 5px solid var(--border-color);
            border-top: 5px solid var(--primary-color);
            border-radius: 50%;
            animation: spin 1s linear infinite;
        }

        @keyframes spin {
            0% {
                transform: rotate(0deg);
            }

            100% {
                transform: rotate(360deg);
            }
        }

        /* 主题切换按钮 */
        .theme-toggle {
            position: fixed;
            top: 20px;
            right: 20px;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            background: var(--surface-color);
            border: 2px solid var(--border-color);
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 1000;
            transition: all 0.3s ease;
            opacity: 0;
            transform: scale(0.8);
        }

        .theme-toggle:hover {
            transform: scale(1);
            opacity: 1;
            background: var(--hover-color);
        }

        .theme-toggle svg {
            width: 24px;
            height: 24px;
            fill: var(--text-color);
            transition: all 0.3s ease;
        }

        /* 响应式布局 */
        @media screen and (max-width: 1200px) {
            .image-grid {
                grid-template-columns: repeat(3, 1fr);
            }
        }

        @media screen and (max-width: 768px) {
            .image-grid {
                grid-template-columns: repeat(2, 1fr);
                gap: 15px;
                padding: 15px;
            }

            .theme-toggle {
                top: 10px;
                right: 10px;
                width: 35px;
                height: 35px;
            }

            .theme-toggle svg {
                width: 20px;
                height: 20px;
            }
        }

        @media screen and (max-width: 480px) {
            .image-grid {
                grid-template-columns: 1fr;
                gap: 10px;
                padding: 10px;
            }

            h1 {
                font-size: 1.5em;
                margin-bottom: 20px;
            }
        }

        /* 图片查看器 */
        .image-viewer {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.9);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 2000;
            cursor: zoom-out;
            opacity: 0;
            transition: opacity 0.4s cubic-bezier(0.4, 0, 1, 1);
            pointer-events: none;
        }

        .image-viewer.active {
            opacity: 1;
            pointer-events: auto;
        }

        .viewer-loading {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 50px;
            height: 50px;
            border: 5px solid var(--border-color);
            border-top: 5px solid var(--primary-color);
            border-radius: 50%;
            animation: spin 1s linear infinite;
            display: none;
        }

        .viewer-loading.show {
            display: block;
        }

        .image-viewer img {
            max-width: 90%;
            max-height: 90vh;
            object-fit: contain;
            cursor: zoom-out;
            transition: transform 0.4s cubic-bezier(0.4, 0, 1, 1), opacity 0.4s cubic-bezier(0.4, 0, 1, 1);
            opacity: 0;
        }

        .image-viewer img.loaded {
            opacity: 1;
        }

        .close-viewer {
            position: absolute;
            top: 20px;
            right: 20px;
            width: 40px;
            height: 40px;
            background: var(--surface-color);
            border: none;
            border-radius: 50%;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            color: var(--text-color);
            font-size: 24px;
        }

        /* 修改折叠按钮和链接容器的样式 */
        .collapse-button {
            width: 100%;
            padding: 10px;
            background: var(--surface-color);
            border: none;
            border-radius: 4px;
            color: var(--text-color);
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: space-between;
            transition: background 0.2s ease;
            margin-bottom: 0;
        }

        .collapse-button:hover {
            background: var(--hover-color);
        }

        .collapse-button::after {
            content: "▼";
            font-size: 12px;
            transition: transform 0.3s ease;
        }

        .collapse-button.collapsed::after {
            transform: rotate(-90deg);
        }

        .links-container {
            display: flex;
            flex-direction: column;
            gap: 8px;
            padding: 8px 0;
            transition: all 0.3s ease;
            overflow: hidden;
            flex: 1;
        }

        .links-container.collapsed {
            padding: 0;
            max-height: 0;
        }

        /* 添加分页样式 */
        .pagination {
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 8px;
            margin: 20px 0;
            flex-wrap: wrap;
            padding: 0 10px;
            opacity: 0;
            transition: opacity 0.3s ease;
        }

        .pagination.show {
            opacity: 1;
        }

        .page-button {
            padding: 8px 16px;
            border: none;
            border-radius: 4px;
            background: var(--surface-color);
            color: var(--text-color);
            cursor: pointer;
            transition: all 0.2s ease;
        }

        .page-button:hover {
            background: var(--hover-color);
        }

        .page-button.active {
            background: var(--primary-color);
            color: var(--background-color);
        }

        .page-button:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }

        /* 添加搜索框样式 */
        .search-container {
            margin: 0px auto;
            width: 100%;
            max-width: 800px;
            position: relative;
            box-sizing: border-box;
        }

        .search-input {
            width: 100%;
            padding: 12px 20px;
            font-size: 16px;
            border: 2px solid var(--border-color);
            border-radius: 8px;
            background: var(--surface-color);
            color: var(--text-color);
            transition: all 0.3s ease;
            box-sizing: border-box;
        }

        .search-input:focus {
            outline: none;
            border-color: var(--primary-color);
            box-shadow: 0 0 5px var(--shadow-color);
        }

        .search-input::placeholder {
            color: var(--secondary-text);
        }

        .clear-search {
            position: absolute;
            right: 10px;
            top: 50%;
            transform: translateY(-50%);
            background: none;
            border: none;
            color: var(--secondary-text);
            cursor: pointer;
            padding: 5px;
            display: none;
        }

        .clear-search:hover {
            color: var(--primary-color);
        }

        .no-results {
            text-align: center;
            padding: 40px;
            color: var(--secondary-text);
            font-size: 1.2em;
        }

        @media screen and (max-width: 1200px) {
            .search-container {
                max-width: 90%;
            }
        }

        @media screen and (max-width: 480px) {
            .search-container {
                margin: 10px auto;
                width: 90%;
            }
            
            .search-input {
                padding: 10px 15px;
                font-size: 14px;
            }
        }

        .page-dots {
            padding: 8px 12px;
            color: var(--text-color);
            user-select: none;
        }
        
        .pagination {
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 8px;
            margin: 20px 0;
            flex-wrap: wrap;
            padding: 0 10px;
            opacity: 0;
            transition: opacity 0.3s ease;
        }

        .pagination.show {
            opacity: 1;
        }

        .page-button {
            min-width: 40px;
            height: 40px;
            padding: 0 12px;
            border: none;
            border-radius: 4px;
            background: var(--surface-color);
            color: var(--text-color);
            cursor: pointer;
            transition: all 0.2s ease;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        @media screen and (max-width: 480px) {
            .page-button {
                min-width: 36px;
                height: 36px;
                padding: 0 8px;
                font-size: 14px;
            }
            
            .pagination {
                gap: 4px;
            }
        }

        /* 添加上传按钮样式 */
        .upload-button {
            position: fixed;
            right: 20px;
            bottom: 20px;
            padding: 0 20px;
            height: 45px;
            border-radius: 25px;
            background: var(--primary-color);
            color: var(--background-color);
            border: none;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 8px;
            font-size: 16px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
            transition: all 0.3s ease;
            z-index: 1000;
            text-decoration: none;
            opacity: 0;
            transform: scale(0.8);
        }

        .upload-button:hover {
            transform: scale(1);
            opacity: 1;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.4);
        }

        .upload-button svg {
            width: 20px;
            height: 20px;
            fill: currentColor;
        }

        @media screen and (max-width: 480px) {
            .upload-button {
                padding: 0 15px;
                height: 40px;
                right: 15px;
                bottom: 15px;
                font-size: 14px;
            }
            
            .upload-button svg {
                width: 18px;
                height: 18px;
            }
        }

        /* 添加导航按钮样式 */
        .viewer-nav {
            position: absolute;
            top: 50%;
            transform: translateY(-50%);
            width: 50px;
            height: 50px;
            background: rgba(0, 0, 0, 0.5);
            border: none;
            border-radius: 50%;
            color: white;
            font-size: 24px;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.3s ease;
            z-index: 2002;
        }

        .viewer-nav:hover {
            background: rgba(0, 0, 0, 0.8);
            transform: translateY(-50%) scale(1.1);
        }

        .viewer-prev {
            left: 20px;
        }

        .viewer-next {
            right: 20px;
        }

        /* 图片计数器样式 */
        .image-counter {
            position: absolute;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            background: rgba(0, 0, 0, 0.5);
            color: white;
            padding: 8px 16px;
            border-radius: 20px;
            font-size: 14px;
            z-index: 2002;
        }

        @media screen and (max-width: 768px) {
            .viewer-nav {
                width: 40px;
                height: 40px;
                font-size: 20px;
            }

            .viewer-prev {
                left: 10px;
            }

            .viewer-next {
                right: 10px;
            }
        }
    </style>
</head>

<body>
    <!-- 添加上传按钮 -->
    <a href="https://rn-alist.1143520.xyz:5244/%E5%9B%BE%E5%BA%8A%E4%B8%8A%E4%BC%A0" target="_blank" class="upload-button" title="上传图片">
        <svg viewBox="0 0 24 24">
            <path d="M9 16h6v-6h4l-7-7-7 7h4v6zm-4 2h14v2H5v-2z"/>
        </svg>
        <span>上传图片</span>
    </a>

    <button class="theme-toggle" id="themeToggle" aria-label="切换主题">
        <svg class="sun-icon" viewBox="0 0 24 24">
            <path
                d="M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zM2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1zm18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1zM11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1zm0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1zM5.99 4.58c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41L5.99 4.58zm12.37 12.37c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0 .39-.39.39-1.03 0-1.41l-1.06-1.06zm1.06-10.96c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06zM7.05 18.36c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06z" />
        </svg>
    </button>

    <div class="container">
        <h1>个人自用图片资源</h1>
        <!-- 添加搜索框 -->
        <div class="search-container">
            <input type="text" id="searchInput" class="search-input" placeholder="搜索图片名称..." autocomplete="off">
            <button id="clearSearch" class="clear-search"></button>
        </div>
        <div class="image-grid" id="imageGrid">
            <!-- 图片将通过 JavaScript 动态加载 -->
        </div>
    </div>

    <div class="loading" id="loading">
        <div class="loading-spinner"></div>
    </div>

    <div class="image-viewer" id="imageViewer">
        <button class="close-viewer" id="closeViewer">×</button>
        <button class="viewer-nav viewer-prev" id="viewerPrev"></button>
        <button class="viewer-nav viewer-next" id="viewerNext"></button>
        <div class="viewer-loading" id="viewerLoading"></div>
        <img src="" alt="" id="viewerImage">
        <div class="image-counter" id="imageCounter"></div>
    </div>

    <div class="pagination" id="pagination"></div>

    <script>
        document.addEventListener('DOMContentLoaded', function () {
            const imageGrid = document.getElementById('imageGrid');
            const loading = document.getElementById('loading');
            const imageViewer = document.getElementById('imageViewer');
            const viewerImage = document.getElementById('viewerImage');
            const closeViewer = document.getElementById('closeViewer');
            const themeToggle = document.getElementById('themeToggle');
            const root = document.documentElement;
            const title = document.querySelector('h1');
            const moonIcon = `<svg class="moon-icon" viewBox="0 0 24 24"><path d="M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-.46-.04-.92-.1-1.36-.98 1.37-2.58 2.26-4.4 2.26-3.03 0-5.5-2.47-5.5-5.5 0-1.82.89-3.42 2.26-4.4-.44-.06-.9-.1-1.36-.1z"/></svg>`;
            const sunIcon = `<svg class="sun-icon" viewBox="0 0 24 24"><path d="M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zM2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1zm18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1zM11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1zm0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1zM5.99 4.58c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41L5.99 4.58zm12.37 12.37c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0 .39-.39.39-1.03 0-1.41l-1.06-1.06zm1.06-10.96c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06zM7.05 18.36c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06z"/></svg>`;

            // 检查本地存储中的主题设置
            const savedTheme = localStorage.getItem('theme') || 'dark';
            root.setAttribute('data-theme', savedTheme);
            themeToggle.innerHTML = savedTheme === 'dark' ? sunIcon : moonIcon;

            // 主题切换
            themeToggle.addEventListener('click', () => {
                const currentTheme = root.getAttribute('data-theme');
                const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
                root.setAttribute('data-theme', newTheme);
                themeToggle.innerHTML = newTheme === 'dark' ? sunIcon : moonIcon;
                localStorage.setItem('theme', newTheme);
            });

            // 创建复制提示元素
            const tooltip = document.createElement('div');
            tooltip.className = 'copy-tooltip';
            tooltip.textContent = '链接已复制到剪贴板';
            document.body.appendChild(tooltip);

            // 复制文本到剪贴板的函数
            async function copyToClipboard(text, event) {
                try {
                    await navigator.clipboard.writeText(text);

                    // 直接显示提示,不需要计算位置
                    tooltip.style.background = '#4CAF50';  // 重置为成功颜色
                    tooltip.textContent = '链接已复制到剪贴板';
                    tooltip.classList.add('show');

                    // 2秒后隐藏提示
                    setTimeout(() => {
                        tooltip.classList.remove('show');
                    }, 2000);
                } catch (err) {
                    console.error('复制失败:', err);
                    // 显示错误提示
                    tooltip.style.background = '#f44336';
                    tooltip.textContent = '复制失败,请重试';
                    tooltip.classList.add('show');

                    // 2秒后隐藏提示
                    setTimeout(() => {
                        tooltip.classList.remove('show');
                    }, 2000);
                }
            }

            const ITEMS_PER_PAGE = 20;
            let currentPage = 1;
            let allImageFiles = [];
            let filteredImageFiles = [];
            let totalPages = 1;
            let searchTimeout;

            // 添加搜索相关的DOM元素
            const searchInput = document.getElementById('searchInput');
            const clearSearch = document.getElementById('clearSearch');

            // 添加搜索输入框的事件监听
            searchInput.addEventListener('input', (e) => {
                const query = e.target.value.trim();
                clearSearch.style.display = query ? 'block' : 'none';
                handleSearch(query);
            });

            // 添加搜索框的键盘事件监听
            searchInput.addEventListener('keydown', (e) => {
                if (e.key === 'Escape') {
                    searchInput.value = '';
                    clearSearch.style.display = 'none';
                    filteredImageFiles = allImageFiles;
                    currentPage = 1;
                    createPagination(filteredImageFiles.length);
                    loadPageImages();
                    updateUrlWithPage(currentPage);
                }
            });

            // 从URL获取页码
            function getPageFromUrl() {
                const path = window.location.pathname;
                const match = path.match(/\/(\d{3})/);
                if (match) {
                    const page = parseInt(match[1]);
                    return page > 0 ? page : 1;
                }
                return 1;
            }

            // 更新URL中的页码
            function updateUrlWithPage(page) {
                const formattedPage = String(page).padStart(3, '0');
                const newUrl = `/${formattedPage}`;
                window.history.pushState({ page }, '', newUrl);
                // 更新分页显示
                createPagination(filteredImageFiles.length);
            }

            // 创建分页按钮
            function createPagination(total) {
                const pagination = document.getElementById('pagination');
                pagination.innerHTML = '';
                totalPages = Math.ceil(total / ITEMS_PER_PAGE);

                // 上一页按钮
                const prevButton = document.createElement('button');
                prevButton.className = 'page-button';
                prevButton.textContent = '上一页';
                prevButton.disabled = currentPage === 1;
                prevButton.addEventListener('click', () => {
                    if (currentPage > 1) {
                        currentPage--;
                        updateUrlWithPage(currentPage);
                        loadPageImages();
                    }
                });
                pagination.appendChild(prevButton);

                // 计算需要显示的页码范围
                let startPage = Math.max(1, currentPage - 10);
                let endPage = Math.min(totalPages, currentPage + 10);
                const showLeftDots = startPage > 2;
                const showRightDots = endPage < totalPages - 1;

                // 第一页
                addPageButton(1);

                // 左侧省略号
                if (showLeftDots) {
                    const dotsSpan = document.createElement('span');
                    dotsSpan.className = 'page-dots';
                    dotsSpan.textContent = '...';
                    pagination.appendChild(dotsSpan);
                }

                // 中间页码
                for (let i = startPage; i <= endPage; i++) {
                    if (i !== 1 && i !== totalPages) {
                        addPageButton(i);
                    }
                }

                // 右侧省略号
                if (showRightDots) {
                    const dotsSpan = document.createElement('span');
                    dotsSpan.className = 'page-dots';
                    dotsSpan.textContent = '...';
                    pagination.appendChild(dotsSpan);
                }

                // 最后一页
                if (totalPages > 1) {
                    addPageButton(totalPages);
                }

                // 下一页按钮
                const nextButton = document.createElement('button');
                nextButton.className = 'page-button';
                nextButton.textContent = '下一页';
                nextButton.disabled = currentPage === totalPages;
                nextButton.addEventListener('click', () => {
                    if (currentPage < totalPages) {
                        currentPage++;
                        updateUrlWithPage(currentPage);
                        loadPageImages();
                    }
                });
                pagination.appendChild(nextButton);
            }

            // 辅助函数:添加页码按钮
            function addPageButton(pageNum) {
                const pageButton = document.createElement('button');
                pageButton.className = `page-button ${pageNum === currentPage ? 'active' : ''}`;
                pageButton.textContent = pageNum;
                pageButton.addEventListener('click', () => {
                    if (pageNum !== currentPage) {
                        currentPage = pageNum;
                        updateUrlWithPage(currentPage);
                        loadPageImages();
                    }
                });
                pagination.appendChild(pageButton);
            }

            // 搜索功能
            function performSearch(query) {
                query = query.toLowerCase();
                filteredImageFiles = allImageFiles.filter(file =>
                    file.toLowerCase().includes(query)
                );
                currentPage = 1;
                createPagination(filteredImageFiles.length);
                loadPageImages();
                updateUrlWithPage(currentPage);
            }

            // 添加分页按钮状态更新函数
            function updatePaginationButtons() {
                const buttons = document.querySelectorAll('.page-button');
                buttons.forEach(button => {
                    if (button.textContent === '上一页') {
                        button.disabled = currentPage === 1;
                    } else if (button.textContent === '下一页') {
                        button.disabled = currentPage === totalPages;
                    } else {
                        button.classList.toggle('active', parseInt(button.textContent) === currentPage);
                    }
                });
            }

            // 优化搜索功能,添加防抖
            function debounce(func, wait) {
                let timeout;
                return function executedFunction(...args) {
                    const later = () => {
                        clearTimeout(timeout);
                        func(...args);
                    };
                    clearTimeout(timeout);
                    timeout = setTimeout(later, wait);
                };
            }

            // 添加一个标志来跟踪是否是首次加载
            let isFirstLoad = true;

            // 修改loadPageImages函数以支持平滑过渡
            async function loadPageImages() {
                const imageGrid = document.getElementById('imageGrid');
                const pagination = document.getElementById('pagination');
                imageGrid.classList.add('loading');
                
                // 立即隐藏分页按钮(移除transition效果)
                pagination.style.transition = 'none';
                pagination.classList.remove('show');
                // 强制浏览器重绘
                pagination.offsetHeight;
                // 恢复transition效果
                pagination.style.transition = '';

                const start = (currentPage - 1) * ITEMS_PER_PAGE;
                const end = Math.min(start + ITEMS_PER_PAGE, filteredImageFiles.length);
                const currentPageFiles = filteredImageFiles.slice(start, end);

                // 如果没有搜索结果,显示提示信息
                if (currentPageFiles.length === 0) {
                    imageGrid.innerHTML = '<div class="no-results">没有找到匹配的图片</div>';
                    imageGrid.classList.remove('loading');
                    setTimeout(() => {
                        pagination.classList.add('show');
                    }, 300);
                    return;
                }

                // 预先获取当前页的JSON数据
                const jsonDataPromises = currentPageFiles.map(image =>
                    fetch(`/random/${image.replace(/\.(jpg|jpeg|png|gif|webp|ico|avif)$/i, '.json')}`)
                        .then(res => res.ok ? res.json() : null)
                        .catch(() => null)
                );

                const jsonDataArray = await Promise.all(jsonDataPromises);

                // 创建一个文档片段来存储所有新元素
                const fragment = document.createDocumentFragment();

                // 创建当前页的图片元素
                const imageElements = await Promise.all(currentPageFiles.map(async (image, index) => {
                    const imageItem = document.createElement('div');
                    imageItem.className = 'image-item';
                    // 添加延迟动画
                    imageItem.style.animationDelay = `${index * 50}ms`;

                    const imageContainer = document.createElement('div');
                    imageContainer.className = 'image-container';

                    const img = document.createElement('img');
                    img.alt = image;
                    img.loading = 'lazy';

                    // 设置图片源
                    const jsonData = jsonDataArray[index];
                    if (jsonData && jsonData['4399']) {
                        img.src = jsonData['4399'];
                        img.onerror = () => {
                            console.log(`Failed to load image from 4399, using local image for ${image}`);
                            img.src = `/random/${image}`;
                        };
                    } else {
                        img.src = `/random/${image}`;
                    }

                    imageContainer.appendChild(img);
                    imageItem.appendChild(imageContainer);

                    const imageInfo = document.createElement('div');
                    imageInfo.className = 'image-info';

                    // 修改图片点击事件,移动到这里
                    imageContainer.addEventListener('click', () => {
                        const allImages = document.querySelectorAll('.image-container img');
                        const index = Array.from(allImages).indexOf(img);
                        showImageViewer(img.src, index);
                    });

                    if (jsonData) {
                        // 创建折叠按钮
                        const collapseButton = document.createElement('button');
                        collapseButton.className = 'collapse-button';
                        collapseButton.textContent = decodeURIComponent(image);
                        imageInfo.appendChild(collapseButton);

                        // 创建链接容器
                        const linksContainer = document.createElement('div');
                        linksContainer.className = 'links-container collapsed';

                        // 获取JSON中的所有字段,保持原始顺序
                        const allFields = Object.keys(jsonData);

                        // 遍历所有字段创建链接
                        allFields.forEach(source => {
                            const url = jsonData[source];
                            const sourceLink = document.createElement('div');
                            sourceLink.className = 'source-link';
                            sourceLink.innerHTML = `
                                <span class="source-name">${source}:</span>
                                <a href="${url}" target="_blank" class="source-url">${url}</a>
                                <span class="copy-icon" title="点击复制链接">📋</span>
                            `;

                                // 只在点击复制图标时复制链接
                                const copyIcon = sourceLink.querySelector('.copy-icon');
                                copyIcon.addEventListener('click', (e) => {
                                    e.stopPropagation();
                                    copyToClipboard(url, e);
                                });

                            linksContainer.appendChild(sourceLink);
                        });

                        imageInfo.appendChild(linksContainer);

                        // 添加折叠功能
                        collapseButton.addEventListener('click', () => {
                            const isCollapsed = collapseButton.classList.toggle('collapsed');
                            linksContainer.classList.toggle('collapsed');

                            // 使用max-height来控制展开和收起
                            if (!isCollapsed) {
                                linksContainer.style.maxHeight = linksContainer.scrollHeight + "px";
                            } else {
                                linksContainer.style.maxHeight = "0";
                            }
                        });

                        // 默认折叠
                        collapseButton.classList.add('collapsed');
                    } else {
                        // 如果没有JSON数据,只显示文件名
                        const fileName = document.createElement('div');
                        fileName.className = 'file-name';
                        fileName.textContent = decodeURIComponent(image);
                        fileName.style.padding = '10px';
                        fileName.style.color = 'var(--text-color)';
                        imageInfo.appendChild(fileName);
                    }

                    imageItem.appendChild(imageInfo);

                    // 当图片加载完成时预加载大图
                    img.addEventListener('load', () => {
                        preloadImage(img.src).catch(console.error);
                    });

                    return imageItem;
                }));

                // 将所有元素添加到文档片段中
                imageElements.forEach(element => fragment.appendChild(element));

                // 清空网格并添加新元素
                requestAnimationFrame(() => {
                    imageGrid.innerHTML = '';
                    imageGrid.appendChild(fragment);
                    imageGrid.classList.remove('loading');
                    
                    // 延时显示分页按钮
                    setTimeout(() => {
                        pagination.classList.add('show');
                    }, 300);

                    // 直接设置滚动位置到顶部
                    window.scrollTo(0, 0);
                });

                // 更新分页按钮状态
                updatePaginationButtons();
            }

            // 修改搜索处理函数,重置首次加载标志
            const handleSearch = debounce((query) => {
                const imageGrid = document.getElementById('imageGrid');
                imageGrid.classList.add('loading');
                isFirstLoad = true; // 搜索时重置为首次加载状态

                setTimeout(() => {
                    performSearch(query);
                }, 10);
            }, 300);

            // 修改清除搜索函数,重置首次加载标志
            clearSearch.addEventListener('click', () => {
                searchInput.value = '';
                clearSearch.style.display = 'none';
                filteredImageFiles = allImageFiles;
                currentPage = 1;
                isFirstLoad = true; // 清除搜索时重置为首次加载状态
                createPagination(filteredImageFiles.length);
                loadPageImages();
                updateUrlWithPage(currentPage);
            });

            // 修改loadPageImages函数以支持平滑过渡
            async function loadPageImages() {
                const imageGrid = document.getElementById('imageGrid');
                const pagination = document.getElementById('pagination');
                imageGrid.classList.add('loading');
                
                // 立即隐藏分页按钮(移除transition效果)
                pagination.style.transition = 'none';
                pagination.classList.remove('show');
                // 强制浏览器重绘
                pagination.offsetHeight;
                // 恢复transition效果
                pagination.style.transition = '';

                const start = (currentPage - 1) * ITEMS_PER_PAGE;
                const end = Math.min(start + ITEMS_PER_PAGE, filteredImageFiles.length);
                const currentPageFiles = filteredImageFiles.slice(start, end);

                // 如果没有搜索结果,显示提示信息
                if (currentPageFiles.length === 0) {
                    imageGrid.innerHTML = '<div class="no-results">没有找到匹配的图片</div>';
                    imageGrid.classList.remove('loading');
                    setTimeout(() => {
                        pagination.classList.add('show');
                    }, 300);
                    return;
                }

                // 预先获取当前页的JSON数据
                const jsonDataPromises = currentPageFiles.map(image =>
                    fetch(`/random/${image.replace(/\.(jpg|jpeg|png|gif|webp|ico|avif)$/i, '.json')}`)
                        .then(res => res.ok ? res.json() : null)
                        .catch(() => null)
                );

                const jsonDataArray = await Promise.all(jsonDataPromises);

                // 创建一个文档片段来存储所有新元素
                const fragment = document.createDocumentFragment();

                // 创建当前页的图片元素
                const imageElements = await Promise.all(currentPageFiles.map(async (image, index) => {
                    const imageItem = document.createElement('div');
                    imageItem.className = 'image-item';
                    // 添加延迟动画
                    imageItem.style.animationDelay = `${index * 50}ms`;

                    const imageContainer = document.createElement('div');
                    imageContainer.className = 'image-container';

                    const img = document.createElement('img');
                    img.alt = image;
                    img.loading = 'lazy';

                    // 设置图片源
                    const jsonData = jsonDataArray[index];
                    if (jsonData && jsonData['4399']) {
                        img.src = jsonData['4399'];
                        img.onerror = () => {
                            console.log(`Failed to load image from 4399, using local image for ${image}`);
                            img.src = `/random/${image}`;
                        };
                    } else {
                        img.src = `/random/${image}`;
                    }

                    imageContainer.appendChild(img);
                    imageItem.appendChild(imageContainer);

                    const imageInfo = document.createElement('div');
                    imageInfo.className = 'image-info';

                    // 修改图片点击事件,移动到这里
                    imageContainer.addEventListener('click', () => {
                        const allImages = document.querySelectorAll('.image-container img');
                        const index = Array.from(allImages).indexOf(img);
                        showImageViewer(img.src, index);
                    });

                    if (jsonData) {
                        // 创建折叠按钮
                        const collapseButton = document.createElement('button');
                        collapseButton.className = 'collapse-button';
                        collapseButton.textContent = decodeURIComponent(image);
                        imageInfo.appendChild(collapseButton);

                        // 创建链接容器
                        const linksContainer = document.createElement('div');
                        linksContainer.className = 'links-container collapsed';

                        // 获取JSON中的所有字段,保持原始顺序
                        const allFields = Object.keys(jsonData);

                        // 遍历所有字段创建链接
                        allFields.forEach(source => {
                            const url = jsonData[source];
                            const sourceLink = document.createElement('div');
                            sourceLink.className = 'source-link';
                            sourceLink.innerHTML = `
                                <span class="source-name">${source}:</span>
                                <a href="${url}" target="_blank" class="source-url">${url}</a>
                                <span class="copy-icon" title="点击复制链接">📋</span>
                            `;

                                // 只在点击复制图标时复制链接
                                const copyIcon = sourceLink.querySelector('.copy-icon');
                                copyIcon.addEventListener('click', (e) => {
                                    e.stopPropagation();
                                    copyToClipboard(url, e);
                                });

                            linksContainer.appendChild(sourceLink);
                        });

                        imageInfo.appendChild(linksContainer);

                        // 添加折叠功能
                        collapseButton.addEventListener('click', () => {
                            const isCollapsed = collapseButton.classList.toggle('collapsed');
                            linksContainer.classList.toggle('collapsed');

                            // 使用max-height来控制展开和收起
                            if (!isCollapsed) {
                                linksContainer.style.maxHeight = linksContainer.scrollHeight + "px";
                            } else {
                                linksContainer.style.maxHeight = "0";
                            }
                        });

                        // 默认折叠
                        collapseButton.classList.add('collapsed');
                    } else {
                        // 如果没有JSON数据,只显示文件名
                        const fileName = document.createElement('div');
                        fileName.className = 'file-name';
                        fileName.textContent = decodeURIComponent(image);
                        fileName.style.padding = '10px';
                        fileName.style.color = 'var(--text-color)';
                        imageInfo.appendChild(fileName);
                    }

                    imageItem.appendChild(imageInfo);

                    // 当图片加载完成时预加载大图
                    img.addEventListener('load', () => {
                        preloadImage(img.src).catch(console.error);
                    });

                    return imageItem;
                }));

                // 将所有元素添加到文档片段中
                imageElements.forEach(element => fragment.appendChild(element));

                // 清空网格并添加新元素
                requestAnimationFrame(() => {
                    imageGrid.innerHTML = '';
                    imageGrid.appendChild(fragment);
                    imageGrid.classList.remove('loading');
                    
                    // 延时显示分页按钮
                    setTimeout(() => {
                        pagination.classList.add('show');
                    }, 300);

                    // 直接设置滚动位置到顶部
                    window.scrollTo(0, 0);
                });

                // 更新分页按钮状态
                updatePaginationButtons();
            }

            // 修改loadImages函数以支持搜索
            const loadImages = async () => {
                try {
                    const response = await fetch('/random/');
                    const text = await response.text();
                    const parser = new DOMParser();
                    const doc = parser.parseFromString(text, 'text/html');
                    const links = Array.from(doc.querySelectorAll('a'));
                    allImageFiles = links
                        .map(link => {
                            const href = link.getAttribute('href');
                            return href ? decodeURIComponent(href) : null;
                        })
                        .filter(href => href && /\.(jpg|jpeg|png|gif|webp|ico|avif)$/i.test(href));

                    filteredImageFiles = allImageFiles; // 初始化过滤后的图片列表

                    // 从URL获取初始页码
                    currentPage = getPageFromUrl();

                    // 创建分页
                    createPagination(filteredImageFiles.length);
                    // 加载当前页
                    await loadPageImages();
                } catch (error) {
                    console.error('Error loading images:', error);
                    loading.style.display = 'none';
                }
            };

            // 添加浏览器后退/前进事件处理
            window.addEventListener('popstate', (event) => {
                if (event.state && event.state.page) {
                    currentPage = event.state.page;
                    loadPageImages();
                }
            });

            // 修改标题点击事件
            title.addEventListener('click', () => {
                if (currentPage !== 1) {
                    currentPage = 1;
                    updateUrlWithPage(currentPage);
                    loadPageImages();
                }
            });

            // 加载图片
            loadImages();

            const viewerLoading = document.getElementById('viewerLoading');

            // 预加载图片函数
            function preloadImage(url) {
                return new Promise((resolve, reject) => {
                    const img = new Image();
                    img.onload = () => resolve(url);
                    img.onerror = () => reject(url);
                    img.src = url;
                });
            }

            let currentViewerIndex = -1; // 当前查看的图片索引

            // 修改图片查看逻辑
            async function showImageViewer(imgSrc, index) {
                currentViewerIndex = index;
                imageViewer.classList.add('active');
                viewerImage.classList.remove('loaded');
                viewerLoading.classList.add('show');

                // 更新计数器
                const start = (currentPage - 1) * ITEMS_PER_PAGE;
                const currentPageImages = filteredImageFiles.slice(start, Math.min(start + ITEMS_PER_PAGE, filteredImageFiles.length));
                document.getElementById('imageCounter').textContent = `${index + 1} / ${currentPageImages.length}`;

                try {
                    await preloadImage(imgSrc);
                    viewerImage.src = imgSrc;
                    viewerImage.classList.add('loaded');
                } catch (error) {
                    console.error('Failed to load image:', error);
                } finally {
                    viewerLoading.classList.remove('show');
                }
            }

            // 切换到上一张图片
            async function showPreviousImage() {
                const start = (currentPage - 1) * ITEMS_PER_PAGE;
                const currentPageImages = filteredImageFiles.slice(start, Math.min(start + ITEMS_PER_PAGE, filteredImageFiles.length));
                if (currentViewerIndex > 0) {
                    currentViewerIndex--;
                    const prevImage = document.querySelectorAll('.image-container img')[currentViewerIndex];
                    await showImageViewer(prevImage.src, currentViewerIndex);
                }
            }

            // 切换到下一张图片
            async function showNextImage() {
                const start = (currentPage - 1) * ITEMS_PER_PAGE;
                const currentPageImages = filteredImageFiles.slice(start, Math.min(start + ITEMS_PER_PAGE, filteredImageFiles.length));
                if (currentViewerIndex < currentPageImages.length - 1) {
                    currentViewerIndex++;
                    const nextImage = document.querySelectorAll('.image-container img')[currentViewerIndex];
                    await showImageViewer(nextImage.src, currentViewerIndex);
                }
            }

            // 添加导航按钮事件监听
            document.getElementById('viewerPrev').addEventListener('click', (e) => {
                e.stopPropagation();
                showPreviousImage();
            });

            document.getElementById('viewerNext').addEventListener('click', (e) => {
                e.stopPropagation();
                showNextImage();
            });

            // 添加键盘事件监听
            document.addEventListener('keydown', (e) => {
                if (imageViewer.classList.contains('active')) {
                    if (e.key === 'Escape') {
                        closeImageViewer();
                    } else if (e.key === 'ArrowLeft') {
                        showPreviousImage();
                    } else if (e.key === 'ArrowRight') {
                        showNextImage();
                    } else if (e.key === 'ArrowUp') {
                        // 上一页
                        if (currentPage > 1) {
                            closeImageViewer();
                            currentPage--;
                            updateUrlWithPage(currentPage);
                            loadPageImages().then(() => {
                                // 在新页面加载完成后,打开最后一张图片
                                setTimeout(() => {
                                    const allImages = document.querySelectorAll('.image-container img');
                                    if (allImages.length > 0) {
                                        const lastIndex = allImages.length - 1;
                                        showImageViewer(allImages[lastIndex].src, lastIndex);
                                    }
                                }, 100);
                            });
                        }
                    } else if (e.key === 'ArrowDown') {
                        // 下一页
                        if (currentPage < totalPages) {
                            closeImageViewer();
                            currentPage++;
                            updateUrlWithPage(currentPage);
                            loadPageImages().then(() => {
                                // 在新页面加载完成后,打开第一张图片
                                setTimeout(() => {
                                    const allImages = document.querySelectorAll('.image-container img');
                                    if (allImages.length > 0) {
                                        showImageViewer(allImages[0].src, 0);
                                    }
                                }, 100);
                            });
                        }
                    }
                } else {
                    // 当图片查看器未打开时的键盘事件处理
                    if (e.key === 'ArrowUp') {
                        // 上一页
                        if (currentPage > 1) {
                            currentPage--;
                            updateUrlWithPage(currentPage);
                            loadPageImages();
                        }
                    } else if (e.key === 'ArrowDown') {
                        // 下一页
                        if (currentPage < totalPages) {
                            currentPage++;
                            updateUrlWithPage(currentPage);
                            loadPageImages();
                        }
                    }
                }
            });

            // 修改关闭查看器的逻辑
            function closeImageViewer() {
                imageViewer.classList.remove('active');
                setTimeout(() => {
                    viewerImage.src = '';
                    viewerImage.classList.remove('loaded');
                }, 500);
            }

            closeViewer.addEventListener('click', (e) => {
                e.stopPropagation();
                closeImageViewer();
            });

            viewerImage.addEventListener('click', (e) => {
                e.stopPropagation();
                closeImageViewer();
            });

            imageViewer.addEventListener('click', () => {
                closeImageViewer();
            });

            document.addEventListener('keydown', (e) => {
                if (e.key === 'Escape' && imageViewer.classList.contains('active')) {
                    closeImageViewer();
                }
            });
        });
    </script>
</body>

</html>

nginx.conf

# 在 server 块之前添加日志格式定义
log_format img_access '$remote_addr - $remote_user [$time_local] '
                   '"$request" $status $body_bytes_sent '
                   '"$http_referer" "$http_user_agent" '
                   '"$http_range" $request_time';

server {
    listen 80 ; 
    listen [::]:80 ; 
    listen 443 ssl http2 ; 
    listen [::]:443 ssl http2 ; 
    server_name img-deploy.1143520.xyz; 
    index index.html index.php index.htm default.php default.htm default.html; 
    proxy_set_header Host $host; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header X-Forwarded-Host $server_name; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_http_version 1.1; 
    proxy_set_header Upgrade $http_upgrade; 
    proxy_set_header Connection $http_connection; 
    access_log /www/sites/img-deploy.1143520.xyz/log/access.log main; 
    error_log /www/sites/img-deploy.1143520.xyz/log/error.log; 
    location ^~ /.well-known/acme-challenge {
        allow all; 
        root /usr/share/nginx/html; 
    }
    root /www/sites/img-deploy.1143520.xyz/index; 
    error_page 404 /404.html; 
    if ($scheme = http) {
        return 301 https://$host$request_uri; 
    }
    ssl_certificate /www/sites/img-deploy.1143520.xyz/ssl/fullchain.pem; 
    ssl_certificate_key /www/sites/img-deploy.1143520.xyz/ssl/privkey.pem; 
    ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1 TLSv1; 
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK:!KRB5:!SRP:!CAMELLIA:!SEED; 
    ssl_prefer_server_ciphers on; 
    ssl_session_cache shared:SSL:10m; 
    ssl_session_timeout 10m; 
    error_page 497 https://$host$request_uri; 
    proxy_set_header X-Forwarded-Proto https; 
    add_header Strict-Transport-Security "max-age=31536000"; 

    # 图片目录配置
    location /random/ {
        valid_referers none blocked server_names
            *.1143520.xyz;
        if ($invalid_referer) {
            return 301 /;
        }

        alias /www/sites/img-deploy.1143520.xyz/index/random/;
        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;
        charset utf-8;
        
        add_header Access-Control-Allow-Origin "*";
        types {
            image/jpeg jpg jpeg;
            image/png png;
            image/gif gif;
            image/webp webp;
            application/json json;
        }
        add_header Cache-Control "public, max-age=3600";
        add_header X-Content-Type-Options "nosniff";
        
        access_log /www/sites/img-deploy.1143520.xyz/log/random_access.log img_access;
    }

    # 根路径配置
    location = / {
        try_files /index.html =404;
    }

    # 添加对页码URL的支持(修复正则表达式)
    location ~ "^/[0-9]{3}$" {
        try_files /index.html =404;
    }

    location = /index.html {
        return 301 /;
    }

    location ~* \.html$ {
        return 403;
    }
}

图片位置

/random

每一个图片对应一个json文件(没有同名json也不影响)

json文件是图片的链接集合

json示例

{
    "meituan-api": "https://img.meituan.net/video/e953cff3e704cf4c3fba3e6d5245204c246872.png",
    "niubi": "https://pic.rmb.bdstatic.com/bjh/3ed2c3ceb1c/241221/e953cff3e704cf4c3fba3e6d5245204c.png",
    "tx": "https://g.gtimg.cn/music/photo_new/T053XD01002eSyln2QiHl6.png",
}
CC BY-NC-SA 4.0 创意的非商业派对入场券
最后更新于 2025-01-09 14:30
晚来天欲雪,能饮一杯无