0
0

common.php 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595
  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. * 本月的开始日期
  1012. *
  1013. * @param bool $His 是否展示时分秒 默认true
  1014. *
  1015. * @return false|string
  1016. */
  1017. function beginMonth($His = true)
  1018. {
  1019. $timestamp = mktime(0, 0, 0, date('m'), 1, date('Y'));
  1020. return $His ? date('Y-m-d H:i:s', $timestamp) : date('Y-m-d', $timestamp);
  1021. }
  1022. /**
  1023. * 本月的结束日期
  1024. *
  1025. * @param bool $His 是否展示时分秒 默认true
  1026. *
  1027. * @return false|string
  1028. */
  1029. function endMonth($His = true)
  1030. {
  1031. $timestamp = mktime(23, 59, 59, date('m'), date('t'), 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 beginYear($His = true)
  1042. {
  1043. $timestamp = mktime(0, 0, 0, 1, 1, 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 endYear($His = true)
  1054. {
  1055. $timestamp = mktime(23, 59, 59, 12, 31, date('Y'));
  1056. return $His ? date('Y-m-d H:i:s', $timestamp) : date('Y-m-d', $timestamp);
  1057. }
  1058. /**
  1059. * 生成二维码
  1060. * @param $value 二维码内容
  1061. * @param $filepath 保存路径
  1062. * @return bool
  1063. */
  1064. function create_qrcode($value,$filepath)
  1065. {
  1066. include_once env('root_path').'/extend/phpqrcode/phpqrcode.php';
  1067. if (empty($value)) {
  1068. return false;
  1069. }
  1070. $dirfile = dirname($filepath);
  1071. if(!file_exists($dirfile)){
  1072. @mkdir($dirfile,0777);
  1073. }
  1074. //创建一个临时二维码的地址
  1075. $dir = getcwd().DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR.'qrcodeimg'.DIRECTORY_SEPARATOR;
  1076. if (!file_exists($dir)) {
  1077. @mkdir($dir);
  1078. }
  1079. //临时二维码地址
  1080. $QRprefix = $dir.DIRECTORY_SEPARATOR.substr(md5($value), 8, 16);
  1081. $QRTemp = $QRprefix.'_temp.png';
  1082. //判断本地是否存在临时的先删了
  1083. if (file_exists($QRTemp)) {
  1084. @unlink($QRTemp);
  1085. }
  1086. $errorCorrectionLevel = 'H';//容错级别
  1087. $matrixPointSize = 6;//生成图片大小
  1088. //生成二维码图片
  1089. QRcode::png(
  1090. $value,
  1091. $QRTemp,
  1092. $errorCorrectionLevel,
  1093. $matrixPointSize,
  1094. 2
  1095. );
  1096. $orgId = cur_org_id();
  1097. if($orgId == 17){
  1098. $logo = env('root_path').'/public/hb.png';//准备好的logo图片
  1099. }else{
  1100. $logo = env('root_path').'/public/logo.png';//准备好的logo图片
  1101. }
  1102. if (!empty($logo)) {
  1103. $QRBuffer = add_logo_2qrcode($QRTemp, $logo);
  1104. } else {
  1105. $QRBuffer = imagecreatefromstring(print_72dip_300dip(file_get_contents($QRTemp)));
  1106. }
  1107. //删除临时文件
  1108. if (file_exists($QRTemp)) {
  1109. @unlink($QRTemp);
  1110. }
  1111. imagejpeg($QRBuffer,$filepath,100);
  1112. ImageDestroy($QRBuffer);
  1113. }
  1114. //添加LOGO
  1115. function add_logo_2qrcode($QRTempPath, $logoPath)
  1116. {
  1117. $QRBuffer = imagecreatefromstring(print_72dip_300dip(file_get_contents($QRTempPath)));
  1118. $logo = imagecreatefromstring(print_72dip_300dip(file_get_contents($logoPath)));
  1119. $QR_width = imagesx($QRBuffer);//二维码图片宽度
  1120. $QR_height = imagesy($QRBuffer);//二维码图片高度
  1121. $logo_width = imagesx($logo);//logo图片宽度
  1122. $logo_height = imagesy($logo);//logo图片高度
  1123. $logo_qr_width = $QR_width / 5;
  1124. $scale = $logo_width/$logo_qr_width;
  1125. $logo_qr_height = $logo_height/$scale;
  1126. $from_width = ($QR_width - $logo_qr_width) / 2;
  1127. //重新组合图片并调整大小
  1128. imagecopyresampled(
  1129. $QRBuffer,
  1130. $logo,
  1131. $from_width,
  1132. $from_width,
  1133. 0,
  1134. 0,
  1135. $logo_qr_width,
  1136. $logo_qr_height,
  1137. $logo_width,
  1138. $logo_height
  1139. );
  1140. return $QRBuffer;
  1141. }
  1142. //浏览器默认输出为72DPI,打印要求为300DPI
  1143. function print_72dip_300dip($QRBufferStr)
  1144. {
  1145. //数据块长度为9
  1146. $len = pack("N", 9);
  1147. //数据块类型标志为pHYs
  1148. $sign = pack("A*", "pHYs");
  1149. //X方向和Y方向的分辨率均为300DPI(1像素/英寸=39.37像素/米),单位为米(0为未知,1为米)
  1150. $data = pack("NNC", 300 * 39.37, 300 * 39.37, 0x01);
  1151. //CRC检验码由数据块符号和数据域计算得到
  1152. $checksum = pack("N", crc32($sign . $data));
  1153. $phys = $len . $sign . $data . $checksum;
  1154. $pos = strpos($QRBufferStr, "pHYs");
  1155. if ($pos > 0) {
  1156. //修改pHYs数据块
  1157. $QRBufferStr = substr_replace($QRBufferStr, $phys, $pos - 4, 21);
  1158. } else {
  1159. //IHDR结束位置(PNG头固定长度为8,IHDR固定长度为25)
  1160. $pos = 33;
  1161. //将pHYs数据块插入到IHDR之后
  1162. $QRBufferStr = substr_replace($QRBufferStr, $phys, $pos, 0);
  1163. }
  1164. return $QRBufferStr;
  1165. }
  1166. /**
  1167. * 压缩文件/目录成zip
  1168. * @param $path
  1169. * @param $zip
  1170. */
  1171. function add_file_to_zip($path,$zip){
  1172. $handler=opendir($path); //打开当前文件夹由$path指定。
  1173. while(($filename=readdir($handler))!==false){
  1174. if($filename != "." && $filename != ".."){//文件夹文件名字为'.'和‘..’,不要对他们进行操作
  1175. if(is_dir($path."/".$filename)){// 如果读取的某个对象是文件夹,则递归
  1176. add_file_to_zip($path."/".$filename, $zip);
  1177. }else{ //将文件加入zip对象
  1178. $pp = $path."/".$filename;
  1179. $pps = explode('//',$pp);
  1180. $zip->addFile($pp,$pps[1]);
  1181. }
  1182. }
  1183. }
  1184. @closedir($path);
  1185. }
  1186. /**
  1187. * 清空文件夹及文件夹下的所有文件
  1188. * @param $path "./code/"
  1189. */
  1190. function deldir($path){
  1191. //如果是目录则继续
  1192. if(is_dir($path)){
  1193. //扫描一个文件夹内的所有文件夹和文件并返回数组
  1194. $p = scandir($path);
  1195. foreach($p as $val){
  1196. //排除目录中的.和..
  1197. if($val !="." && $val !=".."){
  1198. //如果是目录则递归子目录,继续操作
  1199. if(is_dir($path.$val)){
  1200. //子目录中操作删除文件夹和文件
  1201. deldir($path.$val.'/');
  1202. //目录清空后删除空文件夹
  1203. @rmdir($path.$val.'/');
  1204. }else{
  1205. //如果是文件直接删除
  1206. @unlink($path.$val);
  1207. }
  1208. }
  1209. }
  1210. @rmdir($path);
  1211. }
  1212. }
  1213. /*
  1214. * $userId 用户id
  1215. * $delUrl 删除路径(权限标识)
  1216. * */
  1217. function btnAuth($userId,$delUrl){
  1218. if(is_admin($userId)){
  1219. return true;
  1220. }
  1221. $roles = \think\Db::name('user_roles')
  1222. ->alias('a')
  1223. ->join('roles b','a.roles_id=b.id')
  1224. ->where('a.user_id',$userId)
  1225. ->field('b.*')
  1226. ->find();
  1227. if(!empty($roles)){
  1228. $authS = $roles['auths']?explode(',',$roles['auths']):[];
  1229. if($roles['org_id'] > 0){
  1230. $orgauths = \think\Db::name('org')->where('id',$roles['org_id'])->value('auths');
  1231. $orgauths = $orgauths?explode(',',$orgauths):[];
  1232. $authS = array_intersect($authS,$orgauths);
  1233. }
  1234. $menu = \think\Db::name('menu')
  1235. ->where('url',$delUrl)
  1236. ->where('enable',1)
  1237. ->where('del',0)
  1238. ->find();
  1239. if(!empty($menu) && in_array($menu['id'],$authS)){
  1240. return true;
  1241. }
  1242. }
  1243. return false;
  1244. }
  1245. /**
  1246. * 二维数组按照指定字段进行排序
  1247. * @params array $array 需要排序的数组
  1248. * @params string $field 排序的字段
  1249. * @params string $sort 排序顺序标志 SORT_DESC 降序;SORT_ASC 升序
  1250. */
  1251. function arraySequence($array, $field, $sort = 'SORT_ASC') {
  1252. $arrSort = array();
  1253. foreach ($array as $uniqid =>$row) {
  1254. foreach ($row as $key =>$value) {
  1255. $arrSort[$key][$uniqid] = $value;
  1256. }
  1257. }
  1258. array_multisort($arrSort[$field], constant($sort), $array);
  1259. return $array;
  1260. }
  1261. function getM1($do,$cof){
  1262. $diff = strtotime($do) - strtotime($cof);
  1263. $days = floor(($diff )/ (60*60*24));
  1264. $hours = floor(($diff - $days*60*60*24) / (60*60));
  1265. $minutes = floor(($diff - $days*60*60*24 - $hours*60*60)/ 60);
  1266. $seconds = floor(($diff - $days*60*60*24 - $hours*60*60 - $minutes*60));
  1267. if ($diff < 60) {
  1268. $time_cost = $seconds."秒";
  1269. } else if ($diff >= 60 && $diff < 60*60) {
  1270. $time_cost = $minutes."分钟".$seconds."秒";
  1271. } else if ($diff >= 60*60 && $diff < 60*60*24) {
  1272. $time_cost = $hours."小时".$minutes."分钟".$seconds."秒";
  1273. } else {
  1274. $time_cost = $days."天".$hours."小时".$minutes."分钟".$seconds."秒";
  1275. }
  1276. return $time_cost;
  1277. }
  1278. function getOrgGrabOrder($userId,$orgId){
  1279. $rolesId = \think\Db::name('user_roles')
  1280. ->where('user_id', $userId)
  1281. ->value('roles_id');
  1282. $rolesInfo = \think\Db::name('roles')
  1283. ->where('id', $rolesId)
  1284. ->find();
  1285. if ($rolesInfo['parent_id'] > 0) {
  1286. $rolesId = $rolesInfo['parent_id'];
  1287. }
  1288. $workType = \think\Db::name('work_type_mode')
  1289. ->where('type', 1)
  1290. ->where('roles', 'like', '%' . $rolesId . '%')
  1291. ->column('id');
  1292. $is = 0;
  1293. if(empty($workType)){
  1294. return $is;
  1295. }
  1296. foreach ($workType as $k=>$v){
  1297. $orgGrabOrder = (new Config())->getConfig('org_grab_order'.$v,$orgId);
  1298. if($orgGrabOrder && $orgGrabOrder>0){
  1299. $is = 1;
  1300. }
  1301. }
  1302. return $is;
  1303. }
  1304. //获取近12个月 0=包含本月 1=不包含本月
  1305. function monthlater($type=0){
  1306. $str = array();
  1307. for($i=0;$i<12;$i++){
  1308. if($type == 0){
  1309. $str[$i] =date('Y-m',strtotime('-'.$i.'month'));//包含本月
  1310. }else{
  1311. $str[$i] =date('Y-m',strtotime('-1month-'.$i.'month'));//不包含本月
  1312. }
  1313. }
  1314. sort($str);
  1315. return $str;
  1316. }
  1317. function get_sort_user($orgId,$work=-1,$type_id=-1){
  1318. $rolesId = \think\Db::name('roles')
  1319. ->where('parent_id',7)
  1320. ->where('org_id',$orgId)
  1321. ->where('del',0)
  1322. ->column('id');
  1323. $userRolesId = \think\Db::name('user_roles')
  1324. ->where('roles_id','in',$rolesId)
  1325. ->column('user_id');
  1326. $map[] = ['u.id','in',$userRolesId];
  1327. $map[] = ['u.del','=',0];
  1328. $map[] = ['u.type','=',0];
  1329. $map[] = ['u.enable','=',1];
  1330. $map[] = ['u.enable_sorts','=',1];
  1331. $map[] = ['uo.org_id','=',$orgId];
  1332. if($work >0){
  1333. $map[] = ['u.work','=',$work];
  1334. }
  1335. if($type_id >0){
  1336. $map[] = ['u.type_id','=',$type_id];
  1337. }
  1338. $map= empty($map) ? true: $map;
  1339. $lists = \think\Db::name('user')
  1340. ->alias('u')
  1341. ->join('user_org uo','u.id=uo.user_id')
  1342. ->where($map)
  1343. ->field('u.id,uo.org_id')
  1344. ->order(['u.sorts'=>'desc','u.id'=>'asc'])
  1345. ->column('u.id');
  1346. return $lists;
  1347. }
  1348. function get_sort_user_list($orgId,$work=-1){
  1349. $rolesId = \think\Db::name('roles')
  1350. ->where('parent_id',7)
  1351. ->where('org_id',$orgId)
  1352. ->where('del',0)
  1353. ->column('id');
  1354. $userRolesId = \think\Db::name('user_roles')
  1355. ->where('roles_id','in',$rolesId)
  1356. ->column('user_id');
  1357. $map[] = ['u.id','in',$userRolesId];
  1358. $map[] = ['u.del','=',0];
  1359. $map[] = ['u.type','=',0];
  1360. $map[] = ['u.enable','=',1];
  1361. $map[] = ['u.enable_sorts','=',1];
  1362. $map[] = ['uo.org_id','=',$orgId];
  1363. if($work >0){
  1364. $map[] = ['u.work','=',$work];
  1365. }
  1366. $map= empty($map) ? true: $map;
  1367. $lists = \think\Db::name('user')
  1368. ->alias('u')
  1369. ->join('user_org uo','u.id=uo.user_id')
  1370. ->where($map)
  1371. ->field('u.id,uo.org_id,u.sorts')
  1372. ->order(['u.sorts'=>'desc','u.id'=>'asc'])
  1373. ->select();
  1374. return $lists;
  1375. }
  1376. function getDateFromRange($startdate, $enddate){
  1377. $stimestamp = strtotime($startdate);
  1378. $etimestamp = strtotime($enddate);
  1379. // 计算日期段内有多少天
  1380. $days = ($etimestamp-$stimestamp)/86400+1;
  1381. // 保存每天日期
  1382. $date = array();
  1383. for($i=0; $i<$days; $i++){
  1384. $date[] = date('Y-m-d', $stimestamp+(86400*$i));
  1385. }
  1386. return $date;
  1387. }
  1388. /**
  1389. * 加密cookie
  1390. * @param $name
  1391. * @param $val
  1392. * @param $expire
  1393. */
  1394. function encodecookie($name,$val,$expire=100*365*24*60*60){
  1395. cookie($name,think_encrypt($val),$expire);
  1396. }
  1397. /**
  1398. * 解密cookie
  1399. * @param $name
  1400. */
  1401. function decodecookie($name){
  1402. return think_decrypt(cookie($name));
  1403. }
  1404. /**
  1405. * 获取点餐微信公众号配置
  1406. * @param $orgId 组织
  1407. * @return array|bool false=该组织未配置微信账号
  1408. */
  1409. function get_pay_wechat($orgId){
  1410. $wechat = \think\Db::name('dinner_wechat')->where('org_id',$orgId)->order('id','desc')->find();
  1411. if(!$wechat){
  1412. return [];
  1413. }
  1414. $option = [
  1415. 'user_type' => '3'.$wechat['id'],
  1416. 'app_id' => trim($wechat['app_id']),
  1417. 'secret' => trim($wechat['secret']),
  1418. 'mch_id' => trim($wechat['mch_id']), // 商户号
  1419. 'key' => trim($wechat['key']), // API 密钥
  1420. // 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书)
  1421. 'cert_path' => env('root_path').'public'.$wechat['cert_path'],
  1422. 'key_path' => env('root_path').'public'.$wechat['key_path'],
  1423. // 下面为可选项
  1424. // 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
  1425. 'response_type' => 'array',
  1426. 'log' => [
  1427. 'level' => 'error',
  1428. 'file' => env('runtime_path').'/log/wechat.log',
  1429. ],
  1430. ];
  1431. return $option;
  1432. }
  1433. /**
  1434. * 获取某周的周一和周末日期
  1435. * @param int $index //0则代表本周 1则代表下一周
  1436. * @return array
  1437. */
  1438. function get_week_days($index = 0,$format="Y-m-d"){ //0则代表本周
  1439. $week = date('w') == 0 ? 7 : date('w');
  1440. $start = strtotime('today ' . (- ($week - 1) + (7 * $index)) . 'day');
  1441. $end = strtotime('today ' . ((8 - $week) + (7 * $index)) . 'day -1second');
  1442. return [date($format,$start), date($format,$end)];
  1443. }
  1444. /**
  1445. * 获取某天是星期几
  1446. * @param $day 例如:2023-03-30
  1447. * @return string
  1448. */
  1449. function get_week_txt($day){
  1450. $da = date("w",strtotime($day));
  1451. if( $da == "1" ){
  1452. return '周一';
  1453. }else if( $da == "2" ){
  1454. return '周二';
  1455. }else if( $da == "3" ){
  1456. return '周三';
  1457. }else if( $da == "4" ){
  1458. return '周四';
  1459. }else if( $da == "5" ){
  1460. return '周五';
  1461. }else if( $da == "6" ){
  1462. return '周六';
  1463. }else if( $da == "0" ){
  1464. return '周日';
  1465. }
  1466. return '';
  1467. }
  1468. /**
  1469. * 秒数格式化
  1470. * @param $diff
  1471. * @return string
  1472. */
  1473. function second_to_str($diff){
  1474. if($diff <= 0){
  1475. return '0秒';
  1476. }
  1477. $days = floor(($diff )/ (60*60*24));
  1478. $hours = floor(($diff - $days*60*60*24) / (60*60));
  1479. $minutes = floor(($diff - $days*60*60*24 - $hours*60*60)/ 60);
  1480. $seconds = floor(($diff - $days*60*60*24 - $hours*60*60 - $minutes*60));
  1481. if ($diff < 60) {
  1482. $time_cost = $seconds."秒";
  1483. } else if ($diff >= 60 && $diff < 60*60) {
  1484. $time_cost = $minutes."分钟".$seconds."秒";
  1485. } else if ($diff >= 60*60 && $diff < 60*60*24) {
  1486. $time_cost = $hours."小时".$minutes."分钟".$seconds."秒";
  1487. } else {
  1488. $time_cost = $days."天".$hours."小时".$minutes."分钟".$seconds."秒";
  1489. }
  1490. return $time_cost;
  1491. }