common.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  1. <?php
  2. // 应用公共文件
  3. use app\model\Org;
  4. use app\model\Setting;
  5. use OSS\Core\OssException;
  6. use OSS\OssClient;
  7. use sms\ChuanglanSmsApi;
  8. use Overtrue\Pinyin\Pinyin;
  9. use wx\offiaccount\Qrcode;
  10. use toolkits\QrCodeGen;
  11. use app\model\Pool;
  12. use app\model\Wechat;
  13. use app\model\Miniprogram;
  14. use toolkits\Aec;
  15. use app\model\CreditsSetting;
  16. use app\model\DataStatistics;
  17. use xiaohongwu\Vr;
  18. use app\model\VrGroup;
  19. require_once __DIR__ . "/../extend/wx/pay/WxPay.Config.php";
  20. require_once __DIR__ . "/../extend/wx/pay/lib/WxPay.Data.php";
  21. require_once __DIR__ . "/../extend/wx/pay/lib/WxPay.Api.php";
  22. /**
  23. * access_token获取(小程序与公众号获取在于appid和secret不同)
  24. */
  25. function getAccessToken($appid, $secret)
  26. {
  27. $wx = new \wx\Base();
  28. $token = $wx->getAccessToken($appid, $secret);
  29. return $token;
  30. }
  31. /*
  32. * 手机验证码发送(装企端接收)
  33. */
  34. function sendSms($mobile, $content)
  35. {
  36. if (!preg_match("/^1\d{10}$/", $mobile) && empty($content)) {
  37. return false;
  38. }
  39. $smsObj = new ChuanglanSmsApi();
  40. $result = $smsObj->sendSMS($mobile, '【志远装饰】' . $content);
  41. $output = json_decode($result, true);
  42. if (is_null($output)) return false;
  43. if ($output['code'] != 0) {
  44. trace($output, 'error');
  45. return false;
  46. }
  47. return true;
  48. }
  49. /*
  50. * 手机验证码发送(用户端接收)
  51. */
  52. function sendSmsUser($mobile, $content)
  53. {
  54. if (!preg_match("/^1\d{10}$/", $mobile) && empty($content)) {
  55. return false;
  56. }
  57. $smsObj = new ChuanglanSmsApi();
  58. $result = $smsObj->sendSMS($mobile, '【志远装饰】' . $content);
  59. $output = json_decode($result, true);
  60. if (is_null($output)) return false;
  61. if ($output['code'] != 0) {
  62. trace($output, 'error');
  63. return false;
  64. }
  65. return true;
  66. }
  67. /**
  68. * 微信公众号二维码生成
  69. */
  70. function officialQrcode($token, $data)
  71. {
  72. $qr = new Qrcode();
  73. $rs = $qr->create($token, json_encode($data));
  74. $qrArr = json_decode($rs, true);
  75. if (isset($qrArr['errcode'])) {
  76. return ['code' => 1, 'msg' => $qrArr['errmsg']];
  77. }
  78. $url = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=' . $qrArr['ticket'];
  79. return ['code' => 0, 'data' => $url];
  80. }
  81. /**
  82. * 普通网址二维码生成
  83. */
  84. function qrcode($url, $path = false)
  85. {
  86. $qr = QrCodeGen::generateQr($url, $path);
  87. return $qr;
  88. }
  89. /*
  90. * 通信外部接口
  91. */
  92. function curlparam($url, $cmunioncode)
  93. {
  94. $headerArray = array("Content-type:application/json;", "Accept:application/json", 'Cmuc:' . $cmunioncode);
  95. $ch = curl_init();
  96. curl_setopt($ch, CURLOPT_URL, $url);
  97. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  98. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  99. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  100. curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArray);
  101. $output = curl_exec($ch);
  102. curl_close($ch);
  103. return $output;
  104. }
  105. /*
  106. * 通信外部接口
  107. */
  108. function curl($url)
  109. {
  110. $headerArray = array("Content-type:application/json;", "Accept:application/json");
  111. $ch = curl_init();
  112. curl_setopt($ch, CURLOPT_URL, $url);
  113. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  114. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  115. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  116. curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArray);
  117. $output = curl_exec($ch);
  118. curl_close($ch);
  119. return $output;
  120. }
  121. function curlpost($url = '', $params = '')
  122. {
  123. if (empty($url) || empty($param)) {
  124. return false;
  125. }
  126. $curlPost = $params;
  127. $ch = curl_init();
  128. curl_setopt($ch, CURLOPT_URL, $url); //抓取指定网页
  129. curl_setopt($ch, CURLOPT_HEADER, 0); //设置header
  130. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //要求结果为字符串且输出到屏幕上
  131. curl_setopt($ch, CURLOPT_POST, 1); //post提交方式
  132. curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
  133. $output = curl_exec($ch);
  134. curl_close($ch);
  135. return $output;
  136. }
  137. /**
  138. * @name: get_encoding
  139. * @description: 自动检测内容编码进行转换
  140. * @param: string data
  141. * @param: string to 目标编码
  142. * @return: string
  143. **/
  144. function get_encoding($data, $to)
  145. {
  146. $encode_arr = array('UTF-8', 'ASCII', 'GBK', 'GB2312', 'BIG5', 'JIS', 'eucjp-win', 'sjis-win', 'EUC-JP');
  147. $encoded = mb_detect_encoding($data, $encode_arr);
  148. $data = mb_convert_encoding($data, $to, $encoded);
  149. return $data;
  150. }
  151. /**
  152. * 获取汉字拼音首字母
  153. * @param $s0
  154. * @return null|string
  155. */
  156. function getfirstchar($s0)
  157. {
  158. $fchar = ord($s0[0]);
  159. if ($fchar >= ord("A") and $fchar <= ord("z")) return strtoupper($s0[0]);
  160. $s1 = get_encoding($s0, 'GB2312');
  161. $s2 = get_encoding($s1, 'UTF-8');
  162. if ($s2 == $s0) {
  163. $s = $s1;
  164. } else {
  165. $s = $s0;
  166. }
  167. $asc = ord($s[0]) * 256 + ord($s[1]) - 65536;
  168. if ($asc >= -20319 and $asc <= -20284) return "A";
  169. if ($asc >= -20283 and $asc <= -19776) return "B";
  170. if ($asc >= -19775 and $asc <= -19219) return "C";
  171. if ($asc >= -19218 and $asc <= -18711) return "D";
  172. if ($asc >= -18710 and $asc <= -18527) return "E";
  173. if ($asc >= -18526 and $asc <= -18240) return "F";
  174. if ($asc >= -18239 and $asc <= -17923) return "G";
  175. if ($asc >= -17922 and $asc <= -17418) return "H";
  176. if ($asc >= -17922 and $asc <= -17418) return "I";
  177. if ($asc >= -17417 and $asc <= -16475) return "J";
  178. if ($asc >= -16474 and $asc <= -16213) return "K";
  179. if ($asc >= -16212 and $asc <= -15641) return "L";
  180. if ($asc >= -15640 and $asc <= -15166) return "M";
  181. if ($asc >= -15165 and $asc <= -14923) return "N";
  182. if ($asc >= -14922 and $asc <= -14915) return "O";
  183. if ($asc >= -14914 and $asc <= -14631) return "P";
  184. if ($asc >= -14630 and $asc <= -14150) return "Q";
  185. if ($asc >= -14149 and $asc <= -14091) return "R";
  186. if ($asc >= -14090 and $asc <= -13319) return "S";
  187. if ($asc >= -13318 and $asc <= -12839) return "T";
  188. if ($asc >= -12838 and $asc <= -12557) return "W";
  189. if ($asc >= -12556 and $asc <= -11848) return "X";
  190. if ($asc >= -11847 and $asc <= -11056) return "Y";
  191. if ($asc >= -11055 and $asc <= -10247) return "Z";
  192. return '';
  193. }
  194. /**
  195. * 微信native支付
  196. * @param type string 企业类型 hdyj/xjs
  197. * @param data array 订单信息orderNo,money,body,attach,price
  198. * @param money float 金额
  199. * @param attach 标识,回调判断使用
  200. * @param price float 产品价格
  201. */
  202. function wxNativePay($type, $data)
  203. {
  204. $config = [
  205. 'app_id' => config("app.$type.mini_appid"),
  206. 'mch_id' => config("app.$type.mch_id"),
  207. 'key' => config("app.$type.mch_key"),
  208. ];
  209. $wxConfig = new WxPayConfig($config);
  210. $input = new WxPayUnifiedOrder();
  211. $input->SetBody($data['body']);
  212. $input->SetAttach($data['attach']);
  213. $input->SetOut_trade_no($data['orderNo']);
  214. $input->SetTotal_fee($data['money'] * 100);
  215. $input->SetTime_start(date("YmdHis"));
  216. $input->SetTime_expire(date("YmdHis", time() + 600));
  217. $input->SetNotify_url("");
  218. $input->SetTrade_type("NATIVE");
  219. $input->SetProduct_id($data['price']);
  220. $response = \WxPayApi::unifiedOrder($wxConfig, $input);
  221. $payUrl = isset($response['code_url']) ? $response['code_url'] : '';
  222. return $payUrl;
  223. }
  224. /**
  225. * 微信jsapi支付
  226. */
  227. function wxJsapiPay($config, $order, $openid)
  228. {
  229. // 微信支付请求接口配置生成
  230. $wxConfig = new WxPayConfig($config);
  231. $input = new WxPayUnifiedOrder();
  232. $input->SetBody($order['body']);
  233. $input->SetAttach($order['attach']);
  234. $input->SetOut_trade_no($order['orderNo']);
  235. $input->SetTotal_fee($order['money'] * 100);
  236. $input->SetOpenid($openid);
  237. $input->SetTime_start(date("YmdHis"));
  238. $input->SetTime_expire(date("YmdHis", time() + 600));
  239. $input->SetNotify_url($order['notifyUrl']);
  240. $input->SetTrade_type("JSAPI");
  241. $response = \WxPayApi::unifiedOrder($wxConfig, $input, 12);
  242. if ($response['return_code'] != 'SUCCESS') {
  243. trace($response, 'error');
  244. trace($config, 'error');
  245. }
  246. $wxPayResult = new \WxPayResults();
  247. $timeStamp = time();
  248. $wxPayResult->SetData('appId', $response["appid"]);
  249. $wxPayResult->SetData('timeStamp', "$timeStamp");
  250. $wxPayResult->SetData('nonceStr', WxPayApi::getNonceStr());
  251. $wxPayResult->SetData('package', 'prepay_id=' . $response["prepay_id"]);
  252. $wxPayResult->SetData('signType', 'HMAC-SHA256');
  253. $sign = $wxPayResult->MakeSign($wxConfig, false);
  254. $wxPayResult->SetData('paySign', $sign);
  255. $parameters = $wxPayResult->GetValues();
  256. return $parameters;
  257. }
  258. /*
  259. * oss文件上传
  260. */
  261. function ossUpload($path, $file)
  262. {
  263. $accessKeyId = config('app.ali_oss_access_key_id');
  264. $accessKeySecret = config('app.ali_oss_access_key_secret');
  265. $endpoint = config('app.ali_oss_end_point');
  266. $bucket = config('app.ali_oss_bucket');
  267. $oss = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
  268. try {
  269. $oss->uploadFile($bucket, $path, $file);
  270. } catch (OssException $e) {
  271. return false;
  272. }
  273. return true;
  274. }
  275. /*
  276. * 检测文件是否存在于oss
  277. */
  278. function ossFileExist($object)
  279. {
  280. $accessKeyId = config('app.ali_oss_access_key_id');
  281. $accessKeySecret = config('app.ali_oss_access_key_secret');
  282. $endpoint = config('app.ali_oss_end_point');
  283. $bucket = config('app.ali_oss_bucket');
  284. $oss = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
  285. // 检测文件是否存在
  286. return $oss->doesObjectExist($bucket, $object);
  287. }
  288. /**
  289. * oss文件删除
  290. */
  291. function fileDelete($path)
  292. {
  293. if (file_exists($path)) {
  294. // 删除本地文件
  295. return unlink($path);
  296. }
  297. // 删除阿里云oss文件
  298. $accessKeyId = config('app.ali_oss_access_key_id');
  299. $accessKeySecret = config('app.ali_oss_access_key_secret');
  300. $endpoint = config('app.ali_oss_end_point');
  301. $bucket = config('app.ali_oss_bucket');
  302. try {
  303. $oss = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
  304. if (is_array($path)) {
  305. return $oss->deleteObjects($bucket, $path);
  306. } else {
  307. return $oss->deleteObject($bucket, $path);
  308. }
  309. } catch (OssException $e) {
  310. return false;
  311. }
  312. }
  313. /**
  314. * 手机类型获取
  315. */
  316. function mobileType()
  317. {
  318. $agent = $_SERVER['HTTP_USER_AGENT'];
  319. $type = [
  320. 'Macintosh' => 'MAC',
  321. 'Android' => '安卓',
  322. 'iPhone' => 'Iphone',
  323. 'Windows' => 'PC',
  324. ];
  325. foreach ($type as $en => $ch) {
  326. if (stripos($agent, $en) !== false)
  327. return $ch;
  328. }
  329. return '其他';
  330. }
  331. /**
  332. * 数组转url
  333. * @param $data Array
  334. */
  335. function toUrlParams($data)
  336. {
  337. $buff = "";
  338. foreach ($data as $k => $v) {
  339. if ($k != "sign" && $v != "" && !is_array($v)) {
  340. $buff .= $k . "=" . $v . "&";
  341. }
  342. }
  343. $buff = trim($buff, "&");
  344. return $buff;
  345. }
  346. /**
  347. * 查询条件生成
  348. */
  349. function setCondition($param, $item, $condition, &$set)
  350. {
  351. if (!is_array($param)) {
  352. $value = $param;
  353. } else {
  354. if (is_array($item)) {
  355. $value = isset($param[$item[0]]) ? $param[$item[0]] : '';
  356. $item = $item[1];
  357. } else {
  358. $value = isset($param[$item]) ? $param[$item] : '';
  359. }
  360. }
  361. if ($value === '' || $value === null) return;
  362. if (is_array($condition)) {
  363. if (is_string($condition[1]) && preg_match('/VALUE/', $condition[1]))
  364. $condition[1] = str_replace('VALUE', $value, $condition[1]);
  365. else
  366. $condition[1] = $value;
  367. } else {
  368. $condition = [$condition, $value];
  369. }
  370. array_unshift($condition, $item);
  371. $set[] = $condition;
  372. }
  373. /**
  374. * 获取汉子拼音
  375. */
  376. function hanzi2pinyin($hanzi)
  377. {
  378. if (empty($hanzi)) return '';
  379. $pinyin = new Pinyin();
  380. $quanpin = $pinyin->permalink($hanzi, '');
  381. return $quanpin;
  382. }
  383. /**
  384. * 获取汉子首字母
  385. */
  386. function hanziInitials($hanzi)
  387. {
  388. if (empty($hanzi)) return '';
  389. $pinyin = new Pinyin();
  390. $quanpin = $pinyin->permalink($hanzi, '');
  391. return $quanpin[0] ?? '';
  392. }
  393. /**
  394. * 对数组按首字母进行排序
  395. */
  396. function hanziInitsort($arr, $ks)
  397. {
  398. $sort = null;
  399. foreach ($arr as $key => $val) {
  400. $s = hanziInitials($val[$ks]);
  401. $arr[$key]['s'] = $s;
  402. $sort[] = strtoupper($s);
  403. }
  404. array_multisort($sort, SORT_ASC, $arr);
  405. $sort = array_unique($sort);
  406. //asort($sort);
  407. /*foreach($sort as $key=>$val){
  408. $xin[]=strtoupper($val);
  409. }*/
  410. $data = ['sort' => $sort, 'arr' => $arr];
  411. return $data;
  412. }
  413. /**
  414. * 对已排序的数组取第一个
  415. */
  416. function hanziheadstr($arr)
  417. {
  418. $sort = [];
  419. foreach ($arr as $key => $val) {
  420. $arr[$key]['s'] = substr($val['pinyin'], 0, 1);
  421. $sort[] = strtoupper(substr($val['pinyin'], 0, 1));
  422. }
  423. $sort = array_unique($sort);
  424. $data = ['sort' => $sort, 'arr' => $arr];
  425. return $data;
  426. }
  427. /**
  428. * 获取org ids array
  429. * @param integer $orgid 目标节点id
  430. * @return array $orgids 子节点ids数组
  431. */
  432. function orgSubIds($orgid)
  433. {
  434. $theorg = Org::find($orgid);
  435. if ($theorg) {
  436. $orgids = Org::where([['path', 'like', $theorg->path . '%']])->column('id');
  437. return $orgids;
  438. } else {
  439. return [];
  440. }
  441. }
  442. function ossContentUpload($path, $content)
  443. {
  444. $accessKeyId = config('app.ali_oss_access_key_id');
  445. $accessKeySecret = config('app.ali_oss_access_key_secret');
  446. $endpoint = config('app.ali_oss_end_point');
  447. $bucket = config('app.ali_oss_bucket');
  448. $oss = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
  449. try {
  450. $oss->putObject($bucket, $path, $content);
  451. } catch (OssException $e) {
  452. trace('文件内容上传失败,PATH:' . $path . ';error:' . $e->getErrorMessage(), 'error');
  453. return false;
  454. }
  455. return true;
  456. }
  457. /**
  458. * 十进制转64进制
  459. */
  460. function dec52($num)
  461. {
  462. $out = "";
  463. $codes = "zxcvbnmlkjhgfdsaqwertyuiopQWERTYUIOPASDFGHJKLZXCVBNM";
  464. do {
  465. $i = 1;
  466. $y = $num % 52;
  467. $out = $codes[$y] . $out;
  468. $num = $num / 52 >= 1 ? $num / 52 : 0;
  469. $i++;
  470. } while ($num > 0);
  471. for ($i = 1; $i < 3; $i++) {
  472. $r = rand(0, 51);
  473. $out = $codes[$r] . $out;
  474. }
  475. return $out;
  476. }
  477. /**
  478. * 获取公海保护数据
  479. */
  480. function pubpoolSetting($type)
  481. {
  482. $existed_obj = Setting::where('name', 'pubpool')->find();
  483. if ($existed_obj) {
  484. $contentarr = json_decode($existed_obj->content, true);
  485. return $contentarr[$type];
  486. } else {
  487. return null;
  488. }
  489. }
  490. /**
  491. * 获取直属公海ID
  492. */
  493. function knnPubPool($org_id)
  494. {
  495. $ownnodepool = Pool::where('org_id', $org_id)->find();
  496. if (!$ownnodepool) {
  497. if ($org_id == 0) {
  498. return $org_id;
  499. }
  500. $current_org_node = Org::find($org_id);
  501. $parentnodepool = Pool::where('org_id', $current_org_node->pid)->find();
  502. if (!$parentnodepool) {
  503. $grand_parent_org_node = Org::find($current_org_node->pid);
  504. $grandnodepool = Pool::where('org_id', $grand_parent_org_node->pid)->find();
  505. if (!$grandnodepool) {
  506. $far_grand_parent_org_node = Org::find($grand_parent_org_node->pid);
  507. $fargrandnodepool = Pool::where('org_id', $far_grand_parent_org_node->pid)->find();
  508. if (!$fargrandnodepool) {
  509. }
  510. return $grandnodepool->pid;
  511. }
  512. return $parentnodepool->pid;
  513. }
  514. return $current_org_node->pid;
  515. }
  516. return $org_id;
  517. }
  518. /**
  519. * 随机字符串生成
  520. * @param length integer
  521. */
  522. function str_rand(int $length)
  523. {
  524. $range = '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM';
  525. $str = '';
  526. while ($length > 0) {
  527. $rand = mt_rand(0, 61);
  528. $str .= $range[$rand];
  529. $length--;
  530. }
  531. return $str;
  532. }
  533. /*
  534. * 手机加密结构
  535. */
  536. function cypherphone($value)
  537. {
  538. $aec = new Aec(config('app.aec_key'), config('app.aec_iv'));
  539. $value = $aec->encrypt($value);
  540. return $value;
  541. }
  542. /*
  543. * 积分表数据增加
  544. */
  545. function credits($root_id, $val, $code, $org_id = 0)
  546. {
  547. $where[] = ['code', '=', $code];
  548. $where[] = ['root_id', '=', $root_id];
  549. if ($org_id > 0) {
  550. $where[] = ['org_id', '=', $org_id];
  551. }
  552. $info = CreditsSetting::where($where)->find();
  553. if ($info) {
  554. CreditsSetting::where($where)->update(['value' => $val]);
  555. } else {
  556. $save['code'] = $code;
  557. $save['root_id'] = $root_id;
  558. $save['value'] = $val;
  559. if ($org_id > 0) {
  560. $save['org_id'] = $org_id;
  561. }
  562. CreditsSetting::insert($save);
  563. }
  564. }
  565. /*
  566. * 公司unionid本系统自生成函数
  567. */
  568. // function unionidgen($username, $length = 16)
  569. // {
  570. // $key = '';
  571. // $str = md5($username.config('app.salt'));
  572. // for ($i = 0; $i < $length; $i++) {
  573. // $key .= $str{mt_rand(0, 31)}; //生成php随机数
  574. // }
  575. // return $key;
  576. // }
  577. /**
  578. * 断点调试方法
  579. */
  580. if (!function_exists('p')) {
  581. function p($data, $die = true, $show_type = false)
  582. {
  583. $trace = (new \Exception())->getTrace()[0];
  584. echo "{$trace['file']}:{$trace['line']}行";
  585. echo '<pre><meta charset="utf-8">';
  586. if ($show_type) {
  587. var_dump($data);
  588. } else {
  589. print_r($data);
  590. }
  591. echo '</pre>';
  592. if ($die) die;
  593. }
  594. }
  595. /**
  596. * 创建文件夹
  597. * @param $dir
  598. * @param int $mode
  599. * @return bool
  600. */
  601. if (!function_exists('mkdirs')) {
  602. function mkdirs($dir, $mode = 0777)
  603. {
  604. if (is_dir($dir) || @mkdir($dir, $mode)) return TRUE;
  605. if (!mkdirs(dirname($dir), $mode)) return FALSE;
  606. return @mkdir($dir, $mode);
  607. }
  608. }
  609. /**
  610. * 毫秒时间戳格式化
  611. * @param $time
  612. * @return string|string[]
  613. */
  614. if (!function_exists('get_microtime_format')) {
  615. function get_microtime_format($time)
  616. {
  617. $time = $time * 0.001;
  618. if (strstr($time, '.')) {
  619. sprintf("%01.3f", $time); //小数点。不足三位补0
  620. list($usec, $sec) = explode(".", $time);
  621. $sec = str_pad($sec, 3, "0", STR_PAD_RIGHT); //不足3位。右边补0
  622. } else {
  623. $usec = $time;
  624. $sec = "000";
  625. }
  626. $date = date("Y-m-d H:i:s.x", $usec);
  627. return str_replace('x', $sec, $date);
  628. }
  629. }
  630. /**
  631. * 生成一个32位随机字符串
  632. */
  633. if (!function_exists('make_string')) {
  634. function make_string()
  635. {
  636. $time = time();
  637. $random = random_int(1000, 9999);
  638. $str = md5($time . $random);
  639. return $str;
  640. }
  641. }
  642. /**
  643. * 生成一个不重复随机文件名
  644. */
  645. if (!function_exists('make_file_name')) {
  646. function make_file_name($path, $ext)
  647. {
  648. $file_name = make_string() . '.' . $ext;
  649. if (file_exists($path . $file_name)) {
  650. make_file_name($path, $ext);
  651. }
  652. return $file_name;
  653. }
  654. }
  655. /**
  656. * 获取当前部门上级部门
  657. */
  658. if (!function_exists('orgParentIds')) {
  659. function orgParentIds($orgid, $pid = [])
  660. {
  661. $pid[] = $orgid;
  662. $theorg = Org::find($orgid);
  663. if (!empty($theorg) && $theorg['pid'] != 0) {
  664. $pid = orgParentIds($theorg['pid'], $pid);
  665. }
  666. return $pid;
  667. }
  668. }
  669. /**
  670. * 获取根部门
  671. */
  672. if (!function_exists('orgRootId')) {
  673. function orgRootId($orgid)
  674. {
  675. $theorg = Org::find($orgid);
  676. $root_id = $theorg['id'];
  677. if (!empty($theorg) && $theorg['pid'] != 0) {
  678. $root_id = orgRootId($theorg['pid']);
  679. }
  680. return $root_id;
  681. }
  682. }
  683. /**
  684. * 数字转汉字
  685. */
  686. function numToWord($num)
  687. {
  688. $chiNum = array('零', '一', '二', '三', '四', '五', '六', '七', '八', '九');
  689. $chiUni = array('', '十', '百', '千', '万', '亿', '十', '百', '千');
  690. $chiStr = '';
  691. $num_str = (string)$num;
  692. $count = strlen($num_str);
  693. $last_flag = true; //上一个 是否为0
  694. $zero_flag = true; //是否第一个
  695. $temp_num = null; //临时数字
  696. $chiStr = ''; //拼接结果
  697. if ($count == 2) { //两位数
  698. $temp_num = $num_str[0];
  699. $chiStr = $temp_num == 1 ? $chiUni[1] : $chiNum[$temp_num] . $chiUni[1];
  700. $temp_num = $num_str[1];
  701. $chiStr .= $temp_num == 0 ? '' : $chiNum[$temp_num];
  702. } else if ($count > 2) {
  703. $index = 0;
  704. for ($i = $count - 1; $i >= 0; $i--) {
  705. $temp_num = $num_str[$i];
  706. if ($temp_num == 0) {
  707. if (!$zero_flag && !$last_flag) {
  708. $chiStr = $chiNum[$temp_num] . $chiStr;
  709. $last_flag = true;
  710. }
  711. } else {
  712. $chiStr = $chiNum[$temp_num] . $chiUni[$index % 9] . $chiStr;
  713. $zero_flag = false;
  714. $last_flag = false;
  715. }
  716. $index++;
  717. }
  718. } else {
  719. $chiStr = $chiNum[$num_str[0]];
  720. }
  721. return $chiStr;
  722. }
  723. /**
  724. * 数组转树形
  725. */
  726. function tree($data,$pid = 0, $persons)
  727. {
  728. $new_arr = [];
  729. foreach ($data as $k => $v) {
  730. if ($v['pid'] == $pid) {
  731. $persions = isset($persons[$v['id']]) ? $persons[$v['id']] : [];
  732. $children = tree($data, $v['id'], $persons);
  733. $v['children'] = array_merge_recursive($children, $persions);
  734. if (empty($v['children'])) $v['disabled']=true;
  735. $new_arr[] = $v;
  736. }
  737. }
  738. return $new_arr;
  739. }
  740. /**
  741. * 小程序主体 更换 配置信息
  742. * user表和employee表 字段需一致
  743. * 根据域名判断使用的小程序
  744. */
  745. function appletConfiguration()
  746. {
  747. $domain = request()->domain();
  748. $data['url'] = $domain;
  749. //原有小程序
  750. $data['unionid'] = 'unionid'; //主体unionid
  751. $data['mini_openid'] = 'mini_openid'; //小程序openid
  752. $data['appid'] = config('app.kfweb_appid');
  753. $data['secret'] = config('app.kfweb_secret');
  754. $data['name'] = '装修宝pro';
  755. return $data;
  756. }
  757. /**
  758. * 数据统计
  759. */
  760. function dataStatistics($root_id, $field, $count, $type = 'inc')
  761. {
  762. DataStatistics::where('root_id', $root_id)->$type($field, $count)->update();
  763. }
  764. /**
  765. * 查询指定时间范围内的所有日期,月份,季度,年份
  766. *
  767. * @param $startDate 指定开始时间,Y-m-d格式
  768. * @param $endDate 指定结束时间,Y-m-d格式
  769. * @param $type 类型,day 天,month 月份,quarter 季度,year 年份
  770. * @return array
  771. */
  772. function getDateByInterval($startDate, $endDate, $type)
  773. {
  774. $tempDate = $startDate;
  775. $returnData = [];
  776. $i = 0;
  777. if ($type == 'year') {
  778. while (strtotime($tempDate) < strtotime($endDate)) {
  779. $temp = [];
  780. $year = strtotime('+' . $i . ' year', strtotime($startDate));
  781. $temp['name'] = date('Y', $year) . '年';
  782. $temp['startDate'] = date('Y-01-01', $year);
  783. $temp['endDate'] = date('Y-12-31', $year);
  784. $tempDate = $temp['endDate'];
  785. $returnData[] = $temp;
  786. $i++;
  787. }
  788. } elseif ($type == 'month') {
  789. while (strtotime($tempDate) < strtotime($endDate)) {
  790. $temp = [];
  791. $month = strtotime('first day of +' . $i . ' month', strtotime($startDate));
  792. $temp['name'] = date('Y-m', $month);
  793. $temp['startDate'] = date('Y-m-01', $month);
  794. $temp['endDate'] = date('Y-m-t', $month);
  795. $tempDate = $temp['endDate'];
  796. $returnData[] = $temp;
  797. $i++;
  798. }
  799. } else {
  800. if(strtotime($tempDate) == strtotime($endDate)){
  801. $returnData[] = $tempDate;
  802. }else{
  803. while (strtotime($tempDate) < strtotime($endDate)) {
  804. $tempDate = date('Y-m-d', strtotime('+' . $i . ' day', strtotime($startDate)));
  805. $returnData[] = $tempDate;
  806. $i++;
  807. }
  808. }
  809. }
  810. return $returnData;
  811. }
  812. /**
  813. * 计算两个时间的时间差
  814. */
  815. function get_date_diff($start, $end)
  816. {
  817. if (is_numeric($start)) $start = date('Y-m-d H:i:s');
  818. if (is_numeric($end)) $end = date('Y-m-d H:i:s');
  819. $startDate = date_create($start);
  820. $endDate = date_create($end);
  821. $d_time = date_diff($startDate, $endDate);
  822. $start_date = date('Y-m-d', strtotime($start));
  823. $end_date = date('Y-m-d', strtotime($end));
  824. $startDateD = date_create($start_date);
  825. $endDateD = date_create($end_date);
  826. $d_date = date_diff($startDateD, $endDateD);
  827. $d = [
  828. 'y' => $d_time->y,
  829. 'm' => $d_time->m,
  830. 'd' => $d_time->d,
  831. 'h' => $d_time->h,
  832. 'i' => $d_time->i,
  833. 's' => $d_time->s,
  834. 'f' => $d_time->f,
  835. 'invert' => $d_time->invert,
  836. 'days' => $d_date->days
  837. ];
  838. return (object)$d;
  839. }
  840. //vr第一帧
  841. function getFirstImg($vr)
  842. {
  843. if (strpos($vr, '/vr/#')) {
  844. $ali_oss_bindurl = config('app.vr_ali_oss_bindurl');
  845. $show_url = config('app.vr_show_domain');
  846. $sid = substr(str_replace($show_url,'',$vr),0,32);
  847. $pic_path = VrGroup::where('sid',$sid)->value('pic_path');
  848. $res = 'https://' . $ali_oss_bindurl . '/' . $pic_path;
  849. }else{
  850. $vrObj = new Vr();
  851. $res = $vrObj->getFirstImg($vr);
  852. }
  853. return $res;
  854. }
  855. //vr链接设置修改
  856. function vrlinkSet($vr_link)
  857. {
  858. //2023-05-04 装企销冠app创建的vr作品
  859. if (strpos($vr_link, '/vr/#')) return $vr_link;
  860. // 旧域名 替换成 新域名
  861. $links = [
  862. 'xiaohongwu' => 'hnweizhihui.xiaohongwu.nczyzs.com',
  863. 'kujiale' => 'pano337.p.kujiale.com',
  864. 'justeasy' => 'vr-17.justeasy.nczyzs.com',
  865. '3d66' => 'vr.3d66.nczyzs.com',
  866. ];
  867. $url = parse_url($vr_link);
  868. if ($url === false || !isset($url['host'])) {
  869. echo json_encode(['code' => 1, 'msg' => '链接格式错误']);
  870. exit;
  871. }
  872. if (strpos($url['host'], 'xiaohongwu') !== false) {
  873. return str_replace($url['host'], $links['xiaohongwu'], $vr_link);
  874. }
  875. if (strpos($url['host'], 'kujiale') !== false) {
  876. return str_replace($url['host'], $links['kujiale'], $vr_link);
  877. }
  878. if (strpos($url['host'], 'justeasy') !== false) {
  879. return str_replace($url['host'], $links['justeasy'], $vr_link);
  880. }
  881. if (strpos($url['host'], '3d66') !== false) {
  882. return str_replace($url['host'], $links['3d66'], $vr_link);
  883. }
  884. echo json_encode(['code' => 1, 'msg' => '无效的VR链接']);
  885. exit;
  886. }
  887. /**
  888. * 下载文件并上传oss后删除本地文件
  889. */
  890. function downClueRecordUrl($url, $name)
  891. {
  892. $res = down_file($url, 'upload/fishcall/', 'upload/fishcall/' . $name);
  893. if ($res) {
  894. $url = app()->getRootPath() . 'public/upload/fishcall/' . $name;
  895. if(ossUpload('fishcall/' . $name, $url)){
  896. unlink('upload/fishcall/' . $name);
  897. return true;
  898. }
  899. }
  900. return false;
  901. }
  902. /**
  903. * @param $url 文件下载地址
  904. * @param string $folder 文件存储地址
  905. * @param string $down_name 文件另存名称
  906. * @return bool
  907. */
  908. function down_file($url, $folder = "./", $down_name = '')
  909. {
  910. set_time_limit(0); // 设置超时时间
  911. $destination_folder = $folder . '/'; // 文件下载保存目录,默认为当前文件目录
  912. if (!is_dir($destination_folder)) { // 判断目录是否存在
  913. mkdirs($destination_folder); // 如果没有就建立目录
  914. }
  915. $file = fopen($url, "rb"); // 远程下载文件,二进制模式
  916. if ($file) { // 如果下载成功
  917. $newf = fopen($down_name, "wb"); // 远在文件文件
  918. if ($newf) // 如果文件保存成功
  919. while (!feof($file)) { // 判断附件写入是否完整
  920. fwrite($newf, fread($file, 1024 * 8), 1024 * 8); // 没有写完就继续
  921. }
  922. fclose($file); // 关闭远程文件
  923. fclose($newf);
  924. }
  925. return true;
  926. }