Upload.php 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com
  8. * =========================================================
  9. */
  10. namespace app\model\upload;
  11. use app\model\image\ImageService;
  12. use extend\Upload as UploadExtend;
  13. use Intervention\Image\ImageManagerStatic as Image;
  14. use app\model\BaseModel;
  15. class Upload extends BaseModel
  16. {
  17. public $upload_path = __UPLOAD__;//公共上传文件
  18. public $config = []; //上传配置
  19. public $site_id;
  20. public $rule_type;//允许上传 mime类型
  21. public $rule_ext;// 允许上传 文件后缀
  22. public $path;//上传路径
  23. public $ext = '';
  24. public $driver = 'gd';
  25. public $image_service;//图片类实例
  26. public function __construct($site_id = 1, $app_module = 'shop')
  27. {
  28. $this->site_id = $site_id;
  29. $config_model = new Config();
  30. $config_result = $config_model->getUploadConfig(1, 'shop');
  31. $this->config = $config_result[ "data" ][ "value" ];//上传配置
  32. $this->driver = config('upload')[ 'driver' ] ?? 'gd';
  33. $this->image_service = new ImageService($this->driver);
  34. }
  35. /************************************************************上传开始*********************************************/
  36. /**
  37. * 单图上传
  38. * @param number $site_id
  39. * @param string $thumb_type 生成缩略图类型
  40. */
  41. public function image($param)
  42. {
  43. $check_res = $this->checkImg();
  44. if ($check_res[ "code" ] >= 0) {
  45. $file = request()->file($param[ "name" ]);
  46. if (empty($file))
  47. return $this->error();
  48. $tmp_name = $file->getPathname();//获取上传缓存文件
  49. $original_name = $file->getOriginalName();//文件原名
  50. $file_path = $this->path;
  51. // 检测目录
  52. $checkpath_result = $this->checkPath($file_path);//验证写入文件的权限
  53. if ($checkpath_result[ "code" ] < 0)
  54. return $checkpath_result;
  55. $file_name = $file_path . $this->createNewFileName();
  56. $extend_name = $file->getOriginalExtension();
  57. // $thumb_type = $param[ "thumb_type" ];
  58. //原图保存
  59. $new_file = $file_name . "." . $extend_name;
  60. $image = $this->getImageService($tmp_name);
  61. $width = $image->width;//图片宽
  62. $height = $image->height;//图片高
  63. if (!empty($param[ 'width' ]) && !empty($param[ 'height' ]) && $width != $param[ 'width' ] && $height != $param[ 'height' ]) {
  64. return $this->error('', '图片尺寸限制为' . $param[ 'width' ] . ' x ' . $param[ 'height' ]);
  65. } elseif (!empty($param[ 'width' ]) && $width != $param[ 'width' ]) {
  66. return $this->error('', '图片尺寸宽度限制为' . $param[ 'width' ]);
  67. } elseif (!empty($param[ 'height' ]) && $height != $param[ 'height' ]) {
  68. return $this->error('', '图片尺寸高度限制为' . $param[ 'height' ]);
  69. }
  70. // $image->contrast(10);
  71. // 是否需生成水印
  72. if (isset($param[ 'watermark' ]) && $param[ 'watermark' ]) {
  73. $image = $this->imageWater($image);
  74. }
  75. // 是否需上传到云存储
  76. if (isset($param[ 'cloud' ]) && $param[ 'cloud' ]) {
  77. $result = $this->imageCloud($image, $new_file, $file);
  78. if ($result[ "code" ] < 0)
  79. return $result;
  80. } else {
  81. try {
  82. $image->save($new_file);
  83. $result = $this->success($new_file, "UPLOAD_SUCCESS");
  84. } catch (\Exception $e) {
  85. return $this->error('', $e->getMessage());
  86. }
  87. }
  88. // $thumb_res = $this->thumbBatch($tmp_name, $file_name, $extend_name, $thumb_type);//生成缩略图
  89. // if ($thumb_res[ "code" ] < 0)
  90. // return $result;
  91. $data = array (
  92. "pic_path" => $result[ "data" ],//图片云存储
  93. "pic_name" => $original_name,
  94. "file_ext" => $extend_name,
  95. "pic_spec" => $width . "*" . $height,
  96. "update_time" => time(),
  97. "site_id" => $this->site_id
  98. );
  99. return $this->success($data, "UPLOAD_SUCCESS");
  100. } else {
  101. //返回错误信息
  102. return $check_res;
  103. }
  104. }
  105. public function getImageService($file)
  106. {
  107. $image = $this->image_service->open($file);
  108. return $image;
  109. }
  110. /**
  111. * 相册图片上传
  112. * @param number $site_id
  113. * @param number $category_id
  114. * @param string $thumb_type
  115. */
  116. public function imageToAlbum($param)
  117. {
  118. $check_res = $this->checkImg();
  119. if ($check_res[ "code" ] >= 0) {
  120. $file = request()->file($param[ "name" ]);
  121. if (empty($file))
  122. return $this->error();
  123. $tmp_name = $file->getPathname();//获取上传缓存文件
  124. $original_name = $file->getOriginalName();//文件原名
  125. $file_path = $this->path;
  126. // 检测目录
  127. $checkpath_result = $this->checkPath($file_path);//验证写入文件的权限
  128. if ($checkpath_result[ "code" ] < 0)
  129. return $checkpath_result;
  130. $file_name = $file_path . $this->createNewFileName();
  131. $extend_name = $file->getOriginalExtension();
  132. $this->ext = $extend_name;
  133. $thumb_type = $param[ "thumb_type" ];//所留
  134. $album_id = $param[ "album_id" ];
  135. $is_thumb = $param[ 'is_thumb' ] ?? 0;
  136. $new_file = $file_name . "." . $extend_name;
  137. $image = $this->getImageService($tmp_name);
  138. $width = $image->width;//图片宽
  139. $height = $image->height;//图片高
  140. // 原图不需要加水印处理
  141. // if($is_thumb == 1){
  142. // $image = $this->imageWater($image);
  143. // }
  144. $result = $this->imageCloud($image, $new_file, $file);//原图云上传(文档流上传)
  145. if ($result[ "code" ] < 0)
  146. return $result;
  147. if ($is_thumb == 1) {
  148. $thumb_res = $this->thumbBatch($result[ 'data' ], $file_name, $extend_name, $thumb_type);//生成缩略图
  149. if ($thumb_res[ "code" ] < 0)
  150. return $result;
  151. }
  152. $pic_name_first = substr(strrchr($original_name, '.'), 1);
  153. $pic_name = basename($original_name, "." . $pic_name_first);
  154. $data = array (
  155. "pic_path" => $result[ "data" ],//图片云存储
  156. "pic_name" => $pic_name,
  157. "pic_spec" => $width . "*" . $height,
  158. "update_time" => time(),
  159. "site_id" => $this->site_id,
  160. "album_id" => $album_id,
  161. "is_thumb" => $is_thumb,
  162. );
  163. $album_model = new Album();
  164. $res = $album_model->addAlbumPic($data);
  165. if ($res[ 'code' ] >= 0) {
  166. $data[ "id" ] = $res[ "data" ];
  167. return $this->success($data, "UPLOAD_SUCCESS");
  168. } else {
  169. return $this->error($res);
  170. }
  171. } else {
  172. //返回错误信息
  173. return $check_res;
  174. }
  175. }
  176. /*
  177. * 替换图片文件
  178. * */
  179. public function modifyFile($param)
  180. {
  181. // 参数校验
  182. if (empty($param[ 'album_id' ])) {
  183. return $this->error('', "PARAMETER_ERROR");
  184. }
  185. if (empty($param[ 'pic_id' ])) {
  186. return $this->error('', "PARAMETER_ERROR");
  187. }
  188. if (empty($param[ 'filename' ])) {
  189. return $this->error('', "PARAMETER_ERROR");
  190. }
  191. if (empty($param[ 'suffix' ])) {
  192. return $this->error('', "PARAMETER_ERROR");
  193. }
  194. $check_res = $this->checkImg();
  195. if ($check_res[ "code" ] >= 0) {
  196. $file = request()->file($param[ "name" ]);
  197. if (empty($file))
  198. return $this->error();
  199. $tmp_name = $file->getPathname();//获取上传缓存文件
  200. $original_name = $file->getOriginalName();//文件原名
  201. $file_path = $this->path;
  202. // 检测目录
  203. $checkpath_result = $this->checkPath($file_path);//验证写入文件的权限
  204. if ($checkpath_result[ "code" ] < 0) {
  205. return $checkpath_result;
  206. }
  207. // 保留原文件名和后缀
  208. $file_name = $file_path . $param[ 'filename' ];
  209. $extend_name = $param[ 'suffix' ];
  210. $thumb_type = $param[ "thumb_type" ];//所留
  211. //原图保存
  212. $new_file = $file_name . "." . $extend_name;
  213. $image = $this->getImageService($tmp_name);
  214. $width = $image->width;//图片宽
  215. $height = $image->height;//图片高
  216. // $image = $this->imageWater($image);
  217. $result = $this->imageCloud($image, $new_file, $file);//原图云上传(文档流上传)
  218. if ($result[ "code" ] < 0) {
  219. return $result;
  220. }
  221. $thumb_res = $this->thumbBatch($tmp_name, $file_name, $extend_name, $thumb_type);//生成缩略图
  222. if ($thumb_res[ "code" ] < 0) {
  223. return $thumb_res;
  224. }
  225. $pic_name_first = substr(strrchr($original_name, '.'), 1);
  226. $pic_name = basename($original_name, "." . $pic_name_first);
  227. $data = array (
  228. "pic_path" => $result[ "data" ],//图片云存储
  229. "pic_spec" => $width . "*" . $height,
  230. "update_time" => time(),
  231. );
  232. $album_model = new Album();
  233. $condition = array (
  234. [ "pic_id", "=", $param[ 'pic_id' ] ],
  235. [ "site_id", "=", $this->site_id ],
  236. [ 'album_id', "=", $param[ 'album_id' ] ],
  237. );
  238. $res = $album_model->editAlbumPic($data, $condition);
  239. if ($res[ 'code' ] >= 0) {
  240. $data[ "id" ] = $res[ "data" ];
  241. return $this->success($data, "UPLOAD_SUCCESS");
  242. } else {
  243. return $this->error($res);
  244. }
  245. } else {
  246. //返回错误信息
  247. return $check_res;
  248. }
  249. }
  250. /**
  251. * 视频上传
  252. * @param $param
  253. */
  254. public function videoToAlbum($param)
  255. {
  256. $check_res = $this->checkVideo();
  257. if ($check_res[ "code" ] >= 0) {
  258. // 获取表单上传文件
  259. $file = request()->file($param[ "name" ]);
  260. try {
  261. $extend_name = $file->getOriginalExtension();
  262. $new_name = $this->createNewFileName() . "." . $extend_name;
  263. $original_name = $file->getOriginalName();//文件原名
  264. $file_path = $this->path;
  265. \think\facade\Filesystem::disk('public')->putFileAs($file_path, $file, $new_name);
  266. $file_name = $file_path . $new_name;
  267. $result = $this->fileCloud($file_name);
  268. $pic_name_first = substr(strrchr($original_name, '.'), 1);
  269. $pic_name = basename($original_name, "." . $pic_name_first);
  270. $data = array (
  271. "pic_path" => $result[ "data" ],//图片云存储
  272. "pic_name" => $pic_name,
  273. "pic_spec" => '',
  274. "update_time" => time(),
  275. "site_id" => $this->site_id,
  276. "album_id" => $param[ 'album_id' ],
  277. "is_thumb" => 0,
  278. );
  279. $album_model = new Album();
  280. $res = $album_model->addAlbumPic($data);
  281. if ($res[ 'code' ] >= 0) {
  282. $data[ "id" ] = $res[ "data" ];
  283. return $this->success($data, "UPLOAD_SUCCESS");
  284. } else {
  285. return $this->error($res);
  286. }
  287. } catch (\think\exception\ValidateException $e) {
  288. return $this->error('', $e->getMessage());
  289. }
  290. } else {
  291. return $check_res;
  292. }
  293. }
  294. /**
  295. * 视频上传
  296. * @param $param
  297. */
  298. public function video($param)
  299. {
  300. $check_res = $this->checkVideo();
  301. if ($check_res[ "code" ] >= 0) {
  302. // 获取表单上传文件
  303. $file = request()->file($param[ "name" ]);
  304. try {
  305. $extend_name = $file->getOriginalExtension();
  306. $new_name = $this->createNewFileName() . "." . $extend_name;
  307. $file_path = $this->path;
  308. \think\facade\Filesystem::disk('public')->putFileAs($file_path, $file, $new_name);
  309. $file_name = $file_path . $new_name;
  310. $result = $this->fileCloud($file_name);
  311. return $this->success([ "path" => $result[ 'data' ] ?? '' ], "UPLOAD_SUCCESS");
  312. } catch (\think\exception\ValidateException $e) {
  313. return $this->error('', $e->getMessage());
  314. }
  315. } else {
  316. return $check_res;
  317. }
  318. }
  319. /*
  320. * 替换视频文件
  321. * */
  322. public function modifyVideoFile($param)
  323. {
  324. // 参数校验
  325. if (empty($param[ 'album_id' ])) {
  326. return $this->error('', "PARAMETER_ERROR");
  327. }
  328. if (empty($param[ 'pic_id' ])) {
  329. return $this->error('', "PARAMETER_ERROR");
  330. }
  331. $check_res = $this->checkVideo();
  332. if ($check_res[ "code" ] >= 0) {
  333. $file = request()->file($param[ "name" ]);
  334. if (empty($file))
  335. return $this->error();
  336. $extend_name = $file->getOriginalExtension();
  337. $new_name = $this->createNewFileName() . "." . $extend_name;
  338. $original_name = $file->getOriginalName();//文件原名
  339. $file_path = $this->path;
  340. // 检测目录
  341. $checkpath_result = $this->checkPath($file_path);//验证写入文件的权限
  342. if ($checkpath_result[ "code" ] < 0) {
  343. return $checkpath_result;
  344. }
  345. \think\facade\Filesystem::disk('public')->putFileAs($file_path, $file, $new_name);
  346. $file_name = $file_path . $new_name;
  347. $result = $this->fileCloud($file_name);
  348. $pic_name_first = substr(strrchr($original_name, '.'), 1);
  349. $pic_name = basename($original_name, "." . $pic_name_first);
  350. $data = array (
  351. "pic_path" => $result[ "data" ],//图片云存储
  352. "update_time" => time(),
  353. );
  354. $album_model = new Album();
  355. $condition = array (
  356. [ "pic_id", "=", $param[ 'pic_id' ] ],
  357. [ "site_id", "=", $this->site_id ],
  358. [ 'album_id', "=", $param[ 'album_id' ] ],
  359. );
  360. $res = $album_model->editAlbumPic($data, $condition);
  361. if ($res[ 'code' ] >= 0) {
  362. $data[ "id" ] = $res[ "data" ];
  363. return $this->success($data, "UPLOAD_SUCCESS");
  364. } else {
  365. return $this->error($res);
  366. }
  367. } else {
  368. //返回错误信息
  369. return $check_res;
  370. }
  371. }
  372. /**
  373. * 上传文件
  374. * @param $param
  375. */
  376. public function file($param)
  377. {
  378. $check_res = $this->checkFile();
  379. if ($check_res[ "code" ] >= 0) {
  380. // 获取表单上传文件
  381. $file = request()->file($param[ "name" ]);
  382. try {
  383. $extend_name = $file->getOriginalExtension();
  384. if (!empty($param[ 'extend_type' ])) {
  385. if (!in_array($extend_name, $param[ 'extend_type' ])) {
  386. return $this->error([], 'UPLOAD_TYPE_ERROR');
  387. }
  388. }
  389. $new_name = $this->createNewFileName() . "." . $extend_name;
  390. $file_path = $this->path;
  391. \think\facade\Filesystem::disk('public')->putFileAs($file_path, $file, $new_name);
  392. $file_name = $file_path . $new_name;
  393. return $this->success([ "path" => $file_name, 'name' => $new_name ], "UPLOAD_SUCCESS");
  394. } catch (\think\exception\ValidateException $e) {
  395. return $this->error('', $e->getMessage());
  396. }
  397. } else {
  398. return $check_res;
  399. }
  400. }
  401. /**
  402. * 域名校验文件
  403. */
  404. public function domainCheckFile($param)
  405. {
  406. $check_res = $this->checkFile();
  407. if ($check_res[ "code" ] >= 0) {
  408. // 获取表单上传文件
  409. $file = request()->file($param[ "name" ]);
  410. try {
  411. $file_name = $file->getOriginalName();
  412. $file_path = '';
  413. \think\facade\Filesystem::disk('public')->putFileAs($file_path, $file, $file_name);
  414. $file_name = $file_path . $file_name;
  415. return $this->success([ "path" => $file_name ], "UPLOAD_SUCCESS");
  416. } catch (\think\exception\ValidateException $e) {
  417. return $this->error('', $e->getMessage());
  418. }
  419. } else {
  420. return $check_res;
  421. }
  422. }
  423. /************************************************************上传结束*********************************************/
  424. /************************************************************上传功能组件******************************************/
  425. /**
  426. * 缩略图生成
  427. * @param unknown $file_name
  428. * @param unknown $extend_name
  429. * @param unknown $thumb_type
  430. * @return Ambigous <string, multitype:multitype:string >
  431. */
  432. public function thumbBatch($file_path, $file_name, $extend_name, $thumb_type = [])
  433. {
  434. $thumb_type_array = array (
  435. "BIG" => array (
  436. "size" => "BIG",
  437. "width" => $this->config[ "thumb" ][ "thumb_big_width" ],
  438. "height" => $this->config[ "thumb" ][ "thumb_big_height" ],
  439. "thumb_name" => ""
  440. ),
  441. "MID" => array (
  442. "size" => "MID",
  443. "width" => $this->config[ "thumb" ][ "thumb_mid_width" ],
  444. "height" => $this->config[ "thumb" ][ "thumb_mid_height" ],
  445. "thumb_name" => ""
  446. ),
  447. "SMALL" => array (
  448. "size" => "SMALL",
  449. "width" => $this->config[ "thumb" ][ "thumb_small_width" ],
  450. "height" => $this->config[ "thumb" ][ "thumb_small_height" ],
  451. "thumb_name" => ""
  452. )
  453. );
  454. foreach ($thumb_type_array as $k => $v) {
  455. if (!empty($thumb_type) && in_array($k, $thumb_type)) {
  456. $new_path_name = $file_name . "_" . $v[ "size" ] . "." . $extend_name;
  457. $result = $this->imageThumb($file_path, $new_path_name, $v[ "width" ], $v[ "height" ], $v[ "size" ] != 'BIG' ? 'center' : '');
  458. //返回生成的缩略图路径
  459. if ($result[ "code" ] >= 0) {
  460. $thumb_type_array[ $k ][ "thumb_name" ] = $new_path_name;
  461. } else {
  462. return $result;
  463. }
  464. }
  465. }
  466. return $this->success($thumb_type_array);
  467. }
  468. /**
  469. * 缩略图
  470. * @param unknown $file_name
  471. * @param unknown $new_path
  472. * @param unknown $width
  473. * @param unknown $height
  474. * @return multitype:boolean unknown |multitype:boolean
  475. */
  476. public function imageThumb($file, $thumb_name, $width, $height, $fit = 'center')
  477. {
  478. // $image = $this->getImageService($file)->thumb($width, $height, $fit);
  479. // $result = $this->imageCloud($image, $thumb_name);
  480. $image = $this->getImageService($file);
  481. $image = $image->thumb($width, $height, $fit);
  482. $image = $this->imageWater($image);
  483. $result = $this->imageCloud($image, $thumb_name);
  484. return $result;
  485. }
  486. /**
  487. * 添加水印
  488. */
  489. public function imageWater($image)
  490. {
  491. //判断是否有水印(具体走配置)
  492. if ($this->config[ "water" ][ "is_watermark" ]) {
  493. switch ( $this->config[ "water" ][ "watermark_type" ] ) {
  494. case "1"://图片水印
  495. if (!empty($this->config[ "water" ][ "watermark_source" ]) && is_file($this->config[ "water" ][ "watermark_source" ])) {
  496. $water_path = $this->config[ "water" ][ "watermark_source" ];
  497. $water_opacity = empty($this->config[ "water" ][ "watermark_opacity" ]) ? 0 : $this->config[ "water" ][ "watermark_opacity" ];
  498. $water_rotate = empty($this->config[ "water" ][ "watermark_rotate" ]) ? 0 : $this->config[ "water" ][ "watermark_rotate" ];
  499. $water_position = $this->config[ "water" ][ "watermark_position" ];
  500. $water_x = $this->config[ "water" ][ "watermark_x" ];
  501. $water_y = $this->config[ "water" ][ "watermark_y" ];
  502. $image = $image->imageWater($water_path, $water_opacity, $water_rotate, $water_position, $water_x, $water_y);
  503. }
  504. break;
  505. case "2"://文字水印
  506. if (!empty($this->config[ "water" ][ "watermark_text" ])) {
  507. $text = $this->config[ "water" ][ "watermark_text" ];
  508. $x = $this->config[ "water" ][ "watermark_x" ];
  509. if(empty($x)){
  510. $x = 0;
  511. }
  512. $y = $this->config[ "water" ][ "watermark_y" ];
  513. if(empty($y)){
  514. $y = 0;
  515. }
  516. $size = $this->config[ "water" ][ "watermark_text_size" ];
  517. if(empty($size)){
  518. $size = 12;
  519. }
  520. $color = $this->config[ "water" ][ "watermark_text_color" ];
  521. $align = $this->config[ "water" ][ "watermark_text_align" ];
  522. $valign = $this->config[ "water" ][ "watermark_text_valign" ];
  523. $angle = $this->config[ "water" ][ "watermark_text_angle" ];
  524. if(empty($angle)){
  525. $angle = 0;
  526. }
  527. $image = $image->textWater($text, $x, $y, $size, $color, $align, $valign, $angle);
  528. }
  529. break;
  530. }
  531. }
  532. return $image;
  533. }
  534. public function to_unicode($string)
  535. {
  536. $str = mb_convert_encoding($string, 'gb2312', 'UTF-8');
  537. $arrstr = str_split($str, 2);
  538. $unistr = '';
  539. foreach ($arrstr as $n) {
  540. $dec = hexdec(bin2hex($n));
  541. $unistr .= '&#' . $dec . ';';
  542. }
  543. return $unistr;
  544. }
  545. /**
  546. * 删除文件
  547. * @param $file_name
  548. */
  549. public function deleteFile($file_name)
  550. {
  551. if (file_exists($file_name)) {
  552. $res = @unlink($file_name);
  553. if ($res) {
  554. return $this->success();
  555. } else {
  556. return $this->error();
  557. }
  558. }
  559. return $this->success();
  560. }
  561. /**
  562. * 图片云上传中转
  563. * @param $image
  564. * @param $file
  565. * @return array|mixed|string
  566. */
  567. public function imageCloud($image_class, $file, $tmp_file = '')
  568. {
  569. try {
  570. $compress_array = array (
  571. 'large' => 90,
  572. 'medium' => 75,
  573. 'small' => 55,
  574. 'original' => null
  575. );
  576. $compress = $this->config[ 'upload' ][ 'compress' ] ?? 'original';
  577. if ($compress == 'original' && !empty($tmp_file)) {
  578. \think\facade\Filesystem::disk('public')->putFileAs('', $tmp_file, $file);
  579. } else {
  580. $compress = $compress_array[ $this->config[ 'upload' ][ 'compress' ] ?? 'original' ];
  581. $image_class->save($file, $compress);
  582. }
  583. $result = $this->fileCloud($file);
  584. //云上传没有成功 保存到本地
  585. return $result;
  586. } catch (\Exception $e) {
  587. return $this->error('', $e->getMessage());
  588. }
  589. }
  590. /**
  591. * 云上传
  592. */
  593. public function fileCloud($file)
  594. {
  595. try {
  596. //走 云上传
  597. $put_result = event("Put", [ "file_path" => $file, "key" => $file ], true);
  598. if (!empty($put_result)) {
  599. if ($put_result[ "code" ] >= 0) {
  600. $this->deleteFile($file);
  601. $file = $put_result[ "data" ][ "path" ];
  602. } else {
  603. return $put_result;
  604. }
  605. }
  606. //云上传没有成功 保存到本地
  607. return $this->success($file, "UPLOAD_SUCCESS");
  608. } catch (\Exception $e) {
  609. return $this->error('', $e->getMessage());
  610. }
  611. }
  612. /**
  613. * 图片验证
  614. * @param $file
  615. * @return \multitype
  616. */
  617. public function checkImg()
  618. {
  619. try {
  620. $file = request()->file();
  621. $rule_array = [];
  622. $size_rule = $this->config[ 'upload' ][ 'max_filesize' ];
  623. $ext_rule = 'jpg,jpeg,png,gif,pem,webp';
  624. $mime_rule = 'image/webp,image/jpg,image/jpeg,image/gif,image/png,text/plain';
  625. if (!empty($size_rule)) {
  626. $rule_array[] = "fileSize:{$size_rule}";
  627. }
  628. if (!empty($ext_rule)) {
  629. $rule_array[] = "fileExt:{$ext_rule}";
  630. }
  631. if (!empty($mime_rule)) {
  632. $rule_array[] = "fileMime:{$mime_rule}";
  633. }
  634. if (!empty($rule_array)) {
  635. $rule = implode('|', $rule_array);
  636. validate([ 'file' => $rule ])->check($file);
  637. }
  638. return $this->success();
  639. } catch (\think\exception\ValidateException $e) {
  640. return $this->error('', $e->getMessage());
  641. }
  642. }
  643. /**
  644. * 文件验证
  645. * @param $file
  646. * @return \multitype
  647. */
  648. public function checkFile()
  649. {
  650. try {
  651. $file = request()->file();
  652. $suffix = pathinfo($_FILES[ 'file' ][ 'name' ], PATHINFO_EXTENSION);
  653. if ($suffix == "pem" || $suffix == "crt") {
  654. return $this->success();
  655. }
  656. $rule_array = [];
  657. $size_rule = '';
  658. $ext_rule = "txt,xlsx,xls,csv,pem";
  659. $mime_rule = "text/plain,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,text/csv";
  660. if (!empty($size_rule)) {
  661. $rule_array[] = "fileSize:{$size_rule}";
  662. }
  663. if (!empty($ext_rule)) {
  664. $rule_array[] = "fileExt:{$ext_rule}";
  665. }
  666. if (!empty($mime_rule)) {
  667. $rule_array[] = "fileMime:{$mime_rule}";
  668. }
  669. $rule = implode("|", $rule_array);
  670. $res = validate([ 'file' => $rule ])->check($file);
  671. if ($res) {
  672. return $this->success();
  673. } else {
  674. return $this->error();
  675. }
  676. } catch (\think\exception\ValidateException $e) {
  677. return $this->error('', $e->getMessage());
  678. }
  679. }
  680. /************************************************************上传功能组件******************************************/
  681. public function checkVideo()
  682. {
  683. try {
  684. $file = request()->file();
  685. $rule_array = [];
  686. $size_rule = '';
  687. $ext_rule = "mp4,avi";
  688. $mime_rule = "video/mp4,video/x-msvideo";
  689. if (!empty($size_rule)) {
  690. $rule_array[] = "fileSize:{$size_rule}";
  691. }
  692. if (!empty($ext_rule)) {
  693. $rule_array[] = "fileExt:{$ext_rule}";
  694. }
  695. if (!empty($mime_rule)) {
  696. $rule_array[] = "fileMime:{$mime_rule}";
  697. }
  698. $rule = implode("|", $rule_array);
  699. $res = validate([ 'file' => $rule ])->check($file);
  700. if ($res) {
  701. return $this->success();
  702. } else {
  703. return $this->error();
  704. }
  705. } catch (\think\exception\ValidateException $e) {
  706. return $this->error('', $e->getMessage());
  707. }
  708. }
  709. /**
  710. *获取一个新文件名
  711. */
  712. public function createNewFileName()
  713. {
  714. $name = date('Ymdhis', time())
  715. . sprintf('%03d', microtime(true) * 1000)
  716. . sprintf('%02d', mt_rand(10, 99));
  717. return $name;
  718. }
  719. /**
  720. * 验证目录是否可写
  721. * @param unknown $path
  722. * @return boolean
  723. */
  724. public function checkPath($path)
  725. {
  726. if (file_exists($path) || mkdir($path, 0755, true)) {
  727. return $this->success();
  728. }
  729. return $this->error('', "上传目录 {$path} 创建失败,请检测权限");
  730. }
  731. /**
  732. * 设置上传目录
  733. * @param $path
  734. */
  735. public function setPath($path)
  736. {
  737. if ($this->site_id > 0) {
  738. $this->path = $this->site_id . "/" . $path;
  739. } else {
  740. $this->path = $path;
  741. }
  742. $this->path = $this->upload_path . "/" . $this->path;
  743. return $this;
  744. }
  745. /**
  746. * 远程拉取图片
  747. * @param $path
  748. */
  749. public function remotePull($path, $file_name = '')
  750. {
  751. try {
  752. $file_path = $this->path;
  753. // 检测目录
  754. $checkpath_result = $this->checkPath($file_path);//验证写入文件的权限
  755. if ($checkpath_result[ "code" ] < 0)
  756. return $checkpath_result;
  757. $file_name = $file_path . ($file_name ? $file_name : $this->createNewFileName());
  758. $new_file = $file_name . ".png";
  759. $ch = curl_init();
  760. curl_setopt($ch, CURLOPT_URL, $path);
  761. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  762. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
  763. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  764. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  765. $file = curl_exec($ch);
  766. curl_close($ch);
  767. $image = $this->getImageService($file);
  768. $image = $this->imageWater($image);
  769. $result = $this->imageCloud($image, $new_file);//原图云上传(文档流上传)
  770. if ($result[ "code" ] < 0)
  771. return $result;
  772. return $this->success([ "pic_path" => $result[ "data" ] ]);
  773. } catch (\think\exception\ValidateException $e) {
  774. return $this->error('', $e->getMessage());
  775. }
  776. }
  777. public function remotePullBinary($file)
  778. {
  779. $file_path = $this->path;
  780. // 检测目录
  781. $checkpath_result = $this->checkPath($file_path);//验证写入文件的权限
  782. if ($checkpath_result[ "code" ] < 0)
  783. return $checkpath_result;
  784. $file_name = $file_path . $this->createNewFileName();
  785. $new_file = $file_name . ".png";
  786. $image = $this->getImageService($file);
  787. $result = $this->imageCloud($image, $new_file);//原图云上传(文档流上传)
  788. if ($result[ "code" ] < 0)
  789. return $result;
  790. return $this->success([ "pic_path" => $result[ "data" ] ]);
  791. }
  792. /**
  793. * 远程拉取图片到本地
  794. * @param $path
  795. */
  796. public function remotePullToLocal($path)
  797. {
  798. if (stristr($path, 'http://') || stristr($path, 'https://')) {
  799. $file_path = $this->path;
  800. // 检测目录
  801. $checkpath_result = $this->checkPath($file_path);//验证写入文件的权限
  802. if ($checkpath_result[ "code" ] < 0)
  803. return $checkpath_result;
  804. $file_name = $file_path . $this->createNewFileName();
  805. $new_file = $file_name . ".png";
  806. $ch = curl_init();
  807. curl_setopt($ch, CURLOPT_URL, $path);
  808. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  809. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
  810. $file = curl_exec($ch);
  811. curl_close($ch);
  812. $image = $this->getImageService($file);
  813. $image = $this->imageWater($image);
  814. $image->save($new_file);
  815. return $this->success([ "path" => $new_file ]);
  816. } else {
  817. return $this->success([ "path" => $path ]);
  818. }
  819. }
  820. /**
  821. * 远程拉取图片到本地
  822. * @param $path
  823. */
  824. public function remotePullToLocalPic($path)
  825. {
  826. if(strpos($path, 'http://') === false && strpos($path, 'https://') === false){
  827. $path = "https:".$path;
  828. }
  829. $file_path = $this->path;
  830. // 检测目录
  831. $checkpath_result = $this->checkPath($file_path);//验证写入文件的权限
  832. if ($checkpath_result[ "code" ] < 0)
  833. return $checkpath_result;
  834. $file_name = $file_path . $this->createNewFileName();
  835. $new_file = $file_name . ".png";
  836. $content = file_get_contents($path);
  837. //todo 考虑imagick支持文档流的可能性
  838. $image = Image::make($content);//兼容
  839. $image = $this->imageWater($image);
  840. $image->save($new_file);
  841. return $this->success([ "path" => $new_file ]);
  842. }
  843. /**
  844. * 二维码生成 返回base64
  845. * @param $url
  846. * @return array
  847. */
  848. public function qrcode($url)
  849. {
  850. $file_path = qrcode($url, "weixinpay/qrcode/" . date("Ymd") . '/', date("Ymd") . 'qrcode');
  851. //$file:图片地址
  852. //Filetype: JPEG,PNG,GIF
  853. $file = $file_path;
  854. if ($fp = fopen($file, "rb", 0)) {
  855. $gambar = fread($fp, filesize($file_path));
  856. fclose($fp);
  857. $base64 = "data:image/jpg/png/gif;base64," . chunk_split(base64_encode($gambar));
  858. $this->deleteFile($file_path);
  859. return $this->success($base64);
  860. } else {
  861. return $this->error();
  862. }
  863. }
  864. /**
  865. * 远程拉取商品图片
  866. */
  867. public function remoteGoodsPullToLocal($param)
  868. {
  869. $remote_result = $this->remotePullToLocalPic($param[ 'img' ]);
  870. if ($remote_result[ 'code' ] < 0) {
  871. return $remote_result;
  872. }
  873. $img_path = $remote_result[ 'data' ][ 'path' ];//原图本地化的图片路径
  874. $file_path = $this->path;
  875. $file_name = $file_path . $this->createNewFileName();//生成新的完整文件路径
  876. $img_array = explode('.', $param[ 'img' ]);
  877. $extend_name = end($img_array);//获取文件的后缀名
  878. $thumb_type = $param[ "thumb_type" ];
  879. //原图保存
  880. $new_file = $file_name . "." . $extend_name;
  881. $image = $this->getImageService($img_path);
  882. $width = $image->width;//图片宽
  883. $height = $image->height;//图片高
  884. $image = $this->imageWater($image);
  885. $result = $this->imageCloud($image, $new_file);//原图云上传(文档流上传)
  886. if ($result[ "code" ] < 0)
  887. return $result;
  888. if($param['thumb_type']){
  889. $thumb_res = $this->thumbBatch($img_path, $file_name, $extend_name, $thumb_type);//生成缩略图
  890. if ($thumb_res[ "code" ] < 0)
  891. return $result;
  892. }
  893. $data = array (
  894. "pic_path" => $result[ "data" ],//图片云存储
  895. "file_ext" => $extend_name,
  896. "pic_spec" => $width . "*" . $height,
  897. "update_time" => time(),
  898. "site_id" => $this->site_id
  899. );
  900. $album_data = array (
  901. "pic_path" => $result[ "data" ],//图片云存储
  902. "pic_name" => '',
  903. "pic_spec" => $width . "*" . $height,
  904. "update_time" => time(),
  905. "site_id" => $this->site_id,
  906. "album_id" => $param[ 'album_id' ]
  907. );
  908. $album_model = new Album();
  909. $res = $album_model->addAlbumPic($album_data);
  910. if ($res[ 'code' ] >= 0) {
  911. return $this->success($data, "UPLOAD_SUCCESS");
  912. } else {
  913. return $this->error($res);
  914. }
  915. }
  916. public function deletePic($pic_path, $site_id)
  917. {
  918. if (strpos($pic_path, 'https://') === 0 || strpos($pic_path, 'http://') === 0) {
  919. event("ClearAlbumPic", [ "pic_path" => $pic_path, "site_id" => $site_id ]);
  920. } else {
  921. if (file_exists($pic_path)) {
  922. unlink($pic_path);
  923. }
  924. if (file_exists(img($pic_path, 'big'))) {
  925. unlink(img($pic_path, 'big'));
  926. }
  927. if (file_exists(img($pic_path, 'mid'))) {
  928. unlink(img($pic_path, 'mid'));
  929. }
  930. if (file_exists(img($pic_path, 'small'))) {
  931. unlink(img($pic_path, 'small'));
  932. }
  933. }
  934. }
  935. }