598 lines
20 KiB
PHP
598 lines
20 KiB
PHP
<?php
|
|
|
|
namespace app\admin\controller\System;
|
|
|
|
use app\admin\BaseController;
|
|
use think\facade\Filesystem;
|
|
use think\facade\Request;
|
|
use think\facade\Db;
|
|
use think\Response;
|
|
|
|
use app\model\System\FilesCategory;
|
|
use app\model\System\Files;
|
|
|
|
class FileController extends BaseController
|
|
{
|
|
// 文件类型映射
|
|
protected $fileTypes = [
|
|
'image' => 1,
|
|
'document' => 2,
|
|
'video' => 3,
|
|
'audio' => 4
|
|
];
|
|
|
|
// 允许的文件类型
|
|
protected $allowedExtensions = [
|
|
'image' => ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'],
|
|
'document' => ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt'],
|
|
'video' => ['mp4', 'webm', 'mov'],
|
|
'audio' => ['mp3', 'wav', 'ogg']
|
|
];
|
|
|
|
// 获取所有文件
|
|
public function getAllFiles()
|
|
{
|
|
try {
|
|
$page = Request::param('page/d', 1);
|
|
$pageSize = Request::param('pageSize/d', 10);
|
|
$cate = Request::param('cate/d', 0);
|
|
$keyword = Request::param('keyword/s', '');
|
|
|
|
$query = Files::where('delete_time', null)
|
|
->where('tid', $this->getTenantId());
|
|
|
|
if ($cate) {
|
|
$query->where('cate', $cate);
|
|
}
|
|
|
|
if ($keyword) {
|
|
$query->whereLike('name', "%{$keyword}%");
|
|
}
|
|
|
|
$total = $query->count();
|
|
$list = $query->page($page, $pageSize)
|
|
->order('create_time', 'desc')
|
|
->select();
|
|
|
|
return json([
|
|
'code' => 200,
|
|
'msg' => 'success',
|
|
'data' => [
|
|
'list' => $list,
|
|
'total' => $total,
|
|
'page' => $page,
|
|
'pageSize' => $pageSize
|
|
]
|
|
]);
|
|
} catch (\Exception $e) {
|
|
return json([
|
|
'code' => 500,
|
|
'msg' => '获取文件列表失败: ' . $e->getMessage()
|
|
]);
|
|
}
|
|
}
|
|
|
|
//获取用户分类
|
|
public function getUserCate()
|
|
{
|
|
try {
|
|
$tid = $this->getTenantId();
|
|
|
|
// 只根据 tid 筛选分类
|
|
$cate = FilesCategory::where('delete_time', null)
|
|
->where('tid', $tid)
|
|
->field('id,name')
|
|
->select();
|
|
|
|
// 获取每个分类下的文件数量
|
|
foreach ($cate as &$c) {
|
|
$c['total'] = Files::where('cate', $c['id'])
|
|
->where('tid', $tid)
|
|
->where('delete_time', null)
|
|
->count();
|
|
}
|
|
|
|
return json([
|
|
'code' => 200,
|
|
'msg' => 'success',
|
|
'data' => $cate
|
|
]);
|
|
} catch (\Exception $e) {
|
|
return json([
|
|
'code' => 500,
|
|
'msg' => '获取用户分类失败: ' . $e->getMessage()
|
|
]);
|
|
}
|
|
}
|
|
|
|
//新建文件分组
|
|
public function createFileCate()
|
|
{
|
|
try {
|
|
$data = Request::param();
|
|
$data['create_time'] = date('Y-m-d H:i:s');
|
|
$data['tid'] = $this->getTenantId();
|
|
$id = FilesCategory::insertGetId($data);
|
|
|
|
// 记录操作日志
|
|
$this->logSuccess('文件管理', '创建文件分组', ['id' => $id]);
|
|
|
|
return json([
|
|
'code' => 200,
|
|
'msg' => '新建文件分组成功',
|
|
'data' => [
|
|
'id' => $id
|
|
]
|
|
]);
|
|
} catch (\Exception $e) {
|
|
// 记录失败日志
|
|
$this->logFail('文件管理', '创建文件分组', $e->getMessage());
|
|
|
|
return json([
|
|
'code' => 500,
|
|
'msg' => '新建文件分组失败: ' . $e->getMessage()
|
|
]);
|
|
}
|
|
}
|
|
|
|
//重命名文件分组
|
|
public function renameFileCate($id)
|
|
{
|
|
try {
|
|
$data = Request::param();
|
|
$result = FilesCategory::where('id', $id)
|
|
->where('tid', $this->getTenantId())
|
|
->update(['name' => $data['name']]);
|
|
// 记录操作日志
|
|
$this->logSuccess('文件管理', '重命名文件分组', ['id' => $id]);
|
|
return json([
|
|
'code' => 200,
|
|
'msg' => '重命名文件分组成功'
|
|
]);
|
|
} catch (\Exception $e) {
|
|
// 记录失败日志
|
|
$this->logFail('文件管理', '重命名文件分组', $e->getMessage());
|
|
return json([
|
|
'code' => 500,
|
|
'msg' => '重命名文件分组失败: ' . $e->getMessage()
|
|
]);
|
|
}
|
|
}
|
|
|
|
//删除文件分组
|
|
public function deleteFileCate($id)
|
|
{
|
|
try {
|
|
// 检查分组里是否有关联文件
|
|
$fileCount = Files::where('cate', $id)
|
|
->where('tid', $this->getTenantId())
|
|
->where('delete_time', null)
|
|
->count();
|
|
if ($fileCount > 0) {
|
|
return json([
|
|
'code' => 400,
|
|
'msg' => '该分组下还有 ' . $fileCount . ' 个文件,请先删除分组内文件!'
|
|
]);
|
|
}
|
|
|
|
$result = FilesCategory::where('id', $id)
|
|
->where('tid', $this->getTenantId())
|
|
->update(['delete_time' => date('Y-m-d H:i:s')]);
|
|
// 记录操作日志
|
|
$this->logSuccess('文件管理', '删除文件分组', ['id' => $id]);
|
|
return json([
|
|
'code' => 200,
|
|
'msg' => '删除文件分组成功'
|
|
]);
|
|
} catch (\Exception $e) {
|
|
// 记录失败日志
|
|
$this->logFail('文件管理', '删除文件分组', $e->getMessage());
|
|
return json([
|
|
'code' => 500,
|
|
'msg' => '删除文件分组失败: ' . $e->getMessage()
|
|
]);
|
|
}
|
|
}
|
|
|
|
//获取分类文件
|
|
public function getCateFiles(int $id)
|
|
{
|
|
try {
|
|
$page = Request::param('page/d', 1);
|
|
$pageSize = Request::param('pageSize/d', 10);
|
|
$keyword = Request::param('keyword/s', '');
|
|
|
|
$query = Files::where('cate', $id)
|
|
->where('tid', $this->getTenantId())
|
|
->where('delete_time', null);
|
|
|
|
if ($keyword) {
|
|
$query->whereLike('name', "%{$keyword}%");
|
|
}
|
|
|
|
// 获取总条数
|
|
$total = $query->count();
|
|
$list = $query->page($page, $pageSize)
|
|
->order('create_time', 'desc')
|
|
->select();
|
|
|
|
// 格式化文件信息
|
|
foreach ($list as &$file) {
|
|
$file['createTime'] = $file['create_time'];
|
|
$file['groupId'] = $file['cate'];
|
|
$file['url'] = $file['src'];
|
|
}
|
|
return json([
|
|
'code' => 200,
|
|
'msg' => 'success',
|
|
'data' => [
|
|
'list' => $list,
|
|
'total' => $total,
|
|
'page' => $page,
|
|
'pageSize' => $pageSize,
|
|
'categoryId' => $id
|
|
]
|
|
]);
|
|
} catch (\Exception $e) {
|
|
return json([
|
|
'code' => 500,
|
|
'msg' => '获取分类文件失败: ' . $e->getMessage()
|
|
]);
|
|
}
|
|
}
|
|
|
|
// 文件上传
|
|
public function uploadFile()
|
|
{
|
|
try {
|
|
$file = Request::file('file');
|
|
if (!$file) {
|
|
return json(['code' => 400, 'msg' => '请选择要上传的文件']);
|
|
}
|
|
|
|
// 验证文件大小和类型
|
|
$maxSize = 50 * 1024 * 1024; // 50MB
|
|
$fileExt = strtolower($file->getOriginalExtension());
|
|
|
|
if ($file->getSize() > $maxSize) {
|
|
return json(['code' => 400, 'msg' => '文件大小不能超过50MB']);
|
|
}
|
|
|
|
// 计算文件MD5
|
|
$fileMd5 = md5_file($file->getRealPath());
|
|
|
|
// 检查是否已存在相同文件
|
|
$existFile = Files::where('md5', $fileMd5)
|
|
->where('tid', $this->getTenantId())
|
|
->where('delete_time', null)
|
|
->find();
|
|
|
|
if ($existFile) {
|
|
return json([
|
|
'code' => 201,
|
|
'msg' => '文件已存在',
|
|
'data' => [
|
|
'url' => $existFile['src'],
|
|
'id' => $existFile['id'],
|
|
'name' => $existFile['name']
|
|
]
|
|
]);
|
|
}
|
|
|
|
// 确定文件类型
|
|
$fileType = 2; // 默认为文件
|
|
foreach ($this->allowedExtensions as $type => $extensions) {
|
|
if (in_array($fileExt, $extensions)) {
|
|
$fileType = $this->fileTypes[$type];
|
|
break;
|
|
}
|
|
}
|
|
|
|
$cate = Request::param('cate/d', 0);
|
|
// 生成按日期分类的目录结构
|
|
$datePath = date('Y/m/d');
|
|
$saveName = $datePath . '/' . uniqid() . '.' . $fileExt;
|
|
$fullPath = Filesystem::disk('public')->putFileAs('uploads', $file, $saveName);
|
|
$fileUrl = '/storage/' . str_replace('\\', '/', $fullPath);
|
|
|
|
// 获取当前登录用户ID
|
|
$userId = Request::middleware('user_id', '');
|
|
|
|
// 保存文件信息到数据库
|
|
$fileData = [
|
|
'name' => $file->getOriginalName(),
|
|
'type' => $fileType,
|
|
'cate' => $cate,
|
|
'size' => $file->getSize(),
|
|
'src' => $fileUrl,
|
|
'md5' => $fileMd5,
|
|
'uploader' => $userId,
|
|
'tid' => $this->getTenantId(),
|
|
'create_time' => date('Y-m-d H:i:s'),
|
|
];
|
|
|
|
$fileId = Files::insertGetId($fileData);
|
|
|
|
// 记录操作日志
|
|
$this->logSuccess('文件管理', '上传文件', ['id' => $fileId]);
|
|
return json([
|
|
'code' => 200,
|
|
'msg' => '上传成功',
|
|
'data' => [
|
|
'url' => $fileUrl,
|
|
'id' => $fileId,
|
|
'name' => $fileData['name']
|
|
]
|
|
]);
|
|
} catch (\Exception $e) {
|
|
// 记录失败日志
|
|
$this->logFail('文件管理', '上传文件', $e->getMessage());
|
|
return json([
|
|
'code' => 500,
|
|
'msg' => '上传失败: ' . $e->getMessage()
|
|
]);
|
|
}
|
|
}
|
|
|
|
// 更新文件信息
|
|
public function updateFile($id)
|
|
{
|
|
try {
|
|
$data = Request::only(['name', 'cate']);
|
|
if (empty($data)) {
|
|
return json(['code' => 400, 'msg' => '无更新数据']);
|
|
}
|
|
|
|
$data['update_time'] = date('Y-m-d H:i:s');
|
|
|
|
$result = Files::where('id', $id)
|
|
->where('tid', $this->getTenantId())
|
|
->where('delete_time', null)
|
|
->update($data);
|
|
|
|
if ($result) {
|
|
// 记录操作日志
|
|
$this->logSuccess('文件管理', '更新文件', ['id' => $id]);
|
|
return json(['code' => 200, 'msg' => '更新成功']);
|
|
}
|
|
|
|
return json(['code' => 404, 'msg' => '文件不存在']);
|
|
} catch (\Exception $e) {
|
|
// 记录失败日志
|
|
$this->logFail('文件管理', '更新文件', $e->getMessage());
|
|
return json(['code' => 500, 'msg' => '更新失败: ' . $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
// 删除文件
|
|
public function deleteFile($id)
|
|
{
|
|
try {
|
|
// 先获取文件信息
|
|
$file = Files::where('id', $id)
|
|
->where('tid', $this->getTenantId())
|
|
->find();
|
|
if (!$file) {
|
|
return json(['code' => 404, 'msg' => '文件不存在']);
|
|
}
|
|
|
|
$result = Files::where('id', $id)
|
|
->where('tid', $this->getTenantId())
|
|
->update(['delete_time' => date('Y-m-d H:i:s')]);
|
|
|
|
if ($result) {
|
|
// 记录操作日志
|
|
$this->logSuccess('文件管理', '删除文件', ['id' => $id]);
|
|
return json(['code' => 200, 'msg' => '删除成功']);
|
|
}
|
|
|
|
return json(['code' => 404, 'msg' => '文件不存在']);
|
|
} catch (\Exception $e) {
|
|
// 记录失败日志
|
|
$this->logFail('文件管理', '删除文件', $e->getMessage());
|
|
return json(['code' => 500, 'msg' => '删除失败: ' . $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
//永久删除文件
|
|
public function deleteFilePermanently($id)
|
|
{
|
|
try {
|
|
// 先获取文件信息
|
|
$file = Files::where('id', $id)
|
|
->where('tid', $this->getTenantId())
|
|
->find();
|
|
if (!$file) {
|
|
return json(['code' => 404, 'msg' => '文件不存在']);
|
|
}
|
|
|
|
// 删除服务器上的文件
|
|
if ($file['src']) {
|
|
$this->deleteFileFromServer($file['src']);
|
|
}
|
|
|
|
$result = Files::where('id', $id)
|
|
->where('tid', $this->getTenantId())
|
|
->update(['delete_time' => date('Y-m-d H:i:s')]);
|
|
|
|
if ($result) {
|
|
// 记录操作日志
|
|
$this->logSuccess('文件管理', '永久删除文件', ['id' => $id]);
|
|
return json(['code' => 200, 'msg' => '永久删除成功']);
|
|
}
|
|
|
|
return json(['code' => 404, 'msg' => '文件不存在']);
|
|
} catch (\Exception $e) {
|
|
// 记录失败日志
|
|
$this->logFail('文件管理', '永久删除文件', $e->getMessage());
|
|
return json(['code' => 500, 'msg' => '永久删除失败: ' . $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
// 下载文件
|
|
public function download($id)
|
|
{
|
|
try {
|
|
$file = Files::where('id', $id)
|
|
->where('tid', $this->getTenantId())
|
|
->where('delete_time', null)
|
|
->find();
|
|
|
|
if (!$file) {
|
|
return json(['code' => 404, 'msg' => '文件不存在']);
|
|
}
|
|
|
|
$filePath = public_path() . $file['src'];
|
|
|
|
if (!file_exists($filePath)) {
|
|
return json(['code' => 404, 'msg' => '文件不存在']);
|
|
}
|
|
|
|
return download($filePath, $file['name']);
|
|
} catch (\Exception $e) {
|
|
// 记录失败日志
|
|
$this->logFail('文件管理', '下载文件', $e->getMessage());
|
|
return json(['code' => 500, 'msg' => '下载失败: ' . $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
// 移动文件
|
|
public function moveFile($id)
|
|
{
|
|
try {
|
|
$cate = Request::param('cate/d', 0);
|
|
$result = Files::where('id', $id)
|
|
->where('tid', $this->getTenantId())
|
|
->update(['cate' => $cate]);
|
|
if ($result) {
|
|
// 记录操作日志
|
|
$this->logSuccess('文件管理', '移动文件', ['id' => $id]);
|
|
return json(['code' => 200, 'msg' => '移动成功']);
|
|
}
|
|
|
|
return json(['code' => 404, 'msg' => '文件不存在']);
|
|
} catch (\Exception $e) {
|
|
// 记录失败日志
|
|
$this->logFail('文件管理', '移动文件', $e->getMessage());
|
|
return json(['code' => 500, 'msg' => '移动失败: ' . $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
//删除服务器上文件
|
|
private function deleteFileFromServer($fileUrl)
|
|
{
|
|
// 去掉开头的 /storage/,得到相对路径
|
|
$relativePath = ltrim($fileUrl, '/');
|
|
if (strpos($relativePath, 'storage/') === 0) {
|
|
$relativePath = substr($relativePath, 8); // 去掉 'storage/' 部分
|
|
}
|
|
|
|
// 获取实际服务器路径
|
|
$fullPath = root_path() . 'public/storage/' . $relativePath;
|
|
|
|
if (file_exists($fullPath)) {
|
|
unlink($fullPath);
|
|
}
|
|
}
|
|
|
|
// 批量删除文件
|
|
public function batchDeleteFiles()
|
|
{
|
|
try {
|
|
$ids = Request::param('ids/a', []);
|
|
|
|
if (empty($ids)) {
|
|
return json(['code' => 400, 'msg' => '请选择要删除的文件']);
|
|
}
|
|
|
|
foreach ($ids as $id) {
|
|
$file = Files::where('id', $id)
|
|
->where('tid', $this->getTenantId())
|
|
->find();
|
|
if ($file && $file['src']) {
|
|
$this->deleteFileFromServer($file['src']);
|
|
}
|
|
}
|
|
|
|
$result = Files::where('id', 'in', $ids)
|
|
->where('tid', $this->getTenantId())
|
|
->update(['delete_time' => date('Y-m-d H:i:s')]);
|
|
|
|
if ($result) {
|
|
$this->logSuccess('文件管理', '批量删除文件', ['ids' => $ids]);
|
|
return json(['code' => 200, 'msg' => '批量删除成功']);
|
|
}
|
|
|
|
return json(['code' => 404, 'msg' => '文件不存在']);
|
|
} catch (\Exception $e) {
|
|
$this->logFail('文件管理', '批量删除文件', $e->getMessage());
|
|
return json(['code' => 500, 'msg' => '批量删除失败: ' . $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
// 批量彻底删除文件
|
|
public function batchDeleteFilesPermanently()
|
|
{
|
|
try {
|
|
$ids = Request::param('ids/a', []);
|
|
|
|
if (empty($ids)) {
|
|
return json(['code' => 400, 'msg' => '请选择要彻底删除的文件']);
|
|
}
|
|
|
|
foreach ($ids as $id) {
|
|
$file = Files::where('id', $id)
|
|
->where('tid', $this->getTenantId())
|
|
->find();
|
|
if ($file && $file['src']) {
|
|
$this->deleteFileFromServer($file['src']);
|
|
}
|
|
}
|
|
|
|
$result = Files::where('id', 'in', $ids)
|
|
->where('tid', $this->getTenantId())
|
|
->force(true)
|
|
->update(['delete_time' => date('Y-m-d H:i:s')])
|
|
->delete();
|
|
|
|
if ($result) {
|
|
$this->logSuccess('文件管理', '批量彻底删除文件', ['ids' => $ids]);
|
|
return json(['code' => 200, 'msg' => '批量彻底删除成功']);
|
|
}
|
|
|
|
return json(['code' => 404, 'msg' => '文件不存在']);
|
|
} catch (\Exception $e) {
|
|
$this->logFail('文件管理', '批量彻底删除文件', $e->getMessage());
|
|
return json(['code' => 500, 'msg' => '批量彻底删除失败: ' . $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
// 批量移动文件
|
|
public function batchMoveFiles()
|
|
{
|
|
try {
|
|
$ids = Request::param('ids/a', []);
|
|
$cate = Request::param('cate/d', 0);
|
|
|
|
if (empty($ids)) {
|
|
return json(['code' => 400, 'msg' => '请选择要移动的文件']);
|
|
}
|
|
|
|
$result = Files::where('id', 'in', $ids)
|
|
->where('tid', $this->getTenantId())
|
|
->update(['cate' => $cate]);
|
|
|
|
if ($result) {
|
|
$this->logSuccess('文件管理', '批量移动文件', ['ids' => $ids, 'cate' => $cate]);
|
|
return json(['code' => 200, 'msg' => '批量移动成功']);
|
|
}
|
|
|
|
return json(['code' => 404, 'msg' => '文件不存在']);
|
|
} catch (\Exception $e) {
|
|
$this->logFail('文件管理', '批量移动文件', $e->getMessage());
|
|
return json(['code' => 500, 'msg' => '批量移动失败: ' . $e->getMessage()]);
|
|
}
|
|
}
|
|
}
|
|
|