FileManager.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * upload文件管理
  5. *
  6. * @version 0.0.0
  7. * @author by huwhois
  8. * @time 2017/11/27
  9. */
  10. namespace app\sys\controller;
  11. use Exception;
  12. use think\facade\View;
  13. use think\File;
  14. use think\Image;
  15. use think\facade\Config;
  16. use app\common\service\FileService;
  17. use app\common\model\FileManager as FileManagerModel;
  18. class FileManager extends Base
  19. {
  20. protected $t_suffix = '_thumb';
  21. protected $width = 400; // 缩略图高度
  22. protected $height = 300;
  23. /**
  24. * 图片列表
  25. */
  26. // public function index($mod=0)
  27. // {
  28. // }
  29. public function index()
  30. {
  31. // $data = $this->explorer();
  32. // View::assign('dirs', $data['dirs']);
  33. // View::assign('files', $data['files']);
  34. // View::assign('counts', $data['counts']);
  35. // View::assign('activeurl', $data['activeurl']);
  36. // View::assign('activepath', $data['activepath']);
  37. $param = $this->request->param();
  38. $param['limit'] = isset($param['limit']) ? (int) $param['limit'] : Config::get('app.page_size');
  39. $list = FileManagerModel::queryPage($param);
  40. View::assign('list', $list);
  41. return View::fetch();
  42. }
  43. public function uploadFile()
  44. {
  45. $files = $this->request->file('upload_file');
  46. $savename = [];
  47. foreach($files as $file){
  48. $savename[] = \think\facade\Filesystem::disk('public')->putFile('/', $file);
  49. }
  50. }
  51. /**
  52. * 图片上传
  53. * @file upload_file 上传的文件
  54. * @param string $img_id 图片ipnut text id 默认值 picture
  55. * @param boolean $water 是否添加水印
  56. * @param boolean $thumb 是否制作缩略图
  57. * @param int $width 缩略图最大宽
  58. * @param int $height 缩略图最大高
  59. * @param bool $overwrite 生成缩略图后是否保存原图
  60. */
  61. public function uploadimg(string $img_id = 'picture', $water = false, $thumb = false, $width = 400, $height = 300, $overwrite = false)
  62. {
  63. if ($this->request->isPost()) {
  64. $file = $this->request->file('upload_file');
  65. if ($file) {
  66. try {
  67. validate(
  68. [
  69. 'file' => [
  70. // 限制文件大小(单位b),这里限制为4M
  71. 'fileSize' => 4 * 1024 * 1024,
  72. // 限制文件后缀,多个后缀以英文逗号分割
  73. 'fileExt' => 'jpg,png,gif,jpeg,webp,jfif'
  74. ]
  75. ],
  76. [
  77. 'file.fileSize' => '文件太大',
  78. 'file.fileExt' => '不支持的文件后缀',
  79. ]
  80. )->check(['file' => $file]);
  81. $arr = $this->dealUploadImg($file, $water, $thumb, $width, $height, $overwrite);
  82. return array_merge([
  83. 'code' => 0,
  84. 'img_id' => $img_id,
  85. 'picture_url' => Config::get('filesystem.disks.public.url') . '/']
  86. , $arr);
  87. } catch (\think\exception\ValidateException $e) {
  88. $this->error($e->getMessage());
  89. }
  90. } else {
  91. $this->error('图片不能为空');
  92. }
  93. } else {
  94. View::assign('img_id', $img_id);
  95. View::assign('water', $water);
  96. View::assign('thumb', $thumb);
  97. View::assign('width', $width);
  98. View::assign('height', $height);
  99. View::assign('overwrite', $overwrite);
  100. return View::fetch();
  101. }
  102. }
  103. /**
  104. * 图片上传
  105. * @file upload_file 上传的文件
  106. * @param string $img_id 图片ipnut text id 默认值 picture
  107. * @param boolean $water 是否添加水印
  108. * @param boolean $thumb 是否制作缩略图
  109. * @param int $width 缩略图最大宽
  110. * @param int $height 缩略图最大高
  111. * @param bool $overwrite 生成缩略图后是否保存原图
  112. */
  113. public function uploadurlimg(string $img_id = 'picture', $water = false, $thumb = false, $width = 400, $height = 300, $overwrite = false)
  114. {
  115. if ($this->request->isPost()) {
  116. $urlImg = $this->request->param('url_file');
  117. if ($urlImg) {
  118. try {
  119. $fileService = new FileService();
  120. $file = $fileService->urlImg($urlImg);
  121. $arr = $this->dealUploadImg($file, $water, $thumb, $width, $height, $overwrite);
  122. @unlink($file->realPath);
  123. return array_merge([
  124. 'code' => 0,
  125. 'img_id' => $img_id,
  126. 'picture_url' => Config::get('filesystem.disks.public.url') . '/']
  127. , $arr);
  128. } catch (\think\exception\ValidateException $e) {
  129. $this->error($e->getMessage());
  130. }
  131. } else {
  132. $this->error('图片地址不能为空');
  133. }
  134. }
  135. }
  136. public function uploadonlineimg(string $img_id = 'picture', $water = false, $thumb = false, $width = 400, $height = 300, $overwrite = false)
  137. {
  138. if ($this->request->isPost()) {
  139. $pathImg = $this->request->param('online_file');
  140. if ($pathImg && file_exists($this->app->getRootPath() . "public" . $pathImg)) {
  141. $picname = $pathImg;
  142. $thumbname = "";
  143. if ($thumb) {
  144. if (stripos($picname, $this->t_suffix)) {
  145. $thumbname = $pathImg;
  146. } else {
  147. try {
  148. $file = new File($this->app->getRootPath() . "public" . $pathImg);
  149. $ext = $file->getExtension();
  150. $thumbname = str_replace('.' . $ext, '', str_replace('\\', '/', $picname)) . $this->t_suffix . '.' . $ext;
  151. if (!file_exists($thumbname)) {
  152. $image = Image::open($file);
  153. $image->thumb($width, $height, 1);
  154. $image->save($this->app->getRootPath() . "public" . $thumbname);
  155. unset($image);
  156. }
  157. if ($overwrite) {
  158. $picname = $thumbname;
  159. }
  160. } catch (Exception $e) {
  161. $this->error($e->getMessage());
  162. }
  163. }
  164. }
  165. return [
  166. 'code' => 0,
  167. 'img_id' => $img_id,
  168. 'picname' => $picname,
  169. 'thumbname' => $thumbname,
  170. ];
  171. } else {
  172. $this->error('图片地址不存在');
  173. }
  174. }
  175. }
  176. public function onlineimg($page)
  177. {
  178. $files = FileService::getFiles(Config::get('filesystem.disks.public.root'));
  179. if (!count($files)) {
  180. return json_encode(array(
  181. "state" => "no match file",
  182. "list" => array(),
  183. "start" => $page,
  184. "total" => count($files)
  185. ));
  186. }
  187. /* 获取指定范围的列表 */
  188. $page = $page-1 < 0 ? 0 : (int)$page - 1;
  189. $size = 20;
  190. $start = $page * $size;
  191. $end = $start + $size;
  192. $len = count($files);
  193. for ($i = min($end, $len) - 1, $list = array(); $i < $len && $i >= 0 && $i >= $start; $i--){
  194. $list[] = $files[$i];
  195. }
  196. return json([ "code" => 0,
  197. "list" => $list,
  198. "page" => $page+1,
  199. "total" => count($files)
  200. ]);
  201. }
  202. /**
  203. * 获取当前文件相关信息
  204. * @return array $data 文件信息数据组
  205. */
  206. protected function explorer()
  207. {
  208. $param = $this->request->param();
  209. $activepath = isset($param['activepath']) ? $param['activepath'] : '';
  210. $inpath = "";
  211. $inpath = $this->img_path . $activepath;
  212. $dirhandle = scandir($inpath);
  213. $dirs = $files = [];
  214. define('BKM', 1024);
  215. foreach ($dirhandle as $val) {
  216. if ($val == "." || $val == "..") {
  217. continue;
  218. } elseif (is_dir($inpath . DIRECTORY_SEPARATOR . $val)) {
  219. $dirs[] = $val;
  220. } else {
  221. $arr = [];
  222. $file = '';
  223. $file = $inpath . DIRECTORY_SEPARATOR . $val;
  224. $arr['name'] = $val;
  225. $arr['extension'] = pathinfo($file, PATHINFO_EXTENSION);
  226. $filesize = floatval(filesize($file));
  227. if ($filesize > BKM) {
  228. $filesize = round($filesize / BKM, 2);
  229. if ($filesize > BKM) {
  230. $filesize = round($filesize / BKM, 2);
  231. $filesize .= "M";
  232. } else {
  233. $filesize .= "K";
  234. }
  235. } else {
  236. $filesize .= "B";
  237. }
  238. $arr['size'] = $filesize;
  239. $filetime = filemtime("$file");
  240. $arr['time'] = date("Y-m-d H:i:s", $filetime);
  241. $files[] = $arr;
  242. }
  243. }
  244. $counts = count($dirs) + count($files);
  245. $activeurl = preg_replace("#[\/][^\/]*$#i", "", $activepath);
  246. $data = [
  247. 'dirs' => $dirs,
  248. 'files' => $files,
  249. 'counts' => $counts,
  250. 'activeurl' => $activeurl,
  251. 'activepath' => $activepath,
  252. ];
  253. return $data;
  254. }
  255. public function delDir()
  256. {
  257. if ($this->request->isAjax()) {
  258. $activepath = $this->request->param('activepath');
  259. $activepath = str_replace('/', DIRECTORY_SEPARATOR, $activepath);
  260. $dir = $this->request->param('dir');
  261. $dir_name = app()->getRootPath . 'public' . DIRECTORY_SEPARATOR . $activepath . DIRECTORY_SEPARATOR . $dir;
  262. if (count(scandir($dir_name)) > 2) {
  263. return ['status' => 1, 'msg' => '不可删除非空目录'];
  264. }
  265. if (rmdir($dir_name)) {
  266. return ['status' => 2, 'msg' => 'success'];
  267. } else {
  268. return ['status' => 0, 'msg' => 'failed'];
  269. }
  270. }
  271. }
  272. public function del()
  273. {
  274. if ($this->request->isAjax()) {
  275. $activepath = $this->request->param('activepath');
  276. $activepath = str_replace('/', DIRECTORY_SEPARATOR, $activepath);
  277. $filename = $this->request->param('filename');
  278. if (unlink(app()->getRootPath . 'public' . DIRECTORY_SEPARATOR . $activepath . DIRECTORY_SEPARATOR . $filename)) {
  279. return ['status' => 1, 'msg' => 'success'];
  280. } else {
  281. return ['status' => 0, 'msg' => 'failed'];
  282. }
  283. }
  284. }
  285. // public function upload()
  286. // {
  287. // if ($this->request->isGet()) {
  288. // return View::fetch()();
  289. // } else {
  290. // $isthumb = $this->request->has('isthumb', 'post') ? $this->request->post('isthumb') : 0;
  291. // $mode = $this->request->has('formername', 'post') ? $this->request->post('formername') : 0;
  292. // $file = request()->file('image');
  293. // $info = $this->saveUpload($file, $mode);
  294. // if (!$info) {
  295. // $this->error($info->getError());
  296. // }
  297. // $filename = $info->getSaveName();
  298. // unset($info);
  299. // if ($isthumb == 1) {
  300. // $width = $this->request->has('width', 'post') ? $this->request->post('width') : $this->t_width;
  301. // $height = $this->request->has('height', 'post') ? $this->request->post('height') : $this->t_height;
  302. // $thumbname = $this->makeThumb($filename, $width, $height);
  303. // if (!$thumbname) {
  304. // $this->error('缩略图生成失败');
  305. // }
  306. // } else {
  307. // $thumbname = '';
  308. // }
  309. // if ($this->request->isAjax()) {
  310. // return ['code'=>2, 'picname' => $filename, 'thumbname'=>$thumbname];
  311. // } else {
  312. // $this->success('上传成功', '/file_manager/index');
  313. // }
  314. // }
  315. // }
  316. /**
  317. * 保存上传的图片
  318. * @param object $file 获取的上传对象
  319. * @param boolean $mode 是否保存原文件名 0(false), 生成新名称; 1(true), 保留原名
  320. * @return object 返回文件保存对象
  321. */
  322. protected function saveUpload($file, $mode)
  323. {
  324. $validate = ['size' => 2097152, 'ext' => 'jpg,png,gif,jpeg'];
  325. if ($mode) {
  326. $upload = $file->validate($validate)->move(app()->getRootPath . 'public' . DIRECTORY_SEPARATOR . 'uploads', '');
  327. } else {
  328. $upload = $file->validate($validate)->move(app()->getRootPath . 'public' . DIRECTORY_SEPARATOR . 'uploads');
  329. }
  330. return $upload;
  331. }
  332. /**
  333. * 站内选择
  334. * @return void
  335. */
  336. public function selectPicture()
  337. {
  338. $data = $this->explorer();
  339. View::assign('data', $data);
  340. return View::fetch()();
  341. }
  342. public function uploadPicture()
  343. {
  344. return View::fetch()();
  345. }
  346. // public function onlinePicture()
  347. // {
  348. // if ($this->request->isAjax()) {
  349. // $param = $this->request->param();
  350. // $urlimg = $param['filename'];
  351. // $download = $param['download'];
  352. // $isthumb = $param['isthumb'];
  353. // $formername = $param['formername'];
  354. // $res = \mylib\GetImageByurl::isImg($urlimg);
  355. // if (!$res) {
  356. // $this->error('该图片不合法');
  357. // } else {
  358. // if (!$download) {
  359. // return ['code'=>2,'filename'=>$urlimg];
  360. // } else {
  361. // $basepath = \config('url_domain_root') . '/uploads';
  362. // // var_dump($param);
  363. // if ($isthumb!=1 && preg_match("#" . $basepath . "#i", $urlimg)) {
  364. // $this->error('图片已在服务其中, 可直接选用');
  365. // }
  366. // // 按文件夹日期夹存放图片
  367. // $today = date('Ymd', time());
  368. // $savePath = $this->img_path . $today;
  369. // if (!is_dir($savePath)) {
  370. // if (mkdir($savePath) == false) {
  371. // $this->error('下载失败, 请稍后重试');
  372. // }
  373. // }
  374. // if ($formername==1) {
  375. // // 获取原文件名
  376. // $fileinfo = pathinfo($urlimg);
  377. // if (!isset($fileinfo['extension']) || !in_array($fileinfo['extension'], ['jpg', 'jpeg', 'png', 'gif'])) {
  378. // $ext = \mylib\GetImageByurl::getEXTENSION($urlimg);
  379. // }
  380. // $filename = $fileinfo['basename'] . '.' . $ext;
  381. // } else {
  382. // $filename = '';
  383. // }
  384. // $filename = \mylib\GetImageByurl::getImageByurl($urlimg, $filename, $savePath);
  385. // if ($filename) {
  386. // // 生成缩略图
  387. // if ($isthumb==1) {
  388. // $width = $this->request->has('width', 'post') ? $this->request->post('width') : $this->t_width;
  389. // $height = $this->request->has('height', 'post') ? $this->request->post('height') : $this->t_height;
  390. // $thumbname = $this->makeThumb($today . DIRECTORY_SEPARATOR . $filename, $width, $height);
  391. // if (!$thumbname) {
  392. // $this->error('缩略图生成失败');
  393. // }
  394. // } else {
  395. // $thumbname = '';
  396. // }
  397. // return ['code'=>2, 'filename' => $today . DIRECTORY_SEPARATOR . $filename, 'thumbname'=>$thumbname];
  398. // } else {
  399. // $this->error('图片下载失败');
  400. // }
  401. // }
  402. // }
  403. // } else {
  404. // return View::fetch()();
  405. // }
  406. // }
  407. /**
  408. * 判断(远程)文件是否为图片
  409. */
  410. // public function isImg()
  411. // {
  412. // if ($this->request->isAjax()) {
  413. // $filename = $this->request->param('filename');
  414. // $res = \mylib\GetImageByurl::isImg($filename);
  415. // if (!$res) {
  416. // $this->error('该图片不合法');
  417. // } else {
  418. // return ['code'=>2,'msg'=>'图片地址可用'];
  419. // }
  420. // }
  421. // }
  422. /**
  423. * 处理上传的图片
  424. */
  425. protected function dealUploadImg(File $file, $water, $thumb, $width, $height, $overwrite)
  426. {
  427. $savename = "";
  428. $thumbname = "";
  429. if ($water == true || $thumb == true) {
  430. $image = Image::open($file);
  431. if ($water) {
  432. $type = $this->system->water_type ?: Config::get('filesystem.water.type');
  433. if ($type == 'water') {
  434. $watemark = $this->system->watermark ?: Config::get('filesystem.water.watermark');
  435. $image->water($watemark);
  436. } else {
  437. $watetext = $this->system->watertext ?: Config::get('filesystem.water.watertext');
  438. $image->text($watetext, Config::get('filesystem.water.waterfont'), 30, '#ffffff30');
  439. }
  440. }
  441. $savename = $file->hashName();
  442. $realPath = Config::get('filesystem.disks.public.root') . '/' . $savename;
  443. if ($thumb == true) {
  444. if ($overwrite == true) {
  445. $image->thumb($width, $height, 1);
  446. $image->save($realPath);
  447. } else {
  448. $image->save($realPath);
  449. $image->thumb($width, $height, 1);
  450. $ext = $file->extension();
  451. $thumbname = str_replace('.' . $ext, '', str_replace('\\', '/', $savename)) . $this->t_suffix . '.' . $ext;
  452. // halt(Config::get('filesystem.disks.public.root') .'/' . $thumbname);
  453. $image->save(Config::get('filesystem.disks.public.root') . '/' . $thumbname);
  454. }
  455. } else {
  456. $image->save($realPath);
  457. }
  458. unset($image);
  459. } else {
  460. $savename = \think\facade\Filesystem::disk('public')->putFile('/', $file);
  461. }
  462. return [
  463. 'picname' => str_replace('\\', '/', $savename),
  464. 'thumbname' => $thumbname
  465. ];
  466. }
  467. /**
  468. * ckeditor 富文本编辑器上传图片
  469. */
  470. public function ckeditorUploadImage()
  471. {
  472. if ($this->request->isPost()) {
  473. $file = $this->request->file('upload');
  474. if ($file) {
  475. try {
  476. validate(
  477. [
  478. 'file' => [
  479. // 限制文件大小(单位b),这里限制为4M
  480. 'fileSize' => 4 * 1024 * 1024,
  481. // 限制文件后缀,多个后缀以英文逗号分割
  482. 'fileExt' => 'jpg,png,gif,jpeg,webp,jfif'
  483. ]
  484. ],
  485. [
  486. 'file.fileSize' => '文件太大',
  487. 'file.fileExt' => '不支持的文件后缀',
  488. ]
  489. )->check(['file' => $file]);
  490. $savename = \think\facade\Filesystem::disk('public')->putFile('/', $file);
  491. return json([
  492. 'uploaded' => 1,
  493. 'fileName' => basename($savename),
  494. 'url' => Config::get('filesystem.disks.public.url') . '/' . $savename
  495. ]);
  496. } catch (\think\exception\ValidateException $e) {
  497. $this->error($e->getMessage());
  498. return json([
  499. 'uploaded' => 1,
  500. 'error' => ['message'=>$e->getMessage()]
  501. ]);
  502. }
  503. } else {
  504. return json([
  505. 'uploaded' => 1,
  506. 'error' => ['message'=>'图片不能为空']
  507. ]);
  508. }
  509. }
  510. }
  511. }