cms-manage/app/controller/backend/AttachmentController.php

463 lines
17 KiB
PHP

<?php
declare (strict_types = 1);
namespace app\controller\backend;
use app\exception\ModelException;
use app\model\Attachment;
use app\model\AttachmentCate;
use app\model\Model;
use app\model\RecycleBin;
use app\model\SysSetting;
use app\service\CacheService;
use app\service\ThemeService;
use app\service\upload\Upload;
use app\validate\AttachmentValidate;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\Lang;
use think\file\UploadedFile;
class AttachmentController extends BaseController
{
protected $type = [
'file' => 4,
'image' => 2,
'video' => 3,
'mp3' => 5,
'zip' => 1,
];
/**
* 显示资源列表
*
* @return \think\response\Json
* @throws \app\exception\ModelException
*/
public function index(Attachment $attachment): \think\response\Json
{
$type = (int)input('type');
$where = [
['seller_id' ,'=', $this->admin['seller_id']],
['is_del' ,'=', 1],
];
$cate_id = (int)input('cate_id');
if($cate_id){
$Cate = new AttachmentCate();
$cate = $Cate -> getCustomData(['id'=>$cate_id,'seller_id'=>$this->admin['seller_id']])['data'];
$path = $cate['path'] . '-' . $cate['id'];
$cates = $Cate -> getAllCustomArrayData([['path','like',$path.'%'],['seller_id','=',$this->admin['seller_id']]])['data'];
$ids = array_column($cates,'id');
array_unshift($ids,$cate['id']);
if(count($ids) == 1){
$where[] = ['attachment_cate_id', '=', $ids[0]];
}else{
$where[] = ['attachment_cate_id', 'in', $ids];
}
}
if($type){
$where[] = ['type', '=', $type];
}
$name = input('name');
if(!empty($name)){
$where[] = ['name', 'like', '%' . $name . '%'];
}
$limit = $this->setLimit();
$attachmentList = $attachment->getAttachmentList($where,$limit);
$res = pageReturn($attachmentList);
foreach ($res['data'] as &$value) {
$value['prefix_url'] = '';
$value['suffix_url'] = '';
if (strpos($value['url'], 'http') === false) {
if (strpos($value['url'], 'storage/') === false) {
$value['prefix_url'] = 'http://' . $this->request->host() . 'storage/';
$value['suffix_url'] = $value['url'];
$value['url'] = 'http://' . $this->request->host() . $value['url'];
continue;
}
$value['url'] = 'http://' . $this->request->host() . $value['url'];
//前缀,后缀
$urlStr = explode('storage/', $value['url']);
$value['prefix_url'] = $urlStr[0] . 'storage/';
$value['suffix_url'] = $urlStr[1];
}
}
return json($res);
}
// 修改附件路径
public function editFileUrl()
{
$param = $this->request->param();
if (empty($param['id']) || empty($param['name']) || empty($param['suffix_url'])) {
return json(dataReturn(-1, Lang::get('必填项不能为空!')));
}
$attachmentModel = new Attachment();
$info = $attachmentModel->where('id', $param['id'])->find();
if (!isset($info['id'])) {
return json(dataReturn(-1, Lang::get('文件不存在!')));
}
$param['suffix_url'] = str_replace('..', '', $param['suffix_url']);
$param['suffix_url'] = str_replace('//', '/', $param['suffix_url']);
$oldUrl = $info['url'];
$oldPathUrl = CMS_ROOT . 'public' . $oldUrl;
$newUrl = 'storage/' . $param['suffix_url'];
$newPathUrl = CMS_ROOT . 'public/' . $newUrl;
$updateData = [
'name' => $param['name'],
'description' => $param['description'],
'url' => $newUrl,
];
$fileInfo = pathinfo($newPathUrl);
mkdirs($fileInfo['dirname']);
$copyRes = true;
if ($oldPathUrl != $newPathUrl) {
$copyRes = copy($oldPathUrl, $newPathUrl);
}
if ($copyRes) {
// 复制成功
$res = $attachmentModel->where('id', $param['id'])->update($updateData);
} else {
$res = false;
}
if ($res === false) {
return json(dataReturn(-1, lang('修改失败')));
} else {
return json(dataReturn(0, lang('修改成功')));
}
}
/**
* 保存新建的资源
*
* @return \think\response\Json
* @throws \ReflectionException
*/
public function save(Attachment $attachment): \think\response\Json
{
if(request()->isPost()){
$param = input('post.');
foreach($param as &$val){
try{
validate(AttachmentValidate::class)->scene('save')->check($val);
$val['seller_id'] = $this->admin['seller_id'];
}catch (ValidateException $e){
return jsonReturn(-1, $e->getError());
}
if ($val['storage'] == 5 && strpos($val['url'], 'http') !== 0) {
return jsonReturn(-1, lang('网络附件链接地址请以http开头'));
}
}
$res = $attachment->addAllCustomData($param);
CacheService::deleteRelationCacheByObject($attachment);
return json($res);
}
return jsonReturn(-3,Lang::get('请求方法错误'));
}
/**
* 显示指定的资源
*
* @return \think\response\Json
* @throws \app\exception\ModelException
*/
public function read(Attachment $attachment): \think\response\Json
{
$id = (int)input('id');
if(!$id){
return jsonReturn(-1,lang('附件ID不能为空'));
}
$where = [
'id' => $id,
'seller_id' => $this->admin['seller_id'],
'is_del' => 1,
];
$res = $attachment->getAttachment($where);
return json($res);
}
/**
* 保存更新的资源
* @return \think\response\Json
* @throws \app\exception\ModelException
* @throws \ReflectionException
*/
public function update(Attachment $attachment): \think\response\Json
{
if(request()->isPost()){
$param = input('post.');
$seller_id = $this->admin['seller_id'];
try {
validate(AttachmentValidate::class)->scene('update')->check($param);
} catch (ValidateException $e) {
return jsonReturn(-1, $e->getError());
}
if (isset($param['storage']) && $param['storage'] == 5 && strpos($param['url'], 'http') !== 0) {
return jsonReturn(-1, lang('网络附件链接地址请以http开头'));
}
$where = [
'id' => $param['id'],
'seller_id' => $seller_id,
];
$res = $attachment -> updateAttachment($where,$param);
CacheService::deleteRelationCacheByObject($attachment);
return json($res);
}
return jsonReturn(-3,Lang::get('请求方法错误'));
}
/**
* 删除指定资源
*
* @throws \app\exception\ModelException
*/
public function delete(Attachment $Attachment): \think\response\Json
{
$idArr = $this->request->param('id');
if(is_string($idArr)){
$ids = explode(',',$idArr);
}else{
$ids = $idArr;
}
$where = [
['id','in',$ids],
['seller_id','=',$this->admin['seller_id']]
];
$attachment = $Attachment -> getAllCustomArrayData($where)['data'];
Db::startTrans();
try{
$binData=[];
foreach ($attachment as $val){
// 复制删除内容到回收站表
$binData[] = [
'seller_id' => $this->admin['seller_id'],
'object_id' => $val['id'],
'sub_id' => 0,
'module_id' => 0,
'table_name' => '附件-attachment',
'title' => !empty($val['name']) ? $val['name'] : '附件' . $val['id'],
'admin_id' => $this->admin['uid'],
'name' => $this->admin['name'],
];
}
$recycleBin = new RecycleBin();
$recycleBin -> addAllCustomData($binData);
$Attachment -> updateAttachment($where,['is_del'=>2,'delete_time'=>time()]);
CacheService::deleteRelationCacheByObject($Attachment);
optEventLog($idArr,Lang::get('附件'),Lang::get('删除'));
Db::commit();
}catch (\Exception $e){
Db::rollback();
return jsonReturn(-1,Lang::get('删除失败'));
}
return jsonReturn(0,Lang::get('删除成功'));
}
/**
* @throws \app\exception\ModelException
*/
public function uploadAndSave(Attachment $attachment): \think\response\Json
{
if(request()->isPost()){
set_time_limit(0);
$file = request()->file('file');
$reduceImg = request()->file('reduce_img');
if(empty($file)){
return jsonReturn(-8,lang('文件上传失败,请重新尝试'));
}
$seller_id = $this->admin['seller_id'];
$attachmentModel = new Attachment();
$has = $attachmentModel->checkFileExist($this->admin['seller_id'], $file->hash());
if ($has['code'] == 0) {
$reduceImgData = !empty($reduceImg)?$this->singleUpload($reduceImg,$seller_id)['data']:[];
$updateData = [
'update_time' => time(),
'reduce_img'=> !empty($reduceImgData)?$reduceImgData['getUploadFileInfo']['url']:"",
];
// 更新時間
$attachmentModel->where('id', $has['data']['id'])->update($updateData);
return json($has);
}
$fileData = $this->singleUpload($file,$seller_id)['data'];
$reduceImgData = !empty($reduceImg)?$this->singleUpload($reduceImg,$seller_id)['data']:[];
$fileData['getUploadFileInfo']['seller_id'] = $seller_id;
$fileData['getUploadFileInfo']['type'] = $fileData['fileType'];
$fileData['getUploadFileInfo']['size'] = round($fileData['fileSize'] / 1024,2);
$fileData['getUploadFileInfo']['attachment_cate_id'] =$this->request->param('attachment_cate_id/d',0);
$fileData['getUploadFileInfo']['reduce_img'] = !empty($reduceImgData)?$reduceImgData['getUploadFileInfo']['url']:"";
$attachment = new Attachment();
$res = $attachment->addAttachment($fileData['getUploadFileInfo']);
optEventLog($res['data']['id'],Lang::get('附件'),Lang::get('添加'));
return json($res);
}
return jsonReturn(-3,lang('请求方法错误'));
}
/**
* @throws ModelException
*/
private function singleUpload($file,$seller_id)
{
// 查看文件类型
$fileName = $file->getOriginalName();
$fileExt = $file->getOriginalExtension();
$file_type = fileFormat($fileName);
$fileType = $this->type[$file_type];
$Settings = new SysSetting();
$uploadSetting = $Settings->getAllCustomArrayData(['parent_id'=>1,'group'=>'upload','status'=>1],'id desc','id,group,title,value')['data'];
$uploadSetting = getColumnForKeyArray($uploadSetting,'title');
$limitSize = $uploadSetting[$file_type.'_size']['value'] * 1024; // byte
$fileSize = $file->getSize(); // 单位byte
if($fileSize > $limitSize){
throw new ModelException(lang('文件过大,请修改上传限制或者替换小的文件'),-1);
}
$extArr = explode(',',$uploadSetting[$file_type.'_ext']['value']);
if(!in_array($fileExt,$extArr)){
throw new ModelException(lang('文件格式错误,请重新上传'),-2);
}
$type = $this->getUploadType();
$upload = new Upload();
$info = $upload->create($file,$seller_id, $type,$file_type);
if(!$info){
throw new ModelException(lang('上传失败请重新尝试'),-3);
}
return dataReturn(0,'上传成功',
[
'fileType'=>$fileType,
'fileSize'=>$fileSize,
'getUploadFileInfo'=>$upload->getUploadFileInfo()['data']
]);
}
public function sliceUploadAndSave(Upload $uploader): \think\response\Json
{
$params = $this->request->param();
$params['resource_chunk'] = $this->request->file('resource_chunk');
$file_type = fileFormat('abc.'.$params['resource_type']);
$Settings = new SysSetting();
$uploadSetting = $Settings->getAllCustomArrayData(['parent_id'=>1,'group'=>'upload','status'=>1],'id desc','id,group,title,value')['data'];
$uploadSetting = getColumnForKeyArray($uploadSetting,'title');
$extArr = explode(',',$uploadSetting[$file_type.'_ext']['value']);
if(!in_array($params['resource_type'],$extArr)){
return jsonReturn(-2,lang('文件格式错误,请重新上传'));
}
$res = $uploader->tmpMove($params['resource_chunk'],$file_type,$params['resource_temp_path'],$params['chunk_index']);
if($res){
$tmPath = runtime_path() . 'slice/'.$file_type.'/'.$params['resource_temp_path'];
$num = getFileNumber($tmPath);
if($num == $params['chunk_total']){
try {
$filepath = $uploader->mergeBlob($tmPath,$params['resource_temp_path'],$params['chunk_total'],$params['resource_type']);
$type = $this->getUploadType();
$file = new UploadedFile($filepath,$params['resource_temp_path'].'.'.$params['resource_type']);
if($type == 'local'){
if(!file_exists(public_path() . 'storage/' . $file_type.'/'. date('Ymd'))){
@mkdir(public_path() . 'storage/' . $file_type.'/'. date('Ymd'),0755,true);
}
copy($filepath,public_path() . 'storage/' . $file_type.'/'. date('Ymd') .'/'.$params['resource_temp_path'] .'.'.$params['resource_type']);
$cateId = (int)input('attachment_cate_id');
$uploadInfo['name'] = $params['resource_name'];
$uploadInfo['url'] = 'storage/' . $file_type.'/'. date('Ymd') .'/'.$params['resource_temp_path'] .'.'.$params['resource_type'];
$uploadInfo['mime_type'] = $params['resource_type'];
$uploadInfo['storage'] = 1;
$uploadInfo['type'] = $this->type[$file_type];
$uploadInfo['size'] = round($file->getSize() / 1024,2);
$uploadInfo['attachment_cate_id'] = $cateId;
$attachment = new Attachment();
$res = $attachment->addAttachment($uploadInfo);
optEventLog($res['data']['id'],Lang::get('附件'),Lang::get('添加'));
(new ThemeService()) -> deleteFile($tmPath);
return json($res);
}else{
$upload = new Upload();
$res = $upload->create($file,$this->admin['seller_id'], $type);
if($res){
$fileSize = $file->getSize();
$fileType = $this->type[$file_type];
$res = $this->getResponse($fileType,$fileSize,$upload);
(new ThemeService()) -> deleteFile($tmPath);
return json($res);
}else{
return jsonReturn(-1,Lang::get('上传失败'));
}
}
} catch (\Exception $e) {
return jsonReturn(-1,$e->getMessage(),[]);
}
}else{
return jsonReturn(1,Lang::get('上传成功'),$res);
}
}else{
return jsonReturn(-1,Lang::get('上传失败'),$res);
}
}
/**
* @throws \app\exception\ModelException
*/
public function getResponse($fileType, $fileSize, $upload)
{
$uploadInfo = $upload->getUploadFileInfo();
$cateId = (int)input('attachment_cate_id');
if ($uploadInfo['code'] == 0) {
$uploadInfo['data']['type'] = $fileType;
$uploadInfo['data']['size'] = round($fileSize / 1024,2);
$uploadInfo['data']['attachment_cate_id'] = $cateId;
$attachment = new Attachment();
$res = $attachment->addAttachment($uploadInfo['data']);
optEventLog($res['data']['id'],Lang::get('附件'),Lang::get('添加'));
return $res;
} else {
return $uploadInfo;
}
}
public function getFileType()
{
}
/**
* @throws \app\exception\ModelException
*/
public function getUploadType()
{
// 文件信息提取
$where = [
'seller_id' => $this->admin['seller_id'],
'group' => 'upload',
'title' => 'storage'
];
$place = new SysSetting();
return $place->getSysSetting($where)['data']->toArray()['value'];
}
}