环保评级报告edit icon

作者:
Fadinghaze
Fork(复制)
下载
嵌入
BUG反馈
index.html
style.css
index.js
现在支持上传本地图片了!
index.html
            
            <!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>报告管理 v2.1 - 江苏国能智慧生态综合服务平台</title>
    <style>
        /* --- 全局与基础样式 (与v2.0相同) --- */
        @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;700&display=swap');

        :root {
            --bg-color: #0a192f;
            --primary-text-color: #ccd6f6;
            --secondary-text-color: #8892b0;
            --accent-color: #00bcd4;
            --accent-color-hover: #14e5ff;
            --table-header-bg: #112240;
            --table-row-hover-bg: #112240;
            --border-color: #233554;
            --modal-bg-color: #0e1f3a;
        }

        body {
            font-family: 'Noto Sans SC', sans-serif;
            background-color: var(--bg-color);
            color: var(--primary-text-color);
            margin: 0;
            padding: 20px;
            font-size: 14px;
        }

        .container {
            max-width: 1400px; /* 增加宽度以容纳更多筛选条件 */
            margin: 0 auto;
            padding: 20px;
            background-color: rgba(17, 34, 64, 0.3);
            border: 1px solid var(--border-color);
            border-radius: 8px;
        }

        h1 {
            font-size: 24px;
            font-weight: 500;
            color: var(--primary-text-color);
            border-bottom: 2px solid var(--accent-color);
            padding-bottom: 10px;
            margin-top: 0;
        }

        /* --- 操作与筛选区 --- */
        .top-controls {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }
        .filters-container {
            background-color: var(--table-header-bg);
            padding: 15px;
            border-radius: 6px;
            margin-bottom: 20px;
            display: flex;
            align-items: center;
            gap: 20px;
            flex-wrap: wrap;
        }
        .filter-item {
            display: flex;
            align-items: center;
            gap: 8px;
        }
        .filter-item label {
            color: var(--secondary-text-color);
            white-space: nowrap;
        }
        .filter-item select, .filter-item input {
            background-color: var(--bg-color);
            color: var(--primary-text-color);
            border: 1px solid var(--border-color);
            border-radius: 4px;
            padding: 8px 12px;
            font-family: inherit;
        }
        .filter-item input[type="text"] {
            width: 200px;
        }
        
        .time-range-group {
            display: flex;
            gap: 10px;
        }

        .btn {
            padding: 9px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            font-weight: 500;
            transition: background-color 0.3s ease, transform 0.1s ease;
        }
        .btn:active { transform: translateY(1px); }
        .btn-primary { background-color: var(--accent-color); color: #0a192f; }
        .btn-primary:hover { background-color: var(--accent-color-hover); }
        .btn-secondary { background-color: var(--secondary-text-color); color: var(--primary-text-color); }
        .btn-secondary:hover { background-color: #a8b2d1; }
        .btn-danger { background-color: #e94b3cff; color: white; }
        .btn-danger:hover { background-color: #f06a5d; }

        /* --- 表格样式 (与v2.0相同) --- */
        .report-table { width: 100%; border-collapse: collapse; text-align: left; }
        .report-table th, .report-table td { padding: 12px 15px; border-bottom: 1px solid var(--border-color); }
        .report-table thead { background-color: var(--table-header-bg); }
        .report-table th { font-weight: 500; color: var(--primary-text-color); }
        .report-table tbody tr:hover { background-color: var(--table-row-hover-bg); }
        .report-table .actions .action-btn { color: var(--accent-color); background: none; border: none; cursor: pointer; padding: 5px; margin-right: 10px; font-family: inherit; font-size: 14px; }
        .report-table .actions .action-btn:hover { text-decoration: underline; color: var(--accent-color-hover); }

        /* --- 弹窗样式 (与v2.0相同) --- */
        .modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(10, 25, 47, 0.85); display: none; justify-content: center; align-items: center; z-index: 1000; backdrop-filter: blur(5px); }
        .modal-content { background-color: var(--modal-bg-color); padding: 25px 30px; border-radius: 8px; border: 1px solid var(--border-color); box-shadow: 0 10px 30px -15px rgba(2,12,27,0.7); width: 100%; max-width: 550px; }
        .modal-header { display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--border-color); padding-bottom: 15px; margin-bottom: 20px; }
        .modal-header h2 { margin: 0; font-size: 18px; font-weight: 500; }
        .modal-close-btn { background: none; border: none; color: var(--secondary-text-color); font-size: 24px; cursor: pointer; }
        .modal-body .form-group { margin-bottom: 20px; }
        .modal-body label { display: block; margin-bottom: 8px; color: var(--secondary-text-color); font-weight: 500; }
        .modal-body select, .modal-body input[type="text"] { width: 100%; padding: 10px; background-color: var(--bg-color); border: 1px solid var(--border-color); border-radius: 4px; color: var(--primary-text-color); box-sizing: border-box; }
        .modal-footer { display: flex; justify-content: flex-end; gap: 10px; padding-top: 10px; }
        .confirm-modal-body p { font-size: 16px; line-height: 1.6; text-align: center; margin: 10px 0 25px; }
        
        select[multiple] { height: 120px; padding: 10px; }
        select[multiple] option { padding: 5px; }
        select[multiple] option:checked { background-color: var(--accent-color); color: var(--bg-color); }
        .multiselect-note { font-size: 12px; color: var(--secondary-text-color); margin-top: 5px; }

    </style>
</head>
<body>

    <div class="container">
        <div class="top-controls">
            <h1>报告管理</h1>
            <button id="addReportBtn" class="btn btn-primary">[+] 新增报告</button>
        </div>
        
        <div class="filters-container">
            <div class="filter-item">
                <label for="filterName">报告名称:</label>
                <input type="text" id="filterName" placeholder="输入关键词搜索">
            </div>
            <div class="filter-item">
                <label>关联任务:</label>
                <select id="filterTask">
                    <option value="">全部任务</option>
                    <option value="二号文任务盘点">二号文任务盘点</option>
                    <option value="环保合规性评价">环保合规性评价</option>
                </select>
            </div>
            <div class="filter-item">
                 <label>时间范围:</label>
                 <div class="time-range-group">
                     <select id="filterYearSelect">
                         <option value="">全部年份</option>
                         <option>2025</option>
                         <option>2024</option>
                     </select>
                     <select id="filterPeriodTypeSelect">
                         <option value="">全部周期</option>
                         <option value="year">全年</option>
                         <option value="quarter">季度</option>
                         <option value="month">月度</option>
                     </select>
                     <select id="filterPeriodValueSelect" style="display: none;">
                     </select>
                 </div>
            </div>
            <div class="filter-item">
                <button class="btn btn-secondary">查询</button>
                <button class="btn btn-secondary">重置</button>
            </div>
        </div>

        <table class="report-table">
            <thead>
                <tr>
                    <th>报告名称</th>
                    <th>关联任务</th>
                    <th>时间范围</th>
                    <th>生成时间</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody id="reportTbody">
                <tr>
                    <td>环保合规性评价-2025年第二季度分析报告</td>
                    <td>环保合规性评价</td>
                    <td>2025年第二季度</td>
                    <td>2025-07-05 10:22:15</td>
                    <td class="actions">
                        <button class="action-btn">查看</button>
                        <button class="action-btn">下载</button>
                        <button class="action-btn">删除</button>
                    </td>
                </tr>
                <tr>
                    <td>二号文任务盘点-2025年6月分析报告</td>
                    <td>二号文任务盘点</td>
                    <td>2025年6月</td>
                    <td>2025-07-02 14:05:30</td>
                    <td class="actions">
                        <button class="action-btn">查看</button>
                        <button class="action-btn">下载</button>
                        <button class="action-btn">删除</button>
                    </td>
                </tr>
                <tr>
                    <td>二号文任务盘点-2025年第二季度分析报告</td>
                    <td>二号文任务盘点</td>
                    <td>2025年第二季度</td>
                    <td>2025-07-01 09:00:00</td>
                    <td class="actions">
                        <button class="action-btn">查看</button>
                        <button class="action-btn">下载</button>
                        <button class="action-btn">删除</button>
                    </td>
                </tr>
                 <tr>
                    <td>安全生产标准化评审-2025年第二季度分析报告</td>
                    <td>安全生产标准化评审</td>
                    <td>2025年第二季度</td>
                    <td>2025-06-28 11:45:00</td>
                    <td class="actions">
                        <button class="action-btn">查看</button>
                        <button class="action-btn">下载</button>
                        <button class="action-btn">删除</button>
                    </td>
                </tr>
                <tr>
                    <td>环保合规性评价-2025年第一季度分析报告</td>
                    <td>环保合规性评价</td>
                    <td>2025年第一季度</td>
                    <td>2025-04-08 16:30:11</td>
                    <td class="actions">
                        <button class="action-btn">查看</button>
                        <button class="action-btn">下载</button>
                        <button class="action-btn">删除</button>
                    </td>
                </tr>
                <tr data-key="二号文任务盘点-2025年第一季度">
                    <td>二号文任务盘点-2025年第一季度分析报告</td>
                    <td>二号文任务盘点</td>
                    <td>2025年第一季度</td>
                    <td>2025-04-05 09:18:45</td>
                    <td class="actions">
                        <button class="action-btn">查看</button>
                        <button class="action-btn">下载</button>
                        <button class="action-btn">删除</button>
                    </td>
                </tr>
                <tr>
                    <td>二号文任务盘点-2024年年度分析报告</td>
                    <td>二号文任务盘点</td>
                    <td>2024年全年</td>
                    <td>2025-01-15 17:00:00</td>
                    <td class="actions">
                        <button class="action-btn">查看</button>
                        <button class="action-btn">下载</button>
                        <button class="action-btn">删除</button>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>

    <!-- 新增报告弹窗 -->
    <div id="addReportModal" class="modal-overlay">
        <div class="modal-content">
            <div class="modal-header">
                <h2>生成新报告</h2>
                <button class="modal-close-btn">&times;</button>
            </div>
            <div class="modal-body">
                <form id="addReportForm">
                    <div class="form-group">
                        <label for="taskSelect">关联任务</label>
                        <select id="taskSelect" required>
                            <option value="二号文任务盘点">二号文任务盘点</option>
                            <option value="环保合规性评价">环保合规性评价</option>
                            <option value="安全生产标准化评审">安全生产标准化评审</option>
                            <option value="月度安全检查">月度安全检查</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label>时间范围</label>
                        <div class="time-range-group">
                            <select id="yearSelect">
                                <option>2026</option><option selected>2025</option><option>2024</option>
                            </select>
                            <select id="periodTypeSelect">
                                <option value="year">全年</option>
                                <option value="quarter" selected>季度</option>
                                <option value="month">月度</option>
                            </select>
                        </div>
                        <div id="periodValueContainer" class="form-group" style="margin-top: 10px;">
                             <select id="periodValueSelect" multiple>
                             </select>
                             <p class="multiselect-note">提示:按住 Ctrl/Command 键可选择多个</p>
                        </div>
                    </div>
                    <div class="form-group">
                         <label for="reportNameInput">报告名称</label>
                         <input type="text" id="reportNameInput" placeholder="选择任务和时间后自动生成" required>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button id="cancelAddBtn" class="btn btn-secondary">取消</button>
                <button id="confirmAddBtn" type="submit" form="addReportForm" class="btn btn-primary">确定</button>
            </div>
        </div>
    </div>

    <!-- 确认覆盖弹窗 -->
    <div id="confirmOverwriteModal" class="modal-overlay">
        <div class="modal-content" style="max-width: 400px;">
            <div class="modal-header"><h2>确认覆盖</h2><button class="modal-close-btn">&times;</button></div>
            <div class="modal-body confirm-modal-body"><p>部分报告已存在,确认要生成新报告并覆盖旧报告吗?</p></div>
            <div class="modal-footer">
                <button id="cancelOverwriteBtn" class="btn btn-secondary">取消</button>
                <button id="confirmOverwriteBtn" class="btn btn-danger">确认覆盖</button>
            </div>
        </div>
    </div>


    <script>
    document.addEventListener('DOMContentLoaded', () => {
        // --- DOM Element References ---
        const addReportBtn = document.getElementById('addReportBtn');
        const addReportModal = document.getElementById('addReportModal');
        const confirmOverwriteModal = document.getElementById('confirmOverwriteModal');
        
        const closeModalBtns = document.querySelectorAll('.modal-close-btn');
        const cancelAddBtn = document.getElementById('cancelAddBtn');
        const confirmAddBtn = document.getElementById('confirmAddBtn');
        const cancelOverwriteBtn = document.getElementById('cancelOverwriteBtn');
        const confirmOverwriteBtn = document.getElementById('confirmOverwriteBtn');

        const addReportForm = document.getElementById('addReportForm');
        const taskSelect = document.getElementById('taskSelect');
        const yearSelect = document.getElementById('yearSelect');
        const periodTypeSelect = document.getElementById('periodTypeSelect');
        const periodValueSelect = document.getElementById('periodValueSelect');
        const periodValueContainer = document.getElementById('periodValueContainer');
        const reportNameInput = document.getElementById('reportNameInput');
        const reportTbody = document.getElementById('reportTbody');
        
        let pendingReports = [];

        // --- Time Range Selector Logic ---
        const periodOptions = {
            year: [],
            quarter: ['第一季度', '第二季度', '第三季度', '第四季度'],
            month: Array.from({ length: 12 }, (_, i) => `${i + 1}月`)
        };

        function setupTimeRangeSelector(yearEl, typeEl, valueEl, containerEl) {
            function update() {
                const type = typeEl.value;
                if (!valueEl) return;
                
                valueEl.innerHTML = '';
                const isMultiSelect = type === 'quarter' || type === 'month';

                // *** BUG FIX START ***
                // The visibility of the container is the only thing we need to control.
                // If the container is hidden, its children (the select box) will be hidden too.
                if (containerEl) {
                    containerEl.style.display = isMultiSelect ? 'block' : 'none';
                }
                // *** BUG FIX END ***

                if (isMultiSelect) {
                    periodOptions[type].forEach((optionText) => {
                        const optionEl = document.createElement('option');
                        optionEl.textContent = optionText;
                        optionEl.value = optionText;
                        valueEl.appendChild(optionEl);
                    });
                }
            }
            typeEl.addEventListener('change', update);
            update(); // Initial call
        }
        
        // Setup for modal
        setupTimeRangeSelector(yearSelect, periodTypeSelect, periodValueSelect, periodValueContainer);
        // Setup for filter
        const filterPeriodTypeSelect = document.getElementById('filterPeriodTypeSelect');
        const filterPeriodValueSelect = document.getElementById('filterPeriodValueSelect');
        setupTimeRangeSelector(
            document.getElementById('filterYearSelect'),
            filterPeriodTypeSelect,
            filterPeriodValueSelect,
            null // No container for filter, so we handle visibility directly
        );
        filterPeriodTypeSelect.addEventListener('change', function(){
            filterPeriodValueSelect.style.display = (this.value === 'quarter' || this.value === 'month') ? 'block' : 'none';
        });
        filterPeriodValueSelect.style.display = 'none'; // Initial state for filter


        // --- Auto-generate Report Name ---
        function updateReportName() {
            const taskName = taskSelect.value;
            const year = yearSelect.value;
            const periodType = periodTypeSelect.value;
            const selectedValues = Array.from(periodValueSelect.selectedOptions).map(opt => opt.value);

            let timeRangeText = "";
            if (periodType === 'year') {
                timeRangeText = `${year}年全年`;
            } else if (selectedValues.length === 1) {
                timeRangeText = `${year}年${selectedValues[0]}`;
            } else if (selectedValues.length > 1) {
                timeRangeText = `${year}年批量报告`;
            } else {
                reportNameInput.value = "";
                return;
            }
            reportNameInput.value = `${taskName}-${timeRangeText}分析报告`;
        }
        [taskSelect, yearSelect, periodTypeSelect, periodValueSelect].forEach(el => el.addEventListener('change', updateReportName));
        

        // --- Modal Control ---
        const openModal = (modal) => modal.style.display = 'flex';
        const closeModal = (modal) => modal.style.display = 'none';

        addReportBtn.addEventListener('click', () => {
            updateReportName(); // Initialize name on open
            openModal(addReportModal);
        });
        closeModalBtns.forEach(btn => btn.addEventListener('click', () => {
            closeModal(addReportModal);
            closeModal(confirmOverwriteModal);
        }));
        cancelAddBtn.addEventListener('click', () => closeModal(addReportModal));
        cancelOverwriteBtn.addEventListener('click', () => closeModal(confirmOverwriteModal));
        
        // --- Core Logic ---
        addReportForm.addEventListener('submit', (e) => {
            e.preventDefault();
            
            const taskName = taskSelect.value;
            const year = yearSelect.value;
            const periodType = periodTypeSelect.value;
            const selectedPeriods = periodType === 'year' ? ['全年'] : Array.from(periodValueSelect.selectedOptions).map(opt => opt.value);

            if (selectedPeriods.length === 0 && periodType !== 'year') {
                alert('请至少选择一个季度或月份!');
                return;
            }

            pendingReports = selectedPeriods.map(period => ({
                taskName,
                timeRangeText: `${year}年${period}`,
                reportName: (selectedPeriods.length > 1) ? `${taskName}-${year}年${period}分析报告` : reportNameInput.value,
                isExisting: doesReportExist(taskName, `${year}年${period}`)
            }));
            
            const hasExisting = pendingReports.some(r => r.isExisting);

            if (hasExisting) {
                openModal(confirmOverwriteModal);
            } else {
                processReports(pendingReports);
                closeModal(addReportModal);
            }
        });

        confirmOverwriteBtn.addEventListener('click', () => {
            processReports(pendingReports);
            closeModal(confirmOverwriteModal);
            closeModal(addReportModal);
        });

        function doesReportExist(taskName, timeRangeText) {
            let found = false;
            reportTbody.querySelectorAll('tr').forEach(row => {
                if (row.cells[1].textContent === taskName && row.cells[2].textContent === timeRangeText) {
                    found = true;
                }
            });
            return found;
        }

        function processReports(reports) {
            reports.forEach(reportData => {
                if (reportData.isExisting) {
                    overwriteReport(reportData);
                } else {
                    addNewReport(reportData);
                }
            });
        }
        
        function getCurrentTimestamp() {
            return new Date().toLocaleString('sv-SE').replace(' ', ' ').slice(0, 19);
        }
        
        function addNewReport(data) {
            const newRow = document.createElement('tr');
            newRow.innerHTML = `
                <td>${data.reportName}</td>
                <td>${data.taskName}</td>
                <td>${data.timeRangeText}</td>
                <td>${getCurrentTimestamp()}</td>
                <td class="actions">
                    <button class="action-btn">查看</button>
                    <button class="action-btn">下载</button>
                    <button class="action-btn">删除</button>
                </td>
            `;
            reportTbody.prepend(newRow);
        }

        function overwriteReport(data) {
             let rowToUpdate = null;
             reportTbody.querySelectorAll('tr').forEach(row => {
                 if(row.cells[1].textContent === data.taskName && row.cells[2].textContent === data.timeRangeText) {
                    rowToUpdate = row;
                 }
             });

            if (rowToUpdate) {
                rowToUpdate.style.transition = 'background-color 0.5s ease';
                rowToUpdate.style.backgroundColor = 'rgba(0, 188, 212, 0.3)';
                rowToUpdate.cells[0].textContent = data.reportName;
                rowToUpdate.cells[3].textContent = getCurrentTimestamp();
                setTimeout(() => { rowToUpdate.style.backgroundColor = ''; }, 1500);
            }
        }
    });
    </script>
</body>
</html>
        
编辑器加载中
预览
控制台