common.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969
  1. <?php
  2. use think\Container;
  3. use think\Response;
  4. use think\facade\Lang;
  5. use think\facade\Queue;
  6. use think\facade\Cache;
  7. use core\util\Snowflake;
  8. use app\service\core\upload\CoreImageService;
  9. use app\service\core\sys\CoreSysConfigService;
  10. // 应用公共文件
  11. /**
  12. * 接口操作成功,返回信息
  13. * @param array|string $msg
  14. * @param array|string|bool|null $data
  15. * @param int $code
  16. * @param int $http_code
  17. * @return Response
  18. */
  19. function success($msg = 'SUCCESS', $data = [], int $code = 1, int $http_code = 200): Response
  20. {
  21. if (is_array($msg)) {
  22. $data = $msg;
  23. $msg = 'SUCCESS';
  24. }
  25. return Response::create([ 'data' => $data, 'msg' => get_lang($msg), 'code' => $code ], 'json', $http_code);
  26. }
  27. /**
  28. * 接口操作失败,返回信息
  29. * @param $msg
  30. * @param array|null $data
  31. * @param int $code
  32. * @param int $http_code
  33. * @return Response
  34. */
  35. function fail($msg = 'FAIL', ?array $data = [], int $code = 0, int $http_code = 200) : Response
  36. {
  37. if (is_array($msg)) {
  38. $data = $msg;
  39. $msg = 'FAIL';
  40. }
  41. return Response::create([ 'data' => $data, 'msg' => get_lang($msg), 'code' => $code ], 'json', $http_code);
  42. }
  43. /**
  44. * 自动侦测语言并转化
  45. * @param $str
  46. * @return mixed
  47. */
  48. function get_lang($str)
  49. {
  50. return Lang::get($str);
  51. }
  52. /**
  53. * 把返回的数据集转换成Tree
  54. * @param $list 要转换的数据集
  55. * @param string $pk
  56. * @param string $pid
  57. * @param string $child
  58. * @param int $root
  59. * @return array
  60. */
  61. function list_to_tree($list, $pk = 'id', $pid = 'pid', $child = 'child', $root = 0)
  62. {
  63. // 创建Tree
  64. $tree = array ();
  65. if (is_array($list)) {
  66. // 创建基于主键的数组引用
  67. $refer = array ();
  68. foreach ($list as $key => $data) {
  69. $refer[ $data[ $pk ] ] =& $list[ $key ];
  70. }
  71. foreach ($list as $key => $data) {
  72. // 判断是否存在parent
  73. $parent_id = $data[ $pid ];
  74. if ($root == $parent_id) {
  75. $tree[] =& $list[ $key ];
  76. } else {
  77. if (isset($refer[ $parent_id ])) {
  78. $parent =& $refer[ $parent_id ];
  79. $parent[ $child ][] =& $list[ $key ];
  80. }
  81. }
  82. }
  83. }
  84. return $tree;
  85. }
  86. /**
  87. * 生成加密密码
  88. * @param $password
  89. * @param $salt 手动提供散列密码的盐值(salt)。这将避免自动生成盐值(salt)。,默认不填写将自动生成
  90. * @return string
  91. */
  92. function create_password($password, $salt = '')
  93. {
  94. return password_hash($password, PASSWORD_DEFAULT);
  95. }
  96. /**
  97. * 校验比对密码和加密密码是否一致
  98. * @param $password
  99. * @param $hash
  100. * @return bool
  101. */
  102. function check_password($password, $hash)
  103. {
  104. if (!password_verify($password, $hash)) return false;
  105. return true;
  106. }
  107. /**
  108. * 获取键对应的值
  109. * @param array $array 源数组
  110. * @param array $keys 要提取的键数组
  111. * @param string $index 二维组中指定提取的字段(唯一)
  112. * @return array
  113. */
  114. function array_keys_search($array, $keys, $index = '', $is_sort = true)
  115. {
  116. if (empty($array))
  117. return $array;
  118. if (empty($keys))
  119. return [];
  120. if (!empty($index) && count($array) != count($array, COUNT_RECURSIVE))
  121. $array = array_column($array, null, $index);
  122. $list = array ();
  123. foreach ($keys as $key) {
  124. if (isset($array[ $key ])) {
  125. if ($is_sort) {
  126. $list[] = $array[ $key ];
  127. } else {
  128. $list[ $key ] = $array[ $key ];
  129. }
  130. }
  131. }
  132. return $list;
  133. }
  134. /**
  135. * @notes 删除目标目录
  136. * @param $path
  137. * @param $delDir
  138. * @return bool|void
  139. */
  140. function del_target_dir($path, $delDir)
  141. {
  142. //没找到,不处理
  143. if (!file_exists($path)) {
  144. return false;
  145. }
  146. //打开目录句柄
  147. $handle = opendir($path);
  148. if ($handle) {
  149. while (false !== ( $item = readdir($handle) )) {
  150. if ($item != "." && $item != "..") {
  151. if (is_dir("$path/$item")) {
  152. del_target_dir("$path/$item", $delDir);
  153. } else {
  154. unlink("$path/$item");
  155. }
  156. }
  157. }
  158. closedir($handle);
  159. if ($delDir) {
  160. return rmdir($path);
  161. }
  162. } else {
  163. if (file_exists($path)) {
  164. return unlink($path);
  165. }
  166. return false;
  167. }
  168. }
  169. /**
  170. * 获取一些公共的系统参数
  171. * @param string|null $key
  172. * @return array|mixed
  173. */
  174. function system_name(?string $key = '')
  175. {
  176. $params = [
  177. 'admin_token_name' => env('system.admin_token_name', 'token'),///todo !!! 注意 header参数 不能包含_ , 会自动转成 -
  178. 'api_token_name' => env('system.api_token_name', 'token'),
  179. 'admin_site_id_name' => env('system.admin_site_id_name', 'site-id'),
  180. 'api_site_id_name' => env('system.api_site_id_name', 'site-id'),
  181. 'channel_name' => env('system.channel_name', 'channel'),
  182. ];
  183. if (!empty($key)) {
  184. return $params[ $key ];
  185. } else {
  186. return $params;
  187. }
  188. }
  189. /**
  190. * 获取日期(默认不传参 获取当前日期)
  191. * @param int|null $time
  192. * @return string
  193. */
  194. function get_date_by_time(?int $time = null)
  195. {
  196. return date('Y-m-d h:i:s', $time);
  197. }
  198. function get_start_and_end_time_by_day($day = '')
  199. {
  200. $date = $day ? : date('Y-m-d');
  201. $day_start_time = strtotime($date);
  202. //当天结束之间
  203. $day_end_time = $day_start_time + 86400;
  204. return [ $day_start_time, $day_end_time ];
  205. }
  206. /**
  207. * 路径转链接
  208. * @param $path
  209. * @return string
  210. */
  211. function path_to_url($path)
  212. {
  213. return trim(str_replace(DIRECTORY_SEPARATOR, '/', $path), '.');
  214. }
  215. /**
  216. * 链接转化路径
  217. * @param $url
  218. * @return string
  219. */
  220. function url_to_path($url)
  221. {
  222. if (str_contains($url, 'http://') || str_contains($url, 'https://')) return $url;//网络图片不必
  223. return public_path() . trim(str_replace('/', DIRECTORY_SEPARATOR, $url));
  224. }
  225. /**
  226. * 获取本地文件的对外网络路径
  227. * @param string $path
  228. * @return string
  229. */
  230. function get_file_url(string $path)
  231. {
  232. if (!$path) return '';
  233. if (!str_contains($path, 'http://') && !str_contains($path, 'https://')) {
  234. return request()->domain() . '/' . path_to_url($path);
  235. } else {
  236. return path_to_url($path);
  237. }
  238. }
  239. /**
  240. * 新增队列工作
  241. * @param $job
  242. * @param $data
  243. * @param $delay
  244. * @param $queue
  245. * @return bool
  246. */
  247. function create_job($job, $data = '', $delay = 0, $queue = null)
  248. {
  249. if ($delay > 0) {
  250. $is_success = Queue::later($delay, $job, $data, $queue);
  251. } else {
  252. $is_success = Queue::push($job, $data, $queue);
  253. }
  254. if ($is_success !== false) {
  255. return true;
  256. } else {
  257. return false;
  258. }
  259. }
  260. /**
  261. * 获取插件对应资源文件(插件安装后获取)
  262. * @param $addon //插件名称
  263. * @param $file_name //文件名称(包含resource文件路径)
  264. */
  265. function addon_resource($addon, $file_name)
  266. {
  267. return "addon/" . $addon . "/" . $file_name;
  268. }
  269. /**
  270. * 判断 文件/目录 是否可写(取代系统自带的 is_writeable 函数)
  271. *
  272. * @param string $file 文件/目录
  273. * @return boolean
  274. */
  275. function is_write($file)
  276. {
  277. if (is_dir($file)) {
  278. $dir = $file;
  279. if ($fp = @fopen("$dir/test.txt", 'wb')) {
  280. @fclose($fp);
  281. @unlink("$dir/test.txt");
  282. $writeable = true;
  283. } else {
  284. $writeable = false;
  285. }
  286. } else {
  287. if ($fp = @fopen($file, 'ab+')) {
  288. @fclose($fp);
  289. $writeable = true;
  290. } else {
  291. $writeable = false;
  292. }
  293. }
  294. return $writeable;
  295. }
  296. /**
  297. * 主要用于金额格式化(用于显示)
  298. * @param $number
  299. * @return int|mixed|string
  300. */
  301. function format_money($number)
  302. {
  303. if ($number == intval($number)) {
  304. return intval($number);
  305. } elseif ($number == sprintf('%.2f', $number)) {
  306. return sprintf('%.2f', $number);
  307. }
  308. return $number;
  309. }
  310. /**
  311. * 金额浮点数格式化
  312. * @param $number
  313. * @param $precision
  314. * @return float|int
  315. */
  316. function format_float_money($number, $precision = 2)
  317. {
  318. if ($precision > 0) {
  319. return sprintf('%.' . $precision . 'f', floor($number * ( 10 ** $precision )) / ( 10 ** $precision ));
  320. } else {
  321. return sprintf('%.' . $precision . 'f', floor($number));
  322. }
  323. }
  324. /**
  325. * 金额保留小数点后*位
  326. * @param $number
  327. * @return float
  328. */
  329. function format_round_money($number)
  330. {
  331. return round($number, 2);
  332. }
  333. /**
  334. * 基础属性过滤(特殊字符..)
  335. * @param $string
  336. * @return void
  337. */
  338. function filter($string)
  339. {
  340. return $string;
  341. }
  342. /**
  343. * 生成编号
  344. * @param string $prefix
  345. * @param string $tag 业务标识 例如member_id ...
  346. * @return string
  347. * @throws Exception
  348. */
  349. function create_no(string $prefix = '', string $tag = '')
  350. {
  351. $data_center_id = 1;
  352. $machine_id = 2;
  353. $snowflake = new Snowflake($data_center_id, $machine_id);
  354. $id = $snowflake->generateId();
  355. return $prefix . date('Ymd') . $tag . $id;
  356. }
  357. /**
  358. * 多级目录不存在则创建
  359. * @param $dir
  360. * @param $mode
  361. * @return bool
  362. */
  363. function mkdirs($dir, $mode = 0777)
  364. {
  365. if (str_contains($dir, '.')) $dir = dirname($dir);
  366. if (is_dir($dir) || @mkdir($dir, $mode)) return true;
  367. if (!mkdirs(dirname($dir), $mode)) return false;
  368. return @mkdir($dir, $mode);
  369. }
  370. /**
  371. * 创建文件夹
  372. * @param $dir
  373. * @param $mode
  374. * @return true
  375. */
  376. function mkdirs_or_notexist($dir, $mode = 0777)
  377. {
  378. if (!is_dir($dir) && !mkdir($dir, $mode, true) && !is_dir($dir)) {
  379. throw new \RuntimeException(sprintf('Directory "%s" was not created', $dir));
  380. }
  381. return true;
  382. }
  383. /**
  384. * 删除缓存文件使用
  385. * @param $dir
  386. */
  387. function rmdirs($dir)
  388. {
  389. $dh = opendir($dir);
  390. while ($file = readdir($dh)) {
  391. if ($file != "." && $file != "..") {
  392. $fullpath = $dir . "/" . $file;
  393. if (is_dir($fullpath)) {
  394. rmdirs($fullpath);
  395. } else {
  396. unlink($fullpath);
  397. }
  398. }
  399. }
  400. closedir($dh);
  401. }
  402. /**
  403. * 获取唯一随机字符串
  404. * @param int $len
  405. * @return string
  406. */
  407. function unique_random($len = 10)
  408. {
  409. $str = 'qwertyuiopasdfghjklzxcvbnmasdfgh';
  410. str_shuffle($str);
  411. return substr(str_shuffle($str), 0, $len);
  412. }
  413. /**
  414. * 校验事件结果
  415. * @param $result
  416. * @return bool
  417. */
  418. function check_event_result($result)
  419. {
  420. if (empty($result) || is_array($result)) {
  421. return true;
  422. }
  423. foreach ($result as $v) {
  424. if (!$v) return false;
  425. }
  426. return true;
  427. }
  428. /**
  429. * 二维数组合并
  430. * @param array $array1
  431. * @param array $array2
  432. * @return array
  433. */
  434. function array_merge2(array $array1, array $array2)
  435. {
  436. foreach ($array2 as $array2_k => $array2_v) {
  437. if (array_key_exists($array2_k, $array1)) {
  438. if (is_array($array2_v)) {
  439. foreach ($array2_v as $array2_kk => $array2_vv) {
  440. if (array_key_exists($array2_kk, $array1[ $array2_k ])) {
  441. if (is_array($array2_vv)) {
  442. $array1[ $array2_k ][ $array2_kk ] = array_merge($array1[ $array2_k ][ $array2_kk ], $array2_vv);
  443. }
  444. } else {
  445. $array1[ $array2_k ][ $array2_kk ] = $array2_vv;
  446. }
  447. }
  448. } else {
  449. $array1[ $array2_k ] = $array2_v;
  450. }
  451. } else {
  452. $array1[ $array2_k ] = $array2_v;
  453. }
  454. }
  455. return $array1;
  456. }
  457. /**
  458. * 通过目录获取文件结构1
  459. * @param $dir
  460. * @return array
  461. */
  462. function get_files_by_dir($dir)
  463. {
  464. $dh = @opendir($dir); //打开目录,返回一个目录流
  465. $return = array ();
  466. while ($file = @readdir($dh)) { //循环读取目录下的文件
  467. if ($file != '.' and $file != '..') {
  468. $path = $dir . DIRECTORY_SEPARATOR . $file; //设置目录,用于含有子目录的情况
  469. if (is_dir($path)) {
  470. $return[] = $file;
  471. }
  472. }
  473. }
  474. @closedir($dh); //关闭目录流
  475. return $return; //返回文件
  476. }
  477. /**
  478. * 文件夹文件拷贝
  479. * @param string $src 来源文件夹
  480. * @param string $dst 目的地文件夹
  481. * @param array $files 文件夹集合
  482. * @param array $exclude_dirs 排除无需拷贝的文件夹
  483. * @param array $exclude_files 排除无需拷贝的文件
  484. * @return bool
  485. */
  486. function dir_copy(string $src = '', string $dst = '', &$files = [], $exclude_dirs = [], $exclude_files = [])
  487. {
  488. if (empty($src) || empty($dst)) {
  489. return false;
  490. }
  491. if (!file_exists($src)) {
  492. return false;
  493. }
  494. $dir = opendir($src);
  495. dir_mkdir($dst);
  496. while (false !== ( $file = readdir($dir) )) {
  497. if (( $file != '.' ) && ( $file != '..' )) {
  498. if (is_dir($src . '/' . $file)) {
  499. // 排除目录
  500. if (count($exclude_dirs) && in_array($file, $exclude_dirs)) continue;
  501. dir_copy($src . '/' . $file, $dst . '/' . $file, $files);
  502. } else {
  503. // 排除文件
  504. if (count($exclude_files) && in_array($file, $exclude_files)) continue;
  505. copy($src . '/' . $file, $dst . '/' . $file);
  506. $files[] = $dst . '/' . $file;
  507. }
  508. }
  509. }
  510. closedir($dir);
  511. return true;
  512. }
  513. /**
  514. * 删除文件
  515. * @param string $dst
  516. * @param array $dirs
  517. * @return bool
  518. */
  519. function dir_remove(string $dst = '', array $dirs = [])
  520. {
  521. if (empty($dirs) || empty($dst)) {
  522. return false;
  523. }
  524. foreach ($dirs as $v) {
  525. @unlink($dst . $v);
  526. }
  527. return true;
  528. }
  529. /**
  530. * 创建文件夹
  531. *
  532. * @param string $path 文件夹路径
  533. * @param int $mode 访问权限
  534. * @param bool $recursive 是否递归创建
  535. * @return bool
  536. */
  537. function dir_mkdir($path = '', $mode = 0777, $recursive = true)
  538. {
  539. clearstatcache();
  540. if (!is_dir($path)) {
  541. if (mkdir($path, $mode, $recursive)) {
  542. return chmod($path, $mode);
  543. } else {
  544. throw new \core\exception\CommonException("目录{$path}创建失败请检查是否有足够的权限");
  545. }
  546. }
  547. return true;
  548. }
  549. /**
  550. * 分割sql语句
  551. * @param string $content sql内容
  552. * @param bool $string 如果为真,则只返回一条sql语句,默认以数组形式返回
  553. * @param array $replace 替换前缀,如:['my_' => 'me_'],表示将表前缀my_替换成me_
  554. * @return array|string 除去注释之后的sql语句数组或一条语句
  555. */
  556. function parse_sql($content = '', $string = false, $replace = [])
  557. {
  558. // 纯sql内容
  559. $pure_sql = [];
  560. // 被替换的前缀
  561. $from = '';
  562. // 要替换的前缀
  563. $to = '';
  564. // 替换表前缀
  565. if (!empty($replace)) {
  566. $to = current($replace);
  567. $from = current(array_flip($replace));
  568. }
  569. if ($content != '') {
  570. // 多行注释标记
  571. $comment = false;
  572. // 按行分割,兼容多个平台
  573. $content = str_replace([ "\r\n", "\r" ], "\n", $content);
  574. $content = explode("\n", trim($content));
  575. // 循环处理每一行
  576. foreach ($content as $line) {
  577. // 跳过空行
  578. if ($line == '') {
  579. continue;
  580. }
  581. // 跳过以#或者--开头的单行注释
  582. if (preg_match("/^(#|--)/", $line)) {
  583. continue;
  584. }
  585. // 跳过以/**/包裹起来的单行注释
  586. if (preg_match("/^\/\*(.*?)\*\//", $line)) {
  587. continue;
  588. }
  589. // 多行注释开始
  590. if (str_starts_with($line, '/*')) {
  591. $comment = true;
  592. continue;
  593. }
  594. // 多行注释结束
  595. if (str_ends_with($line, '*/')) {
  596. $comment = false;
  597. continue;
  598. }
  599. // 多行注释没有结束,继续跳过
  600. if ($comment) {
  601. continue;
  602. }
  603. // 替换表前缀
  604. if ($from != '') {
  605. $line = str_replace('`' . $from, '`' . $to, $line);
  606. }
  607. // sql语句
  608. $pure_sql[] = $line;
  609. }
  610. // 只返回一条语句
  611. if ($string) {
  612. return implode("", $pure_sql);
  613. }
  614. // 以数组形式返回sql语句
  615. $pure_sql = implode("\n", $pure_sql);
  616. $pure_sql = explode(";\n", $pure_sql);
  617. }
  618. return $pure_sql;
  619. }
  620. /**
  621. * 递归查询目录下所有文件
  622. * @param $path
  623. * @param $data
  624. * @param $search
  625. * @return void
  626. */
  627. function search_dir($path, &$data, $search = '')
  628. {
  629. if (is_dir($path)) {
  630. $path .= DIRECTORY_SEPARATOR;
  631. $fp = dir($path);
  632. while ($file = $fp->read()) {
  633. if ($file != '.' && $file != '..') {
  634. search_dir($path . $file, $data, $search);
  635. }
  636. }
  637. $fp->close();
  638. }
  639. if (is_file($path)) {
  640. if ($search) $path = str_replace($search, '', $path);
  641. $data[] = $path;
  642. }
  643. }
  644. function remove_empty_dir($dirs)
  645. {
  646. }
  647. /**
  648. * 获取文件地图
  649. * @param $path
  650. * @param array $arr
  651. * @return array
  652. */
  653. function getFileMap($path, $arr = [])
  654. {
  655. if (is_dir($path)) {
  656. $dir = scandir($path);
  657. foreach ($dir as $file_path) {
  658. if ($file_path != '.' && $file_path != '..') {
  659. $temp_path = $path . '/' . $file_path;
  660. if (is_dir($temp_path)) {
  661. $arr[ $temp_path ] = $file_path;
  662. $arr = getFileMap($temp_path, $arr);
  663. } else {
  664. $arr[ $temp_path ] = $file_path;
  665. }
  666. }
  667. }
  668. return $arr;
  669. }
  670. }
  671. /**
  672. * 如果不存在则写入缓存
  673. * @param string|null $name
  674. * @param $value
  675. * @param $tag
  676. * @param $options
  677. * @return mixed|string
  678. */
  679. function cache_remember(string $name = null, $value = '', $tag = null, $options = null)
  680. {
  681. if (!empty($hit = Cache::get($name)))//可以用has
  682. return $hit;
  683. if ($value instanceof Closure) {
  684. // 获取缓存数据
  685. $value = Container::getInstance()->invokeFunction($value);
  686. }
  687. if (is_null($tag)) {
  688. Cache::set($name, $value, $options[ 'expire' ] ?? null);
  689. } else {
  690. Cache::tag($tag)->set($name, $value, $options[ 'expire' ] ?? null);
  691. }
  692. return $value;
  693. }
  694. /**
  695. * 项目目录
  696. * @return string
  697. */
  698. function project_path()
  699. {
  700. return dirname(root_path()) . DIRECTORY_SEPARATOR;
  701. }
  702. /**
  703. * 图片转base64
  704. * @param string $path
  705. * @param $is_delete 转换后是否删除原图
  706. * @return string
  707. */
  708. function image_to_base64(string $path, $is_delete = false)
  709. {
  710. if (!file_exists($path)) return 'image not exist';
  711. $mime = getimagesize($path)[ 'mime' ];
  712. $image_data = file_get_contents($path);
  713. // 将图片转换为 base64
  714. $base64_data = base64_encode($image_data);
  715. if ($is_delete) @unlink($path);
  716. return "data:$mime;base64,$base64_data";
  717. }
  718. /**
  719. * 获取缩略图
  720. * @param $site_id
  721. * @param $image
  722. * @param string $thumb_type
  723. * @param bool $is_throw_exception
  724. * @return mixed
  725. * @throws Exception
  726. */
  727. function get_thumb_images($site_id, $image, $thumb_type = 'all', bool $is_throw_exception = false)
  728. {
  729. return ( new CoreImageService() )->thumb($site_id, $image, $thumb_type, $is_throw_exception);
  730. }
  731. /**
  732. * 版本号转整数 例如1.0.0=001.000.000=001000000=1000000
  733. * @param $version
  734. * @return int
  735. */
  736. function version_to_int($version)
  737. {
  738. $version_array = explode(".", $version);
  739. $v1 = sprintf('%03s', (int) $version_array[ 0 ] ?? 0);
  740. $v2 = sprintf('%03s', (int) $version_array[ 1 ] ?? 0);
  741. $v3 = sprintf('%03s', (int) $version_array[ 2 ] ?? 0);
  742. return (int) "{$v1}{$v2}{$v3}";
  743. }
  744. /**
  745. * 整数版本号转字符串例如 1000000=001000000=001.000.000=1.0.0
  746. * @param int $ver
  747. * @return string
  748. */
  749. function version_to_string($ver)
  750. {
  751. if ($ver > 999) {
  752. if ($ver > 999999) {
  753. $ver .= "";
  754. $v3 = (int) substr($ver, -3);
  755. $v2 = (int) substr($ver, -6, 3);
  756. $v1 = (int) substr($ver, 0, -6);
  757. } else {
  758. $ver .= "";
  759. $v3 = (int) substr($ver, -3);
  760. $v2 = (int) substr($ver, 0, -3);
  761. $v1 = 0;
  762. }
  763. } else {
  764. $v3 = $ver;
  765. $v2 = 0;
  766. $v1 = 0;
  767. }
  768. return "{$v1}.{$v2}.{$v3}";
  769. }
  770. /**
  771. * 检测文件是否是本地图片
  772. * @param string $file_path
  773. * @return void
  774. */
  775. function check_file_is_remote(string $file_path)
  776. {
  777. return str_contains($file_path, 'https://') || str_contains($file_path, 'http://') || str_contains($file_path, '.com');
  778. }
  779. /**
  780. * 文件拷贝
  781. * @param string $source_file
  782. * @param string $to_file
  783. * @return void
  784. */
  785. function file_copy(string $source_file, string $to_file)
  786. {
  787. if (!file_exists($source_file)) return false;
  788. // 检查目标文件是否存在
  789. if (!file_exists($to_file)) {
  790. // 创建目录
  791. $directory = dirname($to_file);
  792. if (!file_exists($directory)) {
  793. mkdir($directory, 0777, true);
  794. }
  795. }
  796. if (copy($source_file, $to_file)) {
  797. return true;
  798. } else {
  799. return false;
  800. }
  801. }
  802. /**
  803. * 创建并生成二维码
  804. * @param $url
  805. * @param $site_id
  806. * @param $dir
  807. * @param $file_path
  808. * @param $channel
  809. * @param $size
  810. * @return string
  811. */
  812. function qrcode($url, $page, $data, $site_id, $dir = '', $channel = 'h5', $style = [ 'is_transparent' => true ], $outfile = true)
  813. {
  814. $site_id = 0;
  815. if ($outfile) {
  816. $dir = $dir ?: 'upload' . '/' . 'qrcode' . '/' . $site_id;//二维码默认存储位置
  817. if (!is_dir($dir) && !mkdir($dir, 0777, true) && !is_dir($dir)) {
  818. throw new \RuntimeException(sprintf('Directory "%s" was not created', $dir));
  819. }
  820. $file_path = md5($url . $page . serialize($data) . serialize($style) . $channel);
  821. $path = $dir . '/' . $file_path . '.png';
  822. if (file_exists($path)) {
  823. return $path;
  824. }
  825. }
  826. $result = array_values(array_filter(event('GetQrcodeOfChannel', [
  827. 'filepath' => $path ?? '',
  828. 'url' => $url,
  829. 'page' => $page,
  830. 'data' => $data,
  831. 'site_id' => $site_id,
  832. 'channel' => $channel,
  833. 'outfile' => $outfile
  834. ])));
  835. if (!empty($result[ 0 ])) {
  836. $path = $result[ 0 ];
  837. }
  838. // if(!empty($style)){
  839. // $is_transparent = $style['is_transparent'] ?? false;//是否透明
  840. // $color = $style['color'] ?? '#000';//颜色
  841. // $bg_color = $style['bg_color'] ?? '#FFF';
  842. // //将二维码背景变透明
  843. // $resource = imagecreatefrompng($path);
  844. // @unlink($path);
  845. // if($is_transparent){
  846. // $bgcolor = imagecolorallocate($resource, 255, 255, 255);
  847. // imagefill($resource, 0, 0, $bgcolor);
  848. // imagecolortransparent($resource, $bgcolor);
  849. // }
  850. // // 设置彩色二维码的颜色
  851. // $color = imagecolorallocate($resource, 229, 39, 21); // 红色
  852. // // 修改二维码的像素颜色
  853. // imagesetpixel($resource, 10, 10, $color);
  854. // imagepng($resource,$path);
  855. // }
  856. return $path;
  857. }
  858. /**
  859. * 获取海报
  860. * @param int $site_id
  861. * @param $id
  862. * @param $type
  863. * @param array $param
  864. * @param string $channel
  865. * @param bool $is_throw_exception
  866. * @return string|void
  867. */
  868. function poster(int $site_id, $id, $type, array $param = [], string $channel = '', bool $is_throw_exception = true)
  869. {
  870. return ( new \app\service\core\poster\CorePosterService() )->get($site_id, $id, $type, $param, $channel, $is_throw_exception);
  871. }
  872. /**
  873. * 获取站点插件
  874. * @return array
  875. */
  876. function get_site_addons($site_id = 0) : array
  877. {
  878. $addons = $site_id ? Cache::get("local_install_addons_{$site_id}") : Cache::get("local_install_addons");
  879. return is_null($addons) ? [] : $addons;
  880. }
  881. function get_wap_domain()
  882. {
  883. $wap_url = ( new CoreSysConfigService() )->getSceneDomain()[ 'wap_url' ];
  884. return $wap_url;
  885. }
  886. /**
  887. * $str为要进行截取的字符串,$length为截取长度(汉字算一个字,字母算半个字
  888. * @param $str
  889. * @param int $length
  890. * @param bool $is_need_apostrophe
  891. * @return string
  892. */
  893. function str_sub($str, $length = 10, $is_need_apostrophe = true)
  894. {
  895. return mb_substr($str, 0, $length, 'UTF-8') . ( $is_need_apostrophe ? '...' : '' );
  896. }