helpers.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. <?php
  2. use Illuminate\Http\JsonResponse;
  3. /**
  4. * 获取毫秒
  5. *
  6. * @return int
  7. */
  8. if (!function_exists('millisecond')) {
  9. function millisecond(): int
  10. {
  11. return intval(microtime(true) * 1000);
  12. }
  13. }
  14. /**
  15. * 下划线转驼峰
  16. *
  17. * @param $str
  18. * @return string|null
  19. */
  20. if (!function_exists('convertUnderline')) {
  21. function convertUnderline($str): string|null
  22. {
  23. return preg_replace_callback('/([-_]+([a-z]{1}))/i', function ($matches) {
  24. return strtoupper($matches[2]);
  25. }, $str);
  26. }
  27. }
  28. /**
  29. * 驼峰转下划线
  30. *
  31. * @param $str
  32. * @return string|null
  33. */
  34. if (!function_exists('humpToLine')) {
  35. function humpToLine($str): string|null
  36. {
  37. return preg_replace_callback('/([A-Z]{1})/', function ($matches) {
  38. return '_' . strtolower($matches[0]);
  39. }, $str);
  40. }
  41. }
  42. ###################################################
  43. #### 相关 ##################################
  44. ###################################################
  45. /**
  46. * 返回错误信息
  47. *
  48. * @param $code
  49. * @param $message
  50. * @param string $data
  51. * @return String
  52. */
  53. if (!function_exists('responseMessage')) {
  54. function responseMessage($code, $message, $data = ''): JsonResponse
  55. {
  56. $result = backJson($code, $message, $data);
  57. return response()->json($result);
  58. }
  59. }
  60. if (!function_exists('backJson')) {
  61. /**
  62. * @param $code
  63. * @param $message
  64. * @param string $data
  65. * @return array
  66. */
  67. function backJson($code, $message, $data = ''): array
  68. {
  69. $flag = $code >= 0 && $code < 2000;
  70. return [
  71. 'code' => $flag ? 0 : $code,
  72. 'error' => !$flag,
  73. 'msg' => $message,
  74. 'result' => $data,
  75. ];
  76. }
  77. }
  78. ###################################################
  79. #### 商品相关的函数 ##################################
  80. ###################################################
  81. /**
  82. * 获取sku的价格区间
  83. *
  84. * @param $relates
  85. * @return array
  86. */
  87. if (!function_exists('getBetweenPrice')) {
  88. function getBetweenPrice($relates): array
  89. {
  90. $priceMin = 0;
  91. $priceMax = 0;
  92. $priceMarketMin = 0;
  93. $priceMarketMax = 0;
  94. $stockMin = 0;
  95. $stockMax = 0;
  96. foreach ($relates as $key => $row) {
  97. if ($key == 0) {
  98. $priceMin = $row['sku_price'] ?? 0;
  99. $priceMarketMin = $row['sku_market_price'] ?? 0;
  100. $stockMin = $row['sku_num'] ?? 0;
  101. } else {
  102. $priceMin = min($row['sku_price'] ?? 0, $priceMin);
  103. $priceMarketMin = min($row['sku_market_price'] ?? 0, $priceMarketMin);
  104. $stockMin = min($row['sku_num'] ?? 0, $stockMin);
  105. }
  106. $priceMax = max($row['sku_price'] ?? 0, $priceMax);
  107. $priceMarketMax = max($row['sku_market_price'] ?? 0, $priceMarketMax);
  108. $stockMax = max($row['sku_num'] ?? 0, $stockMax);
  109. }
  110. return [
  111. 'priceMin' => $priceMin,
  112. 'priceMax' => $priceMax,
  113. 'priceMarketMin' => $priceMarketMin,
  114. 'priceMarketMax' => $priceMarketMax,
  115. 'stockMin' => $stockMin,
  116. 'stockMax' => $stockMax,
  117. ];
  118. }
  119. }
  120. /**
  121. * 获取产品的价格,有sku,没有sku的
  122. */
  123. if (!function_exists('getPrice')) {
  124. function getPrice($item)
  125. {
  126. $price = $item['price'];
  127. $product_sku = $item['product_sku'];
  128. //如果存在sku,则根据sku计算价格
  129. $sku = $item['sku'];
  130. if ($sku && $product_sku) {
  131. $product_sku = json_decode($product_sku, true);
  132. if (!empty($sku['spec'])) {
  133. $price = 0;
  134. $relateArr = $sku['relates'] ?? '';
  135. if ($relateArr) {
  136. foreach ($relateArr as $row) {
  137. $idArr = $row['id'];
  138. if (empty(array_diff($product_sku, $idArr))) {
  139. $price = $row['sku_price'];
  140. break;
  141. }
  142. }
  143. } else {
  144. }
  145. }
  146. }
  147. return $price;
  148. }
  149. }
  150. /**
  151. * 获取库存数据
  152. *
  153. * @param $item
  154. * @return int
  155. */
  156. if (!function_exists('getStock')) {
  157. function getStock($item)
  158. {
  159. $stock = $item['stock'];
  160. $product_sku = $item['product_sku']; // 购买的sku
  161. //如果存在sku,则根据sku计算价格
  162. $sku = $item['sku'];
  163. if ($sku && $product_sku) {
  164. $product_sku = json_decode($product_sku, true);
  165. if (!empty($sku['spec'])) {
  166. $stock = 0;
  167. $relateArr = $sku['relates'] ?? '';
  168. if ($relateArr) {
  169. foreach ($relateArr as $row) {
  170. $idArr = $row['id'];
  171. if (empty(array_diff($product_sku, $idArr))) {
  172. $stock = $row['sku_num'];
  173. break;
  174. }
  175. }
  176. }
  177. }
  178. }
  179. return $stock;
  180. }
  181. }
  182. /**
  183. * 如果存在规格,获取规格的信息
  184. */
  185. if (!function_exists('getSpec')) {
  186. function getSpec($item)
  187. {
  188. $product_sku = $item['product_sku'];
  189. $sku = $item['sku'];
  190. $nameArr = [];
  191. if ($sku && $product_sku) {
  192. $product_sku = json_decode($product_sku, true);
  193. $specArr = $sku['spec'] ?? '';
  194. foreach ($product_sku as $val) {
  195. if ($specArr) {
  196. foreach ($specArr as $row) {
  197. $children = $row['children'];
  198. foreach ($children as $item) {
  199. if ($item['pssv_id'] == $val) {
  200. $nameArr[] = $item['value'];
  201. }
  202. }
  203. }
  204. }
  205. }
  206. }
  207. return implode(';', $nameArr);
  208. }
  209. }
  210. /**
  211. * 随机生成订单号
  212. *
  213. * @return string
  214. */
  215. if (!function_exists('createNewOrderNo')) {
  216. function createNewOrderNo()
  217. {
  218. return date('ymd') . //180824 6位
  219. substr(time(), -4) . //秒 4位
  220. substr(microtime(), 2, 2) . //微妙2位
  221. mt_rand(1111, 9999); //4位
  222. }
  223. }
  224. if (!function_exists('getRealIp')) {
  225. function getRealIp()
  226. {
  227. if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown")) $ip = getenv("HTTP_CLIENT_IP");
  228. else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown")) $ip = getenv("HTTP_X_FORWARDED_FOR");
  229. else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown")) $ip = getenv("REMOTE_ADDR");
  230. else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown")) $ip = $_SERVER['REMOTE_ADDR'];
  231. else $ip = "unknown";
  232. return ($ip);
  233. }
  234. }
  235. if (!function_exists('arrToTree')) {
  236. /**
  237. * 递归实现无限极分类
  238. *
  239. * @param $arr
  240. * @param $pid
  241. * @param array $config ['parent_id' => 'parent_id', 'id' => 'id', 'name' => 'name']
  242. * @return array
  243. */
  244. function arrToTree($arr, $pid = 0, $config = [])
  245. {
  246. static $tree = [];
  247. $key_parent_id = $config['parent_id'] ?? 'parent_id';
  248. $key_id = $config['id'] ?? 'id';
  249. $key_name = $config['name'] ?? 'name';
  250. $step = $config['step'] ?? 0;
  251. foreach ($arr as $key => $val) {
  252. if ($val[$key_parent_id] == $pid) {
  253. $flg = str_repeat(" └―― ", $step);
  254. $val['name'] = $flg . $val[$key_name];
  255. $tree[] = $val;
  256. $config['step'] = $step + 1;
  257. arrToTree($arr, $val[$key_id], $config);
  258. }
  259. }
  260. return $tree;
  261. }
  262. }
  263. if (!function_exists('generateToTree')) {
  264. /**
  265. * 引用算法 生成父子树结构
  266. *
  267. * @param $array
  268. * @param $config ['parent_id' => 'parent_id', 'id' => 'id']
  269. * @return array
  270. */
  271. function generateToTree($array, $config = [])
  272. {
  273. $key_parent_id = $config['parent_id'] ?? 'parent_id';
  274. $key_id = $config['id'] ?? 'id';
  275. //第一步 构造数据
  276. $items = array();
  277. foreach ($array as $value) {
  278. $items[$value[$key_id]] = $value;
  279. }
  280. //第二部 遍历数据 生成树状结构
  281. $tree = array();
  282. foreach ($items as $key => $value) {
  283. if (isset($items[$value[$key_parent_id]])) {
  284. $items[$value[$key_parent_id]]['children'][] = &$items[$key];
  285. } else {
  286. $tree[] = &$items[$key];
  287. }
  288. }
  289. return $tree;
  290. }
  291. }
  292. if (!function_exists('getRandNumber')) {
  293. /**
  294. * 生成 12 位的随机码
  295. *
  296. * @param int $num
  297. * @return bool|string
  298. */
  299. function getRandNumber($num = 12)
  300. {
  301. return substr(md5(md5(microtime() . mt_rand()) . uniqid('', true)), mt_rand(0, 32 - $num), $num);
  302. }
  303. }
  304. /**
  305. * 判断是否是微信内部浏览器
  306. *
  307. * @return bool
  308. */
  309. if (!function_exists('isWeixin')) {
  310. function isWeixin()
  311. {
  312. if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false) {
  313. return true;
  314. }
  315. return false;
  316. }
  317. }
  318. if (!function_exists('subtext')) {
  319. function subtext($text, $length)
  320. {
  321. if (mb_strlen($text, 'utf8') > $length) {
  322. return mb_substr($text, 0, $length, 'utf8') . '...';
  323. } else {
  324. return $text;
  325. }
  326. }
  327. }
  328. if (!function_exists('getBonusOdds')) {
  329. /**
  330. * 根据概率,获取中奖编号
  331. *
  332. * @param $proArr
  333. * @return int|string
  334. */
  335. function getBonusOdds($proArr)
  336. {
  337. $result = '';
  338. //概率数组的总概率精度
  339. $proSum = array_sum($proArr);
  340. //概率数组循环
  341. foreach ($proArr as $key => $proCur) {
  342. $randNum = mt_rand(1, $proSum);
  343. if ($randNum <= $proCur) {
  344. $result = $key;
  345. break;
  346. } else {
  347. $proSum -= $proCur;
  348. }
  349. }
  350. return $result;
  351. }
  352. }
  353. ###################################################################################################
  354. ###################################################################################################
  355. if (!function_exists('isMobile')) {
  356. function isMobile($mobile)
  357. {
  358. if (!is_numeric($mobile)) {
  359. return false;
  360. }
  361. return preg_match('#^13[\d]{9}$|^14[5,7]{1}\d{8}$|^15[^4]{1}\d{8}$|^16[\d]{9}$|^17[0,6,7,8]{1}\d{8}$|^18[\d]{9}$|^19[\d]{9}$#', $mobile) ? true : false;
  362. }
  363. }
  364. if (!function_exists('isEmail')) {
  365. /**
  366. * 验证email格式是否正确
  367. *
  368. * @param $email
  369. * @return bool
  370. */
  371. function isEmail($email)
  372. {
  373. $pattern = "/([a-z0-9]*[-_.]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+[.][a-z]{2,3}([.][a-z]{2})?/i";
  374. if (preg_match($pattern, $email)) {
  375. return true;
  376. } else {
  377. return false;
  378. }
  379. }
  380. }
  381. if (!function_exists('hidestr')) {
  382. /**
  383. * 将一个字符串部分字符用$re替代隐藏
  384. *
  385. * @param string $string 待处理的字符串
  386. * @param int $start 规定在字符串的何处开始,
  387. * 正数 -
  388. * 在字符串的指定位置开始
  389. * 负数 -
  390. * 在从字符串结尾的指定位置开始
  391. * 0 -
  392. * 在字符串中的第一个字符处开始
  393. * @param int $length 可选。规定要隐藏的字符串长度。默认是直到字符串的结尾。
  394. * 正数 - 从 start
  395. * 参数所在的位置隐藏
  396. * 负数 -
  397. * 从字符串末端隐藏
  398. * @param string $re 替代符
  399. * @return string 处理后的字符串
  400. */
  401. function hidestr($string, $start = 0, $length = 0, $re = '*')
  402. {
  403. if (empty($string)) {
  404. return false;
  405. }
  406. $strarr = array();
  407. $mb_strlen = mb_strlen($string);
  408. while ($mb_strlen) { //循环把字符串变为数组
  409. $strarr[] = mb_substr($string, 0, 1, 'utf8');
  410. $string = mb_substr($string, 1, $mb_strlen, 'utf8');
  411. $mb_strlen = mb_strlen($string);
  412. }
  413. $strlen = count($strarr);
  414. $begin = $start >= 0 ? $start : ($strlen - abs($start));
  415. $end = $last = $strlen - 1;
  416. if ($length > 0) {
  417. $end = $begin + $length - 1;
  418. } elseif ($length < 0) {
  419. $end -= abs($length);
  420. }
  421. for ($i = $begin; $i <= $end; $i++) {
  422. $strarr[$i] = $re;
  423. }
  424. if ($begin >= $end || $begin >= $last || $end > $last) {
  425. return false;
  426. }
  427. return implode('', $strarr);
  428. }
  429. }
  430. if (!function_exists('toRoute')) {
  431. /**
  432. * 例子
  433. * toRoute('path/show'); # http://www.xx.com/currentBundle/path/show
  434. *
  435. * @param string $url
  436. * @param array $params
  437. * @param bool $scheme
  438. * @return string
  439. */
  440. function toRoute($url = '', $params = [], $scheme = null)
  441. {
  442. return url($url, $params, $scheme);
  443. }
  444. }
  445. ////////////////////////////////////////////////////////////////////////////////////
  446. if (!function_exists('asset_link')) {
  447. /**
  448. * @param $url
  449. * @param string $version
  450. * @param string $urlName
  451. * @return string
  452. */
  453. function asset_link($url, $version = '', $urlName = 'default')
  454. {
  455. return asset($url);
  456. }
  457. }
  458. if (!function_exists('asset_css')) {
  459. /**
  460. * @param $url
  461. * @param array $options
  462. * @param string $urlName
  463. * @return string
  464. */
  465. function asset_css($url, $options = [], $urlName = 'default')
  466. {
  467. return '<link href="' . asset($url) . '" rel="stylesheet" ' . renderTagAttributes($options) . '>';
  468. }
  469. }
  470. if (!function_exists('asset_js')) {
  471. /**
  472. * @param $url
  473. * @param array $options
  474. * @param string $urlName
  475. * @return string
  476. */
  477. function asset_js($url, $options = [], $urlName = 'default')
  478. {
  479. return '<script src="' . asset($url) . '"></script>';
  480. }
  481. }
  482. if (!function_exists('asset_img')) {
  483. /**
  484. * @param $url
  485. * @param array $options
  486. * @param string $urlName
  487. * @return string
  488. */
  489. function asset_img($url, $options = [], $urlName = 'default')
  490. {
  491. return '<img src="' . asset($url) . '" ' . renderTagAttributes($options) . '>';
  492. }
  493. }
  494. function route_info()
  495. {
  496. }
  497. function renderTagAttributes($attributes)
  498. {
  499. if (count($attributes) > 1) {
  500. $sorted = [];
  501. foreach ([
  502. 'type', 'id', 'class', 'name', 'value',
  503. 'href', 'src', 'action', 'method',
  504. 'selected', 'checked', 'readonly', 'disabled', 'multiple',
  505. 'size', 'maxlength', 'width', 'height', 'rows', 'cols',
  506. 'alt', 'title', 'rel', 'media',
  507. ] as $name) {
  508. if (isset($attributes[$name])) {
  509. $sorted[$name] = $attributes[$name];
  510. }
  511. }
  512. $attributes = array_merge($sorted, $attributes);
  513. }
  514. $html = '';
  515. foreach ($attributes as $name => $value) {
  516. if (is_bool($value)) {
  517. if ($value) {
  518. $html .= " $name";
  519. }
  520. } elseif (is_array($value)) {
  521. if ($name === 'class') {
  522. if (empty($value)) {
  523. continue;
  524. }
  525. $html .= " $name=\"" . htmlspecialchars(implode(' ', $value), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', true) . '"';
  526. } elseif ($name === 'style') {
  527. if (empty($value)) {
  528. continue;
  529. }
  530. $result = '';
  531. foreach ($value as $name2 => $value2) {
  532. $result .= "$name2: $value2; ";
  533. }
  534. $result = $result === '' ? null : rtrim($result);
  535. $html .= " $name=\"" . htmlspecialchars($result, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', true) . '"';
  536. } else {
  537. $html .= " $name='" . htmlspecialchars($value, JSON_UNESCAPED_UNICODE | JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS) . "'";
  538. }
  539. } elseif ($value !== null) {
  540. $html .= " $name=\"" . htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', true) . '"';
  541. }
  542. }
  543. return $html;
  544. }
  545. if (!function_exists('subtext')) {
  546. function subtext($text, $length)
  547. {
  548. if (mb_strlen($text, 'utf8') > $length) {
  549. return mb_substr($text, 0, $length, 'utf8') . '...';
  550. } else {
  551. return $text;
  552. }
  553. }
  554. }