196 lines
9.8 KiB
HTML
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>
|
|
|