common.php 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672
  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. return config("app.app_host");
  787. }
  788. /**
  789. * 检查字符串是否为空
  790. * @param $str
  791. * @return bool
  792. */
  793. function check_val_empty($str){
  794. if (empty($str)) {
  795. return false;
  796. }
  797. return true;
  798. }
  799. /**
  800. * 对查询结果集进行排序
  801. * @access public
  802. * @param array $list 查询结果
  803. * @param string $field 排序的字段名
  804. * @param array $sortby 排序类型
  805. * asc正向排序 desc逆向排序 nat自然排序
  806. * @return array
  807. */
  808. function list_sort_by($list,$field, $sortby='asc') {
  809. if(is_array($list)){
  810. $refer = $resultSet = array();
  811. foreach ($list as $i => $data)
  812. $refer[$i] = &$data[$field];
  813. switch ($sortby) {
  814. case 'asc': // 正向排序
  815. asort($refer);
  816. break;
  817. case 'desc':// 逆向排序
  818. arsort($refer);
  819. break;
  820. case 'nat': // 自然排序
  821. natcasesort($refer);
  822. break;
  823. }
  824. foreach ( $refer as $key=> $val)
  825. $resultSet[] = &$list[$key];
  826. return $resultSet;
  827. }
  828. return false;
  829. }
  830. // 格式化以符号分隔的字符串,去空值
  831. function format_str($strs,$glup = ','){
  832. if(!$strs){
  833. return '';
  834. }
  835. $arr = explode($glup,$strs);
  836. $news = [];
  837. foreach ($arr as $k=>$v){
  838. if($v){
  839. $news[] = $v;
  840. }
  841. }
  842. return !empty($news)?implode($glup,$news):'';
  843. }
  844. //判断是否是二级调度 1是0否
  845. function check_two_dispatch($userId){
  846. $is = 0;
  847. $roles = \think\Db::name('user_roles')
  848. ->alias('a')
  849. ->join('roles b','a.roles_id=b.id')
  850. ->where('a.user_id',$userId)
  851. ->field('b.level,b.parent_id')
  852. ->find();
  853. if($roles && $roles['level']==2 && $roles['parent_id']==9){
  854. $is = 1;
  855. }
  856. return $is;
  857. }
  858. //二级调度开关
  859. function two_dispatch_off($orgId){
  860. $res = (new \app\common\model\Config())
  861. ->getConfig('org_two_dispatch',$orgId);
  862. return $res?(int)$res:0;
  863. }
  864. //判断是否是一级调度 1是0否
  865. function check_is_dispatch($userId){
  866. $is = 0;
  867. $roles = \think\Db::name('user_roles')
  868. ->alias('a')
  869. ->join('roles b','a.roles_id=b.id')
  870. ->where('a.user_id',$userId)
  871. ->field('b.*')
  872. ->find();
  873. if($roles && $roles['parent_id']==9 && $roles['level']==1){
  874. $is = 1;
  875. }
  876. return $is;
  877. }
  878. //获取调度权限
  879. function get_dispatch_auth($userId){
  880. $ids = [];
  881. $roles = \think\Db::name('user_roles')
  882. ->alias('a')
  883. ->join('roles b','a.roles_id=b.id')
  884. ->where('a.user_id',$userId)
  885. ->field('b.*')
  886. ->find();
  887. if($roles){
  888. $ids = $roles['work_type_mode']?explode(',',$roles['work_type_mode']):[];
  889. }
  890. return $ids;
  891. }
  892. //array
  893. function formatArray($array1,$array2,$type=0){
  894. if($type==0){//保留$array1
  895. foreach ($array2 as $k=>$v){
  896. if(!in_array($k,$array1)){
  897. unset($array2[$k]);
  898. }
  899. }
  900. }else{//剔除$array1
  901. foreach ($array2 as $k=>$v){
  902. if(in_array($k,$array1)){
  903. unset($array2[$k]);
  904. }
  905. }
  906. }
  907. return $array2;
  908. }
  909. // 近一个月
  910. function get_one_month(){
  911. $time = strtotime(date('Y-m-d'));
  912. $arr = array();
  913. for ($i=29; $i>=0; $i--){
  914. $arr[] = date('Ymd',$time - $i*24*60*60);
  915. }
  916. return $arr;
  917. }
  918. function get_unique_id2 ($prefix='')
  919. {
  920. return $prefix . date ( 'Ymd' ) .
  921. substr ( implode ( NULL, array_map ( 'ord', str_split ( substr ( uniqid (), 7, 13 ), 1 ) ) ), 0, 6 );
  922. }
  923. function get_config($name){
  924. $info = \think\Db::name('config')->where('name',$name)->find();
  925. if($info){
  926. return config_parse($info['type'], $info['value']);
  927. }
  928. }
  929. function config_parse($type, $value){
  930. switch ($type) {
  931. case 3: //解析数组
  932. $array = preg_split('/[,;\r\n]+/', trim($value, ",;\r\n"));
  933. if(strpos($value,':')){
  934. $value = array();
  935. foreach ($array as $val) {
  936. list($k, $v) = explode(':', $val);
  937. $value[$k] = $v;
  938. }
  939. }else{
  940. $value = $array;
  941. }
  942. break;
  943. }
  944. return $value;
  945. }
  946. function birthday($birthday){
  947. $age = strtotime($birthday);
  948. if($age === false){
  949. return false;
  950. }
  951. list($y1,$m1,$d1) = explode("-",date("Y-m-d",$age));
  952. $now = strtotime("now");
  953. list($y2,$m2,$d2) = explode("-",date("Y-m-d",$now));
  954. $age = $y2 - $y1;
  955. if((int)($m2.$d2) < (int)($m1.$d1))
  956. $age -= 1;
  957. return $age;
  958. }
  959. function diffBetweenTwoDays ($day1, $day2) {
  960. $second1 = strtotime($day1);
  961. $second2 = strtotime($day2);
  962. if ($second1 < $second2) {
  963. $tmp = $second2;
  964. $second2 = $second1;
  965. $second1 = $tmp;
  966. }
  967. return intval(($second1 - $second2) / 86400)+1;
  968. }
  969. function curl_post($url , $data=array()){
  970. $ch = curl_init();
  971. curl_setopt($ch, CURLOPT_URL, $url);
  972. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  973. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  974. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  975. // POST数据
  976. curl_setopt($ch, CURLOPT_POST, 1);
  977. // 把post的变量加上
  978. curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  979. $output = curl_exec($ch);
  980. curl_close($ch);
  981. return $output;
  982. }
  983. function nDate($time) {
  984. $tag = 'Y-m-d H:i:s';
  985. $a = substr($time, 0, 10);
  986. $b = substr($time, 10);//毫秒
  987. $date = date($tag, $a - 28800);//.$b
  988. return $date;
  989. }
  990. function getDay($time){
  991. $days =date("t",$time);
  992. for ($i = 0;$i <intval($days);$i++)
  993. {
  994. $day[] =date('Ymd',strtotime("+" .$i." day",strtotime(date("Y-m-01",$time))));
  995. }
  996. return $day;
  997. }
  998. //本年所有月份 开始和结束
  999. function get_month($time){
  1000. $year = $time;
  1001. $yeararr = [];
  1002. for ($i=1; $i <=12 ; $i++) {
  1003. $yeararr[$i] = [
  1004. 'key'=>$year.'年'.$i.'月份',
  1005. 'date'=>date('Ym',strtotime($year.'-'.$i))
  1006. ];
  1007. }
  1008. return $yeararr;
  1009. }
  1010. //本年所有月份 开始和结束
  1011. function get_month1($time){
  1012. $year = $time;
  1013. $yeararr = [];
  1014. for ($i=1; $i <=12 ; $i++) {
  1015. $yeararr[$i-1] = [
  1016. 'key'=>$year.'年'.$i.'月份',
  1017. 'date'=>date('Ym',strtotime($year.'-'.$i))
  1018. ];
  1019. }
  1020. return $yeararr;
  1021. }
  1022. /**
  1023. * 本月的开始日期
  1024. *
  1025. * @param bool $His 是否展示时分秒 默认true
  1026. *
  1027. * @return false|string
  1028. */
  1029. function beginMonth($His = true)
  1030. {
  1031. $timestamp = mktime(0, 0, 0, date('m'), 1, date('Y'));
  1032. return $His ? date('Y-m-d H:i:s', $timestamp) : date('Y-m-d', $timestamp);
  1033. }
  1034. /**
  1035. * 本月的结束日期
  1036. *
  1037. * @param bool $His 是否展示时分秒 默认true
  1038. *
  1039. * @return false|string
  1040. */
  1041. function endMonth($His = true)
  1042. {
  1043. $timestamp = mktime(23, 59, 59, date('m'), date('t'), date('Y'));
  1044. return $His ? date('Y-m-d H:i:s', $timestamp) : date('Y-m-d', $timestamp);
  1045. }
  1046. /**
  1047. * 几年的开始日期
  1048. *
  1049. * @param bool $His 是否展示时分秒 默认true
  1050. *
  1051. * @return false|string
  1052. */
  1053. function beginYear($His = true)
  1054. {
  1055. $timestamp = mktime(0, 0, 0, 1, 1, date('Y'));
  1056. return $His ? date('Y-m-d H:i:s', $timestamp) : date('Y-m-d', $timestamp);
  1057. }
  1058. /**
  1059. * 本月的结束日期
  1060. *
  1061. * @param bool $His 是否展示时分秒 默认true
  1062. *
  1063. * @return false|string
  1064. */
  1065. function endYear($His = true)
  1066. {
  1067. $timestamp = mktime(23, 59, 59, 12, 31, date('Y'));
  1068. return $His ? date('Y-m-d H:i:s', $timestamp) : date('Y-m-d', $timestamp);
  1069. }
  1070. /**
  1071. * 生成二维码
  1072. * @param $value 二维码内容
  1073. * @param $filepath 保存路径
  1074. * @return bool
  1075. */
  1076. function create_qrcode($value,$filepath)
  1077. {
  1078. include_once env('root_path').'/extend/phpqrcode/phpqrcode.php';
  1079. if (empty($value)) {
  1080. return false;
  1081. }
  1082. $dirfile = dirname($filepath);
  1083. if(!file_exists($dirfile)){
  1084. @mkdir($dirfile,0777);
  1085. }
  1086. //创建一个临时二维码的地址
  1087. $dir = getcwd().DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR.'qrcodeimg'.DIRECTORY_SEPARATOR;
  1088. if (!file_exists($dir)) {
  1089. @mkdir($dir);
  1090. }
  1091. //临时二维码地址
  1092. $QRprefix = $dir.DIRECTORY_SEPARATOR.substr(md5($value), 8, 16);
  1093. $QRTemp = $QRprefix.'_temp.png';
  1094. //判断本地是否存在临时的先删了
  1095. if (file_exists($QRTemp)) {
  1096. @unlink($QRTemp);
  1097. }
  1098. $errorCorrectionLevel = 'H';//容错级别
  1099. $matrixPointSize = 6;//生成图片大小
  1100. //生成二维码图片
  1101. QRcode::png(
  1102. $value,
  1103. $QRTemp,
  1104. $errorCorrectionLevel,
  1105. $matrixPointSize,
  1106. 2
  1107. );
  1108. $orgId = cur_org_id();
  1109. if($orgId == 17){
  1110. $logo = env('root_path').'/public/hb.png';//准备好的logo图片
  1111. }else{
  1112. $logo = env('root_path').'/public/logo.png';//准备好的logo图片
  1113. }
  1114. if (!empty($logo)) {
  1115. $QRBuffer = add_logo_2qrcode($QRTemp, $logo);
  1116. } else {
  1117. $QRBuffer = imagecreatefromstring(print_72dip_300dip(file_get_contents($QRTemp)));
  1118. }
  1119. //删除临时文件
  1120. if (file_exists($QRTemp)) {
  1121. @unlink($QRTemp);
  1122. }
  1123. imagejpeg($QRBuffer,$filepath,100);
  1124. ImageDestroy($QRBuffer);
  1125. }
  1126. //添加LOGO
  1127. function add_logo_2qrcode($QRTempPath, $logoPath)
  1128. {
  1129. $QRBuffer = imagecreatefromstring(print_72dip_300dip(file_get_contents($QRTempPath)));
  1130. $logo = imagecreatefromstring(print_72dip_300dip(file_get_contents($logoPath)));
  1131. $QR_width = imagesx($QRBuffer);//二维码图片宽度
  1132. $QR_height = imagesy($QRBuffer);//二维码图片高度
  1133. $logo_width = imagesx($logo);//logo图片宽度
  1134. $logo_height = imagesy($logo);//logo图片高度
  1135. $logo_qr_width = $QR_width / 5;
  1136. $scale = $logo_width/$logo_qr_width;
  1137. $logo_qr_height = $logo_height/$scale;
  1138. $from_width = ($QR_width - $logo_qr_width) / 2;
  1139. //重新组合图片并调整大小
  1140. imagecopyresampled(
  1141. $QRBuffer,
  1142. $logo,
  1143. $from_width,
  1144. $from_width,
  1145. 0,
  1146. 0,
  1147. $logo_qr_width,
  1148. $logo_qr_height,
  1149. $logo_width,
  1150. $logo_height
  1151. );
  1152. return $QRBuffer;
  1153. }
  1154. //浏览器默认输出为72DPI,打印要求为300DPI
  1155. function print_72dip_300dip($QRBufferStr)
  1156. {
  1157. //数据块长度为9
  1158. $len = pack("N", 9);
  1159. //数据块类型标志为pHYs
  1160. $sign = pack("A*", "pHYs");
  1161. //X方向和Y方向的分辨率均为300DPI(1像素/英寸=39.37像素/米),单位为米(0为未知,1为米)
  1162. $data = pack("NNC", 300 * 39.37, 300 * 39.37, 0x01);
  1163. //CRC检验码由数据块符号和数据域计算得到
  1164. $checksum = pack("N", crc32($sign . $data));
  1165. $phys = $len . $sign . $data . $checksum;
  1166. $pos = strpos($QRBufferStr, "pHYs");
  1167. if ($pos > 0) {
  1168. //修改pHYs数据块
  1169. $QRBufferStr = substr_replace($QRBufferStr, $phys, $pos - 4, 21);
  1170. } else {
  1171. //IHDR结束位置(PNG头固定长度为8,IHDR固定长度为25)
  1172. $pos = 33;
  1173. //将pHYs数据块插入到IHDR之后
  1174. $QRBufferStr = substr_replace($QRBufferStr, $phys, $pos, 0);
  1175. }
  1176. return $QRBufferStr;
  1177. }
  1178. /**
  1179. * 压缩文件/目录成zip
  1180. * @param $path
  1181. * @param $zip
  1182. */
  1183. function add_file_to_zip($path,$zip){
  1184. $handler=opendir($path); //打开当前文件夹由$path指定。
  1185. while(($filename=readdir($handler))!==false){
  1186. if($filename != "." && $filename != ".."){//文件夹文件名字为'.'和‘..’,不要对他们进行操作
  1187. if(is_dir($path."/".$filename)){// 如果读取的某个对象是文件夹,则递归
  1188. add_file_to_zip($path."/".$filename, $zip);
  1189. }else{ //将文件加入zip对象
  1190. $pp = $path."/".$filename;
  1191. $pps = explode('//',$pp);
  1192. $zip->addFile($pp,$pps[1]);
  1193. }
  1194. }
  1195. }
  1196. @closedir($path);
  1197. }
  1198. /**
  1199. * 清空文件夹及文件夹下的所有文件
  1200. * @param $path "./code/"
  1201. */
  1202. function deldir($path){
  1203. //如果是目录则继续
  1204. if(is_dir($path)){
  1205. //扫描一个文件夹内的所有文件夹和文件并返回数组
  1206. $p = scandir($path);
  1207. foreach($p as $val){
  1208. //排除目录中的.和..
  1209. if($val !="." && $val !=".."){
  1210. //如果是目录则递归子目录,继续操作
  1211. if(is_dir($path.$val)){
  1212. //子目录中操作删除文件夹和文件
  1213. deldir($path.$val.'/');
  1214. //目录清空后删除空文件夹
  1215. @rmdir($path.$val.'/');
  1216. }else{
  1217. //如果是文件直接删除
  1218. @unlink($path.$val);
  1219. }
  1220. }
  1221. }
  1222. @rmdir($path);
  1223. }
  1224. }
  1225. /*
  1226. * $userId 用户id
  1227. * $delUrl 删除路径(权限标识)
  1228. * */
  1229. function btnAuth($userId,$delUrl){
  1230. if(is_admin($userId)){
  1231. return true;
  1232. }
  1233. $roles = \think\Db::name('user_roles')
  1234. ->alias('a')
  1235. ->join('roles b','a.roles_id=b.id')
  1236. ->where('a.user_id',$userId)
  1237. ->field('b.*')
  1238. ->find();
  1239. if(!empty($roles)){
  1240. $authS = $roles['auths']?explode(',',$roles['auths']):[];
  1241. if($roles['org_id'] > 0){
  1242. $orgauths = \think\Db::name('org')->where('id',$roles['org_id'])->value('auths');
  1243. $orgauths = $orgauths?explode(',',$orgauths):[];
  1244. $authS = array_intersect($authS,$orgauths);
  1245. }
  1246. $menu = \think\Db::name('menu')
  1247. ->where('url',$delUrl)
  1248. ->where('enable',1)
  1249. ->where('del',0)
  1250. ->find();
  1251. if(!empty($menu) && in_array($menu['id'],$authS)){
  1252. return true;
  1253. }
  1254. }
  1255. return false;
  1256. }
  1257. /**
  1258. * 二维数组按照指定字段进行排序
  1259. * @params array $array 需要排序的数组
  1260. * @params string $field 排序的字段
  1261. * @params string $sort 排序顺序标志 SORT_DESC 降序;SORT_ASC 升序
  1262. */
  1263. function arraySequence($array, $field, $sort = 'SORT_ASC') {
  1264. $arrSort = array();
  1265. foreach ($array as $uniqid =>$row) {
  1266. foreach ($row as $key =>$value) {
  1267. $arrSort[$key][$uniqid] = $value;
  1268. }
  1269. }
  1270. array_multisort($arrSort[$field], constant($sort), $array);
  1271. return $array;
  1272. }
  1273. function getM1($do,$cof){
  1274. $diff = strtotime($do) - strtotime($cof);
  1275. $days = floor(($diff )/ (60*60*24));
  1276. $hours = floor(($diff - $days*60*60*24) / (60*60));
  1277. $minutes = floor(($diff - $days*60*60*24 - $hours*60*60)/ 60);
  1278. $seconds = floor(($diff - $days*60*60*24 - $hours*60*60 - $minutes*60));
  1279. if ($diff < 60) {
  1280. $time_cost = $seconds."秒";
  1281. } else if ($diff >= 60 && $diff < 60*60) {
  1282. $time_cost = $minutes."分钟".$seconds."秒";
  1283. } else if ($diff >= 60*60 && $diff < 60*60*24) {
  1284. $time_cost = $hours."小时".$minutes."分钟".$seconds."秒";
  1285. } else {
  1286. $time_cost = $days."天".$hours."小时".$minutes."分钟".$seconds."秒";
  1287. }
  1288. return $time_cost;
  1289. }
  1290. function getOrgGrabOrder($userId,$orgId){
  1291. $rolesId = \think\Db::name('user_roles')
  1292. ->where('user_id', $userId)
  1293. ->value('roles_id');
  1294. $rolesInfo = \think\Db::name('roles')
  1295. ->where('id', $rolesId)
  1296. ->find();
  1297. if ($rolesInfo['parent_id'] > 0) {
  1298. $rolesId = $rolesInfo['parent_id'];
  1299. }
  1300. $workType = \think\Db::name('work_type_mode')
  1301. ->where('type', 1)
  1302. ->where('roles', 'like', '%' . $rolesId . '%')
  1303. ->column('id');
  1304. $is = 0;
  1305. if(empty($workType)){
  1306. return $is;
  1307. }
  1308. foreach ($workType as $k=>$v){
  1309. $orgGrabOrder = (new Config())->getConfig('org_grab_order'.$v,$orgId);
  1310. if($orgGrabOrder && $orgGrabOrder>0){
  1311. $is = 1;
  1312. }
  1313. }
  1314. return $is;
  1315. }
  1316. //获取近12个月 0=包含本月 1=不包含本月
  1317. function monthlater($type=0){
  1318. $str = array();
  1319. for($i=0;$i<12;$i++){
  1320. if($type == 0){
  1321. $str[$i] =date('Y-m',strtotime('-'.$i.'month'));//包含本月
  1322. }else{
  1323. $str[$i] =date('Y-m',strtotime('-1month-'.$i.'month'));//不包含本月
  1324. }
  1325. }
  1326. sort($str);
  1327. return $str;
  1328. }
  1329. function get_sort_user($orgId,$work=-1,$type_id=-1){
  1330. $rolesId = \think\Db::name('roles')
  1331. ->where('parent_id',7)
  1332. ->where('org_id',$orgId)
  1333. ->where('del',0)
  1334. ->column('id');
  1335. $userRolesId = \think\Db::name('user_roles')
  1336. ->where('roles_id','in',$rolesId)
  1337. ->column('user_id');
  1338. $map[] = ['u.id','in',$userRolesId];
  1339. $map[] = ['u.del','=',0];
  1340. $map[] = ['u.type','=',0];
  1341. $map[] = ['u.enable','=',1];
  1342. $map[] = ['u.enable_sorts','=',1];
  1343. $map[] = ['uo.org_id','=',$orgId];
  1344. if($work >0){
  1345. $map[] = ['u.work','=',$work];
  1346. }
  1347. if($type_id >0){
  1348. $map[] = ['u.type_id','=',$type_id];
  1349. }
  1350. $map= empty($map) ? true: $map;
  1351. $lists = \think\Db::name('user')
  1352. ->alias('u')
  1353. ->join('user_org uo','u.id=uo.user_id')
  1354. ->where($map)
  1355. ->field('u.id,uo.org_id')
  1356. ->order(['u.sorts'=>'desc','u.id'=>'asc'])
  1357. ->column('u.id');
  1358. return $lists;
  1359. }
  1360. function get_sort_user_list($orgId,$work=-1){
  1361. $rolesId = \think\Db::name('roles')
  1362. ->where('parent_id',7)
  1363. ->where('org_id',$orgId)
  1364. ->where('del',0)
  1365. ->column('id');
  1366. $userRolesId = \think\Db::name('user_roles')
  1367. ->where('roles_id','in',$rolesId)
  1368. ->column('user_id');
  1369. $map[] = ['u.id','in',$userRolesId];
  1370. $map[] = ['u.del','=',0];
  1371. $map[] = ['u.type','=',0];
  1372. $map[] = ['u.enable','=',1];
  1373. $map[] = ['u.enable_sorts','=',1];
  1374. $map[] = ['uo.org_id','=',$orgId];
  1375. if($work >0){
  1376. $map[] = ['u.work','=',$work];
  1377. }
  1378. $map= empty($map) ? true: $map;
  1379. $lists = \think\Db::name('user')
  1380. ->alias('u')
  1381. ->join('user_org uo','u.id=uo.user_id')
  1382. ->where($map)
  1383. ->field('u.id,uo.org_id,u.sorts')
  1384. ->order(['u.sorts'=>'desc','u.id'=>'asc'])
  1385. ->select();
  1386. return $lists;
  1387. }
  1388. function getDateFromRange($startdate, $enddate){
  1389. $stimestamp = strtotime($startdate);
  1390. $etimestamp = strtotime($enddate);
  1391. // 计算日期段内有多少天
  1392. $days = ($etimestamp-$stimestamp)/86400+1;
  1393. // 保存每天日期
  1394. $date = array();
  1395. for($i=0; $i<$days; $i++){
  1396. $date[] = date('Y-m-d', $stimestamp+(86400*$i));
  1397. }
  1398. return $date;
  1399. }
  1400. /**
  1401. * 加密cookie
  1402. * @param $name
  1403. * @param $val
  1404. * @param $expire
  1405. */
  1406. function encodecookie($name,$val,$expire=100*365*24*60*60){
  1407. cookie($name,think_encrypt($val),$expire);
  1408. }
  1409. /**
  1410. * 解密cookie
  1411. * @param $name
  1412. */
  1413. function decodecookie($name){
  1414. return think_decrypt(cookie($name));
  1415. }
  1416. /**
  1417. * 获取点餐微信公众号配置
  1418. * @param $orgId 组织
  1419. * @return array|bool false=该组织未配置微信账号
  1420. */
  1421. function get_pay_wechat($orgId){
  1422. $wechat = \think\Db::name('dinner_wechat')->where('org_id',$orgId)->order('id','desc')->find();
  1423. if(!$wechat){
  1424. return [];
  1425. }
  1426. $option = [
  1427. 'user_type' => '3'.$wechat['id'],
  1428. 'app_id' => trim($wechat['app_id']),
  1429. 'secret' => trim($wechat['secret']),
  1430. 'mch_id' => trim($wechat['mch_id']), // 商户号
  1431. 'key' => trim($wechat['key']), // API 密钥
  1432. // 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书)
  1433. 'cert_path' => env('root_path').'public'.$wechat['cert_path'],
  1434. 'key_path' => env('root_path').'public'.$wechat['key_path'],
  1435. // 下面为可选项
  1436. // 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
  1437. 'response_type' => 'array',
  1438. 'log' => [
  1439. 'level' => 'error',
  1440. 'file' => env('runtime_path').'/log/wechat.log',
  1441. ],
  1442. ];
  1443. return $option;
  1444. }
  1445. /**
  1446. * 获取某周的周一和周末日期
  1447. * @param int $index //0则代表本周 1则代表下一周
  1448. * @return array
  1449. */
  1450. function get_week_days($index = 0,$format="Y-m-d"){ //0则代表本周
  1451. $week = date('w') == 0 ? 7 : date('w');
  1452. $start = strtotime('today ' . (- ($week - 1) + (7 * $index)) . 'day');
  1453. $end = strtotime('today ' . ((8 - $week) + (7 * $index)) . 'day -1second');
  1454. return [date($format,$start), date($format,$end)];
  1455. }
  1456. /**
  1457. * 获取某天是星期几
  1458. * @param $day 例如:2023-03-30
  1459. * @return string
  1460. */
  1461. function get_week_txt($day){
  1462. $da = date("w",strtotime($day));
  1463. if( $da == "1" ){
  1464. return '周一';
  1465. }else if( $da == "2" ){
  1466. return '周二';
  1467. }else if( $da == "3" ){
  1468. return '周三';
  1469. }else if( $da == "4" ){
  1470. return '周四';
  1471. }else if( $da == "5" ){
  1472. return '周五';
  1473. }else if( $da == "6" ){
  1474. return '周六';
  1475. }else if( $da == "0" ){
  1476. return '周日';
  1477. }
  1478. return '';
  1479. }
  1480. /**
  1481. * 秒数格式化
  1482. * @param $diff
  1483. * @return string
  1484. */
  1485. function second_to_str($diff){
  1486. if($diff <= 0){
  1487. return '0秒';
  1488. }
  1489. $days = floor(($diff )/ (60*60*24));
  1490. $hours = floor(($diff - $days*60*60*24) / (60*60));
  1491. $minutes = floor(($diff - $days*60*60*24 - $hours*60*60)/ 60);
  1492. $seconds = floor(($diff - $days*60*60*24 - $hours*60*60 - $minutes*60));
  1493. if ($diff < 60) {
  1494. $time_cost = $seconds."秒";
  1495. } else if ($diff >= 60 && $diff < 60*60) {
  1496. $time_cost = $minutes."分钟".$seconds."秒";
  1497. } else if ($diff >= 60*60 && $diff < 60*60*24) {
  1498. $time_cost = $hours."小时".$minutes."分钟".$seconds."秒";
  1499. } else {
  1500. $time_cost = $days."天".$hours."小时".$minutes."分钟".$seconds."秒";
  1501. }
  1502. return $time_cost;
  1503. }
  1504. //字符串换行;
  1505. function force_black_string_ex($str, $num){
  1506. $str_length = strlen($str);
  1507. $strNum = $str_length/$num>0 ? ($str_length/$num) : ($str_length/$num)+1;
  1508. $resultStr = '';
  1509. for($i=0; $i<$strNum; $i++){
  1510. $resultStr .= '<br>'.mb_substr($str, $i*$num,$num);
  1511. }
  1512. $resultStr = mb_substr($resultStr, 4);
  1513. return $resultStr;
  1514. }
  1515. //根据分页截取数组
  1516. function array_page_list($list=[],$page=1,$size=10){
  1517. $offset = ($page - 1) * $size;
  1518. $arr = array_slice($list,$offset,$size);
  1519. return $arr;
  1520. }
  1521. //二维数组去重去空
  1522. function array_remove_empty($array, $keys_to_check = []) {
  1523. if (!is_array($array)) {
  1524. return [];
  1525. }
  1526. if(!$array){
  1527. return [];
  1528. }
  1529. $filtered_array = [];
  1530. foreach ($array as $key => $value) {
  1531. if (!is_array($value)) {
  1532. if (!empty($value) || (is_numeric($value) && $value !== 0)) {
  1533. $filtered_array[$key] = $value;
  1534. }
  1535. } else {
  1536. $filtered_array[$key] = array_remove_empty($value, $keys_to_check);
  1537. }
  1538. }
  1539. return $filtered_array;
  1540. }
  1541. //使用htmlpurifier防范xss攻击
  1542. function remove_xss($str){
  1543. $cfg = HTMLPurifier_Config::createDefault();
  1544. $cfg->set('Core.Encoding','UTF-8');
  1545. $cfg->set('HTML.Allowed','div,b,strong,p[style],i,em,a[href|title],ul,ol,li,br,span[style],img[width|height|alt|src]');
  1546. $cfg->set('CSS.AllowedProperties','font,font-size,font-weight,font-style,font-family,text-decoration,padding-left,color,background-color,text-align');
  1547. $cfg->set('HTML.TargetBlank',TRUE);
  1548. // $cfg->set('Core.RemoveJavaScript', true);
  1549. $obj = new HTMLPurifier($cfg);
  1550. return $obj->purify($str);
  1551. }