common.php 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. // 应用公共文件
  12. use app\common\repositories\system\config\ConfigValueRepository;
  13. use app\common\repositories\system\groupData\GroupDataRepository;
  14. use app\common\repositories\system\StorageRepository;
  15. use crmeb\services\UploadService;
  16. use Swoole\Lock;
  17. use think\db\BaseQuery;
  18. if (!function_exists('go')) {
  19. function go(): bool
  20. {
  21. return \Swoole\Coroutine::create(...func_get_args());
  22. }
  23. }
  24. if (!function_exists('isDebug')) {
  25. function isDebug(): bool
  26. {
  27. return !!env('APP_DEBUG');
  28. }
  29. }
  30. if (!function_exists('formToData')) {
  31. function formToData($form): array
  32. {
  33. $rule = $form->formRule();
  34. $action = $form->getAction();
  35. $method = $form->getMethod();
  36. $title = $form->getTitle();
  37. $config = (object)$form->formConfig();
  38. $admin = config('admin.api_admin_prefix');
  39. $merchant = config('admin.api_merchant_prefix');
  40. $api = $action;
  41. if (strpos($api, '/' . $admin) === 0) {
  42. $api = substr($api, strlen($admin) + 1);
  43. } else if (strpos($api, '/' . $merchant) === 0) {
  44. $api = substr($api, strlen($merchant) + 1);
  45. }
  46. $api = str_replace('.html', '', $api);
  47. return compact('rule', 'action', 'method', 'title', 'config', 'api');
  48. }
  49. }
  50. if (!function_exists('getDistance')) {
  51. function getDistance($lat1, $lng1, $lat2, $lng2)
  52. {
  53. //将角度转为狐度
  54. $radLat1 = deg2rad($lat1); //deg2rad()函数将角度转换为弧度
  55. $radLat2 = deg2rad($lat2);
  56. $radLng1 = deg2rad($lng1);
  57. $radLng2 = deg2rad($lng2);
  58. $a = $radLat1 - $radLat2;
  59. $b = $radLng1 - $radLng2;
  60. $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6371;
  61. return round($s, 1);
  62. }
  63. }
  64. /**
  65. * 无线级分类处理
  66. *
  67. * @param array $data 数据源
  68. * @param string $idName 主键
  69. * @param string $fieldName 父级字段
  70. * @param string $childrenKey 子级字段名
  71. * @return array
  72. * @author 张先生
  73. * @date 2020-03-27
  74. */
  75. if (!function_exists('formatCategory')) {
  76. function formatCategory(array $data, string $idName = "id", string $fieldName = 'pid', $childrenKey = 'children')
  77. {
  78. $items = [];
  79. foreach ($data as $item) {
  80. $items[$item[$idName]] = $item;
  81. }
  82. $result = array();
  83. foreach ($items as $item) {
  84. if (isset($items[$item[$fieldName]])) {
  85. $items[$item[$fieldName]][$childrenKey][] = &$items[$item[$idName]];
  86. } else if ($item[$fieldName] == 0) {
  87. $result[] = &$items[$item[$idName]];
  88. }
  89. }
  90. return $result;
  91. }
  92. }
  93. if (!function_exists('formatTreeList')) {
  94. function formatTreeList(&$options, $name, $pidName = 'pid', $pid = 0, $level = 0, &$data = []): array
  95. {
  96. $_options = $options;
  97. foreach ($_options as $k => $option) {
  98. if ($option[$pidName] == $pid) {
  99. $data[] = ['value' => $k, 'label' => str_repeat('|---', $level + 1) . $option[$name]];
  100. unset($options[$k]);
  101. formatTreeList($options, $name, $pidName, $k, $level + 1, $data);
  102. }
  103. }
  104. return $data;
  105. }
  106. }
  107. if (!function_exists('formatTree')) {
  108. function formatTree(&$options, $name, $pidName = 'pid', $pid = 0, $level = 0, $data = []): array
  109. {
  110. $_options = $options;
  111. foreach ($_options as $k => $option) {
  112. if ($option[$pidName] == $pid) {
  113. $value = ['id' => $k, 'title' => $option[$name]];
  114. unset($options[$k]);
  115. $value['children'] = formatTree($options, $name, $pidName, $k, $level + 1);
  116. $data[] = $value;
  117. }
  118. }
  119. return $data;
  120. }
  121. }
  122. if (!function_exists('formatCascaderData')) {
  123. function formatCascaderData(&$options, $name, $baseLevel = 0, $pidName = 'pid', $pid = 0, $level = 0, $data =
  124. [], $disabled = []): array
  125. {
  126. $_options = $options;
  127. foreach ($_options as $k => $option) {
  128. if ($option[$pidName] == $pid) {
  129. $value = ['value' => $k, 'label' => $option[$name],'disabled' => false];
  130. if ($disabled) {
  131. $value['disabled'] = in_array($k,$disabled) ? false : true;
  132. }
  133. unset($options[$k]);
  134. $value['children'] = formatCascaderData($options, $name, $baseLevel, $pidName, $k, $level + 1,[],$disabled);
  135. if (!count($value['children'])) unset($value['children']);
  136. $data[] = $value;
  137. }
  138. }
  139. return $data;
  140. }
  141. }
  142. /**
  143. * @function toMap 数组重新组装
  144. * @param array $data 数据
  145. * @param string $field key
  146. * @param string $value value default null
  147. * @return array
  148. * @author 张先生
  149. * @date 2020-04-01
  150. */
  151. if (!function_exists('toMap')) {
  152. function toMap(array $data, $field = 'id', $value = '')
  153. {
  154. $result = array();
  155. if (empty($data)) {
  156. return $result;
  157. }
  158. //开始处理数据
  159. foreach ($data as $item) {
  160. $val = $item;
  161. if (!empty($value)) {
  162. $val = $item[$value];
  163. }
  164. $result[$item[$field]] = $val;
  165. }
  166. return $result;
  167. }
  168. }
  169. /**
  170. * @function getUniqueListByArray 从数组中获取某个字段的值,重新拼装成新的一维数组
  171. * @param array $data 数据
  172. * @param string $field key
  173. * @return array
  174. * @author 张先生
  175. * @date 2020-04-01
  176. */
  177. if (!function_exists('getUniqueListByArray')) {
  178. function getUniqueListByArray(array $data, $field = 'id')
  179. {
  180. return array_unique(array_values(array_column($data, $field)));
  181. }
  182. }
  183. if (!function_exists('isPhone')) {
  184. function isPhone($test)
  185. {
  186. return !preg_match("/^1[3456789]{1}\d{9}$/", $test);
  187. }
  188. }
  189. if (!function_exists('getMonth')) {
  190. /**
  191. * 获取本季度 time
  192. * @param int|string $time
  193. * @param $ceil
  194. * @return array
  195. */
  196. function getMonth($time = '', $ceil = 0)
  197. {
  198. if ($ceil != 0)
  199. $season = ceil(date('n') / 3) - $ceil;
  200. else
  201. $season = ceil(date('n') / 3);
  202. $firstday = date('Y-m-01', mktime(0, 0, 0, ($season - 1) * 3 + 1, 1, date('Y')));
  203. $lastday = date('Y-m-t', mktime(0, 0, 0, $season * 3, 1, date('Y')));
  204. return array($firstday, $lastday);
  205. }
  206. }
  207. if (!function_exists('getModelTime')) {
  208. /**
  209. * @param BaseQuery $model
  210. * @param string $section
  211. * @param string $prefix
  212. * @param string $field
  213. * @return mixed
  214. * @author xaboy
  215. * @day 2020-04-29
  216. */
  217. function getModelTime(BaseQuery $model, string $section, $prefix = 'create_time', $field = '-',$time = '')
  218. {
  219. if (!isset($section)) return $model;
  220. switch ($section) {
  221. case 'today':
  222. $model->whereBetween($prefix, [date('Y-m-d H:i:s', strtotime('today')), date('Y-m-d H:i:s', strtotime('tomorrow -1second'))]);
  223. break;
  224. case 'week':
  225. $model->whereBetween($prefix, [date('Y-m-d H:i:s', strtotime('this week 00:00:00')), date('Y-m-d H:i:s', strtotime('next week 00:00:00 -1second'))]);
  226. break;
  227. case 'month':
  228. $model->whereBetween($prefix, [date('Y-m-d H:i:s', strtotime('first Day of this month 00:00:00')), date('Y-m-d H:i:s', strtotime('first Day of next month 00:00:00 -1second'))]);
  229. break;
  230. case 'year':
  231. $model->whereBetween($prefix, [date('Y-m-d H:i:s', strtotime('this year 1/1')), date('Y-m-d H:i:s', strtotime('next year 1/1 -1second'))]);
  232. break;
  233. case 'yesterday':
  234. $model->whereBetween($prefix, [date('Y-m-d H:i:s', strtotime('yesterday')), date('Y-m-d H:i:s', strtotime('today -1second'))]);
  235. break;
  236. case 'quarter':
  237. list($startTime, $endTime) = getMonth();
  238. $model = $model->where($prefix, '>', $startTime);
  239. $model = $model->where($prefix, '<', $endTime);
  240. break;
  241. case 'lately7':
  242. $model = $model->where($prefix, 'between', [date('Y-m-d', strtotime("-7 day")), date('Y-m-d H:i:s')]);
  243. break;
  244. case 'lately30':
  245. $model = $model->where($prefix, 'between', [date('Y-m-d', strtotime("-30 day")), date('Y-m-d H:i:s')]);
  246. break;
  247. default:
  248. if (strstr($section, $field) !== false) {
  249. list($startTime, $endTime) = explode($field, $section);
  250. if (strlen($startTime) == 4) {
  251. $model->whereBetweenTime($prefix, date('Y-m-d H:i:s', strtotime($section)), date('Y-m-d H:i:s', strtotime($section . ' +1day -1second')));
  252. } else {
  253. if ($startTime == $endTime) {
  254. $model = $model->whereBetweenTime($prefix, date('Y-m-d 0:0:0', strtotime($startTime)), date('Y-m-d 23:59:59', strtotime($endTime)));
  255. } else if(strpos($startTime, ':')) {
  256. $model = $model->whereBetweenTime($prefix, $startTime, $endTime);
  257. } else {
  258. $model = $model->whereBetweenTime($prefix, date('Y-m-d H:i:s', strtotime($startTime)), date('Y-m-d H:i:s', strtotime($endTime . ' +1day -1second')));
  259. }
  260. }
  261. }
  262. break;
  263. }
  264. return $model;
  265. }
  266. }
  267. if (!function_exists('hasMany')) {
  268. function hasMany($collection, $field, $model, $searchKey, $insertKey, $where = [] ,$select = '*')
  269. {
  270. $ids = [];
  271. $link = [];
  272. if (!$collection) return [];
  273. $collection = $collection->toArray();
  274. foreach ($collection as $k => $item) {
  275. if (is_array($item[$field])) {
  276. $link[$k] = array_unique($item[$field]);
  277. $ids = array_merge($item[$field], $ids);
  278. } else {
  279. $link[$k] = array_unique(explode(',', $item[$field]));
  280. }
  281. $ids = array_merge($link[$k], $ids);
  282. if (isset($collection[$k][$insertKey])) unset($collection[$k][$insertKey]);
  283. }
  284. $ids = array_filter(array_unique($ids));
  285. if (!count($ids)) {
  286. return $collection;
  287. }
  288. $many = $model::whereIn($searchKey, array_unique($ids))->where($where)->field($select)->select();
  289. if (!$many) return $collection;
  290. $many = $many->toArray();
  291. foreach ($link as $k => $val) {
  292. foreach ($many as $item) {
  293. if (in_array($item[$searchKey], $val)) {
  294. if (!isset($collection[$k][$insertKey])) $collection[$k][$insertKey] = [];
  295. $collection[$k][$insertKey][] = $item;
  296. }
  297. }
  298. }
  299. return $collection;
  300. }
  301. }
  302. if (!function_exists('activeProductSku')) {
  303. //格式活动商品SKU
  304. function activeProductSku($activeData, $type = null)
  305. {
  306. $make = app()->make(\app\common\repositories\store\product\ProductRepository::class);
  307. $price = 0;
  308. $data = [];
  309. foreach($activeData as $key => $value) {
  310. $maxPrice = 0;
  311. $must_price = 0;
  312. $attrValue = [];
  313. if(is_null($value['product'])) continue;
  314. $productSku = $value['productSku'];
  315. $productAttr = $value['product']['attr'];
  316. $productAttrValue = $value['product']['attrValue'];
  317. unset($value['productSku'], $value['product']['attrValue'], $value['product']['attr']);
  318. foreach ($productAttrValue as $attr_value) {
  319. if (!empty($productSku)){
  320. foreach ($productSku as $sk => $sv) {
  321. if ( $sv['unique'] == $attr_value['unique']) {
  322. if ($type == 'discounts') {
  323. unset($attr_value['ot_price'], $attr_value['price']);
  324. $attr_value['ot_price'] = $sv['price'];
  325. $attr_value['price'] = $sv['active_price'];
  326. $_price = bcsub($sv['price'], $sv['active_price'], 2);
  327. if ($value['type']){
  328. $must_price = $must_price > $_price ? $must_price : $_price;
  329. } else {
  330. $maxPrice = $maxPrice > $_price ? $maxPrice : $_price;
  331. }
  332. } else {
  333. $attr_value['productSku'] = $sv;
  334. }
  335. $attrValue[] = $attr_value;
  336. }
  337. }
  338. }
  339. }
  340. $attr = $make->detailAttr($productAttr);
  341. if ($type == 'discounts') {
  342. $sku = $make->detailAttrValue($attrValue, null);
  343. $value['product']['sku'] = $sku;
  344. } else {
  345. $value['product']['attrValue'] = $attrValue;
  346. }
  347. $value['product']['attr'] = $attr;
  348. $price = bcadd($price, bcadd($must_price,$maxPrice,2), 2);
  349. if ($value['type'] == 1) {
  350. array_unshift($data,$value);
  351. }else {
  352. $data[] = $value;
  353. }
  354. }
  355. return compact('data', 'price');
  356. }
  357. }
  358. if (!function_exists('systemConfig')) {
  359. /**
  360. * 获取系统配置
  361. *
  362. * @param string|string[] $key
  363. * @return mixed
  364. * @author xaboy
  365. * @day 2020-05-08
  366. */
  367. function systemConfig($key)
  368. {
  369. return merchantConfig(0, $key);
  370. }
  371. }
  372. if (!function_exists('systemConfigNoCache')) {
  373. /**
  374. * 获取系统配置 不读缓存
  375. *
  376. * @param string|string[] $key
  377. * @return mixed
  378. * @author xaboy
  379. */
  380. function systemConfigNoCache($key)
  381. {
  382. return merchantConfigNoCache(0, $key);
  383. }
  384. }
  385. if (!function_exists('merchantConfigNoCache')) {
  386. /**
  387. * 获取商户配置 不读缓存
  388. *
  389. * @param int $merId
  390. * @param string|string[] $key
  391. * @return mixed
  392. * @author xaboy
  393. */
  394. function merchantConfigNoCache(int $merId, $key)
  395. {
  396. $request = app('request');
  397. $make = app()->make(ConfigValueRepository::class);
  398. if (is_array($key)) {
  399. $_key = [];
  400. $cacheData = [];
  401. foreach ($key as $v) {
  402. if ($request->hasCache($merId, $v)) {
  403. $cacheData[$v] = $request->getCache($merId, $v);
  404. } else {
  405. $_key[] = $v;
  406. }
  407. }
  408. if (!count($_key)) return $cacheData;
  409. $data = $make->more($_key, $merId);
  410. $request->setCache($merId, $data);
  411. $data += $cacheData;
  412. } else {
  413. if ($request->hasCache($merId, $key)) {
  414. $data = $request->getCache($merId, $key);
  415. } else {
  416. $data = $make->get($key, $merId);
  417. $request->setCache($merId, $key, $data);
  418. }
  419. }
  420. return $data;
  421. }
  422. }
  423. if (!function_exists('merchantConfig')) {
  424. /**
  425. * 获取商户配置
  426. *
  427. * @param int $merId
  428. * @param string|string[] $key
  429. * @return mixed
  430. * @author xaboy
  431. * @day 2020-05-08
  432. */
  433. function merchantConfig(int $merId, $key)
  434. {
  435. return app()->make(ConfigValueRepository::class)->getConfig($merId,$key);
  436. }
  437. }
  438. if (!function_exists('getDatesBetweenTwoDays')) {
  439. function getDatesBetweenTwoDays($startDate, $endDate, $md = 'm-d')
  440. {
  441. $dates = [];
  442. if (strtotime($startDate) > strtotime($endDate)) {
  443. //如果开始日期大于结束日期,直接return 防止下面的循环出现死循环
  444. return $dates;
  445. } elseif ($startDate == $endDate) {
  446. //开始日期与结束日期是同一天时
  447. array_push($dates, date($md, strtotime($startDate)));
  448. return $dates;
  449. } else {
  450. array_push($dates, date($md, strtotime($startDate)));
  451. $currentDate = $startDate;
  452. do {
  453. $nextDate = date('Y-m-d', strtotime($currentDate . ' +1 days'));
  454. array_push($dates, date($md, strtotime($currentDate . ' +1 days')));
  455. $currentDate = $nextDate;
  456. } while ($endDate != $currentDate);
  457. return $dates;
  458. }
  459. }
  460. }
  461. if (!function_exists('getStartModelTime')) {
  462. function getStartModelTime(string $section)
  463. {
  464. switch ($section) {
  465. case 'today':
  466. case 'yesterday':
  467. return date('Y-m-d', strtotime($section));
  468. case 'week':
  469. return date('Y-m-d', strtotime('this week'));
  470. case 'month':
  471. return date('Y-m-d', strtotime('first Day of this month'));
  472. case 'year':
  473. return date('Y-m-d', strtotime('this year 1/1'));
  474. case 'quarter':
  475. list($startTime, $endTime) = getMonth();
  476. return $startTime;
  477. case 'lately7':
  478. return date('Y-m-d', strtotime("-7 day"));
  479. case 'lately30':
  480. return date('Y-m-d', strtotime("-30 day"));
  481. default:
  482. if (strstr($section, '-') !== false) {
  483. list($startTime, $endTime) = explode('-', $section);
  484. return date('Y-m-d H:i:s', strtotime($startTime));
  485. }
  486. return date('Y-m-d H:i:s');
  487. }
  488. }
  489. }
  490. if (!function_exists('systemGroupData')) {
  491. /**
  492. * 获取总后台组合数据配置
  493. *
  494. * @param string $key
  495. * @param int|null $page
  496. * @param int|null $limit
  497. * @return array
  498. * @author xaboy
  499. * @day 2020/5/27
  500. */
  501. function systemGroupData(string $key, ?int $page = null, ?int $limit = 10)
  502. {
  503. $make = app()->make(GroupDataRepository::class);
  504. return $make->groupData($key, 0, $page, $limit);
  505. }
  506. }
  507. if (!function_exists('merchantGroupData')) {
  508. /**
  509. * 获取商户后台组合数据配置
  510. *
  511. * @param int $merId
  512. * @param string $key
  513. * @param int|null $page
  514. * @param int|null $limit
  515. * @return array
  516. * @author xaboy
  517. * @day 2020/5/27
  518. */
  519. function merchantGroupData(int $merId, string $key, ?int $page = null, ?int $limit = 10)
  520. {
  521. $make = app()->make(GroupDataRepository::class);
  522. return $make->groupData($key, $merId, $page, $limit);
  523. }
  524. }
  525. if (!function_exists('filter_emoji')) {
  526. // 过滤掉emoji表情
  527. function filter_emoji($str)
  528. {
  529. $str = preg_replace_callback( //执行一个正则表达式搜索并且使用一个回调进行替换
  530. '/./u',
  531. function (array $match) {
  532. return strlen($match[0]) >= 4 ? '' : $match[0];
  533. },
  534. $str
  535. );
  536. return $str;
  537. }
  538. }
  539. if (!function_exists('setHttpType')) {
  540. /**
  541. * 修改 https 和 http 移动到common
  542. * @param string $url 域名
  543. * @param int $type 0 返回https 1 返回 http
  544. * @return string
  545. */
  546. function setHttpType($url, $type = 0)
  547. {
  548. $domainTop = substr($url, 0, 5);
  549. if ($type) {
  550. if ($domainTop == 'https') $url = 'http' . substr($url, 5, strlen($url));
  551. } else {
  552. if ($domainTop != 'https') $url = 'https:' . substr($url, 5, strlen($url));
  553. }
  554. return $url;
  555. }
  556. }
  557. if (!function_exists('remoteImage')) {
  558. /**
  559. * 获取小程序二维码是否生成
  560. * @param $url
  561. * @return array
  562. */
  563. function remoteImage($url)
  564. {
  565. $curl = curl_init();
  566. curl_setopt($curl, CURLOPT_URL, $url);
  567. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  568. $result = curl_exec($curl);
  569. $result = json_decode($result, true);
  570. if (is_array($result)) return ['status' => false, 'msg' => $result['errcode'] . '---' . $result['errmsg']];
  571. return ['status' => true];
  572. }
  573. }
  574. if (!function_exists('image_to_base64')) {
  575. /**
  576. * 获取图片转为base64
  577. * @param string $avatar
  578. * @return bool|string
  579. */
  580. function image_to_base64($avatar = '', $timeout = 9)
  581. {
  582. checkSuffix($avatar);
  583. try {
  584. $url = parse_url($avatar);
  585. if (is_file($file = public_path().$url['path'])) {
  586. return "data:image/jpeg;base64," . base64_encode(file_get_contents($file, 1));
  587. }
  588. $url = $url['host'];
  589. $header = [
  590. 'User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0',
  591. 'Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
  592. 'Accept-Encoding: gzip, deflate, br',
  593. 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
  594. 'Host:' . $url
  595. ];
  596. $dir = pathinfo($url);
  597. $host = $dir['dirname'];
  598. $refer = $host . '/';
  599. $curl = curl_init();
  600. curl_setopt($curl, CURLOPT_REFERER, $refer);
  601. curl_setopt($curl, CURLOPT_URL, $avatar);
  602. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  603. curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
  604. curl_setopt($curl, CURLOPT_ENCODING, 'gzip');
  605. curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
  606. curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
  607. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
  608. $data = curl_exec($curl);
  609. $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  610. curl_close($curl);
  611. if ($code == 200) {
  612. return "data:image/jpeg;base64," . base64_encode($data);
  613. } else {
  614. return false;
  615. }
  616. } catch (Exception $e) {
  617. return false;
  618. }
  619. }
  620. }
  621. if (!function_exists('put_image')) {
  622. /**
  623. * 获取图片转为base64
  624. * @param string $avatar
  625. * @return bool|string
  626. */
  627. function put_image($url, $filename = '')
  628. {
  629. if ($url == '') {
  630. return false;
  631. }
  632. try {
  633. if ($filename == '') {
  634. $ext = pathinfo($url);
  635. if ($ext['extension'] != "jpg" && $ext['extension'] != "png" && $ext['extension'] != "jpeg") {
  636. return false;
  637. }
  638. $filename = time() . "." . $ext['extension'];
  639. }
  640. //文件保存路径
  641. ob_start();
  642. readfile($url);
  643. $img = ob_get_contents();
  644. ob_end_clean();
  645. $path = 'public/uploads/qrcode';
  646. $fp2 = fopen($path . '/' . $filename, 'a');
  647. fwrite($fp2, $img);
  648. fclose($fp2);
  649. return $path . '/' . $filename;
  650. } catch (Exception $e) {
  651. return false;
  652. }
  653. }
  654. }
  655. if (!function_exists('path_to_url')) {
  656. /**
  657. * 路径转url路径
  658. * @param $path
  659. * @return string
  660. */
  661. function path_to_url($path)
  662. {
  663. return trim(str_replace(DIRECTORY_SEPARATOR, '/', $path), '.');
  664. }
  665. }
  666. if (!function_exists('tidy_url')) {
  667. /**
  668. * 路径转url路径
  669. * @param $url
  670. * @param int $http
  671. * @param string $site
  672. * @return string
  673. */
  674. function tidy_url($url, $http = null, $site = null)
  675. {
  676. if (!$site) {
  677. $site = systemConfig('site_url');
  678. }
  679. $url = path_to_url($url);
  680. if (strpos($url, 'http') === false)
  681. $url = rtrim($site, '/') . '/' . ltrim($url, '/');
  682. if (is_null($http)) {
  683. $http = (parse_url($site)['scheme'] ?? '') == 'https' ? 0 : 1;
  684. }
  685. $url = set_http_type($url, $http);
  686. return $url;
  687. }
  688. }
  689. if (!function_exists('curl_file_exist')) {
  690. /**
  691. * CURL 检测远程文件是否在
  692. * @param $url
  693. * @return bool
  694. */
  695. function curl_file_exist($url)
  696. {
  697. $ch = curl_init();
  698. try {
  699. curl_setopt($ch, CURLOPT_URL, $url);
  700. curl_setopt($ch, CURLOPT_HEADER, 1);
  701. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  702. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
  703. $contents = curl_exec($ch);
  704. if (preg_match("/404/", $contents)) return false;
  705. if (preg_match("/403/", $contents)) return false;
  706. return true;
  707. } catch (Exception $e) {
  708. return false;
  709. }
  710. }
  711. }
  712. if (!function_exists('set_http_type')) {
  713. /**
  714. * 修改 https 和 http
  715. * @param string $url 域名
  716. * @param int $type 0 返回https 1 返回 http
  717. * @return string
  718. */
  719. function set_http_type($url, $type = 0)
  720. {
  721. $domainTop = substr($url, 0, 5);
  722. if ($type) {
  723. if ($domainTop == 'https') $url = 'http' . substr($url, 5, strlen($url));
  724. } else {
  725. if ($domainTop != 'https') $url = 'https:' . substr($url, 5, strlen($url));
  726. }
  727. return $url;
  728. }
  729. }
  730. if (!function_exists('setSharePoster')) {
  731. /**
  732. * 生成分享二维码图片
  733. * @param array $config
  734. * @param $path
  735. * @return array|bool|string
  736. * @throws Exception
  737. */
  738. function setSharePoster($config, $path)
  739. {
  740. $imageDefault = array(
  741. 'left' => 0,
  742. 'top' => 0,
  743. 'right' => 0,
  744. 'bottom' => 0,
  745. 'width' => 100,
  746. 'height' => 100,
  747. 'opacity' => 100
  748. );
  749. $textDefault = array(
  750. 'text' => '',
  751. 'left' => 0,
  752. 'top' => 0,
  753. 'fontSize' => 32, //字号
  754. 'fontColor' => '255,255,255', //字体颜色
  755. 'angle' => 0,
  756. );
  757. $background = $config['background']; //海报最底层得背景
  758. if (substr($background, 0, 1) === '/') {
  759. $background = substr($background, 1);
  760. }
  761. $backgroundInfo = getimagesize($background);
  762. $background = imagecreatefromstring(file_get_contents($background));
  763. $backgroundWidth = $backgroundInfo[0]; //背景宽度
  764. $backgroundHeight = $backgroundInfo[1]; //背景高度
  765. $imageRes = imageCreatetruecolor($backgroundWidth, $backgroundHeight);
  766. $color = imagecolorallocate($imageRes, 0, 0, 0);
  767. imagefill($imageRes, 0, 0, $color);
  768. imagecopyresampled($imageRes, $background, 0, 0, 0, 0, imagesx($background), imagesy($background), imagesx($background), imagesy($background));
  769. if (!empty($config['image'])) {
  770. foreach ($config['image'] as $key => $val) {
  771. $val = array_merge($imageDefault, $val);
  772. $info = getimagesize($val['url']);
  773. $function = 'imagecreatefrom' . image_type_to_extension($info[2], false);
  774. if ($val['stream']) {
  775. $info = getimagesizefromstring($val['url']);
  776. $function = 'imagecreatefromstring';
  777. }
  778. $res = $function($val['url']);
  779. $resWidth = $info[0];
  780. $resHeight = $info[1];
  781. $canvas = imagecreatetruecolor($val['width'], $val['height']);
  782. imagefill($canvas, 0, 0, $color);
  783. imagecopyresampled($canvas, $res, 0, 0, 0, 0, $val['width'], $val['height'], $resWidth, $resHeight);
  784. $val['left'] = $val['left'] < 0 ? $backgroundWidth - abs($val['left']) - $val['width'] : $val['left'];
  785. $val['top'] = $val['top'] < 0 ? $backgroundHeight - abs($val['top']) - $val['height'] : $val['top'];
  786. imagecopymerge($imageRes, $canvas, $val['left'], $val['top'], $val['right'], $val['bottom'], $val['width'], $val['height'], $val['opacity']); //左,上,右,下,宽度,高度,透明度
  787. }
  788. }
  789. if (isset($config['text']) && !empty($config['text'])) {
  790. foreach ($config['text'] as $key => $val) {
  791. $val = array_merge($textDefault, $val);
  792. list($R, $G, $B) = explode(',', $val['fontColor']);
  793. $fontColor = imagecolorallocate($imageRes, $R, $G, $B);
  794. $val['left'] = $val['left'] < 0 ? $backgroundWidth - abs($val['left']) : $val['left'];
  795. $val['top'] = $val['top'] < 0 ? $backgroundHeight - abs($val['top']) : $val['top'];
  796. imagettftext($imageRes, $val['fontSize'], $val['angle'], $val['left'], $val['top'], $fontColor, $val['fontPath'], $val['text']);
  797. }
  798. }
  799. ob_start();
  800. imagejpeg($imageRes);
  801. imagedestroy($imageRes);
  802. $res = ob_get_contents();
  803. ob_end_clean();
  804. $key = substr(md5(rand(0, 9999)), 0, 5) . date('YmdHis') . rand(0, 999999) . '.jpg';
  805. $uploadType = (int)systemConfig('upload_type') ?: 1;
  806. $upload = UploadService::create($uploadType);
  807. $res = $upload->to($path)->validate()->stream($res, $key);
  808. if ($res === false) {
  809. return $upload->getError();
  810. } else {
  811. $info = $upload->getUploadInfo();
  812. $info['image_type'] = $uploadType;
  813. return $info;
  814. }
  815. }
  816. }
  817. if (!function_exists('getTimes')) {
  818. function getTimes()
  819. {
  820. $dates = [];
  821. for ($i = 0; $i <= 24; $i++) {
  822. for ($j = 0; $j < 60; $j++) {
  823. $dates[] = sprintf('%02.d', $i) . ':' . sprintf('%02.d', $j);
  824. }
  825. }
  826. return $dates;
  827. }
  828. }
  829. if (!function_exists('monday')) {
  830. /**
  831. * 获取周一
  832. *
  833. * @param null $time
  834. * @return false|string
  835. * @author xaboy
  836. * @day 2020/6/22
  837. */
  838. function monday($time = null)
  839. {
  840. return date('Y-m-d', strtotime('Sunday -6 day', $time ?: time()));
  841. }
  842. }
  843. if (!function_exists('orderLock')) {
  844. /**
  845. * @param string $name
  846. * @return Lock
  847. * @author xaboy
  848. * @day 2020/8/25
  849. */
  850. function makeLock($name = 'default'): Lock
  851. {
  852. return $GLOBALS['_swoole_order_lock'][$name];
  853. }
  854. }
  855. if (!function_exists('get_crmeb_version')) {
  856. /**
  857. * 获取CRMEB系统版本号
  858. * @param string $default
  859. * @return string
  860. */
  861. function get_crmeb_version($default = 'v1.0.0')
  862. {
  863. try {
  864. $version = parse_ini_file(app()->getRootPath() . '.version');
  865. return $version['version'] ?? $default;
  866. } catch (Throwable $e) {
  867. return $default;
  868. }
  869. }
  870. }
  871. if (!function_exists('get_crmeb_version_code')) {
  872. /**
  873. * 获取CRMEB系统版本号
  874. * @param string $default
  875. * @return string
  876. */
  877. function get_crmeb_version_code($default = '1.7.2')
  878. {
  879. try {
  880. $version = parse_ini_file(app()->getRootPath() . '.version');
  881. return $version['code'] ?? $default;
  882. } catch (Throwable $e) {
  883. return $default;
  884. }
  885. }
  886. }
  887. if (!function_exists('update_crmeb_compiled')) {
  888. /**
  889. * 获取CRMEB系统版本号
  890. * @param string $default
  891. * @return string
  892. */
  893. function update_crmeb_compiled($default = 'v1.0.0')
  894. {
  895. $compiled = [
  896. '7.1' => 'compiled71',
  897. '7.2' => 'compiled72',
  898. '7.3' => 'compiled73',
  899. '7.4' => 'compiled74',
  900. ];
  901. $phpv = @phpversion();
  902. $phpvs = substr($phpv, 0, 3);
  903. $key = $compiled[$phpvs] ?? '';
  904. if (!$key)
  905. return false;
  906. $root = app()->getRootPath();
  907. $compiledPath = $root . 'install/compiled';
  908. $file = $root . 'install/compiled/' . $key . '.zip';
  909. $toPath = $root . 'crmeb/basic';
  910. $toConfigPath = $root . 'config/crmeb.php';
  911. $demoImage = $root.'public/uploads'.'images.zip';
  912. try {
  913. if (is_file($file)) {
  914. $zip = new ZipArchive();
  915. if ($zip->open($file) === true) {
  916. $zip->extractTo($compiledPath . '/');
  917. $zip->close();
  918. }
  919. if (is_dir($compiledPath . '/basic')) {
  920. if (is_dir($toPath) || mkdir($toPath, 0777) || is_dir($toPath)) {
  921. foreach (glob($compiledPath . '/basic/*') as $item) {
  922. @rename($item, $toPath . '/' . pathinfo($item, PATHINFO_BASENAME));
  923. }
  924. }
  925. @rmdir($compiledPath . '/basic');
  926. }
  927. if (is_file($compiledPath . '/crmeb.php')) {
  928. @rename($compiledPath . '/crmeb.php', $toConfigPath);
  929. }
  930. }
  931. } catch (\Exception $exception) {
  932. return false;
  933. }
  934. try{
  935. if (is_file($demoImage)) {
  936. $zip = new ZipArchive();
  937. if ($zip->open($demoImage) === true) {
  938. $zip->extractTo($compiledPath . '/');
  939. $zip->close();
  940. }
  941. }
  942. }catch (\Exception $exception) {
  943. }
  944. return true;
  945. }
  946. }
  947. if (!function_exists('attr_format')) {
  948. /**
  949. * 格式化属性
  950. * @param $arr
  951. * @return array
  952. */
  953. function attr_format($arr): array
  954. {
  955. $len = count($arr);
  956. $title = array_column($arr, 'value');
  957. $result = [];
  958. if ($len > 0) {
  959. if ($len > 1) {
  960. $result = $arr[0]['detail'];
  961. for ($i = 0; $i < $len - 1; $i++) {
  962. $temp = $result;
  963. $result = [];
  964. foreach ($temp as $item) {
  965. foreach ($arr[$i + 1]['detail'] as $datum) {
  966. $result[] = trim($item) . ',' . trim($datum);
  967. }
  968. }
  969. }
  970. } else {
  971. foreach ($arr[0]['detail'] as $item) {
  972. $result[] = trim($item);
  973. }
  974. }
  975. }
  976. return [$result, $title];
  977. }
  978. }
  979. if (!function_exists('filter_emoji')) {
  980. //过滤掉emoji表情
  981. function filter_emoji($str)
  982. {
  983. $str = preg_replace_callback('/./u', function (array $match) {
  984. return strlen($match[0]) >= 4 ? '' : $match[0];
  985. }, $str);
  986. return $str;
  987. }
  988. }
  989. /*
  990. * 腾讯地图转换百度地图 GCJ02 转 BD09
  991. * 中国正常GCJ02坐标---->百度地图BD09坐标
  992. * 腾讯地图/高德地图用的也是GCJ02坐标
  993. * @param double $lat 纬度
  994. * @param double $lng 经度
  995. */
  996. if (!function_exists('gcj02ToBd09')) {
  997. function gcj02ToBd09($lng, $lat)
  998. {
  999. $x_pi = 3.14159265358979324 * 3000.0 / 180.0;
  1000. $x = $lng;
  1001. $y = $lat;
  1002. $z = sqrt($x * $x + $y * $y) - 0.00002 * sin($y * $x_pi);
  1003. $theta = atan2($y, $x) - 0.000003 * cos($x * $x_pi);
  1004. $lng = $z * cos($theta) + 0.0065;
  1005. $lat = $z * sin($theta) + 0.006;
  1006. return [$lng,$lat];
  1007. }
  1008. }
  1009. if (!function_exists('lbs_address')) {
  1010. function lbs_address($region, $address)
  1011. {
  1012. $locationOption = new \Joypack\Tencent\Map\Bundle\AddressOption(systemConfig('tx_map_key'));
  1013. $locationOption->setAddress($address);
  1014. $locationOption->setRegion($region);
  1015. $location = new \Joypack\Tencent\Map\Bundle\Address($locationOption);
  1016. $res = $location->request();
  1017. if ($res->error) {
  1018. throw new \think\exception\ValidateException($res->error);
  1019. }
  1020. if ($res->status) {
  1021. throw new \think\exception\ValidateException($res->message);
  1022. }
  1023. if (!$res->result) {
  1024. throw new \think\exception\ValidateException('获取失败');
  1025. }
  1026. return $res->result;
  1027. }
  1028. }
  1029. if (!function_exists('aj_captcha_check_one')) {
  1030. /**
  1031. * 验证滑块1次验证
  1032. * @param string $token
  1033. * @param string $pointJson
  1034. * @return bool
  1035. */
  1036. function aj_captcha_check_one(string $captchaType, string $token, string $pointJson)
  1037. {
  1038. aj_get_serevice($captchaType)->check($token, $pointJson);
  1039. return true;
  1040. }
  1041. }
  1042. if (!function_exists('aj_captcha_check_two')) {
  1043. /**
  1044. * 验证滑块2次验证
  1045. * @param string $token
  1046. * @param string $pointJson
  1047. * @return bool
  1048. */
  1049. function aj_captcha_check_two(string $captchaType, string $captchaVerification )
  1050. {
  1051. aj_get_serevice($captchaType)->verificationByEncryptCode($captchaVerification);
  1052. return true;
  1053. }
  1054. }
  1055. if (!function_exists('aj_captcha_create')) {
  1056. /**
  1057. * 创建验证码
  1058. * @return array
  1059. */
  1060. function aj_captcha_create(string $captchaType)
  1061. {
  1062. return aj_get_serevice($captchaType)->get();
  1063. }
  1064. }
  1065. if (!function_exists('aj_get_serevice')) {
  1066. function aj_get_serevice(string $captchaType)
  1067. {
  1068. $config = \think\facade\Config::get('ajcaptcha');
  1069. switch ($captchaType) {
  1070. case "clickWord":
  1071. $service = new \Fastknife\Service\ClickWordCaptchaService($config);
  1072. // $service = new \crmeb\services\BlockPuzzleCaptchaService($config);
  1073. break;
  1074. case "blockPuzzle":
  1075. $service = new \Fastknife\Service\BlockPuzzleCaptchaService($config);
  1076. //$service = new \crmeb\services\BlockPuzzleCaptchaService($config);
  1077. break;
  1078. default:
  1079. throw new \think\exception\ValidateException('captchaType参数不正确:'.$captchaType);
  1080. }
  1081. return $service;
  1082. }
  1083. }
  1084. if (!function_exists('checkSuffix')) {
  1085. function checkSuffix($data)
  1086. {
  1087. $suffix = \think\facade\Config::get('upload.fileExt');
  1088. if (is_array($data)){
  1089. foreach ($data as $datum) {
  1090. if (strpos($datum,'phar://') !== false)
  1091. throw new \think\exception\ValidateException('操作失败');
  1092. $result = pathinfo($datum);
  1093. if (isset($result['extension']) && !in_array($result['extension'],$suffix)) {
  1094. throw new \think\exception\ValidateException('文件后缀不允许');
  1095. }
  1096. }
  1097. } else {
  1098. if (strpos($data,'phar://') !== false )
  1099. throw new \think\exception\ValidateException('操作失败');
  1100. $result = pathinfo($data);
  1101. if (isset($result['extension']) && !in_array($result['extension'],$suffix)) {
  1102. throw new \think\exception\ValidateException('文件后缀不允许');
  1103. }
  1104. }
  1105. return ;
  1106. }
  1107. }
  1108. if (!function_exists('strUcwords')) {
  1109. function strUcwords($str)
  1110. {
  1111. return str_replace(' ', '', ucwords(str_replace('_', ' ', $str)));
  1112. }
  1113. }
  1114. if(!function_exists('getThumbWaterImage')){
  1115. /**
  1116. * 获取缩略图水印文件
  1117. * @param string $filePath 文件路径
  1118. * @param string $fileName 文件名称
  1119. * @param string $type 大中小 ['big', 'mid', 'small'] / all
  1120. * @param string $rename 重命名字段,也就是将获取的图片以新的字段名添加到列表
  1121. * @return mixed
  1122. */
  1123. function getThumbWaterImage($list,array $fields = ['image'], string $type = 'all', $fileName = '', $rename = '')
  1124. {
  1125. $upload_type = systemConfig('upload_type') ?: 1;
  1126. $image_thumb_status = systemConfig('image_thumb_status');
  1127. if ($image_thumb_status) {
  1128. $upload = UploadService::create($upload_type);
  1129. $domain = app()->make(StorageRepository::class)->domains($upload_type);
  1130. foreach ($list as &$item){
  1131. foreach ($fields as $field) {
  1132. $f = $rename ? $rename : $field ;
  1133. if(is_array($item[$field]) && !empty($item[$field])){
  1134. $imageList = $item[$field];
  1135. $item[$f] = [];
  1136. foreach ($imageList as $filePath){
  1137. $host = parse_url($filePath);
  1138. if (isset($host['scheme']) && in_array($host['scheme'].'://'.$host['host'], $domain) ) {
  1139. $thumbResult = $upload->thumb($filePath,$fileName,$type);
  1140. $item[$f][] = $thumbResult[$type] ?: $item[$field];
  1141. } else {
  1142. $item[$f][] = $filePath;
  1143. }
  1144. }
  1145. }else{
  1146. $filePath = $item[$field];
  1147. $host = parse_url($filePath);
  1148. if (isset($host['scheme']) && in_array($host['scheme'].'://'.$host['host'], $domain)) {
  1149. $thumbResult = $upload->thumb($filePath, $fileName, $type);
  1150. $item[$f] = $thumbResult[$type] ?: $item[$field];
  1151. } else {
  1152. $item[$f] = $filePath;
  1153. }
  1154. }
  1155. }
  1156. }
  1157. }
  1158. return $list;
  1159. }
  1160. }
  1161. if(!function_exists('get_extension_info')){
  1162. /**
  1163. * @param $user 用户信息
  1164. * @return array
  1165. */
  1166. function get_extension_info($user = null)
  1167. {
  1168. /**
  1169. * 是否开启分销
  1170. * 分销方式
  1171. * 是否为分销员
  1172. * 是否内购
  1173. */
  1174. $config = systemConfig(['extension_status','promoter_type','extension_self','extension_pop']);
  1175. $extension_status = $config['extension_status'];
  1176. $promoter_type = $config['promoter_type'];
  1177. $isPromoter = 0;//是否分销员
  1178. $isSelfBuy = 0;//是否内购
  1179. $promoter_switch = 1;
  1180. if ($extension_status && $user) {
  1181. if ($user) {
  1182. $promoter_switch = $user['promoter_switch'] ?? 0;
  1183. }
  1184. if ($promoter_switch) {
  1185. $isPromoter = ($user['is_promoter'] ?? 0) ? 1 : 0;
  1186. //如果需要人人分销不设置为每个人都是 is_promoter = 1 ; 就开启这里
  1187. //if (!$isPromoter) {
  1188. // $isPromoter = systemConfig('promoter_type') == 2 ? 1 : 0;
  1189. //}
  1190. $isSelfBuy = $isPromoter && systemConfig('extension_self') ? 1 : 0;//是否内购
  1191. }
  1192. }
  1193. // 佣金显示弹框开关
  1194. //0:全部可见
  1195. //1:推广员可见
  1196. //2:非推广员可见
  1197. //3:关闭
  1198. $extension_pop = 0;
  1199. if ($extension_status) {
  1200. $extension_pop = 1;
  1201. switch ($config['extension_pop']) {
  1202. case 1:
  1203. $extension_pop = $isPromoter ? 1 : 0;
  1204. break;
  1205. case 2:
  1206. $extension_pop = $isPromoter ? 0 : 1;
  1207. break;
  1208. case 3:
  1209. $extension_pop = 0;
  1210. break;
  1211. }
  1212. }
  1213. return compact('isPromoter','isSelfBuy','extension_status','promoter_type','extension_pop');
  1214. }
  1215. }
  1216. if (!function_exists('filter_str')) {
  1217. /**
  1218. * 过滤字符串敏感字符
  1219. * @param $str
  1220. * @return array|mixed|string|string[]|null
  1221. */
  1222. function filter_str($str)
  1223. {
  1224. $rules = [
  1225. '/\.\./', // 禁用包含 ../ 的参数
  1226. '/\<\?/', // 禁止 php 脚本出现
  1227. '/\bor\b.*=.*/i', // 匹配 'or 1=1',防止 SQL 注入(注意边界词 \b 和不区分大小写 i 修饰符)
  1228. '/(select[\s\S]*?)(from|limit)/i', // 防止 SQL 注入
  1229. '/(union[\s\S]*?select)/i', // 防止 SQL 注入
  1230. '/(having|updatexml|extractvalue)/i', // 防止 SQL 注入
  1231. '/sleep\((\s*)(\d*)(\s*)\)/i', // 防止 SQL 盲注
  1232. '/benchmark\((.*)\,(.*)\)/i', // 防止 SQL 盲注
  1233. '/base64_decode\(/i', // 防止 SQL 变种注入
  1234. '/(?:from\W+information_schema\W)/i', // 注意这里的 (?:...) 是不合法的,应该是 (?:...) 表示非捕获组,但通常我们不需要这个
  1235. '/(?:current_|user|database|schema|connection_id)\s*\(/i', // 防止 SQL 注入(注意去掉了不必要的 (?:...))
  1236. '/(?:etc\/\W*passwd)/i', // 防止窥探 Linux 用户信息
  1237. '/into(\s+)(?:dump|out)file\s*/i', // 禁用 MySQL 导出函数
  1238. '/group\s+by.+\(/i', // 防止 SQL 注入
  1239. '/(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(/i', // 禁用 webshell 相关某些函数
  1240. '/(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/\//i', // 防止一些协议攻击(注意协议后的三个斜杠)
  1241. '/\$_(GET|POST|COOKIE|FILES|SESSION|ENV|GLOBALS|SERVER)\[/i', // 禁用一些内置变量,注意 PHP 变量名通常是大写的
  1242. '/<(iframe|script|body|img|layer|div|meta|style|base|object|input)/i', // 防止 XSS 标签植入
  1243. '/(onmouseover|onerror|onload|onclick)\=/i', // 防止 XSS 事件植入
  1244. '/\|\|.*?(?:ls|pwd|whoami|ll|ifconfig|ipconfig|&&|chmod|cd|mkdir|rmdir|cp|mv)/i', // 防止执行 shell(注意去掉了不合适的 ifconfog)
  1245. '/\sand\s+.*=.*/i' // 匹配 and 1=1
  1246. ];
  1247. if (filter_var($str, FILTER_VALIDATE_URL)) {
  1248. $url = parse_url($str);
  1249. if (!isset($url['scheme'])) return $str;
  1250. $host = $url['scheme'] . '://' . $url['host'];
  1251. $str = $host . preg_replace($rules, '', str_replace($host, '', $str));
  1252. } else {
  1253. $str = preg_replace($rules, '', $str);
  1254. }
  1255. return $str;
  1256. }
  1257. }
  1258. if(!function_exists('generateTimeRanges')) {
  1259. /**
  1260. * 生成时间段数组
  1261. *
  1262. * @param string $startTime
  1263. * @param string $endTime
  1264. * @param integer $intervalMinutes
  1265. * @return array
  1266. */
  1267. function generateTimeRanges(string $startTime, string $endTime, int $intervalMinutes = 10) : array
  1268. {
  1269. // 验证时间间隔
  1270. if ($intervalMinutes < 10) {
  1271. throw new \think\exception\ValidateException('时间间隔必须大于等于10分钟');
  1272. }
  1273. // 转换起止时间为时间戳
  1274. $startTimestamp = strtotime($startTime);
  1275. $endTimestamp = strtotime($endTime);
  1276. if ($startTimestamp >= $endTimestamp) {
  1277. throw new \think\exception\ValidateException('起始时间必须小于结束时间');
  1278. }
  1279. // 时间间隔转换为秒
  1280. $intervalSeconds = $intervalMinutes * 60;
  1281. // 初始化时间段数组,生成时间段
  1282. $timeRanges = [];
  1283. for ($current = $startTimestamp; $current < $endTimestamp; $current += $intervalSeconds) {
  1284. // 下一个时间段的开始时间
  1285. $next = $current + $intervalSeconds;
  1286. // 处理最后一个时间段
  1287. if ($next > $endTimestamp) {
  1288. $next = $endTimestamp;
  1289. }
  1290. // 添加时间段到数组中
  1291. $timeRanges[] = [
  1292. 'start' => date('H:i', $current),
  1293. 'end' => date('H:i', $next)
  1294. ];
  1295. }
  1296. return $timeRanges;
  1297. }
  1298. }