ERP/frontend/js/components/shipment-query.js
2026-03-26 10:16:19 +08:00

272 lines
9.6 KiB
JavaScript
Executable File

Router.register('/shipments/query', async () => {
// 获取当前用户信息
let userRole = null;
try {
const userRes = await fetch('/api/auth/me', { credentials: 'include' });
const userData = await userRes.json();
userRole = userData.role;
} catch (e) {
console.error('Failed to get user info:', e);
}
setTimeout(async () => {
const queryTypeSelect = document.getElementById('query-type');
const queryBtn = document.getElementById('query-btn');
const queryInput = document.getElementById('query-input');
const inputLabel = document.getElementById('input-label');
const resultDiv = document.getElementById('query-result');
const statsDiv = document.getElementById('redis-stats');
const clearBtn = document.getElementById('clear-redis-btn');
// 加载统计信息
const loadStats = async () => {
try {
const res = await fetch('/api/shipments/redis-stats', {
credentials: 'include'
});
const data = await res.json();
if (data.count !== undefined) {
statsDiv.innerHTML = `
<div style="display:flex;align-items:center;gap:12px">
<span style="color:var(--text-2)">数据库出货数量:</span>
<span style="font-weight:600;font-size:18px;color:var(--primary)">${data.count}</span>
</div>
`;
}
} catch (e) {
statsDiv.innerHTML = '<div style="color:var(--text-2)">无法获取统计信息</div>';
}
};
// 初始加载统计
await loadStats();
// 根据用户角色控制清空按钮的显示
if (clearBtn) {
if (userRole !== 'superadmin') {
clearBtn.style.display = 'none';
}
}
// 切换查询类型时更新输入框提示
queryTypeSelect?.addEventListener('change', (e) => {
const queryType = e.target.value;
if (queryType === 'sn') {
inputLabel.textContent = '输入 SN/MAC 号';
queryInput.placeholder = '输入 SN 或 MAC 地址';
} else if (queryType === 'box') {
inputLabel.textContent = '输入箱号';
queryInput.placeholder = '输入箱号';
}
resultDiv.innerHTML = '';
});
const performQuery = async () => {
const queryType = queryTypeSelect?.value || 'sn';
const queryValue = queryInput?.value?.trim();
if (!queryValue) {
resultDiv.innerHTML = `<div class="error">请输入${queryType === 'sn' ? 'SN/MAC 号' : '箱号'}</div>`;
return;
}
try {
resultDiv.innerHTML = '<div>查询中...</div>';
let res, data;
if (queryType === 'sn') {
// 按 SN 查询
res = await fetch(`/api/shipments/query-by-sn?sn=${encodeURIComponent(queryValue)}`, {
credentials: 'include'
});
data = await res.json();
if (data.found) {
resultDiv.innerHTML = `
<div class="result-card success">
<div class="result-title">✓ 找到出货记录</div>
<div class="result-item"><span class="label">SN/MAC:</span> ${data.sn}</div>
<div class="result-item"><span class="label">机种:</span> <span class="badge">${data.platform_name || '未知'}</span></div>
<div class="result-item"><span class="label">出货日期:</span> ${data.date}</div>
<div class="result-item"><span class="label">箱号:</span> ${data.box}</div>
<div class="result-item"><span class="label">记录时间:</span> ${data.ts}</div>
</div>
`;
} else {
resultDiv.innerHTML = `
<div class="result-card error">
<div class="result-title">✗ 未找到记录</div>
<div class="result-item">SN/MAC: ${data.sn}</div>
<div class="result-item">${data.message || '该 SN 没有出货记录'}</div>
</div>
`;
}
} else if (queryType === 'box') {
// 按箱号查询
res = await fetch(`/api/shipments/query-by-box?box=${encodeURIComponent(queryValue)}`, {
credentials: 'include'
});
data = await res.json();
if (data.found) {
const recordsHtml = data.records.map((record, index) => `
<div style="padding:8px 12px;background:var(--surface);border:1px solid var(--border);border-radius:4px;margin-bottom:6px">
<div style="font-weight:600;margin-bottom:6px;color:var(--primary)">记录 ${index + 1}</div>
<div class="result-item"><span class="label">SN/MAC:</span> ${record.sn}</div>
<div class="result-item"><span class="label">机种:</span> <span class="badge">${record.platform_name || '未知'}</span></div>
<div class="result-item"><span class="label">出货日期:</span> ${record.date}</div>
<div class="result-item"><span class="label">记录时间:</span> ${record.ts}</div>
</div>
`).join('');
resultDiv.innerHTML = `
<div class="result-card success">
<div class="result-title">✓ 找到出货记录</div>
<div class="result-item"><span class="label">箱号:</span> ${data.box}</div>
<div class="result-item"><span class="label">记录数量:</span> <span style="font-weight:600;color:var(--primary)">${data.count}</span></div>
<div style="margin-top:16px;max-height:50vh;overflow-y:auto;padding-right:8px;border:1px solid var(--border);border-radius:6px;background:var(--bg)">
${recordsHtml}
</div>
</div>
`;
} else {
resultDiv.innerHTML = `
<div class="result-card error">
<div class="result-title">✗ 未找到记录</div>
<div class="result-item">箱号: ${data.box}</div>
<div class="result-item">${data.message || '该箱号没有出货记录'}</div>
</div>
`;
}
}
} catch (e) {
resultDiv.innerHTML = `<div class="error">查询失败:${e.message}</div>`;
}
};
const clearRedis = async () => {
if (!confirm('确定要清空所有发货记录吗?此操作不可恢复!')) {
return;
}
try {
const res = await fetch('/api/shipments/clear-redis', {
method: 'POST',
credentials: 'include'
});
const data = await res.json();
if (data.ok) {
alert(data.message || '清空成功');
await loadStats();
resultDiv.innerHTML = '';
} else {
alert('清空失败:' + (data.error || '未知错误'));
}
} catch (e) {
alert('清空失败:' + e.message);
}
};
queryBtn?.addEventListener('click', performQuery);
// 只有超级管理员才绑定清空按钮事件
if (clearBtn && userRole === 'superadmin') {
clearBtn.addEventListener('click', clearRedis);
}
queryInput?.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
performQuery();
}
});
}, 0);
// 根据用户角色决定是否显示清空按钮
const showClearButton = userRole === 'superadmin';
return `
<style>
#shipment-query-page {
padding: 20px;
background: var(--bg);
}
#shipment-query-page .page-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
#shipment-query-page h1 {
margin: 0;
font-size: 24px;
color: var(--text);
}
#shipment-query-page .content-area {
background: var(--surface);
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
#shipment-query-page .query-section {
padding: 20px;
border-bottom: 1px solid var(--border);
}
#shipment-query-page .result-section {
padding: 20px;
}
#shipment-query-page .stats-box {
padding: 12px;
background: rgba(79,140,255,0.08);
border: 1px solid rgba(79,140,255,0.2);
border-radius: 8px;
margin-bottom: 16px;
}
</style>
<div id="shipment-query-page">
<div class="page-header">
<h1>发货详细记录查询</h1>
${showClearButton ? '<button class="btn" id="clear-redis-btn" style="background:#dc2626;color:white">清空所有记录</button>' : ''}
</div>
<div class="content-area">
<div class="query-section">
<div class="stats-box">
<div id="redis-stats">
<div>加载中...</div>
</div>
</div>
<div class="field" style="margin-bottom:16px">
<label>查询类型</label>
<select id="query-type" class="input">
<option value="sn">按 SN/MAC 查询</option>
<option value="box">按箱号查询</option>
</select>
</div>
<div class="field" style="margin-bottom:16px">
<label id="input-label">输入 SN/MAC 号</label>
<input
id="query-input"
class="input"
placeholder="输入 SN 或 MAC 地址"
style="font-family: monospace"
/>
</div>
<div class="actions">
<button class="btn btn-primary" id="query-btn">查询</button>
</div>
</div>
<div class="result-section">
<div id="query-result"></div>
</div>
</div>
</div>
`;
});