单机版保质期管理系统 HTML 实现及开发要点
### 🍱实现思路 我们将创建一个单机版的 HTML 网页来实现保质期管理系统,利用 HTML、CSS 和 JavaScript 来完成各项功能。使用 `localStorage` 作为数据库来保存和还原数据,使用 `FileSaver.js` 库实现表格导出功能,通过 JavaScript 实现自动和手动刷新功能,以及仪表盘的统计功能。 ### 🔧准备工作 - **依赖**:`FileSaver.js` 用于导出文件。可以从 [GitHub 仓库](https://github.com/eligrey/FileSaver.js) 下载,或者使用 CDN 引入。 - **安装命令**:如果使用 CDN,无需安装,直接在 HTML 文件中引入即可。 ### 📝代码实现 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>保质期管理系统</title> <style> table { width: 100%; border-collapse: collapse; } th, td { border: 1px solid #ccc; padding: 8px; text-align: center; } th { background-color: #f2f2f2; } .black { background-color: black; color: white; } .red { background-color: red; color: white; } .yellow { background-color: yellow; } .green { background-color: green; color: white; } </style> <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script> </head> <body> <h1>保质期管理系统</h1> <button onclick="refreshData()">手动刷新</button> <button onclick="exportTable()">导出表格</button> <button onclick="saveData()">保存数据</button> <button onclick="restoreData()">还原数据</button> <div id="dashboard"></div> <table id="productTable"> <thead> <tr> <th>产品名称</th> <th>生产日期</th> <th>保质期</th> <th>到期日期</th> <th>剩余天数</th> </tr> </thead> <tbody> <!-- 数据将动态添加 --> </tbody> </table> <script> // 从 localStorage 中获取数据 const storedData = localStorage.getItem('productData'); let productData = storedData ? JSON.parse(storedData) : []; // 自动刷新,在页面加载和一段时间无操作后刷新 let idleTime = 0; const idleTimeout = 60 * 1000; // 1 分钟无操作后刷新 document.addEventListener('mousemove', resetIdleTime); document.addEventListener('keydown', resetIdleTime); function resetIdleTime() { idleTime = 0; } setInterval(() => { idleTime += 1000; if (idleTime >= idleTimeout) { refreshData(); idleTime = 0; } }, 1000); // 手动刷新函数 function refreshData() { const tableBody = document.getElementById('productTable').getElementsByTagName('tbody')[0]; tableBody.innerHTML = ''; productData.forEach((product, index) => { const row = tableBody.insertRow(); const nameCell = row.insertCell(0); const productionDateCell = row.insertCell(1); const shelfLifeCell = row.insertCell(2); const expirationDateCell = row.insertCell(3); const remainingDaysCell = row.insertCell(4); nameCell.textContent = product.name; productionDateCell.textContent = product.productionDate; shelfLifeCell.textContent = product.shelfLife; const expirationDate = calculateExpirationDate(product.productionDate, product.shelfLife); expirationDateCell.textContent = expirationDate; const remainingDays = calculateRemainingDays(expirationDate); remainingDaysCell.textContent = remainingDays; if (remainingDays <= 0) { remainingDaysCell.classList.add('black'); } else if (remainingDays <= 7) { remainingDaysCell.classList.add('red'); } else if (remainingDays <= 30) { remainingDaysCell.classList.add('yellow'); } else { remainingDaysCell.classList.add('green'); } }); // 排序 const rows = Array.from(tableBody.rows); rows.sort((a, b) => { const daysA = parseInt(a.cells[4].textContent); const daysB = parseInt(b.cells[4].textContent); return daysA - daysB; }); rows.forEach(row => tableBody.appendChild(row)); // 更新仪表盘 updateDashboard(); } // 计算到期日期 function calculateExpirationDate(productionDate, shelfLife) { const date = new Date(productionDate); if (shelfLife.endsWith('天')) { const days = parseInt(shelfLife.replace('天', '')); date.setDate(date.getDate() + days); } else if (shelfLife.endsWith('个月')) { const months = parseInt(shelfLife.replace('个月', '')); date.setMonth(date.getMonth() + months); } return date.toLocaleDateString(); } // 计算剩余天数 function calculateRemainingDays(expirationDate) { const today = new Date(); const expDate = new Date(expirationDate); const timeDiff = expDate - today; return Math.floor(timeDiff / (1000 * 60 * 60 * 24)); } // 导出表格 function exportTable() { let csvContent = "data:text/csv;charset=utf-8,"; const headers = ["产品名称", "生产日期", "保质期", "到期日期", "剩余天数"]; csvContent += headers.join(",") + "\n"; productData.forEach(product => { const expirationDate = calculateExpirationDate(product.productionDate, product.shelfLife); const remainingDays = calculateRemainingDays(expirationDate); const row = [ product.name, product.productionDate, product.shelfLife, expirationDate, remainingDays ]; csvContent += row.join(",") + "\n"; }); const encodedUri = encodeURI(csvContent); const blob = new Blob([decodeURIComponent(encodedUri)], { type: 'text/csv;charset=utf-8;' }); saveAs(blob, "便利店保质期_2026.csv"); } // 保存数据到 localStorage function saveData() { localStorage.setItem('productData', JSON.stringify(productData)); alert('数据已保存'); } // 从 localStorage 还原数据 function restoreData() { const storedData = localStorage.getItem('productData'); if (storedData) { productData = JSON.parse(storedData); refreshData(); alert('数据已还原'); } else { alert('没有保存的数据'); } } // 更新仪表盘 function updateDashboard() { const dashboard = document.getElementById('dashboard'); let expiredCount = 0; let soonExpireCount = 0; let nearReminderCount = 0; let safeCount = 0; productData.forEach(product => { const expirationDate = calculateExpirationDate(product.productionDate, product.shelfLife); const remainingDays = calculateRemainingDays(expirationDate); if (remainingDays <= 0) { expiredCount++; } else if (remainingDays <= 7) { soonExpireCount++; } else if (remainingDays <= 30) { nearReminderCount++; } else { safeCount++; } }); dashboard.innerHTML = ` <p>已过期: ${expiredCount}</p> <p>即将过期: ${soonExpireCount}</p> <p>临近提醒: ${nearReminderCount}</p> <p>安全期: ${safeCount}</p> `; } // 页面加载时刷新数据 window.onload = refreshData; </script> </body> </html> ``` ### 📋代码解释 1. **HTML 部分**:创建了一个简单的页面结构,包含按钮、仪表盘和表格。 2. **CSS 部分**:对表格进行了美化,设置了不同颜色的预警样式。 3. **JavaScript 部分**: - 使用 `localStorage` 保存和还原数据。 - 实现了自动和手动刷新功能,自动刷新在一段时间无操作后触发。 - 利用 `FileSaver.js` 实现表格导出为 CSV 文件。 - 计算到期日期和剩余天数,并根据剩余天数设置不同的颜色预警。 - 更新仪表盘的统计信息。 ### ⚙️进阶使用指南 - **性能优化**:可以使用虚拟列表来处理大量数据,减少 DOM 操作。 - **错误处理**:在计算日期和保存数据时添加错误处理,避免程序崩溃。 - **扩展功能**:添加数据添加、删除和编辑功能,方便用户管理数据。 - **安全建议**:对用户输入进行验证,防止 XSS 攻击。 - **常见陷阱规避**:注意日期格式的兼容性,避免在不同浏览器中出现问题。 ### 📚相关技术栈推荐和学习资源 - **HTML、CSS、JavaScript**:基础的前端技术,官方文档可以在 [MDN Web Docs](https://developer.mozilla.org/) 上找到。 - **FileSaver.js**:用于文件导出,官方 GitHub 仓库:[FileSaver.js](https://github.com/eligrey/FileSaver.js)。 ### 💡开发建议 - 代码结构要清晰,将不同功能封装成独立的函数,提高代码的可维护性。 - 对用户输入进行验证,确保数据的合法性。 - 添加注释,方便后续维护和理解代码。 ######[AI写代码神器 | 2458点数解答 | 2026-04-01 06:49:18]
- Python 实现球类:精准计算半径、表面积与体积,附输入验证与异常处理!(阿里通义 | 261点数解答 | 2024-11-28 21:19:39)349
- 工程师必知:软件系统用户文档编写九大要点揭秘(百度文心 | 350点数解答 | 2023-11-09 18:23:53)192
- 工程师必备!10 种工程日常易用管理工具大揭秘(百度文心 | 346点数解答 | 2023-11-09 18:26:09)293
- 单机版保质期管理系统 HTML 实现及开发要点(字节豆包 | 2458点数解答 | 2026-04-01 06:49:18)7
- 优化高中英语核心词汇短语HTML页面,这些建议不容错过!(DeepSeek | 217点数解答 | 2025-07-01 23:41:02)191
- Java JSP 代码:用 List 存储 Map 集合并循环添加姓名和年龄(GPT | 240点数解答 | 2024-11-25 09:17:43)247
- 微信钱包前端演示代码:从问题修正到完善功能及安全提示(字节豆包 | 2097点数解答 | 2025-07-11 18:06:46)151
- 英文打字练习程序:从问题重重到全面优化的蜕变(字节豆包 | 2538点数解答 | 2025-08-20 12:28:06)163
- 51 单片机:定时器 0 实现 8 个 LED 循环点亮,附代码及优化建议(字节豆包 | 1193点数解答 | 2024-12-27 15:10:29)319
- 此需求是代码优化,并非生成标题,以下是优化后的代码,若你需要标题请提供合适的描述信息: ```asp <!-- 包含数据库连接文件 --> <!--#include file="inc/conn.asp"--> <!-- 包含配置文件 --> <!--#include file="inc/config.asp"--> <% ' 声明变量 Dim verifyCode, verifyCode2 ' 初始化错误标志 Dim foundErr foundErr = False ' 检查验证码是否匹配 If Trim(verifyCode) <> Trim(verifyCode2) Then ' 验证码不匹配,输出重定向代码并终止脚本执行 Response.Write "<script language='javascript'>location.href='index.asp'</script>" Response.End foundErr = True Else %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <!-- 设置页面标题 --> <title><%=sitename%></title> <!-- 设置字符编码 --> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> </head> <body> <!-- 页面内容 --> </body> </html> <% End If %> ``` (GPT | 45点数解答 | 2024-07-11 14:16:55)356
- 揭秘:精美 HTML 与 CSS 打造的欢迎网页!(GPT | 324点数解答 | 2024-10-30 19:49:49)285
- HTML5基本文档结构全解析:代码详解与关键逻辑点提醒(DeepSeek | 222点数解答 | 2025-02-18 14:20:46)1855