{"id":36540,"date":"2024-04-01T15:11:55","date_gmt":"2024-04-01T07:11:55","guid":{"rendered":"https:\/\/edit-dot-gaewordpress-dot-junyiacademy.appspot.com\/?page_id=36540"},"modified":"2025-05-13T10:40:32","modified_gmt":"2025-05-13T02:40:32","slug":"learning-progress-export","status":"publish","type":"page","link":"https:\/\/www.junyiacademy.org\/event\/learning-progress-export\/","title":{"rendered":"\u532f\u51fa\u5b78\u7fd2\u9032\u5ea6\uff5c\u5747\u4e00\u6559\u80b2\u5e73\u53f0"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"36540\" class=\"elementor elementor-36540\">\n\t\t\t\t\t\t<div class=\"elementor-inner\">\n\t\t\t\t<div class=\"elementor-section-wrap\">\n\t\t\t\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-7c8d8b6e elementor-section-stretched elementor-section-full_width elementor-section-height-default elementor-section-height-default\" data-id=\"7c8d8b6e\" data-element_type=\"section\" data-settings=\"{&quot;stretch_section&quot;:&quot;section-stretched&quot;,&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t\t\t<div class=\"elementor-row\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-bdc1235\" data-id=\"bdc1235\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-column-wrap elementor-element-populated\">\n\t\t\t\t\t\t\t<div class=\"elementor-widget-wrap\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-1af89b4 elementor-widget elementor-widget-html\" data-id=\"1af89b4\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<!DOCTYPE html>\n<html lang=\"zh-TW\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>\u5747\u4e00\u6559\u80b2\u5e73\u53f0 - \u5b78\u7fd2\u8a18\u9304\u532f\u51fa<\/title>\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jquery\/3.6.0\/jquery.min.js\"><\/script>\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/html2pdf.js\/0.9.3\/html2pdf.bundle.min.js\"><\/script>\n    <link href=\"https:\/\/fonts.googleapis.com\/icon?family=Material+Icons\" rel=\"stylesheet\">\n    <style>\n        body {\n            font-family: \"Microsoft JhengHei\", Arial, sans-serif;\n            line-height: 1.5;\n            margin: 0;\n            padding: 15px;\n            background-color: #f5f5f5;\n            color: #333;\n        }\n        \n        .container {\n            max-width: 800px;\n            margin: 0 auto;\n            background: white;\n            padding: 20px;\n            border-radius: 15px;\n            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);\n        }\n        \n        .text-center {\n            text-align: center;\n        }\n        \n        .welcome-message {\n            margin-bottom: 20px;\n            font-size: 1.1em;\n            color: #2196F3;\n            padding: 12px;\n            border-radius: 10px;\n            background: #E3F2FD;\n            transition: all 0.3s ease;\n        }\n        \n        .welcome-message:hover {\n            transform: translateY(-2px);\n            box-shadow: 0 4px 8px rgba(33, 150, 243, 0.1);\n        }\n        \n        .export-container {\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            margin-bottom: 20px;\n        }\n        \n        .export-content {\n            width: 100%;\n        }\n        \n        .export-content h4 {\n            color: #1976D2;\n            font-size: 1.5em;\n            margin-bottom: 25px;\n        }\n        \n        .user-info {\n            text-align: left;\n            font-size: 18px;\n            font-weight: 800;\n            margin: 2em 0;\n            display: none;\n            background: #FAFAFA;\n            padding: 20px;\n            border-radius: 10px;\n            border-left: 4px solid #2196F3;\n        }\n        \n        .user-info-note {\n            font-size: 14px;\n            font-weight: 200;\n            margin-top: 10px;\n            padding: 10px;\n            background: #FFF3E0;\n            border-radius: 5px;\n        }\n        \n        .user-info-note a {\n            color: #1976D2;\n            text-decoration: none;\n            font-weight: 600;\n            transition: color 0.3s ease;\n        }\n        \n        .user-info-note a:hover {\n            color: #2196F3;\n            text-decoration: underline;\n        }\n        \n        .flex-container {\n            display: flex;\n            margin: 20px 0;\n        }\n        \n        .content-list {\n            text-align: left;\n            flex: 1;\n            width: 100%;\n        }\n        \n        .footer {\n            font-size: 12px;\n            font-weight: 200;\n            margin: 2em 0;\n            padding: 15px;\n            background: #EEEEEE;\n            border-radius: 8px;\n        }\n        \n        .button-container {\n            margin: 30px 0;\n            display: flex;\n            flex-direction: row;\n            justify-content: center;\n            align-items: center;\n            gap: 10px;\n        }\n        \n        \/* \u5c0f\u87a2\u5e55\u6309\u9215\u5782\u76f4\u6392\u5217 *\/\n        @media screen and (max-width: 768px) {\n            .button-container {\n                flex-direction: column;\n                gap: 15px;\n            }\n            \n            .bottom-preview-button {\n                width: 100%;\n                justify-content: center;\n                padding: 12px 20px;\n            }\n            \n            .reload-link {\n                width: 100%;\n            }\n            \n            .reload-link a {\n                width: 100%;\n                justify-content: center;\n                padding: 12px 20px;\n                background: rgba(0, 0, 0, 0.05);\n            }\n        }\n        \n        .bottom-preview-button {\n            background-color: #333;\n            color: white;\n            padding: 8px 15px;\n            border: 1px solid rgba(255,255,255,0.3);\n            border-radius: 4px;\n            cursor: pointer;\n            font-size: 14px;\n            display: flex;\n            align-items: center;\n            transition: all 0.3s ease;\n        }\n        \n        .bottom-preview-button:hover {\n            background-color: #444;\n        }\n        \n        .bottom-preview-button .material-icons {\n            font-size: 16px;\n            margin-right: 5px;\n        }\n        \n        .save-button {\n            background-color: #4CAF50;\n            color: white;\n            padding: 12px 25px;\n            border: none;\n            border-radius: 25px;\n            cursor: pointer;\n            font-size: 16px;\n            display: none;\n            transition: all 0.3s ease;\n            box-shadow: 0 2px 5px rgba(76, 175, 80, 0.2);\n        }\n        \n        .save-button:hover {\n            background-color: #45a049;\n            transform: translateY(-2px);\n            box-shadow: 0 4px 10px rgba(76, 175, 80, 0.3);\n        }\n        \n        .reload-link {\n            font-size: 14px;\n            font-weight: 200;\n            display: inline-block;\n            text-align: center;\n        }\n        \n        .reload-link a {\n            color: #666;\n            text-decoration: none;\n            padding: 8px 15px;\n            border-radius: 4px;\n            transition: all 0.3s ease;\n            background: none;\n            display: inline-flex;\n            align-items: center;\n        }\n        \n        .reload-link a:hover {\n            background: rgba(0, 0, 0, 0.05);\n        }\n        \n        .reload-link .material-icons {\n            font-size: 16px;\n            color: #666;\n            margin-right: 5px;\n        }\n        \n        .logout-area {\n            margin-top: 30px;\n            font-size: 12px;\n            text-align: center;\n        }\n        \n        .logout-area a {\n            color: #666;\n            text-decoration: none;\n            transition: color 0.3s ease;\n        }\n        \n        .logout-area a:hover {\n            color: #333;\n        }\n        \n        .logout-message {\n            display: none;\n            position: fixed;\n            bottom: 10%;\n            left: 50%;\n            transform: translate(-50%, -50%);\n            padding: 15px 30px;\n            background-color: #04AA6D;\n            border-radius: 25px;\n            border: none;\n            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);\n            z-index: 1000;\n            color: white;\n            font-size: 16px;\n            font-weight: 600;\n            animation: slideUp 0.3s ease;\n        }\n        \n        .content-item {\n            margin-bottom: 10px;\n            padding: 10px;\n            border-radius: 8px;\n            transition: all 0.3s ease;\n            border: 1px solid #EEEEEE;\n            display: flex;\n            align-items: center;\n            flex-wrap: nowrap;\n        }\n        \n        .content-item:hover {\n            background: #FAFAFA;\n            transform: translateX(5px);\n        }\n        \n        .content-type {\n            border: none;\n            font-size: 14px;\n            border-radius: 15px;\n            padding: 4px 12px;\n            font-weight: 400;\n            display: inline-block;\n            margin-right: 8px;\n            background: #E3F2FD;\n            color: #1976D2;\n            flex-shrink: 0;\n        }\n        \n        .content-title {\n            display: inline-block;\n            max-width: calc(100% - 180px);\n            white-space: nowrap;\n            overflow: hidden;\n            text-overflow: ellipsis;\n            vertical-align: middle;\n        }\n        \n        \/* \u589e\u52a0\u5927\u87a2\u5e55\u4e0a\u7684\u6a19\u984c\u986f\u793a\u7a7a\u9593 *\/\n        @media screen and (min-width: 768px) {\n            .content-title {\n                max-width: calc(100% - 150px);\n            }\n        }\n        \n        @media screen and (min-width: 992px) {\n            .content-title {\n                max-width: calc(100% - 120px);\n            }\n        }\n        \n        @media print {\n            .content-title {\n                max-width: calc(100% - 80px);\n                font-size: 7px !important;\n                white-space: nowrap;\n                overflow: hidden;\n                text-overflow: ellipsis;\n            }\n        }\n        \n        \/* \u4e0d\u540c\u5167\u5bb9\u985e\u578b\u7684\u984f\u8272\u6a23\u5f0f *\/\n        .content-type-video {\n            background: #E8EAF6 !important; \/* \u6dfa\u85cd\u7d2b\u8272 - \u5f71\u7247 *\/\n            color: #3949AB !important;\n        }\n        \n        .content-type-exercise {\n            background: #E0F2F1 !important; \/* \u6dfa\u9752\u8272 - \u7fd2\u984c *\/\n            color: #00897B !important;\n        }\n        \n        .content-type-article {\n            background: #F3E5F5 !important; \/* \u6dfa\u7d2b\u8272 - \u8b1b\u7fa9 *\/\n            color: #8E24AA !important;\n        }\n        \n        .content-type-exam {\n            background: #FFF3E0 !important; \/* \u6dfa\u6a59\u8272 - \u6e2c\u9a57 *\/\n            color: #F57C00 !important;\n        }\n        \n        .content-type .material-icons {\n            font-size: 16px;\n            margin-right: 4px;\n        }\n        \n        .status-incomplete {\n            border: none;\n            font-size: 14px;\n            border-radius: 15px;\n            padding: 4px 12px;\n            background-color: #EEEEEE;\n            font-weight: 400;\n            display: inline-block;\n            margin-right: 8px;\n            color: #666;\n            flex-shrink: 0;\n        }\n        \n        .status-complete {\n            border: none;\n            font-size: 14px;\n            border-radius: 15px;\n            padding: 4px 12px;\n            background-color: #E8F5E9;\n            color: #2E7D32;\n            font-weight: 600;\n            display: inline-block;\n            margin-right: 8px;\n            flex-shrink: 0;\n        }\n        \n        @media print {\n            .status-complete, .status-incomplete {\n                border-radius: 10px;\n                padding: 0px 2px !important;\n                margin-right: 3px !important;\n                font-weight: normal;\n                font-size: 6px !important;\n                display: inline-block;\n                width: auto !important;\n                min-width: auto !important;\n            }\n        }\n        \n        .material-icons {\n            vertical-align: middle;\n            margin-right: 6px;\n            font-size: 20px;\n        }\n        \n        .save-button .material-icons {\n            font-size: 18px;\n        }\n        \n        .logout-area .material-icons {\n            font-size: 14px;\n            color: #666;\n        }\n        \n        @keyframes slideUp {\n            from {\n                opacity: 0;\n                transform: translate(-50%, 20px);\n            }\n            to {\n                opacity: 1;\n                transform: translate(-50%, -50%);\n            }\n        }\n        \n        \/* \u9032\u5ea6\u689d\u6a23\u5f0f *\/\n        .progress-bar {\n            height: 6px;\n            background: #EEEEEE;\n            border-radius: 3px;\n            margin: 5px 0;\n            overflow: hidden;\n        }\n        \n        .progress-bar-fill {\n            height: 100%;\n            background: #4CAF50;\n            border-radius: 3px;\n            transition: width 0.5s ease;\n        }\n        \n        \/* \u8f09\u5165\u52d5\u756b *\/\n        .loading {\n            display: inline-block;\n            position: relative;\n            width: 20px;\n            height: 20px;\n        }\n        \n        .loading:after {\n            content: \" \";\n            display: block;\n            width: 16px;\n            height: 16px;\n            border-radius: 50%;\n            border: 2px solid #fff;\n            border-color: #fff transparent #fff transparent;\n            animation: loading 1.2s linear infinite;\n        }\n        \n        @keyframes loading {\n            0% {\n                transform: rotate(0deg);\n            }\n            100% {\n                transform: rotate(360deg);\n            }\n        }\n        \n        \/* \u5217\u5370\u9810\u89bd\u6a21\u5f0f\u6a23\u5f0f *\/\n        body.preview-mode {\n            background: #fff;\n            padding: 0;\n            margin: 0;\n        }\n        \n        body.preview-mode .container {\n            max-width: 100%;\n            box-shadow: none;\n            padding: 20px;\n            border-radius: 0;\n        }\n        \n        body.preview-mode .preview-hide {\n            display: none !important;\n        }\n        \n        body.preview-mode .export-container {\n            margin: 0;\n        }\n        \n        \/* \u589e\u5f37\u5217\u5370\u9810\u89bd\u6a21\u5f0f\u7684\u5217\u5370\u53cb\u5584\u6027 *\/\n        body.preview-mode .content-item,\n        body.preview-mode .learning-summary, \n        body.preview-mode .verification-block,\n        body.preview-mode .user-info {\n            background: none !important;\n            border-color: #ccc !important;\n            margin: 5px 0 !important;\n            padding: 8px !important;\n        }\n        \n        body.preview-mode .status-complete,\n        body.preview-mode .status-incomplete {\n            background: none !important;\n            border: 1px solid #ccc !important;\n            padding: 2px 8px !important;\n            font-size: 12px !important;\n        }\n        \n        \/* \u5217\u5370\u9810\u89bd\u6a21\u5f0f\u4e0b\u7684\u5167\u5bb9\u985e\u578b\u908a\u6846\u6a23\u5f0f *\/\n        body.preview-mode .content-type {\n            background: none !important;\n            padding: 2px 8px !important;\n            font-size: 12px !important;\n            border: 1px solid #ccc !important;\n        }\n        \n        body.preview-mode .content-type-video {\n            border-color: #3949AB !important;\n            color: #3949AB !important;\n        }\n        \n        body.preview-mode .content-type-exercise {\n            border-color: #00897B !important;\n            color: #00897B !important;\n        }\n        \n        body.preview-mode .content-type-article {\n            border-color: #8E24AA !important;\n            color: #8E24AA !important;\n        }\n        \n        body.preview-mode .content-type-exam {\n            border-color: #F57C00 !important;\n            color: #F57C00 !important;\n        }\n        \n        body.preview-mode h4 {\n            font-size: 18px !important;\n            margin: 10px 0 !important;\n        }\n        \n        body.preview-mode h3 {\n            font-size: 20px !important;\n            margin: 10px 0 !important;\n        }\n        \n        body.preview-mode .chart-item {\n            width: 70px !important;\n        }\n        \n        body.preview-mode .chart-circle {\n            width: 60px !important;\n            height: 60px !important;\n        }\n        \n        body.preview-mode .chart-circle::before {\n            width: 50px !important;\n            height: 50px !important;\n        }\n        \n        body.preview-mode .chart-percentage {\n            font-size: 16px !important;\n        }\n        \n        body.preview-mode .chart-label {\n            font-size: 12px !important;\n        }\n        \n        body.preview-mode .material-icons {\n            font-size: 18px !important;\n            margin-right: 4px !important;\n        }\n        \n        body.preview-mode .verification-block .material-icons {\n            font-size: 24px !important;\n        }\n        \n        body.preview-mode .flex-container {\n            margin: 10px 0 !important;\n        }\n        \n        body.preview-mode .learning-summary-title {\n            font-size: 14px !important;\n            margin-bottom: 5px !important;\n        }\n        \n        body.preview-mode .learning-summary-chart {\n            margin: 8px 0 !important;\n        }\n        \n        body.preview-mode .verification-block strong {\n            font-size: 14px !important;\n            margin-bottom: 3px !important;\n        }\n        \n        body.preview-mode .signature-line {\n            margin-top: 10px !important;\n            padding-top: 5px !important;\n            font-size: 12px !important;\n        }\n        \n        body.preview-mode .document-footer {\n            margin-top: 15px !important;\n            padding-top: 10px !important;\n            font-size: 10px !important;\n        }\n        \n        \/* \u9810\u89bd\u63a7\u5236\u5217 *\/\n        .preview-controls {\n            position: fixed;\n            top: 0;\n            left: 0;\n            right: 0;\n            background: #333;\n            color: white;\n            padding: 10px 20px;\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            z-index: 1000;\n            box-shadow: 0 2px 5px rgba(0,0,0,0.2);\n        }\n        \n        \/* \u5c0f\u87a2\u5e55\u96b1\u85cf\u4e0a\u65b9\u5c0e\u89bd\u5217 *\/\n        @media screen and (max-width: 768px) {\n            .preview-controls {\n                display: none !important;\n            }\n        }\n        \n        .preview-controls.hidden {\n            display: none;\n        }\n        \n        .preview-buttons {\n            display: flex;\n            gap: 10px;\n        }\n        \n        .preview-button {\n            background: transparent;\n            color: white;\n            border: 1px solid rgba(255,255,255,0.3);\n            padding: 5px 10px;\n            border-radius: 4px;\n            cursor: pointer;\n            display: flex;\n            align-items: center;\n            transition: all 0.3s ease;\n        }\n        \n        .preview-button:hover {\n            background: rgba(255,255,255,0.1);\n        }\n        \n        .preview-button .material-icons {\n            font-size: 16px;\n            margin-right: 5px;\n        }\n        \n        \/* \u6dfb\u52a0\u7279\u6b8a\u6a23\u5f0f\u7d66\u8fd4\u56de\u7db2\u9801\u700f\u89bd\u6a21\u5f0f\u6309\u9215 *\/\n        .back-to-edit {\n            background: rgba(255,255,255,0.2) !important;\n            border: 1px solid rgba(255,255,255,0.5) !important;\n            font-weight: bold;\n        }\n        \n        .back-to-edit:hover {\n            background: rgba(255,255,255,0.3) !important;\n        }\n        \n        \/* \u986f\u793a\u5217\u5370\u9810\u89bd\u6a21\u5f0f\u6d6e\u52d5\u63d0\u793a *\/\n        .preview-mode-indicator {\n            position: fixed;\n            bottom: 20px;\n            right: 20px;\n            background: rgba(0,0,0,0.7);\n            color: white;\n            padding: 10px 15px;\n            border-radius: 30px;\n            font-size: 14px;\n            z-index: 1000;\n            display: none;\n            align-items: center;\n            box-shadow: 0 2px 10px rgba(0,0,0,0.3);\n        }\n        \n        body.preview-mode .preview-mode-indicator {\n            display: flex;\n        }\n        \n        .watermark {\n            position: fixed;\n            top: 50%;\n            left: 50%;\n            transform: translate(-50%, -50%) rotate(-45deg);\n            font-size: 8em;\n            color: rgba(0,0,0,0.03);\n            pointer-events: none;\n            z-index: -1;\n            white-space: nowrap;\n        }\n        \n        \/* \u66f4\u65b0\u9a57\u8b49\u5340\u584a\u6a23\u5f0f *\/\n        .verification-content {\n            flex: 1;\n        }\n        \n        .signature-line {\n            margin-top: 15px;\n            padding-top: 10px;\n            border-top: 1px dashed #AED581;\n            display: flex;\n            justify-content: space-between;\n        }\n        \n        @media print {\n            .signature-line {\n                margin-top: 20px;\n                padding-top: 15px;\n            }\n        }\n        \n        \/* \u9801\u7709\u9801\u8173 *\/\n        .document-header {\n            border-bottom: 1px solid #ddd;\n            padding-bottom: 15px;\n            margin-bottom: 20px;\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n        }\n        \n        .document-header .logo {\n            height: 40px;\n        }\n        \n        .document-header .document-title {\n            font-size: 24px;\n            font-weight: bold;\n            color: #1976D2;\n        }\n        \n        .document-footer {\n            border-top: 1px solid #ddd;\n            padding-top: 15px;\n            margin-top: 30px;\n            font-size: 12px;\n            display: flex;\n            justify-content: space-between;\n        }\n        \n        .footer-logo {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n        \n        .junyi-footer-logo {\n            height: 20px !important;\n        }\n        \n        \/* \u9a57\u8b49\u5340\u584a *\/\n        .verification-block {\n            background: #F9FBE7;\n            border: 1px dashed #AED581;\n            border-radius: 10px;\n            padding: 15px;\n            margin: 15px 0;\n            display: flex;\n            align-items: center;\n            font-size: 13px;\n            line-height: 1.6;\n        }\n        \n        .verification-block .material-icons {\n            color: #7CB342;\n            font-size: 28px;\n            margin-right: 15px;\n            flex-shrink: 0;\n        }\n        \n        .verification-block strong {\n            font-size: 16px;\n            display: block;\n            margin-bottom: 5px;\n            color: #33691E;\n        }\n        \n        .verification-qr {\n            width: 60px;\n            height: 60px;\n            background: #ddd;\n            margin-left: 15px;\n        }\n        \n        \/* \u5b78\u7fd2\u6458\u8981 *\/\n        .learning-summary {\n            background: #F5F5F5;\n            border-radius: 10px;\n            padding: 12px;\n            margin: 15px 0;\n        }\n        \n        \/* \u7d9c\u5408\u8a55\u8a9e\u5340\u584a *\/\n        .progress-comment {\n            background: #E8F5E9;\n            border-radius: 10px;\n            padding: 15px;\n            margin: 15px 0;\n            border-left: 4px solid #4CAF50;\n            font-size: 15px;\n            line-height: 1.6;\n            text-align: left;\n        }\n        \n        .progress-comment .comment-title {\n            font-weight: bold;\n            color: #2E7D32;\n            margin-bottom: 5px;\n            font-size: 17px;\n            display: flex;\n            align-items: center;\n        }\n        \n        .progress-comment .comment-title .material-icons {\n            margin-right: 8px;\n            color: #4CAF50;\n        }\n        \n        .progress-comment .progress-value {\n            font-weight: bold;\n            color: #1976D2;\n        }\n        \n        .progress-comment .comment-message {\n            margin-top: 8px;\n        }\n        \n        \/* \u4e0d\u5728\u5217\u5370\u6a21\u5f0f\u986f\u793a *\/\n        @media print {\n            .progress-comment {\n                display: none !important;\n            }\n        }\n        \n        body.preview-mode .progress-comment {\n            display: none !important;\n        }\n        \n        .learning-summary-title {\n            font-weight: bold;\n            margin-bottom: 10px;\n            font-size: 16px;\n            color: #333;\n        }\n        \n        .learning-summary-chart {\n            display: flex;\n            justify-content: space-around;\n            margin: 15px 0;\n        }\n        \n        .chart-item {\n            text-align: center;\n            width: 80px;\n        }\n        \n        .chart-circle {\n            width: 70px;\n            height: 70px;\n            border-radius: 50%;\n            background: conic-gradient(#4CAF50 0%, #4CAF50 var(--percent), #EEEEEE var(--percent), #EEEEEE 100%);\n            margin: 0 auto 8px;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            position: relative;\n        }\n        \n        .chart-circle::before {\n            content: \"\";\n            position: absolute;\n            width: 60px;\n            height: 60px;\n            border-radius: 50%;\n            background: white;\n        }\n        \n        .chart-percentage {\n            position: relative;\n            z-index: 1;\n            font-weight: bold;\n            font-size: 18px;\n            color: #333;\n        }\n        \n        .chart-label {\n            font-size: 14px;\n            color: #666;\n        }\n        \n        .chart-count {\n            font-size: 13px;\n            color: #555;\n            margin-top: 4px;\n        }\n        \n        @media print {\n            .chart-count {\n                font-size: 10px !important;\n            }\n        }\n        \n        body.preview-mode .chart-count {\n            font-size: 11px !important;\n        }\n        \n        \/* \u5217\u5370\u65b9\u5411\u5207\u63db\u6309\u9215\u6a23\u5f0f *\/\n        .print-orientation-toggle {\n            background-color: #ff9800 !important;\n            color: white !important;\n        }\n        \n        .print-orientation-toggle:hover {\n            background-color: #e68a00 !important;\n        }\n        \n        \/* \u9810\u8a2d\u96b1\u85cf\u9700\u8981\u767b\u5165\u5f8c\u624d\u986f\u793a\u7684\u5143\u4ef6 *\/\n        .learning-summary, \n        #progressComment, \n        .verification-block, \n        .document-footer, \n        .button-container, \n        .preview-controls,\n        #contentContainer {\n            display: none;\n        }\n        \n        \/* \u5168\u5c4floading\u8986\u84cb\u5c64 *\/\n        .loading-overlay {\n            position: fixed;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background-color: rgba(255, 255, 255, 0.8);\n            display: flex;\n            flex-direction: column;\n            justify-content: center;\n            align-items: center;\n            z-index: 9999;\n            transition: opacity 0.3s ease;\n        }\n        \n        .loading-spinner {\n            width: 60px;\n            height: 60px;\n            border-radius: 50%;\n            border: 5px solid #f3f3f3;\n            border-top: 5px solid #2196F3;\n            animation: spin 1.5s linear infinite;\n            margin-bottom: 20px;\n        }\n        \n        .loading-text {\n            font-size: 18px;\n            color: #333;\n            text-align: center;\n            max-width: 80%;\n        }\n        \n        .loading-progress {\n            width: 200px;\n            height: 4px;\n            background-color: #f3f3f3;\n            border-radius: 2px;\n            margin-top: 15px;\n            overflow: hidden;\n        }\n        \n        .loading-progress-bar {\n            height: 100%;\n            width: 0%;\n            background-color: #2196F3;\n            border-radius: 2px;\n            transition: width 0.3s ease;\n        }\n        \n        @keyframes spin {\n            0% { transform: rotate(0deg); }\n            100% { transform: rotate(360deg); }\n        }\n        \n        \/* \u9801\u9762\u6a19\u984c\u8207\u6a19\u8a8c *\/\n        .page-header {\n            text-align: center;\n            margin-bottom: 20px;\n            padding-bottom: 15px;\n            border-bottom: 1px solid #eee;\n        }\n        \n        .junyi-logo {\n            height: 40px !important;\n            margin: 10px 0;\n        }\n        \n        body.preview-mode .junyi-logo {\n            height: 20px !important;\n            margin: 5px 0;\n        }\n    <\/style>\n<\/head>\n<body>\n    <!-- \u9810\u89bd\u63a7\u5236\u5217 -->\n    <div class=\"preview-controls preview-hide\">\n        <div>\u7db2\u9801\u700f\u89bd\u6a21\u5f0f<\/div>\n        <div class=\"preview-buttons\">\n            <button class=\"preview-button\" id=\"togglePreviewBtn\">\n                <span class=\"material-icons\">visibility<\/span>\u9810\u89bd\u6a21\u5f0f\n            <\/button>\n            <button class=\"preview-button\" id=\"savePdfBtn\">\n                <span class=\"material-icons\">download<\/span>\u5132\u5b58PDF\n            <\/button>\n        <\/div>\n    <\/div>\n    \n    <!-- \u5217\u5370\u9810\u89bd\u6a21\u5f0f\u6d6e\u52d5\u63d0\u793a -->\n    <div class=\"preview-mode-indicator\">\n        <span class=\"material-icons\" style=\"margin-right: 5px;\">visibility<\/span>\n        <span>\u9810\u89bd\u6a21\u5f0f<\/span>\n        <button onclick=\"togglePreviewMode(false)\" style=\"background: #4CAF50; border: none; color: white; border-radius: 4px; padding: 3px 8px; margin-left: 10px; cursor: pointer;\">\n            <span class=\"material-icons\" style=\"font-size: 14px; margin-right: 3px;\">arrow_back<\/span>\u8fd4\u56de\u7db2\u9801\u700f\u89bd\n        <\/button>\n    <\/div>\n    \n    <div class=\"watermark\">\u5747\u4e00\u6559\u80b2\u5e73\u53f0<\/div>\n    \n    <!-- \u5168\u5c4floading\u8986\u84cb\u5c64 -->\n    <div id=\"loadingOverlay\" class=\"loading-overlay\">\n        <div class=\"loading-spinner\"><\/div>\n        <div class=\"loading-text\">\u6b63\u5728\u8f09\u5165\u8ab2\u7a0b\u5167\u5bb9\uff0c\u8acb\u7a0d\u5019...<\/div>\n        <div class=\"loading-progress\">\n            <div id=\"loadingProgressBar\" class=\"loading-progress-bar\"><\/div>\n        <\/div>\n    <\/div>\n    \n    <div class=\"container\">\n        <!-- \u9801\u9762\u6a19\u984c\u8207\u6a19\u8a8c -->\n        <div class=\"page-header\">\n            <img src=\"https:\/\/www.junyiacademy.org\/_next\/image?url=%2Fjunyi-logo.png&w=384&q=75\" alt=\"\u5747\u4e00\u6559\u80b2\u5e73\u53f0\" class=\"junyi-logo\">\n        <\/div>\n        \n        <!-- \u6b61\u8fce\u8a0a\u606f -->\n        <div id=\"welcome\" class=\"welcome-message text-center preview-hide\">\n            <span class=\"material-icons\">waving_hand<\/span>\u55e8\uff01<span id=\"nickname\"><\/span> \u4f60\u597d\uff0c\u6b61\u8fce\u7533\u8acb\n        <\/div>\n        \n        <!-- \u5b78\u7fd2\u8a18\u9304\u532f\u51fa\u5340\u57df -->\n        <div id=\"export_learning_progress\" class=\"export-container\">\n            <div class=\"export-content\">\n                <!-- \u79fb\u9664\u6587\u4ef6\u9801\u7709\u5340\u57df -->\n                <h4 class=\"text-center\">\u5747\u4e00\u6559\u80b2\u5e73\u53f0<br>\u7dda\u4e0a\u8ab2\u7a0b\u5b78\u7fd2\u8a18\u9304<\/h4>\n                <div id=\"breadcrumb\" class=\"text-center\"><\/div>\n                <h3 id=\"subject\" class=\"text-center\"><\/h3>\n                <div id=\"res-area\" class=\"text-center\"><\/div>\n                \n                <!-- \u7528\u6236\u8cc7\u8a0a -->\n                <div id=\"divUserInfo\" class=\"user-info\">\n                    <div><span class=\"material-icons\">person<\/span>\u59d3\u540d\uff1a<span id=\"export_UserName\"><\/span><\/div>\n                    <div><span class=\"material-icons\">apartment<\/span>\u5b78\u6821\uff1a<span id=\"export_UserSchool\"><\/span><\/div>\n                    <div class=\"user-info-note preview-hide\"><span class=\"material-icons\">info<\/span>\u82e5\u986f\u793a\u7684\u8cc7\u8a0a\u6709\u8aa4\uff0c\u8acb\u81f3<a href=\"https:\/\/www.junyiacademy.org\/account-setting\" target=\"_blank\">\u4fee\u6539\u57fa\u672c\u4eba\u8cc7\u6599<\/a>\uff0c\u66f4\u65b0\u300c\u540d\u7a31\u300d\u8207\u300c\u5c31\u8b80\u5b78\u6821\u300d\uff0c\u5b58\u6a94\u5f8c\u518d\u91cd\u65b0\u6253\u958b\u9019\u500b\u9801\u9762\u3002<\/div>\n                <\/div>\n                \n                <!-- \u5b78\u7fd2\u6458\u8981 -->\n                <div class=\"learning-summary\">\n                    <div class=\"learning-summary-title\"><span class=\"material-icons\">insights<\/span> \u8ab2\u7a0b\u5b78\u7fd2\u7d9c\u5408\u6458\u8981<\/div>\n                    <div class=\"learning-summary-chart\" id=\"summaryChart\">\n                        <!-- JS \u6703\u52d5\u614b\u586b\u5165\u5716\u8868 -->\n                    <\/div>\n                <\/div>\n                \n                <!-- \u7d9c\u5408\u8a55\u8a9e\u5340\u584a -->\n                <div class=\"progress-comment preview-hide\" id=\"progressComment\">\n                    <!-- JS \u6703\u52d5\u614b\u586b\u5165\u8a55\u8a9e -->\n                <\/div>\n                \n                <!-- \u8ab2\u7a0b\u5167\u5bb9\u8207\u9032\u5ea6 -->\n                <div class=\"flex-container\">\n                    <!-- \u5167\u5bb9\u5217\u8868 -->\n                    <div id=\"contentContainer\" class=\"content-list\"><\/div>\n                <\/div>\n                \n                <!-- \u9a57\u8b49\u5340\u584a -->\n                <div class=\"verification-block\">\n                    <span class=\"material-icons\">verified<\/span>\n                    <div class=\"verification-content\">\n                        <div><strong>\u5b78\u7fd2\u7d00\u9304\u8aa0\u4fe1\u8072\u660e<\/strong><\/div>\n                        <div>\u6b64\u6587\u4ef6\u7531\u5747\u4e00\u6559\u80b2\u5e73\u53f0\u81ea\u52d5\u7522\u751f\uff0c\u8cc7\u6599\u64f7\u53d6\u6642\u9593: <span id=\"verification_time\"><\/span><\/div>\n                        <div>\u672c\u4eba\u627f\u8afe\u6b64\u4efd\u5b78\u7fd2\u8a18\u9304\u7684\u5167\u5bb9\u5c6c\u5be6\uff0c\u672a\u7d93\u904e\u4efb\u4f55\u4eba\u70ba\u7be1\u6539\u6216\u4fee\u6539\u3002<\/div>\n                        <div class=\"signature-line\">\n                            <div>\u5b78\u751f\u7c3d\u540d\uff1a________________<\/div>\n                            <div>\u65e5\u671f\uff1a________________<\/div>\n                        <\/div>\n                    <\/div>\n                <\/div>\n                \n                <!-- \u6587\u4ef6\u9801\u8173 -->\n                <div class=\"document-footer\">\n                    <div class=\"footer-logo\">\n                        <img src=\"https:\/\/www.junyiacademy.org\/_next\/image?url=%2Fjunyi-logo.png&w=384&q=75\" alt=\"\u5747\u4e00\u6559\u80b2\u5e73\u53f0\" class=\"junyi-footer-logo\">\n                        <span>\u5747\u4e00\u6559\u80b2\u5e73\u53f0 (https:\/\/www.junyiacademy.org\/)<\/span>\n                    <\/div>\n                    <div>\u6587\u4ef6ID: <span id=\"document_id\"><\/span><\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n        \n        <!-- \u6309\u9215\u5340\u57df -->\n        <div class=\"button-container text-center preview-hide\">\n            <button class=\"bottom-preview-button\" onclick=\"togglePreviewMode()\">\n                <span class=\"material-icons\">visibility<\/span>\u9810\u89bd\u6a21\u5f0f\n            <\/button>\n            <button class=\"bottom-preview-button\" onclick=\"saveHtmltoPDF()\">\n                <span class=\"material-icons\">download<\/span>\u5132\u5b58PDF\n            <\/button>\n            <div id=\"reloadBtn\" class=\"reload-link\">\n                <a href=\"#\" onclick=\"reloadPage()\">\n                    <span class=\"material-icons\">refresh<\/span>\u91cd\u6574\u9801\u9762\n                <\/a>\n            <\/div>\n        <\/div>\n        \n        <!-- \u767b\u51fa\u5340\u57df -->\n        <div id=\"logout-area\" class=\"logout-area text-center preview-hide\"><\/div>\n        <div id=\"logOutMessage\" class=\"logout-message preview-hide\"><span class=\"loading\"><\/span><span class=\"material-icons\">logout<\/span>\u6b63\u5728\u767b\u51fa\u5747\u4e00<\/div>\n    <\/div>\n\n    <script>\n    \/\/ \u5168\u57df\u8b8a\u6578\n    window.xsrfToken = null;\n    \n    \/\/ \u9801\u9762\u8f09\u5165\u6642\u57f7\u884c\n    $(document).ready(function() {\n        \/\/ \u521d\u59cb\u5316loading\u8986\u84cb\u5c64\n        const loadingOverlay = document.getElementById('loadingOverlay');\n        const loadingProgressBar = document.getElementById('loadingProgressBar');\n        \n        \/\/ \u5982\u679c\u9801\u9762\u76f4\u63a5\u5f9e\u7de9\u5b58\u8f09\u5165\uff0c\u53ef\u80fd\u4e0d\u9700\u8981\u986f\u793aloading\n        if (document.readyState === 'complete') {\n            loadingOverlay.style.display = 'none';\n        } else {\n            loadingProgressBar.style.width = '5%';\n        }\n        \n        \/\/ \u6aa2\u67e5\u662f\u5426\u9700\u8981\u91cd\u5b9a\u5411\n        checkRedirection();\n        \n        \/\/ \u7372\u53d6\u8ab2\u7a0b\u8cc7\u8a0a\n        const fullURL = window.location.href;\n        const subject_slug = getTopicSlug(fullURL);\n        let subject_page;\n        let subject_title;\n        let course_path;\n        \n        \/\/ \u8655\u7406\u8ab2\u7a0b\u8cc7\u8a0a\n        if (subject_slug !== '') {\n            subject_page = getTopicPage(subject_slug);\n            \n            if (subject_page !== null) {\n                subject_title = subject_page.data.title;\n                course_path = subject_page.data.breadcrumb;\n            } else {\n                subject_title = '\u26a0\u7121\u6548\u7684\u8ab2\u7a0b\u76ee\u9304\uff0c\u8acb\u78ba\u8a8d';\n            }\n        } else {\n            subject_page = '\u7121\u6307\u5b9a\u8ab2\u7a0b\u76ee\u9304';\n            subject_title = '\u26a0\u7121\u6548\u7684\u8ab2\u7a0b\u76ee\u9304\uff0c\u8acb\u78ba\u8a8d';\n            \n            \/\/ \u5143\u4ef6\u5df2\u7d93\u5728CSS\u4e2d\u9810\u8a2d\u96b1\u85cf\uff0c\u4e0d\u9700\u8981\u518d\u6b21\u96b1\u85cf\n        }\n        \n        \/\/ \u986f\u793a\u8ab2\u7a0b\u6a19\u984c\u548c\u8def\u5f91\n        $('#subject').html(subject_title);\n        $('#breadcrumb').html(extractAndFormatTitles(course_path));\n        \n        \/\/ \u7372\u53d6\u7528\u6236\u4ee4\u724c\n        window.xsrfToken = getUserToken(document);\n        \n        \/\/ \u6aa2\u67e5\u7528\u6236\u767b\u5165\u72c0\u614b\n        const isLogin = getUserLoginStatus(window.xsrfToken);\n        \n        if (isLogin) {\n            \/\/ \u7372\u53d6\u7528\u6236\u8cc7\u6599\n            const userProfileData = getUserProfile(window.xsrfToken);\n            \n            const isPhantom = userProfileData.isPhantom;\n            const lastActivity = userProfileData.lastActivity;\n            const userKey = userProfileData.userKey;\n            const nickname = userProfileData.nickname;\n            const userEmail = userProfileData.email;\n            const userSchool = userProfileData.schoolName.replace(\/,\/g, '\uff5c');\n            const userdistrict = userProfileData.district.replace(\/,\/g, '\uff5c');\n            \n            if (!isPhantom) {\n                \/\/ \u986f\u793a\u767b\u51fa\u8cc7\u8a0a\n                printLogoutInfo();\n                \n                if (subject_title !== '\u26a0\u7121\u6548\u7684\u8ab2\u7a0b\u76ee\u9304\uff0c\u8acb\u78ba\u8a8d') {\n                    \/\/ \u986f\u793a\u6b61\u8fce\u8a0a\u606f\n                    printWelcomeMsg(nickname, userdistrict, userSchool);\n                    \n                    \/\/ \u7372\u53d6\u7528\u6236\u9032\u5ea6\u8cc7\u6599\n                    const userProgressCache = getUserProgressCache(window.xsrfToken, userKey, lastActivity);\n                    \n                    \/\/ \u986f\u793a\u8ab2\u7a0b\u5167\u5bb9\u548c\u9032\u5ea6\n                    displayContentWithProgress(subject_page, userProgressCache, window.xsrfToken);\n                    \n                    \/\/ \u986f\u793a\u9a57\u8b49\u5b8c\u6210\u8a0a\u606f\n                    printValidationCompeltedMsg();\n                }\n            } else {\n                \/\/ \u986f\u793a\u8a2a\u5ba2\u63d0\u793a\u8a0a\u606f\n                printGuestAlertMsg();\n            }\n        } else {\n            \/\/ \u986f\u793a\u767b\u5165\u63d0\u793a\u8a0a\u606f\n            printLoginRequiredMsg();\n        }\n    });\n    \n    \/\/ \u6aa2\u67e5\u662f\u5426\u9700\u8981\u91cd\u5b9a\u5411\n    function checkRedirection() {\n        const currentUrl = window.location.href;\n        const originalDomain = 'edit-dot-gaewordpress-dot-junyiacademy.appspot.com';\n        const redirectDomain = 'www.junyiacademy.org\/event';\n        \n        if (currentUrl.includes(originalDomain)) {\n            const modifiedUrl = currentUrl.replace(originalDomain, redirectDomain);\n            window.location.href = modifiedUrl;\n        }\n    }\n    \n    \/\/ \u5f9e URL \u7372\u53d6\u4e3b\u984c slug\n    function getTopicSlug(pageURL) {\n        const hashIndex = pageURL.indexOf('?');\n        \n        if (hashIndex !== -1) {\n            return pageURL.substring(hashIndex + 1);\n        }\n        \n        return '';\n    }\n    \n    \/\/ \u7372\u53d6\u4e3b\u984c\u9801\u9762\u8cc7\u6599\n    function getTopicPage(topicSlug) {\n        const requestUrl = 'https:\/\/www.junyiacademy.org\/api\/v2\/content\/topicpage\/' + topicSlug + '?casing=camel';\n        let pageData = null;\n        \n        $.ajax({\n            url: requestUrl,\n            method: 'GET',\n            async: false,\n            cache: false, \/\/ \u7981\u7528\u7de9\u5b58\u4ee5\u9632\u6b62\u700f\u89bd\u5668\u6b77\u53f2\u8fd4\u56de\u6642\u51fa\u932f\n        }).done(function(data) {\n            pageData = data;\n        }).fail(function(jqXHR, textStatus, errorThrown) {\n            \/\/ \u8655\u7406 404 \u932f\u8aa4\n            if (jqXHR.status === 404) {\n                console.error('\u5b58\u53d6\u7121\u6548\u7684\u8ab2\u7a0b\u76ee\u9304');\n                \/\/ \u96b1\u85cf loading \u8986\u84cb\u5c64\n                const loadingOverlay = document.getElementById('loadingOverlay');\n                loadingOverlay.style.display = 'none';\n                document.getElementById('loadingProgressBar').style.width = '0%';\n            } else {\n                console.error('\u53d6\u5f97\u8ab2\u7a0b\u8cc7\u6599\u6642\u767c\u751f\u932f\u8aa4:', textStatus, errorThrown);\n            }\n        });\n        \n        return pageData;\n    }\n    \n    \/\/ \u63d0\u53d6\u4e26\u683c\u5f0f\u5316\u6a19\u984c\n    function extractAndFormatTitles(data) {\n        if (!Array.isArray(data)) {\n            console.error('\u7121\u6548\u7684\u8f38\u5165\uff1a\u9810\u671f\u70ba\u9663\u5217');\n            return '';\n        }\n        \n        const titles = data.map(item => item.title);\n        return titles.join(' \/ ');\n    }\n    \n    \/\/ \u7372\u53d6\u7528\u6236\u4ee4\u724c\n    function getUserToken(doc) {\n        let token = null;\n        \n        $.ajax({\n            url: 'https:\/\/www.junyiacademy.org\/',\n            method: 'GET',\n            async: false,\n            cache: false,\n        }).done(function() {\n            token = \/fkey=([^;]*)\/.exec(doc.cookie) ? \/fkey=([^;]*)\/.exec(doc.cookie)[1] : null;\n        });\n        \n        return token;\n    }\n    \n    \/\/ \u6aa2\u67e5\u7528\u6236\u767b\u5165\u72c0\u614b\n    function getUserLoginStatus(token) {\n        let status = null;\n        \n        $.ajax({\n            url: 'https:\/\/www.junyiacademy.org\/api\/v2\/user\/tracking-identity',\n            method: 'GET',\n            async: false,\n            cache: false,\n            xhrFields: { withCredentials: true },\n            headers: { 'X-KA-FKey': token },\n        }).done(function(data) {\n            data = data.data;\n            status = data.isLoggedIn;\n        });\n        \n        return status;\n    }\n    \n    \/\/ \u7372\u53d6\u7528\u6236\u8cc7\u6599\n    function getUserProfile(token) {\n        let userProfileData = null;\n        \n        $.ajax({\n            url: 'https:\/\/www.junyiacademy.org\/api\/v2\/wordpress\/user\/profile',\n            method: 'GET',\n            async: false,\n            cache: false,\n            xhrFields: { withCredentials: true },\n            headers: { 'X-KA-FKey': token },\n        }).done(function(data) {\n            userProfileData = data.data;\n        });\n        \n        return userProfileData;\n    }\n    \n    \/\/ \u7372\u53d6\u7528\u6236\u9032\u5ea6\u7de9\u5b58\n    function getUserProgressCache(token, key, timeStamp) {\n        const requestUrl = 'https:\/\/www.junyiacademy.org\/user_progress_cache?userKey=' + key + '&lastActivity=' + timeStamp;\n        let cacheData = null;\n        \n        $.ajax({\n            url: requestUrl,\n            method: 'GET',\n            async: false,\n            cache: false,\n            xhrFields: { withCredentials: true },\n            headers: { 'X-KA-FKey': token },\n        }).done(function(data) {\n            cacheData = data;\n        });\n        \n        return cacheData;\n    }\n    \n    \/\/ \u6aa2\u67e5\u5fc5\u8981\u8cc7\u6599\u662f\u5426\u5b58\u5728\u65bc\u7528\u6236\u9032\u5ea6\u4e2d\n    function doRequiredDataExistInUserProgress(requiredData, userProgressData) {\n        return requiredData.every(item => userProgressData.includes(item));\n    }\n    \n    \/\/ \u7372\u53d6\u7528\u6236\u8003\u8a66\u7de9\u5b58\n    function getUserExamCache(examID, token) {\n        const requestUrl = 'https:\/\/www.junyiacademy.org\/api\/v2\/exam?exam_infos=[%7B%22type%22:%22Exam%22,%22id%22:%22' + examID + '%22%7D]&check_report=1&casing=camel';\n        let cacheData = null;\n        \n        $.ajax({\n            url: requestUrl,\n            method: 'GET',\n            async: false,\n            cache: false,\n            xhrFields: { withCredentials: true },\n            headers: { 'X-KA-FKey': token },\n        }).done(function(data) {\n            cacheData = data;\n        });\n        \n        return cacheData;\n    }\n    \n    \/\/ \u986f\u793a\u5167\u5bb9\u548c\u9032\u5ea6\n    function displayContentWithProgress(topicPage, userProgressData, token) {\n        \/\/ \u986f\u793aloading\u8986\u84cb\u5c64\n        const loadingOverlay = document.getElementById('loadingOverlay');\n        const loadingProgressBar = document.getElementById('loadingProgressBar');\n        const loadingText = loadingOverlay.querySelector('.loading-text');\n        \n        loadingOverlay.style.display = 'flex';\n        \n        \/\/ \u4f7f\u7528setTimeout\u8b93\u700f\u89bd\u5668\u6709\u6642\u9593\u6e32\u67d3loading\u8986\u84cb\u5c64\n        setTimeout(() => {\n            const container = document.getElementById('contentContainer');\n            \n            let totalVideo = 0;\n            let completedVideo = 0;\n            let totalExercise = 0;\n            let completedExercise = 0;\n            let totalArticle = 0;\n            let completedArticle = 0;\n            let totalExam = 0;\n            let completedExam = 0;\n            \n            \/\/ \u6e05\u7a7a\u5bb9\u5668\n            container.innerHTML = '';\n            \n            \/\/ \u904e\u6ffe\u51fa\u5f71\u7247\u3001\u7fd2\u984c\u3001\u8b1b\u7fa9\u548c\u6e2c\u9a57\n            const contents = topicPage.data.child.filter(item => \n                item.type === \"Video\" || \n                item.type === \"Exercise\" || \n                item.type === \"Article\" || \n                item.type === \"Exam\"\n            );\n            \n            const totalContents = contents.length;\n            let processedContents = 0;\n            \n            \/\/ \u66f4\u65b0\u9032\u5ea6\u689d\u521d\u59cb\u72c0\u614b\n            loadingProgressBar.style.width = '5%';\n            \n            \/\/ \u4f7f\u7528requestAnimationFrame\u4f86\u5206\u6279\u8655\u7406\u5167\u5bb9\uff0c\u907f\u514dUI\u51cd\u7d50\n            function processContentBatch(startIndex, batchSize) {\n                const endIndex = Math.min(startIndex + batchSize, contents.length);\n                \n                for (let i = startIndex; i < endIndex; i++) {\n                    const content = contents[i];\n                    let content_status;\n                    \n                    \/\/ \u66f4\u65b0loading\u6587\u5b57\n                    loadingText.textContent = `\u6b63\u5728\u8f09\u5165\u8ab2\u7a0b\u5167\u5bb9 (${i+1}\/${totalContents})...`;\n                    \n                    \/\/ \u6839\u64da\u5167\u5bb9\u985e\u578b\u6aa2\u67e5\u72c0\u614b\n                    switch (content.type) {\n                        case 'Article':\n                            totalArticle++;\n                            content_status = checkArticleStatus(content.id, userProgressData.article);\n                            if (content_status !== '\u672a\u5b8c\u6210') {\n                                completedArticle++;\n                            }\n                            break;\n                            \n                        case 'Exam':\n                            totalExam++;\n                            content_status = checkExamStatus(content.id, token);\n                            if (content_status !== '\u672a\u5b8c\u6210') {\n                                completedExam++;\n                            }\n                            break;\n                            \n                        case 'Video':\n                            totalVideo++;\n                            content_status = checkVideoStatus(content.progress_id, userProgressData.video);\n                            if (content_status !== '\u672a\u5b8c\u6210') {\n                                completedVideo++;\n                            }\n                            break;\n                            \n                        case 'Exercise':\n                            totalExercise++;\n                            content_status = checkExerciseStatus(content.progress_id, userProgressData.exercise);\n                            if (content_status !== '\u672a\u5b8c\u6210') {\n                                completedExercise++;\n                            }\n                            break;\n                            \n                        default:\n                            console.log('\u672a\u77e5\u7684\u5167\u5bb9\u985e\u578b:', content.type);\n                            break;\n                    }\n                    \n                    \/\/ \u5275\u5efa\u5167\u5bb9\u5143\u7d20\n                    const contentDiv = document.createElement('div');\n                    contentDiv.className = 'content-item';\n                    \n                    \/\/ \u8a2d\u7f6e\u5167\u5bb9\n                    const typeSpan = document.createElement('span');\n                    typeSpan.className = 'content-type';\n                    \n                    \/\/ \u70ba\u4e0d\u540c\u5167\u5bb9\u985e\u578b\u6dfb\u52a0\u7279\u5b9a\u7684CSS\u985e\n                    if (content.type === 'Video') {\n                        typeSpan.className += ' content-type-video';\n                    } else if (content.type === 'Exercise') {\n                        typeSpan.className += ' content-type-exercise';\n                    } else if (content.type === 'Article') {\n                        typeSpan.className += ' content-type-article';\n                    } else if (content.type === 'Exam') {\n                        typeSpan.className += ' content-type-exam';\n                    }\n                    \n                    typeSpan.innerHTML = translateType(content.type);\n                    \n                    const statusSpan = document.createElement('span');\n                    statusSpan.className = content_status === '\u672a\u5b8c\u6210' ? 'status-incomplete' : 'status-complete';\n                    statusSpan.innerHTML = content_status;\n                    \n                    const titleSpan = document.createElement('span');\n                    titleSpan.className = 'content-title';\n                    \/\/ \u4e0d\u518d\u786c\u7de8\u78bc\u622a\u65b7\u6a19\u984c\uff0c\u6539\u7531 CSS \u7684 text-overflow: ellipsis \u8655\u7406\n                    titleSpan.innerHTML = content.title;\n                    titleSpan.title = content.title; \/\/ \u5b8c\u6574\u6a19\u984c\u986f\u793a\u5728\u63d0\u793a\u4e2d\n                    \n                    \/\/ \u6dfb\u52a0\u5230\u5bb9\u5668\n                    contentDiv.appendChild(typeSpan);\n                    contentDiv.appendChild(statusSpan);\n                    contentDiv.appendChild(titleSpan);\n                    \n                    container.appendChild(contentDiv);\n                    \n                    \/\/ \u66f4\u65b0\u9032\u5ea6\n                    processedContents++;\n                    const progressPercentage = 5 + (processedContents \/ totalContents * 70); \/\/ 5%-75%\u7684\u9032\u5ea6\n                    loadingProgressBar.style.width = progressPercentage + '%';\n                }\n                \n                \/\/ \u5982\u679c\u9084\u6709\u5167\u5bb9\u9700\u8981\u8655\u7406\uff0c\u7e7c\u7e8c\u4e0b\u4e00\u6279\n                if (endIndex < contents.length) {\n                    requestAnimationFrame(() => {\n                        processContentBatch(endIndex, batchSize);\n                    });\n                } else {\n                    \/\/ \u6240\u6709\u5167\u5bb9\u8655\u7406\u5b8c\u6210\uff0c\u66f4\u65b0\u5716\u8868\n                    loadingText.textContent = '\u6b63\u5728\u751f\u6210\u5b78\u7fd2\u9032\u5ea6\u5716\u8868...';\n                    loadingProgressBar.style.width = '85%';\n                    \n                    \/\/ \u4f7f\u7528setTimeout\u8b93UI\u6709\u6642\u9593\u66f4\u65b0\n                    setTimeout(() => {\n                        \/\/ \u8a08\u7b97\u5b8c\u6210\u767e\u5206\u6bd4\uff08\u9632\u6b62\u9664\u4ee5\u96f6\u7684\u60c5\u6cc1\uff09\n                        const videoPercent = totalVideo > 0 ? Math.round((completedVideo\/totalVideo)*100) : 0;\n                        const exercisePercent = totalExercise > 0 ? Math.round((completedExercise\/totalExercise)*100) : 0;\n                        const articlePercent = totalArticle > 0 ? Math.round((completedArticle\/totalArticle)*100) : 0;\n                        const examPercent = totalExam > 0 ? Math.round((completedExam\/totalExam)*100) : 0;\n                        \n                        \/\/ \u66f4\u65b0\u6458\u8981\u5716\u8868\uff0c\u50b3\u5165\u5b8c\u6210\u6578\u91cf\u548c\u7e3d\u6578\n                        updateSummaryChart(\n                            videoPercent, completedVideo, totalVideo,\n                            exercisePercent, completedExercise, totalExercise,\n                            articlePercent, completedArticle, totalArticle,\n                            examPercent, completedExam, totalExam\n                        );\n                        \n                        \/\/ \u5b8c\u6210\u6240\u6709\u8655\u7406\uff0c\u96b1\u85cfloading\u8986\u84cb\u5c64\n                        loadingProgressBar.style.width = '100%';\n                        loadingText.textContent = '\u8f09\u5165\u5b8c\u6210\uff01';\n                        \n                        setTimeout(() => {\n                            loadingOverlay.style.opacity = '0';\n                            setTimeout(() => {\n                                loadingOverlay.style.display = 'none';\n                                loadingOverlay.style.opacity = '1';\n                                loadingProgressBar.style.width = '0%';\n                            }, 300);\n                        }, 200);\n                    }, 200);\n                }\n            }\n            \n            \/\/ \u958b\u59cb\u8655\u7406\u7b2c\u4e00\u6279\u5167\u5bb9\uff0c\u6bcf\u6279\u8655\u74065\u500b\n            processContentBatch(0, 5);\n        }, 100);\n        \n        \/\/ \u7ffb\u8b6f\u5167\u5bb9\u985e\u578b\n        function translateType(type) {\n            const typeTranslations = {\n                \"Video\": '<span class=\"material-icons\">play_circle<\/span>\u5f71\u7247',\n                \"Article\": '<span class=\"material-icons\">article<\/span>\u8b1b\u7fa9',\n                \"Exercise\": '<span class=\"material-icons\">edit_note<\/span>\u7fd2\u984c',\n                \"Exam\": '<span class=\"material-icons\">quiz<\/span>\u6e2c\u9a57'\n            };\n            return typeTranslations[type] || type;\n        }\n        \n        \/\/ \u6aa2\u67e5\u8b1b\u7fa9\u72c0\u614b\n        function checkArticleStatus(cid, userLog) {\n            const articleList = Array.of('.' + cid);\n            const userProgressData = userLog.completed;\n            \n            const result = doRequiredDataExistInUserProgress(articleList, userProgressData);\n            \n            return (result ? '\u5df2\u5b8c\u6210' : '\u672a\u5b8c\u6210');\n        }\n        \n        \/\/ \u6aa2\u67e5\u5f71\u7247\u72c0\u614b\n        function checkVideoStatus(cid, userLog) {\n            const videoList = Array.of('.' + cid);\n            \n            let result = '\u672a\u5b8c\u6210';\n            let isExist = false;\n            let userProgressData;\n            \n            \/\/ \u770b\u5b8c\u5f71\u7247\n            userProgressData = userLog.completed;\n            isExist = doRequiredDataExistInUserProgress(videoList, userProgressData);\n            \n            if (isExist) {\n                result = '\u5df2\u5b8c\u6210';\n                return result;\n            }\n            \n            \/\/ \u5f71\u7247\u958b\u59cb\u89c0\u770b\n            userProgressData = userLog.started;\n            isExist = doRequiredDataExistInUserProgress(videoList, userProgressData);\n            \n            if (isExist) {\n                result = '\u89c0\u770b\u4e2d';\n                return result;\n            }\n            \n            return result;\n        }\n        \n        \/\/ \u6aa2\u67e5\u7fd2\u984c\u72c0\u614b\n        function checkExerciseStatus(cid, userLog) {\n            const exerciseList = Array.of(cid);\n            \n            let result = '\u672a\u5b8c\u6210';\n            let isExist = false;\n            let userProgressData;\n            \n            \/\/ \u6aa2\u67e5\u7b49\u7d1a1\n            userProgressData = userLog.level1;\n            isExist = doRequiredDataExistInUserProgress(exerciseList, userProgressData);\n            \n            if (isExist) {\n                result = '\u5df2\u5b8c\u6210'; \/\/\uff5c\u7b49\u7d1a\uff11\n                return result;\n            }\n            \n            \/\/ \u6aa2\u67e5\u7b49\u7d1a2\n            userProgressData = userLog.level2;\n            isExist = doRequiredDataExistInUserProgress(exerciseList, userProgressData);\n            \n            if (isExist) {\n                result = '\u5df2\u5b8c\u6210'; \/\/\uff5c\u7b49\u7d1a\uff12\n                return result;\n            }\n            \n            \/\/ \u6aa2\u67e5\u7b49\u7d1a3\n            userProgressData = userLog.level3;\n            isExist = doRequiredDataExistInUserProgress(exerciseList, userProgressData);\n            \n            if (isExist) {\n                result = '\u5df2\u5b8c\u6210'; \/\/\uff5c\u7b49\u7d1a\uff13\n                return result;\n            }\n            \n            \/\/ \u6aa2\u67e5\u7cbe\u719f\n            userProgressData = userLog.proficient;\n            isExist = doRequiredDataExistInUserProgress(exerciseList, userProgressData);\n            \n            if (isExist) {\n                result = '\u5df2\u5b8c\u6210'; \/\/\uff5c\u7cbe\u719f\u7d1a\n                return result;\n            }\n            \n            return result;\n        }\n        \n        \/\/ \u6aa2\u67e5\u6e2c\u9a57\u72c0\u614b\n        function checkExamStatus(cid, token) {\n            const userExamData = getUserExamCache(cid, token);\n            const result = userExamData.data[0].has_exam_log;\n            \n            return (result ? '\u5df2\u5b8c\u6210' : '\u672a\u5b8c\u6210');\n        }\n    }\n    \n    \/\/ \u5728\u9801\u9762\u8f09\u5165\u6642\u6dfb\u52a0\u5b78\u7fd2\u6458\u8981\u5713\u74b0\u5716\n    function updateSummaryChart(\n        videoPercent, completedVideo, totalVideo,\n        exercisePercent, completedExercise, totalExercise,\n        articlePercent, completedArticle, totalArticle,\n        examPercent, completedExam, totalExam\n    ) {\n        const summaryChart = document.getElementById('summaryChart');\n        summaryChart.innerHTML = '';\n        \n        \/\/ \u6dfb\u52a0\u5f71\u7247\u5713\u74b0\u5716\n        const videoChart = document.createElement('div');\n        videoChart.className = 'chart-item';\n        videoChart.innerHTML = `\n            <div class=\"chart-circle\" style=\"--percent: ${totalVideo > 0 ? videoPercent : 0}%\">\n                <div class=\"chart-percentage\">${totalVideo > 0 ? videoPercent + '%' : 'Na%'}<\/div>\n            <\/div>\n            <div class=\"chart-label\">\u5f71\u7247\u5b8c\u6210\u7387<\/div>\n            <div class=\"chart-count\">${completedVideo}\/${totalVideo}<\/div>\n        `;\n        summaryChart.appendChild(videoChart);\n        \n        \/\/ \u6dfb\u52a0\u7fd2\u984c\u5713\u74b0\u5716\n        const exerciseChart = document.createElement('div');\n        exerciseChart.className = 'chart-item';\n        exerciseChart.innerHTML = `\n            <div class=\"chart-circle\" style=\"--percent: ${totalExercise > 0 ? exercisePercent : 0}%\">\n                <div class=\"chart-percentage\">${totalExercise > 0 ? exercisePercent + '%' : 'Na%'}<\/div>\n            <\/div>\n            <div class=\"chart-label\">\u7fd2\u984c\u5b8c\u6210\u7387<\/div>\n            <div class=\"chart-count\">${completedExercise}\/${totalExercise}<\/div>\n        `;\n        summaryChart.appendChild(exerciseChart);\n        \n        \/\/ \u6dfb\u52a0\u8b1b\u7fa9\u5713\u74b0\u5716\n        const articleChart = document.createElement('div');\n        articleChart.className = 'chart-item';\n        articleChart.innerHTML = `\n            <div class=\"chart-circle\" style=\"--percent: ${totalArticle > 0 ? articlePercent : 0}%\">\n                <div class=\"chart-percentage\">${totalArticle > 0 ? articlePercent + '%' : 'Na%'}<\/div>\n            <\/div>\n            <div class=\"chart-label\">\u8b1b\u7fa9\u5b8c\u6210\u7387<\/div>\n            <div class=\"chart-count\">${completedArticle}\/${totalArticle}<\/div>\n        `;\n        summaryChart.appendChild(articleChart);\n        \n        \/\/ \u6dfb\u52a0\u6e2c\u9a57\u5713\u74b0\u5716\n        const examChart = document.createElement('div');\n        examChart.className = 'chart-item';\n        examChart.innerHTML = `\n            <div class=\"chart-circle\" style=\"--percent: ${totalExam > 0 ? examPercent : 0}%\">\n                <div class=\"chart-percentage\">${totalExam > 0 ? examPercent + '%' : 'Na%'}<\/div>\n            <\/div>\n            <div class=\"chart-label\">\u6e2c\u9a57\u5b8c\u6210\u7387<\/div>\n            <div class=\"chart-count\">${completedExam}\/${totalExam}<\/div>\n        `;\n        summaryChart.appendChild(examChart);\n        \n        \/\/ \u8a08\u7b97\u5e73\u5747\u9032\u5ea6\u4e26\u66f4\u65b0\u8a55\u8a9e\u5340\u57df\n        updateProgressComment(\n            totalVideo > 0 ? videoPercent : null,\n            totalExercise > 0 ? exercisePercent : null,\n            totalArticle > 0 ? articlePercent : null,\n            totalExam > 0 ? examPercent : null\n        );\n    }\n    \n    \/\/ \u66f4\u65b0\u9032\u5ea6\u8a55\u8a9e\n    function updateProgressComment(videoPercent, exercisePercent, articlePercent, examPercent) {\n        const commentDiv = document.getElementById('progressComment');\n        \n        \/\/ \u8a08\u7b97\u5e73\u5747\u9032\u5ea6\uff08\u6392\u9664Na\u503c\uff09\n        let validPercents = [videoPercent, exercisePercent, articlePercent, examPercent].filter(p => p !== null);\n        let averageProgress = 0;\n        \n        if (validPercents.length > 0) {\n            averageProgress = Math.round(validPercents.reduce((sum, p) => sum + p, 0) \/ validPercents.length);\n        }\n        \n        \/\/ \u6839\u64da\u5e73\u5747\u9032\u5ea6\u8a2d\u7f6e\u8a55\u8a9e\n        let commentTitle = '';\n        let commentMessage = '';\n        let icon = '';\n        \n        if (averageProgress === 100) {\n            commentTitle = '\u5b8c\u6210\u8005';\n            commentMessage = '\u606d\u559c\u4f60\u5b8c\u6210\u4e86\u6240\u6709\u5b78\u7fd2\u5167\u5bb9\uff01\u9019\u8b49\u660e\u4e86\u4f60\u7684\u6bc5\u529b\u548c\u5b78\u7fd2\u71b1\u5ff1\u3002\u6301\u7e8c\u5b78\u7fd2\u5c07\u5e36\u7d66\u4f60\u66f4\u591a\u77e5\u8b58\u7684\u529b\u91cf\uff01';\n            icon = 'emoji_events';\n        } else if (averageProgress >= 91) {\n            commentTitle = '\u63a5\u8fd1\u5b8c\u6210';\n            commentMessage = '\u7576\u4f60\u5982\u6b64\u63a5\u8fd1\u6210\u529f\u6642\uff0c\u8acb\u4e0d\u8981\u653e\u68c4\u3002\u6210\u529f\u5c31\u5728\u773c\u524d\uff0c\u518d\u591a\u4e00\u9ede\u52aa\u529b\uff0c\u4f60\u5c31\u80fd\u9054\u6210\u76ee\u6a19\uff01';\n            icon = 'stars';\n        } else if (averageProgress >= 61) {\n            commentTitle = '\u63a5\u8fd1\u6210\u529f\u8005';\n            commentMessage = '\u4f60\u5df2\u7d93\u8d70\u904e\u4e86\u5927\u90e8\u5206\u7684\u5b78\u7fd2\u65c5\u7a0b\uff01\u4fdd\u6301\u9019\u80a1\u52d5\u80fd\uff0c\u5805\u6301\u5230\u6700\u5f8c\uff0c\u4f60\u5c07\u6536\u7a6b\u6eff\u6eff\u7684\u6210\u5c31\u611f\u3002';\n            icon = 'trending_up';\n        } else if (averageProgress >= 31) {\n            commentTitle = '\u52aa\u529b\u8005';\n            commentMessage = '\u4f60\u6b63\u5728\u7a69\u6b65\u524d\u9032\uff01\u6bcf\u5b8c\u6210\u4e00\u500b\u5b78\u7fd2\u55ae\u5143\uff0c\u90fd\u662f\u77e5\u8b58\u7684\u7a4d\u7d2f\u3002\u6301\u7e8c\u4fdd\u6301\u5b78\u7fd2\u7684\u71b1\u60c5\uff0c\u4f60\u6703\u770b\u5230\u66f4\u591a\u9032\u6b65\u3002';\n            icon = 'directions_run';\n        } else {\n            commentTitle = '\u521d\u5b78\u8005';\n            commentMessage = '\u6bcf\u500b\u5c08\u5bb6\u90fd\u66fe\u662f\u521d\u5b78\u8005\uff0c\u5b78\u7fd2\u7684\u65c5\u7a0b\u525b\u525b\u958b\u59cb\uff01\u8ddf\u8457\u8ab2\u7a0b\u4e00\u6b65\u6b65\u524d\u9032\uff0c\u4f60\u5c07\u9010\u6f38\u638c\u63e1\u6240\u6709\u77e5\u8b58\u9ede\u3002';\n            icon = 'hiking';\n        }\n        \n        \/\/ \u66f4\u65b0\u8a55\u8a9e\u5340\u584a\n        commentDiv.innerHTML = `\n            <div class=\"comment-title\">\n                <span class=\"material-icons\">${icon}<\/span>\n                \u5b78\u7fd2\u9032\u5ea6\u8a55\u4f30\uff1a${commentTitle}\n            <\/div>\n            <div>\n                \u5e73\u5747\u5b78\u7fd2\u9032\u5ea6\uff1a<span class=\"progress-value\">${averageProgress}%<\/span>\n            <\/div>\n            <div class=\"comment-message\">\n                ${commentMessage}\n            <\/div>\n        `;\n    }\n    \n    \/\/ \u986f\u793a\u6b61\u8fce\u8a0a\u606f\n    function printWelcomeMsg(nickname, district, school) {\n        $('#nickname').html(nickname);\n        $('#export_UserName').html(nickname);\n        $('#export_UserSchool').html(district + \"\uff5c\" + school);\n        document.getElementById('divUserInfo').style.display = \"block\";\n        \n        $('#res-area').html(`\n            <div id=\"success_login_msg\">\n                <div id=\"check-progress\">\n                    <span class=\"loading\"><\/span>\n                    <span class=\"material-icons\">hourglass_empty<\/span>\u6b63\u5728\u6aa2\u67e5\u8ab2\u7a0b\u5b78\u7fd2\u9032\u5ea6\uff0c\u8acb\u7b49\u5f85...\n                <\/div>\n            <\/div>\n        `);\n    }\n    \n    \/\/ \u986f\u793a\u9a57\u8b49\u5b8c\u6210\u8a0a\u606f\n    function printValidationCompeltedMsg() {\n        $('#res-area').html(`\n            <div id=\"success_login_msg\" style=\"opacity: 0\">\n                <div id=\"check-progress\">\n                    <span class=\"material-icons\">check_circle<\/span>\u8ab2\u7a0b\u5b78\u7fd2\u9032\u5ea6...\u532f\u51fa\u5b8c\u6210\u2713\n                <\/div>\n            <\/div>\n        `);\n        \n        $('#success_login_msg').animate({ opacity: 1 }, 500);\n        \n        \/\/ \u78ba\u4fdd\u6240\u6709\u9700\u8981\u7684\u5143\u4ef6\u90fd\u986f\u793a\uff08\u8207\u672a\u767b\u5165\u6642\u76f8\u53cd\u7684\u64cd\u4f5c\uff09\n        document.querySelector('.learning-summary').style.display = 'block';\n        document.getElementById('progressComment').style.display = 'block';\n        document.querySelector('.verification-block').style.display = 'flex';\n        document.querySelector('.document-footer').style.display = 'flex';\n        document.querySelector('.button-container').style.display = 'flex';\n        document.querySelector('.preview-controls').style.display = 'flex';\n        document.getElementById('contentContainer').style.display = 'block';\n        \n        \/\/ \u78ba\u4fddloading\u8986\u84cb\u5c64\u5df2\u96b1\u85cf\n        const loadingOverlay = document.getElementById('loadingOverlay');\n        loadingOverlay.style.display = 'none';\n        document.getElementById('loadingProgressBar').style.width = '0%';\n        \n        \/\/ \u79fb\u9664\u5c0d saveBtn \u7684\u986f\u793a\u63a7\u5236\uff0c\u56e0\u70ba\u6211\u5011\u5df2\u7d93\u4f7f\u7528\u65b0\u7684\u6309\u9215\u8a2d\u8a08\n        document.getElementById('reloadBtn').style.display = \"inline-block\";\n        \n        \/\/ \u6dfb\u52a0\u6309\u9215\u51fa\u73fe\u52d5\u756b\n        $('#reloadBtn').css('opacity', 0).animate({ opacity: 1 }, 500);\n    }\n    \n    \/\/ \u986f\u793a\u8a2a\u5ba2\u63d0\u793a\u8a0a\u606f\n    function printGuestAlertMsg() {\n        $('#nickname').html('\u672a\u8a3b\u518a\u8a2a\u5ba2');\n        $('#res-area').html(`\n            <div id=\"success_login_msg\">\n                <div id=\"check-progress\"><span class=\"material-icons\">hourglass_empty<\/span>\u6b63\u5728\u6aa2\u67e5\u8ab2\u7a0b\u5b78\u7fd2\u9032\u5ea6\uff0c\u8acb\u7b49\u5f85...<\/div>\n            <\/div>\n        `);\n        \n        \/\/ \u96b1\u85cfloading\u8986\u84cb\u5c64\n        document.getElementById('loadingOverlay').style.display = 'none';\n        \n        \/\/ \u9019\u4e9b\u5143\u4ef6\u5df2\u7d93\u5728CSS\u4e2d\u9810\u8a2d\u96b1\u85cf\uff0c\u4e0d\u9700\u8981\u518d\u6b21\u96b1\u85cf\n    }\n    \n    \/\/ \u986f\u793a\u767b\u5165\u63d0\u793a\u8a0a\u606f\n    function printLoginRequiredMsg() {\n        const currentPage = window.location.href;\n        \n        $('#res-area').html(`\n            <div id=\"not_login_msg\">\n                <span class=\"material-icons\">login<\/span>\u5c1a\u672a\u767b\u5165\uff0c\u9ede\u64ca\u9019\u88e1 \n                <a id=\"login\" href=\"\/login?continue=${currentPage}\">\u8a3b\u518a\/\u767b\u5165<\/a> \u5747\u4e00\u5e33\u865f\uff0c\u518d\u6b21\u9032\u884c\u7533\u8acb\u3002\n            <\/div>\n        `);\n        \n        \/\/ \u96b1\u85cfloading\u8986\u84cb\u5c64\n        document.getElementById('loadingOverlay').style.display = 'none';\n        \n        \/\/ \u9019\u4e9b\u5143\u4ef6\u5df2\u7d93\u5728CSS\u4e2d\u9810\u8a2d\u96b1\u85cf\uff0c\u4e0d\u9700\u8981\u518d\u6b21\u96b1\u85cf\n    }\n    \n    \/\/ \u986f\u793a\u767b\u51fa\u8cc7\u8a0a\n    function printLogoutInfo() {\n        $('#logout-area').html(`\n            <div id=\"protect_msg\">\n                <span style=\"font-size: 12px\">\n                    <br\/>\n                    <span class=\"material-icons\">security<\/span>\u4fdd\u8b77\u81ea\u5df1\u7684\u5e33\u865f\u3002\n                    <br\/>\u5982\u679c\u4f7f\u7528\u516c\u7528\u96fb\u8166\uff0c\u586b\u5beb\u5f8c\u8a18\u5f97\n                    <a href=\"#\" id=\"logout\"><span class=\"material-icons\">logout<\/span>\u767b\u51fa\u5747\u4e00\u5e33\u865f\u3002<\/a>\n                <\/span>\n            <\/div>\n            <div id=\"logOutMessage\" style=\"display: none;\"><span class=\"loading\"><\/span><span class=\"material-icons\">logout<\/span>\u6b63\u5728\u767b\u51fa\u5747\u4e00<\/div>\n        `);\n        \n        const currentPage = window.location.href;\n        \n        $(\"#logout\").click(function(e) {\n            e.preventDefault();\n            \n            $('#logOutMessage').fadeIn().delay(5000).fadeOut();\n            \n            $.ajax({\n                url: 'https:\/\/www.junyiacademy.org\/logout?continue=' + currentPage,\n                method: 'GET',\n                async: false,\n                cache: false,\n                xhrFields: { withCredentials: true },\n                headers: { 'X-KA-FKey': window.xsrfToken },\n            }).done(function() {\n                window.location.replace(currentPage);\n            });\n        });\n    }\n    \n    \/\/ \u5132\u5b58\u70ba PDF\n    function saveHtmltoPDF() {\n        const element = document.getElementById('export_learning_progress');\n        const file_name = document.getElementById('subject').innerHTML;\n        const currentDate = new Date();\n        const options = { \n            timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone, \n            year: 'numeric', \n            month: 'long', \n            day: 'numeric' \n        };\n        const formattedDate = currentDate.toLocaleString(undefined, options);\n        \n        \/\/ \u8a2d\u7f6e\u9a57\u8b49\u6642\u9593\u548c\u6587\u4ef6ID\n        $('#verification_time').html(formattedDate);\n        $('#document_id').html(generateDocumentId());\n        \n        \/\/ \u9032\u5165\u9810\u89bd\u6a21\u5f0f\u751f\u6210PDF\n        togglePreviewMode(true);\n        \n        const opt = {\n            margin: 0.5,\n            filename: `${file_name}-\u5b78\u7fd2\u8a18\u9304-${formattedDate}.pdf`,\n            image: { type: 'jpeg', quality: 1 },\n            html2canvas: { scale: 2 },\n            jsPDF: { \n                unit: 'cm', \n                format: 'a4', \n                orientation: 'portrait' \n            },\n            pagebreak: { mode: 'avoid-all' }\n        };\n        \n        html2pdf().set(opt).from(element).save().then(() => {\n            setTimeout(() => {\n                togglePreviewMode(false);\n            }, 1000);\n        });\n    }\n    \n    \/\/ \u751f\u6210\u6587\u4ef6ID\n    function generateDocumentId() {\n        return 'DOC-' + Math.random().toString(36).substr(2, 9).toUpperCase();\n    }\n    \n    \/\/ \u5207\u63db\u9810\u89bd\u6a21\u5f0f\n    function togglePreviewMode(forcePreview) {\n        const body = document.body;\n        const previewControls = document.querySelector('.preview-controls');\n        const previewBtn = document.getElementById('togglePreviewBtn');\n        \n        if (forcePreview === true || !body.classList.contains('preview-mode')) {\n            \/\/ \u9032\u5165\u9810\u89bd\u6a21\u5f0f\n            body.classList.add('preview-mode');\n            previewBtn.innerHTML = '<span class=\"material-icons\">visibility_off<\/span>\u7db2\u9801\u700f\u89bd\u6a21\u5f0f';\n            previewBtn.classList.add('back-to-edit');\n            previewControls.style.top = '0';\n            \n            \/\/ \u8a2d\u7f6e\u9801\u9762\u6a19\u984c\uff0c\u65b9\u4fbf\u7528\u6236\u8b58\u5225\u8a72\u6a21\u5f0f\n            const subject = document.getElementById('subject').innerText || '\u5b78\u7fd2\u7d00\u9304';\n            document.title = `${subject} - \u9810\u89bd\u6a21\u5f0f | \u5747\u4e00\u6559\u80b2\u5e73\u53f0`;\n            \n            \/\/ \u66f4\u65b0\u63d0\u793a\u6587\u5b57\uff0c\u5f37\u8abf\u9019\u662f\u9810\u89bd\n            document.querySelector('.preview-controls > div:first-child').innerText = '\u9810\u89bd\u6a21\u5f0f';\n            \n            \/\/ \u53ea\u6709\u5728\u9996\u6b21\u9032\u5165\u9810\u89bd\u6a21\u5f0f\u6642\u986f\u793a\u63d0\u793a\n            if (forcePreview !== true) {\n                setTimeout(() => {\n                    alert('\u60a8\u5df2\u9032\u5165\u9810\u89bd\u6a21\u5f0f\uff0c\u6b64\u6a21\u5f0f\u5df2\u91dd\u5c0d\u6587\u4ef6\u95b1\u8b80\u6700\u4f73\u5316\uff0c\u6e1b\u5c11\u4e86\u984f\u8272\u4f7f\u7528\u8207\u9593\u8ddd\u3002\u53ef\u4ee5\u4f7f\u7528\u53f3\u4e0b\u89d2\u300c\u8fd4\u56de\u7db2\u9801\u700f\u89bd\u300d\u6309\u9215\u8fd4\u56de\u539f\u59cb\u756b\u9762\u3002');\n                }, 300);\n            }\n            \n        } else {\n            \/\/ \u8fd4\u56de\u7db2\u9801\u700f\u89bd\u6a21\u5f0f\n            body.classList.remove('preview-mode');\n            previewBtn.innerHTML = '<span class=\"material-icons\">visibility<\/span>\u9810\u89bd\u6a21\u5f0f';\n            previewBtn.classList.remove('back-to-edit');\n            previewControls.style.top = '0';\n            \n            \/\/ \u6062\u5fa9\u539f\u59cb\u6a19\u984c\n            document.title = '\u5747\u4e00\u6559\u80b2\u5e73\u53f0 - \u5b78\u7fd2\u8a18\u9304\u532f\u51fa';\n            \n            \/\/ \u6062\u5fa9\u539f\u59cb\u63d0\u793a\u6587\u5b57\n            document.querySelector('.preview-controls > div:first-child').innerText = '\u7db2\u9801\u700f\u89bd\u6a21\u5f0f';\n        }\n    }\n    \n    \/\/ \u91cd\u6574\u9801\u9762\n    function reloadPage() {\n        window.location.reload();\n    }\n\n    \/\/ \u6587\u6a94\u8f09\u5165\u5b8c\u6210\u5f8c\u8a2d\u7f6e\u4e8b\u4ef6\u76e3\u807d\u5668\n    document.addEventListener('DOMContentLoaded', function() {\n        \/\/ \u8a2d\u7f6e\u9810\u89bd\u6309\u9215\u4e8b\u4ef6\n        document.getElementById('togglePreviewBtn').addEventListener('click', function() {\n            togglePreviewMode();\n        });\n        \n        \/\/ \u8a2d\u7f6e\u5132\u5b58PDF\u6309\u9215\u4e8b\u4ef6\n        document.getElementById('savePdfBtn').addEventListener('click', function() {\n            saveHtmltoPDF();\n        });\n        \n        \/\/ \u8a2d\u7f6e\u9375\u76e4\u5feb\u6377\u9375Escape\u8fd4\u56de\u7db2\u9801\u700f\u89bd\u6a21\u5f0f\n        document.addEventListener('keydown', function(event) {\n            if (event.key === 'Escape' && document.body.classList.contains('preview-mode')) {\n                togglePreviewMode(false);\n            }\n        });\n    });\n    <\/script>\n<\/body>\n<\/html>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>\u5747\u4e00\u6559\u80b2\u5e73\u53f0 &#8211; \u5b78\u7fd2\u8a18\u9304\u532f\u51fa \u7db2\u9801\u700f\u89bd\u6a21\u5f0f visibility\u9810\u89bd\u6a21\u5f0f download\u5132\u5b58P [&hellip;]<\/p>\n","protected":false},"author":15,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v19.6.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u532f\u51fa\u5b78\u7fd2\u9032\u5ea6\uff5c\u5747\u4e00\u6559\u80b2\u5e73\u53f0 - \u5747\u4e00\u6559\u80b2\u5e73\u53f0<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.junyiacademy.org\/event\/learning-progress-export\/\" \/>\n<meta property=\"og:locale\" content=\"zh_TW\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u532f\u51fa\u5b78\u7fd2\u9032\u5ea6\uff5c\u5747\u4e00\u6559\u80b2\u5e73\u53f0 - \u5747\u4e00\u6559\u80b2\u5e73\u53f0\" \/>\n<meta property=\"og:description\" content=\"\u5747\u4e00\u6559\u80b2\u5e73\u53f0 &#8211; \u5b78\u7fd2\u8a18\u9304\u532f\u51fa \u7db2\u9801\u700f\u89bd\u6a21\u5f0f visibility\u9810\u89bd\u6a21\u5f0f download\u5132\u5b58P [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.junyiacademy.org\/event\/learning-progress-export\/\" \/>\n<meta property=\"og:site_name\" content=\"\u5747\u4e00\u6559\u80b2\u5e73\u53f0\" \/>\n<meta property=\"article:modified_time\" content=\"2025-05-13T02:40:32+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.junyiacademy.org\/_next\/image?url=%2Fjunyi-logo.png&w=384&q=75\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"20 \u5206\u9418\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.junyiacademy.org\/event\/learning-progress-export\/\",\"url\":\"https:\/\/www.junyiacademy.org\/event\/learning-progress-export\/\",\"name\":\"\u532f\u51fa\u5b78\u7fd2\u9032\u5ea6\uff5c\u5747\u4e00\u6559\u80b2\u5e73\u53f0 - \u5747\u4e00\u6559\u80b2\u5e73\u53f0\",\"isPartOf\":{\"@id\":\"https:\/\/www.junyiacademy.org\/event\/#website\"},\"datePublished\":\"2024-04-01T07:11:55+00:00\",\"dateModified\":\"2025-05-13T02:40:32+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.junyiacademy.org\/event\/learning-progress-export\/#breadcrumb\"},\"inLanguage\":\"zh-TW\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.junyiacademy.org\/event\/learning-progress-export\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.junyiacademy.org\/event\/learning-progress-export\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/edit-dot-gaewordpress-dot-junyiacademy.appspot.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u532f\u51fa\u5b78\u7fd2\u9032\u5ea6\uff5c\u5747\u4e00\u6559\u80b2\u5e73\u53f0\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.junyiacademy.org\/event\/#website\",\"url\":\"https:\/\/www.junyiacademy.org\/event\/\",\"name\":\"\u5747\u4e00\u6559\u80b2\u5e73\u53f0\",\"description\":\"\u8b93\u6bcf\u4e00\u4f4d\u5b69\u5b50\u90fd\u6709\u6a5f\u6703\u6210\u70ba\u7d42\u8eab\u5b78\u7fd2\u8005\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.junyiacademy.org\/event\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"zh-TW\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"\u532f\u51fa\u5b78\u7fd2\u9032\u5ea6\uff5c\u5747\u4e00\u6559\u80b2\u5e73\u53f0 - \u5747\u4e00\u6559\u80b2\u5e73\u53f0","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.junyiacademy.org\/event\/learning-progress-export\/","og_locale":"zh_TW","og_type":"article","og_title":"\u532f\u51fa\u5b78\u7fd2\u9032\u5ea6\uff5c\u5747\u4e00\u6559\u80b2\u5e73\u53f0 - \u5747\u4e00\u6559\u80b2\u5e73\u53f0","og_description":"\u5747\u4e00\u6559\u80b2\u5e73\u53f0 &#8211; \u5b78\u7fd2\u8a18\u9304\u532f\u51fa \u7db2\u9801\u700f\u89bd\u6a21\u5f0f visibility\u9810\u89bd\u6a21\u5f0f download\u5132\u5b58P [&hellip;]","og_url":"https:\/\/www.junyiacademy.org\/event\/learning-progress-export\/","og_site_name":"\u5747\u4e00\u6559\u80b2\u5e73\u53f0","article_modified_time":"2025-05-13T02:40:32+00:00","og_image":[{"url":"https:\/\/www.junyiacademy.org\/_next\/image?url=%2Fjunyi-logo.png&w=384&q=75"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"20 \u5206\u9418"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.junyiacademy.org\/event\/learning-progress-export\/","url":"https:\/\/www.junyiacademy.org\/event\/learning-progress-export\/","name":"\u532f\u51fa\u5b78\u7fd2\u9032\u5ea6\uff5c\u5747\u4e00\u6559\u80b2\u5e73\u53f0 - \u5747\u4e00\u6559\u80b2\u5e73\u53f0","isPartOf":{"@id":"https:\/\/www.junyiacademy.org\/event\/#website"},"datePublished":"2024-04-01T07:11:55+00:00","dateModified":"2025-05-13T02:40:32+00:00","breadcrumb":{"@id":"https:\/\/www.junyiacademy.org\/event\/learning-progress-export\/#breadcrumb"},"inLanguage":"zh-TW","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.junyiacademy.org\/event\/learning-progress-export\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.junyiacademy.org\/event\/learning-progress-export\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/edit-dot-gaewordpress-dot-junyiacademy.appspot.com\/"},{"@type":"ListItem","position":2,"name":"\u532f\u51fa\u5b78\u7fd2\u9032\u5ea6\uff5c\u5747\u4e00\u6559\u80b2\u5e73\u53f0"}]},{"@type":"WebSite","@id":"https:\/\/www.junyiacademy.org\/event\/#website","url":"https:\/\/www.junyiacademy.org\/event\/","name":"\u5747\u4e00\u6559\u80b2\u5e73\u53f0","description":"\u8b93\u6bcf\u4e00\u4f4d\u5b69\u5b50\u90fd\u6709\u6a5f\u6703\u6210\u70ba\u7d42\u8eab\u5b78\u7fd2\u8005","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.junyiacademy.org\/event\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"zh-TW"}]}},"_links":{"self":[{"href":"https:\/\/www.junyiacademy.org\/event\/wp-json\/wp\/v2\/pages\/36540"}],"collection":[{"href":"https:\/\/www.junyiacademy.org\/event\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.junyiacademy.org\/event\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.junyiacademy.org\/event\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/www.junyiacademy.org\/event\/wp-json\/wp\/v2\/comments?post=36540"}],"version-history":[{"count":663,"href":"https:\/\/www.junyiacademy.org\/event\/wp-json\/wp\/v2\/pages\/36540\/revisions"}],"predecessor-version":[{"id":46020,"href":"https:\/\/www.junyiacademy.org\/event\/wp-json\/wp\/v2\/pages\/36540\/revisions\/46020"}],"wp:attachment":[{"href":"https:\/\/www.junyiacademy.org\/event\/wp-json\/wp\/v2\/media?parent=36540"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}