fix(upload): 改进应用文件名生成逻辑并统一上传路径

refactor(version_control): 重构版本控制文件处理逻辑

- 在upload_app.php和version_control.php中:
  - 使用6位随机数和清理后的应用名称生成文件名
  - 统一上传路径到uploads/apps目录
  - 添加500MB文件大小限制
  - 改进错误处理和日志记录

- 在version_control.php中:
  - 使用SweetAlert替代原生确认对话框
  - 优化文件删除逻辑
  - 改进版本更新流程
This commit is contained in:
2025-09-23 17:35:57 +08:00
parent f0105ce819
commit 378319117c
81 changed files with 4879 additions and 89 deletions

View File

@@ -88,7 +88,11 @@ if (!($conn instanceof mysqli)) {
$error = '应用文件大小不能超过500MB';
}
$appExtension = pathinfo($appFile['name'], PATHINFO_EXTENSION);
$appFileName = uniqid() . '.' . $appExtension;
// 生成6位随机数
$randomNumber = str_pad(mt_rand(0, 999999), 6, '0', STR_PAD_LEFT);
// 清理应用名称中的特殊字符
$cleanAppName = preg_replace('/[^a-zA-Z0-9_]/', '_', $appName);
$appFileName = $cleanAppName . '_' . $randomNumber . '.' . $appExtension;
$appRelativePath = 'uploads/apps/' . $appFileName;
$appFilePath = __DIR__ . '/../' . $appRelativePath;
if (!move_uploaded_file($appFile['tmp_name'], $appFilePath)) {

View File

@@ -46,47 +46,59 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['upload_version'])) {
$error = '版本号和安装包不能为空';
} else {
// 处理App文件上传
$uploadDir = __DIR__ . '/../files/';
$uploadDir = __DIR__ . '/../uploads/apps/';
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
$fileName = basename($_FILES['app_file']['name']);
$targetPath = $uploadDir . $fileName;
if (move_uploaded_file($_FILES['app_file']['tmp_name'], $targetPath)) {
$version = $_POST['version'];
$changelog = $_POST['changelog'] ?? '';
// 插入新版本记录
$insertVersionSql = "INSERT INTO app_versions (app_id, version, changelog, file_path) VALUES (?, ?, ?, ?)";
$verStmt = $conn->prepare($insertVersionSql);
if (!$verStmt) {
log_error("版本插入准备失败: " . $conn->error, __FILE__, __LINE__);
$error = '版本保存失败,请稍后再试';
unlink($targetPath); // 清理已上传文件
} else {
$verStmt->bind_param("isss", $appId, $version, $changelog, $fileName);
if ($verStmt->execute()) {
// 更新应用表中的最新版本
$updateAppSql = "UPDATE apps SET version = ? WHERE id = ?";
$updStmt = $conn->prepare($updateAppSql);
if (!$updStmt) {
log_error("应用版本更新准备失败: " . $conn->error, __FILE__, __LINE__);
$error = '更新应用版本失败,请稍后再试';
unlink($targetPath); // 数据库更新失败,删除文件
} else {
$updStmt->bind_param("si", $version, $appId);
$updStmt->execute();
$success = '版本上传成功';
}
} else {
$error = '版本保存失败: '. $conn->error;
unlink($targetPath); // 数据库更新失败,删除文件
}
}
// 验证文件大小 (500MB)
if ($_FILES['app_file']['size'] > 500 * 1024 * 1024) {
log_error('应用文件过大: ' . number_format($_FILES['app_file']['size'] / 1024 / 1024, 2) . 'MB', __FILE__, __LINE__);
$error = '应用文件大小不能超过500MB';
} else {
$error = '文件上传失败';
$appExtension = pathinfo($_FILES['app_file']['name'], PATHINFO_EXTENSION);
// 生成6位随机数
$randomNumber = str_pad(mt_rand(0, 999999), 6, '0', STR_PAD_LEFT);
// 清理应用名称中的特殊字符
$cleanAppName = preg_replace('/[^a-zA-Z0-9_]/', '_', $app['name']);
$appFileName = $cleanAppName . '_' . $randomNumber . '.' . $appExtension;
$appRelativePath = 'uploads/apps/' . $appFileName;
$targetPath = $uploadDir . $appFileName;
if (move_uploaded_file($_FILES['app_file']['tmp_name'], $targetPath)) {
$version = $_POST['version'];
$changelog = $_POST['changelog'] ?? '';
// 插入新版本记录
$insertVersionSql = "INSERT INTO app_versions (app_id, version, changelog, file_path) VALUES (?, ?, ?, ?)";
$verStmt = $conn->prepare($insertVersionSql);
if (!$verStmt) {
log_error("版本插入准备失败: " . $conn->error, __FILE__, __LINE__);
$error = '版本保存失败,请稍后再试';
unlink($targetPath); // 清理已上传文件
} else {
$verStmt->bind_param("isss", $appId, $version, $changelog, $appRelativePath);
if ($verStmt->execute()) {
// 更新应用表中的最新版本
$updateAppSql = "UPDATE apps SET version = ? WHERE id = ?";
$updStmt = $conn->prepare($updateAppSql);
if (!$updStmt) {
log_error("应用版本更新准备失败: " . $conn->error, __FILE__, __LINE__);
$error = '更新应用版本失败,请稍后再试';
unlink($targetPath); // 数据库更新失败,删除文件
} else {
$updStmt->bind_param("si", $version, $appId);
$updStmt->execute();
$success = '版本上传成功';
}
} else {
$error = '版本保存失败: '. $conn->error;
unlink($targetPath); // 数据库更新失败,删除文件
}
}
} else {
$error = '文件上传失败';
}
}
}
}
@@ -99,53 +111,64 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['version_id'])) {
// 检查是否有新文件上传
if (!empty($_FILES['new_app_file']['name'])) {
$uploadDir = __DIR__ . '/../files/';
$uploadDir = __DIR__ . '/../uploads/apps/';
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
$fileName = basename($_FILES['new_app_file']['name']);
$newFilePath = $uploadDir . $fileName;
if (move_uploaded_file($_FILES['new_app_file']['tmp_name'], $newFilePath)) {
// 获取旧文件路径并删除
$getOldPathSql = "SELECT file_path FROM app_versions WHERE id = ?";
$getOldPathStmt = $conn->prepare($getOldPathSql);
if (!$getOldPathStmt) {
log_error("获取旧文件路径查询准备失败: " . $conn->error, __FILE__, __LINE__);
$error = '版本修改失败,请稍后再试';
unlink($newFilePath);
} else {
$getOldPathStmt->bind_param("i", $versionId);
$getOldPathStmt->execute();
$oldPathResult = $getOldPathStmt->get_result();
if ($oldPathResult->num_rows > 0) {
$oldPathRow = $oldPathResult->fetch_assoc();
$oldFileName = $oldPathRow['file_path'];
$oldFilePath = $uploadDir . $oldFileName;
if (file_exists($oldFilePath)) {
unlink($oldFilePath);
}
}
// 更新版本信息
$updateVersionSql = "UPDATE app_versions SET version = ?, changelog = ?, file_path = ? WHERE id = ?";
$updateVersionStmt = $conn->prepare($updateVersionSql);
if (!$updateVersionStmt) {
log_error("版本更新查询准备失败: " . $conn->error, __FILE__, __LINE__);
// 验证文件大小 (500MB)
if ($_FILES['new_app_file']['size'] > 500 * 1024 * 1024) {
log_error('应用文件过大: ' . number_format($_FILES['new_app_file']['size'] / 1024 / 1024, 2) . 'MB', __FILE__, __LINE__);
$error = '应用文件大小不能超过500MB';
} else {
$appExtension = pathinfo($_FILES['new_app_file']['name'], PATHINFO_EXTENSION);
// 生成6位随机数
$randomNumber = str_pad(mt_rand(0, 999999), 6, '0', STR_PAD_LEFT);
// 清理应用名称中的特殊字符
$cleanAppName = preg_replace('/[^a-zA-Z0-9_]/', '_', $app['name']);
$appFileName = $cleanAppName . '_' . $randomNumber . '.' . $appExtension;
$appRelativePath = 'uploads/apps/' . $appFileName;
$newFilePath = $uploadDir . $appFileName;
if (move_uploaded_file($_FILES['new_app_file']['tmp_name'], $newFilePath)) {
// 获取旧文件路径并删除
$getOldPathSql = "SELECT file_path FROM app_versions WHERE id = ?";
$getOldPathStmt = $conn->prepare($getOldPathSql);
if (!$getOldPathStmt) {
log_error("获取旧文件路径查询准备失败: " . $conn->error, __FILE__, __LINE__);
$error = '版本修改失败,请稍后再试';
unlink($newFilePath);
} else {
$updateVersionStmt->bind_param("sssi", $version, $changelog, $fileName, $versionId);
if ($updateVersionStmt->execute()) {
$success = '版本修改成功';
} else {
$error = '版本修改失败: ' . $conn->error;
$getOldPathStmt->bind_param("i", $versionId);
$getOldPathStmt->execute();
$oldPathResult = $getOldPathStmt->get_result();
if ($oldPathResult->num_rows > 0) {
$oldPathRow = $oldPathResult->fetch_assoc();
$oldFilePath = __DIR__ . '/../' . $oldPathRow['file_path'];
if (file_exists($oldFilePath)) {
unlink($oldFilePath);
}
}
// 更新版本信息
$updateVersionSql = "UPDATE app_versions SET version = ?, changelog = ?, file_path = ? WHERE id = ?";
$updateVersionStmt = $conn->prepare($updateVersionSql);
if (!$updateVersionStmt) {
log_error("版本更新查询准备失败: " . $conn->error, __FILE__, __LINE__);
$error = '版本修改失败,请稍后再试';
unlink($newFilePath);
} else {
$updateVersionStmt->bind_param("sssi", $version, $changelog, $appRelativePath, $versionId);
if ($updateVersionStmt->execute()) {
$success = '版本修改成功';
} else {
$error = '版本修改失败: ' . $conn->error;
unlink($newFilePath);
}
}
}
} else {
$error = '文件上传失败';
}
} else {
$error = '文件上传失败';
}
} else {
// 仅更新版本号和更新日志
@@ -168,7 +191,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['version_id'])) {
// 处理版本删除请求
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_version'])) {
$versionId = $_POST['version_id'];
$uploadDir = __DIR__ . '/../files/';
// 获取文件路径
$getFilePathSql = "SELECT file_path FROM app_versions WHERE id = ?";
@@ -182,8 +204,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_version'])) {
$fileResult = $getFileStmt->get_result();
if ($fileResult->num_rows > 0) {
$fileRow = $fileResult->fetch_assoc();
$fileName = $fileRow['file_path'];
$filePath = $uploadDir . $fileName;
$filePath = __DIR__ . '/../' . $fileRow['file_path'];
// 删除文件
if (file_exists($filePath)) {
@@ -420,17 +441,44 @@ if (!$verStmt) {
}
function confirmDelete(versionId) {
const formData = new FormData();
formData.append('delete_version', 'true');
formData.append('version_id', versionId);
fetch('version_control.php', { method: 'POST', body: formData })
.then(response => response.text())
.then(data => {
window.location.reload();
})
.catch(error => {
window.location.reload();
// 使用Sweet Alert弹窗进行确认
Swal.fire({
title: '确定要删除这个版本吗?',
text: "此操作无法撤销,删除后将无法恢复。",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#d33',
cancelButtonColor: '#3085d6',
confirmButtonText: '确认删除',
cancelButtonText: '取消'
}).then((result) => {
if (result.isConfirmed) {
const formData = new FormData();
formData.append('delete_version', 'true');
formData.append('version_id', versionId);
fetch('version_control.php', { method: 'POST', body: formData })
.then(response => response.text())
.then(data => {
// 显示操作结果
Swal.fire({
title: '操作成功',
text: data,
icon: 'success'
}).then(() => {
window.location.reload();
});
})
.catch(error => {
Swal.fire(
'操作失败',
'版本删除失败,请稍后再试',
'error'
).then(() => {
window.location.reload();
});
});
}
});
}
</script>