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

326 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; justify-content: space-between; align-items: center; margin-bottom: 16px; }
.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: 160px;
}
.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; }
.btn-danger { background: #f56c6c; color: #fff; }
.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; }
.tag { display: inline-block; padding: 2px 8px; border-radius: 10px; background: #ecf5ff; color: #409EFF; font-size: 12px; margin-right: 6px; }
.badge { display: inline-block; padding: 2px 8px; border-radius: 10px; background: #fef0f0; color: #f56c6c; font-size: 12px; }
.grid { display: grid; grid-template-columns: 2fr 1fr; gap: 16px; }
.perm-list { display: flex; flex-direction: column; gap: 10px; }
.perm-item { display: flex; justify-content: space-between; align-items: center; padding: 10px 12px; border: 1px solid #ebeef5; border-radius: 4px; background: #f9fafc; }
.switch { width: 46px; height: 24px; border-radius: 12px; background: #dcdfe6; position: relative; cursor: pointer; transition: all 0.2s; }
.switch.on { background: #409EFF; }
.switch-circle { width: 20px; height: 20px; background: #fff; border-radius: 50%; position: absolute; top: 2px; left: 2px; transition: all 0.2s; }
.switch.on .switch-circle { left: 24px; }
</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="grid">
<!-- 文件列表 -->
<div class="card">
<div class="page-header">
<div class="page-title">文件中心</div>
<div style="display:flex;gap:8px;">
<button class="btn btn-primary" onclick="uploadFile()">上传文件</button>
<button class="btn btn-default" onclick="exportList()">导出列表</button>
</div>
</div>
<div class="filters">
<select id="filter-project" class="form-select">
<option value="">项目</option>
<option value="25-1">25-1 XX工程项目</option>
<option value="25-3">25-3 ZZ工程项目</option>
</select>
<select id="filter-type" class="form-select">
<option value="">类型</option>
<option value="合同">合同</option>
<option value="成果">成果</option>
<option value="开票">开票</option>
<option value="请款">请款</option>
</select>
<select id="filter-perm" class="form-select">
<option value="">权限</option>
<option value="只读">只读</option>
<option value="可下载">可下载</option>
<option value="可删除">可删除</option>
</select>
<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>
<table class="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>上传人/时间</th>
<th style="width:200px;">操作</th>
</tr>
</thead>
<tbody id="file-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="perm-list">
<div class="perm-item">
<div>
<div style="color:#303133;">下载权限</div>
<div style="color:#909399;font-size:13px;">限制仅指定角色可下载</div>
</div>
<div class="switch on" data-key="download" onclick="toggleSwitch(this)">
<div class="switch-circle"></div>
</div>
</div>
<div class="perm-item">
<div>
<div style="color:#303133;">删除权限</div>
<div style="color:#909399;font-size:13px;">仅文件所属人或管理员可删</div>
</div>
<div class="switch on" data-key="delete" onclick="toggleSwitch(this)">
<div class="switch-circle"></div>
</div>
</div>
<div class="perm-item">
<div>
<div style="color:#303133;">预览水印</div>
<div style="color:#909399;font-size:13px;">预览/导出添加用户与时间水印</div>
</div>
<div class="switch on" data-key="watermark" onclick="toggleSwitch(this)">
<div class="switch-circle"></div>
</div>
</div>
<div class="perm-item">
<div>
<div style="color:#303133;">导出审计</div>
<div style="color:#909399;font-size:13px;">导出时记录操作人、时间、IP</div>
</div>
<div class="switch on" data-key="audit" onclick="toggleSwitch(this)">
<div class="switch-circle"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="common.js"></script>
<script src="unified-layout.js"></script>
<script>
const files = [
{ id: 'F-001', name: '合同-25-1-v2.pdf', type: '合同', project: '25-1', version: 'v2', tags: ['正式', '盖章'], perm: '可下载', uploader: '李四', time: '2024-11-30', owner: '李四' },
{ id: 'F-002', name: '成果-25-3-图纸.dwg', type: '成果', project: '25-3', version: 'v1', tags: ['图纸'], perm: '只读', uploader: '王五', time: '2024-11-28', owner: '王五' },
{ id: 'F-003', name: '发票-25-3-12月.pdf', type: '开票', project: '25-3', version: 'v1', tags: ['发票'], perm: '可下载', uploader: '张三', time: '2024-11-26', owner: '张三' }
];
let filtered = [...files];
const switchState = { download: true, delete: true, watermark: true, audit: true };
function applyFilters() {
const project = document.getElementById('filter-project').value;
const type = document.getElementById('filter-type').value;
const perm = document.getElementById('filter-perm').value;
const kw = document.getElementById('filter-keyword').value.trim();
filtered = files.filter(f => {
if (project && f.project !== project) return false;
if (type && f.type !== type) return false;
if (perm && f.perm !== perm) return false;
if (kw && !(f.name.includes(kw) || f.tags.join(',').includes(kw) || f.uploader.includes(kw))) return false;
return true;
});
renderTable();
}
function resetFilters() {
document.getElementById('filter-project').value = '';
document.getElementById('filter-type').value = '';
document.getElementById('filter-perm').value = '';
document.getElementById('filter-keyword').value = '';
filtered = [...files];
renderTable();
}
function renderTable() {
const tbody = document.getElementById('file-body');
tbody.innerHTML = '';
filtered.forEach(f => {
const tr = document.createElement('tr');
tr.innerHTML = `
<td><input type="checkbox" class="row-check" value="${f.id}"></td>
<td>${f.name}</td>
<td>${f.type}</td>
<td>${f.project}</td>
<td>${f.version}</td>
<td>${f.tags.map(t => `<span class="tag">${t}</span>`).join('')}</td>
<td>${f.perm}</td>
<td>${f.uploader} / ${f.time}</td>
<td>
<span class="btn btn-default" style="padding:6px 10px;" onclick="preview('${f.id}')">预览</span>
<span class="btn btn-default" style="padding:6px 10px;" onclick="download('${f.id}')">下载</span>
<span class="btn btn-danger" style="padding:6px 10px;" onclick="removeFile('${f.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 uploadFile() {
CommonUtils.uploadFile('', (file) => {
CommonUtils.showMessage(`已上传:${file.name}`);
// 这里可追加到 files 列表并刷新
}, 100);
}
function preview(id) {
const item = files.find(f => f.id === id);
if (!item) return;
const wm = switchState.watermark ? '<div style="color:#f56c6c;font-size:12px;margin-top:8px;">水印:张三 | ' + new Date().toLocaleString() + '</div>' : '';
CommonUtils.createModal('预览', `
<div style="color:#303133;">${item.name}</div>
<div style="color:#909399;font-size:13px;margin-top:6px;">类型:${item.type} | 版本:${item.version} | 项目:${item.project}</div>
${wm}
`, () => true);
}
function download(id) {
const item = files.find(f => f.id === id);
if (!item) return;
if (!switchState.download && item.perm !== '可下载') {
CommonUtils.showMessage('当前角色无下载权限', 'error');
return;
}
CommonUtils.downloadFile(item.name, item.id);
}
function removeFile(id) {
const item = files.find(f => f.id === id);
if (!item) return;
if (!switchState.delete) {
CommonUtils.showMessage('删除权限已关闭', 'error');
return;
}
CommonUtils.deleteFile(id, item.name, () => {
CommonUtils.showMessage('已删除(示例,不持久化)');
});
}
function exportList() {
CommonUtils.exportExcel('文件中心列表.xlsx');
}
function toggleSwitch(el) {
const key = el.getAttribute('data-key');
switchState[key] = !switchState[key];
el.classList.toggle('on', switchState[key]);
CommonUtils.showMessage((switchState[key] ? '已开启 ' : '已关闭 ') + key);
}
function goHome() { window.location.href = 'dashboard.html'; }
initUnifiedLayout('file');
// 初始化
renderTable();
</script>
</body>
</html>