فهرست منبع

划分license_model.js文件

GTong 8 ماه پیش
والد
کامیت
4548c32380
4فایلهای تغییر یافته به همراه477 افزوده شده و 475 حذف شده
  1. 2 2
      config.toml
  2. 1 0
      static/license_info/license_info.html
  3. 13 473
      static/license_info/license_info.js
  4. 461 0
      static/license_info/license_info_modal.js

+ 2 - 2
config.toml

@@ -3,13 +3,13 @@ ip = "127.0.0.1"
 port = "8080"
 
 [database]
-oadb_ip = "10.28.20.233"
+oadb_ip = "127.0.0.1"
 oadb_port = "5138"
 oadb_db = "OAdb"
 oadb_user = "SYSDBA"
 oadb_password = "SYSDBA"
 
-licdb_ip = "10.28.20.233"
+licdb_ip = "127.0.0.1"
 licdb_port = "5138"
 licdb_db = "license"
 licdb_user = "SYSDBA"

+ 1 - 0
static/license_info/license_info.html

@@ -161,6 +161,7 @@
 
 
     <script src="license_info.js"></script>
+    <script src="license_info_modal.js"></script>
     <script src="license_info_distribution.js"></script>
     <script
     src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js">

+ 13 - 473
static/license_info/license_info.js

@@ -1,7 +1,7 @@
 // 全局变量定义
-let page = 11; // 初始页码为1,代表从第1条数据开始获取
-let pageSize = 20; // 初始每次固定获取10条数据
-let total = 0; // 数据总量(从接口获取)
+let page = 21; // 初始页码为1,代表从第1条数据开始获取
+let pageSize = 30; // 初始每次固定获取10条数据
+let licenseTotal = 0; // 数据总量(从接口获取)
 let loadedItems = 0; // 已加载的数据条目数量
 let isLoading = false; // 防止多次加载
 const timeoutDuration = 10000; // 超时时间10秒
@@ -234,13 +234,14 @@ async function fetchLicenseData(page, pageSize) {
         const result = await response.json();
         
         // 设置总量,如果第一次加载,获取total字段
-        if (total === 0 && result.total) {
-            total = result.total;
+        if (licenseTotal === 0 && result.total) {
+            licenseTotal = result.total;
         }
-   
+      
+        console.log("result  total ",licenseTotal,result.total);
            // 使用 concat 方法将新数据与之前的数据进行累加
            LicApplicationData = LicApplicationData.concat(result.data || []);
-        console.log("LicApplicationData: ",LicApplicationData);
+        console.log("LicApplicationData: ",LicApplicationData,licenseTotal,result);
         return result.data || [];
 
     } catch (error) {
@@ -261,8 +262,8 @@ function renderLicenseCards(data, clearContainer = false) {
         license_info_container.innerHTML = ''; // 清空容器内容
         isLoading = false; // 重置加载状态
         loadedItems = 0; // 重置已加载项数
-        page = 11; // 每次请求后,page 增加10,表示从下一组数据开始
-        pageSize = 20; // pageSize 每次递增10
+        page = 21; // 每次请求后,page 增加10,表示从下一组数据开始
+        pageSize = 30; // pageSize 每次递增10
         console.log("-----------渲染清除");
     }
     console.log("-----------data:",data);
@@ -328,7 +329,7 @@ function renderLicenseCards(data, clearContainer = false) {
 
 // 检查是否滚动到底部并触发加载
 // async function checkAndLoadMore(scrollHeight, scrollTop, clientHeight) {
-//     if (isLoading || loadedItems >= total) return; // 如果正在加载或已加载完所有数据则退出
+//     if (isLoading || loadedItems >= licenseTotal) return; // 如果正在加载或已加载完所有数据则退出
 
 //   //  console.log(`Scroll Info - scrollHeight: ${scrollHeight}, scrollTop: ${scrollTop}, clientHeight: ${clientHeight}`);
 
@@ -423,7 +424,7 @@ function handleMainScroll() {
 }
 
 async function checkAndLoadMore(scrollHeight, scrollTop, clientHeight) {
-    if (isLoading || loadedItems >= total) return; // 如果正在加载或已加载完所有数据则退出
+    if (isLoading || loadedItems >= licenseTotal) return; // 如果正在加载或已加载完所有数据则退出
 
     // console.log(`Scroll Info - scrollHeight: ${scrollHeight}, scrollTop: ${scrollTop}, clientHeight: ${clientHeight}`);
 
@@ -439,7 +440,7 @@ async function checkAndLoadMore(scrollHeight, scrollTop, clientHeight) {
 
 // 初始化加载第一页
 (async function() {
-    const data = await fetchLicenseData(1, 10);
+    const data = await fetchLicenseData(1, 20);
     if (data.length > 0) {
         renderLicenseCards(data); // 渲染数据到页面
         loadedItems += data.length; // 更新已加载的条目数
@@ -453,467 +454,6 @@ async function checkAndLoadMore(scrollHeight, scrollTop, clientHeight) {
 //初始化监听滚动条
 initializeScrollListeners()
 
-//-----------点击卡片弹出模态框------------------------------------------------------
-
-// 模态框显示函数
-// 模态框显示函数
-function showModalForCard(item,oaRequestId) {
-    const modal = document.getElementById('license-info-modal');
-    const modalContent = document.querySelector('.license-info-modal-content');
-    const modalBody = document.getElementById('license-info-modal-body'); // 获取下半部分容器
-    console.log(`当前点击的卡片 ID: ${oaRequestId}`);
-    
-    // 设置分页相关的变量
-    let currentPage = 1;
-    const itemsPerPage = 3; // 每页显示两组
-
-    // 对 item 数组按 oa_id 进行升序排序
-    const sortedItem = item.sort((a, b) => a.oa_id - b.oa_id);
-
-    const totalPages = Math.ceil(sortedItem.length / itemsPerPage); // 计算总页数
-
-    // 获取分页容器
-    const paginationContainer = document.querySelector('.license-info-modal-pagination');
-
-    // 清空分页容器,避免重复创建元素
-    paginationContainer.innerHTML = '';
-
-    // 创建"上一页"按钮
-    const prevButton = document.createElement('button');
-    prevButton.classList.add('prev-page');
-    prevButton.innerText = '上一页';
-    paginationContainer.appendChild(prevButton);
-
-    // 创建下拉框
-    const selectPageDropdown = document.createElement('select');
-    paginationContainer.appendChild(selectPageDropdown);
-
-    // 创建"下一页"按钮
-    const nextButton = document.createElement('button');
-    nextButton.classList.add('next-page');
-    nextButton.innerText = '下一页';
-    paginationContainer.appendChild(nextButton);
-
- 
-   // 初始化上半部分内容(Company, Creator, ApplicationDate, ApplicationTime 和两个按钮)
-function initializeHeaderContent(firstItem,sortedItem) {
-    console.log("initializeHeaderContent");  // 检查是否找到按钮
-    // 清空上半部分内容
-    const modalHeader = document.querySelector('.license-info-modal-header');
-    modalHeader.innerHTML = ''; // 确保不会重复创建
-
-    let statusClass = '';
-    if (firstItem.LicenseFlage === '已生成') {
-        statusClass = 'license-status-green';
-    } else if (firstItem.LicenseFlage === '未生成') {
-        statusClass = 'license-status-yellow';
-    } else if (firstItem.LicenseFlage === '已失效') {
-        statusClass = 'license-status-red';
-    }
-
-   // 检查当前用户是否有权限生成或分发
-   const hasGeneratePermission = currentUserPermissions.includes('generate_license');
-   const hasDispatchPermission = currentUserPermissions.includes('dispat_license');
-
-console.log(`当前用户是否有生成权限: ${hasGeneratePermission}, ${hasDispatchPermission}`);
-    // 设置卡片内容
-// 修改后的卡片内容部分代码
-modalHeader.innerHTML = `
-    <div class="license-info-card-header">
-        <h3 class="card-title">${firstItem.GlxmName}</h3>
-    </div>
-    <div class="license-info-card-content">
-        <p class="card-text">${firstItem.ApplicationDate} ${firstItem.ApplicationTime}</p> <!-- 显示日期和时间 -->
-        <p class="card-text">公司:${firstItem.Company}</p>
-        <p class="card-text">${firstItem.Project}</p>
-        <p class="card-text">创建者:${firstItem.Creator}</p>
-        <p class="card-text license-status ${statusClass}">许可证状态:${firstItem.LicenseFlage}</p>
-        <div class="license-info-card-buttons">
-            ${
-            firstItem.LicenseFlage === '已生成' && hasDispatchPermission
-                ? `<button class="license-info-modal-button" id="distributeButton">分发</button>`
-                : `<button class="license-info-modal-button" id="distributeButton" disabled style="background-color:#ccc;cursor:not-allowed;">分发</button>`
-            }
-            ${
-            firstItem.LicenseFlage !== '已生成' && hasGeneratePermission
-                ? `<button class="license-info-modal-button" id="generateOrDistribute">生成</button>`
-                : ''
-            }
-            <button class="license-info-modal-button" id="downloadAllLicenses-button">打包下载所有license.dat</button>
-            <button class="license-info-modal-button" id="viewDistributionHistory-button">查看分发历史</button>
-        </div>
-    </div>
-`;
-
-        // 绑定 generateOrDistribute 的点击事件(如果按钮存在)
-        const generateOrDistribute = modalHeader.querySelector('#generateOrDistribute');
-        if (generateOrDistribute) {
-            generateOrDistribute.addEventListener('click', () => {
-                if (firstItem.LicenseFlage === '已生成') {
-                    // 执行分发逻辑
-                    showDistributeModal(firstItem);
-                
-                } else {
-                    // 执行生成逻辑
-                    const oaRequestID = parseInt(firstItem.oa_request_id, 10);  // 10 表示10进制
-                 generateLicense(oaRequestID, true);
-                }
-                console.log('Button 1 clicked');
-            });
-        };
-
-        // 绑定分发按钮的点击事件
-        const distributeButton = modalHeader.querySelector('#distributeButton');
-        if (distributeButton && !distributeButton.disabled) {
-            distributeButton.addEventListener('click', () => {
-                showDistributeModal(firstItem);
-            });
-        }  
-          
-        //         // 在生成或分发按钮点击时,调用 showDistributeModal 函数
-        // generateOrDistribute.addEventListener('click', () => {
-        //     if (firstItem.LicenseFlage === '已生成') {
-        //         showDistributeModal(firstItem);  // 显示分发模态框
-        //     } else {
-        //         const oaRequestID = parseInt(firstItem.oa_request_id, 10);  // 生成许可证
-        //         generateLicense(oaRequestID, true);
-        //     }
-        // });
-
-
-
-        // 绑定 "打包下载所有license.dat" 按钮的点击事件
-        const downloadButton = modalHeader.querySelector('#downloadAllLicenses-button');
-
-        // 如果 LicenseFlage 是 "未生成" 或 "已失效",按钮变灰且不可点击
-        if (firstItem.LicenseFlage === '未生成' || firstItem.LicenseFlage === '已失效') {
-            downloadButton.disabled = true;
-            downloadButton.style.backgroundColor = '#ccc'; // 设置为灰色
-            downloadButton.style.cursor = 'not-allowed'; // 修改鼠标样式
-        } else {
-            // 只有当 LicenseFlage 是 "已生成" 时,才能点击下载按钮
-            downloadButton.addEventListener('click', () => {
-                downloadAllLicenses(sortedItem);
-            });
-        }
-   // 在初始化完成后绑定 "查看分发历史" 按钮的点击事件
-   const viewDistributionHistoryButton = document.getElementById('viewDistributionHistory-button');
-   if (viewDistributionHistoryButton) {
-       viewDistributionHistoryButton.addEventListener('click', () => {
-           showDistributionHistory(firstItem);
-       });
-   }
-
-    }
-
-
-    // 初始化下拉框的页码选项
-    function initializeDropdown() {
-            selectPageDropdown.innerHTML = ''; // 清空下拉框中的选项
-            for (let page = 1; page <= totalPages; page++) {
-                const option = document.createElement('option');
-                option.value = page;
-                option.innerText = `第 ${page} 页`;
-                selectPageDropdown.appendChild(option);
-            }
-            selectPageDropdown.value = currentPage; // 设置默认选项为当前页
-        }
-
-        // 渲染当前页内容
-    function ModalForCardRenderPage(page) {
-            modalBody.innerHTML = ''; // 清空之前的内容
-
-            // 计算当前页的起始和结束索引
-            const startIndex = (page - 1) * itemsPerPage;
-            const endIndex = Math.min(startIndex + itemsPerPage, sortedItem.length);
-
-            // 更新上半部分的字段内容 (以第一个元素为例)
-            const firstItem = sortedItem[0];
-            initializeHeaderContent(firstItem,sortedItem); // 动态生成上半部分内容
-
-            // 遍历当前页的数据
-            for (let i = startIndex; i < endIndex; i++) {
-                const group = sortedItem[i];
-                const groupBox = document.createElement('div');
-                groupBox.classList.add('license-info-group-box');
-
-                // 动态生成组内容,显示编号为 i+1(表示组1, 组2...)
-                groupBox.innerHTML = `
-                    <div class="license-info-group-title">集群 ${i + 1} :</div>
-
-                    <p><strong>节点数:</strong> ${group.NodeCount}</p>
-                    <p><strong>数据库版本: </strong> ${group.ProductName}${group.ProductVersion}</p>
-                    <p><strong>CPU 型号:</strong> ${group.oa_cpu}</p>
-                    <p><strong>操作系统环境:</strong> ${group.oa_operating_system}</p>
-                    <p><strong>以下为测试显示:</strong> </p>
-                    <p><strong>oa_id:</strong> ${group.oa_id}</p>
-                    <p><strong>oa_request_id:</strong> ${group.oa_request_id}</p>
-                `;
-
-                // 将生成的组内容加入到 modalBody
-                modalBody.appendChild(groupBox);
-            }
-
-            // 更新下拉框的值
-            selectPageDropdown.value = page;
-
-            // 更新按钮状态
-            prevButton.disabled = (page === 1);
-            nextButton.disabled = (page === totalPages);
-    }
-
-    // 下拉框页码选择事件
-    selectPageDropdown.addEventListener('change', function() {
-            currentPage = parseInt(this.value);
-            ModalForCardRenderPage(currentPage); // 根据选择的页码渲染对应页面
-    });
-
-    // 上一页按钮点击事件
-    prevButton.addEventListener('click', function() {
-            if (currentPage > 1) {
-                currentPage--;
-                ModalForCardRenderPage(currentPage);
-            }
-    });
-
-        // 下一页按钮点击事件
-    nextButton.addEventListener('click', function() {
-            if (currentPage < totalPages) {
-                currentPage++;
-                ModalForCardRenderPage(currentPage);
-            }
-    });
-
-    // 显示或隐藏分页相关控件
-    function togglePaginationVisibility() {
-            if (totalPages <= 1) {
-                // 隐藏下拉框和分页容器
-                paginationContainer.style.display = 'none';
-            } else {
-                // 显示下拉框和分页容器
-                paginationContainer.style.display = 'flex';
-            }
-    }
-
-    // 初始化下拉框并渲染第一页
-    initializeDropdown();
-    // 渲染模态框内容
-    ModalForCardRenderPage(currentPage);
-    // 根据页数决定是否显示分页控件
-    togglePaginationVisibility();
-
-        // 显示模态框
-    modal.style.display = 'flex'; // 显示模态框背景
-        setTimeout(() => {
-            modalContent.classList.add('show'); // 添加动画效果
-        }, 10); // 延时确保动画生效
-
-    // 关闭模态框逻辑
-    const closeModal = document.querySelector('.license-info-close');
-        closeModal.addEventListener('click', () => {
-            modalContent.classList.remove('show'); // 移除动画类
-            setTimeout(() => {
-                modal.style.display = 'none'; // 完全隐藏模态框
-            }, 500); // 等待动画结束后再隐藏
-        });
-
-    // 点击模态框外部关闭模态框
-    window.addEventListener('click', (event) => {
-            if (event.target === modal) {
-                modalContent.classList.remove('show');
-                setTimeout(() => {
-                    modal.style.display = 'none'; // 完全隐藏模态框
-                }, 500); // 等待动画结束后再隐藏
-            }
-        });
-}
-
-//-------下载全部licstr按钮
-// 下载许可证功能
-function downloadAllLicenses(sortedApplicationArray) {
-    const zip = new JSZip();
-    console.log("传进来的 sortedApplicationArray:", sortedApplicationArray);
-
-    // 初始化计数器,从1开始
-    let idCounter = 1;
-    let Project = sortedApplicationArray[0].Project;
-    console.log("Project", Project);
-
-    // 遍历 sortedApplicationArray,下载 lic1 和 lic2 数据
-    sortedApplicationArray.forEach(row => {
-        if (row.LicenseFlage === "已生成") {
-            // 替换 oa_main_mac 和 oa_second_mac 中的冒号为点
-            const mainMac = row.oa_main_mac.replace(/:/g, '.');
-            const secondMac = row.oa_second_mac.replace(/:/g, '.');
-
-            // 使用递增的 idCounter 替换 row.oa_id
-            if (row.lic1) {
-                const filename1 = `${idCounter}_license.dat_1_${mainMac}`;
-                zip.file(filename1, row.lic1);
-            }
-            if (row.lic2) {
-                const filename2 = `${idCounter}_license.dat_2_${secondMac}`;
-                zip.file(filename2, row.lic2);
-            }
-
-            // 每次循环后递增计数器
-            idCounter++;
-        }
-    });
-
-    // 生成 ZIP 文件并触发下载
-    zip.generateAsync({ type: "blob" }).then(content => {
-        const link = document.createElement('a');
-        link.href = URL.createObjectURL(content);
-        link.download = `${Project}_license.zip`;
-        link.click();
-    });
-}
-
-
-
-
-
-
-// 刷新数据并滚动到目标卡片的函数
-// 刷新数据并滚动到目标卡片,同时重新打开目标卡片的模态框
-async function refreshLicenseDataAndScrollAndOpenModal(selfPage,selfPageSize, targetCardId) {
-    const data = await fetchLicenseData(selfPage, selfPageSize);
-    if (data.length > 0) {
-        isLoading = true;
-        console.log('加载的数据:', data); // 检查是否成功获取数据
-        renderLicenseCards(data, true); // 渲染数据到页面并清空之前的内容
-        page = selfPageSize+1;
-        pageSize= selfPageSize +10;
-
-        // 滚动到目标卡片
-        if (targetCardId) {
-            const targetCard = document.querySelector(`[data-oa-request-id="${targetCardId}"]`);
-            if (targetCard) {
-                targetCard.scrollIntoView({ behavior: 'smooth', block: 'center' });
-                
-                // 延迟打开模态框,确保页面滚动完成
-                setTimeout(() => {
-                    targetCard.click(); // 模拟点击卡片,触发模态框
-                }, 500); // 延时500ms确保滚动完成
-            }
-        }
-
-        
-         setTimeout(() => {
-            isLoading = false;
-        }, 2000); 
-     
-    } else {
-        console.error('未加载到数据');
-    }
-}
-
-
-
-
-
-function generateLicense(id, isParentRow) {
-        // 显示加载进度条并设置动态提示信息
-        showLoadingModal('正在生成 License...');
-   // const payload = isParentRow ? { oa_request_id: JSON.stringify(id) } : { uniqueID:JSON.stringify(id) };
-   const payload = isParentRow 
-   ? { oa_request_id: parseInt(id, 10) }  // 将 id 转换为整数
-   : { uniqueID: parseInt(id, 10) };  // 将 id 转换为整数
-
-    console.log("generateLicense",payload ,id, isParentRow)
-    fetch('http://127.0.0.1:8080/api/admin/GenerateLicense', {
-        method: 'POST',
-        headers: {
-            'Authorization': `Bearer ${authToken}`,
-            'Content-Type': 'application/json'
-        },
-        body: JSON.stringify(payload)
-    })
-    .then(response => response.json())
-    .then(data => {
-        if (data.success) {
-          // 隐藏加载进度条
-                hideLoadingModal();
-                alert('License 生成成功!');
-            //刷新页面
-                 // 调用封装的更新方法
-            //updateCardAndModalStatus(id, isParentRow);
-            // 调用刷新函数,传入当前的 page 和 pageSize
-            refreshLicenseDataAndScrollAndOpenModal(1,pageSize,id);
-            } else {
-                    // 请求失败时隐藏加载进度条
-                hideLoadingModal();
-                alert('License 生成失败:' + data.error);
-            }
-            
-    })
-    .catch(error => {
-        console.error('生成过程中出现错误Error:', error);
-     // 请求失败时隐藏加载进度条
-     hideLoadingModal();
-        alert('生成过程中出现错误,请稍后再试。',error);
-    });
-}
-
-
-//更新卡片样式
-function updateCardAndModalStatus(id, isParentRow) {
-    // 获取对应的卡片元素,通过 oa_request_id 或 uniqueID 定位
-    const cardSelector = isParentRow ? `[data-oa-request-id="${id}"]` : `[data-unique-id="${id}"]`;
-    const card = document.querySelector(cardSelector);
-    console.log("generateLicense card", cardSelector, card);
-    
-    if (card) {
-        // 1. 更新卡片内许可证状态
-        const statusElement = card.querySelector('.license-status');
-        console.log("statusElement:", statusElement); // 检查状态元素是否存在
-        
-        if (statusElement) {
-            // 只更新许可证状态部分的文本,而不是整个 p 标签
-            statusElement.innerHTML = '许可证状态:已生成';
-            
-            // 更新状态的 CSS 类
-            statusElement.classList.remove('license-status-yellow', 'license-status-red');
-            statusElement.classList.add('license-status-green');
-        } else {
-            console.error('找不到 .license-status 元素');
-        }
-
-        // 2. 更新模态框中的状态(如果模态框已经打开)
-        const modalStatusElement = document.querySelector('.license-info-modal-header .license-status');
-        console.log("modalStatusElement:", modalStatusElement); // 检查状态元素是否存在
-        
-        if (modalStatusElement) {
-            modalStatusElement.textContent = '许可证状态:已生成';
-            modalStatusElement.classList.remove('license-status-yellow', 'license-status-red');
-            modalStatusElement.classList.add('license-status-green');
-        } else {
-            console.error('找不到 #license-info-modal-body .license-status 元素');
-        }
-
-        // 3. 更新模态框中的按钮为“分发”
-        const generateButton = document.getElementById('button1'); // 获取生成按钮
-        if (generateButton) {
-            generateButton.textContent = '分发'; // 修改按钮文本为“分发”
-            generateButton.removeEventListener('click', generateLicense); // 移除生成逻辑
-            generateButton.addEventListener('click', () => {
-                distributeLicense(id); // 添加分发逻辑
-            });
-        }
-
-        // 4. 启用 #downloadAllLicenses-button
-        const downloadButton = document.getElementById('downloadAllLicenses-button');
-        if (downloadButton) {
-            downloadButton.disabled = false; // 启用按钮
-            downloadButton.style.backgroundColor = '#007aff'; // 恢复正常的背景颜色
-            downloadButton.style.cursor = 'pointer'; // 修改鼠标样式为可点击
-        }
-
-    } else {
-        console.error(`找不到与 ID ${id} 对应的卡片`);
-    }
-}
 
 
 ///-----------获取登录用户信息----------------------------------------

+ 461 - 0
static/license_info/license_info_modal.js

@@ -0,0 +1,461 @@
+//-----------点击卡片弹出模态框------------------------------------------------------
+
+// 模态框显示函数
+// 模态框显示函数
+function showModalForCard(item,oaRequestId) {
+    const modal = document.getElementById('license-info-modal');
+    const modalContent = document.querySelector('.license-info-modal-content');
+    const modalBody = document.getElementById('license-info-modal-body'); // 获取下半部分容器
+    console.log(`当前点击的卡片 ID: ${oaRequestId}`);
+    
+    // 设置分页相关的变量
+    let currentPage = 1;
+    const itemsPerPage = 3; // 每页显示两组
+
+    // 对 item 数组按 oa_id 进行升序排序
+    const sortedItem = item.sort((a, b) => a.oa_id - b.oa_id);
+
+    const totalPages = Math.ceil(sortedItem.length / itemsPerPage); // 计算总页数
+
+    // 获取分页容器
+    const paginationContainer = document.querySelector('.license-info-modal-pagination');
+
+    // 清空分页容器,避免重复创建元素
+    paginationContainer.innerHTML = '';
+
+    // 创建"上一页"按钮
+    const prevButton = document.createElement('button');
+    prevButton.classList.add('prev-page');
+    prevButton.innerText = '上一页';
+    paginationContainer.appendChild(prevButton);
+
+    // 创建下拉框
+    const selectPageDropdown = document.createElement('select');
+    paginationContainer.appendChild(selectPageDropdown);
+
+    // 创建"下一页"按钮
+    const nextButton = document.createElement('button');
+    nextButton.classList.add('next-page');
+    nextButton.innerText = '下一页';
+    paginationContainer.appendChild(nextButton);
+
+ 
+   // 初始化上半部分内容(Company, Creator, ApplicationDate, ApplicationTime 和两个按钮)
+function initializeHeaderContent(firstItem,sortedItem) {
+    console.log("initializeHeaderContent");  // 检查是否找到按钮
+    // 清空上半部分内容
+    const modalHeader = document.querySelector('.license-info-modal-header');
+    modalHeader.innerHTML = ''; // 确保不会重复创建
+
+    let statusClass = '';
+    if (firstItem.LicenseFlage === '已生成') {
+        statusClass = 'license-status-green';
+    } else if (firstItem.LicenseFlage === '未生成') {
+        statusClass = 'license-status-yellow';
+    } else if (firstItem.LicenseFlage === '已失效') {
+        statusClass = 'license-status-red';
+    }
+
+   // 检查当前用户是否有权限生成或分发
+   const hasGeneratePermission = currentUserPermissions.includes('generate_license');
+   const hasDispatchPermission = currentUserPermissions.includes('dispat_license');
+
+console.log(`当前用户是否有生成权限: ${hasGeneratePermission}, ${hasDispatchPermission}`);
+    // 设置卡片内容
+// 修改后的卡片内容部分代码
+modalHeader.innerHTML = `
+    <div class="license-info-card-header">
+        <h3 class="card-title">${firstItem.GlxmName}</h3>
+    </div>
+    <div class="license-info-card-content">
+        <p class="card-text">${firstItem.ApplicationDate} ${firstItem.ApplicationTime}</p> <!-- 显示日期和时间 -->
+        <p class="card-text">公司:${firstItem.Company}</p>
+        <p class="card-text">项目信息:${firstItem.Project}</p>
+        <p class="card-text">创建者:${firstItem.Creator}</p>
+        <p class="card-text license-status ${statusClass}">许可证状态:${firstItem.LicenseFlage}</p>
+        <div class="license-info-card-buttons">
+            ${
+            firstItem.LicenseFlage === '已生成' && hasDispatchPermission
+                ? `<button class="license-info-modal-button" id="distributeButton">分发</button>`
+                : `<button class="license-info-modal-button" id="distributeButton" disabled style="background-color:#ccc;cursor:not-allowed;">分发</button>`
+            }
+            ${
+            firstItem.LicenseFlage !== '已生成' && hasGeneratePermission
+                ? `<button class="license-info-modal-button" id="generateOrDistribute">生成</button>`
+                : ''
+            }
+            <button class="license-info-modal-button" id="downloadAllLicenses-button">打包下载所有license.dat</button>
+            <button class="license-info-modal-button" id="viewDistributionHistory-button">查看分发历史</button>
+        </div>
+    </div>
+`;
+
+        // 绑定 generateOrDistribute 的点击事件(如果按钮存在)
+        const generateOrDistribute = modalHeader.querySelector('#generateOrDistribute');
+        if (generateOrDistribute) {
+            generateOrDistribute.addEventListener('click', () => {
+                if (firstItem.LicenseFlage === '已生成') {
+                    // 执行分发逻辑
+                    showDistributeModal(firstItem);
+                
+                } else {
+                    // 执行生成逻辑
+                    const oaRequestID = parseInt(firstItem.oa_request_id, 10);  // 10 表示10进制
+                 generateLicense(oaRequestID, true);
+                }
+                console.log('Button 1 clicked');
+            });
+        };
+
+        // 绑定分发按钮的点击事件
+        const distributeButton = modalHeader.querySelector('#distributeButton');
+        if (distributeButton && !distributeButton.disabled) {
+            distributeButton.addEventListener('click', () => {
+                showDistributeModal(firstItem);
+            });
+        }  
+          
+        //         // 在生成或分发按钮点击时,调用 showDistributeModal 函数
+        // generateOrDistribute.addEventListener('click', () => {
+        //     if (firstItem.LicenseFlage === '已生成') {
+        //         showDistributeModal(firstItem);  // 显示分发模态框
+        //     } else {
+        //         const oaRequestID = parseInt(firstItem.oa_request_id, 10);  // 生成许可证
+        //         generateLicense(oaRequestID, true);
+        //     }
+        // });
+
+
+
+        // 绑定 "打包下载所有license.dat" 按钮的点击事件
+        const downloadButton = modalHeader.querySelector('#downloadAllLicenses-button');
+
+        // 如果 LicenseFlage 是 "未生成" 或 "已失效",按钮变灰且不可点击
+        if (firstItem.LicenseFlage === '未生成' || firstItem.LicenseFlage === '已失效') {
+            downloadButton.disabled = true;
+            downloadButton.style.backgroundColor = '#ccc'; // 设置为灰色
+            downloadButton.style.cursor = 'not-allowed'; // 修改鼠标样式
+        } else {
+            // 只有当 LicenseFlage 是 "已生成" 时,才能点击下载按钮
+            downloadButton.addEventListener('click', () => {
+                downloadAllLicenses(sortedItem);
+            });
+        }
+   // 在初始化完成后绑定 "查看分发历史" 按钮的点击事件
+   const viewDistributionHistoryButton = document.getElementById('viewDistributionHistory-button');
+   if (viewDistributionHistoryButton) {
+       viewDistributionHistoryButton.addEventListener('click', () => {
+           showDistributionHistory(firstItem);
+       });
+   }
+
+    }
+
+
+    // 初始化下拉框的页码选项
+    function initializeDropdown() {
+            selectPageDropdown.innerHTML = ''; // 清空下拉框中的选项
+            for (let page = 1; page <= totalPages; page++) {
+                const option = document.createElement('option');
+                option.value = page;
+                option.innerText = `第 ${page} 页`;
+                selectPageDropdown.appendChild(option);
+            }
+            selectPageDropdown.value = currentPage; // 设置默认选项为当前页
+        }
+
+        // 渲染当前页内容
+    function ModalForCardRenderPage(page) {
+            modalBody.innerHTML = ''; // 清空之前的内容
+
+            // 计算当前页的起始和结束索引
+            const startIndex = (page - 1) * itemsPerPage;
+            const endIndex = Math.min(startIndex + itemsPerPage, sortedItem.length);
+
+            // 更新上半部分的字段内容 (以第一个元素为例)
+            const firstItem = sortedItem[0];
+            initializeHeaderContent(firstItem,sortedItem); // 动态生成上半部分内容
+
+            // 遍历当前页的数据
+            for (let i = startIndex; i < endIndex; i++) {
+                const group = sortedItem[i];
+                const groupBox = document.createElement('div');
+                groupBox.classList.add('license-info-group-box');
+
+                // 动态生成组内容,显示编号为 i+1(表示组1, 组2...)
+                groupBox.innerHTML = `
+                    <div class="license-info-group-title">集群 ${i + 1} :</div>
+
+                    <p><strong>节点数:</strong> ${group.NodeCount}</p>
+                    <p><strong>数据库版本: </strong> ${group.ProductName}${group.ProductVersion}</p>
+                    <p><strong>CPU 型号:</strong> ${group.oa_cpu}</p>
+                    <p><strong>操作系统环境:</strong> ${group.oa_operating_system}</p>
+                    <p><strong>以下为测试显示:</strong> </p>
+                    <p><strong>oa_id:</strong> ${group.oa_id}</p>
+                    <p><strong>oa_request_id:</strong> ${group.oa_request_id}</p>
+                `;
+
+                // 将生成的组内容加入到 modalBody
+                modalBody.appendChild(groupBox);
+            }
+
+            // 更新下拉框的值
+            selectPageDropdown.value = page;
+
+            // 更新按钮状态
+            prevButton.disabled = (page === 1);
+            nextButton.disabled = (page === totalPages);
+    }
+
+    // 下拉框页码选择事件
+    selectPageDropdown.addEventListener('change', function() {
+            currentPage = parseInt(this.value);
+            ModalForCardRenderPage(currentPage); // 根据选择的页码渲染对应页面
+    });
+
+    // 上一页按钮点击事件
+    prevButton.addEventListener('click', function() {
+            if (currentPage > 1) {
+                currentPage--;
+                ModalForCardRenderPage(currentPage);
+            }
+    });
+
+        // 下一页按钮点击事件
+    nextButton.addEventListener('click', function() {
+            if (currentPage < totalPages) {
+                currentPage++;
+                ModalForCardRenderPage(currentPage);
+            }
+    });
+
+    // 显示或隐藏分页相关控件
+    function togglePaginationVisibility() {
+            if (totalPages <= 1) {
+                // 隐藏下拉框和分页容器
+                paginationContainer.style.display = 'none';
+            } else {
+                // 显示下拉框和分页容器
+                paginationContainer.style.display = 'flex';
+            }
+    }
+
+    // 初始化下拉框并渲染第一页
+    initializeDropdown();
+    // 渲染模态框内容
+    ModalForCardRenderPage(currentPage);
+    // 根据页数决定是否显示分页控件
+    togglePaginationVisibility();
+
+        // 显示模态框
+    modal.style.display = 'flex'; // 显示模态框背景
+        setTimeout(() => {
+            modalContent.classList.add('show'); // 添加动画效果
+        }, 10); // 延时确保动画生效
+
+    // 关闭模态框逻辑
+    const closeModal = document.querySelector('.license-info-close');
+        closeModal.addEventListener('click', () => {
+            modalContent.classList.remove('show'); // 移除动画类
+            setTimeout(() => {
+                modal.style.display = 'none'; // 完全隐藏模态框
+            }, 500); // 等待动画结束后再隐藏
+        });
+
+    // 点击模态框外部关闭模态框
+    window.addEventListener('click', (event) => {
+            if (event.target === modal) {
+                modalContent.classList.remove('show');
+                setTimeout(() => {
+                    modal.style.display = 'none'; // 完全隐藏模态框
+                }, 500); // 等待动画结束后再隐藏
+            }
+        });
+}
+
+//-------下载全部licstr按钮
+// 下载许可证功能
+function downloadAllLicenses(sortedApplicationArray) {
+    const zip = new JSZip();
+    console.log("传进来的 sortedApplicationArray:", sortedApplicationArray);
+
+    // 初始化计数器,从1开始
+    let idCounter = 1;
+    let Project = sortedApplicationArray[0].Project;
+    console.log("Project", Project);
+
+    // 遍历 sortedApplicationArray,下载 lic1 和 lic2 数据
+    sortedApplicationArray.forEach(row => {
+        if (row.LicenseFlage === "已生成") {
+            // 替换 oa_main_mac 和 oa_second_mac 中的冒号为点
+            const mainMac = row.oa_main_mac.replace(/:/g, '.');
+            const secondMac = row.oa_second_mac.replace(/:/g, '.');
+
+            // 使用递增的 idCounter 替换 row.oa_id
+            if (row.lic1) {
+                const filename1 = `${idCounter}_license.dat_1_${mainMac}`;
+                zip.file(filename1, row.lic1);
+            }
+            if (row.lic2) {
+                const filename2 = `${idCounter}_license.dat_2_${secondMac}`;
+                zip.file(filename2, row.lic2);
+            }
+
+            // 每次循环后递增计数器
+            idCounter++;
+        }
+    });
+
+    // 生成 ZIP 文件并触发下载
+    zip.generateAsync({ type: "blob" }).then(content => {
+        const link = document.createElement('a');
+        link.href = URL.createObjectURL(content);
+        link.download = `${Project}_license.zip`;
+        link.click();
+    });
+}
+
+
+
+
+
+
+// 刷新数据并滚动到目标卡片的函数
+// 刷新数据并滚动到目标卡片,同时重新打开目标卡片的模态框
+async function refreshLicenseDataAndScrollAndOpenModal(selfPage,selfPageSize, targetCardId) {
+    const data = await fetchLicenseData(selfPage, selfPageSize);
+    if (data.length > 0) {
+        isLoading = true;
+        console.log('加载的数据:', data); // 检查是否成功获取数据
+        renderLicenseCards(data, true); // 渲染数据到页面并清空之前的内容
+        page = selfPageSize+1;
+        pageSize= selfPageSize +10;
+
+        // 滚动到目标卡片
+        if (targetCardId) {
+            const targetCard = document.querySelector(`[data-oa-request-id="${targetCardId}"]`);
+            if (targetCard) {
+                targetCard.scrollIntoView({ behavior: 'smooth', block: 'center' });
+                
+                // 延迟打开模态框,确保页面滚动完成
+                setTimeout(() => {
+                    targetCard.click(); // 模拟点击卡片,触发模态框
+                }, 500); // 延时500ms确保滚动完成
+            }
+        }
+
+        
+         setTimeout(() => {
+            isLoading = false;
+        }, 2000); 
+     
+    } else {
+        console.error('未加载到数据');
+    }
+}
+
+
+
+
+
+function generateLicense(id, isParentRow) {
+        // 显示加载进度条并设置动态提示信息
+        showLoadingModal('正在生成 License...');
+   // const payload = isParentRow ? { oa_request_id: JSON.stringify(id) } : { uniqueID:JSON.stringify(id) };
+   const payload = isParentRow 
+   ? { oa_request_id: parseInt(id, 10) }  // 将 id 转换为整数
+   : { uniqueID: parseInt(id, 10) };  // 将 id 转换为整数
+
+    console.log("generateLicense",payload ,id, isParentRow)
+    fetch('http://127.0.0.1:8080/api/admin/GenerateLicense', {
+        method: 'POST',
+        headers: {
+            'Authorization': `Bearer ${authToken}`,
+            'Content-Type': 'application/json'
+        },
+        body: JSON.stringify(payload)
+    })
+    .then(response => response.json())
+    .then(data => {
+        if (data.success) {
+          // 隐藏加载进度条
+                hideLoadingModal();
+                alert('License 生成成功!');
+            //刷新页面
+                 // 调用封装的更新方法
+            updateCardAndModalStatus(id, isParentRow);
+            // 调用刷新函数,传入当前的 page 和 pageSize
+            refreshLicenseDataAndScrollAndOpenModal(1,pageSize,id);
+            } else {
+                    // 请求失败时隐藏加载进度条
+                hideLoadingModal();
+                alert('License 生成失败:' + data.error);
+            }
+            
+    })
+    .catch(error => {
+        console.error('生成过程中出现错误Error:', error);
+     // 请求失败时隐藏加载进度条
+     hideLoadingModal();
+        alert('生成过程中出现错误,请稍后再试。',error);
+    });
+}
+
+
+//更新卡片样式
+function updateCardAndModalStatus(id, isParentRow) {
+    // 获取对应的卡片元素,通过 oa_request_id 或 uniqueID 定位
+    const cardSelector = isParentRow ? `[data-oa-request-id="${id}"]` : `[data-unique-id="${id}"]`;
+    const card = document.querySelector(cardSelector);
+    console.log("generateLicense card", cardSelector, card);
+    
+    if (card) {
+        // 1. 更新卡片内许可证状态
+        const statusElement = card.querySelector('.license-status');
+        console.log("statusElement:", statusElement); // 检查状态元素是否存在
+        
+        if (statusElement) {
+            // 只更新许可证状态部分的文本,而不是整个 p 标签
+            statusElement.innerHTML = '许可证状态:已生成';
+            
+            // 更新状态的 CSS 类
+            statusElement.classList.remove('license-status-yellow', 'license-status-red');
+            statusElement.classList.add('license-status-green');
+        } else {
+            console.error('找不到 .license-status 元素');
+        }
+
+        // 2. 更新模态框中的状态(如果模态框已经打开)
+        const modalStatusElement = document.querySelector('.license-info-modal-header .license-status');
+        console.log("modalStatusElement:", modalStatusElement); // 检查状态元素是否存在
+        
+        if (modalStatusElement) {
+            modalStatusElement.textContent = '许可证状态:已生成';
+            modalStatusElement.classList.remove('license-status-yellow', 'license-status-red');
+            modalStatusElement.classList.add('license-status-green');
+        } else {
+            console.error('找不到 #license-info-modal-body .license-status 元素');
+        }
+
+        // 3. 更新模态框中的按钮为“分发”
+        const generateButton = document.getElementById('button1'); // 获取生成按钮
+        if (generateButton) {
+            generateButton.textContent = '分发'; // 修改按钮文本为“分发”
+            generateButton.removeEventListener('click', generateLicense); // 移除生成逻辑
+            generateButton.addEventListener('click', () => {
+                distributeLicense(id); // 添加分发逻辑
+            });
+        }
+
+        // 4. 启用 #downloadAllLicenses-button
+        const downloadButton = document.getElementById('downloadAllLicenses-button');
+        if (downloadButton) {
+            downloadButton.disabled = false; // 启用按钮
+            downloadButton.style.backgroundColor = '#007aff'; // 恢复正常的背景颜色
+            downloadButton.style.cursor = 'pointer'; // 修改鼠标样式为可点击
+        }
+
+    } else {
+        console.error(`找不到与 ID ${id} 对应的卡片`);
+    }
+}