Initial commit: Flutter 无书应用项目

This commit is contained in:
Developer
2026-03-30 02:35:31 +08:00
commit 9175ff9905
566 changed files with 103261 additions and 0 deletions

203
ht/api/upload.php Normal file
View File

@@ -0,0 +1,203 @@
<?php
/**
* 图片上传处理API
* 处理图片上传支持自动调整大于1280宽度的图片为1024宽度
*/
// 引入必要文件
require_once '../inc/pubs.php';
require_once '../inc/sqls.php';
// 验证用户登录状态
if (!checkLogin()) {
exit(json_encode([
'code' => 1001,
'msg' => '请先登录'
]));
}
// 检查请求方法
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
exit(json_encode([
'code' => 1002,
'msg' => '请求方法错误'
]));
}
// 检查是否有文件上传
if (!isset($_FILES['image']) || $_FILES['image']['error'] !== UPLOAD_ERR_OK) {
exit(json_encode([
'code' => 1003,
'msg' => '上传失败: ' . uploadErrorMessage($_FILES['image']['error'])
]));
}
// 验证文件类型
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
$fileType = $_FILES['image']['type'];
if (!in_array($fileType, $allowedTypes)) {
exit(json_encode([
'code' => 1004,
'msg' => '只允许上传JPG、PNG、GIF和WEBP格式的图片'
]));
}
// 验证文件大小最大10MB
$maxFileSize = 10 * 1024 * 1024; // 10MB
if ($_FILES['image']['size'] > $maxFileSize) {
exit(json_encode([
'code' => 1005,
'msg' => '文件大小超过限制最大允许10MB'
]));
}
// 准备上传路径
$uploadDir = '../uploads/';
if (!file_exists($uploadDir)) {
mkdir($uploadDir, 0777, true);
}
// 生成唯一文件名
$extension = pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION);
$fileName = uniqid('img_') . '_' . date('Ymd') . '.' . $extension;
$uploadPath = $uploadDir . $fileName;
$relativeUrl = 'uploads/' . $fileName;
// 处理图片上传
$uploaded = false;
// 获取图片信息
$imageInfo = getimagesize($_FILES['image']['tmp_name']);
if (!$imageInfo) {
exit(json_encode([
'code' => 1006,
'msg' => '无效的图片文件'
]));
}
$width = $imageInfo[0];
$height = $imageInfo[1];
// 如果图片宽度大于1280则调整为1024宽度尽管前端已经处理这里作为后端保障
if ($width > 1280) {
// 计算新高度,保持比例
$newWidth = 1024;
$newHeight = intval($height * ($newWidth / $width));
// 根据图片类型创建图像
switch ($imageInfo[2]) {
case IMAGETYPE_JPEG:
$source = imagecreatefromjpeg($_FILES['image']['tmp_name']);
break;
case IMAGETYPE_PNG:
$source = imagecreatefrompng($_FILES['image']['tmp_name']);
break;
case IMAGETYPE_GIF:
$source = imagecreatefromgif($_FILES['image']['tmp_name']);
break;
case IMAGETYPE_WEBP:
$source = imagecreatefromwebp($_FILES['image']['tmp_name']);
break;
default:
exit(json_encode([
'code' => 1007,
'msg' => '不支持的图片格式'
]));
}
// 创建新图像
$thumb = imagecreatetruecolor($newWidth, $newHeight);
// 保持PNG和WebP的透明度
if ($imageInfo[2] == IMAGETYPE_PNG || $imageInfo[2] == IMAGETYPE_WEBP) {
imagealphablending($thumb, false);
imagesavealpha($thumb, true);
$transparent = imagecolorallocatealpha($thumb, 255, 255, 255, 127);
imagefilledrectangle($thumb, 0, 0, $newWidth, $newHeight, $transparent);
}
// 调整图像大小
imagecopyresampled($thumb, $source, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
// 保存图像
switch ($imageInfo[2]) {
case IMAGETYPE_JPEG:
$uploaded = imagejpeg($thumb, $uploadPath, 90);
break;
case IMAGETYPE_PNG:
$uploaded = imagepng($thumb, $uploadPath, 9);
break;
case IMAGETYPE_GIF:
$uploaded = imagegif($thumb, $uploadPath);
break;
case IMAGETYPE_WEBP:
$uploaded = imagewebp($thumb, $uploadPath, 90);
break;
}
// 释放内存
imagedestroy($source);
imagedestroy($thumb);
} else {
// 直接移动上传的文件
$uploaded = move_uploaded_file($_FILES['image']['tmp_name'], $uploadPath);
}
// 检查上传是否成功
if (!$uploaded) {
exit(json_encode([
'code' => 1008,
'msg' => '文件保存失败'
]));
}
// 记录日志
$user = $_SESSION['user'];
$ip = "".$_SERVER['REMOTE_ADDR'];
$db = new DB();
$db->insert('logs', [
'user_id' => $user['id'],
'action' => '上传图片',
'idesc' => '上传了图片: ' . $fileName,
'ip' => $ip,
'logtime' => date('Y-m-d H:i:s')
]);
// 返回成功信息和图片URL
exit(json_encode([
'code' => 0,
'msg' => '上传成功',
'data' => [
'url' => $relativeUrl,
'width' => $width,
'height' => $height
]
]));
/**
* 获取上传错误消息
* @param int $errorCode 上传错误代码
* @return string 错误消息
*/
function uploadErrorMessage($errorCode) {
switch ($errorCode) {
case UPLOAD_ERR_INI_SIZE:
return '上传的文件超过了php.ini中upload_max_filesize指令限制的大小';
case UPLOAD_ERR_FORM_SIZE:
return '上传的文件超过了HTML表单中MAX_FILE_SIZE指令指定的大小';
case UPLOAD_ERR_PARTIAL:
return '文件只有部分被上传';
case UPLOAD_ERR_NO_FILE:
return '没有文件被上传';
case UPLOAD_ERR_NO_TMP_DIR:
return '找不到临时文件夹';
case UPLOAD_ERR_CANT_WRITE:
return '文件写入失败';
case UPLOAD_ERR_EXTENSION:
return '文件上传被PHP扩展程序中断';
default:
return '未知上传错误';
}
}