someone-oa/pc/audit-log.html
2025-12-11 19:04:46 +08:00

196 lines
9.8 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>操作日志与审计 - OA系统</title>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 统一布局样式 -->
<link rel="stylesheet" href="unified-layout.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif; background: #f0f2f5; overflow: hidden; }
.layout-container { height: 100vh; display: flex; flex-direction: column; }
.navbar { height: 50px; background:#fff; border-bottom:1px solid #e6e6e6; display:flex; align-items:center; justify-content:space-between; padding:0 20px; box-shadow:0 1px 4px rgba(0,21,41,.08); }
.navbar-left { display:flex; align-items:center; }
.logo { font-size:20px; font-weight:bold; color:#409EFF; cursor:pointer; }
.nav-menu { display:flex; gap:8px; margin-left:16px; }
.nav-item { padding:8px 16px; cursor:pointer; border-radius:4px; color:#303133; }
.nav-item:hover { background:#ecf5ff; color:#409EFF; }
.nav-item.active { background:#409EFF; color:#fff; }
.navbar-right { display:flex; align-items:center; gap:20px; }
.content { flex:1; padding:20px; overflow-y:auto; }
.card { background:#fff; border:1px solid #e6e6e6; border-radius:4px; box-shadow:0 1px 3px rgba(0,0,0,0.04); padding:20px; margin-bottom:16px; }
.page-header { display:flex; justify-content:space-between; align-items:center; margin-bottom:12px; }
.page-title { font-size:18px; font-weight:500; color:#303133; }
.filters { display:flex; gap:10px; flex-wrap:wrap; margin-bottom:12px; }
.form-input, .form-select { height:36px; padding:0 10px; border:1px solid #dcdfe6; border-radius:4px; min-width:150px; }
.btn { padding:8px 14px; border:none; border-radius:4px; cursor:pointer; }
.btn-primary { background:#409EFF; color:#fff; }
.btn-default { background:#fff; color:#303133; border:1px solid #dcdfe6; }
.table { width:100%; border-collapse:collapse; }
.table th, .table td { border:1px solid #ebeef5; padding:10px 12px; color:#606266; font-size:14px; }
.table th { background:#f5f7fa; text-align:left; }
.diff-box { background:#f5f7fa; border:1px solid #ebeef5; border-radius:4px; padding:10px; font-family:Menlo,Consolas,monospace; white-space:pre-wrap; }
.added { color:#67c23a; }
.removed { color:#f56c6c; }
</style>
</head>
<body>
<div id="app">
<div class="layout-container">
<div class="navbar">
<div class="navbar-left">
<div class="logo" onclick="goHome()">OA系统</div>
<div class="nav-menu">
<div class="nav-item" onclick="window.location.href='dashboard.html'">首页</div>
<div class="nav-item" onclick="window.location.href='project-initiation.html'">商机管理</div>
<div class="nav-item" onclick="window.location.href='project-start.html'">过程管理</div>
<div class="nav-item" onclick="window.location.href='finance-invoice.html'">财务管理</div>
<div class="nav-item" onclick="window.location.href='report-project-detail.html'">报表管理</div>
<div class="nav-item active">操作日志</div>
</div>
</div>
<div class="navbar-right">
<span style="color:#303133;">张三</span><span style="color:#909399;margin:0 8px;">|</span>
<a href="profile.html" style="color:#409EFF;text-decoration:none;">个人中心</a>
<span style="color:#909399;">|</span>
<a href="login.html" style="color:#409EFF;text-decoration:none;">退出</a>
</div>
</div>
<div class="content">
<div class="card">
<div class="page-header">
<div class="page-title">操作日志</div>
<div style="display:flex;gap:8px;">
<button class="btn btn-default" onclick="exportLogs()">导出</button>
</div>
</div>
<div class="filters">
<select id="filter-module" class="form-select">
<option value="">模块</option>
<option value="项目">项目</option>
<option value="合同">合同</option>
<option value="发票">发票</option>
<option value="请款">请款</option>
<option value="系统">系统</option>
</select>
<select id="filter-type" class="form-select">
<option value="">操作类型</option>
<option value="新增">新增</option>
<option value="编辑">编辑</option>
<option value="删除">删除</option>
<option value="导出">导出</option>
<option value="登录">登录</option>
</select>
<input type="date" id="filter-start" class="form-input">
<input type="date" id="filter-end" class="form-input">
<input type="text" id="filter-user" class="form-input" placeholder="操作人">
<button class="btn btn-primary" onclick="applyFilters()">查询</button>
<button class="btn btn-default" onclick="resetFilters()">重置</button>
</div>
<table class="table">
<thead>
<tr>
<th>时间</th><th>操作人</th><th>模块</th><th>类型</th><th>对象</th><th>IP</th><th style="width:120px;">操作</th>
</tr>
</thead>
<tbody id="log-body"></tbody>
</table>
</div>
<div class="card">
<div class="page-header">
<div class="page-title">变更对比</div>
<div style="color:#909399;font-size:13px;">展示关键字段修改前后</div>
</div>
<div class="diff-box" id="diffBox">
选择一条编辑日志查看差异
</div>
</div>
</div>
</div>
</div>
<script src="common.js"></script>
<script src="unified-layout.js"></script>
<script>
const logs = [
{ id:1, time:'2024-12-02 10:20', user:'张三', module:'项目', type:'新增', target:'XX工程 25-1', ip:'192.168.1.10', diff:null },
{ id:2, time:'2024-12-02 11:05', user:'李四', module:'合同', type:'编辑', target:'合同 HT-001', ip:'192.168.1.20', diff:{ old:'金额: 1000万', new:'金额: 1200万' } },
{ id:3, time:'2024-12-02 11:30', user:'王五', module:'发票', type:'导出', target:'发票 FP-003', ip:'192.168.1.30', diff:null },
{ id:4, time:'2024-12-02 12:00', user:'张三', module:'系统', type:'登录', target:'Chrome Mac', ip:'192.168.1.40', diff:null }
];
let filtered = [...logs];
function renderTable() {
const tbody = document.getElementById('log-body');
tbody.innerHTML = filtered.map(l => `
<tr>
<td>${l.time}</td>
<td>${l.user}</td>
<td>${l.module}</td>
<td>${l.type}</td>
<td>${l.target}</td>
<td>${l.ip}</td>
<td>
<span class="btn btn-default" style="padding:6px 10px;" onclick="viewDiff(${l.id})">查看</span>
</td>
</tr>
`).join('');
}
function applyFilters() {
const module = document.getElementById('filter-module').value;
const type = document.getElementById('filter-type').value;
const start = document.getElementById('filter-start').value;
const end = document.getElementById('filter-end').value;
const user = document.getElementById('filter-user').value.trim();
filtered = logs.filter(l => {
if (module && l.module !== module) return false;
if (type && l.type !== type) return false;
if (user && !l.user.includes(user)) return false;
if (start && new Date(l.time) < new Date(start)) return false;
if (end && new Date(l.time) > new Date(end + ' 23:59:59')) return false;
return true;
});
renderTable();
}
function resetFilters() {
document.getElementById('filter-module').value = '';
document.getElementById('filter-type').value = '';
document.getElementById('filter-start').value = '';
document.getElementById('filter-end').value = '';
document.getElementById('filter-user').value = '';
filtered = [...logs];
renderTable();
}
function viewDiff(id) {
const item = logs.find(l => l.id === id);
const box = document.getElementById('diffBox');
if (!item || !item.diff) {
box.innerText = '无字段差异或非编辑操作';
return;
}
box.innerHTML = `
<div><span class="removed">- ${item.diff.old}</span></div>
<div><span class="added">+ ${item.diff.new}</span></div>
<div style="color:#909399;font-size:12px;margin-top:6px;">操作人:${item.user} | 时间:${item.time}</div>
`;
}
function exportLogs() {
CommonUtils.exportExcel('操作日志.xlsx');
}
function goHome() { window.location.href = 'dashboard.html'; }
renderTable();
initUnifiedLayout('audit');
</script>
</body>
</html>