v1.0.10
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* 文件删除接口(同时删除物理文件) POST /api/document/delete.php
|
||||
* 入参:id(或 ids 逗号分隔批量)
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
require_once __DIR__ . '/../common/logger.php';
|
||||
|
||||
checkAjax();
|
||||
checkPermission('document');
|
||||
|
||||
$id = (int)($_POST['id'] ?? 0);
|
||||
$ids = trim($_POST['ids'] ?? '');
|
||||
$idList = [];
|
||||
if ($id > 0) $idList[] = $id;
|
||||
if ($ids !== '') {
|
||||
foreach (explode(',', $ids) as $v) {
|
||||
$v = (int)trim($v);
|
||||
if ($v > 0) $idList[] = $v;
|
||||
}
|
||||
}
|
||||
$idList = array_unique($idList);
|
||||
if (!$idList) {
|
||||
Response::error('参数错误', 400);
|
||||
}
|
||||
|
||||
$pdo = DB::getInstance()->getPdo();
|
||||
$in = implode(',', array_fill(0, count($idList), '?'));
|
||||
|
||||
// 取出物理路径
|
||||
$stmt = $pdo->prepare("SELECT id, storage_path FROM company_documents WHERE id IN ($in)");
|
||||
$stmt->execute($idList);
|
||||
$docs = $stmt->fetchAll();
|
||||
|
||||
// 删除物理文件(仅限本站上传目录内的文件)
|
||||
foreach ($docs as $doc) {
|
||||
$path = $doc['storage_path'];
|
||||
if (strpos($path, 'static/uploads/documents/') === 0) {
|
||||
$full = __DIR__ . '/../../' . $path;
|
||||
if (is_file($full)) {
|
||||
@unlink($full);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 删除记录(document_links 级联删除)
|
||||
$del = $pdo->prepare("DELETE FROM company_documents WHERE id IN ($in)");
|
||||
$del->execute($idList);
|
||||
$affected = $del->rowCount();
|
||||
|
||||
logCurrent('delete', 'document', 'company_documents', null, ['ids' => $idList]);
|
||||
Response::success(['affected' => $affected], "已删除 $affected 个文件(含物理文件)");
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* 文件列表接口 GET/POST /api/document/list.php
|
||||
* 参数:page / limit / keyword / file_type / is_active
|
||||
* 数据源:company_documents 表
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
|
||||
checkPermission('document');
|
||||
|
||||
[$page, $limit] = pageParams();
|
||||
$keyword = trim($_REQUEST['keyword'] ?? '');
|
||||
$fileType = trim($_REQUEST['file_type'] ?? '');
|
||||
$active = isset($_REQUEST['is_active']) && $_REQUEST['is_active'] !== '' ? (int)$_REQUEST['is_active'] : null;
|
||||
|
||||
$where = ['is_active = 1'];
|
||||
$params = [];
|
||||
if ($active !== null) {
|
||||
$where = ['is_active = ?'];
|
||||
$params = [$active];
|
||||
}
|
||||
if ($keyword !== '') {
|
||||
$where[] = '(doc_name LIKE ? OR document_source LIKE ?)';
|
||||
$like = "%$keyword%";
|
||||
array_push($params, $like, $like);
|
||||
}
|
||||
if ($fileType !== '') { $where[] = 'file_type = ?'; $params[] = $fileType; }
|
||||
$whereSql = implode(' AND ', $where);
|
||||
|
||||
$pdo = DB::getInstance()->getPdo();
|
||||
|
||||
$stmt = $pdo->prepare("SELECT COUNT(*) FROM company_documents WHERE $whereSql");
|
||||
$stmt->execute($params);
|
||||
$total = (int)$stmt->fetchColumn();
|
||||
|
||||
$offset = ($page - 1) * $limit;
|
||||
$stmt = $pdo->prepare(
|
||||
"SELECT id, doc_name, storage_path, file_type, is_current, publish_date, document_source, tags, is_active, created_at
|
||||
FROM company_documents
|
||||
WHERE $whereSql
|
||||
ORDER BY id DESC
|
||||
LIMIT $limit OFFSET $offset"
|
||||
);
|
||||
$stmt->execute($params);
|
||||
$list = $stmt->fetchAll();
|
||||
|
||||
Response::success(['list' => $list, 'total' => $total, 'page' => $page, 'limit' => $limit]);
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* 文件上传接口 POST /api/document/upload.php (multipart/form-data, 字段名 file)
|
||||
* 可选:doc_name(默认取原文件名)/ tags(JSON)
|
||||
* 存储:static/uploads/documents/年/月/随机文件名
|
||||
* 返回:相对路径 storage_path
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
require_once __DIR__ . '/../common/logger.php';
|
||||
|
||||
checkAjax();
|
||||
checkPermission('document');
|
||||
|
||||
if (empty($_FILES['file']) || $_FILES['file']['error'] !== UPLOAD_ERR_OK) {
|
||||
Response::error('请选择要上传的文件', 400);
|
||||
}
|
||||
|
||||
$file = $_FILES['file'];
|
||||
$maxSize = 50 * 1024 * 1024; // 50MB
|
||||
if ($file['size'] > $maxSize) {
|
||||
Response::error('文件不能超过50MB', 400);
|
||||
}
|
||||
|
||||
// 安全扩展名白名单
|
||||
$extMap = [
|
||||
'pdf' => 'application/pdf', 'doc' => 'application/msword',
|
||||
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'xls' => 'application/vnd.ms-excel',
|
||||
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'ppt' => 'application/vnd.ms-powerpoint',
|
||||
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'txt' => 'text/plain', 'csv' => 'text/csv', 'png' => 'image/png',
|
||||
'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'gif' => 'image/gif',
|
||||
'zip' => 'application/zip', 'rar' => 'application/x-rar-compressed',
|
||||
];
|
||||
$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
|
||||
if (!isset($extMap[$ext])) {
|
||||
Response::error('不允许的文件类型:' . ($ext !== '' ? $ext : '无扩展名'), 400);
|
||||
}
|
||||
|
||||
// 目录:static/uploads/documents/年/月
|
||||
$baseDir = __DIR__ . '/../../static/uploads/documents';
|
||||
$subDir = date('Y') . '/' . date('m');
|
||||
$dir = $baseDir . '/' . $subDir;
|
||||
if (!is_dir($dir) && !mkdir($dir, 0777, true)) {
|
||||
Response::error('创建上传目录失败', 500);
|
||||
}
|
||||
|
||||
$newName = date('YmdHis') . '_' . substr(uniqid(), -6) . '.' . $ext;
|
||||
$dest = $dir . '/' . $newName;
|
||||
if (!move_uploaded_file($file['tmp_name'], $dest)) {
|
||||
Response::error('文件保存失败', 500);
|
||||
}
|
||||
|
||||
$storagePath = 'static/uploads/documents/' . $subDir . '/' . $newName;
|
||||
$docName = trim($_POST['doc_name'] ?? '') !== '' ? trim($_POST['doc_name']) : $file['name'];
|
||||
$tags = $_POST['tags'] ?? null;
|
||||
$tagsJson = null;
|
||||
if ($tags !== null && $tags !== '') {
|
||||
$decoded = json_decode($tags, true);
|
||||
$tagsJson = is_array($decoded) ? json_encode($decoded, JSON_UNESCAPED_UNICODE) : null;
|
||||
}
|
||||
|
||||
$pdo = DB::getInstance()->getPdo();
|
||||
$stmt = $pdo->prepare(
|
||||
"INSERT INTO company_documents (doc_name, storage_path, file_type, is_current, document_source, tags)
|
||||
VALUES (?, ?, ?, 1, ?, ?)"
|
||||
);
|
||||
$stmt->execute([$docName, $storagePath, $extMap[$ext], '本地上传', $tagsJson]);
|
||||
$newId = (int)$pdo->lastInsertId();
|
||||
|
||||
logCurrent('upload', 'document', 'company_documents', $newId, ['doc_name' => $docName, 'storage_path' => $storagePath]);
|
||||
Response::success(['id' => $newId, 'storage_path' => $storagePath, 'doc_name' => $docName], '上传成功');
|
||||
Reference in New Issue
Block a user