1 <?php 2 3 use IlluminateSupportFacadesCache; 4 use AppModelsConf; 5 6 /** 7 * 协作路由 8 * 9 * @param string $version 10 * @param bool $noAuth 11 * @return void 12 */ 13 function initTeamRoute(string $version, bool $noAuth = false) 14 { 15 $dir = app_path('Routes/' . $version . '/'); 16 17 if (is_dir($dir)) { 18 19 if ($noAuth) { 20 $noAuthDir = $dir . 'noauth'; 21 if (is_dir($noAuthDir)) { 22 $fs = glob($noAuthDir . '/*.php'); 23 foreach ($fs as $f) { 24 require $f; 25 } 26 } 27 } else { 28 $h = scandir($dir); 29 foreach ($h as $file) { 30 if (is_dir($dir . $file) && $file[0] != '.') { 31 $fs = glob($dir . $file . '/*.php'); 32 foreach ($fs as $f) { 33 require $f; 34 } 35 } 36 } 37 } 38 39 } 40 } 41 42 /** 43 * 返回成功后的数据 44 * 45 * @param mixed $data 46 * @param string $msg 47 * @return array 48 */ 49 function apiSuccessData($data = [], string $msg = '操作成功') 50 { 51 $result = [ 52 'code' => 0, 53 'msg' => $msg 54 ]; 55 56 $data != [] && $result['data'] = $data; 57 58 return $result; 59 } 60 61 /** 62 * 返回失败后的数据 63 * 64 * @param string $msg 65 * @param mixed $data 66 * @return array 67 */ 68 function apiFailureData(string $msg = '操作失败', $data = []) 69 { 70 $result = [ 71 'code' => 1, 72 'msg' => $msg 73 ]; 74 75 $data != [] && $result['data'] = $data; 76 77 return $result; 78 } 79 80 /** 81 * 为返回列表获取配置信息,本地仅获取status配置 82 * 83 * @param string $field 数据库字段名 84 * @param string $key 配置key 85 * @param string $type 类型,local:本地配置,remote:远程配置,可省略 86 * @return array 87 */ 88 function conf(string $field, string $key, string $type = 'remote') 89 { 90 // 本地配置 91 if ($type == 'local') { 92 $conf = []; 93 $localConf = config('status.' . $key); 94 95 if ($localConf) { 96 foreach ($localConf as $key => $val) { 97 $conf[] = ['label' => $val, 'value' => $key]; 98 } 99 return [$field => $conf]; 100 } 101 102 return apiFailureData('本地配置不存在'); 103 } 104 105 // 远程配置 106 $cacheKey = 'config.' . $key; 107 if (!Cache::has($cacheKey)) { 108 $confData = Conf::query()->select('conf_content')->where('conf_key', $key)->first(); 109 $confData && Cache::forever($cacheKey, json_decode($confData->conf_content, true)); 110 } 111 112 return Cache::has($cacheKey) ? [$field => Cache::get($cacheKey)[$key]] : apiFailureData('远程配置不存在'); 113 } 114 115 /** 116 * 为Rule::in规则获取配置信息,本地仅获取status配置 117 * 118 * @param string $key 配置key 119 * @param string $type 类型,local:本地配置,remote:远程配置,可省略 120 * @return array 121 */ 122 function confRuleIn(string $key, string $type = 'remote') 123 { 124 // 本地配置 125 if ($type == 'local') { 126 $localConf = config('status.' . $key); 127 128 if ($localConf) { 129 $localConf = array_filter(array_keys($localConf), function ($value) { 130 return $value !== ""; 131 }); 132 133 return array_values($localConf); 134 } 135 136 return apiFailureData('本地配置不存在'); 137 } 138 139 // 远程配置 140 $cacheKey = 'config.' . $key; 141 if (!Cache::has($cacheKey)) { 142 $confData = Conf::query()->select('conf_content')->where('conf_key', $key)->first(); 143 $confData && Cache::forever($cacheKey, json_decode($confData->conf_content, true)); 144 } 145 146 if (Cache::has($cacheKey)) { 147 $remoteConf = Cache::get($cacheKey); 148 $remoteConf = $remoteConf[$key]; 149 $conf = []; 150 foreach ($remoteConf as $val) { 151 if ($val['value'] === '') { 152 continue; 153 } 154 $conf[] = $val['value']; 155 } 156 157 return $conf; 158 } 159 160 return apiFailureData('远程配置不存在'); 161 } 162 163 /** 164 * 关键词处理 165 * 166 * @param string|null $keyword 167 * @return string 168 */ 169 function trimKeyword($keyword) 170 { 171 $keyword = urldecode($keyword); 172 $keyword = trim($keyword); 173 $keyword = preg_replace('/_|%|insert|update|select|delete|create|join|union|where|like|drop|modify|rename|alter/i', '', $keyword); 174 175 return $keyword; 176 } 177 178 179 /** 180 * 上传文件命名 181 * 182 * @return string 183 */ 184 function upFileName() 185 { 186 return uniqid() . mt_rand(100, 999); 187 } 188 189 /** 190 * 手机号验证规则,用于验证rule(适当放宽号段,避免中间运营商放号) 191 * 192 * @return string 193 */ 194 function phoneRegex() 195 { 196 return 'regex:/^1[3-9]d{9}$/'; 197 } 198 199 function cardnoRegex() 200 { 201 return 'regex:/^[1-9]d{5}(18|19|([23]d))d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)d{3}[0-9Xx]$/'; 202 } 203 204 /** 205 * 手机号部分隐藏 206 * 207 * @param string $phone 208 * @return string 209 */ 210 function getHidePhone(string $phone) 211 { 212 return substr_replace($phone, '****', 3, 4); 213 } 214 215 /** 216 * 加密手机号 217 * 218 * @param string $phone 219 * @return string 220 */ 221 function encryptPhone(string $phone) 222 { 223 $map = array('i', '3', 'd', 'p', '2', '9', 'k', '+', '-', '6'); 224 $disturb = array(0, 2, 3, 5, 6, 7, 8, 10, 11, 12, 14, 15, 16, 17, 18, 20, 22, 23, 24, 27, 28, 30); 225 $lastNo = $phone[10]; 226 $firstNo = $phone[$lastNo]; 227 $firstStr = $firstNo . substr($phone, 1); 228 $secondStr = ''; 229 for ($i = 0; $i <= 10; $i++) { 230 $secondStr .= $map[$firstStr[$i]]; 231 } 232 $thirdStr = encryptVisualData($secondStr); 233 $resultChar = md5($thirdStr); 234 for ($i = 0; $i < 22; $i++) { 235 $resultChar[$disturb[$i]] = $thirdStr[$i]; 236 } 237 238 return $resultChar; 239 } 240 241 /** 242 * 解密手机号 243 * 244 * @param string $phoneCode 245 * @return string 246 */ 247 function decryptPhone(string $phoneCode) 248 { 249 $map = ['i', '3', 'd', 'p', '2', '9', 'k', '+', '-', '6']; 250 $disturb = [0, 2, 3, 5, 6, 7, 8, 10, 11, 12, 14, 15, 16, 17, 18, 20, 22, 23, 24, 27, 28, 30]; 251 $phoneChar = ''; 252 for ($i = 0; $i < 22; $i++) { 253 $phoneChar .= $phoneCode[$disturb[$i]]; 254 } 255 $thirdStr = decryptVisualData($phoneChar); 256 $secondStr = ''; 257 for ($i = 0; $i <= 10; $i++) { 258 foreach ($map as $key => $val) { 259 if ($thirdStr[$i] == $val) { 260 $secondStr .= $key; 261 break; 262 } 263 } 264 } 265 $firstStr = '1' . substr($secondStr, 1); 266 267 return $firstStr; 268 } 269 270 271 /** 272 * 加密数据显示化 273 * 274 * @param string $str 275 * @return string 276 */ 277 function encryptVisualData(string $str) 278 { 279 return urlBase64Encode(encryptData($str, config('app.key'))); 280 } 281 282 /** 283 * 加密数据显示化解密 284 * 285 * @param string $str 286 * @return string 287 */ 288 function decryptVisualData(string $str) 289 { 290 return decryptData(urlBase64Decode($str), config('app.key')); 291 } 292 293 /** 294 * 简单数据加密 by liu21st 295 * 296 * @param string $data 297 * @param string $key 298 * @return string 299 */ 300 function encryptData(string $data, string $key) 301 { 302 $str = ''; 303 $char = ''; 304 $key = md5($key); 305 $data = base64_encode($data); 306 $x = 0; 307 $len = strlen($data); 308 $l = strlen($key); 309 for ($i = 0; $i < $len; $i++) { 310 if ($x == $l) $x = 0; 311 $char .= substr($key, $x, 1); 312 $x++; 313 } 314 for ($i = 0; $i < $len; $i++) { 315 $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1))) % 256); 316 } 317 318 return $str; 319 } 320 321 /** 322 * 简单数据解密 by liu21st 323 * 324 * @param string $data 325 * @param string $key 326 * @return string 327 */ 328 function decryptData(string $data, string $key) 329 { 330 $char = ''; 331 $str = ''; 332 $key = md5($key); 333 $x = 0; 334 $len = strlen($data); 335 $l = strlen($key); 336 for ($i = 0; $i < $len; $i++) { 337 if ($x == $l) $x = 0; 338 $char .= substr($key, $x, 1); 339 $x++; 340 } 341 for ($i = 0; $i < $len; $i++) { 342 if (ord(substr($data, $i, 1)) < ord(substr($char, $i, 1))) { 343 $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1))); 344 } else { 345 $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1))); 346 } 347 } 348 349 return base64_decode($str); 350 } 351 352 353 /** 354 * 去除Base64编码的特殊符号 355 * 356 * @param string $str 357 * @return string 358 */ 359 function urlBase64Encode(string $str) 360 { 361 $data = base64_encode($str); 362 $data = str_replace(['+', '/', '='], ['-', '_', ''], $data); 363 364 return $data; 365 } 366 367 /** 368 * 还原Base64编码的特殊符号 369 * 370 * @param string $str 371 * @return string 372 */ 373 function urlBase64Decode(string $str) 374 { 375 $data = str_replace(['-', '_'], ['+', '/'], $str); 376 ($mod = strlen($data)) % 4 && $data .= substr('====', $mod); 377 378 return base64_decode($data); 379 } 380 381 /** 382 * 加密身份证号 383 * 384 * @param string $cardNo 身份证号 385 * @param string $methodOne 加密方法一 386 * @param string $methodTwo 加密方法二 387 * @param int $option 数据格式 388 * @param string $iv 初始化向量 389 * @return string 加密后64位字符串 390 */ 391 function encryptCardno(string $cardNo, $methodOne = 'DES-ECB', $methodTwo = 'DES-OFB', $option = OPENSSL_RAW_DATA, $iv = 'YC0Xkac6') 392 { 393 $disturb = array(1, 3, 5, 6, 8, 10, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 30, 32, 35, 36, 39, 40, 42, 45, 46, 48, 53, 57, 58, 60, 63); 394 395 // firstStr 396 $tail = substr($cardNo, strlen($cardNo) - 5, 4); 397 $firstStr = $cardNo . $tail; 398 // secondStr 399 $secondStr = openssl_encrypt($firstStr, $methodOne, config('app.key'), $option); 400 // thirdStr 401 $thirdStr = openssl_encrypt($secondStr, $methodTwo, config('app.key'), $option, $iv); 402 $secondStr = base64_encode($secondStr); 403 $thirdStr = base64_encode($thirdStr); 404 // resultChar 405 $resultChar = $secondStr . $thirdStr; 406 for ($i = 0; $i < 32; $i++) { 407 $resultChar[$disturb[$i]] = $thirdStr[$i]; 408 } 409 410 return $resultChar; 411 } 412 413 /** 414 * 解密身份证号 415 * 416 * @param string $CardCode 加密后的64位字符串 417 * @param string $methodOne 第一个解密方法 418 * @param string $methodTwo 第二个解密方法 419 * @param int $option 数据格式 420 * @param string $iv 初始化向量 421 * @return bool|string 解密后身份证号 422 */ 423 function decryptCardno(string $CardCode, $methodOne = 'DES-ECB', $methodTwo = 'DES-OFB', $option = OPENSSL_RAW_DATA, $iv = 'YC0Xkac6') 424 { 425 426 $disturb = array(1, 3, 5, 6, 8, 10, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 30, 32, 35, 36, 39, 40, 42, 45, 46, 48, 53, 57, 58, 60, 63); 427 428 $thirdStr = ''; 429 for ($i = 0; $i < 32; $i++) { 430 $thirdStr .= $CardCode[$disturb[$i]]; 431 } 432 $thirdStr = base64_decode($thirdStr); 433 $secondStr = openssl_decrypt($thirdStr, $methodTwo, config('app.key'), $option, $iv); 434 $firstStr = openssl_decrypt($secondStr, $methodOne, config('app.key'), $option); 435 436 $firstStr = substr($firstStr, 0, strlen($firstStr) - 4); 437 return $firstStr; 438 } 439 440 /** 441 * 私钥加密 442 * 443 * @param $aString 444 * @return string 445 */ 446 function enRsaPrivate($aString) 447 { 448 $str = '-----BEGIN RSA PRIVATE KEY-----' . PHP_EOL . config('app.private_key') . PHP_EOL . '-----END RSA PRIVATE KEY-----'; 449 450 $pr_key = openssl_pkey_get_private($str);//这个函数可用来判断私钥是否是可用的,可用返回资源id Resource id 451 openssl_private_encrypt($aString, $encrypted, $pr_key);//私钥加密 452 $encrypted = base64_encode($encrypted);//加密后的内容通常含有特殊字符,需要编码转换下,在网络间通过url传输时要注意base64编码是否是url安全的 453 return $encrypted; 454 } 455 456 /** 457 * 递归获取树桩结构数据 458 * 459 * @param $data 查询获取的数组 460 * @param int $pid 初始父级id 461 * @param string $table 表名 462 * @return array 树状结构数据 463 */ 464 function oneCoverTree($data, int $pid = 0, string $table = '') 465 { 466 $tree = array(); 467 468 foreach ($data as $k => $v) { 469 if ($v[$table . '_pid'] == $pid) { //父亲找到儿子 470 $v[$table . '_children'] = oneCoverTree($data, $v[$table . '_id'], $table); 471 $tree[] = $v; 472 unset($data[$k]); 473 } 474 } 475 476 return $tree; 477 } 478 479 /** 480 * 递归恢复树状结构数组为一维数组并添加$table . _order字段数组 481 * 482 * @param $data 树状结构数组 483 * @param int $pid 初始父级id 484 * @param string $table 表名 485 * @return array 带$table . _order一维数组数据 486 */ 487 function treeCoverOne($data, int $pid = 0, string $table = '', int $icon = 0) 488 { 489 static $list = []; 490 $order = 1000; 491 foreach ($data as $k => $v) { 492 $v[$table . '_order'] = $order; 493 if ($icon) { 494 $v[$table . '_icon'] = $v[$table . '_icon'] ? $v[$table . '_icon'][0] : null; 495 } 496 $v[$table . '_pid'] = $pid; 497 treeCoverOne($v[$table . '_children'], $v[$table . '_id'], $table, $icon); 498 unset($v[$table . '_children']); 499 $list[] = $v; 500 $order--; 501 502 } 503 504 return $list; 505 } 506 507 function getFileTypeCode(String $fileName = '') 508 { 509 $fileContent = IlluminateSupportFacadesFile::get($fileName); 510 $fileInfo = @unpack("c2chars", substr($fileContent, 0, 2)); 511 $fileTypeCode = intval($fileInfo['chars1'] . $fileInfo['chars2']); 512 return $fileTypeCode; 513 }