使用短链API写了一个批量短链生成网页,支持通过表格批量导入生成并且导出

随便发发 · 02-24 · 34 人浏览

使用短链API写了一个批量短链生成网页,支持通过表格批量导入生成并且导出,以下是网页源码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>批量短链生成系统</title>
    <style>
        :root {
            --primary-color: #6200ea;
            --secondary-color: #3700b3;
            --background-color: #f5f5f5;
            --text-color: #333;
            --border-color: #e0e0e0;
        }
        body {
            font-family: 'Segoe UI', system-ui, sans-serif;
            margin: 0;
            padding: 20px;
            background: var(--background-color);
            color: var(--text-color);
            line-height: 1.6;
        }
        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 16px;
            box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1);
            padding: 40px;
        }
        .header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 40px;
            padding-bottom: 20px;
            border-bottom: 2px solid var(--border-color);
        }
        .header h1 {
            font-size: 2rem;
            font-weight: 600;
            color: var(--primary-color);
        }
        .header button {
            background: var(--primary-color);
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 8px;
            cursor: pointer;
            font-size: 1rem;
            transition: background 0.3s ease;
        }
        .header button:hover {
            background: var(--secondary-color);
        }
        .batch-tools {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 30px;
            margin-bottom: 40px;
        }
        .file-upload-box {
            border: 2px dashed var(--border-color);
            border-radius: 12px;
            padding: 30px;
            text-align: center;
            position: relative;
            transition: border-color 0.3s ease;
        }
        .file-upload-box:hover {
            border-color: var(--primary-color);
        }
        .file-upload-box p {
            font-size: 1rem;
            margin-bottom: 15px;
        }
        .file-upload-box button {
            background: var(--primary-color);
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 8px;
            cursor: pointer;
            font-size: 1rem;
            transition: background 0.3s ease;
        }
        .file-upload-box button:hover {
            background: var(--secondary-color);
        }
        .template-download {
            color: var(--primary-color);
            cursor: pointer;
            margin-top: 10px;
            font-size: 0.9rem;
            transition: color 0.3s ease;
        }
        .template-download:hover {
            color: var(--secondary-color);
        }
        .progress-bar {
            height: 10px;
            background: var(--border-color);
            border-radius: 5px;
            margin-top: 20px;
            overflow: hidden;
        }
        .progress-fill {
            width: 0%;
            height: 100%;
            background: var(--primary-color);
            transition: width 0.3s ease;
        }
        .result-table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 20px;
        }
        .result-table th {
            background: var(--primary-color);
            color: white;
            padding: 15px;
            text-align: left;
            font-size: 1rem;
        }
        .result-table td {
            padding: 15px;
            border-bottom: 1px solid var(--border-color);
            font-size: 0.95rem;
        }
        .status-indicator {
            display: inline-block;
            width: 12px;
            height: 12px;
            border-radius: 50%;
            margin-right: 10px;
        }
        .status-success { background: #4caf50; }
        .status-error { background: #ff4444; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>WZU批量短链生成系统</h1>
            <div>
                <button onclick="downloadTemplate()">下载模板</button>
                <button onclick="exportToCSV()">导出数据</button>
            </div>
        </div>
        <div class="batch-tools">
            <div class="file-upload-box" ondragover="event.preventDefault()" ondrop="handleFileDrop(event)">
                <input type="file" id="csvFile" accept=".csv" hidden>
                <p>拖放CSV文件到此区域或</p>
                <button onclick="document.getElementById('csvFile').click()">选择文件</button>
                <div class="template-download" onclick="downloadTemplate()">下载CSV模板</div>
                <div class="progress-bar">
                    <div class="progress-fill" id="progressFill"></div>
                </div>
            </div>
            <div>
                <h3>批量生成设置</h3>
                <select id="batchConfig">
                    <option value="same">统一设置(所有链接相同配置)</option>
                    <option value="custom">自定义设置(按CSV列配置)</option>
                </select>
            </div>
        </div>
        <table class="result-table">
            <thead>
                <tr>
                    <th>状态</th>
                    <th>原链接</th>
                    <th>短链接</th>
                    <th>生成时间</th>
                </tr>
            </thead>
            <tbody id="resultBody"></tbody>
        </table>
    </div>
    <script>
        const API_KEY = 'wIziec93ZL';
        let batchData = [];
        // CSV模板下载
        function downloadTemplate() {
            const BOM = '\uFEFF';
            const csvContent = BOM + `原链接,标题,跳转类型,有效期,设备限制,短码位数\nhttp://example.com,示例链接,1,ever,1,4`;
            const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8' });
            const link = document.createElement('a');
            link.href = URL.createObjectURL(blob);
            link.download = '短链模板.csv';
            link.click();
        }
        // 文件拖放处理
        async function handleFileDrop(e) {
            e.preventDefault();
            const file = e.dataTransfer.files[0];
            if (file) await processCSV(file);
        }
        // CSV解析处理
        async function processCSV(file) {
            const reader = new FileReader();
            reader.onload = async (e) => {
                const text = e.target.result;
                const rows = text.split('\n').slice(1);
                batchData = [];
                let successCount = 0;
                document.getElementById('progressFill').style.width = '0%';
                for (let i = 0; i < rows.length; i++) {
                    const [url, title, type, validity, device, length] = rows[i].split(',');
                    if (!url) continue;
                    try {
                        const shortUrl = await generateShortUrl({
                            dwz_url: url.trim(),
                            dwz_title: title?.trim() || '默认标题',
                            dwz_reditype: type?.trim() || '1',
                            dwz_yxq: validity?.trim() || 'ever',
                            dwz_type: device?.trim() || '1',
                            dwz_keynum: length?.trim() || '4'
                        });
                        batchData.push({ url, shortUrl });
                        successCount++;
                    } catch (error) {
                        console.error(`第${i+1}行处理失败:`, error);
                    }
                    document.getElementById('progressFill').style.width = `${Math.round((i + 1) / rows.length * 100)}%`;
                }
                updateResultTable();
            };
            reader.readAsText(file);
        }
        // API请求生成短链
        async function generateShortUrl(params) {
            const query = new URLSearchParams({ ...params, api_key: API_KEY });
            const response = await fetch(`https://wzu.me/api/creat.php?${query}`);
            const data = await response.json();
            if (data.code === '100') return data.url;
            throw new Error(data.msg);
        }
        // 更新结果表格
        function updateResultTable() {
            const tbody = document.getElementById('resultBody');
            tbody.innerHTML = '';
            batchData.forEach(item => {
                const row = document.createElement('tr');
                row.innerHTML = `
                    <td><span class="status-indicator status-success"></span>成功</td>
                    <td>${item.url}</td>
                    <td><a href="${item.shortUrl}" target="_blank">${item.shortUrl}</a></td>
                    <td>${new Date().toLocaleString()}</td>
                `;
                tbody.appendChild(row);
            });
        }
        // 导出CSV功能
        function exportToCSV() {
            const BOM = '\uFEFF';
            const header = '原链接,短链接,生成时间\n';
            const content = batchData.map(item => 
                `${item.url},${item.shortUrl},${new Date().toLocaleString()}`
            ).join('\n');
            const blob = new Blob([BOM + header + content], { type: 'text/csv;charset=utf-8' });
            const link = document.createElement('a');
            link.href = URL.createObjectURL(blob);
            link.download = `短链导出_${Date.now()}.csv`;
            link.click();
        }
        // 初始化文件选择监听
        document.getElementById('csvFile').addEventListener('change', async (e) => {
            if (e.target.files[0]) await processCSV(e.target.files[0]);
        });
    </script>
</body>
</html>

因为APIkey需要单独授权,可以查看https://blog.wzu.me/ff/35.html开发文档,免费获取

表情
爱心
手势
动物
美食
天气