{"id":2342,"date":"2026-02-27T08:02:53","date_gmt":"2026-02-27T00:02:53","guid":{"rendered":"https:\/\/guolab.org.cn\/?page_id=2342"},"modified":"2026-03-22T12:22:18","modified_gmt":"2026-03-22T04:22:18","slug":"%e5%9b%be%e5%83%8f%e5%a4%84%e7%90%86","status":"publish","type":"page","link":"https:\/\/guolab.org.cn\/?page_id=2342","title":{"rendered":"\u56fe\u50cf\u5904\u7406"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"2342\" class=\"elementor elementor-2342\">\n\t\t\t\t<div class=\"elementor-element elementor-element-63fb521 e-flex e-con-boxed e-con e-parent\" data-id=\"63fb521\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-6c830e7 e-flex e-con-boxed e-con e-parent\" data-id=\"6c830e7\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4779223 elementor-widget elementor-widget-html\" data-id=\"4779223\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"zh-CN\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <title>SIRecon \u8d85\u5206\u8fa8\u7387\u5904\u7406<\/title>\r\n    <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/utif@3.1.0\/UTIF.js\"><\/script>\r\n    <style>\r\n        \/* \u57fa\u7840\u6837\u5f0f\u7cbe\u7b80 *\/\r\n        body { font-family: Arial, sans-serif; max-width: 1500px; margin: 0 auto; padding: 20px; background-color: #f5f5f5; }\r\n        .container { background-color: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }\r\n        h1 { color: #333; text-align: center; border-bottom: 2px solid #0073aa; padding-bottom: 15px; }\r\n        h2 { color: #444; font-size: 18px; margin: 15px 0; }\r\n        .section { background-color: #f9f9f9; padding: 15px; border-radius: 8px; margin-bottom: 15px; border: 1px solid #ddd; }\r\n        .param-group { display: flex; gap: 15px; flex-wrap: wrap; }\r\n        .param-item { flex: 1; min-width: 200px; }\r\n        label { font-weight: bold; font-size: 14px; display: block; margin-bottom: 5px; }\r\n        input[type=\"file\"], select { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; }\r\n        \r\n        \/* \u6309\u94ae\u6837\u5f0f *\/\r\n        button { background-color: #0073aa; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer; font-weight: bold; transition: 0.3s; }\r\n        button:hover { background-color: #005a87; }\r\n        button:disabled { background-color: #ccc; cursor: not-allowed; }\r\n        .btn-success { background-color: #28a745; }\r\n        .btn-warning { background-color: #ff9800; }\r\n        \r\n        \/* \u72b6\u6001\u4e0e\u8fdb\u5ea6\u6761 *\/\r\n        .status-box { padding: 15px; border-radius: 5px; margin: 15px 0; font-weight: bold; text-align: center; }\r\n        .status-info { background: #e7f3fe; color: #004085; }\r\n        .status-processing { background: #fff3cd; color: #856404; }\r\n        .status-success { background: #d4edda; color: #155724; }\r\n        .status-error { background: #f8d7da; color: #721c24; }\r\n        .progress-container { width: 100%; height: 20px; background: #e0e0e0; border-radius: 10px; position: relative; overflow: hidden; display: none; }\r\n        .progress-bar { height: 100%; background: linear-gradient(90deg, #0073aa, #00aaff); width: 0%; transition: 0.5s; }\r\n        .progress-text { position: absolute; width: 100%; text-align: center; font-size: 12px; font-weight: bold; line-height: 20px; }\r\n\r\n        \/* ===== \u56fe\u50cf\u9884\u89c8\u5bf9\u6bd4\u533a\u57df (\u5df2\u5b8c\u7f8e\u8fd8\u539f) ===== *\/\r\n        .preview-section { margin-top: 20px; padding: 20px; background-color: #1a1a2e; border-radius: 10px; border: 1px solid #16213e; display: none; }\r\n        .preview-section h2 { color: #e0e0e0; text-align: center; margin-bottom: 18px; font-size: 17px; letter-spacing: 1px; }\r\n        .preview-wrapper { display: flex; align-items: flex-start; justify-content: center; gap: 0; }\r\n        .preview-panel { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; }\r\n        .preview-label { font-size: 13px; font-weight: bold; letter-spacing: 1px; text-transform: uppercase; margin-bottom: 10px; padding: 4px 14px; border-radius: 20px; }\r\n        .preview-label.input-label { background-color: #223355; color: #7ab8f5; border: 1px solid #3a6090; }\r\n        .preview-label.output-label { background-color: #1e3a28; color: #7dd8a0; border: 1px solid #2e6644; }\r\n        .canvas-wrapper { position: relative; width: 100%; max-width: 600px; background: #111; border-radius: 6px; overflow: hidden; display: flex; align-items: center; justify-content: center; min-height: 200px; border: 1px solid #333; }\r\n        .canvas-wrapper canvas { max-width: 100%; max-height: 520px; width: auto; height: auto; display: block; image-rendering: pixelated; }\r\n        .canvas-placeholder { color: #555; font-size: 13px; text-align: center; padding: 40px 20px; user-select: none; }\r\n        .canvas-placeholder .icon { font-size: 36px; display: block; margin-bottom: 8px; opacity: 0.4; }\r\n        .preview-info { margin-top: 8px; font-size: 12px; color: #888; text-align: center; min-height: 18px; }\r\n        .preview-divider { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 0 16px; align-self: center; flex-shrink: 0; }\r\n        .divider-line { width: 1px; height: 60px; background: linear-gradient(to bottom, transparent, #444, transparent); }\r\n        .divider-arrow { color: #0073aa; font-size: 22px; margin: 8px 0; }\r\n        .canvas-loading { display: flex; flex-direction: column; align-items: center; justify-content: center; color: #666; font-size: 13px; padding: 40px; }\r\n        .spinner { width: 32px; height: 32px; border: 3px solid #333; border-top-color: #0073aa; border-radius: 50%; animation: spin 0.8s linear infinite; margin-bottom: 10px; }\r\n        @keyframes spin { to { transform: rotate(360deg); } }\r\n        .render-error { color: #e57373; font-size: 12px; text-align: center; padding: 20px; }\r\n        @media (max-width: 700px) {\r\n            .preview-wrapper { flex-direction: column; gap: 16px; }\r\n            .preview-divider { flex-direction: row; padding: 0; }\r\n            .divider-line { width: 60px; height: 1px; }\r\n        }\r\n        \/* ===== END \u56fe\u50cf\u9884\u89c8 ===== *\/\r\n\r\n        \/* \ud83c\udf1f \u53f3\u4e0b\u89d2\u60ac\u6d6e VIP \u5546\u57ce\u6837\u5f0f *\/\r\n        .vip-float-panel { position: fixed; bottom: 20px; right: 20px; width: 320px; background: white; border-radius: 10px; box-shadow: 0 5px 20px rgba(0,0,0,0.3); z-index: 9999; overflow: hidden; display: none; font-size: 14px; }\r\n        .vip-header { background: linear-gradient(135deg, #f57c00, #ffb300); color: white; padding: 12px; text-align: center; font-weight: bold; cursor: pointer; user-select: none; }\r\n        .vip-body { padding: 15px; display: none; max-height: 400px; overflow-y: auto; }\r\n        .store-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 15px; }\r\n        .store-item { background: #e3f2fd; border: 1px solid #90caf9; padding: 10px; text-align: center; border-radius: 6px; cursor: pointer; transition: 0.2s; }\r\n        .store-item:hover { background: #bbdefb; }\r\n        .store-item strong { color: #1565c0; display: block; font-size: 16px; }\r\n        .redeem-box { display: flex; gap: 5px; margin-top: 15px; border-top: 1px dashed #ccc; padding-top: 15px; }\r\n        .redeem-box input { flex: 1; padding: 8px; border: 1px solid #ffb300; border-radius: 4px; }\r\n    <\/style>\r\n<\/head>\r\n<body>\r\n    <div class=\"container\">\r\n        <h1>SIRecon \u8d85\u5206\u8fa8\u7387\u56fe\u50cf\u5904\u7406<\/h1>\r\n        \r\n        <div class=\"section\">\r\n            <h2>1. \u9009\u62e9\u56fe\u50cf\u6587\u4ef6<\/h2>\r\n            <input type=\"file\" id=\"imageFile\" accept=\".tif,.tiff,.mrc\">\r\n            <div id=\"fileInfo\" style=\"font-size: 12px; color: #666; margin-top: 5px;\"><\/div>\r\n        <\/div>\r\n        \r\n        <div class=\"section\">\r\n            <h2>2. \u8bbe\u7f6e\u53c2\u6570<\/h2>\r\n            <div class=\"param-group\">\r\n                <div class=\"param-item\">\r\n                    <label>\u542f\u7528\u8d85\u5206\u8fa8\u7387:<\/label>\r\n                    <select id=\"srEnabled\"><option value=\"1\">\u542f\u7528<\/option><option value=\"0\">\u7981\u7528<\/option><\/select>\r\n                <\/div>\r\n                <div class=\"param-item\">\r\n                    <label>SR\u6a21\u578b:<\/label>\r\n                    <select id=\"srModel\"><option value=\"3\">ssr<\/option><\/select>\r\n                <\/div>\r\n            <\/div>\r\n        <\/div>\r\n        \r\n        <div style=\"text-align: center; margin: 20px 0;\">\r\n            <button id=\"processBtn\" style=\"font-size: 18px; padding: 12px 40px;\">\ud83d\ude80 \u5f00\u59cb\u5904\u7406<\/button>\r\n        <\/div>\r\n        \r\n        <div id=\"status\" class=\"status-box status-info\">\u51c6\u5907\u5c31\u7eea\uff0c\u8bf7\u9009\u62e9\u56fe\u50cf\u6587\u4ef6<\/div>\r\n        \r\n        <div id=\"progressContainer\" class=\"progress-container\">\r\n            <div id=\"progressBar\" class=\"progress-bar\"><\/div>\r\n            <div id=\"progressText\" class=\"progress-text\">0%<\/div>\r\n        <\/div>\r\n\r\n        <!-- ===== \u56fe\u50cf\u9884\u89c8\u5bf9\u6bd4\u533a\u57df (\u5b8c\u7f8e\u8fd8\u539f\u7248) ===== -->\r\n        <div id=\"previewSection\" class=\"preview-section\">\r\n            <h2>\ud83d\udcca \u56fe\u50cf\u5904\u7406\u5bf9\u6bd4<\/h2>\r\n            <div class=\"preview-wrapper\">\r\n                <!-- \u8f93\u5165\u56fe\u50cf -->\r\n                <div class=\"preview-panel\">\r\n                    <div class=\"preview-label input-label\">\u8f93\u5165\u56fe\u50cf<\/div>\r\n                    <div class=\"canvas-wrapper\" id=\"inputCanvasWrapper\">\r\n                        <div class=\"canvas-placeholder\">\r\n                            <span class=\"icon\">\ud83d\uddbc\ufe0f<\/span>\r\n                            \u9009\u62e9\u56fe\u50cf\u6587\u4ef6\u540e\u663e\u793a\u9884\u89c8\r\n                        <\/div>\r\n                    <\/div>\r\n                    <p id=\"inputInfo\" class=\"preview-info\"><\/p>\r\n                <\/div>\r\n\r\n                <!-- \u4e2d\u95f4\u7bad\u5934 -->\r\n                <div class=\"preview-divider\">\r\n                    <div class=\"divider-line\"><\/div>\r\n                    <div class=\"divider-arrow\">\u2192<\/div>\r\n                    <div class=\"divider-line\"><\/div>\r\n                <\/div>\r\n\r\n                <!-- \u8f93\u51fa\u56fe\u50cf -->\r\n                <div class=\"preview-panel\">\r\n                    <div class=\"preview-label output-label\">\u5904\u7406\u7ed3\u679c<\/div>\r\n                    <div class=\"canvas-wrapper\" id=\"outputCanvasWrapper\">\r\n                        <div class=\"canvas-placeholder\">\r\n                            <span class=\"icon\">\u2728<\/span>\r\n                            \u5904\u7406\u5b8c\u6210\u540e\u663e\u793a\u8d85\u5206\u8fa8\u7387\u7ed3\u679c\r\n                        <\/div>\r\n                    <\/div>\r\n                    <p id=\"outputInfo\" class=\"preview-info\"><\/p>\r\n                <\/div>\r\n            <\/div>\r\n        <\/div>\r\n        <!-- ===== END \u56fe\u50cf\u9884\u89c8 ===== -->\r\n        \r\n        <!-- \u4e0b\u8f7d\u533a -->\r\n        <div id=\"resultSection\" class=\"section\" style=\"display: none; text-align: center; margin-top: 20px;\">\r\n            <h2>\u2705 \u5904\u7406\u5b8c\u6210<\/h2>\r\n            <a id=\"downloadLink\"><button class=\"btn-success\">\u2b07\ufe0f \u4e0b\u8f7d\u7ed3\u679c<\/button><\/a>\r\n            <button id=\"resetBtn\" style=\"background: #666; margin-left: 10px;\">\u5904\u7406\u65b0\u56fe\u50cf<\/button>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <!-- \ud83c\udf1f \u53f3\u4e0b\u89d2\u60ac\u6d6e VIP \u5546\u57ce\u4e0e\u5151\u6362\u9762\u677f -->\r\n    <div id=\"vipFloatPanel\" class=\"vip-float-panel\">\r\n        <div class=\"vip-header\" id=\"vipHeader\">\ud83d\udc8e VIP \u5145\u503c\u4e0e\u5151\u6362 (\u70b9\u51fb\u5c55\u5f00)<\/div>\r\n        <div class=\"vip-body\" id=\"vipBody\">\r\n            <div style=\"font-size: 12px; color: #666; margin-bottom: 10px; text-align: center;\">\u8d2d\u4e70\u5957\u9910\u81ea\u52a8\u53d1\u5361\uff0c\u514d\u6392\u961f\u6781\u901f\u5904\u7406<\/div>\r\n            \r\n            <!-- \u5546\u54c1\u5217\u8868 -->\r\n            <div class=\"store-grid\">\r\n                <div class=\"store-item buy-btn\" data-level=\"v1\" data-price=\"9.9\">V1 (10\u6b21)<br><strong>\uffe59.9<\/strong><\/div>\r\n                <div class=\"store-item buy-btn\" data-level=\"v3\" data-price=\"29.9\">V3 (50\u6b21)<br><strong>\uffe529.9<\/strong><\/div>\r\n                <div class=\"store-item buy-btn\" data-level=\"v6\" data-price=\"99.9\" style=\"grid-column: span 2;\">V6 (\u65e0\u9650\u6b21) - <strong>\uffe599.9<\/strong><\/div>\r\n            <\/div>\r\n\r\n            <!-- \u6a21\u62df\u652f\u4ed8\u533a -->\r\n            <div id=\"paymentArea\" style=\"display: none; text-align: center; background: #f5f5f5; padding: 10px; border-radius: 6px;\">\r\n                <p style=\"margin: 0 0 10px 0;\">\u8bf7\u652f\u4ed8 <strong style=\"color:red; font-size: 18px;\" id=\"payAmount\">0<\/strong> \u5143<\/p>\r\n                <div style=\"width: 120px; height: 120px; background: #ddd; margin: 0 auto 10px; line-height: 120px; color: #888;\">[\u6536\u6b3e\u7801\u56fe\u7247]<\/div>\r\n                <button id=\"simPayBtn\" class=\"btn-success\" style=\"width: 100%; margin-bottom: 5px;\">\u6211\u5df2\u652f\u4ed8 (\u6a21\u62df\u83b7\u53d6\u5361\u5bc6)<\/button>\r\n                <button id=\"cancelPayBtn\" style=\"width: 100%; background: #999;\">\u53d6\u6d88<\/button>\r\n            <\/div>\r\n\r\n            <!-- \u5361\u5bc6\u5151\u6362\u533a -->\r\n            <div class=\"redeem-box\">\r\n                <input type=\"text\" id=\"redeemInput\" placeholder=\"\u5728\u6b64\u8f93\u5165\u5361\u5bc6\u5151\u6362\u7801\">\r\n                <button id=\"redeemBtn\" class=\"btn-warning\">\u5151\u6362<\/button>\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <script>\r\n        \/\/ ================= API \u914d\u7f6e =================\r\n        const API_BASE = 'https:\/\/unspeedy-semitransparently-adolph.ngrok-free.dev';\r\n        const SIMPLE_PROCESS_ENDPOINT = API_BASE + '\/api\/v1\/process\/simple';\r\n        \r\n        \/\/ ================= DOM \u5143\u7d20 =================\r\n        const el = id => document.getElementById(id);\r\n        let isProcessing = false;\r\n\r\n        \/\/ UI \u66f4\u65b0\u5de5\u5177\r\n        const updateStatus = (msg, type = 'info') => { el('status').textContent = msg; el('status').className = `status-box status-${type}`; };\r\n        const updateProgress = (pct, msg = '') => { el('progressContainer').style.display = 'block'; el('progressBar').style.width = `${pct}%`; el('progressText').textContent = msg || `${pct}%`; };\r\n\r\n        \/\/ ================= \u56fe\u50cf\u89e3\u7801\u903b\u8f91 (\u8fd8\u539f\u7248) =================\r\n        async function renderImageBuffer(buffer, filename, wrapper, infoEl) {\r\n            wrapper.innerHTML = `<div class=\"canvas-loading\"><div class=\"spinner\"><\/div>\u89e3\u7801\u4e2d...<\/div>`;\r\n            if (infoEl) infoEl.textContent = '';\r\n            \r\n            try {\r\n                const ext = filename.split('.').pop().toLowerCase();\r\n                let imgData, w, h;\r\n                if (ext === 'mrc') { ({ imageData: imgData, width: w, height: h } = decodeMRC(buffer)); } \r\n                else if (ext === 'tif' || ext === 'tiff') { ({ imageData: imgData, width: w, height: h } = decodeTIFF(buffer)); } \r\n                else throw new Error('\u4e0d\u652f\u6301\u7684\u683c\u5f0f');\r\n\r\n                const canvas = document.createElement('canvas');\r\n                canvas.width = w; canvas.height = h;\r\n                canvas.getContext('2d').putImageData(imgData, 0, 0);\r\n                wrapper.innerHTML = ''; wrapper.appendChild(canvas);\r\n                if (infoEl) infoEl.textContent = `${w} \u00d7 ${h} px`;\r\n            } catch (err) { \r\n                wrapper.innerHTML = `<div class=\"render-error\">\u26a0\ufe0f \u9884\u89c8\u4e0d\u53ef\u7528<br><span style=\"font-size:11px\">${err.message}<\/span><\/div>`; \r\n            }\r\n        }\r\n\r\n        function decodeMRC(buffer) {\r\n            const view = new DataView(buffer);\r\n            const nx = view.getInt32(0, true), ny = view.getInt32(4, true), mode = view.getInt32(12, true), offset = 1024 + view.getInt32(92, true);\r\n            const pixels = nx * ny; let raw = new Float64Array(pixels);\r\n            if (mode === 0) for (let i=0; i<pixels; i++) raw[i] = view.getInt8(offset + i);\r\n            else if (mode === 1) for (let i=0; i<pixels; i++) raw[i] = view.getInt16(offset + i*2, true);\r\n            else if (mode === 2) for (let i=0; i<pixels; i++) raw[i] = view.getFloat32(offset + i*4, true);\r\n            else if (mode === 6) for (let i=0; i<pixels; i++) raw[i] = view.getUint16(offset + i*2, true);\r\n            const sorted = Float64Array.from(raw).sort(), lo = sorted[Math.floor(pixels*0.02)], hi = sorted[Math.floor(pixels*0.98)], range = hi - lo || 1;\r\n            const uint8 = new Uint8ClampedArray(pixels * 4);\r\n            for (let i=0; i<pixels; i++) {\r\n                const v = Math.round(((raw[i] - lo) \/ range) * 255), idx = i * 4;\r\n                uint8[idx] = uint8[idx+1] = uint8[idx+2] = v; uint8[idx+3] = 255;\r\n            }\r\n            return { imageData: new ImageData(uint8, nx, ny), width: nx, height: ny };\r\n        }\r\n\r\n        function decodeTIFF(buffer) {\r\n            const ifds = UTIF.decode(buffer); UTIF.decodeImage(buffer, ifds[0]);\r\n            return { imageData: new ImageData(new Uint8ClampedArray(UTIF.toRGBA8(ifds[0]).buffer), ifds[0].width, ifds[0].height), width: ifds[0].width, height: ifds[0].height };\r\n        }\r\n\r\n        \/\/ ================= \u6838\u5fc3\u5904\u7406\u6d41\u7a0b =================\r\n        el('processBtn').addEventListener('click', async () => {\r\n            if (typeof window.WP_IS_LOGGED_IN === 'undefined' || !window.WP_IS_LOGGED_IN) {\r\n                updateStatus('\u8bf7\u5148\u767b\u5f55\u7f51\u7ad9\u8d26\u53f7\uff01', 'error'); return;\r\n            }\r\n            const file = el('imageFile').files[0];\r\n            if (!file) { updateStatus('\u8bf7\u9009\u62e9\u6587\u4ef6', 'error'); return; }\r\n            if (isProcessing) return;\r\n\r\n            isProcessing = true; el('processBtn').disabled = true;\r\n\r\n            try {\r\n                \/\/ 1. \u67e5\u989d\u5ea6\u4e0e\u6392\u961f\r\n                updateStatus('\u9a8c\u8bc1\u6743\u9650...', 'processing');\r\n                const statusRes = await fetch(window.WP_AJAX_URL + '?action=check_ai_status');\r\n                const statusData = await statusRes.json();\r\n                if (!statusData.success) throw new Error(statusData.data.message);\r\n\r\n                const { level, wait_time } = statusData.data;\r\n                \r\n                if (wait_time > 0) {\r\n                    for (let i = wait_time; i > 0; i--) {\r\n                        updateStatus(`[${level.toUpperCase()}] \u6392\u961f\u4e2d\uff0c\u9884\u8ba1 ${i} \u79d2... (\u5347\u7ea7\u514d\u6392\u961f)`, 'processing');\r\n                        updateProgress(10, `\u6392\u961f ${i}s`);\r\n                        await new Promise(r => setTimeout(r, 1000));\r\n                    }\r\n                } else {\r\n                    updateStatus(`[${level.toUpperCase()}] \u6781\u901f\u901a\u9053\u5f00\u542f\uff01`, 'success');\r\n                    await new Promise(r => setTimeout(r, 500));\r\n                }\r\n\r\n                \/\/ 2. \u53d1\u9001\u7ed9 Ngrok\r\n                updateStatus('\u5904\u7406\u4e2d...', 'processing'); updateProgress(40, '\u8ba1\u7b97\u4e2d...');\r\n                const formData = new FormData();\r\n                formData.append('file', file); formData.append('sr_enabled', el('srEnabled').value); formData.append('sr_model', el('srModel').value);\r\n                \r\n                const startTime = Date.now();\r\n                const response = await fetch(SIMPLE_PROCESS_ENDPOINT, { method: 'POST', body: formData });\r\n                if (!response.ok) throw new Error(`\u5904\u7406\u5931\u8d25 (${response.status})`);\r\n\r\n                \/\/ 3. \u6263\u9664\u989d\u5ea6 & \u6e32\u67d3\r\n                await fetch(window.WP_AJAX_URL + '?action=record_ai_usage', { method: 'POST' });\r\n                \r\n                updateProgress(80, '\u751f\u6210\u7ed3\u679c...');\r\n                const blob = await response.blob();\r\n                const downloadName = `SR_Result_${Date.now()}.mrc`;\r\n                \r\n                el('downloadLink').href = URL.createObjectURL(blob);\r\n                el('downloadLink').download = downloadName;\r\n                \r\n                updateProgress(90, '\u6e32\u67d3\u9884\u89c8...');\r\n                \/\/ \u4f20\u5165 outputInfo \u66f4\u65b0\u5c3a\u5bf8\u4fe1\u606f\r\n                await renderImageBuffer(await blob.arrayBuffer(), downloadName, el('outputCanvasWrapper'), el('outputInfo'));\r\n\r\n                el('resultSection').style.display = 'block';\r\n                updateProgress(100, '\u5b8c\u6210');\r\n                updateStatus(`\u5904\u7406\u5b8c\u6210\uff01\u8017\u65f6: ${Date.now() - startTime}ms`, 'success');\r\n                setTimeout(() => { el('previewSection').scrollIntoView({ behavior: 'smooth' }); }, 500);\r\n\r\n            } catch (err) {\r\n                updateStatus(err.message, 'error'); updateProgress(0, '\u5931\u8d25');\r\n                el('outputCanvasWrapper').innerHTML = `<div class=\"render-error\">\u26a0\ufe0f \u5904\u7406\u5931\u8d25<\/div>`;\r\n            } finally {\r\n                isProcessing = false; el('processBtn').disabled = false;\r\n            }\r\n        });\r\n\r\n        \/\/ ================= \u60ac\u6d6e\u7a97 VIP \u5546\u57ce\u903b\u8f91 =================\r\n        let buyLevel = '';\r\n        \r\n        window.addEventListener('load', () => {\r\n            if (window.WP_IS_LOGGED_IN) el('vipFloatPanel').style.display = 'block';\r\n        });\r\n\r\n        el('vipHeader').addEventListener('click', () => {\r\n            const body = el('vipBody');\r\n            body.style.display = body.style.display === 'block' ? 'none' : 'block';\r\n        });\r\n\r\n        document.querySelectorAll('.buy-btn').forEach(btn => {\r\n            btn.addEventListener('click', function() {\r\n                buyLevel = this.getAttribute('data-level');\r\n                el('payAmount').textContent = this.getAttribute('data-price');\r\n                el('paymentArea').style.display = 'block';\r\n            });\r\n        });\r\n\r\n        el('cancelPayBtn').addEventListener('click', () => el('paymentArea').style.display = 'none');\r\n\r\n        el('simPayBtn').addEventListener('click', async () => {\r\n            el('simPayBtn').textContent = '\u751f\u6210\u4e2d...';\r\n            try {\r\n                const fd = new FormData(); fd.append('action', 'buy_and_generate_code'); fd.append('level', buyLevel);\r\n                const res = await fetch(window.WP_AJAX_URL, { method: 'POST', body: fd });\r\n                const data = await res.json();\r\n                if (data.success) {\r\n                    alert(`\u652f\u4ed8\u6210\u529f\uff01\u60a8\u7684\u5361\u5bc6\u662f\uff1a${data.data.code}\\n\u5df2\u81ea\u52a8\u4e3a\u60a8\u586b\u5165\u8f93\u5165\u6846\u3002`);\r\n                    el('redeemInput').value = data.data.code;\r\n                    el('paymentArea').style.display = 'none';\r\n                } else alert(data.data.message);\r\n            } catch (e) { alert('\u7f51\u7edc\u9519\u8bef'); }\r\n            finally { el('simPayBtn').textContent = '\u6211\u5df2\u652f\u4ed8 (\u6a21\u62df\u83b7\u53d6\u5361\u5bc6)'; }\r\n        });\r\n\r\n        el('redeemBtn').addEventListener('click', async () => {\r\n            const code = el('redeemInput').value.trim();\r\n            if (!code) return alert('\u8bf7\u8f93\u5165\u5361\u5bc6');\r\n            el('redeemBtn').textContent = '...';\r\n            try {\r\n                const fd = new FormData(); fd.append('action', 'redeem_ai_code'); fd.append('code', code);\r\n                const res = await fetch(window.WP_AJAX_URL, { method: 'POST', body: fd });\r\n                const data = await res.json();\r\n                alert(data.data.message);\r\n                if (data.success) { el('redeemInput').value = ''; el('vipBody').style.display = 'none'; }\r\n            } catch (e) { alert('\u5151\u6362\u5931\u8d25'); }\r\n            finally { el('redeemBtn').textContent = '\u5151\u6362'; }\r\n        });\r\n\r\n        \/\/ ================= \u57fa\u7840\u4ea4\u4e92 =================\r\n        el('imageFile').addEventListener('change', async function() {\r\n            if (!this.files[0]) return;\r\n            el('fileInfo').textContent = `\u5df2\u9009: ${this.files[0].name}`;\r\n            \r\n            \/\/ \u91cd\u7f6e\u8f93\u51fa\u533a\r\n            el('outputCanvasWrapper').innerHTML = `<div class=\"canvas-placeholder\"><span class=\"icon\">\u2728<\/span>\u5904\u7406\u5b8c\u6210\u540e\u663e\u793a\u8d85\u5206\u8fa8\u7387\u7ed3\u679c<\/div>`;\r\n            el('outputInfo').textContent = '';\r\n            el('resultSection').style.display = 'none';\r\n            \r\n            el('previewSection').style.display = 'block';\r\n            \r\n            \/\/ \u6e32\u67d3\u8f93\u5165\u56fe\u50cf\u5e76\u66f4\u65b0\u5c3a\u5bf8\u4fe1\u606f\r\n            await renderImageBuffer(await this.files[0].arrayBuffer(), this.files[0].name, el('inputCanvasWrapper'), el('inputInfo'));\r\n        });\r\n        \r\n        el('resetBtn').addEventListener('click', () => location.reload());\r\n    <\/script>\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>SIRecon \u8d85\u5206\u8fa8\u7387\u5904\u7406 SIRec [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"no-sidebar","site-content-layout":"","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-2342","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/guolab.org.cn\/index.php?rest_route=\/wp\/v2\/pages\/2342","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/guolab.org.cn\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/guolab.org.cn\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/guolab.org.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/guolab.org.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2342"}],"version-history":[{"count":154,"href":"https:\/\/guolab.org.cn\/index.php?rest_route=\/wp\/v2\/pages\/2342\/revisions"}],"predecessor-version":[{"id":2535,"href":"https:\/\/guolab.org.cn\/index.php?rest_route=\/wp\/v2\/pages\/2342\/revisions\/2535"}],"wp:attachment":[{"href":"https:\/\/guolab.org.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2342"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}