common.php 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: 流年 <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. // 应用公共文件
  12. use app\common\model\Config;
  13. use tools\Qxsms;
  14. /**
  15. * 校验手机格式
  16. * @param $phone
  17. * @return int
  18. */
  19. function check_mobile($phone){
  20. return preg_match("/1\d{10}$/",$phone);
  21. }
  22. /**
  23. * [check_email 校验邮箱格式]
  24. */
  25. function check_email($email){
  26. $pattern = "/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i";
  27. return preg_match($pattern,$email);
  28. }
  29. /**
  30. * 字符串截取,支持中文和其他编码
  31. * @static
  32. * @access public
  33. * @param string $str 需要转换的字符串
  34. * @param string $start 开始位置
  35. * @param string $length 截取长度
  36. * @param string $charset 编码格式
  37. * @param string $suffix 截断显示字符
  38. * @return string
  39. */
  40. function msubstr($str, $start=0, $length, $charset="utf-8", $suffix=false) {
  41. if(function_exists("mb_substr"))
  42. $slice = mb_substr($str, $start, $length, $charset);
  43. elseif(function_exists('iconv_substr')) {
  44. $slice = iconv_substr($str,$start,$length,$charset);
  45. if(false === $slice) {
  46. $slice = '';
  47. }
  48. }else{
  49. $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
  50. $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
  51. $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
  52. $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
  53. preg_match_all($re[$charset], $str, $match);
  54. $slice = join("",array_slice($match[0], $start, $length));
  55. }
  56. return $suffix ? $slice.'...' : $slice;
  57. }
  58. /**
  59. * 系统加密方法
  60. * @param string $data 要加密的字符串
  61. * @param string $key 加密密钥
  62. * @param int $expire 过期时间 单位 秒
  63. * @return string
  64. */
  65. function think_encrypt($data, $key = '', $expire = 0) {
  66. $key = md5(empty($key) ? config('app.encryption_key') : $key);
  67. $data = base64_encode($data);
  68. $x = 0;
  69. $len = strlen($data);
  70. $l = strlen($key);
  71. $char = '';
  72. for ($i = 0; $i < $len; $i++) {
  73. if ($x == $l) $x = 0;
  74. $char .= substr($key, $x, 1);
  75. $x++;
  76. }
  77. $str = sprintf('%010d', $expire ? $expire + time():0);
  78. for ($i = 0; $i < $len; $i++) {
  79. $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1)))%256);
  80. }
  81. return str_replace(array('+','/','='),array('-','_',''),base64_encode($str));
  82. }
  83. /**
  84. * 系统解密方法
  85. * @param string $data 要解密的字符串 (必须是think_encrypt方法加密的字符串)
  86. * @param string $key 加密密钥
  87. * @return string
  88. */
  89. function think_decrypt($data, $key = ''){
  90. $key = md5(empty($key) ? config('app.encryption_key') : $key);
  91. $data = str_replace(array('-','_'),array('+','/'),$data);
  92. $mod4 = strlen($data) % 4;
  93. if ($mod4) {
  94. $data .= substr('====', $mod4);
  95. }
  96. $data = base64_decode($data);
  97. $expire = substr($data,0,10);
  98. $data = substr($data,10);
  99. if($expire > 0 && $expire < time()) {
  100. return '';
  101. }
  102. $x = 0;
  103. $len = strlen($data);
  104. $l = strlen($key);
  105. $char = $str = '';
  106. for ($i = 0; $i < $len; $i++) {
  107. if ($x == $l) $x = 0;
  108. $char .= substr($key, $x, 1);
  109. $x++;
  110. }
  111. for ($i = 0; $i < $len; $i++) {
  112. if (ord(substr($data, $i, 1))<ord(substr($char, $i, 1))) {
  113. $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));
  114. }else{
  115. $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));
  116. }
  117. }
  118. return base64_decode($str);
  119. }
  120. /**
  121. * 根据省份证号获取生日和性别
  122. * @param $idcard
  123. * @return array
  124. */
  125. function get_birthday_sex_by_idcard($idcard){
  126. if(mb_strlen($idcard) != 18){
  127. return ['birthday'=>null,'gender'=>0];
  128. }
  129. $birthday = msubstr($idcard, 6, 8);
  130. $birthday = date('Y-m-d',strtotime($birthday));
  131. $gender = msubstr($idcard,16,1)%2;
  132. $gender = $gender?1:2;
  133. return ['birthday'=>$birthday,'gender'=>$gender];
  134. }
  135. /**
  136. * ajax 请求正确返回
  137. * @param string $msg
  138. * @param array $data
  139. * @return json
  140. */
  141. function ajax_return_ok($data = array(),$msg = ''){
  142. $result['code'] = 0;
  143. $result['data'] = $data;
  144. $result['message'] = $msg ;
  145. header('Content-Type:application/json; charset=utf-8');
  146. if(version_compare(PHP_VERSION,'5.4.0','<')){
  147. exit(json_encode($result));
  148. }else{
  149. exit(json_encode($result,JSON_UNESCAPED_UNICODE)); //显示中文
  150. }
  151. }
  152. /**
  153. * ajax 请求错误返回
  154. * @param string $msg
  155. * @param string $code
  156. * @return json
  157. */
  158. function ajax_return_error($msg = null,$code = 1){
  159. if ($msg == null){
  160. $msgDefault = config ( 'e_msg_default' );
  161. $result['msg'] = $msgDefault [$code];
  162. }else{
  163. $result['msg'] = $msg ;
  164. }
  165. $result['status'] = 0;
  166. $result['code'] = $code;
  167. header('Content-Type:application/json; charset=utf-8');
  168. if(version_compare(PHP_VERSION,'5.4.0','<')){
  169. exit(json_encode($result));
  170. }else{
  171. exit(json_encode($result,JSON_UNESCAPED_UNICODE)); //显示中文
  172. }
  173. }
  174. /**
  175. * AES 128 ecb 加密 与java加密保持一致
  176. * @param $data 加密字符串
  177. * @param $key 加密key
  178. * @return string 加密串
  179. */
  180. function aes_encrypt($data) {
  181. $key = config('app.encryption_key');
  182. $data = openssl_encrypt($data, 'aes-128-ecb', $key, OPENSSL_RAW_DATA);
  183. return base64_encode($data);
  184. }
  185. /**
  186. * AES 128 ecb 解密 与java加密保持一致
  187. * @param $data 解密字符串
  188. * @param $key 加密key
  189. * @return string 解密串
  190. */
  191. function aes_decrypt($data) {
  192. $key = config('app.encryption_key');
  193. $encrypted = base64_decode($data);
  194. return openssl_decrypt($encrypted, 'aes-128-ecb', $key, OPENSSL_RAW_DATA);
  195. }
  196. /**
  197. * 下划线转驼峰
  198. * @param $str
  199. * @return string|string[]|null
  200. */
  201. function line_to_hump($str){
  202. return preg_replace_callback('/(_[a-z])/', function ($match) {
  203. return ucfirst(trim($match[0], '_'));
  204. }, $str);
  205. }
  206. /**
  207. * 驼峰转下划线
  208. * @param $str
  209. * @return string|string[]|null
  210. */
  211. function hump_to_line($str){
  212. return preg_replace_callback('/([A-Z])/', function ($match) {
  213. return '_' . lcfirst($match[0]);
  214. }, $str);
  215. }
  216. /**
  217. * 多维数组键值下划线转换为驼峰
  218. * @param $arr
  219. * @return array
  220. */
  221. function array_change_line_to_hump($arr){
  222. $tem = [];
  223. foreach ($arr as $k=>$v){
  224. if(is_array($v)){
  225. $tem[line_to_hump($k)] = array_change_line_to_hump($v);
  226. }else{
  227. $tem[line_to_hump($k)] = $v;
  228. }
  229. }
  230. return $tem;
  231. }
  232. /**
  233. * 多维数组取某一字段
  234. * @param array $arr
  235. * @param string $field 要删除字段
  236. * @param string $child
  237. * @return array
  238. */
  239. function array_delete_char($arr,$field,$child = 'depAndJobDtos'){
  240. $tem = [];
  241. foreach ($arr as $k=>$v){
  242. unset($v[$field]);
  243. if(!empty($v[$child])){
  244. $v[$child] = array_delete_char($v[$child],$field);
  245. }
  246. $tem[$k] = $v;
  247. }
  248. return $tem;
  249. }
  250. /**
  251. * 把返回的数据集转换成Tree 主要组织部门岗位人员树使用
  252. * @param array $list 要转换的数据集
  253. * @param string $pid parent标记字段
  254. * @param string $child 子孙键名
  255. * @param int $root 父级值
  256. * @return array
  257. */
  258. function list_to_tree($list, $pid = 'pid', $child = '_child', $root = 0)
  259. {
  260. $tree = [];
  261. foreach($list as $k => $v){
  262. if($v[$pid] == $root){
  263. $children = list_to_tree($list, $pid, $child, $v['id']);
  264. if(!empty($v[$child])){
  265. $children = array_merge($children,$v[$child]);
  266. }
  267. $v[$child] = $children;
  268. $tree[] = $v;
  269. }
  270. }
  271. return $tree;
  272. }
  273. /**
  274. * 获取编号
  275. * @param $prefix
  276. * @return string
  277. */
  278. function get_unique_id($prefix=''){
  279. return $prefix.date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 12), 1))), 0, 8);
  280. }
  281. /**
  282. * 获取编号
  283. * @param string $prefix
  284. * @return string
  285. */
  286. function get_unique_sn($prefix=''){
  287. return $prefix.date('YmdHis').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 12), 1))), 0, 6);
  288. }
  289. /**
  290. * flowjson排序
  291. * @param $flowJson
  292. * @param string $nodeid
  293. * @param array $result
  294. * @return array
  295. */
  296. function sort_flow_json($flowJson,$nodeid='',&$result=[]){
  297. foreach ($flowJson as $k=>$v){
  298. if((!$nodeid && $v['type'] == 1) || $nodeid && $v['id'] == $nodeid){
  299. $result[] = $v;
  300. if(count($result) != count($flowJson)){
  301. sort_flow_json($flowJson,$v['nextId'],$result);
  302. break;
  303. }
  304. }
  305. }
  306. return $result;
  307. }
  308. /**
  309. *
  310. * @param $start
  311. * @param $end
  312. * @param $type
  313. * @return float|int
  314. */
  315. function calculate_leave($start,$end,$type){
  316. $starts = explode(' ',$start);
  317. $ends = explode(' ',$end);
  318. $start = date('Ymd',strtotime($starts[0]));
  319. $stxt = $starts[1];
  320. $end = date('Ymd',strtotime($ends[0]));
  321. $etxt = $ends[1];
  322. if($start > $end){
  323. return 0;
  324. }
  325. $bxday = \think\Db::name('holiday')
  326. ->where('holiday',0)
  327. ->where('day','>=',date('Y-m-d',strtotime($starts[0])))
  328. ->where('day','<=',date('Y-m-d',strtotime($ends[0])))
  329. ->column('day');
  330. $bxday = $bxday?$bxday:[];
  331. $holiday = \think\Db::name('holiday')
  332. ->where('holiday',1)
  333. ->where('day','>=',date('Y-m-d',strtotime($starts[0])))
  334. ->where('day','<=',date('Y-m-d',strtotime($ends[0])))
  335. ->column('day');
  336. $holiday = $holiday?$holiday:[];
  337. $days = 0;
  338. $cday = (strtotime($end) - strtotime($start))/86400 + 1;
  339. for ($i=1;$i<=$cday;$i++){
  340. if($type == 1){ // 减去节假日
  341. $cur = strtotime($start) + ($i-1)*86400;
  342. $w = date('w',$cur);
  343. $itxt = date('Y-m-d',$cur);
  344. if(($w == 6 || $w == 0) && in_array($itxt,$bxday)){ // 检查是否是补休日
  345. if($i == 1 && $stxt == '下午'){ // 开始日期
  346. $days += 0.5;
  347. }else if($i == $cday && $etxt == '上午'){
  348. $days += 0.5;
  349. }else{
  350. $days++;
  351. }
  352. } else if($w >0 && $w < 6 && !in_array($itxt,$holiday)){
  353. if($i == 1&&$stxt == '下午'){ // 开始日期
  354. $days += 0.5;
  355. } else if($i == $cday && $etxt == '上午'){
  356. $days += 0.5;
  357. }else{
  358. $days++;
  359. }
  360. }
  361. } else { // 不减节假日
  362. $days++;
  363. }
  364. }
  365. return $days;
  366. }
  367. /**
  368. * 计算社保比例金额
  369. * @param $money
  370. * @param $bl
  371. * @param $bl_type
  372. * @param $bl_extra
  373. * @param $free_bl
  374. * @return false|float
  375. */
  376. function calculate_money($money,$bl,$bl_type,$bl_extra,$free_bl){
  377. $gjjp = $money*$bl;
  378. if($bl_extra > 0){
  379. if($bl_type == 1){ // 比例
  380. $gjjp += $money*$bl_extra;
  381. } else { // 整数
  382. $gjjp += $bl_extra;
  383. }
  384. }
  385. $gjjp = $gjjp*(1 - $free_bl);
  386. return round($gjjp,2);
  387. }
  388. /**
  389. * 延迟任务
  390. * @param $delay 延迟时间(s)
  391. * @param $data 数据
  392. * @param int $type 0=推送 1=短信
  393. * @return bool true=成功
  394. */
  395. function queue_later($delay,$data,$type = 0){
  396. $connector = strtolower(config('queue.connector'));
  397. try{
  398. if($type == 0){ //取消订单
  399. $job = "app\queue\OrderJob@cancel";
  400. $queue = "cancel";
  401. }else if($type == 1){ //处理拼团单
  402. $job = "app\queue\OrderJob@group";
  403. $queue = "group";
  404. }else{
  405. return false;
  406. }
  407. if($connector == 'redis'){
  408. \think\Queue::later($delay, $job, $data, $queue);
  409. return true;
  410. }else{
  411. $res = \think\Queue::later($delay, $job, $data, $queue);
  412. return $res?true:false;
  413. }
  414. }catch (Exception $e){
  415. trace($e->getMessage());
  416. }
  417. return false;
  418. }
  419. /**
  420. * 推送队列任务
  421. * @param string $data 业务数据
  422. * @param int $type 0=推送 1=短信
  423. * @param int $delay 延迟时间(s)
  424. * @return bool true=成功
  425. */
  426. function queue_push($data,$type = 0,$delay = 0){
  427. try{
  428. if($type == 0){ //推送
  429. $job = "app\queue\Jobs@jpush";
  430. $queue = "jpush";
  431. }else if($type == 1){ //短信
  432. $job = "app\queue\Jobs@qxsms";
  433. $queue = "qxsms";
  434. }else if($type == 3){ //自动派单
  435. $job = "app\queue\Jobs@autoSend";
  436. $queue = "autoSend";
  437. }else{
  438. return false;
  439. }
  440. if($delay > 0){
  441. \think\Queue::later($delay, $job, $data, $queue);
  442. }else{
  443. \think\Queue::push($job, $data,$queue);
  444. }
  445. return true;
  446. }catch (Exception $e){
  447. trace('队列添加失败:'.$e->getMessage());
  448. return false;
  449. }
  450. }
  451. /**
  452. * 验证短信发送类
  453. * @param $mobile 手机号
  454. * @return bool
  455. */
  456. function send_verify_sms($mobile){
  457. \think\Db::startTrans();
  458. try{
  459. $curTime = time();
  460. $endTime = $curTime + 10*60; //有效期10分钟
  461. $code = mt_rand(100000,999999);
  462. $data = array(
  463. 'mobile' => $mobile,
  464. 'code' => $code,
  465. 'status' => 0,
  466. 'create_yyyymmdd' => date('Ymd',$curTime),
  467. 'create_time' => date('Y-m-d H:i:s',$curTime),
  468. 'end_time' => date('Y-m-d H:i:s',$endTime)
  469. );
  470. $ret = \think\Db::name('sms_record')->insertGetId($data);
  471. if (!$ret) {
  472. exception('短信记录失败');
  473. }
  474. $content = \app\common\util\AppMsg::getSmsMsg(\app\common\util\AppMsg::SMS_VERIFY,['code'=>$code]);
  475. $json = [
  476. 'orgId' => 0,
  477. 'mobiles' => [$mobile],
  478. 'msg' => $content,
  479. 'fromId' => 0,
  480. 'type' => 1
  481. ];
  482. $ret = queue_push(json_encode($json),1);
  483. if(!$ret){
  484. exception('添加短信队列失败');
  485. }
  486. \think\Db::commit();
  487. return true;
  488. }catch (Exception $e){
  489. trace('短信发送失败:'.$e->getMessage());
  490. trace('短信发送号码:'.$mobile);
  491. \think\Db::rollback();
  492. return false;
  493. }
  494. }
  495. /**
  496. * 验证短信验证码
  497. * @param $mobile 手机号
  498. * @param $code 验证码
  499. * @return bool
  500. */
  501. function verify_sms($mobile,$code){
  502. if(!$code){
  503. return false;
  504. }
  505. $curTime = date('Y-m-d H:i:s');
  506. $info = \think\Db::name('sms_record')
  507. ->where('code',$code)
  508. ->where('mobile',$mobile)
  509. ->where('status',0)
  510. ->where('end_time','>=',$curTime)
  511. ->find();
  512. if(!$info){
  513. return false;
  514. }
  515. \think\Db::name('sms_record')->where('id',$info['id'])->setField('status',1);
  516. return true;
  517. }
  518. /**
  519. * 营销短信发送
  520. * @param array $mobiles 手机号
  521. * @param string $msg 内容
  522. * @return bool
  523. */
  524. function send_sms($mobiles,$msg='',$orgId=0,$fromId=0){
  525. if(!$mobiles){
  526. return true;
  527. }
  528. try{
  529. $json = [
  530. 'orgId' => $orgId,
  531. 'mobiles' => $mobiles,
  532. 'msg' => $msg,
  533. 'fromId' => $fromId,
  534. 'type' => 2
  535. ];
  536. $ret = queue_push(json_encode($json),1);
  537. if(!$ret){
  538. exception('添加短信队列失败');
  539. }
  540. return true;
  541. }catch (Exception $e){
  542. trace('短信添加失败:'.$e->getMessage());
  543. trace('短信添加号码:'.implode(',',$mobiles));
  544. \think\Db::rollback();
  545. return false;
  546. }
  547. }
  548. /**
  549. * 极光推送
  550. * @param array $userids
  551. * @param string $msg
  552. * @param array $extras
  553. */
  554. function send_jpush($userids,$type,$msg='',$extras=array()){
  555. if(!$userids){
  556. return true;
  557. }
  558. try {
  559. // {"users":[1,2,3],"type":1,"msg":"有新订单需要你的处理","extra"=>[]}
  560. $json = [
  561. 'users' => $userids,
  562. 'type' => $type,
  563. 'msg' => $msg,
  564. 'extra' => $extras
  565. ];
  566. $ret = queue_push(json_encode($json),0);
  567. if(!$ret){
  568. exception('添加推送队列失败');
  569. }
  570. return true;
  571. } catch (Exception $e) {
  572. trace('push-error:'.$e->getMessage().':'.json_encode($json));
  573. return false;
  574. }
  575. }
  576. /**
  577. * 计算年龄/工龄
  578. * @param $date
  579. * @return false|mixed|string
  580. */
  581. function calculate_age($date){
  582. list($year,$month,$day) = explode("-",$date);
  583. $year_diff = date("Y") - $year;
  584. $month_diff = date("m") - $month;
  585. $day_diff = date("d") - $day;
  586. if ($day_diff < 0 || $month_diff < 0)
  587. $year_diff--;
  588. return $year_diff;
  589. }
  590. // 过滤以逗号分隔的内容,去掉空项
  591. function check_exp_imp($data){
  592. if(!$data){
  593. return '';
  594. }
  595. $vals = explode(',',$data);
  596. $nr = [];
  597. foreach ($vals as $v){
  598. if($v && !in_array($v,$nr)){
  599. $nr[] = $v;
  600. }
  601. }
  602. return empty($nr)?'':implode(',',$nr);
  603. }
  604. /**
  605. * [check_wechat 校验微信号格式]
  606. */
  607. function check_wechat($wechat){
  608. return preg_match('/^[_a-zA-Z0-9]{5,19}+$/isu',$wechat);
  609. }
  610. /**
  611. * [check_link 校验url格式]
  612. */
  613. function check_url($link){
  614. return preg_match("/http[s]?:\/\/[\w.]+[\w\/]*[\w.]*\??[\w=&\+\%]*/is", $link);
  615. }
  616. /**
  617. * 数据签名认证
  618. * @param array $data 被认证的数据
  619. * @return string 签名
  620. */
  621. function data_auth_sign($data) {
  622. //数据类型检测
  623. if(!is_array($data)){
  624. $data = (array)$data;
  625. }
  626. ksort($data); //排序
  627. $code = http_build_query($data); //url编码并生成query字符串
  628. $sign = sha1($code); //生成签名
  629. return $sign;
  630. }
  631. function education($key){
  632. $arr = [
  633. '暂无',
  634. '初中及以下',
  635. '高中',
  636. '中专/中技',
  637. '大专',
  638. '本科',
  639. '硕士',
  640. '博士',
  641. ];
  642. return isset($arr[$key])?$arr[$key]:'暂无';
  643. }
  644. function politics($val){
  645. $arr = [
  646. '暂无',
  647. '中共党员',
  648. '中共预备党员',
  649. '共青团员',
  650. '民革会员',
  651. '民盟盟员',
  652. '民建会员',
  653. '民进会员',
  654. '农工党党员',
  655. '致公党党员',
  656. '九三学社社员',
  657. '台盟盟员',
  658. '无党派人士',
  659. '群众',
  660. ];
  661. return isset($arr[$val])?$arr[$val]:'暂无';
  662. }
  663. /**
  664. * 加载小部件
  665. * @param $template 模板
  666. * @param $data 参数
  667. * @return string
  668. */
  669. function widget_view($template,$data){
  670. return \think\facade\View::fetch($template,$data);
  671. }
  672. /**
  673. * 加载小部件
  674. * @param $template 模板
  675. * @param $data 参数
  676. * @return string
  677. */
  678. function widget($template,$data){
  679. return \think\facade\View::fetch($template,$data);
  680. }
  681. /**
  682. * 创建token
  683. * @param $userid
  684. * @return string
  685. */
  686. function create_token($userid){
  687. //十进制转八进制
  688. $token = decoct($userid).'9'.decoct(intval(time()));
  689. return $token;
  690. }
  691. /**
  692. * select返回的数组进行整数映射转换
  693. *
  694. * @param array $map 映射关系二维数组 array(
  695. * '字段名1'=>array(映射关系数组),
  696. * '字段名2'=>array(映射关系数组),
  697. * ......
  698. * )
  699. * @author 朱亚杰 <zhuyajie@topthink.net>
  700. * @return array
  701. *
  702. * array(
  703. * array('id'=>1,'title'=>'标题','status'=>'1','status_text'=>'正常')
  704. * ....
  705. * )
  706. *
  707. */
  708. function int_to_string(&$data,$map=array('status'=>array(1=>'正常',0=>'禁用'))) {
  709. if($data === false || $data === null ){
  710. return $data;
  711. }
  712. $data = (array)$data;
  713. foreach ($data as $key => $row){
  714. foreach ($map as $col=>$pair){
  715. if(isset($row[$col]) && isset($pair[$row[$col]])){
  716. $data[$key][$col.'_text'] = $pair[$row[$col]];
  717. }
  718. }
  719. }
  720. return $data;
  721. }
  722. //生成guid
  723. function new_guid()
  724. {
  725. if (function_exists('com_create_guid')) {
  726. return com_create_guid();
  727. } else {
  728. mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
  729. $charid = strtoupper(md5(uniqid(rand(), true)));
  730. $hyphen = chr(45);// "-"
  731. $uuid = chr(123)// "{"
  732. .substr($charid, 0, 8).$hyphen
  733. .substr($charid, 8, 4).$hyphen
  734. .substr($charid, 12, 4).$hyphen
  735. .substr($charid, 16, 4).$hyphen
  736. .substr($charid, 20, 12)
  737. .chr(125);// "}"
  738. return $uuid;
  739. }
  740. }
  741. /**
  742. * 获取二维码加密串(urlencode是避免生成的字符被转码)
  743. * @param $type 二维码类型
  744. * @param $id 二维码ID
  745. * @return string 加密后的字符串
  746. */
  747. function get_qrcode_str($type,$id){
  748. $data = array(
  749. 'type' => (string)$type,
  750. 'id' => (int)$id,
  751. 'ucode' => config('app.ucode') //正式使用后不可修改
  752. );
  753. $strs = aes_encrypt(json_encode($data),config('app.encryption_key'));
  754. return str_ireplace('+','_',$strs);
  755. }
  756. /**
  757. * 获取二维码加密串(urlencode是避免生成的字符被转码)
  758. * @param $str 内容
  759. * @return array 解密后的数组
  760. */
  761. function get_qrcode_arr($str){
  762. $str = str_ireplace('_','+',$str);
  763. $data = json_decode(aes_decrypt($str, config('app.encryption_key')),true);
  764. return $data ? $data : array();
  765. }
  766. //本周日期
  767. function get_week_date(){
  768. $week = date('W');
  769. $time = strtotime(date('Y-m-d'));
  770. $arr = array();
  771. for ($i=6; $i>=0; $i--){
  772. $t = $time - $i*24*60*60;
  773. $w = date('W',$t);
  774. if($w == $week) {
  775. $arr[] = date('Ymd', $t);
  776. }
  777. }
  778. return $arr;
  779. }
  780. function getTime(){
  781. return date('Y-m-d H:i:s');
  782. }
  783. function getSite(){
  784. $http_type = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';
  785. return $http_type.$_SERVER['HTTP_HOST'];
  786. }
  787. /**
  788. * 检查字符串是否为空
  789. * @param $str
  790. * @return bool
  791. */
  792. function check_val_empty($str){
  793. if (empty($str)) {
  794. return false;
  795. }
  796. return true;
  797. }
  798. /**
  799. * 对查询结果集进行排序
  800. * @access public
  801. * @param array $list 查询结果
  802. * @param string $field 排序的字段名
  803. * @param array $sortby 排序类型
  804. * asc正向排序 desc逆向排序 nat自然排序
  805. * @return array
  806. */
  807. function list_sort_by($list,$field, $sortby='asc') {
  808. if(is_array($list)){
  809. $refer = $resultSet = array();
  810. foreach ($list as $i => $data)
  811. $refer[$i] = &$data[$field];
  812. switch ($sortby) {
  813. case 'asc': // 正向排序
  814. asort($refer);
  815. break;
  816. case 'desc':// 逆向排序
  817. arsort($refer);
  818. break;
  819. case 'nat': // 自然排序
  820. natcasesort($refer);
  821. break;
  822. }
  823. foreach ( $refer as $key=> $val)
  824. $resultSet[] = &$list[$key];
  825. return $resultSet;
  826. }
  827. return false;
  828. }
  829. // 格式化以符号分隔的字符串,去空值
  830. function format_str($strs,$glup = ','){
  831. if(!$strs){
  832. return '';
  833. }
  834. $arr = explode($glup,$strs);
  835. $news = [];
  836. foreach ($arr as $k=>$v){
  837. if($v){
  838. $news[] = $v;
  839. }
  840. }
  841. return !empty($news)?implode($glup,$news):'';
  842. }
  843. //判断是否是二级调度 1是0否
  844. function check_two_dispatch($userId){
  845. $is = 0;
  846. $roles = \think\Db::name('user_roles')
  847. ->alias('a')
  848. ->join('roles b','a.roles_id=b.id')
  849. ->where('a.user_id',$userId)
  850. ->field('b.level,b.parent_id')
  851. ->find();
  852. if($roles && $roles['level']==2 && $roles['parent_id']==9){
  853. $is = 1;
  854. }
  855. return $is;
  856. }
  857. //二级调度开关
  858. function two_dispatch_off($orgId){
  859. $res = (new \app\common\model\Config())
  860. ->getConfig('org_two_dispatch',$orgId);
  861. return $res?(int)$res:0;
  862. }
  863. //判断是否是一级调度 1是0否
  864. function check_is_dispatch($userId){
  865. $is = 0;
  866. $roles = \think\Db::name('user_roles')
  867. ->alias('a')
  868. ->join('roles b','a.roles_id=b.id')
  869. ->where('a.user_id',$userId)
  870. ->field('b.*')
  871. ->find();
  872. if($roles && $roles['parent_id']==9 && $roles['level']==1){
  873. $is = 1;
  874. }
  875. return $is;
  876. }
  877. //获取调度权限
  878. function get_dispatch_auth($userId){
  879. $ids = [];
  880. $roles = \think\Db::name('user_roles')
  881. ->alias('a')
  882. ->join('roles b','a.roles_id=b.id')
  883. ->where('a.user_id',$userId)
  884. ->field('b.*')
  885. ->find();
  886. if($roles){
  887. $ids = $roles['work_type_mode']?explode(',',$roles['work_type_mode']):[];
  888. }
  889. return $ids;
  890. }
  891. //array
  892. function formatArray($array1,$array2,$type=0){
  893. if($type==0){//保留$array1
  894. foreach ($array2 as $k=>$v){
  895. if(!in_array($k,$array1)){
  896. unset($array2[$k]);
  897. }
  898. }
  899. }else{//剔除$array1
  900. foreach ($array2 as $k=>$v){
  901. if(in_array($k,$array1)){
  902. unset($array2[$k]);
  903. }
  904. }
  905. }
  906. return $array2;
  907. }
  908. // 近一个月
  909. function get_one_month(){
  910. $time = strtotime(date('Y-m-d'));
  911. $arr = array();
  912. for ($i=29; $i>=0; $i--){
  913. $arr[] = date('Ymd',$time - $i*24*60*60);
  914. }
  915. return $arr;
  916. }
  917. function get_unique_id2 ($prefix='')
  918. {
  919. return $prefix . date ( 'Ymd' ) .
  920. substr ( implode ( NULL, array_map ( 'ord', str_split ( substr ( uniqid (), 7, 13 ), 1 ) ) ), 0, 6 );
  921. }
  922. function get_config($name){
  923. $info = \think\Db::name('config')->where('name',$name)->find();
  924. if($info){
  925. return config_parse($info['type'], $info['value']);
  926. }
  927. }
  928. function config_parse($type, $value){
  929. switch ($type) {
  930. case 3: //解析数组
  931. $array = preg_split('/[,;\r\n]+/', trim($value, ",;\r\n"));
  932. if(strpos($value,':')){
  933. $value = array();
  934. foreach ($array as $val) {
  935. list($k, $v) = explode(':', $val);
  936. $value[$k] = $v;
  937. }
  938. }else{
  939. $value = $array;
  940. }
  941. break;
  942. }
  943. return $value;
  944. }
  945. function birthday($birthday){
  946. $age = strtotime($birthday);
  947. if($age === false){
  948. return false;
  949. }
  950. list($y1,$m1,$d1) = explode("-",date("Y-m-d",$age));
  951. $now = strtotime("now");
  952. list($y2,$m2,$d2) = explode("-",date("Y-m-d",$now));
  953. $age = $y2 - $y1;
  954. if((int)($m2.$d2) < (int)($m1.$d1))
  955. $age -= 1;
  956. return $age;
  957. }
  958. function diffBetweenTwoDays ($day1, $day2) {
  959. $second1 = strtotime($day1);
  960. $second2 = strtotime($day2);
  961. if ($second1 < $second2) {
  962. $tmp = $second2;
  963. $second2 = $second1;
  964. $second1 = $tmp;
  965. }
  966. return intval(($second1 - $second2) / 86400)+1;
  967. }
  968. function curl_post($url , $data=array(),$header=[]){
  969. $ch = curl_init();
  970. if(!empty($header)){
  971. curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
  972. curl_setopt($ch, CURLOPT_HEADER, 0);//返回response头部信息
  973. }
  974. curl_setopt($ch, CURLOPT_URL, $url);
  975. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  976. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  977. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  978. // POST数据
  979. curl_setopt($ch, CURLOPT_POST, 1);
  980. // 把post的变量加上
  981. curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  982. $output = curl_exec($ch);
  983. curl_close($ch);
  984. return $output;
  985. }
  986. function nDate($time) {
  987. $tag = 'Y-m-d H:i:s';
  988. $a = substr($time, 0, 10);
  989. $b = substr($time, 10);//毫秒
  990. $date = date($tag, $a - 28800);//.$b
  991. return $date;
  992. }
  993. function getDay($time){
  994. $days =date("t",$time);
  995. for ($i = 0;$i <intval($days);$i++)
  996. {
  997. $day[] =date('Ymd',strtotime("+" .$i." day",strtotime(date("Y-m-01",$time))));
  998. }
  999. return $day;
  1000. }
  1001. //本年所有月份 开始和结束
  1002. function get_month($time){
  1003. $year = $time;
  1004. $yeararr = [];
  1005. for ($i=1; $i <=12 ; $i++) {
  1006. $yeararr[$i] = [
  1007. 'key'=>$year.'年'.$i.'月份',
  1008. 'date'=>date('Ym',strtotime($year.'-'.$i))
  1009. ];
  1010. }
  1011. return $yeararr;
  1012. }
  1013. /**
  1014. * 本月的开始日期
  1015. *
  1016. * @param bool $His 是否展示时分秒 默认true
  1017. *
  1018. * @return false|string
  1019. */
  1020. function beginMonth($His = true)
  1021. {
  1022. $timestamp = mktime(0, 0, 0, date('m'), 1, date('Y'));
  1023. return $His ? date('Y-m-d H:i:s', $timestamp) : date('Y-m-d', $timestamp);
  1024. }
  1025. /**
  1026. * 本月的结束日期
  1027. *
  1028. * @param bool $His 是否展示时分秒 默认true
  1029. *
  1030. * @return false|string
  1031. */
  1032. function endMonth($His = true)
  1033. {
  1034. $timestamp = mktime(23, 59, 59, date('m'), date('t'), date('Y'));
  1035. return $His ? date('Y-m-d H:i:s', $timestamp) : date('Y-m-d', $timestamp);
  1036. }
  1037. /**
  1038. * 几年的开始日期
  1039. *
  1040. * @param bool $His 是否展示时分秒 默认true
  1041. *
  1042. * @return false|string
  1043. */
  1044. function beginYear($His = true)
  1045. {
  1046. $timestamp = mktime(0, 0, 0, 1, 1, date('Y'));
  1047. return $His ? date('Y-m-d H:i:s', $timestamp) : date('Y-m-d', $timestamp);
  1048. }
  1049. /**
  1050. * 本月的结束日期
  1051. *
  1052. * @param bool $His 是否展示时分秒 默认true
  1053. *
  1054. * @return false|string
  1055. */
  1056. function endYear($His = true)
  1057. {
  1058. $timestamp = mktime(23, 59, 59, 12, 31, date('Y'));
  1059. return $His ? date('Y-m-d H:i:s', $timestamp) : date('Y-m-d', $timestamp);
  1060. }
  1061. /**
  1062. * 生成二维码
  1063. * @param $value 二维码内容
  1064. * @param $filepath 保存路径
  1065. * @return bool
  1066. */
  1067. function create_qrcode($value,$filepath)
  1068. {
  1069. include_once env('root_path').'/extend/phpqrcode/phpqrcode.php';
  1070. if (empty($value)) {
  1071. return false;
  1072. }
  1073. $dirfile = dirname($filepath);
  1074. if(!file_exists($dirfile)){
  1075. @mkdir($dirfile,0777);
  1076. }
  1077. //创建一个临时二维码的地址
  1078. $dir = getcwd().DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR.'qrcodeimg'.DIRECTORY_SEPARATOR;
  1079. if (!file_exists($dir)) {
  1080. @mkdir($dir);
  1081. }
  1082. //临时二维码地址
  1083. $QRprefix = $dir.DIRECTORY_SEPARATOR.substr(md5($value), 8, 16);
  1084. $QRTemp = $QRprefix.'_temp.png';
  1085. //判断本地是否存在临时的先删了
  1086. if (file_exists($QRTemp)) {
  1087. @unlink($QRTemp);
  1088. }
  1089. $errorCorrectionLevel = 'H';//容错级别
  1090. $matrixPointSize = 6;//生成图片大小
  1091. //生成二维码图片
  1092. QRcode::png(
  1093. $value,
  1094. $QRTemp,
  1095. $errorCorrectionLevel,
  1096. $matrixPointSize,
  1097. 2
  1098. );
  1099. $orgId = cur_org_id();
  1100. if($orgId == 17){
  1101. $logo = env('root_path').'/public/hb.png';//准备好的logo图片
  1102. }else{
  1103. $logo = env('root_path').'/public/logo.png';//准备好的logo图片
  1104. }
  1105. if (!empty($logo)) {
  1106. $QRBuffer = add_logo_2qrcode($QRTemp, $logo);
  1107. } else {
  1108. $QRBuffer = imagecreatefromstring(print_72dip_300dip(file_get_contents($QRTemp)));
  1109. }
  1110. //删除临时文件
  1111. if (file_exists($QRTemp)) {
  1112. @unlink($QRTemp);
  1113. }
  1114. imagejpeg($QRBuffer,$filepath,100);
  1115. ImageDestroy($QRBuffer);
  1116. }
  1117. //添加LOGO
  1118. function add_logo_2qrcode($QRTempPath, $logoPath)
  1119. {
  1120. $QRBuffer = imagecreatefromstring(print_72dip_300dip(file_get_contents($QRTempPath)));
  1121. $logo = imagecreatefromstring(print_72dip_300dip(file_get_contents($logoPath)));
  1122. $QR_width = imagesx($QRBuffer);//二维码图片宽度
  1123. $QR_height = imagesy($QRBuffer);//二维码图片高度
  1124. $logo_width = imagesx($logo);//logo图片宽度
  1125. $logo_height = imagesy($logo);//logo图片高度
  1126. $logo_qr_width = $QR_width / 5;
  1127. $scale = $logo_width/$logo_qr_width;
  1128. $logo_qr_height = $logo_height/$scale;
  1129. $from_width = ($QR_width - $logo_qr_width) / 2;
  1130. //重新组合图片并调整大小
  1131. imagecopyresampled(
  1132. $QRBuffer,
  1133. $logo,
  1134. $from_width,
  1135. $from_width,
  1136. 0,
  1137. 0,
  1138. $logo_qr_width,
  1139. $logo_qr_height,
  1140. $logo_width,
  1141. $logo_height
  1142. );
  1143. return $QRBuffer;
  1144. }
  1145. //浏览器默认输出为72DPI,打印要求为300DPI
  1146. function print_72dip_300dip($QRBufferStr)
  1147. {
  1148. //数据块长度为9
  1149. $len = pack("N", 9);
  1150. //数据块类型标志为pHYs
  1151. $sign = pack("A*", "pHYs");
  1152. //X方向和Y方向的分辨率均为300DPI(1像素/英寸=39.37像素/米),单位为米(0为未知,1为米)
  1153. $data = pack("NNC", 300 * 39.37, 300 * 39.37, 0x01);
  1154. //CRC检验码由数据块符号和数据域计算得到
  1155. $checksum = pack("N", crc32($sign . $data));
  1156. $phys = $len . $sign . $data . $checksum;
  1157. $pos = strpos($QRBufferStr, "pHYs");
  1158. if ($pos > 0) {
  1159. //修改pHYs数据块
  1160. $QRBufferStr = substr_replace($QRBufferStr, $phys, $pos - 4, 21);
  1161. } else {
  1162. //IHDR结束位置(PNG头固定长度为8,IHDR固定长度为25)
  1163. $pos = 33;
  1164. //将pHYs数据块插入到IHDR之后
  1165. $QRBufferStr = substr_replace($QRBufferStr, $phys, $pos, 0);
  1166. }
  1167. return $QRBufferStr;
  1168. }
  1169. /**
  1170. * 压缩文件/目录成zip
  1171. * @param $path
  1172. * @param $zip
  1173. */
  1174. function add_file_to_zip($path,$zip){
  1175. $handler=opendir($path); //打开当前文件夹由$path指定。
  1176. while(($filename=readdir($handler))!==false){
  1177. if($filename != "." && $filename != ".."){//文件夹文件名字为'.'和‘..’,不要对他们进行操作
  1178. if(is_dir($path."/".$filename)){// 如果读取的某个对象是文件夹,则递归
  1179. add_file_to_zip($path."/".$filename, $zip);
  1180. }else{ //将文件加入zip对象
  1181. $pp = $path."/".$filename;
  1182. $pps = explode('//',$pp);
  1183. $zip->addFile($pp,$pps[1]);
  1184. }
  1185. }
  1186. }
  1187. @closedir($path);
  1188. }
  1189. /**
  1190. * 清空文件夹及文件夹下的所有文件
  1191. * @param $path "./code/"
  1192. */
  1193. function deldir($path){
  1194. //如果是目录则继续
  1195. if(is_dir($path)){
  1196. //扫描一个文件夹内的所有文件夹和文件并返回数组
  1197. $p = scandir($path);
  1198. foreach($p as $val){
  1199. //排除目录中的.和..
  1200. if($val !="." && $val !=".."){
  1201. //如果是目录则递归子目录,继续操作
  1202. if(is_dir($path.$val)){
  1203. //子目录中操作删除文件夹和文件
  1204. deldir($path.$val.'/');
  1205. //目录清空后删除空文件夹
  1206. @rmdir($path.$val.'/');
  1207. }else{
  1208. //如果是文件直接删除
  1209. @unlink($path.$val);
  1210. }
  1211. }
  1212. }
  1213. @rmdir($path);
  1214. }
  1215. }
  1216. /*
  1217. * $userId 用户id
  1218. * $delUrl 删除路径(权限标识)
  1219. * */
  1220. function btnAuth($userId,$delUrl){
  1221. if(is_admin($userId)){
  1222. return true;
  1223. }
  1224. $roles = \think\Db::name('user_roles')
  1225. ->alias('a')
  1226. ->join('roles b','a.roles_id=b.id')
  1227. ->where('a.user_id',$userId)
  1228. ->field('b.*')
  1229. ->find();
  1230. if(!empty($roles)){
  1231. $authS = $roles['auths']?explode(',',$roles['auths']):[];
  1232. if($roles['org_id'] > 0){
  1233. $orgauths = \think\Db::name('org')->where('id',$roles['org_id'])->value('auths');
  1234. $orgauths = $orgauths?explode(',',$orgauths):[];
  1235. $authS = array_intersect($authS,$orgauths);
  1236. }
  1237. $menu = \think\Db::name('menu')
  1238. ->where('url',$delUrl)
  1239. ->where('enable',1)
  1240. ->where('del',0)
  1241. ->find();
  1242. if(!empty($menu) && in_array($menu['id'],$authS)){
  1243. return true;
  1244. }
  1245. }
  1246. return false;
  1247. }
  1248. /**
  1249. * 二维数组按照指定字段进行排序
  1250. * @params array $array 需要排序的数组
  1251. * @params string $field 排序的字段
  1252. * @params string $sort 排序顺序标志 SORT_DESC 降序;SORT_ASC 升序
  1253. */
  1254. function arraySequence($array, $field, $sort = 'SORT_ASC') {
  1255. $arrSort = array();
  1256. foreach ($array as $uniqid =>$row) {
  1257. foreach ($row as $key =>$value) {
  1258. $arrSort[$key][$uniqid] = $value;
  1259. }
  1260. }
  1261. array_multisort($arrSort[$field], constant($sort), $array);
  1262. return $array;
  1263. }
  1264. function getM1($do,$cof){
  1265. $diff = strtotime($do) - strtotime($cof);
  1266. $days = floor(($diff )/ (60*60*24));
  1267. $hours = floor(($diff - $days*60*60*24) / (60*60));
  1268. $minutes = floor(($diff - $days*60*60*24 - $hours*60*60)/ 60);
  1269. $seconds = floor(($diff - $days*60*60*24 - $hours*60*60 - $minutes*60));
  1270. if ($diff < 60) {
  1271. $time_cost = $seconds."秒";
  1272. } else if ($diff >= 60 && $diff < 60*60) {
  1273. $time_cost = $minutes."分钟".$seconds."秒";
  1274. } else if ($diff >= 60*60 && $diff < 60*60*24) {
  1275. $time_cost = $hours."小时".$minutes."分钟".$seconds."秒";
  1276. } else {
  1277. $time_cost = $days."天".$hours."小时".$minutes."分钟".$seconds."秒";
  1278. }
  1279. return $time_cost;
  1280. }
  1281. function getOrgGrabOrder($userId,$orgId){
  1282. $rolesId = \think\Db::name('user_roles')
  1283. ->where('user_id', $userId)
  1284. ->value('roles_id');
  1285. $rolesInfo = \think\Db::name('roles')
  1286. ->where('id', $rolesId)
  1287. ->find();
  1288. if ($rolesInfo['parent_id'] > 0) {
  1289. $rolesId = $rolesInfo['parent_id'];
  1290. }
  1291. $workType = \think\Db::name('work_type_mode')
  1292. ->where('type', 1)
  1293. ->where('roles', 'like', '%' . $rolesId . '%')
  1294. ->column('id');
  1295. $is = 0;
  1296. if(empty($workType)){
  1297. return $is;
  1298. }
  1299. foreach ($workType as $k=>$v){
  1300. $orgGrabOrder = (new Config())->getConfig('org_grab_order'.$v,$orgId);
  1301. if($orgGrabOrder && $orgGrabOrder>0){
  1302. $is = 1;
  1303. }
  1304. }
  1305. return $is;
  1306. }
  1307. //获取近12个月 0=包含本月 1=不包含本月
  1308. function monthlater($type=0){
  1309. $str = array();
  1310. for($i=0;$i<12;$i++){
  1311. if($type == 0){
  1312. $str[$i] =date('Y-m',strtotime('-'.$i.'month'));//包含本月
  1313. }else{
  1314. $str[$i] =date('Y-m',strtotime('-1month-'.$i.'month'));//不包含本月
  1315. }
  1316. }
  1317. sort($str);
  1318. return $str;
  1319. }
  1320. function get_sort_user($orgId,$work=-1,$type_id=-1){
  1321. $rolesId = \think\Db::name('roles')
  1322. ->where('parent_id',7)
  1323. ->where('org_id',$orgId)
  1324. ->where('del',0)
  1325. ->column('id');
  1326. $userRolesId = \think\Db::name('user_roles')
  1327. ->where('roles_id','in',$rolesId)
  1328. ->column('user_id');
  1329. $map[] = ['u.id','in',$userRolesId];
  1330. $map[] = ['u.del','=',0];
  1331. $map[] = ['u.type','=',0];
  1332. $map[] = ['u.enable','=',1];
  1333. $map[] = ['u.enable_sorts','=',1];
  1334. $map[] = ['uo.org_id','=',$orgId];
  1335. if($work >0){
  1336. $map[] = ['u.work','=',$work];
  1337. }
  1338. if($type_id >0){
  1339. $map[] = ['u.type_id','=',$type_id];
  1340. }
  1341. $map= empty($map) ? true: $map;
  1342. $lists = \think\Db::name('user')
  1343. ->alias('u')
  1344. ->join('user_org uo','u.id=uo.user_id')
  1345. ->where($map)
  1346. ->field('u.id,uo.org_id')
  1347. ->order(['u.sorts'=>'desc','u.id'=>'asc'])
  1348. ->column('u.id');
  1349. return $lists;
  1350. }
  1351. function get_sort_user_list($orgId,$work=-1){
  1352. $rolesId = \think\Db::name('roles')
  1353. ->where('parent_id',7)
  1354. ->where('org_id',$orgId)
  1355. ->where('del',0)
  1356. ->column('id');
  1357. $userRolesId = \think\Db::name('user_roles')
  1358. ->where('roles_id','in',$rolesId)
  1359. ->column('user_id');
  1360. $map[] = ['u.id','in',$userRolesId];
  1361. $map[] = ['u.del','=',0];
  1362. $map[] = ['u.type','=',0];
  1363. $map[] = ['u.enable','=',1];
  1364. $map[] = ['u.enable_sorts','=',1];
  1365. $map[] = ['uo.org_id','=',$orgId];
  1366. if($work >0){
  1367. $map[] = ['u.work','=',$work];
  1368. }
  1369. $map= empty($map) ? true: $map;
  1370. $lists = \think\Db::name('user')
  1371. ->alias('u')
  1372. ->join('user_org uo','u.id=uo.user_id')
  1373. ->where($map)
  1374. ->field('u.id,uo.org_id,u.sorts')
  1375. ->order(['u.sorts'=>'desc','u.id'=>'asc'])
  1376. ->select();
  1377. return $lists;
  1378. }
  1379. function getDateFromRange($startdate, $enddate){
  1380. $stimestamp = strtotime($startdate);
  1381. $etimestamp = strtotime($enddate);
  1382. // 计算日期段内有多少天
  1383. $days = ($etimestamp-$stimestamp)/86400+1;
  1384. // 保存每天日期
  1385. $date = array();
  1386. for($i=0; $i<$days; $i++){
  1387. $date[] = date('Y-m-d', $stimestamp+(86400*$i));
  1388. }
  1389. return $date;
  1390. }
  1391. /**
  1392. * 加密cookie
  1393. * @param $name
  1394. * @param $val
  1395. * @param $expire
  1396. */
  1397. function encodecookie($name,$val,$expire=100*365*24*60*60){
  1398. cookie($name,think_encrypt($val),$expire);
  1399. }
  1400. /**
  1401. * 解密cookie
  1402. * @param $name
  1403. */
  1404. function decodecookie($name){
  1405. return think_decrypt(cookie($name));
  1406. }
  1407. /**
  1408. * 获取点餐微信公众号配置
  1409. * @param $orgId 组织
  1410. * @return array|bool false=该组织未配置微信账号
  1411. */
  1412. function get_pay_wechat($orgId){
  1413. $wechat = \think\Db::name('dinner_wechat')->where('org_id',$orgId)->order('id','desc')->find();
  1414. if(!$wechat){
  1415. return [];
  1416. }
  1417. $option = [
  1418. 'user_type' => '3'.$wechat['id'],
  1419. 'app_id' => trim($wechat['app_id']),
  1420. 'secret' => trim($wechat['secret']),
  1421. 'mch_id' => trim($wechat['mch_id']), // 商户号
  1422. 'key' => trim($wechat['key']), // API 密钥
  1423. // 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书)
  1424. 'cert_path' => env('root_path').'public'.$wechat['cert_path'],
  1425. 'key_path' => env('root_path').'public'.$wechat['key_path'],
  1426. // 下面为可选项
  1427. // 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
  1428. 'response_type' => 'array',
  1429. 'log' => [
  1430. 'level' => 'error',
  1431. 'file' => env('runtime_path').'/log/wechat.log',
  1432. ],
  1433. ];
  1434. return $option;
  1435. }
  1436. /**
  1437. * 获取某周的周一和周末日期
  1438. * @param int $index //0则代表本周 1则代表下一周
  1439. * @return array
  1440. */
  1441. function get_week_days($index = 0,$format="Y-m-d"){ //0则代表本周
  1442. $week = date('w') == 0 ? 7 : date('w');
  1443. $start = strtotime('today ' . (- ($week - 1) + (7 * $index)) . 'day');
  1444. $end = strtotime('today ' . ((8 - $week) + (7 * $index)) . 'day -1second');
  1445. return [date($format,$start), date($format,$end)];
  1446. }
  1447. /**
  1448. * 获取某天是星期几
  1449. * @param $day 例如:2023-03-30
  1450. * @return string
  1451. */
  1452. function get_week_txt($day){
  1453. $da = date("w",strtotime($day));
  1454. if( $da == "1" ){
  1455. return '周一';
  1456. }else if( $da == "2" ){
  1457. return '周二';
  1458. }else if( $da == "3" ){
  1459. return '周三';
  1460. }else if( $da == "4" ){
  1461. return '周四';
  1462. }else if( $da == "5" ){
  1463. return '周五';
  1464. }else if( $da == "6" ){
  1465. return '周六';
  1466. }else if( $da == "0" ){
  1467. return '周日';
  1468. }
  1469. return '';
  1470. }
  1471. /**
  1472. * 连接国天sp数据库
  1473. * @param string $name
  1474. * @return \think\db\Query
  1475. */
  1476. function gtspdb($name = ''){
  1477. $config = config('database.db_config_gt_sp');
  1478. return \db($name,$config,false);
  1479. }
  1480. /**
  1481. * 连接霸洁云数据库
  1482. * @param string $name
  1483. * @return \think\db\Query
  1484. */
  1485. function bjydb($name = ''){
  1486. $config = config('database.db_config_bjy');
  1487. return \db($name,$config,false);
  1488. }
  1489. /**
  1490. * 连接新城域数据库
  1491. * @param string $name
  1492. * @return \think\db\Query
  1493. */
  1494. function xcydb($name = ''){
  1495. $config = config('database.db_config_xcy');
  1496. return \db($name,$config,false);
  1497. }
  1498. /**
  1499. * 秒数格式化
  1500. * @param $diff
  1501. * @return string
  1502. */
  1503. function second_to_str($diff){
  1504. if($diff <= 0){
  1505. return '0秒';
  1506. }
  1507. $days = floor(($diff )/ (60*60*24));
  1508. $hours = floor(($diff - $days*60*60*24) / (60*60));
  1509. $minutes = floor(($diff - $days*60*60*24 - $hours*60*60)/ 60);
  1510. $seconds = floor(($diff - $days*60*60*24 - $hours*60*60 - $minutes*60));
  1511. if ($diff < 60) {
  1512. $time_cost = $seconds."秒";
  1513. } else if ($diff >= 60 && $diff < 60*60) {
  1514. $time_cost = $minutes."分钟".$seconds."秒";
  1515. } else if ($diff >= 60*60 && $diff < 60*60*24) {
  1516. $time_cost = $hours."小时".$minutes."分钟".$seconds."秒";
  1517. } else {
  1518. $time_cost = $days."天".$hours."小时".$minutes."分钟".$seconds."秒";
  1519. }
  1520. return $time_cost;
  1521. }
  1522. //计算指定时间中间小时
  1523. function getMinFromRange($startdate, $enddate){
  1524. $stimestamp = strtotime($startdate);
  1525. $etimestamp = strtotime($enddate);
  1526. // 计算日期段内有多少小时
  1527. $days = ($etimestamp-$stimestamp)/3600;
  1528. // 保存
  1529. $date = array();
  1530. for($i=0; $i<=$days; $i++){
  1531. $date[] = date('Y-m-d H:i:s', $stimestamp+(3600*$i));
  1532. }
  1533. return $date;
  1534. }