aps-agent/aps-frontend/pages/conflicts.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>