Upload.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 山西牛酷信息科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com.cn
  8. * 这不是一个自由软件!您只能在不用于商业目的的前提下对程序代码进行修改和使用。
  9. * 任何企业和个人不允许对程序代码以任何形式任何目的再发布。
  10. * =========================================================
  11. */
  12. namespace app\model\upload;
  13. use extend\Upload as UploadExtend;
  14. use Intervention\Image\ImageManagerStatic as Image;
  15. use app\model\BaseModel;
  16. class Upload extends BaseModel
  17. {
  18. public $upload_path = __UPLOAD__;//公共上传文件
  19. public $config = []; //上传配置
  20. public $site_id;
  21. public $rule_type;//允许上传 mime类型
  22. public $rule_ext;// 允许上传 文件后缀
  23. public $path;//上传路径
  24. public function __construct($site_id = 0)
  25. {
  26. $this->site_id = $site_id;
  27. $config_model = new Config();
  28. $config_result = $config_model->getUploadConfig();
  29. $this->config = $config_result["data"]["value"];//上传配置
  30. }
  31. /************************************************************上传开始*********************************************/
  32. /**
  33. * 单图上传
  34. * @param number $site_id
  35. * @param string $thumb_type 生成缩略图类型
  36. */
  37. public function image($param)
  38. {
  39. $check_res = $this->checkImg();
  40. if($check_res["code"] >= 0){
  41. $file = request()->file($param["name"]);
  42. if(empty($file))
  43. return $this->error();
  44. $tmp_name = $file->getPathname();//获取上传缓存文件
  45. $original_name = $file->getOriginalName();//文件原名
  46. // $file_path = $this->upload_path."/".$this->site_id . "/images/".date("Ymd"). '/';
  47. $file_path = $this->path;
  48. // 检测目录
  49. $checkpath_result = $this->checkPath($file_path);//验证写入文件的权限
  50. if($checkpath_result["code"] < 0)
  51. return $checkpath_result;
  52. $file_name = $file_path.$this->createNewFileName();
  53. $extend_name = $file->getOriginalExtension();
  54. $thumb_type = $param["thumb_type"];
  55. //原图保存
  56. $new_file = $file_name . "." . $extend_name;
  57. $image = Image::make($tmp_name);
  58. $width = $image->width();//图片宽
  59. $height = $image->height();//图片高
  60. $image = $this->imageWater($image);
  61. $result = $this->fileCloud($image, $new_file);//原图云上传(文档流上传)
  62. if($result["code"] < 0)
  63. return $result;
  64. $thumb_res = $this->thumbBatch($tmp_name, $file_name, $extend_name, $thumb_type);//生成缩略图
  65. if($thumb_res["code"] < 0)
  66. return $result;
  67. $data = array(
  68. "pic_path" => $result["data"],//图片云存储
  69. "pic_name" => $original_name,
  70. "file_ext" => $extend_name,
  71. "pic_spec" => $width . "*" . $height,
  72. "update_time" =>time(),
  73. "site_id" => $this->site_id
  74. );
  75. return $this->success($data, "SUCCESS");
  76. }else{
  77. //返回错误信息
  78. return $check_res;
  79. }
  80. }
  81. /**
  82. * 相册图片上传
  83. * @param number $site_id
  84. * @param number $category_id
  85. * @param string $thumb_type
  86. */
  87. public function imageToAlbum($param)
  88. {
  89. $check_res = $this->checkImg();
  90. if($check_res["code"] >= 0){
  91. $file = request()->file($param["name"]);
  92. if(empty($file))
  93. return $this->error();
  94. $tmp_name = $file->getPathname();//获取上传缓存文件
  95. $original_name = $file->getOriginalName();//文件原名
  96. // $file_path = $this->upload_path."/".$this->site_id . "/images/".date("Ymd"). '/';
  97. $file_path = $this->path;
  98. // 检测目录
  99. $checkpath_result = $this->checkPath($file_path);//验证写入文件的权限
  100. if($checkpath_result["code"] < 0)
  101. return $checkpath_result;
  102. $file_name = $file_path.$this->createNewFileName();
  103. $extend_name = $file->getOriginalExtension();
  104. $thumb_type = $param["thumb_type"];//所留
  105. $album_id = $param["album_id"];
  106. //原图保存
  107. $new_file = $file_name . "." . $extend_name;
  108. $image = Image::make($tmp_name);
  109. $width = $image->width();//图片宽
  110. $height = $image->height();//图片高
  111. // $image = $this->imageWater($image);
  112. $result = $this->fileCloud($image, $new_file);//原图云上传(文档流上传)
  113. if($result["code"] < 0)
  114. return $result;
  115. $thumb_res = $this->thumbBatch($tmp_name, $file_name, $extend_name, $thumb_type);//生成缩略图
  116. if($thumb_res["code"] < 0)
  117. return $result;
  118. $pic_name_first = substr(strrchr($original_name, '.'), 1);
  119. $pic_name = basename($original_name,".".$pic_name_first);
  120. $data = array(
  121. "pic_path" => $result["data"],//图片云存储
  122. "pic_name" => $pic_name,
  123. "pic_spec" => $width . "*" . $height,
  124. "update_time" =>time(),
  125. "site_id" => $this->site_id,
  126. "album_id" => $album_id
  127. );
  128. $album_model = new Album();
  129. $res = $album_model->addAlbumPic($data);
  130. if ($res['code'] >= 0) {
  131. $data["id"] = $res["data"];
  132. return $this->success($data, "UPLOAD_SUCCESS");
  133. } else {
  134. return $this->error($res);
  135. }
  136. }else{
  137. //返回错误信息
  138. return $check_res;
  139. }
  140. }
  141. /**
  142. * 视频上传
  143. * @param $param
  144. */
  145. public function video($param){
  146. $check_res = $this->checkFile();
  147. if($check_res["code"] >= 0){
  148. // 获取表单上传文件
  149. $file = request()->file($param["name"]);
  150. try {
  151. $extend_name = $file->getOriginalExtension();
  152. $new_name = $this->createNewFileName().".".$extend_name;
  153. $file_path = $this->path;
  154. \think\facade\Filesystem::disk('public')->putFileAs( $file_path, $file, $new_name);
  155. $file_name = $file_path.$new_name;
  156. return $this->success(["path" => $file_name], "UPLOAD_SUCCESS");
  157. } catch (\think\exception\ValidateException $e) {
  158. return $this->error('', $e->getMessage());
  159. }
  160. }else{
  161. return $check_res;
  162. }
  163. }
  164. /**
  165. * 上传文件
  166. * @param $param
  167. */
  168. public function file($param){
  169. $check_res = $this->checkFile();
  170. if($check_res["code"] >= 0){
  171. // 获取表单上传文件
  172. $file = request()->file($param["name"]);
  173. try {
  174. $extend_name = $file->getOriginalExtension();
  175. $new_name = $this->createNewFileName().".".$extend_name;
  176. $file_path = $this->path;
  177. \think\facade\Filesystem::disk('public')->putFileAs( $file_path, $file, $new_name);
  178. $file_name = $file_path.$new_name;
  179. return $this->success(["path" => $file_name], "UPLOAD_SUCCESS");
  180. } catch (\think\exception\ValidateException $e) {
  181. return $this->error('', $e->getMessage());
  182. }
  183. }else{
  184. return $check_res;
  185. }
  186. }
  187. /************************************************************上传结束*********************************************/
  188. /************************************************************上传功能组件******************************************/
  189. /**
  190. * 缩略图生成
  191. * @param unknown $file_name
  192. * @param unknown $extend_name
  193. * @param unknown $thumb_type
  194. * @return Ambigous <string, multitype:multitype:string >
  195. */
  196. private function thumbBatch($file_path, $file_name, $extend_name, $thumb_type = [])
  197. {
  198. $thumb_type_array = array(
  199. "big" => array(
  200. "size" => "big",
  201. "width" => $this->config["thumb"]["thumb_big_width"],
  202. "height" => $this->config["thumb"]["thumb_big_height"],
  203. "thumb_name" => ""
  204. ),
  205. "mid" => array(
  206. "size" => "mid",
  207. "width" => $this->config["thumb"]["thumb_mid_width"],
  208. "height" => $this->config["thumb"]["thumb_mid_height"],
  209. "thumb_name" => ""
  210. ),
  211. "small" => array(
  212. "size" => "small",
  213. "width" => $this->config["thumb"]["thumb_small_width"],
  214. "height" => $this->config["thumb"]["thumb_small_height"],
  215. "thumb_name" => ""
  216. )
  217. );
  218. foreach ($thumb_type_array as $k => $v) {
  219. if (!empty($thumb_type) && in_array($k, $thumb_type)) {
  220. $new_path_name = $file_name . "_" . $v["size"] . "." . $extend_name;
  221. $result = $this->imageThumb($file_path, $new_path_name, $v["width"], $v["height"]);
  222. //返回生成的缩略图路径
  223. if ($result["code"] >= 0) {
  224. $thumb_type_array[ $k ]["thumb_name"] = $new_path_name;
  225. } else {
  226. return $result;
  227. }
  228. }
  229. }
  230. return $this->success($thumb_type_array);
  231. }
  232. /**
  233. * 缩略图
  234. * @param unknown $file_name
  235. * @param unknown $new_path
  236. * @param unknown $width
  237. * @param unknown $height
  238. * @return multitype:boolean unknown |multitype:boolean
  239. */
  240. public function imageThumb($file, $thumb_name, $width, $height)
  241. {
  242. $image = Image::make($file)->fit($width, $height,function ($constraint) {
  243. // $constraint->upsize();//防止图片放大 不需要
  244. }, $this->config["thumb"]["thumb_position"]);
  245. $image = $this->imageWater($image);
  246. $result = $this->fileCloud($image, $thumb_name);
  247. return $result;
  248. }
  249. /**
  250. * 添加水印
  251. */
  252. public function imageWater($image)
  253. {
  254. //判断是否有水印(具体走配置)
  255. if($this->config["water"]["is_watermark"]){
  256. switch ($this->config["water"]["watermark_type"]) {
  257. case "1"://图片水印
  258. if(!empty($this->config["water"]["watermark_source"]) && is_file($this->config["water"]["watermark_source"])){
  259. $watermark = Image::make($this->config["water"]["watermark_source"]);
  260. $image->insert($watermark, $this->config["water"]["watermark_position"], $this->config["water"]["watermark_x"], $this->config["water"]["watermark_y"]);
  261. }
  262. break;
  263. case "2"://文字水印
  264. if(!empty($this->config["water"]["watermark_text"])){
  265. $image->text($this->config["water"]["watermark_text"], $this->config["water"]["watermark_x"], $this->config["water"]["watermark_y"], function($font) {
  266. // $font->file($this->config["water"]["watermark_text_file"]);//设置字体文件位置
  267. $font->size($this->config["water"]["watermark_text_size"]);//设置字号大小
  268. $font->color($this->config["water"]["watermark_text_color"]);//设置字号颜色
  269. $font->align($this->config["water"]["watermark_text_align"]);//设置字号水平位置
  270. $font->valign($this->config["water"]["watermark_text_valign"]);//设置字号 垂直位置
  271. $font->angle($this->config["water"]["watermark_text_angle"]);//设置字号倾斜角度
  272. });
  273. }
  274. break;
  275. }
  276. }
  277. return $image;
  278. }
  279. /**
  280. * 删除文件
  281. * @param $file_name
  282. */
  283. private function deleteFile($file_name)
  284. {
  285. $res = @unlink($file_name);
  286. if ($res) {
  287. return $this->success();
  288. } else {
  289. return $this->error();
  290. }
  291. }
  292. /**
  293. * 云上传
  294. */
  295. public function fileCloud($image, $file){
  296. try {
  297. //走 云上传
  298. //...
  299. $put_result = event("Put",["file_path" => $file, "key" => $file], true);
  300. if(!empty($put_result)){
  301. $this->deleteFile($file);
  302. if($put_result["code"] >= 0){
  303. $file = $put_result["data"]["path"];
  304. }else{
  305. return $put_result;
  306. }
  307. }else{
  308. $image->save($file);
  309. }
  310. //云上传没有成功 保存到本地
  311. return $this->success($file, "UPLOAD_SUCCESS");
  312. } catch (\Exception $e) {
  313. return $this->error('', $e->getMessage());
  314. }
  315. }
  316. /**
  317. * 检测图片上传 类型 大小
  318. * @param $file_info
  319. * @return \multitype
  320. */
  321. public function checkImage1($file_info){
  322. $upload_extend = new UploadExtend('');//实例化上传类
  323. $upload_extend->setFilename($file_info["tmp_name"]);
  324. $rule_type = $this->config["upload"]["image_allow_mime"];//规则mine类型
  325. $rule_ext = $this->config["upload"]["image_allow_ext"];//规则 允许上传后缀
  326. // $rule = [ "type" => "image/png,image/jpeg,image/gif,image/bmp", "ext" => "gif,jpg,jpeg,bmp,png" ];//上传文件验证规则
  327. $rule = [ "type" => $rule_type, "ext" => $rule_ext ];//上传文件验证规则
  328. $old_name = $upload_extend->getFileName($file_info["name"]);//文件原名
  329. $file_name = $this->site_id . "/images/".date("Ymd"). "/". $upload_extend->createNewFileName();
  330. $extend_name = $upload_extend->getFileExt($file_info["name"]);
  331. $size_data = $upload_extend->getImageInfo($file_info["tmp_name"]);//获取图片信息
  332. $check = $upload_extend->setValidate($rule)->setUploadInfo($file_info)->checkAll($this->upload_path, $file_name.".".$extend_name);
  333. if(!$check)
  334. return $this->error("", $upload_extend->getError());
  335. $data = array(
  336. "file_name" => $file_name,
  337. "old_name" => $old_name,
  338. "extend_name" => $extend_name,
  339. "size_data" => $size_data,
  340. );
  341. return $this->success($data);
  342. }
  343. /**
  344. * 图片验证
  345. * @param $file
  346. * @return \multitype
  347. */
  348. public function checkImg(){
  349. try {
  350. $file = request()->file();
  351. $rule_array = [];
  352. $size_rule = $this->config["upload"]["max_filesize"];
  353. $ext_rule = $this->config["upload"]["image_allow_ext"];
  354. $mime_rule = $this->config["upload"]["image_allow_mime"];
  355. // $size_rule = 10240;
  356. // $ext_rule = "jpg,jpeg,png,gif,pem";
  357. // $mime_rule = "image/jpeg,image/gif,image/png,text/plain";
  358. if(!empty($size_rule)){
  359. $rule_array[] = "fileSize:{$size_rule}";
  360. }
  361. if(!empty($ext_rule)){
  362. $rule_array[] = "fileExt:{$ext_rule}";
  363. }
  364. if(!empty($mime_rule)){
  365. $rule_array[] = "fileMime:{$mime_rule}";
  366. }
  367. if(!empty($rule_array)){
  368. // 'image'=>'filesize:10240|fileExt:jpg,jpeg,png,gif,pem|fileMime:image/jpeg,image/gif,image/png,text/plain'
  369. $rule = implode("|", $rule_array);
  370. validate(['file'=>$rule])->check($file);
  371. }
  372. return $this->success();
  373. } catch (\think\exception\ValidateException $e) {
  374. return $this->error('', $e->getMessage());
  375. }
  376. }
  377. /**
  378. * 图片验证
  379. * @param $file
  380. * @return \multitype
  381. */
  382. public function checkFile(){
  383. try {
  384. $file = request()->file();
  385. $rule_array = [];
  386. $size_rule = $this->config["upload"]["max_filesize"];
  387. // $ext_rule = $this->config["upload"]["image_allow_ext"];
  388. // $mime_rule = $this->config["upload"]["image_allow_mime"];
  389. // $size_rule = 10240*100;
  390. // $ext_rule = "jpg,jpeg,png,gif,pem";
  391. // $mime_rule = "image/jpeg,image/gif,image/png,text/plain";
  392. // if(!empty($size_rule)){
  393. // $rule_array[] = "fileSize:{$size_rule}";
  394. // }
  395. // if(!empty($ext_rule)){
  396. // $rule_array[] = "fileExt:{$ext_rule}";
  397. // }
  398. // if(!empty($mime_rule)){
  399. // $rule_array[] = "fileMime:{$mime_rule}";
  400. // }
  401. // $rule = implode("|", $rule_array);
  402. // 'image'=>'filesize:10240|fileExt:jpg,jpeg,png,gif,pem|fileMime:image/jpeg,image/gif,image/png,text/plain'
  403. // $res = validate(['file'=>$rule])->check($file);
  404. // if($res){
  405. // return $this->success();
  406. // }else{
  407. // return $this->error();
  408. // }
  409. return $this->success();
  410. } catch (\think\exception\ValidateException $e) {
  411. echo $e->getMessage();
  412. }
  413. }
  414. /************************************************************上传功能组件******************************************/
  415. /**
  416. *获取一个新文件名
  417. */
  418. public function createNewFileName()
  419. {
  420. $name = date('Ymdhis', time())
  421. . sprintf('%03d', microtime(true) * 1000)
  422. . sprintf('%02d', mt_rand(10, 99));
  423. return $name;
  424. }
  425. /**
  426. * 验证目录是否可写
  427. * @param unknown $path
  428. * @return boolean
  429. */
  430. public function checkPath($path)
  431. {
  432. if (is_dir($path) || mkdir($path, 0755, true)) {
  433. return $this->success();
  434. }
  435. return $this->error('', "directory {$path} creation failed");
  436. }
  437. /**
  438. * 设置上传目录
  439. * @param $path
  440. */
  441. public function setPath($path){
  442. if($this->site_id > 0){
  443. $this->path = $this->site_id."/".$path;
  444. }else{
  445. $this->path = $path;
  446. }
  447. $this->path = $this->upload_path."/".$this->path;
  448. return $this;
  449. }
  450. /**
  451. * 远程拉取图片
  452. * @param $path
  453. */
  454. public function remotePull($path){
  455. $file_path = $this->path;
  456. // 检测目录
  457. $checkpath_result = $this->checkPath($file_path);//验证写入文件的权限
  458. if($checkpath_result["code"] < 0)
  459. return $checkpath_result;
  460. $file_name = $file_path.$this->createNewFileName();
  461. $new_file = $file_name.".png";
  462. $ch = curl_init();
  463. curl_setopt($ch, CURLOPT_URL, $path);
  464. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  465. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
  466. $file = curl_exec($ch);
  467. curl_close($ch);
  468. // $resource = fopen($new_file, 'a');
  469. // fwrite($resource, $file);
  470. // fclose($resource);
  471. //
  472. // $image = Image::make($new_file);
  473. $image = Image::make($file);
  474. $image = $this->imageWater($image);
  475. $result = $this->fileCloud($image, $new_file);//原图云上传(文档流上传)
  476. if($result["code"] < 0)
  477. return $result;
  478. return $this->success(["pic_path" => $result["data"]]);
  479. }
  480. }