simCardCharge.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. <?php
  2. // SIM卡计费脚本
  3. class XRsa
  4. {
  5. const CHAR_SET = "UTF-8";
  6. const BASE_64_FORMAT = "UrlSafeNoPadding";
  7. const RSA_ALGORITHM_KEY_TYPE = OPENSSL_KEYTYPE_RSA;
  8. const RSA_ALGORITHM_SIGN = OPENSSL_ALGO_SHA256;
  9. protected $public_key;
  10. protected $private_key;
  11. protected $key_len;
  12. public function __construct($pub_key, $pri_key = null)
  13. {
  14. $this->public_key = $pub_key;
  15. $this->private_key = $pri_key;
  16. $pub_id = openssl_get_publickey($this->public_key);
  17. $this->key_len = openssl_pkey_get_details($pub_id)['bits'];
  18. }
  19. public static function createKeys($key_size = 2048)
  20. {
  21. $config = array(
  22. "private_key_bits" => $key_size,
  23. "private_key_type" => self::RSA_ALGORITHM_KEY_TYPE,
  24. );
  25. $res = openssl_pkey_new($config);
  26. openssl_pkey_export($res, $private_key);
  27. $public_key_detail = openssl_pkey_get_details($res);
  28. $public_key = $public_key_detail["key"];
  29. return [
  30. "public_key" => $public_key,
  31. "private_key" => $private_key,
  32. ];
  33. }
  34. public function publicEncrypt($data)
  35. {
  36. $encrypted = '';
  37. $part_len = $this->key_len / 8 - 11;
  38. $parts = str_split($data, $part_len);
  39. foreach ($parts as $part) {
  40. $encrypted_temp = '';
  41. openssl_public_encrypt($part, $encrypted_temp, $this->public_key);
  42. $encrypted .= $encrypted_temp;
  43. }
  44. return url_safe_base64_encode($encrypted);
  45. }
  46. public function privateDecrypt($encrypted)
  47. {
  48. $decrypted = "";
  49. $part_len = $this->key_len / 8;
  50. $base64_decoded = url_safe_base64_decode($encrypted);
  51. $parts = str_split($base64_decoded, $part_len);
  52. foreach ($parts as $part) {
  53. $decrypted_temp = '';
  54. openssl_private_decrypt($part, $decrypted_temp,$this->private_key);
  55. $decrypted .= $decrypted_temp;
  56. }
  57. return $decrypted;
  58. }
  59. public function privateEncrypt($data)
  60. {
  61. $encrypted = '';
  62. $part_len = $this->key_len / 8 - 11;
  63. $parts = str_split($data, $part_len);
  64. foreach ($parts as $part) {
  65. $encrypted_temp = '';
  66. openssl_private_encrypt($part, $encrypted_temp, $this->private_key);
  67. $encrypted .= $encrypted_temp;
  68. }
  69. return url_safe_base64_encode($encrypted);
  70. }
  71. public function publicDecrypt($encrypted)
  72. {
  73. $decrypted = "";
  74. $part_len = $this->key_len / 8;
  75. $base64_decoded = url_safe_base64_decode($encrypted);
  76. $parts = str_split($base64_decoded, $part_len);
  77. foreach ($parts as $part) {
  78. $decrypted_temp = '';
  79. openssl_public_decrypt($part, $decrypted_temp,$this->public_key);
  80. $decrypted .= $decrypted_temp;
  81. }
  82. return $decrypted;
  83. }
  84. public function sign($data)
  85. {
  86. openssl_sign($data, $sign, $this->private_key, self::RSA_ALGORITHM_SIGN);
  87. return url_safe_base64_encode($sign);
  88. }
  89. public function verify($data, $sign)
  90. {
  91. $pub_id = openssl_get_publickey($this->public_key);
  92. $res = openssl_verify($data, url_safe_base64_decode($sign), $pub_id, self::RSA_ALGORITHM_SIGN);
  93. return $res;
  94. }
  95. }
  96. if (! function_exists('url_safe_base64_encode')) {
  97. function url_safe_base64_encode ($data) {
  98. return str_replace(array('+','/', '='),array('-','_', ''), base64_encode($data));
  99. }
  100. }
  101. if (! function_exists('url_safe_base64_decode')) {
  102. function url_safe_base64_decode ($data) {
  103. $base_64 = str_replace(array('-','_'),array('+','/'), $data);
  104. return base64_decode($base_64);
  105. }
  106. }
  107. if (! function_exists('base64_to_url_safe_base64')) {
  108. function base64_to_url_safe_base64 ($data) {
  109. return str_replace(array('+', '/', '='),array('-', '_', ''), $data);
  110. }
  111. }
  112. if (! function_exists('url_safe_base64_to_base64')) {
  113. function url_safe_base64_to_base64 ($data) {
  114. return str_replace(array('-','_'),array('+','/'), $data);
  115. }
  116. }
  117. // 获取套餐剩余周期
  118. function get_package_surplus($db,$rsa){
  119. $netList = $db->query('select simid,id from network where (protocoltype = 1 or protocoltype = 2) AND simid != ""');
  120. foreach ($netList as $v) {
  121. if (empty($v['simid'])) continue;
  122. $msisdnData = $db->query('select msisdn,type from msisdn where imsi = '.$v['simid']);
  123. if (!empty($msisdnData[0]) && !empty($msisdnData[0]['msisdn'])) {
  124. if ($msisdnData[0]['type'] == 0) {
  125. $msisdn = $msisdnData[0]['msisdn'] + 0;
  126. $data = array('_type' => 'list','msisdns' => [$msisdn]);
  127. $data = json_encode($data);
  128. //加密
  129. $encrypted = $rsa->privateEncrypt($data);
  130. $url = "https://aiot.wl1688.net/docking/card/cardinfo.do";
  131. $rt = http_post_data($url,$encrypted);
  132. //解密
  133. $data = $rsa->privateDecrypt($rt);
  134. $data = json_decode($data,true);
  135. if (!empty($data) && $data['code'] == 0) {
  136. $cardData = $data['data']['cards'][0];
  137. $db->table('network')->where('`id`='.$v['id'])->update(['packageSurplus'=>$cardData['period_number'],'down_time'=>date('Y-m-d H:i:s',$cardData['down_time']/1000),'is_charge_card'=>1,'monthly_can_usage'=>$cardData['monthly_can_usage'],'monthly_already_usage'=>$cardData['monthly_already_usage']]);
  138. }
  139. sleep(1);
  140. }else{
  141. $url = 'http://api.quectel-service.com/openapi/router';
  142. $msisdn = $msisdnData[0]['msisdn'];
  143. $appkey = '7A9137C166B948B747C7F493BFE097EB';
  144. $sercet = '7ECB7521AD5D8239303A6AB7DC61D638';
  145. $method = 'fc.function.card.info';
  146. $time = time();
  147. $str = 'appKey'.$appkey.'method'.$method.'msisdn'.$msisdn.'t'.$time;
  148. $sign = sha1($sercet.$str.$sercet);
  149. $reqData = array('appKey'=>$appkey,'t'=>$time,'method'=>$method,'sign'=>$sign,'msisdn'=>$msisdn);
  150. $data = request_post($url,$reqData);
  151. $info = json_decode($data,true);
  152. if ($info['resultCode'] == 0) {
  153. $flow = $info['flow']; // 已使用流量
  154. $residueFlow = $info['residueFlow']; // 剩余流量
  155. $all = $residueFlow + $flow;
  156. $expiryDate = $info['expiryDate']; // 套餐到期时间
  157. if (empty($expiryDate)) {
  158. $db->table('network')->where('`id`='.$v['id'])->update(['packageSurplus'=>$residueFlow,'is_charge_card'=>1,'monthly_can_usage'=>$all,'monthly_already_usage'=>$flow]);
  159. }else{
  160. $db->table('network')->where('`id`='.$v['id'])->update(['packageSurplus'=>$residueFlow,'down_time'=>$expiryDate,'is_charge_card'=>1,'monthly_can_usage'=>$all,'monthly_already_usage'=>$flow]);
  161. }
  162. }
  163. }
  164. }
  165. }
  166. }
  167. // 套餐到期提醒
  168. function send_sms($db){
  169. $netList = $db->query('select down_time,projectid,id from network where is_charge_card=1');
  170. foreach ($netList as $v) {
  171. $projectData = $db->query('select company,projectname from project where id = '.$v['projectid']);
  172. if (empty($projectData[0]) || empty($projectData[0]['company']) || $projectData[0]['projectname'] == '') continue;
  173. $lampData = $db->query('select id,number,section from lampinfo where networkid = '.$v['id']);
  174. if (empty($lampData[0]) || empty($lampData[0]['id'])) continue;
  175. if (empty($v['down_time'])) continue;
  176. $dayCount = ceil((strtotime($v['down_time']) - time())/(24*3600));
  177. if ($dayCount > 30) continue;
  178. if (empty($lampData[0]['section'])) {
  179. $msg = '【太阳能路灯系统】您位于'.$projectData[0]['projectname'].'项目路灯编号为'.$lampData[0]['number'].'的路灯剩余套餐不足'.$dayCount.'天!';
  180. }else{
  181. $msg = '【太阳能路灯系统】您位于'.$projectData[0]['projectname'].'项目'.$lampData[0]['section'].'路段路灯编号为'.$lampData[0]['number'].'的路灯剩余套餐不足'.$dayCount.'天!';
  182. }
  183. // 获取公司管理员
  184. $userList = $db->query('select mobile,email from user where role = 2 AND companyid = '.$projectData[0]['company']);
  185. foreach ($userList as $u) {
  186. if (!empty($u['mobile'])) {
  187. // 发送短信通知
  188. $res = send_sms_msg($u['mobile'],$msg);
  189. if ($res != '00') {
  190. // 发送短信失败,重发
  191. $db->table('send_sms_info')->insert(['phone'=>$u['mobile'],'msg'=>$msg]);
  192. }
  193. }
  194. if (!empty($u['mobile'])) {
  195. // 发送邮件通知
  196. send_email($u['mobile'],$msg);
  197. }
  198. sleep(1);
  199. }
  200. }
  201. }
  202. // 发送短信通知
  203. function send_sms_msg($phone, $message) {
  204. $config['epid'] = '124441';
  205. $config['username'] = 'solar';
  206. $config['password'] = 'Weclouds456';
  207. $config['linkid'] = '00';
  208. $config['signature'] = '【LampMind】';
  209. $epid = $config['epid'];
  210. $username = $config['username'];
  211. $password = md5($config['password']);
  212. $linkid = $config['linkid'];
  213. $signature = $config['signature'];
  214. $subcode = '';
  215. $message = urlencode(iconv("UTF-8", "GBK//IGNORE", $message));
  216. $url = "http://q.hl95.com:8061/?username={$username}&password={$password}&epid={$epid}&linkid={$linkid}&subcode={$subcode}&phone={$phone}&message={$message}";
  217. return http_get($url);
  218. }
  219. function http_get($url) {
  220. $ch = curl_init();
  221. curl_setopt($ch, CURLOPT_URL, $url);
  222. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  223. curl_setopt($ch, CURLOPT_HEADER, 0);
  224. // curl_setopt($ch, CURLOPT_TIMEOUT_MS, 1);
  225. $result = curl_exec($ch);
  226. curl_close($ch);
  227. return $result;
  228. }
  229. // 发送邮件
  230. function send_email($to,$msg,$title = 'SIM卡套餐通知'){
  231. require_once '../application/libraries/Smtp.php';
  232. //******************** 配置信息 ********************************
  233. $config['protocol'] = 'smtp';
  234. $config['smtp_host'] = 'smtpdm.aliyun.com';
  235. $config['user_email'] = 'admin@lampmind.com';
  236. $config['smtp_user'] = 'admin@lampmind.com';
  237. $config['smtp_pass'] = 'wecloudsSMTP2018';
  238. $config['smtp_port'] = 80;
  239. $config['smtp_timeout'] = 30;
  240. $config['crlf'] = "\r\n";
  241. $config['newline'] = "\r\n";
  242. $config['mailtype'] = "html";
  243. $smtpserver = $config['smtp_host'];//SMTP服务器
  244. $smtpserverport = $config['smtp_port'];//SMTP服务器端口
  245. $smtpusermail = $config['user_email'];//SMTP服务器的用户邮箱
  246. $smtpemailto = $to;//发送给谁
  247. $smtpuser = $config['smtp_user'];//SMTP服务器的用户帐号,注:部分邮箱只需@前面的用户名
  248. $smtppass = $config['smtp_pass'];//SMTP服务器的用户密码
  249. $mailtitle = $title;//邮件主题
  250. $mailcontent = $msg;//邮件内容
  251. $mailtype = "HTML";//邮件格式(HTML/TXT),TXT为文本邮件
  252. //************************ 配置信息 ****************************
  253. $smtp = new Smtp($smtpserver,$smtpserverport,true,$smtpuser,$smtppass);//这里面的一个true是表示使用身份验证,否则不使用身份验证.
  254. $smtp->debug = false;//是否显示发送的调试信息
  255. return $smtp->sendmail($smtpemailto, $smtpusermail, $mailtitle, $mailcontent, $mailtype);
  256. }
  257. require_once './DB.php';
  258. date_default_timezone_set('Asia/Shanghai');
  259. $publicKey = file_get_contents("../file/certificate/rsa_public_key.der");
  260. $privateKey = file_get_contents('../file/certificate/private_key.pem');
  261. $rsa = new XRsa($publicKey,$privateKey);
  262. $config = [
  263. 'hostname' => 'rm-wz98r5cn33zq4ou980o.mysql.rds.aliyuncs.com',
  264. 'username' => 'lampmanager',
  265. 'password' => 'lampmanager@2019',
  266. 'dbname' => 'lampmanager',
  267. ];
  268. $index = 0;
  269. while (1) {
  270. $db = new Db($config);
  271. $t = date('H');
  272. if ($index >= 10) {
  273. // 1、获取剩余使用周期
  274. get_package_surplus($db,$rsa);
  275. $index = 0;
  276. }else{
  277. $index ++;
  278. }
  279. if ($t == '10') {
  280. // 2、发送短信通知
  281. send_sms($db);
  282. sleep(3600);
  283. }
  284. $db->close();
  285. sleep(30);
  286. }
  287. function request_post($url = '', $data = '') {
  288. $tuCurl = curl_init();
  289. //参数
  290. curl_setopt($tuCurl, CURLOPT_URL,$url);
  291. curl_setopt($tuCurl, CURLOPT_POSTFIELDS, $data);
  292. curl_setopt($tuCurl, CURLOPT_SSL_VERIFYPEER, false);
  293. // curl_setopt($tuCurl, CURLOPT_SSL_VERIFYHOST, false);
  294. curl_setopt($tuCurl, CURLOPT_SSLVERSION, 1);
  295. curl_setopt($tuCurl, CURLOPT_RETURNTRANSFER, 1);
  296. $tuData = curl_exec($tuCurl);
  297. curl_close($tuCurl);
  298. return $tuData;
  299. }
  300. function http_post_data($url, $data_string) {
  301. $ch = curl_init();
  302. curl_setopt($ch, CURLOPT_POST, 1);
  303. curl_setopt($ch, CURLOPT_URL, $url);
  304. curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
  305. curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  306. 'Content-Type: application/json; charset=utf-8',
  307. 'Content-Length: ' . strlen($data_string),
  308. 'customId:741')
  309. );
  310. ob_start();
  311. curl_exec($ch);
  312. $return_content = ob_get_contents();
  313. // echo $return_content."<br>";
  314. ob_end_clean();
  315. $return_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  316. return $return_content;
  317. }