FileManager.php 18 KB

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