Stroage.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. <?php
  2. namespace app\weixin\model;
  3. use cmf\lib\Upload;
  4. use think\Model;
  5. use think\Request;
  6. class Stroage extends Model
  7. {
  8. /**
  9. * 上传图片
  10. * @param $formId 图片表单名称
  11. * @param $scene 应用场景
  12. * @return array|string
  13. */
  14. public static function uploadImg($file, $scene = 'default')
  15. {
  16. $data = [];
  17. $path = "upload/{$scene}";
  18. if (!is_dir($path)) {
  19. mkdir($path, 0755, true);
  20. }
  21. $fileSize = config('files.imageSize');
  22. $fileSize = $fileSize ? $fileSize * 1024 * 1024 : 10 * 1024 * 1024;
  23. $info = $file->validate(['size' => $fileSize, 'ext' => 'jpg,jpeg,png,gif'])->move('./' . $path);
  24. if ($info) {
  25. $filename = str_replace('\\', '/', $info->getSaveName());
  26. $fileInfo = $info->getInfo();
  27. $name = isset($fileInfo['name']) ? $fileInfo['name'] : '';
  28. $fileType = cmf_get_file_extension($name);
  29. $data = [
  30. 'name' => $name,
  31. 'file' => "{$scene}/" . $filename,
  32. 'preview' => cmf_get_image_preview_url("{$scene}/" . $filename),
  33. 'file_type' => $fileType,
  34. 'file_size' => isset($fileInfo['size']) ? getFileSize($fileInfo['size']) : 0,
  35. 'md5_key' => md5_file(cmf_get_image_preview_url("{$scene}/" . $filename)),
  36. 'total_page' => 1,
  37. ];
  38. } else {
  39. return $info;
  40. }
  41. return $data;
  42. }
  43. /**
  44. * 上传base图片
  45. * @param $baseList
  46. * @param string $scene
  47. * @return bool|int|string
  48. */
  49. public static function uploadBaseImg($baseList, $scene = 'default')
  50. {
  51. $data = [];
  52. $path = "{$scene}/" . date('Ymd') . '/';
  53. foreach ($baseList as $k => $item) {
  54. if (!is_dir('/public/' . $path)) {
  55. mkdir('/public/' . $path, 755, true);
  56. }
  57. $filename = $path . 'P_' . md5(uniqid() . time() . $k) . '.jpg';
  58. $src = isset($item['src']) ? $item['src'] : '';
  59. if ($src && !preg_match("/default//", $src) && file_put_contents('/public/' . $filename, $src)) {
  60. $data[] = [
  61. 'name' => isset($item['name']) ? trim($item['name']) : '',
  62. 'url' => $filename,
  63. 'nums' => isset($item['nums']) ? intval($item['nums']) : 1,
  64. 'total_page' => 1,
  65. 'file_size' => isset($item['file_size']) ? intval($item['file_size']) : 0,
  66. 'file_type' => isset($item['file_type']) ? ltrim($item['file_type'], 'image/') : '',
  67. 'type' => isset($item['type']) ? trim($item['type']) : '',
  68. 'md5_key' => md5_file(cmf_get_image_preview_url($filename)),
  69. 'created_at' => date('Y-m-d H:i:s')
  70. ];
  71. }
  72. }
  73. if ($data) {
  74. return FileLogs::insertAll($data);
  75. } else {
  76. return false;
  77. }
  78. }
  79. /**
  80. * 上传图片
  81. * @param $formId 图片表单名称
  82. * @param $scene 应用场景
  83. * @return array|string
  84. */
  85. public static function uploadFile($file, $scene = 'default')
  86. {
  87. $data = [];
  88. $path = "upload/files/{$scene}";
  89. if (!is_dir($path)) {
  90. mkdir($path, 0755, true);
  91. }
  92. $fileTypes = config('files.fileTypes');
  93. $fileSize = config('files.fileSize');
  94. $fileSize = $fileSize ? $fileSize * 1024 * 1024 : 30 * 1024 * 1024;
  95. $fileTypes = $fileTypes ? $fileTypes : ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf'];
  96. $info = $file->validate(['size' => $fileSize, 'ext' => implode(',', $fileTypes)])->move('./' . $path);
  97. if ($info) {
  98. $filename = str_replace('\\', '/', $info->getSaveName());
  99. $fileInfo = $info->getInfo();
  100. $name = isset($fileInfo['name']) ? $fileInfo['name'] : '';
  101. $fileType = cmf_get_file_extension($name);
  102. $file = "files/{$scene}/" . $filename;
  103. if (Stroage::checkFileExists($file)) {
  104. $page = Stroage::getFilePage($file);
  105. if (in_array($fileType, ['xls', 'xlsx'])) {
  106. $file = str_replace('.' . $fileType, '.pdf', $file);
  107. }
  108. $data = [
  109. 'name' => $name,
  110. 'file' => $file,
  111. 'preview' => cmf_get_image_preview_url($file),
  112. 'file_type' => $fileType,
  113. 'file_size' => isset($fileInfo['size']) ? getFileSize($fileInfo['size']) : 0,
  114. 'md5_key' => md5_file(cmf_get_image_preview_url($file)),
  115. 'total_page' => $page,
  116. ];
  117. }
  118. }
  119. return $data;
  120. }
  121. /**
  122. * 验证上传文件是否存在
  123. * @param $file
  124. * @return bool
  125. */
  126. public static function checkFileExists($file)
  127. {
  128. $file = preg_match("/^files/", $file) ? UPLOAD_PATH . $file : $file;
  129. return is_file($file);
  130. }
  131. /**
  132. * 打包文件为ZIP
  133. * @param $file 文件
  134. * @param $fileType
  135. * @return mixed
  136. */
  137. public static function makeZipFile($file, $fileType)
  138. {
  139. $filename = str_replace('.' . $fileType, '.zip', $file);
  140. $zip = new \ZipArchive();
  141. $file = UPLOAD_PATH . $file;
  142. $zip->open(UPLOAD_PATH . $filename, \ZipArchive::CREATE); //打开压缩包
  143. $zip->addFile($file, basename($file)); //向压缩包中添加文件
  144. $zip->close(); //关闭压缩包
  145. return $filename;
  146. }
  147. /**
  148. * 修改文件后缀为zip压缩包
  149. * @param $file 文件
  150. * @param $fileType 文件类型
  151. * @return bool|mixed
  152. */
  153. public static function moveFileToZip($file, $fileType = '')
  154. {
  155. $fileType = getFileType($file);
  156. $file = preg_match("/^files/", $file) ? UPLOAD_PATH . $file : $file;
  157. $filename = str_replace('.' . $fileType, '.zip', $file);
  158. if (copy($file, $filename)) {
  159. return str_replace('\\', '/', $filename);;
  160. }
  161. return false;
  162. }
  163. /**
  164. * 解压读取ZIP内指定文件
  165. * @param $file ZIP压缩文件
  166. * @return bool|string
  167. */
  168. public static function getZipPageFile($file)
  169. {
  170. $zip = new \ZipArchive();
  171. $file = preg_match("/^files/", $file) ? UPLOAD_PATH . $file : $file;
  172. // 中文文件名要使用ANSI编码的文件格式
  173. if ($zip->open($file) === TRUE) {
  174. //提取全部文件
  175. $file = str_replace('.zip', '', $file);
  176. $zip->extractTo($file); //提取部分文件
  177. $zip->close();
  178. return str_replace('\\', '/', $file . '/docProps/app.xml');
  179. } else {
  180. return false;
  181. }
  182. }
  183. /**
  184. * 删除文件
  185. * @param $file
  186. */
  187. public static function deleteFile($file)
  188. {
  189. $file = preg_match("/^files/", $file) ? UPLOAD_PATH . $file : $file;
  190. if (is_file($file)) {
  191. unlink($file);
  192. }
  193. }
  194. /**
  195. * 删除ZIP压缩包以及其解压文件
  196. * @param $file 压缩奥文件
  197. */
  198. public static function deleteZip($file)
  199. {
  200. if (is_file($file)) {
  201. Stroage::deleteFile($file);
  202. }
  203. $zipDir = str_replace('.zip', '', $file);
  204. if (is_dir($zipDir)) {
  205. deleteDir($zipDir);
  206. }
  207. }
  208. /**
  209. * 获取文档页数
  210. * @param $file 文件
  211. * @return int
  212. */
  213. public static function getFilePage($file)
  214. {
  215. set_time_limit(0);
  216. $fileType = getFileType($file);
  217. // PDF 类型文件
  218. if (in_array($fileType, ['pdf'])) {
  219. return Stroage::getPdfFilePage($file);
  220. }
  221. // 表格文件转PDF
  222. $typeData = config('files.convertTypes');
  223. $typeData = $typeData ? array_keys($typeData) : ['doc','docx', 'xls', 'xlsx', 'ppt', 'pptx'];
  224. if (in_array($fileType, $typeData)) {
  225. if($fileType == 'docx'){
  226. $file = Stroage::convertFile($file,'doc');
  227. }
  228. $file = Stroage::onLineConvertFile($file);
  229. return Stroage::getPdfFilePage($file);
  230. }
  231. // 其他文件
  232. $fileTypes = config('files.fileTypes');
  233. $fileTypes = $fileTypes ? $fileTypes : ['txt', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf'];
  234. if (!in_array($fileType, $fileTypes)) {
  235. return 0;
  236. }
  237. $zipFile = Stroage::moveFileToZip($file);
  238. if (!is_file($zipFile)) {
  239. return 0;
  240. }
  241. // 获取页数文件内容
  242. $pageFile = Stroage::getZipPageFile($zipFile);
  243. if (!is_file($pageFile)) {
  244. return 0;
  245. }
  246. $content = file_get_contents($pageFile);
  247. if (empty($content)) {
  248. return 0;
  249. }
  250. preg_match("/(<Pages>([1-9][0-9]*):?<\/Pages>)|(<Slides>([1-9][0-9]*):?<\/Slides>)|(<vt:i4>([1-9][0-9]*):?<\/vt:i4>)/", $content, $result);
  251. $page = $result ? intval(end($result)) : 0;
  252. // 删除处理生成临时压缩包文件
  253. $deleteTemp = config('print.deleteTemp');
  254. if ($deleteTemp) {
  255. Stroage::deleteZip($zipFile);
  256. }
  257. return $page;
  258. }
  259. /**
  260. * 文件服务器转换
  261. * @param $file 文件
  262. * @param string $type 转换类型
  263. * @return mixed
  264. */
  265. public static function convertFile($file, $type = 'pdf')
  266. {
  267. $fileType = getFileType($file);
  268. $pathFile = preg_match("/^files/", $file) ? UPLOAD_PATH . $file : $file;
  269. $path = dirname($pathFile) . '/';
  270. $filename = str_replace('.' . $fileType, '.' . $type, $file);
  271. switch ($type) {
  272. case 'pdf':
  273. $command = "libreoffice6.3 --invisible --convert-to pdf --outdir \"{$path}\" \"{$pathFile}\"";
  274. exec($command);
  275. break;
  276. case 'doc':
  277. $command = "libreoffice6.3 --invisible --convert-to doc --outdir \"{$path}\" \"{$pathFile}\"";
  278. exec($command);
  279. break;
  280. }
  281. return $filename;
  282. }
  283. /**
  284. * 图片转黑白
  285. * @param $file
  286. * @return string
  287. */
  288. public static function filtterColor($file, $type=1, $light=6)
  289. {
  290. $filepath = dirname($file);
  291. $newFile = $filepath . '/color_' . basename($file);
  292. if (!file_exists('upload/' . $file)) {
  293. return false;
  294. }
  295. @fopen('upload/' . $newFile, 'w+');
  296. $im = imagecreatefromjpeg('upload/' . $file);
  297. if ($im && imagefilter($im, 1)) {
  298. imagefilter($im, 2, $light);
  299. // imagefilter($im, 4, 0,0,0);
  300. imagepng($im, 'upload/' . $newFile);
  301. } else {
  302. $newFile = '';
  303. }
  304. imagedestroy($im);
  305. return $newFile;
  306. }
  307. /**
  308. * 文件在线转换
  309. * @param $file 文件
  310. * @return mixed
  311. */
  312. public static function onLineConvertFile($file, $type='pdf')
  313. {
  314. $fileType = getFileType($file);
  315. $pathFile = preg_match("/^files/", $file) ? UPLOAD_PATH . $file : $file;
  316. $path = dirname($pathFile) . '/';
  317. $filename = str_replace('.' . $fileType, '.'.$type, $file);
  318. $typeData = config('files.convertTypes');
  319. $minType = isset($typeData[$fileType]) ? $typeData[$fileType] : '';
  320. if (empty($minType)) {
  321. return false;
  322. }
  323. $name = basename($filename);
  324. if (!class_exists('CURLFile')) {
  325. return false;
  326. }
  327. $convertApi = config('files.convertApi');
  328. $convertApiUrl = isset($convertApi['convert']) ? $convertApi['convert'] : '';
  329. if (empty($convertApiUrl)) {
  330. return false;
  331. }
  332. // 转换
  333. $postData = file_get_contents($pathFile);
  334. $result = httpHeaderRequest($convertApiUrl, $postData, ["fileName:{$name}","content-Type:{$minType}"]);
  335. $errorCode = isset($result['errorCode']) ? intval($result['errorCode']) : 1;
  336. $status = isset($result['status']) ? intval($result['status']) : 0;
  337. $convertId = isset($result['data']) ? $result['data'] : '';
  338. if ($errorCode != 0 || empty($convertId) || $status) {
  339. return false;
  340. }
  341. // 下载
  342. $downloadApiUrl = isset($convertApi['download']) ? $convertApi['download'] : '';
  343. if (empty($downloadApiUrl)) {
  344. return false;
  345. }
  346. $downloadApiUrl = sprintf($downloadApiUrl, $convertId);
  347. $content = httpRequest($downloadApiUrl, '', 'get', 'text', 120);
  348. if (empty($content)) {
  349. return false;
  350. }
  351. // 另存
  352. $downloadFile = str_replace('.' . $fileType, '.pdf', $pathFile);
  353. file_put_contents($downloadFile, $content);
  354. return $filename;
  355. }
  356. /**
  357. * 读取PDF文件页数
  358. * @param $file 文件
  359. * @return bool|int
  360. */
  361. public static function getPdfFilePage($file)
  362. {
  363. $file = preg_match("/^files/", $file) ? UPLOAD_PATH . $file : $file;
  364. if (!is_readable($file) || !file_exists($file)) {
  365. return 0;
  366. }
  367. $max = 0;
  368. $fp = @fopen($file, "r");
  369. if (!$fp) {
  370. return 0;
  371. }
  372. while (!feof($fp)) {
  373. $line = fgets($fp, 255);
  374. if (preg_match('/\/Count [0-9]+/', $line, $matches)) {
  375. preg_match('/[0-9]+/', $matches[0], $matches2);
  376. if ($max < $matches2[0]) $max = $matches2[0];
  377. }
  378. }
  379. fclose($fp);
  380. return $max;
  381. }
  382. }