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

368 lines
16 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;
}
.page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.page-title { font-size: 18px; font-weight: 500; color: #303133; }
.filters { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.form-input, .form-select {
height: 36px;
padding: 0 10px;
border: 1px solid #dcdfe6;
border-radius: 4px;
min-width: 160px;
}
.date-range { display: flex; align-items: center; gap: 6px; }
.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; }
.tabs { display: flex; gap: 12px; margin-bottom: 12px; }
.tab {
padding: 10px 14px;
background: #f5f7fa;
border: 1px solid #e4e7ed;
border-radius: 4px;
cursor: pointer;
color: #606266;
}
.tab.active { background: #409EFF; color: #fff; border-color: #409EFF; }
.actions-bar {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
}
.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; }
.status-badge {
display: inline-block;
padding: 2px 8px;
border-radius: 10px;
font-size: 12px;
color: #fff;
}
.status-wait { background: #e6a23c; }
.status-pass { background: #67c23a; }
.status-reject { background: #f56c6c; }
.status-copy { background: #909399; }
.link-btn { color: #409EFF; cursor: pointer; margin-right: 6px; }
</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="color:#909399;font-size:13px;">快速处理待办并查看历史记录</div>
</div>
<div class="filters">
<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>
<select id="filter-status" class="form-select">
<option value="">状态</option>
<option value="待处理">待处理</option>
<option value="已通过">已通过</option>
<option value="已驳回">已驳回</option>
<option value="已抄送">已抄送</option>
</select>
<div class="date-range">
<input type="date" id="filter-start" class="form-input">
<span style="color:#909399;"></span>
<input type="date" id="filter-end" class="form-input">
</div>
<input type="text" id="filter-keyword" class="form-input" placeholder="项目/单号/提交人">
<button class="btn btn-primary" onclick="applyFilters()">查询</button>
<button class="btn btn-default" onclick="resetFilters()">重置</button>
</div>
<div class="tabs">
<div class="tab active" id="tab-todo" onclick="switchTab('todo')">待办事项</div>
<div class="tab" id="tab-done" onclick="switchTab('done')">已办事项</div>
<div class="tab" id="tab-copy" onclick="switchTab('copy')">抄送事项</div>
</div>
<div class="actions-bar">
<div id="batch-actions">
<button class="btn btn-primary" onclick="batchApprove()">批量同意</button>
<button class="btn btn-default" onclick="batchReject()">批量驳回</button>
<button class="btn btn-default" onclick="batchTransfer()">批量转办</button>
</div>
<div>
<button class="btn btn-default" onclick="exportList()">导出列表</button>
</div>
</div>
<table class="table" id="task-table">
<thead>
<tr>
<th style="width:40px;"><input type="checkbox" id="select-all" onchange="toggleAll(this)"></th>
<th>单号</th>
<th>流程类型</th>
<th>项目</th>
<th>节点/状态</th>
<th>提交人</th>
<th>提交时间</th>
<th style="width:180px;">操作</th>
</tr>
</thead>
<tbody id="table-body"></tbody>
</table>
</div>
</div>
</div>
</div>
<script src="common.js"></script>
<script src="unified-layout.js"></script>
<script>
const tasks = [
{ id: 'LX-202412-001', type: '立项', project: '25-1 XX工程项目', status: '待处理', node: '部门审核', submitter: '李四', time: '2024-12-02', tab: 'todo' },
{ id: 'QD-202412-009', type: '启动', project: '25-3 ZZ工程项目', status: '待处理', node: '财务确认', submitter: '王五', time: '2024-12-03', tab: 'todo' },
{ id: 'CG-202412-005', type: '成果提交', project: '25-1 XX工程项目', status: '已通过', node: '归档', submitter: '张三', time: '2024-11-28', tab: 'done' },
{ id: 'KP-202412-012', type: '开票', project: '25-3 ZZ工程项目', status: '已驳回', node: '财务复核', submitter: '李四', time: '2024-11-26', tab: 'done' },
{ id: 'QK-202412-021', type: '请款', project: '25-3 ZZ工程项目', status: '已抄送', node: '总监已阅', submitter: '赵六', time: '2024-11-25', tab: 'copy' }
];
let activeTab = 'todo';
let filtered = [...tasks];
function switchTab(tab) {
activeTab = tab;
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
document.getElementById(`tab-${tab}`).classList.add('active');
document.getElementById('batch-actions').style.display = tab === 'todo' ? 'flex' : 'none';
renderTable();
}
function applyFilters() {
const type = document.getElementById('filter-type').value;
const status = document.getElementById('filter-status').value;
const start = document.getElementById('filter-start').value;
const end = document.getElementById('filter-end').value;
const kw = document.getElementById('filter-keyword').value.trim();
filtered = tasks.filter(t => {
if (t.tab !== activeTab) return false;
if (type && t.type !== type) return false;
if (status && t.status !== status) return false;
if (start && new Date(t.time) < new Date(start)) return false;
if (end && new Date(t.time) > new Date(end)) return false;
if (kw && !(t.id.includes(kw) || t.project.includes(kw) || t.submitter.includes(kw))) return false;
return true;
});
renderTable();
}
function resetFilters() {
document.getElementById('filter-type').value = '';
document.getElementById('filter-status').value = '';
document.getElementById('filter-start').value = '';
document.getElementById('filter-end').value = '';
document.getElementById('filter-keyword').value = '';
filtered = tasks.filter(t => t.tab === activeTab);
renderTable();
}
function statusBadge(status) {
if (status === '待处理') return '<span class="status-badge status-wait">待处理</span>';
if (status === '已通过') return '<span class="status-badge status-pass">已通过</span>';
if (status === '已驳回') return '<span class="status-badge status-reject">已驳回</span>';
return '<span class="status-badge status-copy">已抄送</span>';
}
function renderTable() {
const tbody = document.getElementById('table-body');
tbody.innerHTML = '';
const list = filtered.filter(t => t.tab === activeTab);
list.forEach(item => {
const tr = document.createElement('tr');
tr.innerHTML = `
<td><input type="checkbox" class="row-check" value="${item.id}"></td>
<td>${item.id}</td>
<td>${item.type}</td>
<td>${item.project}</td>
<td>${item.node} ${statusBadge(item.status)}</td>
<td>${item.submitter}</td>
<td>${item.time}</td>
<td>
${activeTab === 'todo' ? `
<span class="link-btn" onclick="approve('${item.id}')">同意</span>
<span class="link-btn" onclick="reject('${item.id}')">驳回</span>
<span class="link-btn" onclick="transfer('${item.id}')">转办</span>
` : ''}
<span class="link-btn" onclick="viewDetail('${item.id}')">查看</span>
</td>
`;
tbody.appendChild(tr);
});
document.getElementById('select-all').checked = false;
}
function toggleAll(checkbox) {
document.querySelectorAll('.row-check').forEach(cb => cb.checked = checkbox.checked);
}
function getSelectedIds() {
return Array.from(document.querySelectorAll('.row-check'))
.filter(cb => cb.checked)
.map(cb => cb.value);
}
function approve(id) {
CommonUtils.confirm(`确定同意 ${id} 吗?`, () => {
CommonUtils.showMessage('已同意');
return true;
});
}
function reject(id) {
CommonUtils.createModal('驳回原因', `
<textarea id="reject-reason" class="form-input" style="height:80px;padding:8px 10px;border:1px solid #dcdfe6;border-radius:4px;"></textarea>
`, () => {
CommonUtils.showMessage('已驳回');
return true;
});
}
function transfer(id) {
CommonUtils.createModal('转办给', `
<input id="transfer-user" class="form-input" placeholder="输入转办人姓名">
`, () => {
const user = document.getElementById('transfer-user').value.trim();
if (!user) {
CommonUtils.showMessage('请输入转办人', 'error');
return false;
}
CommonUtils.showMessage('已转办给 ' + user);
return true;
});
}
function batchApprove() {
const ids = getSelectedIds();
if (!ids.length) return CommonUtils.showMessage('请选择待处理项', 'error');
CommonUtils.confirm(`确定批量同意 ${ids.length} 条?`, () => {
CommonUtils.showMessage('批量同意完成');
return true;
});
}
function batchReject() {
const ids = getSelectedIds();
if (!ids.length) return CommonUtils.showMessage('请选择待处理项', 'error');
CommonUtils.createModal('批量驳回', `
<div style="margin-bottom:8px;color:#606266;">共 ${ids.length} 条,填写驳回原因:</div>
<textarea id="batch-reject-reason" class="form-input" style="height:80px;padding:8px 10px;border:1px solid #dcdfe6;border-radius:4px;"></textarea>
`, () => {
CommonUtils.showMessage('批量驳回完成');
return true;
});
}
function batchTransfer() {
const ids = getSelectedIds();
if (!ids.length) return CommonUtils.showMessage('请选择待处理项', 'error');
CommonUtils.createModal('批量转办', `
<div style="margin-bottom:8px;color:#606266;">共 ${ids.length} 条,选择转办人:</div>
<input id="batch-transfer-user" class="form-input" placeholder="输入转办人姓名">
`, () => {
const user = document.getElementById('batch-transfer-user').value.trim();
if (!user) {
CommonUtils.showMessage('请输入转办人', 'error');
return false;
}
CommonUtils.showMessage(`已批量转办给 ${user}`);
return true;
});
}
function viewDetail(id) {
CommonUtils.showMessage('查看详情:' + id);
// 可跳转到具体流程详情页
}
function exportList() {
CommonUtils.exportExcel('审批中心列表.xlsx');
}
function goHome() { window.location.href = 'dashboard.html'; }
initUnifiedLayout('approval');
// 初始化
resetFilters();
switchTab('todo');
</script>
</body>
</html>