首页
关于
友链
推荐
肥啾解析
百度一下
肥啾GPT
Search
1
宝塔面板登录 phpMyAdmin 提示服务器和客户端上指示的HTTPS之间不匹配
274 阅读
2
Customer complaints evolve with in-car tech
188 阅读
3
JavaScript解析
153 阅读
4
内连接,左连接,右连接作用及区别
112 阅读
5
所谓关系
109 阅读
默认分类
网游架设
手机游戏
python
PHP
Mysql
VBA
C++
JAVASCRIPT
javascript基础
Oracle
生产管理
计划控制
ERP系统开发
APS排产
MES研究
考勤系统
CPA
财管
实务
经济法
战略
审计
税法
藏书架
古典名著
世界名著
编程秘籍
攻防渗透
经管书籍
大佬传经
风雅读物
考试相关
心情格言
拾玉良言
外文报刊
外刊随选
Facebook
Twitter
China Daily
软考
登录
Search
标签搜索
期刊读物
古文
何瑜明
累计撰写
178
篇文章
累计收到
154
条评论
首页
栏目
默认分类
网游架设
手机游戏
python
PHP
Mysql
VBA
C++
JAVASCRIPT
javascript基础
Oracle
生产管理
计划控制
ERP系统开发
APS排产
MES研究
考勤系统
CPA
财管
实务
经济法
战略
审计
税法
藏书架
古典名著
世界名著
编程秘籍
攻防渗透
经管书籍
大佬传经
风雅读物
考试相关
心情格言
拾玉良言
外文报刊
外刊随选
Facebook
Twitter
China Daily
软考
页面
关于
友链
推荐
肥啾解析
百度一下
肥啾GPT
搜索到
31
篇与
的结果
2025-07-04
字符串核对
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>字符串比较工具</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background: linear-gradient(135deg, #8e8f93fc 100%, #8e8f93fc 100%); color: #333; min-height: 100vh; padding: 20px; display: flex; justify-content: center; align-items: center; } .container { width: 100%; max-width: 800px; background-color: white; border-radius: 15px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); overflow: hidden; } header { background: linear-gradient(to right, #514d4d, #514d4d); color: white; padding: 25px 30px; text-align: center; } h1 { font-size: 28px; margin-bottom: 8px; } .subtitle { font-size: 16px; opacity: 0.9; max-width: 600px; margin: 0 auto; } .content { padding: 30px; } .input-group { margin-bottom: 25px; } label { display: block; font-weight: 600; margin-bottom: 10px; color: #2c3e50; font-size: 18px; } textarea { width: 100%; height: 120px; padding: 15px; border: 2px solid #ddd; border-radius: 8px; font-size: 16px; resize: vertical; transition: border-color 0.3s; } textarea:focus { border-color: #3498db; outline: none; box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.2); } .example { background-color: #f8f9fa; border-left: 4px solid #3498db; padding: 12px 15px; margin-top: 8px; border-radius: 0 4px 4px 0; font-size: 14px; } .example-title { font-weight: bold; margin-bottom: 5px; color: #2c3e50; } .actions { display: flex; justify-content: center; gap: 15px; margin-top: 20px; } button { padding: 14px 28px; font-size: 17px; border: none; border-radius: 8px; cursor: pointer; font-weight: 600; transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; } .compare-btn { background: linear-gradient(to right, #35c1a9, #35c1a9); color: white; flex: 1; } .clear-btn { background: #514d4d; color: white; } button:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); } button:active { transform: translateY(0); } .compare-btn:hover { background: linear-gradient(to right, #009a87, #85b536); } .clear-btn:hover { background: #c0392b; } .result-container { margin-top: 30px; padding: 25px; border-radius: 10px; display: none; } .result-title { font-size: 20px; font-weight: bold; margin-bottom: 15px; display: flex; align-items: center; } .result-content { padding: 15px; border-radius: 8px; margin-top: 10px; font-size: 16px; line-height: 1.6; } .success { background-color: rgba(46, 204, 113, 0.1); border: 1px solid #2ecc71; color: #27ae60; } .error { background-color: rgba(231, 76, 60, 0.1); border: 1px solid #e74c3c; color: #c0392b; } .icon { margin-right: 10px; font-size: 24px; } .requirements { background-color: #f8f9fa; border-radius: 10px; padding: 20px; margin-top: 25px; } .requirements h3 { color: #2c3e50; margin-bottom: 15px; display: flex; align-items: center; } .requirements ul { padding-left: 20px; } .requirements li { margin-bottom: 10px; line-height: 1.5; } footer { text-align: center; padding: 20px; color: #7f8c8d; font-size: 14px; border-top: 1px solid #eee; } @media (max-width: 600px) { .content { padding: 20px; } h1 { font-size: 24px; } .actions { flex-direction: column; } } </style> </head> <body> <div class="container"> <header> <h1>字符串比较工具</h1> <p class="subtitle">验证格式并比较两个字符串 - 检查第二个字符串是否是第一个字符串的子集</p> </header> <div class="content"> <div class="input-group"> <label for="str1">第一个字符串 (蓝本):</label> <textarea id="str1" placeholder="请输入第一个字符串,使用英文逗号分隔各项">3SV,实心胎(进口品牌),闪光警示灯,丰田样式悬浮座椅,高挂预滤器,高排气,VM330,3AP</textarea> </div> <div class="input-group"> <label for="str2">第二个字符串 (待比较):</label> <textarea id="str2" placeholder="请输入第二个字符串,使用英文逗号分隔各项">3SV,实心胎(进口品牌),闪光警示灯,丰田样式悬浮座椅,高挂预滤器,高排气</textarea> </div> <div class="actions"> <button class="compare-btn" onclick="compareStrings()"> <span class="icon">✓</span> 比较字符串 </button> <button class="clear-btn" onclick="clearInputs()"> <span class="icon">✕</span> 清空 </button> </div> <div id="result-container" class="result-container"> <div class="result-title"> <span class="icon" id="result-icon">?</span> <span id="result-title">结果</span> </div> <div id="result-content" class="result-content"></div> </div> <div class="requirements"> <h3>字符串要求</h3> <ul> <li>只能使用<strong>英文逗号</strong>作为分隔符(不允许中文逗号)</li> <li>字符串中<strong>不允许包含任何空格</strong></li> <li>第二个字符串必须是第一个字符串的<strong>子集</strong></li> <li>所有元素必须<strong>完全匹配</strong>(包括大小写和特殊字符)</li> <li>元素顺序<strong>不影响</strong>比较结果</li> </ul> </div> </div> </div> <script> function compareStrings() { const str1 = document.getElementById('str1').value.trim(); const str2 = document.getElementById('str2').value.trim(); const resultContainer = document.getElementById('result-container'); const resultContent = document.getElementById('result-content'); const resultTitle = document.getElementById('result-title'); const resultIcon = document.getElementById('result-icon'); // 清空之前的结果 resultContainer.style.display = 'none'; // 验证字符串1 const validation1 = validateString(str1, "第一个字符串"); if (!validation1.isValid) { showError(validation1.message, resultContainer, resultContent, resultTitle, resultIcon); return; } // 验证字符串2 const validation2 = validateString(str2, "第二个字符串"); if (!validation2.isValid) { showError(validation2.message, resultContainer, resultContent, resultTitle, resultIcon); return; } // 获取元素数组 const arr1 = str1.split(','); const arr2 = str2.split(','); // 检查第二个字符串是否是第一个字符串的子集 const missingElements = []; for (const element of arr2) { if (!arr1.includes(element)) { missingElements.push(element); } } // 检查结果并显示 if (missingElements.length === 0) { showSuccess("验证通过!第二个字符串是第一个字符串的子集。", resultContainer, resultContent, resultTitle, resultIcon); } else { showError(`第二个字符串包含第一个字符串中没有的元素:${missingElements.join(', ')}`, resultContainer, resultContent, resultTitle, resultIcon); } } function validateString(str, strName) { // 检查是否为空 if (str === '') { return { isValid: false, message: `${strName}不能为空!` }; } // 检查是否包含空格 if (/\s/.test(str)) { return { isValid: false, message: `${strName}包含空格!请移除所有空格。` }; } // 检查是否包含中文逗号 if (str.includes(',')) { return { isValid: false, message: `${strName}包含中文逗号!请使用英文逗号(,)。` }; } // 检查其他非法符号(只允许中文字符、英文字母、数字、英文逗号和括号) const illegalChars = str.match(/[^\u4e00-\u9fa5a-zA-Z0-9,()]/g); if (illegalChars && illegalChars.length > 0) { const uniqueChars = [...new Set(illegalChars)]; return { isValid: false, message: `${strName}包含非法字符:${uniqueChars.join('')}` }; } // 检查连续逗号或开头/结尾逗号 if (str.startsWith(',') || str.endsWith(',') || str.includes(',,')) { return { isValid: false, message: `${strName}格式错误:存在连续逗号或开头/结尾逗号` }; } return { isValid: true }; } function showError(message, container, content, title, icon) { container.style.display = 'block'; container.classList.remove('success'); container.classList.add('error'); content.innerHTML = message; title.textContent = '验证失败'; icon.textContent = '✕'; container.scrollIntoView({ behavior: 'smooth' }); } function showSuccess(message, container, content, title, icon) { container.style.display = 'block'; container.classList.remove('error'); container.classList.add('success'); content.innerHTML = message; title.textContent = '验证通过'; icon.textContent = '✓'; container.scrollIntoView({ behavior: 'smooth' }); } function clearInputs() { document.getElementById('str1').value = ''; document.getElementById('str2').value = ''; document.getElementById('result-container').style.display = 'none'; } </script> </body> </html>
2025年07月04日
6 阅读
0 评论
0 点赞
2025-06-26
图例管理
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>服务器图例管理系统</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } :root { --primary: #4361ee; --primary-dark: #3a56d4; --secondary: #3f37c9; --accent: #4895ef; --light: #f8f9fa; --dark: #212529; --gray: #6c757d; --light-gray: #e9ecef; --success: #4cc9f0; --warning: #f72585; --border-radius: 8px; --shadow: 0 4px 6px rgba(0, 0, 0, 0.1); --transition: all 0.3s ease; } body { background: linear-gradient(135deg, #f0f4f8 0%, #e2e8f0 100%); color: var(--dark); min-height: 100vh; padding: 20px; } .container { max-width: 1400px; margin: 0 auto; } /* 头部样式 */ header { background: white; border-radius: var(--border-radius); padding: 15px 25px; margin-bottom: 25px; box-shadow: var(--shadow); display: flex; align-items: center; flex-wrap: wrap; gap: 15px; } .logo { display: flex; align-items: center; font-size: 1.8rem; font-weight: bold; color: var(--primary); } .logo i { margin-right: 15px; font-size: 2.2rem; } .search-container { flex: 1; min-width: 300px; position: relative; } .search-container input { width: 100%; padding: 12px 15px 12px 45px; border-radius: 30px; border: 2px solid var(--light-gray); background: white; color: var(--dark); font-size: 1rem; transition: var(--transition); } .search-container input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.2); } .search-container i { position: absolute; left: 18px; top: 50%; transform: translateY(-50%); color: var(--gray); font-size: 1.2rem; } .header-controls { display: flex; gap: 15px; flex-wrap: wrap; } .btn { padding: 10px 20px; border-radius: 30px; border: none; background: var(--light); color: var(--dark); font-weight: 600; cursor: pointer; display: flex; align-items: center; gap: 8px; transition: var(--transition); box-shadow: var(--shadow); } .btn:hover { transform: translateY(-2px); box-shadow: 0 6px 10px rgba(0, 0, 0, 0.1); } .btn-primary { background: var(--primary); color: white; } .btn-primary:hover { background: var(--primary-dark); } /* 目录生成区 */ .directory-section { background: white; border-radius: var(--border-radius); padding: 25px; margin-bottom: 25px; box-shadow: var(--shadow); } .directory-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; flex-wrap: wrap; gap: 15px; } .directory-header h2 { color: var(--dark); font-weight: 600; } .directory-controls { display: flex; gap: 15px; } .folder-info { display: flex; align-items: center; gap: 15px; background: var(--light); padding: 15px; border-radius: var(--border-radius); margin-bottom: 20px; } .folder-info i { color: var(--primary); font-size: 1.5rem; } .folder-details { flex: 1; } .folder-details h3 { margin-bottom: 5px; } .folder-details p { color: var(--gray); font-size: 0.9rem; } .directory-tree { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 15px; } .tree-category { background: var(--light); border-radius: var(--border-radius); padding: 15px; transition: var(--transition); cursor: pointer; } .tree-category:hover { background: rgba(67, 97, 238, 0.1); } .tree-category h3 { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; color: var(--primary); } .tree-category h3 i { font-size: 1.2rem; } .tree-items { padding-left: 25px; } .tree-item { padding: 8px 0; display: flex; align-items: center; gap: 8px; color: var(--gray); } .tree-item i { font-size: 0.9rem; color: var(--accent); } /* 图例展示区 */ .legends-section { background: white; border-radius: var(--border-radius); padding: 25px; box-shadow: var(--shadow); } .legends-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; flex-wrap: wrap; gap: 15px; } .view-controls { display: flex; gap: 12px; } .view-btn { width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--light-gray); background: white; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: var(--transition); } .view-btn:hover, .view-btn.active { background: var(--primary); color: white; border-color: var(--primary); } .legend-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 25px; } .legend-card { background: white; border-radius: var(--border-radius); overflow: hidden; box-shadow: var(--shadow); transition: var(--transition); cursor: pointer; display: flex; flex-direction: column; border: 1px solid var(--light-gray); } .legend-card:hover { transform: translateY(-8px); box-shadow: 0 12px 20px rgba(0, 0, 0, 0.15); border-color: var(--accent); } .card-img { height: 180px; background: var(--light-gray); display: flex; align-items: center; justify-content: center; overflow: hidden; position: relative; } .card-img img { width: 100%; height: 100%; object-fit: cover; transition: var(--transition); } .legend-card:hover .card-img img { transform: scale(1.05); } .zoom-btn { position: absolute; bottom: 12px; right: 12px; width: 36px; height: 36px; border-radius: 50%; background: rgba(255, 255, 255, 0.9); color: var(--dark); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: var(--transition); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); } .zoom-btn:hover { background: var(--primary); color: white; transform: scale(1.1); } .card-content { padding: 18px; flex: 1; display: flex; flex-direction: column; } .card-content h4 { margin-bottom: 8px; font-weight: 600; color: var(--dark); } .card-content p { font-size: 0.9rem; color: var(--gray); line-height: 1.5; flex: 1; } .file-info { display: flex; justify-content: space-between; margin-top: 12px; font-size: 0.8rem; color: var(--gray); } /* 响应式设计 */ @media (max-width: 992px) { header { flex-direction: column; gap: 20px; } .search-container { min-width: 100%; margin: 0; } .header-controls { width: 100%; justify-content: center; } .directory-tree { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); } } @media (max-width: 768px) { .legend-grid { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); } .directory-tree { grid-template-columns: 1fr; } } @media (max-width: 480px) { .legend-grid { grid-template-columns: 1fr; } .header-controls { flex-direction: column; } .btn { width: 100%; justify-content: center; } .directory-controls { flex-direction: column; } } /* 大图模态框 */ .modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.9); z-index: 1000; justify-content: center; align-items: center; } .modal-content { max-width: 90%; max-height: 90%; position: relative; } .modal-content img { max-width: 100%; max-height: 80vh; border: 3px solid white; border-radius: 8px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5); } .close-modal { position: absolute; top: 20px; right: 30px; color: white; font-size: 40px; cursor: pointer; transition: var(--transition); } .close-modal:hover { color: var(--accent); } .image-info { color: white; text-align: center; margin-top: 15px; font-size: 1.2rem; } /* 加载动画 */ .loader { display: flex; justify-content: center; padding: 40px 0; } .loader .spinner { width: 50px; height: 50px; border: 5px solid var(--light-gray); border-top: 5px solid var(--primary); border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } /* 空状态 */ .empty-state { text-align: center; padding: 40px 0; color: var(--gray); grid-column: 1 / -1; } .empty-state i { font-size: 3rem; margin-bottom: 20px; opacity: 0.5; } .notification { position: fixed; bottom: 20px; right: 20px; background: var(--primary); color: white; padding: 15px 25px; border-radius: 8px; box-shadow: 0 5px 15px rgba(0,0,0,0.2); z-index: 1000; animation: fadeInOut 3s ease-in-out; display: none; } @keyframes fadeInOut { 0% { opacity: 0; transform: translateY(20px); } 10% { opacity: 1; transform: translateY(0); } 90% { opacity: 1; transform: translateY(0); } 100% { opacity: 0; transform: translateY(20px); } } </style> </head> <body> <div class="container"> <!-- 头部区域 --> <header> <div class="logo"> <i class="fas fa-map-marked-alt"></i> <span>服务器图例管理系统</span> </div> <div class="search-container"> <i class="fas fa-search"></i> <input type="text" id="searchInput" placeholder="搜索图例..."> </div> <div class="header-controls"> <button class="btn" id="refreshBtn"> <i class="fas fa-sync-alt"></i> 刷新图例 </button> <button class="btn btn-primary" id="generateCatalogBtn"> <i class="fas fa-folder-plus"></i> 生成目录 </button> </div> </header> <!-- 目录生成区 --> <section class="directory-section"> <div class="directory-header"> <h2><i class="fas fa-folder-tree"></i> 服务器图例目录</h2> <div class="directory-controls"> <div class="btn" id="expandAllBtn"> <i class="fas fa-expand"></i> 展开所有 </div> <div class="btn" id="collapseAllBtn"> <i class="fas fa-compress"></i> 折叠所有 </div> </div> </div> <div class="folder-info"> <i class="fas fa-folder-open"></i> <div class="folder-details"> <h3>服务器图片目录</h3> <p>路径: <span id="folderPath">./img</span> | 最后更新: <span id="lastUpdate">正在获取...</span></p> </div> </div> <div class="directory-tree" id="directoryTree"> <div class="loader"> <div class="spinner"></div> </div> </div> </section> <!-- 图例展示区 --> <section class="legends-section"> <div class="legends-header"> <h2><i class="fas fa-images"></i> 图例展示 (<span id="imageCount">0</span> 个图例)</h2> <div class="view-controls"> <div class="view-btn active" title="网格视图"> <i class="fas fa-th"></i> </div> <div class="view-btn" title="列表视图"> <i class="fas fa-list"></i> </div> <div class="view-btn" title="放大"> <i class="fas fa-search-plus"></i> </div> <div class="view-btn" title="缩小"> <i class="fas fa-search-minus"></i> </div> </div> </div> <div class="legend-grid" id="legendGrid"> <div class="loader"> <div class="spinner"></div> </div> </div> </section> </div> <!-- 大图模态框 --> <div class="modal" id="imageModal"> <span class="close-modal" id="closeModal">×</span> <div class="modal-content"> <img id="modalImage" src="" alt="大图预览"> <div class="image-info" id="imageInfo"></div> </div> </div> <!-- 通知区域 --> <div class="notification" id="notification"></div> <script> // 获取服务器图片的函数 async function getServerImages() { try { // 显示加载状态 document.getElementById('legendGrid').innerHTML = ` <div class="loader"> <div class="spinner"></div> </div> `; // 调用后端API获取图片数据 const response = await fetch('get_images.php'); if (!response.ok) { throw new Error('获取图片数据失败'); } const data = await response.json(); // 更新最后更新时间 document.getElementById('lastUpdate').textContent = data.last_updated; // 更新图片数量 document.getElementById('imageCount').textContent = data.images.length; // 渲染图片到页面 renderImages(data.images); // 生成目录树 generateDirectoryTree(data.categories); // 显示文件夹路径 document.getElementById('folderPath').textContent = data.folder_path; } catch (error) { console.error('获取图片数据时出错:', error); document.getElementById('legendGrid').innerHTML = ` <div class="empty-state"> <i class="fas fa-exclamation-triangle"></i> <h3>无法加载图片</h3> <p>${error.message}</p> <button class="btn" id="retryBtn" style="margin-top: 15px;"> <i class="fas fa-redo"></i> 重试 </button> </div> `; document.getElementById('retryBtn').addEventListener('click', getServerImages); } } // 渲染图片到页面 function renderImages(images) { const grid = document.getElementById('legendGrid'); if (images.length === 0) { grid.innerHTML = ` <div class="empty-state"> <i class="fas fa-folder-open"></i> <h3>没有找到图片</h3> <p>请检查服务器上的图片文件夹</p> </div> `; return; } grid.innerHTML = ''; images.forEach(image => { const card = document.createElement('div'); card.className = 'legend-card'; card.innerHTML = ` <div class="card-img"> <img src="${image.path}" alt="${image.name}"> <div class="zoom-btn" data-image="${image.path}" data-name="${image.name}"> <i class="fas fa-search-plus"></i> </div> </div> <div class="card-content"> <h4>${image.name}</h4> <p>${image.description}</p> <div class="file-info"> <span>${image.size}</span> <span>${image.date}</span> </div> </div> `; grid.appendChild(card); }); // 绑定放大按钮事件 document.querySelectorAll('.zoom-btn').forEach(btn => { btn.addEventListener('click', function(e) { e.stopPropagation(); const imageUrl = this.getAttribute('data-image'); const imageName = this.getAttribute('data-name'); showImageModal(imageUrl, imageName); }); }); } // 生成目录树 function generateDirectoryTree(categories) { const treeContainer = document.getElementById('directoryTree'); if (!categories || categories.length === 0) { treeContainer.innerHTML = ` <div class="empty-state"> <i class="fas fa-exclamation-circle"></i> <h3>没有目录数据</h3> <p>点击"生成目录"按钮创建目录</p> </div> `; return; } treeContainer.innerHTML = ''; categories.forEach(category => { const categoryElement = document.createElement('div'); categoryElement.className = 'tree-category'; categoryElement.innerHTML = ` <h3><i class="${category.icon}"></i> ${category.name} (${category.count})</h3> <div class="tree-items"> ${category.items.map(item => ` <div class="tree-item"> <i class="fas fa-file-image"></i> ${item} </div> `).join('')} </div> `; treeContainer.appendChild(categoryElement); }); } // 显示大图模态框 function showImageModal(imageUrl, imageName) { const modal = document.getElementById('imageModal'); const modalImg = document.getElementById('modalImage'); const imageInfo = document.getElementById('imageInfo'); modalImg.src = imageUrl; modalImg.alt = imageName; imageInfo.textContent = imageName; modal.style.display = 'flex'; } // 显示通知 function showNotification(message) { const notification = document.getElementById('notification'); notification.textContent = message; notification.style.display = 'block'; setTimeout(() => { notification.style.display = 'none'; }, 3000); } // 页面加载完成后初始化 document.addEventListener('DOMContentLoaded', function() { // 加载服务器图片 getServerImages(); // 刷新按钮事件 document.getElementById('refreshBtn').addEventListener('click', getServerImages); // 生成目录按钮事件 document.getElementById('generateCatalogBtn').addEventListener('click', function() { // 在实际应用中,这里会调用后端生成目录的API showNotification('目录已重新生成!'); // 模拟重新加载数据 setTimeout(() => { getServerImages(); }, 1000); }); // 关闭模态框 document.getElementById('closeModal').addEventListener('click', function() { document.getElementById('imageModal').style.display = 'none'; }); // 搜索功能 document.getElementById('searchInput').addEventListener('input', function(e) { const searchTerm = e.target.value.toLowerCase(); filterLegends(searchTerm); }); // 展开所有目录 document.getElementById('expandAllBtn').addEventListener('click', function() { // 实际应用中应展开所有目录项 showNotification('已展开所有目录'); }); // 折叠所有目录 document.getElementById('collapseAllBtn').addEventListener('click', function() { // 实际应用中应折叠所有目录项 showNotification('已折叠所有目录'); }); }); // 过滤图例 function filterLegends(searchTerm) { const cards = document.querySelectorAll('.legend-card'); let visibleCount = 0; cards.forEach(card => { const title = card.querySelector('h4').textContent.toLowerCase(); const description = card.querySelector('p').textContent.toLowerCase(); if (title.includes(searchTerm) || description.includes(searchTerm)) { card.style.display = ''; visibleCount++; } else { card.style.display = 'none'; } }); // 更新计数 document.getElementById('imageCount').textContent = visibleCount; } </script> </body> </html><?php // 设置响应头为JSON格式 header('Content-Type: application/json'); // 图片文件夹路径(相对于此PHP文件的路径) $imgFolder = './img'; // 获取最后更新时间 $lastUpdated = date("Y-m-d H:i:s", filemtime($imgFolder)); // 获取文件夹路径 $folderPath = realpath($imgFolder); // 扫描文件夹获取图片文件 $imageFiles = []; $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; if (is_dir($imgFolder)) { $files = scandir($imgFolder); foreach ($files as $file) { if ($file != '.' && $file != '..') { $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION)); if (in_array($extension, $allowedExtensions)) { $imageFiles[] = $file; } } } } // 构建图片数据 $images = []; foreach ($imageFiles as $index => $file) { $filePath = $imgFolder . '/' . $file; $fileSize = filesize($filePath); $fileDate = date("Y-m-d", filemtime($filePath)); // 生成友好的文件大小显示 $sizeFormatted = formatFileSize($fileSize); // 获取不带扩展名的文件名 $fileName = pathinfo($file, PATHINFO_FILENAME); $images[] = [ 'id' => $index + 1, 'name' => $fileName, 'path' => $filePath, 'description' => getDescription($fileName), 'size' => $sizeFormatted, 'date' => $fileDate, 'category' => getCategory($fileName) ]; } // 生成目录结构 $categories = [ [ 'name' => '地形地貌', 'icon' => 'fas fa-mountain', 'count' => count(array_filter($images, function($img) { return strpos($img['category'], '地形地貌') !== false; })), 'items' => ['地形等高线', '地貌分类', '高程图'] ], [ 'name' => '交通网络', 'icon' => 'fas fa-road', 'count' => count(array_filter($images, function($img) { return strpos($img['category'], '交通网络') !== false; })), 'items' => ['主要公路', '铁路网络', '机场位置'] ], [ 'name' => '自然地理', 'icon' => 'fas fa-water', 'count' => count(array_filter($images, function($img) { return strpos($img['category'], '自然地理') !== false; })), 'items' => ['水系分布', '地质构造', '土壤类型'] ], [ 'name' => '植被生态', 'icon' => 'fas fa-tree', 'count' => count(array_filter($images, function($img) { return strpos($img['category'], '植被生态') !== false; })), 'items' => ['森林覆盖', '草地分布', '植被类型'] ], [ 'name' => '人文地理', 'icon' => 'fas fa-city', 'count' => count(array_filter($images, function($img) { return strpos($img['category'], '人文地理') !== false; })), 'items' => ['城市区域', '工业区域', '居民点分布'] ] ]; // 构建响应数据 $response = [ 'status' => 'success', 'folder_path' => $folderPath, 'last_updated' => $lastUpdated, 'image_count' => count($images), 'images' => $images, 'categories' => $categories ]; // 输出JSON响应 echo json_encode($response); // 辅助函数:格式化文件大小 function formatFileSize($bytes) { if ($bytes >= 1048576) { return round($bytes / 1048576, 1) . ' MB'; } elseif ($bytes >= 1024) { return round($bytes / 1024, 1) . ' KB'; } else { return $bytes . ' bytes'; } } // 辅助函数:根据文件名生成描述 function getDescription($fileName) { $descriptions = [ '地形等高线' => '用于表示地形高度的等高线系统,间隔20米', '主要公路' => '国家级和省级主要公路交通网络', '水系分布' => '河流、湖泊、水库等水系分布图例', '森林覆盖' => '森林、灌木林、草地的植被覆盖分类', '城市区域' => '城市建成区、开发区、居民点分布', '工业区域' => '工厂、矿山、工业园区等分布', '降雨量分布' => '年平均降雨量分布图例(毫米)', '农业用地' => '农田、果园、养殖区等农业用地分类' ]; return $descriptions[$fileName] ?? $fileName . ' 图例,用于地图制作和地理信息系统分析'; } // 辅助函数:根据文件名分配类别 function getCategory($fileName) { $categories = [ '地形等高线' => '地形地貌', '地貌分类' => '地形地貌', '主要公路' => '交通网络', '铁路网络' => '交通网络', '水系分布' => '自然地理', '森林覆盖' => '植被生态', '城市区域' => '人文地理', '工业区域' => '人文地理', '降雨量分布' => '气候气象', '农业用地' => '土地利用' ]; return $categories[$fileName] ?? '其他'; } ?>
2025年06月26日
4 阅读
0 评论
0 点赞
2025-06-22
此内容被密码保护
加密文章,请前往内页查看详情
2025年06月22日
2 阅读
0 评论
0 点赞
2025-05-14
扫描文件逻辑
时区设置 date_default_timezone_set('Asia/Shanghai'); 将脚本时区设置为北京时间(东八区),确保所有时间相关函数返回中国时区的时间37。 安全配置 set_time_limit(1000); $allowed_extensions = ['pdf', 'jpg', 'jpeg', 'png']; 设置脚本最大执行时间为1000秒 定义允许处理的文件扩展名白名单 路径定义 $dataFilePath = __DIR__.'/data/files2.json'; $pdfBasePath = __DIR__.'/pdf2/'; 指定JSON输出文件路径 设置PDF文件存储根目录 目录创建 if (!file_exists(dirname($dataFilePath))) { mkdir(dirname($dataFilePath), 0755, true); } 递归创建JSON文件所需的目录结构(如果不存在) 核心扫描函数 function scanFiles($dir, &$result, $rootDir, $allowed) { // 扫描目录 $files = scandir($dir); foreach ($files as $file) { // 跳过特殊目录 if ($file === '.' || $file === '..') continue; $fullPath = $dir.'/'.$file; // 递归处理子目录 if (is_dir($fullPath)) { scanFiles($fullPath, $result, $rootDir, $allowed); continue; } // 文件名编码转换 $fileNameUTF8 = iconv('GBK', 'UTF-8//IGNORE', $file); $ext = strtolower(pathinfo($fileNameUTF8, PATHINFO_EXTENSION)); // 扩展名检查 if (!in_array($ext, $allowed)) continue; // 路径处理 $relativePath = substr($fullPath, strlen($rootDir) + 1); $relativePathUTF8 = iconv('GBK', 'UTF-8//IGNORE', $relativePath); // 构建文件信息数组 $result[] = [ 'name' => $fileNameUTF8, 'path' => str_replace('\\', '/', $relativePathUTF8), 'size' => filesize($fullPath), 'time' => date('Y-m-d H:i:s', filemtime($fullPath)) ]; } } 路径验证 $pdfPathGBK = iconv('UTF-8', 'GBK', $pdfBasePath); $realPdfPath = realpath($pdfPathGBK); if (!$realPdfPath || !is_dir($realPdfPath)) { die("PDF目录不存在或无法访问"); } 处理中文路径编码问题 验证PDF目录有效性 执行扫描 $fileList = []; scanFiles($realPdfPath, $fileList, $realPdfPath, $allowed_extensions); 初始化空数组并开始递归扫描 排序处理 usort($fileList, function($a, $b) { return $b['time'] - $a['time']; }); 按文件修改时间降序排序 结果输出 file_put_contents( $dataFilePath, json_encode(['files' => $fileList], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ); 将结果以JSON格式写入文件,保留Unicode字符和斜杠 完成提示 echo "<script>alert('已生成 ".count($fileList)." 个文件索引');</script>"; 通过JavaScript弹窗显示处理结果 这段代码主要实现了: 递归扫描指定目录下的文件 过滤指定扩展名的文件 处理中文路径编码问题 生成包含文件信息的JSON索引 按修改时间排序输出结果 特别注意: 代码中多处使用iconv()处理GBK/UTF-8编码转换,说明目标环境可能存在中文Windows服务器 时区设置确保所有时间戳都显示为北京时间37 路径处理中统一使用正斜杠提高跨平台兼容性<?php // generate_json.php // 设置时区为北京时间 date_default_timezone_set('Asia/Shanghai'); // 安全配置 set_time_limit(1000); // 将最大执行时间设置为60秒 $allowed_extensions = ['pdf', 'jpg', 'jpeg', 'png']; $dataFilePath = __DIR__.'/data/files2.json'; // JSON存储路径 $pdfBasePath = __DIR__.'/pdf2/'; // PDF存储根目录 // 创建数据目录 if (!file_exists(dirname($dataFilePath))) { mkdir(dirname($dataFilePath), 0755, true); } // 递归扫描目录 function scanFiles($dir, &$result, $rootDir, $allowed) { $files = scandir($dir); foreach ($files as $file) { if ($file === '.' || $file === '..') continue; $fullPath = $dir.'/'.$file; if (is_dir($fullPath)) { scanFiles($fullPath, $result, $rootDir, $allowed); continue; } // 处理文件名编码(GBK转UTF-8) $fileNameUTF8 = iconv('GBK', 'UTF-8//IGNORE', $file); $ext = strtolower(pathinfo($fileNameUTF8, PATHINFO_EXTENSION)); if (!in_array($ext, $allowed)) continue; // 计算相对路径 $relativePath = substr($fullPath, strlen($rootDir) + 1); $relativePathUTF8 = iconv('GBK', 'UTF-8//IGNORE', $relativePath); $result[] = [ 'name' => $fileNameUTF8, 'path' => str_replace('\\', '/', $relativePathUTF8), // 统一斜杠方向 'size' => filesize($fullPath), 'time' => date('Y-m-d H:i:s', filemtime($fullPath)) ]; } } // 验证PDF目录有效性 $pdfPathGBK = iconv('UTF-8', 'GBK', $pdfBasePath); $realPdfPath = realpath($pdfPathGBK); if (!$realPdfPath || !is_dir($realPdfPath)) { die("PDF目录不存在或无法访问"); } $fileList = []; scanFiles($realPdfPath, $fileList, $realPdfPath, $allowed_extensions); // 按修改时间排序 usort($fileList, function($a, $b) { return $b['time'] - $a['time']; }); // 写入JSON文件 file_put_contents( $dataFilePath, json_encode(['files' => $fileList], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ); //echo "已生成 ".count($fileList)." 个文件索引"; echo "<script>alert('已生成 ".count($fileList)." 个文件索引');</script>"; ?>
2025年05月14日
12 阅读
0 评论
0 点赞
2025-05-05
此内容被密码保护
加密文章,请前往内页查看详情
2025年05月05日
6 阅读
0 评论
0 点赞
1
2
3
4
...
7
0:00