77 lines
4.0 KiB
HTML
77 lines
4.0 KiB
HTML
<!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="../css/common.css">
|
|
</head>
|
|
<body>
|
|
<div id="app">
|
|
<header class="header" id="header"></header>
|
|
<div class="body">
|
|
<aside class="sidebar" id="sidebar"></aside>
|
|
<main class="main">
|
|
<h1 class="page-title">冲突预警</h1>
|
|
<div class="toolbar">
|
|
<button class="btn btn-primary" onclick="autoResolve()">一键应用建议</button>
|
|
<select id="severityFilter" class="btn" style="padding:7px 10px" onchange="render()">
|
|
<option value="">全部级别</option><option value="CRITICAL">致命</option><option value="MAJOR">严重</option><option value="MINOR">警告</option>
|
|
</select>
|
|
<select id="typeFilter" class="btn" style="padding:7px 10px" onchange="render()">
|
|
<option value="">全部类型</option><option value="CAPACITY">产能</option><option value="MATERIAL">物料</option><option value="EQUIPMENT">设备</option><option value="DELAY">交期</option>
|
|
</select>
|
|
</div>
|
|
<div class="card">
|
|
<div class="card-body table-wrap">
|
|
<table id="conflictTable">
|
|
<thead><tr><th>级别</th><th>类型</th><th>资源</th><th>描述</th><th>建议方案</th><th>状态</th><th>操作</th></tr></thead>
|
|
<tbody></tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
<script src="../js/data.js"></script>
|
|
<script src="../js/common.js"></script>
|
|
<script>
|
|
initPage('conflicts');
|
|
function render() {
|
|
const sev = document.getElementById('severityFilter').value;
|
|
const type = document.getElementById('typeFilter').value;
|
|
const tbody = document.querySelector('#conflictTable tbody');
|
|
const rows = apsData.conflicts.filter(c => {
|
|
if (sev && c.severity !== sev) return false;
|
|
if (type && c.conflictType !== type) return false;
|
|
return true;
|
|
}).sort((a, b) => { const rank = { CRITICAL:3, MAJOR:2, MINOR:1 }; return (rank[b.severity] || 0) - (rank[a.severity] || 0) || b.id - a.id; });
|
|
tbody.innerHTML = rows.map(c => `
|
|
<tr>
|
|
<td>${statusBadge(c.severity, { CRITICAL:'danger', MAJOR:'warning', MINOR:'info' })}</td>
|
|
<td>${c.conflictType}</td>
|
|
<td class="text-muted">${c.resourceName || c.resourceType || '-'}</td>
|
|
<td>${c.description}</td>
|
|
<td class="text-muted">${c.suggestedSolution}</td>
|
|
<td>${c.isResolved ? '<span class="badge badge-success">已解决</span>' : '<span class="badge badge-default">未解决</span>'}</td>
|
|
<td class="actions">${c.isResolved ? '' : `<button class="btn btn-sm btn-success" onclick="resolve(${c.id})">解决</button>`}</td>
|
|
</tr>`).join('') || '<tr><td colspan="7" class="text-center text-muted">暂无冲突</td></tr>';
|
|
}
|
|
function resolve(id) {
|
|
const c = findById(apsData.conflicts, id);
|
|
c.isResolved = true; c.resolutionAction = c.suggestedSolution; c.resolvedBy = 'admin'; c.resolvedAt = apsData.$utils.fmtDateTime(new Date());
|
|
apsData.logs.unshift({ id: apsData.$utils.nextId('log'), type: 'INFO', category: 'CONSTRAINT', operationType: 'RESOLVE', targetType: 'CONFLICT', targetId: id, action: '解决冲突', description: c.description, operator: 'admin', createdAt: apsData.$utils.fmtDateTime(new Date()) });
|
|
apsData.$utils.save(apsData);
|
|
showToast('冲突已解决', c.suggestedSolution); render();
|
|
}
|
|
function autoResolve() {
|
|
let count = 0;
|
|
apsData.conflicts.filter(c => !c.isResolved).forEach(c => { c.isResolved = true; c.resolutionAction = c.suggestedSolution; c.resolvedBy = 'admin'; c.resolvedAt = apsData.$utils.fmtDateTime(new Date()); count++; });
|
|
apsData.$utils.save(apsData);
|
|
showToast('一键应用完成', `已处理 ${count} 条冲突建议`); render();
|
|
}
|
|
render();
|
|
</script>
|
|
</body>
|
|
</html>
|