function.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. <?php
  2. use App\Library\Redis;
  3. use App\Library\Log;
  4. use Hyperf\DbConnection\Db;
  5. /**
  6. * 下一天
  7. * @param $data 日期格式 2022-04-05
  8. * @return false|string
  9. */
  10. function nextDay($data)
  11. {
  12. return date('Y-m-d',strtotime('+1 day', strtotime($data)));
  13. }
  14. /*
  15. * 把十位时间戳转换为日期格式
  16. */
  17. function nowDate()
  18. {
  19. return date('Y-m-d H:i:s');
  20. }
  21. /*
  22. * 获取十三位时间戳
  23. */
  24. function thirteenTime(){
  25. return floor(microtime(true)*1000);
  26. }
  27. /*
  28. * 十三位时间戳转换为日期格式
  29. */
  30. function nowDateThirteen($timess){
  31. return date('Y-m-d H:i:s', floor($timess / 1000));
  32. }
  33. if (!function_exists('getTree')){
  34. function getTree($data, $pId=0)
  35. {
  36. $tree = array();
  37. foreach ($data as $k => $v) {
  38. if ($v->parentId == $pId) { //父亲找到儿子
  39. $v->children = getTree($data, $v->id);
  40. $tree[] = $v;
  41. //unset($data[$k]);
  42. }
  43. }
  44. return $tree;
  45. }
  46. }
  47. /**
  48. * 把数字1-1亿换成汉字表述,如:123->一百二十三
  49. * @param [num] $num [数字]
  50. * @return [string] [string]
  51. */
  52. if (!function_exists('numToWord')) {
  53. function numToWord($num)
  54. {
  55. $chiNum = array('零', '一', '二', '三', '四', '五', '六', '七', '八', '九');
  56. $chiUni = array('','十', '百', '千', '万', '亿', '十', '百', '千');
  57. $chiStr = '';
  58. $num_str = (string)$num;
  59. $count = strlen($num_str);
  60. $last_flag = true; //上一个 是否为0
  61. $zero_flag = true; //是否第一个
  62. $temp_num = null; //临时数字
  63. $chiStr = '';//拼接结果
  64. if ($count == 2) {//两位数
  65. $temp_num = $num_str[0];
  66. $chiStr = $temp_num == 1 ? $chiUni[1] : $chiNum[$temp_num].$chiUni[1];
  67. $temp_num = $num_str[1];
  68. $chiStr .= $temp_num == 0 ? '' : $chiNum[$temp_num];
  69. }else if($count > 2){
  70. $index = 0;
  71. for ($i=$count-1; $i >= 0 ; $i--) {
  72. $temp_num = $num_str[$i];
  73. if ($temp_num == 0) {
  74. if (!$zero_flag && !$last_flag ) {
  75. $chiStr = $chiNum[$temp_num]. $chiStr;
  76. $last_flag = true;
  77. }
  78. }else{
  79. $chiStr = $chiNum[$temp_num].$chiUni[$index%9] .$chiStr;
  80. $zero_flag = false;
  81. $last_flag = false;
  82. }
  83. $index ++;
  84. }
  85. }else{
  86. $chiStr = $chiNum[$num_str[0]];
  87. }
  88. return $chiStr;
  89. }
  90. }
  91. if (!function_exists('createNo')) {
  92. function createNo($prefix = '')
  93. {
  94. return $prefix . date('YmdHis') . sprintf("%03d", rand(1, 99));
  95. }
  96. }
  97. if (!function_exists('llog')) {
  98. /**
  99. * 记入日志
  100. * @param $log_title [日志路径]
  101. * @param $message [内容,不支持数组]
  102. * @param $remarks [备注]
  103. */
  104. function llog($log_title,$message,$remarks='info'){
  105. Log::get($remarks,$log_title)->info($message);
  106. }
  107. }
  108. if (!function_exists('transDate')) {
  109. function transDate($data)
  110. {
  111. return date('Y-m-d H:i:s', strtotime($data));
  112. }
  113. }
  114. if (!function_exists('complete_user_pic')) {
  115. function complete_user_pic($val) {
  116. if ($val == '') {
  117. return env('DEFAULT_USER_PIC');
  118. } else {
  119. if (strpos('http', $val) === false) {
  120. return env('OSS_URL') . $val;
  121. }
  122. }
  123. }
  124. }
  125. if (!function_exists('createOrderNo')) {
  126. function createOrderNo()
  127. {
  128. return date('YmdHis') . sprintf("%03d", rand(1, 999));
  129. }
  130. }
  131. if (!function_exists('genKey')) {
  132. function genKey($key_length){
  133. $str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  134. $len = strlen($str)-1;
  135. $key = '';
  136. for ($i=0; $i<$key_length; $i++){
  137. $num = mt_rand(0, $len);
  138. $key .= $str[$num];
  139. }
  140. return $key;
  141. }
  142. }
  143. if (!function_exists('complete_pic')) {
  144. function complete_pic($val) {
  145. // $url = $remote == 'server' ? env('APP_URL') : env('API_URL');
  146. if ($val != '' && strpos($val, 'http') === false) {
  147. return env('OSS_URL') . $val;
  148. }
  149. return $val;
  150. }
  151. }
  152. /**
  153. * 系统数据字典表
  154. * @param $type [0.读取 1.更新]
  155. */
  156. function configDictionary($type=0){
  157. $prefix = env('REDIS_PREFIX','swapbot_');
  158. if($type == 1){
  159. Redis::del($prefix.'DictionaryData');
  160. }else{
  161. $data = Redis::get($prefix.'DictionaryData');
  162. }
  163. if(empty($data)){
  164. $res = Db::table('sys_data_dictionary')->select('dic_key','dic_value','dic_name')->get()->map(function ($value){
  165. return (array)$value;
  166. })->toArray();
  167. $data= array();
  168. foreach ($res as $key => $v) {
  169. $data[$v['dic_key']][$v['dic_value']] = $v['dic_name'];
  170. }
  171. Redis::setex($prefix.'DictionaryData',86400,serialize($data));
  172. }else{
  173. $data = unserialize($data);
  174. }
  175. return $data;
  176. }
  177. /**
  178. * 系统配置
  179. * @param $type [0.读取 1.更新]
  180. */
  181. function configDataDictionary($type=0){
  182. $prefix = env('REDIS_PREFIX','swapbot_');
  183. if($type == 1){
  184. Redis::del($prefix.'ConfigData');
  185. }else{
  186. $data = Redis::get($prefix.'ConfigData');
  187. }
  188. if(empty($data)){
  189. $res = Db::table('sys_config')->select('config_key','config_val')->get()->map(function ($value){
  190. return (array)$value;
  191. })->toArray();
  192. $data= array();
  193. foreach ($res as $key => $v) {
  194. $data[$v['config_key']] = json_decode($v['config_val'],true);
  195. }
  196. Redis::setex($prefix.'ConfigData',86400,serialize($data));
  197. }else{
  198. $data = unserialize($data);
  199. }
  200. return $data;
  201. }
  202. /**
  203. * 获取Redis
  204. * @param $field 字段
  205. */
  206. function getRedis($field){
  207. $prefix = env('REDIS_PREFIX','swapbot_');
  208. return Redis::get($prefix.$field);
  209. }
  210. /**
  211. * 存储Redis
  212. * @param $field 字段
  213. * @param $data 值
  214. */
  215. function setRedis($field,$data){
  216. $prefix = env('REDIS_PREFIX','swapbot_');
  217. return Redis::set($prefix.$field,$data);
  218. }
  219. /**
  220. * 删除Redis
  221. * @param $data 值
  222. */
  223. function deleteRedis($data){
  224. $prefix = env('REDIS_PREFIX','swapbot_');
  225. return Redis::del($prefix.$data);
  226. }
  227. /**
  228. * API请求
  229. * @param $url 链接
  230. * @param $data 参数
  231. */
  232. function Get_Pay($url, $data = null, array $heders = [], $time=0)
  233. {
  234. $ch = curl_init();
  235. curl_setopt($ch, CURLOPT_URL, $url);
  236. curl_setopt($ch, CURLOPT_HEADER, 0);
  237. curl_setopt($ch, CURLOPT_TIMEOUT, $time); //单位 秒,也可以使用
  238. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  239. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //这个是重点,规避ssl的证书检查。
  240. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 跳过host验证
  241. if(!empty($data)){
  242. curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  243. }
  244. if(!empty($heders)){
  245. curl_setopt($ch, CURLOPT_HTTPHEADER, $heders);
  246. }
  247. $content = curl_exec($ch);
  248. curl_close($ch);
  249. return $content;
  250. }
  251. /**
  252. * post请求
  253. * @param $url string api链接
  254. * @param $url array 参数
  255. * @param $time_out int 超时时间
  256. */
  257. function post_url(string $url, array $data = [],$time_out = 5)
  258. {
  259. $data = json_encode($data);
  260. $headerArray = array("Content-type: application/json;charset='utf-8'");
  261. $curl = curl_init();
  262. curl_setopt($curl, CURLOPT_URL, $url);
  263. curl_setopt($curl, CURLOPT_CONNECTTIMEOUT , $time_out);
  264. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
  265. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
  266. curl_setopt($curl, CURLOPT_POST, 1);
  267. curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
  268. curl_setopt($curl, CURLOPT_HTTPHEADER, $headerArray);
  269. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  270. $output = curl_exec($curl);
  271. curl_close($curl);
  272. return json_decode($output,true);
  273. }
  274. /**
  275. * post请求
  276. * @param $url string api链接
  277. * @param $data array 参数
  278. * @param $time_out int 超时时间
  279. */
  280. function post_multi(string $url, array $data = [],$time_out = 5)
  281. {
  282. $headerArray = array("Content-Type: multipart/form-data;charset='utf-8'");
  283. $curl = curl_init();
  284. curl_setopt($curl, CURLOPT_URL, $url);
  285. curl_setopt($curl, CURLOPT_CONNECTTIMEOUT , $time_out);
  286. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
  287. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
  288. curl_setopt($curl, CURLOPT_POST, 1);
  289. curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
  290. curl_setopt($curl, CURLOPT_HTTPHEADER, $headerArray);
  291. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  292. $output = curl_exec($curl);
  293. curl_close($curl);
  294. return json_decode($output,true);
  295. }
  296. /**
  297. * API请求2
  298. * @param $url 链接
  299. * @param $data 参数
  300. */
  301. function curl_post_https($url,$data,$headers=null,$cookie=null){ // 模拟提交数据函数
  302. $curl = curl_init(); // 启动一个CURL会话
  303. curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
  304. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
  305. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); // 从证书中检查SSL加密算法是否存在
  306. // curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
  307. // curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
  308. // curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
  309. if(!empty($headers)){
  310. curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);//设置请求头
  311. }
  312. if(!empty($cookie)){
  313. curl_setopt($curl, CURLOPT_COOKIE, $cookie); // 带上COOKIE请求
  314. }
  315. curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
  316. curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的数据包
  317. curl_setopt($curl, CURLOPT_TIMEOUT, 10); // 设置超时限制防止死循环
  318. curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
  319. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
  320. $tmpInfo = curl_exec($curl); // 执行操作
  321. curl_close($curl); // 关闭CURL会话
  322. return $tmpInfo; // 返回数据
  323. }
  324. /**
  325. * API请求3
  326. * @param $url 链接
  327. * @param $data 参数
  328. */
  329. function curl_get_https($url,$headers=null,$raw=null,$time=6){
  330. $curl = curl_init();
  331. curl_setopt($curl, CURLOPT_URL, $url);
  332. curl_setopt($curl, CURLOPT_TIMEOUT, $time);
  333. curl_setopt($curl, CURLOPT_HEADER, 0);
  334. if(!empty($headers)){
  335. curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);//设置请求头
  336. }
  337. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  338. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
  339. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); // 从证书中检查SSL加密算法是否存在
  340. if($raw){
  341. curl_setopt($curl, CURLOPT_POSTFIELDS, $raw); // Post提交的数据包
  342. }
  343. $tmpInfo = curl_exec($curl); //返回api的json对象
  344. curl_close($curl);
  345. return $tmpInfo;
  346. }
  347. // 获取域名
  348. function getyuming(){
  349. $http_type = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';
  350. return env('APP_URL') ?? $http_type;
  351. }
  352. function array_replace_key_by_column(array $lists, $key = ''){
  353. $datas = [];
  354. if(is_array($lists) && $lists){
  355. foreach ($lists as $item){
  356. $datas[$item[$key]] = $item;
  357. }
  358. }
  359. return $datas;
  360. }
  361. /**
  362. * 添加后台管理员操作日志
  363. * @param $opt_ref_sn [操作对象ID]
  364. */
  365. function addAdminOptLog($opt_ref_sn=''){
  366. Db::table('sys_admin_opt_log')->insert([
  367. 'admin_id' => auth('admin')->id(), //管理用户ID
  368. 'opt_module' => request()->path(), //操作模块
  369. 'opt_ref_sn' => $opt_ref_sn, //操作对象ID
  370. 'opt_time' => nowDate(), //操作时间
  371. 'opt_ip' => request()->getClientIp(), //操作ip
  372. ]);
  373. }
  374. /**
  375. * 获取Redis数组key
  376. * @param $data 值
  377. */
  378. function getKeyRedis(){
  379. $prefix = env('REDIS_PREFIX','swapbot_');
  380. return Redis::keys($prefix."*");
  381. }
  382. /**
  383. * 获取最后一位数字
  384. * @param $str 字符串
  385. */
  386. function descNumberOne($str){
  387. $str = strrev($str); //倒序
  388. $data = '';
  389. for ($i=0; $i < strlen($str); $i++) {
  390. if(is_numeric($str[$i])){
  391. $data = $str[$i];
  392. break;
  393. }
  394. }
  395. return $data;
  396. }
  397. /**
  398. * 字符串位数不足在前面补0
  399. * @param $str
  400. * @param int $bit
  401. * @return string
  402. */
  403. function fill0($str, $bit=64){
  404. if(!strlen($str)) return "";
  405. $str_len = strlen($str);
  406. $zero = '';
  407. for($i=$str_len; $i<$bit; $i++){
  408. $zero .= "0";
  409. }
  410. $real_str = $zero . $str;
  411. return $real_str;
  412. }
  413. /**
  414. * 转为十六进制
  415. * @param string|number $value 十进制的数
  416. * @param boolean $mark 是否加0x头
  417. * @return string
  418. */
  419. function decToHex($value, $mark = true)
  420. {
  421. $hexvalues = [
  422. '0','1','2','3','4','5','6','7',
  423. '8','9','a','b','c','d','e','f'
  424. ];
  425. $hexval = '';
  426. while($value != '0') {
  427. $hexval = $hexvalues[bcmod($value, '16')] . $hexval;
  428. $value = bcdiv($value, '16', 0);
  429. }
  430. return ($mark ? '0x' . $hexval : $hexval);
  431. }
  432. /**
  433. * 数组转json
  434. * @param $array
  435. * @return false|string
  436. */
  437. function jsonEncode($array){
  438. return json_encode($array, JSON_UNESCAPED_UNICODE);
  439. }
  440. /**
  441. * json转数组
  442. * @param $json
  443. * @return mixed
  444. */
  445. function jsonDecode($json){
  446. return json_decode($json, true);
  447. }
  448. /**
  449. * 高精度计算相除
  450. * @param $price [金额]
  451. * @param $number [多少个0]
  452. */
  453. function calculationExcept($price,$number){
  454. $multiple = 1; //倍数
  455. if($number > 0){
  456. for ($i=0; $i < $number; $i++) {
  457. $multiple = $multiple.'0';
  458. }
  459. $multiple = (int)$multiple;
  460. }
  461. $data = bcdiv($price,$multiple,$number);
  462. if(strpos(floatval($data),'-') == false){
  463. // 精度未失效
  464. $data = floatval($data);
  465. }else{
  466. // 精度失效
  467. $data = rtrim(rtrim($data, '0'), '.');
  468. }
  469. return $data;
  470. }
  471. /**
  472. * 处理金额
  473. * @param $amount [金额]
  474. */
  475. function handleAmount($amount){
  476. return $amount * 10 ** 6;
  477. }
  478. /**
  479. * 转为十进制
  480. * @param string $number 十六进制的数
  481. * @return string
  482. */
  483. function hexToDec($number)
  484. {
  485. // 如果有0x去除它
  486. $number = remove0x(strtolower($number));
  487. $decvalues = [
  488. '0' => '0', '1' => '1', '2' => '2',
  489. '3' => '3', '4' => '4', '5' => '5',
  490. '6' => '6', '7' => '7', '8' => '8',
  491. '9' => '9', 'a' => '10', 'b' => '11',
  492. 'c' => '12', 'd' => '13', 'e' => '14',
  493. 'f' => '15'];
  494. $decval = '0';
  495. $number = strrev($number);
  496. for($i = 0; $i < strlen($number); $i++) {
  497. $decval = bcadd(bcmul(bcpow('16', $i, 0), $decvalues[$number[$i]]), $decval);
  498. }
  499. return $decval;
  500. }
  501. /**
  502. * 如果有0x去除它
  503. * @param $value
  504. * @return false|string
  505. */
  506. function remove0x($value)
  507. {
  508. if (strtolower(substr($value, 0, 2)) == '0x') {
  509. return substr($value, 2);
  510. }
  511. return $value;
  512. }
  513. /**
  514. * 生成 Mefree API 的签名
  515. * @param string $timestamp UTC 时间戳 (ISO 8601 格式)
  516. * @param string $method HTTP 方法 (GET/POST)
  517. * @param string $request_path API 请求路径(含参数)
  518. * @param string $secret_key API 的 Secret Key
  519. * @return string 返回 Base64 编码的签名
  520. */
  521. function generate_signature($timestamp, $method, $request_path, $secret_key) {
  522. // 拼接待签名字符串
  523. $string_to_sign = $timestamp . $method . $request_path;
  524. // 使用 HMAC-SHA256 算法对字符串进行加密
  525. $hash = hash_hmac('sha256', $string_to_sign, $secret_key, true);
  526. // 返回 Base64 编码的签名
  527. return base64_encode($hash);
  528. }
  529. /**
  530. * 发起 Mefree API 请求
  531. * @param string $method HTTP 方法 (GET/POST)
  532. * @param string $request_path API 请求路径(含查询参数)
  533. * @param string $base_url API 基础 URL
  534. * @param string $api_key API Key
  535. * @param string $secret_key API Secret Key
  536. * @return mixed 返回 API 响应内容
  537. */
  538. function send_request($method, $request_path, $base_url, $api_key, $secret_key) {
  539. // 当前 UTC 时间戳
  540. $timestamp = gmdate("Y-m-d\TH:i:s.v\Z");
  541. // 生成签名
  542. $signature = generate_signature($timestamp, $method, $request_path, $secret_key);
  543. // 设置请求头
  544. $headers = [
  545. "Content-Type: application/json",
  546. "MF-ACCESS-KEY: {$api_key}",
  547. "MF-ACCESS-SIGN: {$signature}",
  548. "MF-ACCESS-TIMESTAMP: {$timestamp}",
  549. ];
  550. // 初始化 CURL
  551. $ch = curl_init();
  552. curl_setopt($ch, CURLOPT_URL, $base_url . $request_path); // 设置 URL
  553. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); // 设置请求方法
  554. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // 设置请求头
  555. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回响应内容
  556. // 执行请求
  557. $response = curl_exec($ch);
  558. $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); // 获取 HTTP 状态码
  559. curl_close($ch);
  560. // 返回结果
  561. return [
  562. "status_code" => $http_code,
  563. "response" => $response
  564. ];
  565. }