Utils.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: wangchen
  5. * Date: 2019-05-07
  6. * Time: 15:22
  7. */
  8. namespace App\Libs;
  9. use App\Cache\CacheKeys;
  10. use Hashids;
  11. use App\Exceptions\ApiException;
  12. use PhpAmqpLib\Connection\AMQPStreamConnection;
  13. use PhpAmqpLib\Message\AMQPMessage;
  14. class Utils
  15. {
  16. /**
  17. * 异常报错
  18. * @param $errorData
  19. * @throws ApiException
  20. */
  21. public static function throwError($errorData)
  22. {
  23. // 分解错误码、错误信息
  24. $arr = explode(':', (string)$errorData);
  25. $code = (int)$arr[0];
  26. $msg = (string)$arr[1];
  27. throw new ApiException($code, $msg);
  28. }
  29. /**
  30. * 解码加密id
  31. * @param $idStr
  32. * @return int
  33. */
  34. public static function getDecodeId($idStr)
  35. {
  36. if (!is_numeric($idStr)) {
  37. $idArr = Hashids::decode($idStr);
  38. $id = isset($idArr[0]) ? (int)$idArr[0] : 0;
  39. } else {
  40. $id = $idStr;
  41. }
  42. return $id;
  43. }
  44. /**
  45. * 加密id
  46. * @param $id
  47. * @return mixed
  48. */
  49. public static function getEncodeId($id)
  50. {
  51. return Hashids::encode($id);
  52. }
  53. /**
  54. * 加密批量bid
  55. * @param $bids
  56. * @return array
  57. */
  58. public static function getEncodeIds($bids)
  59. {
  60. return array_map(function ($bid) {
  61. return Hashids::encode($bid);
  62. }, $bids);
  63. }
  64. /**
  65. * 审核状态判断,true为审核状态,false默认
  66. * @param $package
  67. * @param $brand
  68. * @param $codeVersion
  69. * @return bool
  70. */
  71. public static function checkIsAudit($package, $brand, $codeVersion): bool
  72. {
  73. $audit = getProp(config('audit'), $package, []);
  74. if ($audit && $brand === getProp($audit, 'brand') && $codeVersion === getProp($audit, 'codeVersion')) {
  75. return true;
  76. }
  77. return false;
  78. }
  79. /**
  80. * 获取redis的key
  81. * @param $keyStr // 例如:wap.rank_page
  82. * @param array $args // 例如:[10, 2000]
  83. *
  84. * Utils::getCacheKey('wap.rank_page', [10, 2000])
  85. * Utils::getCacheKey('promotion.setStatus')
  86. * Utils::getCacheKey('promotion.infos', [2])
  87. *
  88. * @return string
  89. */
  90. public static function getCacheKey($keyStr, $args = [])
  91. {
  92. $stdStr = array_get(CacheKeys::$all, $keyStr, '');
  93. if ($args) {
  94. $stdStr = sprintf($stdStr, ...$args);
  95. }
  96. return $stdStr;
  97. }
  98. /**
  99. * 展示友好数字
  100. * @param $num
  101. * @return string
  102. */
  103. public static function showNiceNumber($num)
  104. {
  105. if ($num >= 10000) {
  106. $num = sprintf('%.1f', round($num / 10000 * 100) / 100) . '万';
  107. } elseif ($num >= 1000) {
  108. $num = sprintf('%.1f', round($num / 1000 * 100) / 100) . '千';
  109. }
  110. return $num;
  111. }
  112. /**
  113. * 根据日期获得这周的周一
  114. * @param $date
  115. * @param int $d
  116. * @param string $format
  117. * @return false|string
  118. */
  119. public static function firstOfWeek($date, $d = 0, $format = 'Ymd')
  120. {
  121. $now = strtotime($date) - $d * 86400; //当时的时间戳
  122. $number = date("w", $now); //当时是周几
  123. $number = $number == 0 ? 7 : $number; //如遇周末,将0换成7
  124. $diff_day = $number - 1; //求到周一差几天
  125. return date($format, $now - ($diff_day * 60 * 60 * 24));
  126. }
  127. /**
  128. * 老原创的签名
  129. * @param $time
  130. * @return string
  131. */
  132. public static function getOldYcSign($time): string
  133. {
  134. $privateKey = env('EXTERNAL_PRIVATE_KEY');
  135. return md5(md5($time . $privateKey) . $privateKey);
  136. }
  137. /**
  138. * @param array $data
  139. * @param array $colHeaders
  140. * @param bool $asString
  141. * @return bool|string
  142. */
  143. public static function toCSV(array $data, array $colHeaders = array(), $asString = false)
  144. {
  145. $stream = $asString ? fopen('php://temp/maxmemory', 'wb+') : fopen('php://output', 'wb');
  146. if (!empty($colHeaders)) {
  147. fputcsv($stream, $colHeaders);
  148. }
  149. foreach ($data as $record) {
  150. fputcsv($stream, $record);
  151. }
  152. if ($asString) {
  153. rewind($stream);
  154. $returnVal = stream_get_contents($stream);
  155. fclose($stream);
  156. return $returnVal;
  157. }
  158. fclose($stream);
  159. return true;
  160. }
  161. /**
  162. * 设备信息
  163. * @return string
  164. */
  165. public static function getDeviceType(): string
  166. {
  167. //全部变成小写字母
  168. $agent = strtolower(getProp($_SERVER, 'HTTP_USER_AGENT'));
  169. $type = 'other';
  170. //分别进行判断
  171. if (strpos($agent, 'iphone') || strpos($agent, 'ipad')) {
  172. $type = 'ios';
  173. }
  174. if (strpos($agent, 'android')) {
  175. $type = 'android';
  176. }
  177. return $type;
  178. }
  179. /**
  180. * 是否在微信内打卡
  181. * @return bool
  182. */
  183. public static function isOpenedInWechat(): bool
  184. {
  185. //全部变成小写字母
  186. $agent = strtolower($_SERVER['HTTP_USER_AGENT']);
  187. //判断
  188. if (strpos($agent, 'micromessenger')) {
  189. return true;
  190. }
  191. return false;
  192. }
  193. /**
  194. * 组装meta数据
  195. * @param $page
  196. * @param $total
  197. * @param int $pageSize
  198. * @return array
  199. */
  200. public static function buildMeta($page, $total, $pageSize = 15): array
  201. {
  202. $lastPage = (int)ceil($total / $pageSize);
  203. return [
  204. 'current_page' => (int)$page,
  205. 'next_page' => ++$page,
  206. 'last_page' => $lastPage ?? 1,
  207. 'per_page' => (int)$pageSize,
  208. 'total' => (int)$total,
  209. 'next_page_url' => '',
  210. 'prev_page_url' => ''
  211. ];
  212. }
  213. /**
  214. * 随机书币
  215. * @param $coin
  216. * @param $num
  217. * @return array|bool
  218. * @throws \Exception
  219. */
  220. public static function getRandomCoin($coin, $num)
  221. {
  222. $result = [];
  223. if ($coin < $num || $coin < 1 || $num < 1) {
  224. return $result;
  225. }
  226. // 计算平均值
  227. $rem = $coin % $num;
  228. $mean = ($coin - $rem) / $num;
  229. // 水平分割
  230. for ($i = 0; $i < $num; $i++) {
  231. $result[$i] = $mean;
  232. }
  233. // 水平分割后将取模多余部分分配给第一个红包
  234. $result[0] += $rem;
  235. // 随机分配金额
  236. for ($i = 0; $i < $num; $i++) {
  237. $r1 = random_int(0, $num - 1);
  238. $r2 = random_int(0, $num - 1);
  239. $per = random_int(1, 99) / 100;
  240. // 随机金额
  241. $mon = $result[$r1] - floor($result[$r1] * $per);
  242. if ($result[$r1] - $mon > 0) {
  243. // 减去随机金额
  244. $result[$r1] -= $mon;
  245. // 添加随机金额
  246. $result[$r2] += $mon;
  247. }
  248. }
  249. return $result;
  250. }
  251. /**
  252. * 将数据推送到rabbitMq
  253. * 参考:https://www.vckai.com/xiao-xi-dui-lie-rabbitmq-san-phpde-shi-yong-shi-li
  254. * @param $messageBody
  255. * @param string $queue
  256. * @return bool
  257. */
  258. public static function pushDataToAppSyncMq($messageBody, $queue = 'ycsd_sync'): bool
  259. {
  260. $exchange = $queue; // 交换器
  261. $routing_key = $queue;
  262. try {
  263. $host = env('RABBITMQ_HOST');
  264. $port = env('RABBITMQ_PORT');
  265. $user = env('RABBITMQ_LOGIN');
  266. $passwd = env('RABBITMQ_PASSWORD');
  267. $vhost = env('RABBITMQ_VHOST');
  268. $connection = new AMQPStreamConnection($host, $port, $user, $passwd, $vhost);
  269. // 创建通道
  270. $channel = $connection->channel();
  271. /**
  272. * 创建队列(Queue)
  273. * name: hello // 队列名称
  274. * passive: false // 如果用户仅仅想查询某一个队列是否已存在,如果不存在,不想建立该队列,仍然可以调用queue.declare,
  275. * 只不过需要将参数passive设为true,传给queue.declare,如果该队列已存在,则会返回true;
  276. * 如果不存在,则会返回Error,但是不会创建新的队列。
  277. * durable: true // 是不持久化, true ,表示持久化,会存盘,服务器重启仍然存在,false,非持久化
  278. * exclusive: false // 是否排他,指定该选项为true则队列只对当前连接有效,连接断开后自动删除
  279. * auto_delete: false // 是否自动删除,当最后一个消费者断开连接之后队列是否自动被删除
  280. */
  281. $channel->queue_declare($queue, true, false, false, false);
  282. /**
  283. * 创建交换机(Exchange)
  284. * name: vckai_exchange// 交换机名称
  285. * type: direct // 交换机类型,分别为direct/fanout/topic,参考另外文章的Exchange Type说明。
  286. * passive: false // 如果设置true存在则返回OK,否则就报错。设置false存在返回OK,不存在则自动创建
  287. * durable: false // 是否持久化,设置false是存放到内存中的,RabbitMQ重启后会丢失
  288. * auto_delete: false // 是否自动删除,当最后一个消费者断开连接之后队列是否自动被删除
  289. */
  290. // $channel->exchange_declare('', 'direct', true, false, false);
  291. // 绑定消息交换机和队列
  292. // $channel->queue_bind($queue, $exchange);
  293. /**
  294. * 创建AMQP消息类型
  295. * delivery_mode 消息是否持久化
  296. * AMQPMessage::DELIVERY_MODE_NON_PERSISTENT 不持久化
  297. * AMQPMessage::DELIVERY_MODE_PERSISTENT 持久化
  298. */
  299. $msg = new AMQPMessage($messageBody, ['delivery_mode' => AMQPMessage::DELIVERY_MODE_NON_PERSISTENT]);
  300. /**
  301. * 发送消息
  302. * msg: $msg // AMQP消息内容
  303. * exchange: vckai_exchange // 交换机名称
  304. * queue: hello // 队列名称
  305. */
  306. $channel->basic_publish($msg, '', $routing_key);
  307. /**
  308. * 关闭链接
  309. */
  310. $channel->close();
  311. $connection->close();
  312. } catch (\Exception $e) {
  313. sendNotice('RabbitMq 连接失败 ' . $e->getMessage());
  314. }
  315. return true;
  316. }
  317. }