初始化

This commit is contained in:
2026-08-08 18:28:49 +08:00
parent 9bef4420e0
commit f082037a6e
854 changed files with 217171 additions and 11 deletions
+350
View File
@@ -0,0 +1,350 @@
<?php
/**
* 文件管理工位视图
*
* 管理员:可上传、删除、打开文件
* 操作员:只能查看和打开文件
*
* 所需变量:
* $user - 当前用户
* $sysConfig - 系统配置
* $stations - 所有工位列表
* $documents - 文档列表
* $categories - 文档分类列表
* $csrfToken - CSRF token
* $isAdmin - 是否为管理员
*/
$activeStation = 'document_manage';
$title = '文件管理';
include APP_PATH . 'app/views/layouts/station_header.php';
// 权限判断
$isAdmin = ($user['role'] === \core\base\Controller::ROLE_SUPER_ADMIN
|| $user['role'] === \core\base\Controller::ROLE_ADMIN);
?>
<div class="content">
<a href="<?php echo BASE_URL; ?>/Front/index" class="back-link"><i class="fa fa-arrow-left"></i> 返回工位选择</a>
<div class="page-title-bar">
<div>
<h1><i class="fa fa-folder-open"></i> 文件管理</h1>
</div>
<div class="today-count-badge">
<i class="fa fa-user"></i> <?php echo htmlspecialchars($user['emp_name'] ?? ''); ?>
&nbsp;共:<span class="count-num" id="docCount"><?php echo count($documents); ?></span> 个文件
</div>
</div>
<!-- 搜索和筛选区 -->
<div class="card" style="margin-bottom:12px;">
<div class="card-body" style="padding:12px 16px;">
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;">
<input type="text" id="searchInput" class="form-control" placeholder="搜索文件名称..."
style="max-width:300px;">
<select id="categoryFilter" class="form-control" style="max-width:200px;">
<option value="">全部分类</option>
<?php foreach ($categories as $cat): ?>
<option value="<?php echo htmlspecialchars($cat['category']); ?>">
<?php echo htmlspecialchars($cat['category']); ?>
</option>
<?php endforeach; ?>
</select>
<?php if ($isAdmin): ?>
<button type="button" class="btn btn-primary" id="uploadBtn" style="margin-left:auto;">
<i class="fa fa-upload"></i> 上传文件
</button>
<?php endif; ?>
</div>
</div>
</div>
<?php if ($isAdmin): ?>
<!-- 上传表单(默认隐藏) -->
<div class="card" id="uploadCard" style="display:none;margin-bottom:12px;">
<div class="card-header">
<h3><i class="fa fa-upload"></i> 上传文件</h3>
<button type="button" class="btn btn-sm btn-warning" id="cancelUploadBtn">
<i class="fa fa-times"></i> 取消
</button>
</div>
<div class="card-body">
<form id="uploadForm" method="post" enctype="multipart/form-data" action="<?php echo BASE_URL; ?>/Front/documentManageUpload">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
<div class="row" style="display:flex;flex-wrap:wrap;gap:12px;">
<div class="station-field-item" style="flex:1;min-width:200px;">
<label>文档标题 <span class="text-danger">*</span></label>
<input type="text" name="title" class="form-control" placeholder="输入文档标题" required>
</div>
<div class="station-field-item" style="flex:1;min-width:150px;">
<label>文档编号</label>
<input type="text" name="doc_no" class="form-control" placeholder="如:SOP-001">
</div>
<div class="station-field-item" style="flex:1;min-width:150px;">
<label>分类</label>
<input type="text" name="category" class="form-control" placeholder="如:操作规程" list="categoryList">
<datalist id="categoryList">
<?php foreach ($categories as $cat): ?>
<option value="<?php echo htmlspecialchars($cat['category']); ?>">
<?php endforeach; ?>
</datalist>
</div>
<div class="station-field-item" style="flex:1;min-width:100px;">
<label>版本</label>
<input type="text" name="version" class="form-control" value="1.0" placeholder="版本号">
</div>
</div>
<div class="row" style="display:flex;flex-wrap:wrap;gap:12px;margin-top:12px;">
<div class="station-field-item" style="flex:1;min-width:200px;">
<label>选择文件 <span class="text-danger">*</span></label>
<input type="file" name="doc_file" class="form-control" required
accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.csv,.zip,.rar,.jpg,.jpeg,.png,.gif">
</div>
<div class="station-field-item" style="flex:1;min-width:200px;">
<label>描述</label>
<input type="text" name="description" class="form-control" placeholder="简要描述">
</div>
</div>
<div style="margin-top:12px;">
<button type="submit" class="btn btn-success btn-lg">
<i class="fa fa-cloud-upload"></i> 确认上传
</button>
<span id="uploadStatus" style="margin-left:10px;color:var(--primary);display:none;">
<i class="fa fa-spinner fa-spin"></i> 上传中...
</span>
</div>
</form>
</div>
</div>
<?php endif; ?>
<!-- 文件列表 -->
<div class="card">
<div class="card-header">
<h3><i class="fa fa-list"></i> 文件列表</h3>
</div>
<div class="card-body no-padding">
<div class="table-wrap">
<table class="table" id="docTable">
<thead>
<tr>
<th data-col="title" style="text-align:left;padding-left:16px;">文件名称</th>
<th data-col="category">分类</th>
<th data-col="version">版本</th>
<th data-col="file_size">大小</th>
<th data-col="operator">上传人</th>
<th data-col="created_at">上传时间</th>
<th data-col="actions">操作</th>
</tr>
</thead>
<tbody>
<?php if (!empty($documents)): ?>
<?php foreach ($documents as $doc):
$sizeStr = '';
$fs = (int)($doc['file_size'] ?? 0);
if ($fs > 1048576) $sizeStr = round($fs / 1048576, 1) . ' MB';
elseif ($fs > 1024) $sizeStr = round($fs / 1024, 1) . ' KB';
else $sizeStr = $fs . ' B';
$fileExt = strtolower($doc['file_type'] ?? '');
$fileIcon = 'fa-file-o';
if (in_array($fileExt, ['pdf'])) $fileIcon = 'fa-file-pdf-o';
elseif (in_array($fileExt, ['doc','docx'])) $fileIcon = 'fa-file-word-o';
elseif (in_array($fileExt, ['xls','xlsx','csv'])) $fileIcon = 'fa-file-excel-o';
elseif (in_array($fileExt, ['ppt','pptx'])) $fileIcon = 'fa-file-powerpoint-o';
elseif (in_array($fileExt, ['jpg','jpeg','png','gif'])) $fileIcon = 'fa-file-image-o';
elseif (in_array($fileExt, ['zip','rar'])) $fileIcon = 'fa-file-archive-o';
elseif (in_array($fileExt, ['txt'])) $fileIcon = 'fa-file-text-o';
?>
<tr class="doc-row" data-title="<?php echo htmlspecialchars(mb_strtolower($doc['title'] ?? '')); ?>"
data-category="<?php echo htmlspecialchars($doc['category'] ?? ''); ?>">
<td data-col="title" style="text-align:left;padding-left:16px;">
<i class="fa <?php echo $fileIcon; ?>" style="color:var(--primary);margin-right:6px;"></i>
<strong><?php echo htmlspecialchars($doc['title']); ?></strong>
<?php if (!empty($doc['description'])): ?>
<br><small class="text-muted"><?php echo htmlspecialchars(mb_substr($doc['description'], 0, 60)); ?><?php echo mb_strlen($doc['description']) > 60 ? '...' : ''; ?></small>
<?php endif; ?>
</td>
<td data-col="category">
<?php if (!empty($doc['category'])): ?>
<span class="label label-info"><?php echo htmlspecialchars($doc['category']); ?></span>
<?php else: ?>
<span class="text-muted">-</span>
<?php endif; ?>
</td>
<td data-col="version"><?php echo htmlspecialchars($doc['version'] ?? '1.0'); ?></td>
<td data-col="file_size"><?php echo $sizeStr; ?></td>
<td data-col="operator"><?php echo htmlspecialchars($doc['operator'] ?? '-'); ?></td>
<td data-col="created_at"><?php echo htmlspecialchars($doc['created_at'] ?? '-'); ?></td>
<td data-col="actions">
<?php if (!empty($doc['file_path'])): ?>
<a href="<?php echo BASE_URL . htmlspecialchars($doc['file_path']); ?>"
class="btn btn-xs btn-info" target="_blank" title="打开文件">
<i class="fa fa-external-link"></i> 打开
</a>
<a href="<?php echo BASE_URL . htmlspecialchars($doc['file_path']); ?>"
class="btn btn-xs btn-info" download title="下载文件">
<i class="fa fa-download"></i> 下载
</a>
<?php else: ?>
<span class="text-muted">无文件</span>
<?php endif; ?>
<?php if ($isAdmin): ?>
<button type="button" class="btn btn-xs btn-danger doc-del-btn"
data-id="<?php echo $doc['id']; ?>" data-title="<?php echo htmlspecialchars($doc['title'], ENT_QUOTES); ?>"
title="删除文件">
<i class="fa fa-trash"></i>
</button>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="7">
<div class="empty-state">
<i class="fa fa-folder-open-o"></i>
<p>暂无文件,<?php echo $isAdmin ? '请点击「上传文件」添加' : '请联系管理员上传'; ?></p>
</div>
</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<script nonce="<?php echo csp_nonce(); ?>">
var BASE_URL = '<?php echo BASE_URL; ?>';
// ========== 搜索和筛选 ==========
function filterDocuments() {
var searchText = ($('#searchInput').val() || '').toLowerCase();
var category = $('#categoryFilter').val() || '';
var visibleCount = 0;
$('#docTable .doc-row').each(function() {
var title = $(this).data('title') || '';
var rowCat = $(this).data('category') || '';
var match = true;
if (searchText && title.indexOf(searchText) < 0) match = false;
if (category && rowCat !== category) match = false;
if (match) {
$(this).show();
visibleCount++;
} else {
$(this).hide();
}
});
$('#docCount').text(visibleCount);
}
// CSP:搜索/筛选事件绑定(替代内联 oninput/onchange
$('#searchInput').on('input', filterDocuments);
$('#categoryFilter').on('change', filterDocuments);
<?php if ($isAdmin): ?>
// ========== 上传表单 ==========
function showUploadForm() {
$('#uploadCard').slideDown(300);
}
function hideUploadForm() {
$('#uploadCard').slideUp(300);
}
function updateFileName(input) {
// 如果标题为空,自动用文件名填充
var fileName = input.files[0] ? input.files[0].name.replace(/\.[^/.]+$/, '') : '';
if (fileName && !$('#uploadForm input[name="title"]').val()) {
$('#uploadForm input[name="title"]').val(fileName);
}
}
// 上传表单提交
$('#uploadForm').on('submit', function(e) {
e.preventDefault();
var $form = $(this);
var title = $form.find('input[name="title"]').val().trim();
if (!title) {
alert('请输入文档标题');
return;
}
if (!$form.find('input[name="doc_file"]').val()) {
alert('请选择要上传的文件');
return;
}
$('#uploadStatus').show();
var formData = new FormData($form[0]);
$.ajax({
url: $form.attr('action'),
type: 'POST',
data: formData,
processData: false,
contentType: false,
dataType: 'json',
success: function(res) {
$('#uploadStatus').hide();
if (res.success) {
alert('文件上传成功!');
location.reload();
} else {
alert('上传失败: ' + (res.error || '未知错误'));
}
},
error: function(xhr) {
$('#uploadStatus').hide();
var msg = '网络错误,请重试';
try {
var r = JSON.parse(xhr.responseText);
if (r && r.error) msg = r.error;
else if (xhr.responseText) msg = xhr.responseText;
} catch (e) {
if (xhr.responseText) msg = xhr.responseText;
}
alert(msg);
}
});
});
// ========== 删除文件 ==========
function deleteDocument(id, title) {
if (!confirm('确定删除文件「' + title + '」吗?\n此操作不可撤销。')) return;
$.ajax({
url: BASE_URL + '/Front/documentManageDelete',
type: 'POST',
data: {
id: id,
csrf_token: '<?php echo htmlspecialchars($csrfToken); ?>'
},
dataType: 'json',
success: function(res) {
if (res.success) {
alert('文件已删除');
location.reload();
} else {
alert('删除失败: ' + (res.error || '未知错误'));
}
},
error: function() {
alert('网络错误,请重试');
}
});
}
// CSP:上传/删除相关事件绑定(替代内联 onclick/onchange
$('#uploadBtn').on('click', showUploadForm);
$('#cancelUploadBtn').on('click', hideUploadForm);
$('#uploadForm input[name="doc_file"]').on('change', function () { updateFileName(this); });
$('#docTable').on('click', '.doc-del-btn', function () {
deleteDocument($(this).attr('data-id'), $(this).attr('data-title'));
});
<?php endif; ?>
</script>
<?php include APP_PATH . 'app/views/layouts/station_footer.php'; ?>