Files
basicBench/001/001_r.html
邓智航 c989a4973f strong 1
2026-01-17 14:23:46 +08:00

1098 lines
50 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SYS_V4.2_INVENTORY_MANAGE_INTERNAL_USE_ONLY</title>
<style>
/* === CSS Reset & Modernizer === */
:root {
--primary: #2563eb;
--danger: #dc2626;
--bg: #f8fafc;
--panel: #ffffff;
--border: #e2e8f0;
--text: #334155;
}
body {
font-family: 'Segoe UI', system-ui, sans-serif;
background-color: var(--bg) !important; /* 覆盖原有 bgcolor */
color: var(--text) !important;
margin: 0;
padding: 0;
line-height: 1.5;
}
a { text-decoration: none; color: var(--primary) !important; transition: 0.2s; }
a:hover { text-decoration: underline; }
/* === 布局重构 (将 Table 强制改为 Flex 风格) === */
/* 隐藏最外层大表格的边框和背景 */
.main-layout-table {
background-color: transparent !important;
border: none !important;
width: 100%;
border-collapse: collapse;
}
/* 顶部 Header */
.header-row td {
background-color: #1e293b !important; /* 深色顶栏 */
color: white !important;
padding: 15px 20px !important;
border: none !important;
}
.header-row h1 { margin: 0; font-size: 1.2rem; font-weight: 600; }
.header-row p { margin: 5px 0 0; opacity: 0.8; font-size: 0.9rem; }
.header-row a { color: #94a3b8 !important; margin: 0 5px; }
/* 侧边栏 & 主内容 & Widget 布局调整 */
/* 利用 CSS 让这些 td 看起来像独立的列 */
.layout-cell {
vertical-align: top;
padding: 20px !important;
border: none !important;
}
/* 左侧导航栏 */
.sidebar-nav ul {
list-style: none;
padding: 0;
background: var(--panel);
border: 1px solid var(--border);
border-radius: 8px;
overflow: hidden;
}
.sidebar-nav ul li a {
display: block;
padding: 10px 15px;
border-bottom: 1px solid var(--border);
color: var(--text) !important;
}
.sidebar-nav ul li a:hover {
background-color: #eff6ff;
color: var(--primary) !important;
text-decoration: none;
}
/* 隐藏旧版干扰链接 */
.legacy-link { display: none !important; }
/* 中间主内容 */
.main-content h2 {
font-size: 1.5rem;
border-bottom: 2px solid var(--primary);
padding-bottom: 10px;
margin-top: 0;
}
/* 筛选表单美化 */
.filter-table {
background: var(--panel);
padding: 15px;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
border: 1px solid var(--border) !important;
}
.filter-table td { border: none !important; padding: 5px !important; }
input[type="text"], select {
padding: 6px; border: 1px solid #ccc; border-radius: 4px;
}
input[type="submit"], input[type="reset"] {
padding: 6px 15px; border-radius: 4px; border: none; cursor: pointer;
font-weight: bold;
}
input[type="submit"] { background: var(--primary); color: white; }
/* 数据表格 (核心改造) */
.data-table {
background: var(--panel) !important;
border-collapse: collapse !important;
border: none !important;
box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);
border-radius: 8px;
overflow: hidden;
width: 100%;
margin-top: 20px;
}
.data-table th {
background-color: #f1f5f9 !important; /* 覆盖原来的灰色 */
color: #475569;
text-transform: uppercase;
font-size: 0.85rem;
padding: 12px !important;
border: none !important;
border-bottom: 2px solid var(--border) !important;
}
.data-table td {
border: none !important;
border-bottom: 1px solid var(--border) !important;
padding: 12px !important;
font-size: 0.95rem;
}
.data-table tr:hover td { background-color: #f8fafc; }
/* 操作链接样式化为按钮 */
.action-group a {
display: inline-block;
padding: 2px 6px;
font-size: 0.8rem;
border-radius: 4px;
text-decoration: none !important;
margin-right: 2px;
margin-bottom: 2px;
border: 1px solid transparent;
}
.btn-view { background: #e0f2fe; color: #0369a1 !important; }
.btn-edit { background: #dcfce7; color: #15803d !important; }
.btn-danger { background: #fee2e2; color: #b91c1c !important; }
/* === 干扰项隐藏 (重点) === */
/* 隐藏所有被标记为 interference 的行 */
.interference-row { display: none !important; }
/* 右侧 Widget 美化 */
.widget-table {
background: var(--panel) !important;
border: 1px solid var(--border) !important;
border-radius: 8px;
margin-bottom: 20px;
border-collapse: collapse;
}
.widget-header {
background-color: #334155 !important;
color: white !important;
padding: 10px !important;
font-weight: bold;
border-radius: 7px 7px 0 0;
}
.widget-content td { padding: 8px 15px !important; border-bottom: 1px solid #eee !important; }
/* 页脚 */
.footer-row td {
background-color: var(--panel) !important;
color: #94a3b8 !important;
border-top: 1px solid var(--border) !important;
padding: 20px !important;
}
/* === 新增样式: 模态框 (Modal) === */
.modal-overlay {
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
background: rgba(0, 0, 0, 0.5);
display: none; justify-content: center; align-items: center;
z-index: 1000; opacity: 0; transition: opacity 0.3s ease;
}
.modal-overlay.show { display: flex; opacity: 1; }
.modal-window {
background: white; width: 600px; max-width: 90%;
border-radius: 8px; box-shadow: 0 10px 25px rgba(0,0,0,0.2);
transform: translateY(-20px); transition: transform 0.3s ease;
display: flex; flex-direction: column; overflow: hidden;
}
.modal-overlay.show .modal-window { transform: translateY(0); }
.modal-header {
padding: 15px 20px; background: #f8fafc; border-bottom: 1px solid #e2e8f0;
display: flex; justify-content: space-between; align-items: center;
}
.modal-title { margin: 0; font-size: 1.1rem; font-weight: 600; color: #334155; }
.modal-close { cursor: pointer; font-size: 1.5rem; color: #94a3b8; line-height: 1; }
.modal-body { padding: 20px; overflow-y: auto; max-height: 70vh; }
.modal-footer {
padding: 15px 20px; background: #f8fafc; border-top: 1px solid #e2e8f0;
text-align: right;
}
/* 表单组样式 */
.form-group { margin-bottom: 15px; }
.form-group label { display: block; margin-bottom: 5px; font-weight: 500; font-size: 0.9rem; }
.form-group input, .form-group select, .form-group textarea {
width: 100%; padding: 8px; border: 1px solid #cbd5e1; border-radius: 4px;
box-sizing: border-box; font-family: inherit;
}
.form-group .hint { font-size: 0.8rem; color: #64748b; margin-top: 4px; }
/* === 新增样式: 分页组件 (Pagination) === */
.pagination-container {
display: flex; justify-content: space-between; align-items: center;
margin-top: 20px; padding: 10px; background: #fff; border-radius: 8px;
border: 1px solid #e2e8f0;
}
.pagination-info { font-size: 0.9rem; color: #64748b; }
.pagination-controls { display: flex; gap: 5px; }
.page-btn {
padding: 5px 10px; border: 1px solid #e2e8f0; background: white;
cursor: pointer; border-radius: 4px; font-size: 0.9rem; color: #475569;
}
.page-btn:hover { background: #f1f5f9; border-color: #cbd5e1; }
.page-btn.active { background: var(--primary); color: white; border-color: var(--primary); }
.page-btn:disabled { opacity: 0.5; cursor: not-allowed; }
/* === 新增样式: Toast 通知 === */
.toast-container {
position: fixed; bottom: 20px; right: 20px; z-index: 2000;
display: flex; flex-direction: column; gap: 10px;
}
.toast {
background: white; border-left: 4px solid var(--primary);
padding: 15px 20px; border-radius: 4px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);
min-width: 250px; transform: translateX(100%); transition: transform 0.3s ease;
display: flex; align-items: center; justify-content: space-between;
}
.toast.show { transform: translateX(0); }
.toast-success { border-left-color: #10b981; }
.toast-error { border-left-color: #ef4444; }
.toast-warning { border-left-color: #f59e0b; }
/* === 新增样式: 只有 CSS 的加载动画 === */
.spinner {
width: 20px; height: 20px; border: 2px solid #f3f3f3;
border-top: 2px solid var(--primary); border-radius: 50%;
animation: spin 1s linear infinite; display: inline-block; vertical-align: middle;
}
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
</style>
</head>
<body bgcolor="#e0e0e0" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000">
<table width="100%" border="1" cellpadding="5" cellspacing="0" bgcolor="#cccccc" class="main-layout-table">
<tr class="header-row">
<td colspan="3" align="center">
<h1>内部库存管控系统 V4.2 (非密级)</h1>
<p>当前登录: OPERATOR_8821 | <a href="#" onclick="alert('模拟注销')">[注销]</a> | <a href="#">[切换节点]</a> | <a href="#">[系统日志]</a> | <a href="#">[报错]</a></p>
</td>
</tr>
<tr>
<td width="20%" valign="top" class="layout-cell sidebar-nav">
<h3>快速导航</h3>
<ul id="sidebarList">
<li><a href="javascript:void(0)" onclick="filterCategory('all')">📌 概览面板</a></li>
<li><a href="javascript:void(0)" onclick="filterCategory('urgent')">🔥 入库申请 (急)</a></li>
<li><a href="javascript:void(0)" onclick="filterCategory('normal')">📥 入库申请 (常规)</a></li>
<li><a href="javascript:void(0)" onclick="showToast('归档数据需管理员权限', 'warning')">🗄️ 入库申请 (存档)</a></li>
<li><a href="javascript:void(0)" onclick="filterCategory('out_a')">📤 出库审批 (A区)</a></li>
<li><a href="javascript:void(0)" onclick="filterCategory('out_b')">📤 出库审批 (B区)</a></li>
<li><a href="javascript:void(0)" onclick="showToast('C区系统维护中', 'error')">🚫 出库审批 (C区)</a></li>
<li><a href="javascript:void(0)" onclick="openModal('reportModal')">📉 报损登记</a></li>
<li><a href="javascript:void(0)" onclick="showToast('权限不足: 仅HR可访问', 'error')">👥 人员管理</a></li>
<li><a href="javascript:void(0)" onclick="showToast('正在连接财务接口...', 'info')">💰 财务对接</a></li>
<li><a href="javascript:void(0)" onclick="openModal('settingsModal')">⚙️ 系统设置</a></li>
<li><a href="javascript:void(0)" onclick="window.print()">🖨️ 打印测试页</a></li>
<li class="legacy-link"><a href="#">旧版入口 (已停用)</a></li>
<li class="legacy-link"><a href="#">旧版入口 V2 (已停用)</a></li>
<li class="legacy-link"><a href="#">帮助文档 1998版</a></li>
<li><a href="javascript:void(0)" onclick="openHelp()">❓ 帮助与支持</a></li>
<li><a href="javascript:void(0)" onclick="showToast('无需下载,浏览器已支持', 'success')">💾 下载控件</a></li>
<li><a href="javascript:void(0)" onclick="location.reload()">🔄 刷新系统</a></li>
</ul>
<hr>
<div style="background:#fff7ed; padding:10px; border-radius:4px; font-size:0.9em; border:1px solid #ffedd5;">
<p style="margin:0; color:#c2410c;"><b>系统广播:</b><br>请注意,服务器将于今晚 03:00 进行维护,请勿在此期间提交表单。</p>
</div>
<p style="text-align:center; color:#888; margin-top:10px;"><b>今日格言:</b><br>安全生产,效率第一。</p>
</td>
<td width="60%" valign="top" class="layout-cell main-content">
<h2>库存列表 - 区域 A1</h2>
<form action="submit_filter">
<table border="0" width="100%" class="filter-table">
<tr>
<td>关键词: <input type="text" name="kw" size="30" placeholder="输入 ID 或名称"></td>
<td>
类型:
<select name="type">
<option value="all">-- 所有 --</option>
<option value="res">电阻</option>
<option value="cap">电容</option>
<option value="ind">电感</option>
<option value="chip">芯片</option>
<option value="conn">连接器</option>
</select>
</td>
<td>
状态:
<label><input type="checkbox" name="st1" checked> 正常</label>
<label><input type="checkbox" name="st2"> 警告</label>
<label><input type="checkbox" name="st3"> 损坏</label>
</td>
</tr>
<tr>
<td colspan="3" style="padding-top:10px;">
高级选项:
<label><input type="radio" name="sort" value="date"> 按日期</label>
<label><input type="radio" name="sort" value="id"> 按ID</label>
<label><input type="radio" name="sort" value="wt"> 按重量</label>
<label><input type="radio" name="sort" value="pr"> 按优先级</label>
<br><br>
<input type="submit" value="开始检索">
<input type="reset" value="重置条件">
<input type="button" value="导出Excel (不可用)" disabled style="background:#eee; color:#aaa; cursor:not-allowed;">
</td>
</tr>
</table>
</form>
<hr style="border:0; margin:20px 0;">
<table border="1" width="100%" cellpadding="3" cellspacing="1" class="data-table" id="inventoryTable">
<thead>
<tr bgcolor="#999999">
<th width="40"><input type="checkbox" id="selectAll"></th>
<th width="100">ID</th>
<th>物料名称</th>
<th width="120">批次号</th>
<th width="80">库存量</th>
<th width="80">重量(g)</th>
<th width="100">入库日期</th>
<th width="100">状态码</th>
<th width="180">操作</th>
</tr>
</thead>
<tbody id="tableBody">
<!-- 数据将由 JS 动态生成 -->
<tr><td colspan="9" align="center" style="padding: 50px;">正在加载库存数据... <div class="spinner"></div></td></tr>
</tbody>
</table>
<!-- 新版分页组件 -->
<div class="pagination-container">
<div class="pagination-info">
显示第 <span id="startRecord">0</span><span id="endRecord">0</span> 条,共 <span id="totalRecords">0</span> 条记录
</div>
<div style="display:flex; align-items:center; gap:10px;">
<select id="pageSizeSelect" onchange="changePageSize()">
<option value="10">10条/页</option>
<option value="20">20条/页</option>
<option value="50">50条/页</option>
<option value="100">100条/页</option>
</select>
<div class="pagination-controls" id="paginationControls">
<!-- 分页按钮由 JS 生成 -->
</div>
</div>
</div>
<br><br>
<table border="1" width="100%" bgcolor="#eeeeee" style="border:none; border-radius:8px; overflow:hidden; background:#f1f5f9;">
<tr>
<td style="padding:20px; border:none;">
<h4 style="margin-top:0;">批量操作控制台</h4>
<p>选中项操作:
<select id="batchActionSelect">
<option>-- 请选择操作 --</option>
<option>批量导出</option>
<option>批量删除 (需管理员权限)</option>
<option>转移仓库</option>
</select>
<input type="button" value="执行" onclick="executeBatchAction()">
</p>
<p style="font-size:0.9em; color:#666;">
<label><input type="checkbox"> 我已阅读并同意《数据安全操作规范 v9.0》</label><br>
<label><input type="checkbox"> 确认非误操作</label>
</p>
</td>
</tr>
</table>
</td>
<td width="20%" valign="top" class="layout-cell sidebar-widgets">
<table border="1" width="100%" class="widget-table">
<tr><td bgcolor="#000000" class="widget-header"><font color="white" align="center"><b>服务器负载</b></font></td></tr>
<tbody class="widget-content">
<tr><td>CPU: <div style="display:inline-block; width:50px; height:8px; background:#e2e8f0; border-radius:4px;"><div style="width:12%; height:100%; background:green; border-radius:4px;"></div></div> 12%</td></tr>
<tr><td>RAM: <div style="display:inline-block; width:50px; height:8px; background:#e2e8f0; border-radius:4px;"><div style="width:64%; height:100%; background:orange; border-radius:4px;"></div></div> 64%</td></tr>
<tr><td>DISK: <div style="display:inline-block; width:50px; height:8px; background:#e2e8f0; border-radius:4px;"><div style="width:98%; height:100%; background:red; border-radius:4px;"></div></div> <span style="color:red">98% (警告)</span></td></tr>
</tbody>
</table>
<br>
<table border="1" width="100%" class="widget-table">
<tr><td bgcolor="#000000" class="widget-header"><font color="white"><b>待办事项</b></font></td></tr>
<tbody class="widget-content">
<tr><td><label><input type="checkbox"> 审批张三的请假</label></td></tr>
<tr><td><label><input type="checkbox"> 订购咖啡豆</label></td></tr>
<tr><td><label><input type="checkbox"> 修复打印机</label></td></tr>
<tr><td><label><input type="checkbox"> 更新防火墙</label></td></tr>
<tr><td><label><input type="checkbox"> 年底报表汇总</label></td></tr>
</tbody>
</table>
<br>
<center>
<p style="font-size:0.8rem; color:#888;">扫码下载APP</p>
<div style="background:white; padding:10px; border-radius:8px; display:inline-block; border:1px solid #ddd;">
<table border="1" width="100" height="100" style="border:none;">
<tr><td align="center" style="border:none;">QR CODE</td></tr>
</table>
</div>
</center>
</td>
</tr>
<tr class="footer-row">
<td colspan="3" bgcolor="#333333" align="center">
<font color="#ffffff" size="2">
&copy; 2005-2025 Galactic Logistics Corp. All Rights Reserved.<br>
Address: Sector 7G, Industrial Zone, Mars Colony.<br>
<a href="#" style="color: #aaaaaa">Privacy Policy</a> |
<a href="#" style="color: #aaaaaa">Terms of Service</a> |
<a href="#" style="color: #aaaaaa">Sitemap</a> |
<a href="#" style="color: #aaaaaa">Report Abuse</a>
<br>
<span style="opacity:0.5;">Render Time: 0.04s | SQL Queries: 142 | Memory: 4MB</span>
</font>
</td>
</tr>
</table>
<!-- === 隐藏的模态框 (HTML 结构) === -->
<!-- 1. 编辑/新增 模态框 -->
<div class="modal-overlay" id="editModal">
<div class="modal-window">
<div class="modal-header">
<h3 class="modal-title">库存条目编辑</h3>
<span class="modal-close" onclick="closeModal('editModal')">&times;</span>
</div>
<div class="modal-body">
<form id="editForm">
<div class="form-group">
<label>物料 ID (只读)</label>
<input type="text" id="edit_id" readonly style="background:#f1f5f9; color:#64748b;">
</div>
<div class="form-group">
<label>物料名称 <span style="color:red">*</span></label>
<input type="text" id="edit_name" required>
<div class="hint">请输入完整的器件型号,例如: Resistor 0603 10k 1%</div>
</div>
<div class="form-group">
<label>供应商</label>
<select id="edit_supplier">
<option value="Alpha Corp">Alpha Corp - 优质供应商</option>
<option value="Beta Ltd">Beta Ltd - 长期合作</option>
<option value="Gamma Inc">Gamma Inc</option>
<option value="ConnWorld">ConnWorld - 连接器专供</option>
<option value="ST Micro">ST Micro - 芯片原厂</option>
<option value="Other">其他 (需备注)</option>
</select>
</div>
<div class="form-group">
<div style="display:flex; gap:10px;">
<div style="flex:1;">
<label>库存数量</label>
<input type="number" id="edit_qty" min="0">
</div>
<div style="flex:1;">
<label>单重 (g)</label>
<input type="number" id="edit_weight" step="0.01">
</div>
</div>
</div>
<div class="form-group">
<label>状态</label>
<select id="edit_status">
<option value="NORMAL">正常 (NORMAL)</option>
<option value="LOW">库存不足 (LOW)</option>
<option value="CRITICAL">严重短缺 (CRITICAL)</option>
<option value="DAMAGED">已损坏 (DAMAGED)</option>
<option value="PENDING">待检 (PENDING)</option>
</select>
</div>
<div class="form-group">
<label>备注说明</label>
<textarea id="edit_notes" rows="3"></textarea>
</div>
</form>
</div>
<div class="modal-footer">
<button class="page-btn" onclick="closeModal('editModal')">取消</button>
<button class="page-btn active" onclick="saveEdit()">保存更改</button>
</div>
</div>
</div>
<!-- 2. 详情 模态框 -->
<div class="modal-overlay" id="detailModal">
<div class="modal-window">
<div class="modal-header">
<h3 class="modal-title">物料详情档案</h3>
<span class="modal-close" onclick="closeModal('detailModal')">&times;</span>
</div>
<div class="modal-body">
<table width="100%" border="0" cellpadding="8" style="background:#f8fafc; border-radius:8px;">
<tr>
<td width="30%" align="right" style="color:#64748b;">内部编号:</td>
<td width="70%"><b id="detail_id">#---</b></td>
</tr>
<tr>
<td align="right" style="color:#64748b;">物料名称:</td>
<td><span id="detail_name">---</span></td>
</tr>
<tr>
<td align="right" style="color:#64748b;">批次号:</td>
<td><code id="detail_batch" style="background:#e2e8f0; padding:2px 4px; border-radius:3px;">---</code></td>
</tr>
<tr>
<td align="right" style="color:#64748b;">实时库存:</td>
<td><span id="detail_qty">0</span> 单位</td>
</tr>
<tr>
<td align="right" style="color:#64748b;">入库时间:</td>
<td><span id="detail_date">---</span></td>
</tr>
<tr>
<td align="right" style="color:#64748b;">生命周期状态:</td>
<td><span id="detail_status">---</span></td>
</tr>
</table>
<div style="margin-top:20px;">
<h4 style="border-bottom:1px solid #ddd; padding-bottom:5px;">最近流转记录</h4>
<ul style="font-size:0.9rem; color:#475569; padding-left:20px;" id="detail_history">
<li>暂无记录</li>
</ul>
</div>
<div style="margin-top:20px; background:#fff7ed; padding:10px; border-left:4px solid #f97316; font-size:0.9rem;">
<strong>注意:</strong> 该物料属于精密器件,请轻拿轻放,存储温度控制在 20-25℃。
</div>
</div>
<div class="modal-footer">
<button class="page-btn" onclick="printDetail()">打印档案</button>
<button class="page-btn" onclick="closeModal('detailModal')">关闭</button>
</div>
</div>
</div>
<!-- 3. 系统设置 模态框 -->
<div class="modal-overlay" id="settingsModal">
<div class="modal-window">
<div class="modal-header">
<h3 class="modal-title">系统偏好设置</h3>
<span class="modal-close" onclick="closeModal('settingsModal')">&times;</span>
</div>
<div class="modal-body">
<h4 style="border-bottom: 2px solid var(--primary); padding-bottom: 5px;">界面显示</h4>
<div class="form-group">
<label>主题模式</label>
<select id="themeSelect" onchange="showToast('主题切换功能开发中...', 'warning')">
<option value="light">明亮 (默认)</option>
<option value="dark">深色 (Dark Mode)</option>
<option value="auto">跟随系统</option>
</select>
</div>
<div class="form-group">
<label><input type="checkbox" checked> 启用动画效果</label><br>
<label><input type="checkbox" checked> 显示实时时钟</label><br>
<label><input type="checkbox"> 紧凑表格模式</label>
</div>
<h4 style="border-bottom: 2px solid var(--primary); padding-bottom: 5px; margin-top:20px;">数据与隐私</h4>
<div class="form-group">
<label>自动刷新间隔</label>
<select>
<option value="0">关闭</option>
<option value="30">30 秒</option>
<option value="60">1 分钟</option>
<option value="300">5 分钟</option>
</select>
</div>
<div class="form-group">
<label><input type="checkbox" checked> 允许本地缓存 (LocalStorage)</label><br>
<label><input type="checkbox"> 发送匿名使用统计</label>
</div>
<h4 style="border-bottom: 2px solid var(--primary); padding-bottom: 5px; margin-top:20px;">通知设置</h4>
<div class="form-group">
<label><input type="checkbox" checked> 库存不足警告</label><br>
<label><input type="checkbox" checked> 审批通过通知</label><br>
<label><input type="checkbox"> 每日报表推送</label>
</div>
</div>
<div class="modal-footer">
<button class="page-btn" onclick="closeModal('settingsModal')">取消</button>
<button class="page-btn active" onclick="closeModal('settingsModal'); showToast('设置已保存', 'success')">保存配置</button>
</div>
</div>
</div>
<!-- 4. 帮助文档 模态框 (长文本) -->
<div class="modal-overlay" id="helpModal">
<div class="modal-window" style="width:800px;">
<div class="modal-header">
<h3 class="modal-title">用户操作指南 v4.2</h3>
<span class="modal-close" onclick="closeModal('helpModal')">&times;</span>
</div>
<div class="modal-body" style="line-height:1.8; color:#334155;">
<h3>1. 系统概述</h3>
<p>本系统SYS_V4.2)旨在为 Galactic Logistics Corp 提供高效、透明的内部库存管理解决方案。系统集成了物资入库、库存监控、出库审批及报表生成四大核心模块。</p>
<h3>2. 快速入门</h3>
<ul>
<li><strong>登录系统:</strong> 使用分配的工号(如 OPERATOR_8821和动态令牌登录。</li>
<li><strong>浏览库存:</strong> 在主界面查看当前仓库的实时库存状态。支持按名称、ID、状态筛选。</li>
<li><strong>数据编辑:</strong> 点击表格右侧的 [编辑] 按钮修改库存数量或状态。</li>
<li><strong>导出报表:</strong> 勾选需要的数据行,从底部“批量操作控制台”选择“批量导出”。</li>
</ul>
<h3>3. 状态码说明</h3>
<table width="100%" border="1" cellpadding="5" style="border-collapse:collapse; border-color:#e2e8f0;">
<tr bgcolor="#f1f5f9"><th>状态码</th><th>含义</th><th>处理建议</th></tr>
<tr><td>NORMAL</td><td>库存正常</td><td>无需操作,定期盘点。</td></tr>
<tr><td style="color:orange">LOW</td><td>库存偏低</td><td>建议发起采购申请,补充库存至安全水位。</td></tr>
<tr><td style="color:red">CRITICAL</td><td>严重短缺</td><td>立即联系供应商紧急补货,可能会影响生产线。</td></tr>
<tr><td style="color:gray">DAMAGED</td><td>已损坏</td><td>物资已不可用,请发起报废流程并隔离存放。</td></tr>
<tr><td>PENDING</td><td>待检</td><td>物资刚入库或等待质检,暂时冻结出库。</td></tr>
</table>
<h3>4. 常见问题 (FAQ)</h3>
<p><strong>Q: 为什么找不到刚才添加的数据?</strong><br>
A: 请确筛选器设置正确。如果问题依旧,请尝试点击左侧导航栏的“刷新系统”。</p>
<p><strong>Q: 可以在手机上使用本系统吗?</strong><br>
A: 可以。本系统采用响应式设计(虽然主要针对桌面优化),支持主流移动浏览器。</p>
<p><strong>Q: 如何申请管理员权限?</strong><br>
A: 请填写《IT权限变更申请表》并提交至 Sector 7G 信息中心,审批周期约 3 个工作日。</p>
<hr>
<p style="font-size:0.8rem; color:#94a3b8;">最后更新时间: 2025-10-15 | 文档版本: 4.2.1-beta</p>
</div>
<div class="modal-footer">
<button class="page-btn" onclick="window.open('https://example.com/manual.pdf')">下载 PDF 版</button>
<button class="page-btn" onclick="closeModal('helpModal')">关闭</button>
</div>
</div>
</div>
<!-- 5. 报损登记 模态框 -->
<div class="modal-overlay" id="reportModal">
<div class="modal-window">
<div class="modal-header">
<h3 class="modal-title">报损登记表</h3>
<span class="modal-close" onclick="closeModal('reportModal')">&times;</span>
</div>
<div class="modal-body">
<p style="background:#fee2e2; padding:10px; color:#b91c1c; border-radius:4px;">
警告: 虚假报损属于严重违规行为。
</p>
<form>
<div class="form-group">
<label>关联物料 ID</label>
<input type="text" placeholder="输入 ID 或扫描条码">
</div>
<div class="form-group">
<label>报损原因</label>
<select>
<option>运输损坏</option>
<option>存储过期</option>
<option>受潮/氧化</option>
<option>人为损坏</option>
<option>盘点丢失</option>
</select>
</div>
<div class="form-group">
<label>责任人</label>
<input type="text" value="OPERATOR_8821 (当前用户)">
</div>
<div class="form-group">
<label>现场照片证据 (URL)</label>
<input type="text" placeholder="http://...">
</div>
</form>
</div>
<div class="modal-footer">
<button class="page-btn" onclick="closeModal('reportModal')">取消</button>
<button class="page-btn btn-danger" onclick="closeModal('reportModal'); showToast('报损单已提交审核', 'warning')">提交报损</button>
</div>
</div>
</div>
<!-- Toast 通知容器 -->
<div class="toast-container" id="toastContainer"></div>
<script>
// === JavaScript 核心逻辑重构 (SPA模式) ===
// 配置与状态
const CONFIG = {
totalItems: 358, // 模拟总数据量
defaultPageSize: 10,
suppliers: ["Alpha Corp", "Beta Ltd", "Gamma Inc", "ConnWorld", "ST Micro", "Texas Inst", "NXP", "Murata"],
statuses: ["NORMAL", "LOW", "CRITICAL", "DAMAGED", "PENDING"],
components: [
"Resistor 10k 0603", "Capacitor 100nF", "Inductor 22uH", "MCU STM32F103", "Connector USB-C",
"LED Red 0805", "Diode 1N4148", "Transistor 2N2222", "Regulator 3.3V", "Crystal 16MHz",
"Battery Holder", "Fuse 500mA", "Switch Tactile", "Header 2.54mm", "PCB Stiffener"
]
};
let state = {
data: [], // 所有数据
filteredData: [], // 筛选后的数据
currentPage: 1,
pageSize: 10,
sortBy: 'id', // id, date, qty
sortDesc: false
};
// --- 导航与通用模态框 ---
function openModal(id) {
const modal = document.getElementById(id);
if (modal) {
modal.style.display = 'flex';
modal.offsetHeight; // force reflow
modal.classList.add('show');
}
}
function openHelp() {
openModal('helpModal');
}
// 侧边栏分类筛选模拟
function filterCategory(category) {
// 重置所有选中状态
document.querySelectorAll('#sidebarList a').forEach(a => {
a.style.color = '';
a.style.backgroundColor = '';
});
// 高亮当前简单处理实际应传this
showToast(`正在切换至视图: ${category}`, 'info');
// 模拟数据筛选逻辑
if (category === 'all') {
state.filteredData = [...state.data];
document.querySelector('.main-content h2').innerText = '库存列表 - 所有';
} else if (category === 'urgent') {
document.querySelector('.main-content h2').innerText = '库存列表 - 急需补货';
state.filteredData = state.data.filter(d => d.status === 'CRITICAL' || d.status === 'LOW');
} else if (category === 'normal') {
document.querySelector('.main-content h2').innerText = '库存列表 - 正常状态';
state.filteredData = state.data.filter(d => d.status === 'NORMAL');
} else if (category === 'out_a') {
document.querySelector('.main-content h2').innerText = '出库审批 - A 区';
// 随机造一点假象
state.filteredData = state.data.filter(d => d.id.endsWith('1') || d.id.endsWith('3'));
} else if (category === 'out_b') {
document.querySelector('.main-content h2').innerText = '出库审批 - B 区';
state.filteredData = state.data.filter(d => d.id.endsWith('2') || d.id.endsWith('4'));
}
// 重置分页
state.currentPage = 1;
renderTable();
}
// --- 1. 数据生成器 (模拟后端数据库) ---
function generateMockData() {
console.time("DataGeneration");
const data = [];
for (let i = 1; i <= CONFIG.totalItems; i++) {
const padId = String(i).padStart(4, '0');
const typeIdx = Math.floor(Math.random() * CONFIG.components.length);
const supplIdx = Math.floor(Math.random() * CONFIG.suppliers.length);
const statusIdx = Math.random() > 0.8 ? (Math.random() > 0.5 ? 2 : 1) : 0; // 大部分正常
// 随机日期 (过去2年内)
const date = new Date(Date.now() - Math.floor(Math.random() * 63072000000));
const batchYear = date.getFullYear();
const batchCode = `BATCH_${batchYear}_${String.fromCharCode(65 + Math.floor(Math.random() * 26))}${Math.floor(Math.random()*100)}`;
data.push({
id: `8821${padId}`,
name: CONFIG.components[typeIdx],
supplier: CONFIG.suppliers[supplIdx],
batch: batchCode,
qty: Math.floor(Math.random() * 10000),
weight: (Math.random() * 10).toFixed(2),
date: date.toISOString().split('T')[0],
status: CONFIG.statuses[statusIdx],
notes: "自动生成的模拟数据记录..."
});
}
console.timeEnd("DataGeneration");
return data;
}
// --- 2. 核心渲染逻辑 ---
function init() {
showToast("系统初始化中...", "info");
state.data = generateMockData();
applyFilter(); // 初始筛选(就是全量)
console.log(`Loaded ${state.data.length} records.`);
// 绑定事件
document.getElementById('editForm').addEventListener('submit', (e) => { e.preventDefault(); saveEdit(); });
}
// 筛选与排序
function applyFilter() {
// 简单模拟:获取搜索框的值 (这里简化了实际可以读取DOM)
// 省略复杂的DOM读取直接用全部数据演示分页
state.filteredData = [...state.data];
// 排序
state.filteredData.sort((a, b) => {
let valA = a[state.sortBy];
let valB = b[state.sortBy];
if (state.sortBy === 'qty' || state.sortBy === 'weight') {
valA = parseFloat(valA);
valB = parseFloat(valB);
}
if (valA < valB) return state.sortDesc ? 1 : -1;
if (valA > valB) return state.sortDesc ? -1 : 1;
return 0;
});
state.currentPage = 1;
renderTable();
}
function renderTable() {
const tbody = document.getElementById('tableBody');
tbody.innerHTML = ''; // 清空
const start = (state.currentPage - 1) * state.pageSize;
const end = Math.min(start + state.pageSize, state.filteredData.length);
const pageData = state.filteredData.slice(start, end);
if (pageData.length === 0) {
tbody.innerHTML = '<tr><td colspan="9" align="center" style="padding:20px;">没有找到匹配的数据</td></tr>';
return;
}
pageData.forEach(item => {
const tr = document.createElement('tr');
tr.className = 'data-row';
// 状态样式
let statusColor = 'green';
if (item.status === 'LOW') statusColor = 'orange';
if (item.status === 'CRITICAL' || item.status === 'DAMAGED') statusColor = 'red';
tr.innerHTML = `
<td align="center"><input type="checkbox" class="row-check" value="${item.id}"></td>
<td><font face="monospace">#${item.id}</font></td>
<td>
<strong>${item.name}</strong><br>
<small style="color:#666">供应商: ${item.supplier}</small>
</td>
<td><code style="background:#f1f5f9; padding:2px;">${item.batch}</code></td>
<td>${item.qty.toLocaleString()}</td>
<td>${item.weight}g</td>
<td>${item.date}</td>
<td><span style="color:${statusColor}; font-weight:bold; font-size:0.85rem;">${item.status}</span></td>
<td class="action-group">
<a href="javascript:void(0)" class="btn-view" onclick="openDetail('${item.id}')">[详情]</a>
<a href="javascript:void(0)" class="btn-edit" onclick="openEdit('${item.id}')">[编辑]</a>
<a href="javascript:void(0)" class="btn-danger" onclick="deleteItem('${item.id}', this)">[删]</a>
</td>
`;
tbody.appendChild(tr);
});
renderPagination(start, end, state.filteredData.length);
}
function renderPagination(start, end, total) {
document.getElementById('startRecord').innerText = total === 0 ? 0 : start + 1;
document.getElementById('endRecord').innerText = end;
document.getElementById('totalRecords').innerText = total;
const controls = document.getElementById('paginationControls');
controls.innerHTML = '';
const totalPages = Math.ceil(total / state.pageSize);
// 简单的分页算法:首页,上一页,当前页-1, 当前页, 当前页+1, 下一页,末页
const createBtn = (text, page, active = false, disabled = false) => {
const btn = document.createElement('button');
btn.className = `page-btn ${active ? 'active' : ''}`;
btn.innerText = text;
btn.disabled = disabled;
if (!disabled) btn.onclick = () => { state.currentPage = page; renderTable(); };
return btn;
};
controls.appendChild(createBtn('<<', 1, false, state.currentPage === 1));
controls.appendChild(createBtn('<', state.currentPage - 1, false, state.currentPage === 1));
// 显示当前页附近
let pStart = Math.max(1, state.currentPage - 2);
let pEnd = Math.min(totalPages, state.currentPage + 2);
for (let p = pStart; p <= pEnd; p++) {
controls.appendChild(createBtn(p, p, p === state.currentPage));
}
controls.appendChild(createBtn('>', state.currentPage + 1, false, state.currentPage === totalPages));
controls.appendChild(createBtn('>>', totalPages, false, state.currentPage === totalPages));
}
// --- 3. 交互逻辑 ---
// 改变每页显示数量
function changePageSize() {
const select = document.getElementById('pageSizeSelect');
state.pageSize = parseInt(select.value);
state.currentPage = 1;
renderTable();
showToast(`每页显示 ${state.pageSize}`, "info");
}
// 模态框控制
function closeModal(result) {
const modal = document.getElementById(result); // 这里 result 实际上是 ID
modal.classList.remove('show');
setTimeout(() => { modal.style.display = 'none'; }, 300);
}
// 打开编辑模态框
function openEdit(id) {
const item = state.data.find(d => d.id === id);
if (!item) return;
// 填充表单
document.getElementById('edit_id').value = item.id;
document.getElementById('edit_name').value = item.name;
document.getElementById('edit_supplier').value = item.supplier;
document.getElementById('edit_qty').value = item.qty;
document.getElementById('edit_weight').value = item.weight;
document.getElementById('edit_status').value = item.status;
document.getElementById('edit_notes').value = item.notes || "";
const modal = document.getElementById('editModal');
modal.style.display = 'flex';
// 强制重绘以触发 transition
modal.offsetHeight;
modal.classList.add('show');
}
function saveEdit() {
const id = document.getElementById('edit_id').value;
const newName = document.getElementById('edit_name').value;
const newQty = parseInt(document.getElementById('edit_qty').value);
// 更新本地数据
const idx = state.data.findIndex(d => d.id === id);
if (idx !== -1) {
state.data[idx].name = newName;
state.data[idx].qty = newQty;
state.data[idx].supplier = document.getElementById('edit_supplier').value;
state.data[idx].status = document.getElementById('edit_status').value;
state.data[idx].weight = document.getElementById('edit_weight').value;
// 重要:更新 filteredData 里的引用(其实是同一个对象,但如果重新过滤可能需要刷新)
}
closeModal('editModal');
showToast("保存成功!数据已更新。", "success");
renderTable(); // 重新渲染当前页
}
// 打开详情模态框
function openDetail(id) {
const item = state.data.find(d => d.id === id);
if(!item) return;
document.getElementById('detail_id').innerText = item.id;
document.getElementById('detail_name').innerText = item.name;
document.getElementById('detail_batch').innerText = item.batch;
document.getElementById('detail_qty').innerText = item.qty.toLocaleString();
document.getElementById('detail_date').innerText = item.date;
document.getElementById('detail_status').innerText = item.status;
// 模拟生成一些历史记录
const historyList = document.getElementById('detail_history');
historyList.innerHTML = '';
for(let i=0; i<3; i++) {
historyList.innerHTML += `<li>${new Date().toLocaleDateString()} - 系统自动审核通过 (Audit Log #${Math.floor(Math.random()*9000)})</li>`;
}
const modal = document.getElementById('detailModal');
modal.style.display = 'flex';
modal.offsetHeight;
modal.classList.add('show');
}
function printDetail() {
alert("正在连接打印机... \n(模拟: 发送指令 PCL_PRINT_JOB_001)");
}
// 删除项目
function deleteItem(id, btnElement) {
if(confirm(`确定要删除物料 ${id} 吗?`)) {
// 这只是前端模拟,实际应该发请求
state.data = state.data.filter(d => d.id !== id);
applyFilter(); // 重新走一遍筛选和排序
showToast(`物料 ${id} 已删除`, "warning");
}
}
// 批量操作
function executeBatchAction() {
const select = document.getElementById('batchActionSelect');
const action = select.value;
const checks = document.querySelectorAll('.row-check:checked');
if (checks.length === 0) {
showToast("请先选择至少一项数据!", "error");
return;
}
if (select.selectedIndex === 0) {
showToast("请选择一个有效的操作类型", "warning");
} else {
// 模拟进度条
showToast(`正在处理 ${checks.length} 条数据: ${action}...`, "info");
setTimeout(() => {
showToast("批量操作完成!", "success");
// 取消所有勾选
checks.forEach(c => c.checked = false);
document.getElementById('selectAll').checked = false;
}, 1500);
}
}
// Toast 提示工具
function showToast(message, type = 'info') {
const container = document.getElementById('toastContainer');
const toast = document.createElement('div');
toast.className = `toast toast-${type}`;
let icon = '';
if (type === 'success') icon = '✅';
if (type === 'error') icon = '❌';
if (type === 'warning') icon = '⚠️';
toast.innerHTML = `
<div style="display:flex; align-items:center; gap:10px;">
<span style="font-size:1.2rem;">${icon}</span>
<span>${message}</span>
</div>
<span style="cursor:pointer; opacity:0.5;" onclick="this.parentElement.remove()">&times;</span>
`;
container.appendChild(toast);
// 动画
requestAnimationFrame(() => toast.classList.add('show'));
// 自动消失
setTimeout(() => {
toast.classList.remove('show');
setTimeout(() => toast.remove(), 300);
}, 3000);
}
// 全选功能
document.getElementById('selectAll').addEventListener('change', function(e) {
const isChecked = e.target.checked;
document.querySelectorAll('.row-check').forEach(cb => cb.checked = isChecked);
});
// 启动
window.onload = init;
</script>
</body>
</html>