WxApiAction.class.php 99 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516
  1. <?php
  2. class WxApiAction extends Action {
  3. private function getHumenTime( $timeInterval ){
  4. if ($timeInterval < 60){
  5. $formatime = $timeInterval.'秒';
  6. }elseif($timeInterval < 60 * 60){
  7. $min = floor($timeInterval/60);
  8. $formatime = $min.'分钟';
  9. }elseif($timeInterval < 60 * 60 * 24){
  10. $h = floor($timeInterval/(60*60));
  11. $formatime = $h.'小时';
  12. }elseif($timeInterval < 60 * 60 * 24 * 30){
  13. $d = floor($timeInterval/(60*60*24));
  14. $formatime = $d.'天';
  15. }elseif($timeInterval < 60 * 60 * 24 * 30 * 12){
  16. $m = floor($timeInterval/(60*60*24*30));
  17. $formatime = $m.'月';
  18. }else{
  19. $y = floor($timeInterval/(60*60*24*30*12));
  20. $formatime = $y.'年';
  21. }
  22. return $formatime;
  23. }
  24. public function register( ){
  25. header('Access-Control-Allow-Origin: *');
  26. // 通过手机号和短信验证码注册
  27. $data = json_decode( file_get_contents("php://input") ,true);
  28. // 用户类型:个人(personal)、团体(group)
  29. $userType = $data['userType'];
  30. // 设备类型:卡牌(card)、徽章(badge)
  31. $deviceType = $data['deviceType'];
  32. // 团体卡牌用户(group_card_user) 不可注册
  33. // 个人用户(personal),团体徽章用户(group_badge_user) 可注册
  34. if ($userType == 'personal') { // 个人用户
  35. $identify = 'personal';
  36. } elseif ($userType == 'group' && $deviceType == 'badge') { // 团体徽章用户
  37. $identify = 'group_badge_user';
  38. } elseif ($userType == 'group' && $deviceType == 'card') { // 团体卡牌用户
  39. // $identify = 'group_card_user';
  40. json_fail('团体卡牌用户无需注册,请联系发卡人询问账号!');
  41. } else {
  42. json_fail('未知用户类型');
  43. }
  44. if(!$data['phone']){
  45. json_fail('手机号码不能为空');
  46. }
  47. if(!$data['smsCode']){
  48. json_fail('短信验证码不能为空');
  49. }
  50. if(! $data['password']){
  51. json_fail('密码不能为空');
  52. }
  53. if(! $data['confirmPassword']){
  54. json_fail('请输入确认密码');
  55. }
  56. if ($data['password'] != $data['confirmPassword']) {
  57. json_fail('两次密码不一致');
  58. }
  59. /*
  60. $cond = array(
  61. 'username'=>$data['phone']
  62. );
  63. $user_info = M('users')->where($cond)->join('user_has_roles ON users.id = user_has_roles.uid')->find();
  64. if($user_info){
  65. //存在用户则判断
  66. $role_identify=M('roles')->where(array('id'=>$user_info['role_id']))->getField('identify');
  67. if($role_identify==$identify){
  68. json_fail('该类型用户已经存在,请前往登陆');
  69. }
  70. }*/
  71. // 获取角色id
  72. $roleId = M('roles')->where(['identify' => $identify])->getField('id');
  73. if (!$roleId) {
  74. json_fail('未知角色类型');
  75. }
  76. // 判断角色、号码是否已注册
  77. $userinfo = M('users')->alias('a')->where(['username'=>$data['phone']])->join("INNER JOIN user_has_roles b ON a.id = b.uid AND b.role_id = {$roleId}")->find();
  78. if ($userinfo) {
  79. json_fail('该号码已注册');
  80. }
  81. // 验证码有效性
  82. $res = $this->isValidSmsCode($data['phone'], $data['smsCode']);
  83. if (!$res['success']) {
  84. json_fail($res['message']);
  85. }
  86. //if($user_info['password'] != password_hash($data['password'],PASSWORD_DEFAULT) ){
  87. $savePwd = password_hash($data['password'],PASSWORD_DEFAULT);
  88. $saveData = [
  89. 'username' => $data['phone'],
  90. 'realname' => '用户'.$data['phone'],
  91. 'password' => $savePwd,
  92. 'phone' => $data['phone'],
  93. 'created_at' => time(),
  94. ];
  95. // 个人用户给定默认部门
  96. if ($identify == 'personal') {
  97. $where = [
  98. 'type' => 'basic_config',
  99. 'field' => 'department_id',
  100. ];
  101. $department_id = M('sys_config')->where($where)->getField('fieldValue');
  102. if ($department_id) {
  103. $saveData['department_id'] = $department_id;
  104. }
  105. }
  106. M()->startTrans();
  107. $userid = M('users')->add($saveData);
  108. if(!$userid){
  109. M()->rollback();
  110. json_fail('注册失败');
  111. }
  112. $hasRoleData = [
  113. 'uid' => $userid,
  114. 'role_id' => $roleId
  115. ];
  116. $userHasRoleRes = M('user_has_roles')->add($hasRoleData);
  117. if(!$userHasRoleRes){
  118. M()->rollback();
  119. json_fail('注册失败');
  120. }
  121. M()->commit();
  122. json_success('注册成功',$userid);
  123. }
  124. public function login( ){
  125. header('Access-Control-Allow-Origin: *');
  126. //json_fail('登录失败');
  127. $openid = I('get.openid');
  128. if(!$openid){
  129. json_fail('未授权,请关闭当前页面重新进入');
  130. }
  131. $data = json_decode( file_get_contents("php://input") ,true);
  132. $identify = 'chezhu';
  133. $role_id = M('roles')->where(array('identify'=>$identify))->getField('id');
  134. if (!$role_id) {
  135. json_fail('未知用户类型');
  136. }
  137. $cond = array(
  138. 'username' => $data['username'],
  139. );
  140. $user_info = M('users')->alias('u')->where($cond)->join("INNER JOIN user_has_roles AS r ON u.id = r.uid AND r.role_id = {$role_id}")->find();
  141. if(!$user_info){
  142. json_fail('账号错误');
  143. }
  144. if(!password_verify($data['password'], $user_info['password'])){
  145. json_fail('密码错误');
  146. }
  147. $where = array(
  148. 'wx_open_id' => $openid,
  149. 'id' => ['NEQ', $user_info['uid']],
  150. );
  151. //$result = M('users')->createSave($where,['wx_open_id'=>'']);
  152. $result = M('users')->where($where)->save(['wx_open_id'=>'']);
  153. if($result===false){
  154. json_fail('登陆失败');
  155. }
  156. if($user_info['wx_open_id'] != $openid){
  157. $update = array(
  158. 'wx_open_id' => $openid,
  159. 'last_login_ip' => $_SERVER['REMOTE_ADDR'],
  160. 'last_login_time' => time(),
  161. );
  162. $result = M('users')->createSave(array('id'=>$user_info['uid']),$update);
  163. if(!$result){
  164. json_fail('登陆失败');
  165. }
  166. }
  167. //如果当前openid与其他账号openid相同,清空其他表中openid
  168. $res = array(
  169. 'id'=>$user_info['uid'],
  170. 'realname'=>$user_info['realname'],
  171. 'avatar' => $user_info['avatar'],
  172. 'phone'=>$user_info['phone'],
  173. );
  174. json_success('登录成功', $res);
  175. }
  176. public function getLastPositionMulti( ){
  177. header('Access-Control-Allow-Origin: *');
  178. $userid = I('get.userid');
  179. if(!$userid){
  180. json_fail('未检测到用户标识');
  181. }
  182. $vehiclesIds = M('vehicles')->where(['user_id' => $userid ])->getField('id',true);
  183. $devices=M('devices')->where(['bind_id' =>array('in',$vehiclesIds) ])->select();
  184. if(!$devices){
  185. json_fail('名下查询不到任何设备');
  186. }
  187. $resp = [];
  188. foreach($devices as &$locationInfo){
  189. //wifi_online_time
  190. //wifi_longitude
  191. //wifi_latitude
  192. //addr
  193. $locationInfo['isAlarm'] = $locationInfo['alarm_status'];
  194. $isWifi = $locationInfo['wifi_online_time'] > $locationInfo['online_time'] || intval($locationInfo['latitude']) < 1 ;
  195. $locationInfo['time'] = $isWifi ? $locationInfo['wifi_online_time'] : $locationInfo['online_time'];
  196. $locationInfo['lat'] = $isWifi ? $locationInfo['wifi_latitude'] : $locationInfo['latitude'];
  197. $locationInfo['lng'] = $isWifi ? $locationInfo['wifi_longitude'] : $locationInfo['longitude'];
  198. $locationInfo['address'] = $locationInfo['address'];
  199. if(!$locationInfo['time']){
  200. $locationInfo['awayTime'] = '从未在线';
  201. }else{
  202. $timeInterval = time() - (int)strtotime($locationInfo['time']);
  203. $locationInfo['awayTime'] = $this->getHumenTime($timeInterval);
  204. }
  205. $lngLatAlter = new \Jms\Algo\Geometry();
  206. if(!$locationInfo['lat'] || !$locationInfo['lng']){
  207. continue;
  208. }
  209. $latLng = $lngLatAlter->convertBd09ToGcj02($locationInfo['lat'], $locationInfo['lng']);
  210. $locationInfo['lat'] = $latLng['lat'];
  211. $locationInfo['lng'] = $latLng['lng'];
  212. $locationInfo['date_time'] =$locationInfo['time'];
  213. array_push($resp, $locationInfo);
  214. }
  215. if(!$resp){
  216. json_fail('暂无任何设备上报过数据哦!');
  217. }
  218. json_success('查询成功', $resp);
  219. }
  220. private function checkLoginState( $openid, $userid ){
  221. $wx_open_id=M('users')->where(array('id'=>$userid))->getField('wx_open_id');
  222. if($wx_open_id === 'test_openid'){
  223. return array('status'=>true,'message'=>'');
  224. }
  225. if($wx_open_id!=$openid){
  226. //已被他人登录
  227. return array('status'=>false,'message'=>'账号可能在其他设备登录,请重新登录');
  228. }
  229. return array('status'=>true,'message'=>'');
  230. }
  231. public function getMyDevices( ){
  232. header('Access-Control-Allow-Origin: *');
  233. $openid = I('get.openid');
  234. $userid = I('get.userid');
  235. //检测登录状态
  236. $res=$this->checkLoginState($openid,$userid);
  237. if(!$res['status']){
  238. json_fail($res['message']);
  239. }
  240. //$vehiclesIds = M('vehicles')->where(['user_id' => $userid ])->getField('id',true);
  241. //$devices=M('devices')->where(['bind_id' =>array('in',$vehiclesIds) ])->select();
  242. $list=M('vehicles')->where(array('user_id'=>$userid))->select();
  243. $type_id=M('sys_dict_type')->where(['code'=>'DeviceType'])->getField('id');
  244. foreach($list as &$val){
  245. $deivice_info=M('devices')->where(['bind_id' =>$val['id']])->find();
  246. if(!$deivice_info){
  247. $deivice_info=[
  248. 'name'=>'-',
  249. 'imei'=>'-',
  250. 'loc_mode'=>'-',
  251. ];
  252. }
  253. $val['deivice_info']=$deivice_info;
  254. $val['department_name']=M('departments')->where(['id'=>$val['department_id']])->getField('department_name');
  255. $val['creator']=M('users')->where(['id'=>$val['creator_id']])->getField('username');
  256. }
  257. if(!$list){
  258. json_fail('暂无车辆');
  259. }
  260. json_success('查询成功',$list);
  261. }
  262. public function getAlarmList( ){
  263. header('Access-Control-Allow-Origin: *');
  264. $userid = I('get.userid');
  265. if(!$userid || $userid == 'undefined' || $userid == 'null'){
  266. json_fail('获取不到你的用户标识,请重新登陆');
  267. }
  268. $openid = I('get.openid');
  269. //检测登录状态
  270. $res=$this->checkLoginState($openid,$userid);
  271. if(!$res['status']){
  272. json_fail($res['message']);
  273. }
  274. $imeiArr=M('devices')->where(['user_id' => $userid])->getField('imei',true);
  275. $page = I('get.page') ? I('get.page') : 1;
  276. $pageSize = 10;
  277. $start = ($page - 1) * $pageSize;
  278. $cond = [];
  279. $alarmType = I('get.alarmType');
  280. $imei = I('get.imei');
  281. if(!$imei){
  282. $cond['device_number'] = array('in',$imeiArr);
  283. }else{
  284. $cond['device_number'] = $imei;
  285. }
  286. if($alarmType){
  287. $cond['alarm_type'] = $alarmType;
  288. }
  289. $list = M('alarm_report')->where($cond)->limit( $start, $pageSize)->order('created_at desc')->select();
  290. $type_id=M('sys_dict_type')->where(array('code'=>'AlarmType'))->getField('id');
  291. foreach($list as &$val){
  292. $val['alarm_type_str']=M('sys_dict_data')->where(array('type_id'=>$type_id,'code'=>$val['alarm_type']))->getField('value');
  293. $val['created_at_str'] = date('Y-m-d H:i:s', $val['created_at']);
  294. }
  295. $total = M('alarm_report')->where($cond)->count() ?: 0;
  296. $resp = [
  297. 'list' => $list ?:[],
  298. 'total' => $total,
  299. 'pageSize' => $pageSize
  300. ];
  301. json_success('获取成功', $resp);
  302. }
  303. public function getSignaturEtc( ){
  304. header('Access-Control-Allow-Origin: *');
  305. $url = I('get.url');
  306. if(!$url){
  307. json_fail('no url');
  308. }
  309. $url = urldecode($url);
  310. $accessToken = $this->getWeixinAccessToken();
  311. if (!$accessToken) {
  312. json_fail('获取 access token 失败');
  313. }
  314. $apiTiket = $this->getJsapiTikcet($accessToken);
  315. if(is_array($apiTiket)){
  316. json_fail($apiTiket['errcode'].':'.$apiTiket['errmsg']);
  317. }
  318. $noncestr = substr(md5(time()), 0, 16);
  319. $timestamp = time();
  320. //jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value
  321. $str = 'jsapi_ticket='.$apiTiket.'&noncestr='.$noncestr.'&timestamp='.$timestamp.'&url='.$url;
  322. $signature = sha1($str);
  323. $data = [
  324. 'appId' => C('WECHAT_APPID'),
  325. 'timeStamp' => $timestamp,
  326. 'nonceStr' => $noncestr,
  327. 'signature' => $signature,
  328. 'url' => $url,
  329. 'jsapi_ticket' =>S('wx_jsapi_ticket'),
  330. 'accessToken' => $accessToken,
  331. ];
  332. json_success('get success', $data);
  333. }
  334. private function getJsapiTikcet( $accessToken ){
  335. $jsapiTicket = S('wx_jsapi_ticket');
  336. if(!$jsapiTicket){
  337. $ch = curl_init();
  338. curl_setopt($ch, CURLOPT_URL, 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$accessToken .'&type=jsapi');
  339. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  340. $output = json_decode(curl_exec($ch), true);
  341. curl_close($ch);
  342. if($output['errcode'] != 0){
  343. return $output;
  344. }
  345. S('wx_jsapi_ticket', $output['ticket'], '7100');
  346. return $output['ticket'];
  347. }else{
  348. return $jsapiTicket;
  349. }
  350. }
  351. public function getGpsRoutes( ){
  352. header('Access-Control-Allow-Origin: *');
  353. $imei = I('get.imei');
  354. $startTime = I('get.startTime');
  355. $endTime = I('get.endTime');
  356. if(!$imei){
  357. json_fail('获取不到设备号');
  358. }
  359. if(!$startTime){
  360. json_fail('无起始时间');
  361. }
  362. if(!$endTime){
  363. json_fail('无结束时间');
  364. }
  365. //end_time
  366. //start_time
  367. //student_id
  368. //queyRouteListByStudentId
  369. $routeInfo = [];
  370. $lngLatAlter = new \Jms\Algo\Geometry();
  371. $routeInfo = queyGpsRouteListByimei($imei, $startTime, $endTime);
  372. //$routeInfo = analyzeRouteInfoGaodeBatch($routeInfo);
  373. $routeInfo = analyzeRouteInfoWayzBatch($routeInfo);
  374. $arr = [];
  375. foreach($routeInfo as &$v){
  376. $v['lat'] = $v['Latitude'];
  377. $v['lng'] = $v['Longitude'];
  378. if($v['lat']){
  379. array_unshift($arr, $v);
  380. }
  381. }
  382. $routeInfo =$arr;
  383. //$routeInfo =bmapFilterOutliers($arr);
  384. json_success('success', $routeInfo);
  385. }
  386. private function analyzeRouteInfo( $list ){
  387. if(!$list){
  388. return array();
  389. }
  390. $arr= [];
  391. foreach($list as $k=> $v){
  392. if(isset($v['WifiMacs']) && $v['WifiMacs'] !=''){
  393. $wifiRes =$this->requestWifiLBS($v);
  394. if($wifiRes['success']){
  395. if($wifiRes['data']['lon'] == '' || is_null($wifiRes['data']['lat'])){
  396. continue;
  397. }
  398. $list[$k]['Latitude'] = $wifiRes['data']['lat'];
  399. $list[$k]['Longitude'] = $wifiRes['data']['lon'];
  400. $list[$k]['SignalType'] = 'WiFi';
  401. $list[$k]['WifiAddress'] = $wifiRes['data']['address'];
  402. array_push($arr, $list[$k]);
  403. }else{
  404. // array_splice($list,$k,1);
  405. continue;
  406. }
  407. }else{
  408. $list[$k]['SignalType'] = 'GPS';
  409. array_push($arr, $list[$k]);
  410. }
  411. }
  412. return $arr;
  413. }
  414. private function requestWifiLBS( $routeInfo ){
  415. if(!$routeInfo){
  416. return array(
  417. 'success' => false,
  418. 'msg' => '空数据'
  419. );
  420. }
  421. if(!isset( $routeInfo['WifiMacs']) ){
  422. return array(
  423. 'success' => false,
  424. 'msg' => '无wifi信息'
  425. );
  426. }
  427. $WifiMacs = $routeInfo['WifiMacs'];
  428. $userKey = '';
  429. if(!$userKey){
  430. $userKey = 'f107b0b3a513e6e37c6fb0424bed6633';
  431. }
  432. //$url = 'http://api.cellocation.com:81/loc/?wl=' . $WifiMacs .'&output=json&coord=gcj02';
  433. $url = 'http://apilocate.amap.com/position?accesstype=1&imei=' . $routeInfo['DeviceNumber'] . '&macs=' . $WifiMacs . '&key=' . $userKey;
  434. $curl = curl_init($url);
  435. curl_setopt($curl, CURLOPT_TIMEOUT, 3);
  436. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  437. $response = curl_exec($curl);
  438. if (curl_errno($curl)) {
  439. $errmsg = curl_error($curl);
  440. curl_close($curl);
  441. return array(
  442. 'success' => false,
  443. 'msg' => $errmsg
  444. );
  445. }
  446. curl_close($curl);
  447. $response = json_decode($response, true);
  448. if($response['info'] != 'OK' || count($response['result']) <2 ){
  449. return array(
  450. 'success' => false,
  451. 'msg' => $response['info']
  452. );
  453. }
  454. $result = $response['result'];
  455. $location = $response['result']['location'];
  456. $location = explode(',', $location);
  457. $response = array(
  458. 'lon' => $location[0],
  459. 'lat' => $location[1],
  460. 'address' => $result['desc']
  461. );
  462. return array(
  463. 'success' => true,
  464. 'data' => $response
  465. );
  466. }
  467. private function registerDevice2third( $deviceImei ){
  468. $tokenInfo = $this->getThirdTokenInfo();
  469. if(!$tokenInfo){
  470. return false;
  471. }
  472. $postData = [
  473. "deviceImei" => $deviceImei,
  474. "phone" => "",
  475. "userId" => $tokenInfo['holder']
  476. ];
  477. var_dump($postData);
  478. $url = "http://rinlink-a18.beijing-cn-k8s-test.rinlink.com/device";
  479. $headers[] = "Content-Type: application/json";
  480. $headers[] = "Authorization: ". $tokenInfo['token'];
  481. $ch = curl_init();
  482. curl_setopt($ch, CURLOPT_URL, $url);
  483. curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
  484. curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
  485. curl_setopt($ch, CURLOPT_POST, 1);
  486. curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode($postData) );
  487. $output = curl_exec($ch);
  488. curl_close($ch);
  489. if($output === false){
  490. $this->push_log('thirdapi_register_device_curl_error',curl_error($curl));
  491. return false;
  492. }
  493. $deviceRes = json_decode($output, ture) ;
  494. if($deviceRes['error'] || $deviceRes['code']){
  495. $this->push_log('thirdapi_register_device_response_error',$deviceRes);
  496. return false;
  497. }
  498. $this->push_log('thirdapi_register_device_response_success',$deviceRes);
  499. return true;
  500. }
  501. private function getThirdRoutes( $imei, $option ){
  502. /*
  503. {
  504. "page": 0,
  505. "size": 6000,
  506. "total": 8,
  507. "content": [{
  508. "collectDt": "2021-07-07 10:33:39",
  509. "receiveAt": "2021-07-07 10:33:39",
  510. "lat": "40.02577751048506",
  511. "lon": "116.35762812669113",
  512. "battery": 91,
  513. "positionType": 2,
  514. "imei": "71041607133",
  515. "isOnline": null
  516. }]
  517. }
  518. */
  519. if (!$imei) {
  520. $this->push_log('thirdapi_devicelocation_curl_error', 'imei 为空');
  521. return false;
  522. }
  523. $tokenInfo = $this->getThirdTokenInfo();
  524. if(!$tokenInfo){
  525. return false;
  526. }
  527. $pageNo = $option['pageNo'] ? $option['pageNo'] : 0;
  528. $pageSize = $option['pageSize'] ?$option['pageSize']: 6000;
  529. $startTime = isset($option['startTime']) ? $option['startTime'] * 1000 : '';
  530. $endTime = isset($option['endTime']) ? $option['endTime'] * 1000 : '';
  531. $positionTypes = $option['positionTypes'] ? $option['positionTypes']: '';
  532. $headers[] = "Content-Type: application/json";
  533. $headers[] = "Authorization: ". $tokenInfo['token'];
  534. $url = 'http://rinlink-a18.beijing-cn-k8s-test.rinlink.com/devicedata/location/filter?imei='.$imei.'&pageNo='.$pageNo.'&pageSize='.$pageSize.'&startTime='.$startTime.'&endTime='.$endTime.'&positionTypes='.$positionTypes;
  535. //var_dump($url);
  536. $response = $this->http_get($url, $headers);
  537. if (!$response) {
  538. $this->push_log('thirdapi_devicelocation_curl_error', $response);
  539. return false;
  540. }
  541. return json_decode($response, true);
  542. }
  543. private function getThirdLocation( $imei ){
  544. if (!$imei) {
  545. $this->push_log('third_newlocation_curl_error', 'imei 为空');
  546. return false;
  547. }
  548. $tokenInfo = $this->getThirdTokenInfo();
  549. if(!$tokenInfo){
  550. return false;
  551. }
  552. $headers[] = "Content-Type: application/json";
  553. $headers[] = "Authorization: ". $tokenInfo['token'];
  554. $url = 'http://rinlink-a18.beijing-cn-k8s-test.rinlink.com/devicedata/location/'.$imei;
  555. $response = $this->http_get($url, $headers);
  556. if (!$response) {
  557. $this->push_log('third_lastLocation_error', $response);
  558. return false;
  559. }
  560. return json_decode($response, true);
  561. }
  562. private function http_get( $url, $headers ){
  563. $oCurl = curl_init();
  564. if(!$headers){
  565. $headers = [];
  566. }
  567. if(stripos($url,"https://")!==FALSE){
  568. curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
  569. curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);
  570. }
  571. curl_setopt($oCurl, CURLOPT_URL, $url);
  572. curl_setopt($oCurl, CURLOPT_HTTPHEADER, $headers );
  573. curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
  574. $sContent = curl_exec($oCurl);
  575. $aStatus = curl_getinfo($oCurl);
  576. if(intval($aStatus["http_code"])==200){
  577. curl_close($oCurl);
  578. return $sContent;
  579. }else{
  580. $this->push_log('thirdapi_token_curl_error',curl_error($oCurl));
  581. curl_close($oCurl);
  582. return false;
  583. }
  584. }
  585. public function sendSmsCode( ){
  586. header('Access-Control-Allow-Origin: *');
  587. $postData = json_decode(file_get_contents('php://input'), true) ?:[];
  588. if (!$postData['phone']) {
  589. json_fail('手机号码不能为空');
  590. }
  591. if (!preg_match('/^1[3456789]\d{9}$/', $postData['phone'])) {
  592. json_fail('手机号码格式不正确');
  593. }
  594. // 是否重置密码
  595. $isReset = $postData['isReset'];
  596. if ($postData['userType'] == 'personal') { // 个人用户
  597. $identify = 'personal';
  598. } elseif ($postData['userType'] == 'group' && $postData['deviceType'] == 'badge') { // 团体徽章用户
  599. $identify = 'group_badge_user';
  600. } elseif ($postData['userType'] == 'group' && $postData['deviceType'] == 'card') { // 团体卡牌用户
  601. $identify = 'group_card_user';
  602. } else {
  603. json_fail('暂不支持的用户类型');
  604. }
  605. // 注册时检测
  606. if (!$isReset && $identify == 'group_card_user') {
  607. json_fail('暂不支持的注册用户类型');
  608. }
  609. // 获取角色id
  610. $roleId = M('roles')->where(['identify' => $identify])->getField('id');
  611. // 判断角色、号码是否已注册
  612. $userinfo = M('users')->alias('a')->where(['username'=>$postData['phone']])->join("INNER JOIN user_has_roles b ON a.id = b.uid AND b.role_id = {$roleId}")->find();
  613. // 重置密码时
  614. if ($isReset && empty($userinfo)) {
  615. json_fail('该号码未注册');
  616. } elseif (!$isReset && $userinfo) {
  617. json_fail('该号码已注册');
  618. }
  619. $sms_code_mode = M('sms_verification_code'); // 短信验证码模型
  620. // 防盗刷IP地址检测
  621. $todayTime = strtotime(date('Y-m-d'));
  622. $where = ['access_ip' => $_SERVER['REMOTE_ADDR'], 'created_at' => ['GT', $todayTime]];
  623. $count = $sms_code_mode->where($where)->count();
  624. if ($count >= 10) {
  625. json_fail('已达到当日获取次数上限');
  626. }
  627. // 获取短信配置
  628. $rlyunId = M('sms_config')->where(['name' => 'rlyun'])->getField('id');
  629. $smsConfig = M('sms_config')->where(['pid' => $rlyunId])->getField('key,value');
  630. if (empty($smsConfig)) {
  631. json_fail('获取短信配置失败');
  632. }
  633. // 获取短信验证码模板信息
  634. $where = ['operator' => 'rlyun', 'code' => 'verification_code'];
  635. $tmpInfo = M('sms_template')->where($where)->find();
  636. if (empty($tmpInfo)) {
  637. json_fail('获取短信验证码模板信息失败');
  638. }
  639. // 生成验证码
  640. $code = rand(0, 9999);
  641. $code = str_pad($code, 4, '0',STR_PAD_LEFT);
  642. // 保存验证码
  643. $time = time();
  644. $saveData = [
  645. 'mobile' => $postData['phone'],
  646. 'code' => $code,
  647. 'access_ip' => $_SERVER['REMOTE_ADDR'],
  648. 'created_at' => $time,
  649. 'updated_at' => $time,
  650. ];
  651. M()->startTrans(); // 开启事务
  652. $res = $sms_code_mode->createAdd($saveData);
  653. if ($res === false) {
  654. M()->rollback();
  655. json_fail('发送失败,请稍后重试');
  656. }
  657. //M()->commit();
  658. //json_success('测试,不发短信,看数据库');
  659. // 发送短信验证码
  660. $content = str_replace('{1}', $code, $tmpInfo['content']);
  661. $content = str_replace('{2}', '5分钟', $content);
  662. $contentData = [
  663. 'tplno' => $tmpInfo['identify'],
  664. 'tpldata' => [ $code, '5分钟' ],
  665. //'tpldata' => $content, // error test
  666. 'info' => $content,
  667. ];
  668. //$res = (new \Jms\Sms\RlyuntxV100)->send($postData['phone'], $contentData, $smsConfig);
  669. $res = send_sms_with_config($postData['phone'], $contentData, $smsConfig);
  670. if (!$res['success']) {
  671. M()->rollback();
  672. $res = M('sms_send_log')->add($res['data']);
  673. json_fail($res['message'] ?: '发送失败');
  674. }
  675. M()->commit();
  676. json_success($res['message']);
  677. }
  678. public function getAlarmTypeOptions( ){
  679. header('Access-Control-Allow-Origin: *');
  680. $typeid = M('sys_dict_type')->where(['code' => 'AlarmType'])->getField('id');
  681. $options = M('sys_dict_data')->field('id, value as text, code as value')->where(['type_id' => $typeid])->select();
  682. if(!$options){
  683. json_fail('获取告警选项失败');
  684. }
  685. json_success('获取选项成功', $options);
  686. //AlarmType
  687. }
  688. private function isValidSmsCode( $mobile, $code ){
  689. if (!$mobile) {
  690. return ['success' => false, 'message' => '手机号码不存在'];
  691. }
  692. if (!$code) {
  693. return ['success' => false, 'message' => '验证码不存在'];
  694. }
  695. // 根据手机号码和验证码查询最后一次验证码
  696. $sms_verification_code_model = M('sms_verification_code');
  697. $cond = [ 'mobile' => $mobile, 'code' => $code ];
  698. $info = $sms_verification_code_model->where($cond)->order('created_at', 'desc')->find();
  699. // 不存在
  700. if (empty($info)) {
  701. return ['success' => false, 'message' => '验证失败,请确保手机号码和验证码输入无误'];
  702. }
  703. // 超过时间(暂定5分钟)
  704. $valid_time = 60 * 5;
  705. if (time() - $info['created_at'] > $valid_time) {
  706. return ['success' => false, 'message' => '验证码已失效'];
  707. }
  708. // 超过使用次数(暂定3次)
  709. if ($info['use_times'] >= 3) {
  710. return ['success' => false, 'message' => '验证码已失效'];
  711. }
  712. // 可以使用,使用次数+1
  713. $cond = ['id' => $info['id']];
  714. $res = $sms_verification_code_model->where($cond)->setInc('use_times');
  715. if ($res === false) {
  716. return ['success' => false, 'message' => '操作失败,请重试'];
  717. }
  718. return ['success' => true, 'message' => '验证码有效'];
  719. }
  720. public function userBindDevice( ){
  721. header('Access-Control-Allow-Origin: *');
  722. $openid = I('get.openid');
  723. $userid = I('get.userid');
  724. //检测登录状态
  725. $res=$this->checkLoginState($openid,$userid);
  726. if(!$res['status']){
  727. json_fail($res['message']);
  728. }
  729. // 通过手机号和短信验证码注册
  730. $data = json_decode( file_get_contents("php://input") ,true);
  731. // 用户类型:个人(personal)、团体(group)
  732. $userType = $data['userType'];
  733. // 设备类型:卡牌(card)、徽章(badge)
  734. $deviceType = $data['deviceType'];
  735. // 团体卡牌用户(group_card_user) 不可注册
  736. // 个人用户(personal),团体徽章用户(group_badge_user) 可注册
  737. if ($userType == 'personal') { // 个人用户
  738. $identify = 'personal';
  739. } elseif ($userType == 'group' && $deviceType == 'badge') { // 团体徽章用户
  740. $identify = 'group_badge_user';
  741. } elseif ($userType == 'group' && $deviceType == 'card') { // 团体卡牌用户
  742. $identify = 'group_card_user';
  743. } else {
  744. json_fail('未知用户类型');
  745. }
  746. if ($identify == 'group_card_user') {
  747. json_fail('无绑定设备权限');
  748. }
  749. //$data['imei'],$data['user_no'],$data['username']
  750. if(!$data['imei'] ){
  751. json_fail('缺少IMEI参数');
  752. }
  753. //先查询设备信息 看是否被绑定
  754. $where = array('imei'=>$data['imei']);
  755. $device_info=M('devices')->where($where)->find();
  756. if(!$device_info){
  757. json_fail('设备不存在,请确认输入无误');
  758. }
  759. if($device_info['user_id']){
  760. json_fail('设备已被绑定');
  761. }
  762. if ($identify == 'group_badge_user' && $device_info['device_type'] != 1 ) {
  763. json_fail('无法绑定该类型的设备');
  764. }
  765. $userType = $data['userType'];
  766. $device_name = '';
  767. if ($data['device_name']) {
  768. $device_name = $data['device_name'];
  769. } elseif ($data['username']) {
  770. $device_name = $data['username'];
  771. } else {
  772. $device_name = '用户'. substr($data['imei'], -4);
  773. }
  774. $save_data=array(
  775. 'device_name' => $device_name,
  776. 'user_id'=>$userid,
  777. 'use_state'=>1,
  778. );
  779. M()->startTrans();
  780. if ($identify == 'group_badge_user'){
  781. //团体用户 绑定设备 并绑定用户信息
  782. if( !$data['user_no'] || !$data['username'] ){
  783. json_fail('用户姓名和编号不能为空');
  784. }
  785. // 第一次绑定:将 badgeuser 中的 department_id 赋给 users 的 department_id,之后将只能绑定该部门下的设备
  786. // badge_cond
  787. $badge_cond = ['user_no'=>$data['user_no'], 'username'=>$data['username']];
  788. $userinfo = M('users')->where(['id'=>$userid])->find();
  789. if ($userinfo['department_id']) {
  790. $badge_cond['department_id'] = $userinfo['department_id'];
  791. }
  792. $badge_info = M('badgeuser')->where($badge_cond)->find();
  793. if(!$badge_info){
  794. json_fail('绑定用户不存在');
  795. }
  796. if ($badge_info['is_used']) {
  797. json_fail('该用户已绑定');
  798. }
  799. // 检测设备与用户是否在同一部门
  800. if ($device_info['department_id'] != $badge_info['department_id']) {
  801. json_fail('用户与设备所属部门不一致');
  802. }
  803. $update_data=array('is_used'=>1);
  804. //$badgeRes=M('badgeuser')->createSave(array('id'=>$badge_info['uid']),$update_data);
  805. // 修改徽章用户状态
  806. $badgeRes = M('badgeuser')->where(array('id'=>$badge_info['id']))->setField($update_data);
  807. if(!$badgeRes){
  808. M()->rollback();
  809. json_fail('绑定用户失败');
  810. }
  811. $save_data['badge_user_id']=$badge_info['id'];
  812. // 设置登录用户部门
  813. if (!$userinfo['department_id']) {
  814. $res = M('users')->where(['id'=>$userid])->setField(['department_id'=>$badge_info['department_id']]);
  815. if($res === false){
  816. M()->rollback();
  817. json_fail('设置用户部门失败');
  818. }
  819. }
  820. }
  821. $devRes=M('devices')->createSave(array('id'=>$device_info['id']),$save_data);
  822. if(!$devRes){
  823. M()->rollback();
  824. json_fail('绑定设备失败');
  825. }
  826. //未同步设备需要先同步
  827. if($device_info['sync_status']!=1){
  828. $result=$this->addToVoiceCenter($device_info['imei']);
  829. if(!$result['success']){
  830. create_log($device_info['imei'].'绑定时同步失败 message: '.$result['messaget'], 'AddVoiceCenter');
  831. M()->rollback();
  832. json_fail('绑定设备失败');
  833. }
  834. }
  835. M()->commit();
  836. json_success('绑定成功',$userid);
  837. }
  838. public function getUserFences( ){
  839. //user_has_students
  840. header('Access-Control-Allow-Origin: *');
  841. $userid =intval(I('get.userid'));
  842. if(!$userid){
  843. json_fail('获取不到你的用户标识,请重新登陆');
  844. }
  845. $field = 'id, name, fence_shape as shape, creator_id as userid, is_check_in as inFenceAlarm, is_check_out as outFenceAlarm, fence_info as fenceInfo, sent_interval';
  846. $res = M('fences')->field($field)->where(['creator_id' => $userid, 'fence_type' => 1])->select();
  847. if(!$res){
  848. json_fail('查询不到用户围栏');
  849. }
  850. foreach($res as &$v){
  851. $v['inFenceAlarm'] = (bool)($v['inFenceAlarm']);
  852. $v['outFenceAlarm'] = (bool)($v['outFenceAlarm']);
  853. $v['fenceInfo'] = json_decode($v['fenceInfo'], true);
  854. $convPoint = (new \Jms\Algo\Geometry())->convertBd09ToGcj02($v['fenceInfo']['center']['lat'], $v['fenceInfo']['center']['lng']);
  855. $v['fenceInfo']['center']['lat'] = $convPoint['lat'];
  856. $v['fenceInfo']['center']['lng'] = $convPoint['lng'];
  857. }
  858. json_success('查询成功', $res);
  859. }
  860. public function changeUserFenceAlarmStatus( ){
  861. //user_has_students
  862. header('Access-Control-Allow-Origin: *');
  863. $post_data = file_get_contents('php://input');
  864. $post_data = json_decode($post_data, true);
  865. $fenceId = $post_data['id'];
  866. if(!$fenceId){
  867. json_fail('获取不到围栏标识,请刷新下');
  868. }
  869. $alarmType = $post_data['alarmType'];
  870. $value = $post_data['value'];
  871. if(is_null($value) ){
  872. json_fail('获取不到告警标识值');
  873. }
  874. $saveData = [];
  875. if($alarmType == 'in'){
  876. $saveData['is_check_in'] = $value;
  877. }else{
  878. $saveData['is_check_out'] = $value;
  879. }
  880. $res = M('fences')->where(['id' => $fenceId])->save($saveData);
  881. if(!res){
  882. json_fail('修改告警状态失败');
  883. }
  884. json_success('修改告警状态成功');
  885. }
  886. public function updateDeviceInfo( ){
  887. header('Access-Control-Allow-Origin: *');
  888. $openid = I('get.openid');
  889. $userid = I('get.userid');
  890. //检测登录状态
  891. $res=$this->checkLoginState($openid,$userid);
  892. if(!$res['status']){
  893. json_fail($res['message']);
  894. }
  895. $data = json_decode( file_get_contents("php://input") ,true);
  896. $device_id=$data['device_id'];
  897. if(!$device_id){
  898. json_fail('缺少设备ID');
  899. }
  900. $device_name=$data['device_name'];
  901. if(!$device_name){
  902. json_fail('缺少修改信息');
  903. }
  904. $cond=array('id'=>$device_id);
  905. $res=M('devices')->createSave($cond,array('device_name'=>$device_name));
  906. if(!$res){
  907. json_fail('修改失败');
  908. }
  909. json_success('修改成功',$list);
  910. }
  911. public function getSystemFences( ){
  912. //user_has_students
  913. header('Access-Control-Allow-Origin: *');
  914. $userid =intval(I('get.userid'));
  915. if(!$userid){
  916. json_fail('获取不到你的用户标识,请重新登陆');
  917. }
  918. $userBelongDep = M('users')->where(['id' => $userid ])->getField('department_id');
  919. if(!$userBelongDep){
  920. json_fail('查询不到用户归属组织');
  921. }
  922. $departIds = M('departments')->where(['id' => $userBelongDep ])->getField('level');
  923. if($departIds){
  924. $departIds = explode('-', $departIds);
  925. }else{
  926. $departIds =[];
  927. }
  928. array_push($departIds, $userBelongDep);
  929. $typeid = M('sys_dict_type')->where(['code' =>'FenceType'])->getField('id');
  930. $fenceTypeAssoc = M('sys_dict_data')->where(['type_id' => $typeid])->getField('code, value');
  931. $fenceCond = [
  932. 'fence_type' => ['in', [0, 2]],
  933. 'departments' => ['in', $departIds]
  934. ];
  935. $field = 'fences.id, name, fence_shape as shape,fences.creator_id as userid, is_check_in as inFenceAlarm,fence_type, is_check_out as outFenceAlarm, fence_info as fenceInfo, departments.department_name';
  936. $res = M('fences')->field($field)
  937. ->join('departments on fences.departments = departments.id')
  938. ->where($fenceCond)
  939. ->select();
  940. if(!$res){
  941. json_fail('查询不到系统围栏');
  942. }
  943. foreach($res as &$v){
  944. $v['inFenceAlarm'] = (bool)($v['inFenceAlarm']);
  945. $v['outFenceAlarm'] = (bool)($v['inFenceAlarm']);
  946. $v['fence_type_text'] = $fenceTypeAssoc[$v['fence_type']];
  947. }
  948. json_success('查询成功', $res);
  949. }
  950. public function userUnbindDevice( ){
  951. header('Access-Control-Allow-Origin: *');
  952. $openid = I('get.openid');
  953. $userid = I('get.userid');
  954. //检测登录状态
  955. $res=$this->checkLoginState($openid,$userid);
  956. if(!$res['status']){
  957. json_fail($res['message']);
  958. }
  959. // 通过手机号和短信验证码注册
  960. $data = json_decode( file_get_contents("php://input") ,true);
  961. //$data['imei'],$data['user_no'],$data['username']
  962. //先查询设备信息 看是否被绑定
  963. if(!$data['device_id']){
  964. json_fail('缺少设备ID参数');
  965. }
  966. $device_info=M('devices')->where(array('id'=>$data['device_id']))->find();
  967. if(!$device_info){
  968. json_fail('设备不存在,请确认输入无误');
  969. }
  970. $save_data=array(
  971. 'user_id'=>'',
  972. 'badge_user_id'=>'',
  973. 'use_state'=>0,
  974. );
  975. M()->startTrans();
  976. if($device_info['badge_user_id']){
  977. $badRes=M('badgeuser')->createSave(array('id'=>$device_info['badge_user_id']),array('is_used'=>0));
  978. if(!$badRes){
  979. json_fail('解绑失败');
  980. }
  981. }
  982. $devRes=M('devices')->createSave(array('id'=>$device_info['id']),$save_data);
  983. if(!$devRes){
  984. M()->rollback();
  985. json_fail('解绑失败');
  986. }
  987. // 如果没有设备了,置空 department_id
  988. if (!M('devices')->where(['user_id'=>$userid])->count()) {
  989. $res = M('users')->where(['id'=>$userid])->setField(['department_id'=>'']);
  990. if($res === false){
  991. M()->rollback();
  992. json_fail('解绑失败2');
  993. }
  994. }
  995. M()->commit();
  996. json_success('解绑成功',$userid);
  997. }
  998. public function addUserFence( ){
  999. //user_has_students
  1000. header('Access-Control-Allow-Origin: *');
  1001. $data = json_decode( file_get_contents("php://input") ,true);
  1002. $userid =intval($data['userid']);
  1003. if(!$userid){
  1004. json_fail('获取不到你的用户标识,请重新登陆');
  1005. }
  1006. $fenceName = $data['fenceName'];
  1007. if(!$fenceName){
  1008. json_fail('获取不到围栏名');
  1009. }
  1010. $fenceInfo = $data['fenceInfo'];
  1011. if(!$fenceInfo){
  1012. json_fail('获取不到围栏信息');
  1013. }
  1014. $convPoint = (new \Jms\Algo\Geometry())->convertGcj02ToBd09($fenceInfo['center']['lat'], $fenceInfo['center']['lng']);
  1015. $fenceInfo['center']['lat'] = $convPoint['lat'];
  1016. $fenceInfo['center']['lng'] = $convPoint['lng'];
  1017. $saveData = [
  1018. 'creator_id' => $userid,
  1019. 'name' => $fenceName,
  1020. 'push_users' => json_encode([$userid]),
  1021. 'fence_shape' => 'circle',
  1022. 'fence_type' => 1,
  1023. 'fence_info' => json_encode($fenceInfo),
  1024. 'created_at' => time(),
  1025. 'created_at' => time()
  1026. ];
  1027. $res = M('fences')->add($saveData);
  1028. if(!$res){
  1029. json_fail('保存入库失败');
  1030. }
  1031. json_success('保存入库成功');
  1032. }
  1033. private function getWeixinAccessToken( ){
  1034. $token = (new \Jiaruan\WxTmp())->getAccessToken();
  1035. return $token;
  1036. /*
  1037. $appid= C('WECHAT_APPID');
  1038. $appSecret = C('WECHAT_APPSECRET');
  1039. $accessToken = S('wx_pub_accessToken');
  1040. if(!$accessToken){
  1041. $ch = curl_init();
  1042. curl_setopt($ch, CURLOPT_URL, 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$appid.'&secret='.$appSecret);
  1043. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  1044. $output = json_decode(curl_exec($ch), true);
  1045. curl_close($ch);
  1046. if($output['errcode']){
  1047. return $output;
  1048. }
  1049. S('wx_pub_accessToken', $output['access_token'], '7100');
  1050. return $output['access_token'];
  1051. }else{
  1052. return $accessToken;
  1053. }
  1054. */
  1055. }
  1056. public function getAlarmRecords( ){
  1057. header('Access-Control-Allow-Origin: *');
  1058. $post_data = json_decode(file_get_contents('php://input'), true);
  1059. $openid = $post_data['openid'];
  1060. $userid = $post_data['userid'];
  1061. //检测登录状态
  1062. $res = $this->checkLoginState($openid,$userid);
  1063. if(!$res['status']){
  1064. json_fail($res['message']);
  1065. }
  1066. // 获取登录账号部门下所有告警状态的学生数据
  1067. $user_model = M('users');
  1068. $where = ['id' => $userid];
  1069. $userinfo = $user_model->field('id,department_id')->where($where)->find();
  1070. // 获取权限范围内的用户id
  1071. $creator_ids = $this->getRightCreatorIds($userinfo);
  1072. if ($creator_ids === false) {
  1073. json_fail('获取数据失败');
  1074. }
  1075. $limit = isset($post_data['limit']) ? $post_data['limit'] : 10;
  1076. $page = isset($post_data['page']) ? $post_data['page'] : 1;
  1077. // 告警记录条件
  1078. // 初始化条件
  1079. $cond = [];
  1080. $reason = I('get.reason');
  1081. $state = I('get.state');
  1082. $result = I('get.result');
  1083. if ($reason) {
  1084. if ($reason == 'fence') {
  1085. $cond['alarm_reason'] = ['IN', ['fence_in', 'fence_out']];
  1086. } else {
  1087. $cond['alarm_reason'] = $reason;
  1088. }
  1089. } else {
  1090. // 默认只显示 SOS 和围栏告警记录
  1091. $cond['alarm_reason'] = ['IN', ['fence_in', 'fence_out', 'press']];
  1092. }
  1093. if ($state) {
  1094. $cond['state'] = $state;
  1095. }
  1096. if ($result !== '' && is_numeric($result)) {
  1097. $cond['result'] = $result;
  1098. }
  1099. if (is_array($creator_ids)) {
  1100. $cond['creator_id'] = ['IN', $creator_ids];
  1101. }
  1102. // 查出总数量
  1103. $list = [];
  1104. $total = M('alarm_records')->where($cond)->count();
  1105. if ($total) {
  1106. if ($state == 'start' || $state == 'end') {
  1107. $order = "{$state}_time desc";
  1108. } else {
  1109. $order = 'id desc';
  1110. }
  1111. $fields = 'id,device_number,alarm_reason,handler_id,start_time,end_time,state,comment,result';
  1112. $list = M('alarm_records')->field($fields)->where($cond)->limit($limit)->page($page)->order($order)->select() ?: [];
  1113. if (!empty($list)) {
  1114. // alarm_reason,handler_id,result
  1115. // 获取告警类型
  1116. $typeid = M('sys_dict_type')->where(['code' => 'AlarmType'])->getField('id');
  1117. $reason_arr = M('sys_dict_data')->where(['type_id' => $typeid])->getField('code, value');
  1118. // 处理结果
  1119. $result_arr = [
  1120. 0 => '待处理',
  1121. 1 => '已处理',
  1122. 2 => '误报',
  1123. ];
  1124. // 中文转换
  1125. foreach ($list as &$alarm) {
  1126. $alarm['start_time'] = $alarm['start_time'] ? date('Y-m-d H:i:s', $alarm['start_time']) : '';
  1127. $alarm['end_time'] = $alarm['end_time'] ? date('Y-m-d H:i:s', $alarm['end_time']) : '';
  1128. if (is_array($reason_arr)) {
  1129. $alarm['alarm_reason'] = $reason_arr[$alarm['alarm_reason']];
  1130. }
  1131. if (is_numeric($alarm['result'])) {
  1132. $alarm['result'] = $result_arr[$alarm['result']];
  1133. }
  1134. }
  1135. }
  1136. }
  1137. // 返回
  1138. $data = [
  1139. 'total' => $total,
  1140. 'limit' => $limit,
  1141. 'page' => $page,
  1142. 'list' => $list,
  1143. ];
  1144. json_success('获取成功', $data);
  1145. }
  1146. public function getAlarmDetail( ){
  1147. header('Access-Control-Allow-Origin: *');
  1148. $openid = I('get.openid');
  1149. $userid = I('get.userid');
  1150. if(!$userid || $userid == 'undefined' || $userid == 'null'){
  1151. json_fail('获取不到你的用户标识,请重新登陆');
  1152. }
  1153. //检测登录状态
  1154. $res = $this->checkLoginState($openid,$userid);
  1155. if(!$res['status']){
  1156. json_fail($res['message']);
  1157. }
  1158. $alarm_id = I('get.id');
  1159. if (!$alarm_id) {
  1160. json_fail('获取告警信息失败1');
  1161. }
  1162. // 查出告警数据
  1163. $where = ['id' => $alarm_id];
  1164. $alarm_info = M('alarm_records')->where($where)->find();
  1165. if (empty($alarm_info)) {
  1166. json_fail('获取告警信息失败2');
  1167. }
  1168. $report_id = I('get.rid');
  1169. if (!$report_id) {
  1170. json_fail('获取告警信息失败3');
  1171. }
  1172. $where = ['id' => $report_id];
  1173. $alarm_report = M('alarm_report')->where($where)->find();
  1174. if (empty($alarm_report)) {
  1175. json_fail('获取告警信息失败4');
  1176. }
  1177. $alarm_info['address']=$alarm_report['address'];
  1178. // 查出设备信息
  1179. $where = ['imei' => $alarm_info['device_number']];
  1180. $device_info = M('devices')->where($where)->find();
  1181. if (empty($alarm_info)) {
  1182. json_fail('获取告警设备信息失败');
  1183. }
  1184. if ($device_info['online_time'] > $device_info['wifi_online_time']) {
  1185. $device_info['last_online_time'] = date('Y-m-d H:i:s', $device_info['online_time']);
  1186. $device_info['last_location'] = $device_info['longitude'] .','. $device_info['latitude'];
  1187. $res = bmap_geocoding($device_info['latitude'], $device_info['longitude']);
  1188. if($res['success']){
  1189. $device_info['address'] = $res['address'];
  1190. }else{
  1191. $device_info['address']='';
  1192. }
  1193. } elseif ($device_info['online_time'] < $device_info['wifi_online_time']) {
  1194. $device_info['last_online_time'] = date('Y-m-d H:i:s', $device_info['wifi_online_time']);
  1195. $device_info['last_location'] = $device_info['wifi_longitude'] .','. $device_info['wifi_latitude'];
  1196. } else {
  1197. $device_info['last_online_time'] = '0000-00-00 00:00:00';
  1198. $device_info['last_location'] = '';
  1199. $device_info['address']='';
  1200. }
  1201. // 查出设备用户
  1202. if ($device_info['badge_user_id']) {
  1203. $where = ['id' => $device_info['badge_user_id']];
  1204. $user_info = M('badgeuser')->where($where)->find() ?: [];
  1205. } else {
  1206. $where = ['id' => $device_info['user_id']];
  1207. $user_info = M('users')->where($where)->find() ?: [];
  1208. }
  1209. //if (empty($user_info)) {
  1210. //json_fail('获取告警用户信息失败');
  1211. //}
  1212. // 获取紧急联系人
  1213. $where = ['device_id' => $device_info['id']];
  1214. $urgent_list = M('kq_urgent')->where($where)->select() ? : [];
  1215. if (!empty($urgent_list)) {
  1216. $type_id = M('sys_dict_type')->where(['code' => 'Relationships'])->getField('id');
  1217. $ships = M('sys_dict_data')->where(['type_id' => $type_id])->getField('code,value');
  1218. foreach ($urgent_list as $key => &$urgent) {
  1219. $urgent['relationship_text'] = $ships[$urgent['relationship']];
  1220. }
  1221. }
  1222. // 部门名称
  1223. $alarm_info['department_name'] = M('departments')->where(['id' => $user_info['department_id']])->getField('department_name');
  1224. $alarm_info['user_info'] = $user_info;
  1225. $alarm_info['urgent_list'] = $urgent_list;
  1226. $alarm_info['device_info'] = $device_info;
  1227. $alarm_info['device_info']['department_name'] = $alarm_info['department_name'];
  1228. json_success('获取成功', $alarm_info);
  1229. }
  1230. public function handleAlarm( ){
  1231. header('Access-Control-Allow-Origin: *');
  1232. $post_data = json_decode(file_get_contents('php://input'), true);
  1233. $openid = I('get.openid');
  1234. $userid = I('get.userid');
  1235. if(!$userid || $userid == 'undefined' || $userid == 'null'){
  1236. json_fail('获取不到你的用户标识,请重新登陆');
  1237. }
  1238. //检测登录状态
  1239. $res = $this->checkLoginState($openid,$userid);
  1240. if(!$res['status']){
  1241. json_fail($res['message']);
  1242. }
  1243. // result 1-出警,2-误报
  1244. if (!$post_data['result']) {
  1245. json_fail('处理结果不能为空');
  1246. }
  1247. if (!$post_data['comment']) {
  1248. json_fail('处理原因不能为空');
  1249. }
  1250. if (!$post_data['id']) {
  1251. json_fail('未获取到告警信息1');
  1252. }
  1253. $time = time();
  1254. M()->startTrans();
  1255. // 修改前,检测结果是否一致,如果一致不允许重复操作
  1256. $records_model = M('alarm_records');
  1257. $where = ['id' => $post_data['id']];
  1258. $record_info = $records_model->where($where)->field('device_number,result')->find();
  1259. if (empty($record_info)) {
  1260. json_fail('未获取到告警信息2');
  1261. }
  1262. //if ($record_info['result'] > 0) {
  1263. if ($record_info['result'] == $post_data['result']) {
  1264. M()->rollback();
  1265. json_fail('已处理,请勿重复操作');
  1266. }
  1267. $where = ['id' => $post_data['id']];
  1268. $save_data = [
  1269. 'comment' => $post_data['comment'],
  1270. 'result' => $post_data['result'],
  1271. 'handler_id' => $userid,
  1272. 'state' => 'end',
  1273. 'end_time' => $time,
  1274. 'updated_at' => $time,
  1275. ];
  1276. $res = $records_model->createSave($where, $save_data);
  1277. if ($res === false) {
  1278. M()->rollback();
  1279. json_fail('操作失败');
  1280. }
  1281. // 查出设备告警状态
  1282. $where = ['imei' => $record_info['device_number']];
  1283. $device_info = M('devices')->where($where)->field('id,alarm_state')->find();
  1284. if ($device_info['alarm_state'] > 0) {
  1285. // 修改设备状态
  1286. $where = ['id' => $device_info['id']];
  1287. $res = M('devices')->where($where)->setField('alarm_state', 0);
  1288. if (!$res) {
  1289. M()->rollback();
  1290. json_fail('修改设备状态失败');
  1291. }
  1292. }
  1293. M()->commit();
  1294. json_success('操作成功');
  1295. }
  1296. public function editYysProfile( ){
  1297. header('Access-Control-Allow-Origin: *');
  1298. $openid = I('get.openid');
  1299. $userid = I('get.userid');
  1300. //检测登录状态
  1301. $res = $this->checkLoginState($openid,$userid);
  1302. if(!$res['status']){
  1303. json_fail($res['message']);
  1304. }
  1305. $data = json_decode( file_get_contents("php://input") ,true);
  1306. $data = array_map(function($item){
  1307. return trim($item);
  1308. }, $data);
  1309. if (!$data['nickName']) {
  1310. json_fail('昵称不能为空');
  1311. }
  1312. if (!$data['phone']) {
  1313. json_fail('手机号码不能为空');
  1314. }
  1315. if (!preg_match('/^[-_a-zA-Z0-9]{6,16}?$/', $data['phone'])) {
  1316. json_fail('手机号码格式不正确');
  1317. }
  1318. // 修改密码
  1319. if ($data['oldPwd']) {
  1320. if (!$data['newPwd']) {
  1321. json_fail('新密码不能为空');
  1322. }
  1323. if (!$data['confirmNewPwd']) {
  1324. json_fail('确认密码不能为空');
  1325. }
  1326. if ($data['newPwd'] != $data['confirmNewPwd']) {
  1327. json_fail('两次新密码不一致');
  1328. }
  1329. }
  1330. $userCond = array( 'id' => $userid);
  1331. $user_info = M('users')->where($userCond)->find();
  1332. if(!$user_info){
  1333. json_fail('获取用户信息失败');
  1334. }
  1335. if ($user_info['wx_open_id'] != $openid) {
  1336. json_fail('账号可能被其他用户登录,请重新登录');
  1337. }
  1338. if ($data['oldPwd']) {
  1339. if(!password_verify($data['oldPwd'], $user_info['password'])){
  1340. json_fail('原密码不正确');
  1341. }
  1342. }
  1343. $saveData = [
  1344. 'realname' => $data['nickName'],
  1345. 'phone' => $data['phone'],
  1346. ];
  1347. // 有原密码才能修改
  1348. if ($data['oldPwd']) {
  1349. $saveData['password'] = password_hash($data['newPwd'], PASSWORD_DEFAULT);
  1350. }
  1351. $result = M('users')->createSave($userCond, $saveData);
  1352. if(!$result){
  1353. json_fail('修改失败');
  1354. }
  1355. $respData = [
  1356. 'id' => $user_info['id'],
  1357. 'realname' => $data['nickName'],
  1358. 'avatar' => $user_info['avatar'],
  1359. 'phone' => $data['phone'],
  1360. ];
  1361. json_success('修改成功', $respData);
  1362. }
  1363. public function changeAuthorize( ){
  1364. //user_has_students
  1365. header('Access-Control-Allow-Origin: *');
  1366. $imei = I('get.imei');
  1367. if(!$imei){
  1368. json_fail('获取不到设备号');
  1369. }
  1370. $authorize = intval(I('get.authorize') );
  1371. if($authorize !== 0 && $authorize !== 1){
  1372. json_fail('授权状态值不合法');
  1373. }
  1374. $saveData = [
  1375. 'authorize' => $authorize,
  1376. 'updated_at' => time()
  1377. ];
  1378. $res = M('devices')->where(['imei' => $imei])->save($saveData);
  1379. if(!res){
  1380. json_fail('权限修改失败');
  1381. }
  1382. json_success('权限修改成功');
  1383. }
  1384. public function getDeviceInfoSingle( ){
  1385. //user_has_students
  1386. header('Access-Control-Allow-Origin: *');
  1387. $imei = I('get.imei');
  1388. if(!$imei){
  1389. json_fail('获取不到设备号');
  1390. }
  1391. $res = M('devices')->where(['imei' => $imei])->find();
  1392. if(!res){
  1393. json_fail('获取设备信息失败');
  1394. }
  1395. json_success('获取设备信息成功', $res);
  1396. }
  1397. public function getDevices( ){
  1398. // 获取登录用户信息
  1399. $userinfo = $this->getYysLoginUserinfo();
  1400. // 获取权限范围内的用户id
  1401. $creator_ids = $this->getRightCreatorIds($userinfo);
  1402. if ($creator_ids === false) {
  1403. json_fail('获取失败');
  1404. }
  1405. // 获取 POST 数据
  1406. $post_data = json_decode(file_get_contents('php://input'), true);
  1407. $limit = isset($post_data['limit']) ? $post_data['limit'] : 10;
  1408. $page = isset($post_data['page']) ? $post_data['page'] : 1;
  1409. $imei = $post_data['imei'];
  1410. $list = [];
  1411. $cond = [];
  1412. $devices_model = M('devices');
  1413. // 查出总数量
  1414. if (is_array($creator_ids)) {
  1415. $cond['creator_id'] = ['IN', $creator_ids];
  1416. }
  1417. if ($imei) {
  1418. $cond['imei'] = ['LIKE', "%{$imei}%"];
  1419. }
  1420. $total = $devices_model->where($cond)->count();
  1421. if ($total) {
  1422. $list = $devices_model->where($cond)->limit($limit)->page($page)->select() ?: [];
  1423. }
  1424. // 返回
  1425. $data = [
  1426. 'total' => $total,
  1427. 'limit' => $limit,
  1428. 'page' => $page,
  1429. 'list' => $list,
  1430. ];
  1431. json_success('获取成功', $data);
  1432. }
  1433. private function getYysLoginUserinfo( ){
  1434. header('Access-Control-Allow-Origin: *');
  1435. $openid = I('get.openid');
  1436. if(!$openid){
  1437. json_fail('未获取到微信授权信息,请重新点击菜单进入并授权');
  1438. }
  1439. // 微信运营角色
  1440. $where = ['identify' => 'wxyy'];
  1441. $role_id = M('roles')->where($where)->getField('id');
  1442. if (!$role_id) {
  1443. json_fail('未开放微信运营角色');
  1444. }
  1445. // 获取登录账号信息
  1446. $userid = I('get.userid');
  1447. $cond = [
  1448. //'u.wx_open_id' => $openid,
  1449. 'u.id' => $userid,
  1450. ];
  1451. //$userinfo = M('users')->field('id,department_id')->where($where)->find();
  1452. $userinfo = M('users')->alias('u')->field('u.*')->where($cond)->join("INNER JOIN user_has_roles AS r ON u.id = r.uid AND r.role_id = {$role_id}")->find();
  1453. if (!$userinfo) {
  1454. json_fail('获取用户信息失败,请重新登录');
  1455. }
  1456. if ($userinfo['wx_open_id'] != $openid) {
  1457. json_fail('账号可能在其他设备登录,请重新登录');
  1458. }
  1459. return $userinfo;
  1460. }
  1461. public function getDeviceDetail( ){
  1462. header('Access-Control-Allow-Origin: *');
  1463. $userid = I('get.userid');
  1464. if(!$userid || $userid == 'undefined' || $userid == 'null'){
  1465. json_fail('未获取到用户标识,请重新登陆');
  1466. }
  1467. $id = I('get.id');
  1468. if (!$id) {
  1469. json_fail('获取设备信息失败');
  1470. }
  1471. $openid = I('get.openid');
  1472. //检测登录状态
  1473. $res = $this->checkLoginState($openid, $userid);
  1474. if(!$res['status']){
  1475. json_fail($res['message']);
  1476. }
  1477. // 检测是否在查询权限范围
  1478. // 查出设备信息
  1479. $where = ['id' => $id];
  1480. $device_info = M('devices')->where($where)->find() ? : [];
  1481. if (empty($device_info)) {
  1482. json_fail('未获取到设备信息');
  1483. }
  1484. if ($device_info['online_time'] >= $device_info['wifi_online_time']) {
  1485. $device_info['last_online_time'] = date('Y-m-d H:i:s', $device_info['online_time']);
  1486. $convPoint = (new \Jms\Algo\Geometry())->convertBd09ToGcj02($device_info['latitude'],$device_info['longitude']);
  1487. $device_info['last_location'] = $convPoint['lng'] .','. $convPoint['lat'];
  1488. } elseif ($device_info['online_time'] < $device_info['wifi_online_time']) {
  1489. $device_info['last_online_time'] = date('Y-m-d H:i:s', $device_info['wifi_online_time']);
  1490. $convPoint = (new \Jms\Algo\Geometry())->convertBd09ToGcj02($device_info['wifi_latitude'],$device_info['wifi_longitude']);
  1491. $device_info['last_location'] = $convPoint['lng'] .','. $convPoint['lat'];
  1492. } else {
  1493. $device_info['last_online_time'] = '0000-00-00 00:00:00';
  1494. $device_info['last_location'] = '';
  1495. }
  1496. // 查出设备用户
  1497. if ($device_info['badge_user_id']) {
  1498. $where = ['id' => $device_info['badge_user_id']];
  1499. $user_info = M('badgeuser')->where($where)->find() ?: [];
  1500. } else {
  1501. $where = ['id' => $device_info['user_id']];
  1502. $user_info = M('users')->where($where)->find() ?: [];
  1503. }
  1504. //if (empty($user_info)) {
  1505. //json_fail('获取告警用户信息失败');
  1506. //}
  1507. // 获取紧急联系人
  1508. $where = ['device_id' => $device_info['id']];
  1509. $urgent_list = M('kq_urgent')->where($where)->select() ? : [];
  1510. if (!empty($urgent_list)) {
  1511. $type_id = M('sys_dict_type')->where(['code' => 'Relationships'])->getField('id');
  1512. $ships = M('sys_dict_data')->where(['type_id' => $type_id])->getField('code,value');
  1513. foreach ($urgent_list as $key => &$urgent) {
  1514. $urgent['relationship_text'] = $ships[$urgent['relationship']];
  1515. }
  1516. }
  1517. // 部门名称
  1518. $device_info['department_name'] = M('departments')->where(['id' => $user_info['department_id']])->getField('department_name');
  1519. $device_info['user_info'] = $user_info;
  1520. $device_info['urgent_list'] = $urgent_list;
  1521. json_success('获取成功', $device_info);
  1522. }
  1523. public function getWaitHandleAlarmCounts( ){
  1524. // 获取登录用户信息
  1525. $userinfo = $this->getYysLoginUserinfo();
  1526. // 获取权限范围内的用户id
  1527. $creator_ids = $this->getRightCreatorIds($userinfo);
  1528. if ($creator_ids === false) {
  1529. json_fail('获取失败');
  1530. }
  1531. $cond = [
  1532. 'state' => 'start',
  1533. ];
  1534. // 查出总数量
  1535. if (is_array($creator_ids)) {
  1536. $cond['creator_id'] = ['IN', $creator_ids];
  1537. }
  1538. $fields = 'alarm_reason, count(alarm_reason) as count';
  1539. $list = M('alarm_records')->where($cond)->group('alarm_reason')->getField($fields) ?:[];
  1540. json_success('获取成功', $list);
  1541. }
  1542. public function getDevicePositionList( ){
  1543. // 获取登录用户信息
  1544. $userinfo = $this->getYysLoginUserinfo();
  1545. // 获取权限范围内的用户id
  1546. $creator_ids = $this->getRightCreatorIds($userinfo);
  1547. if ($creator_ids === false) {
  1548. json_fail('获取失败');
  1549. }
  1550. $cond = [
  1551. 'use_state' => 1,
  1552. ];
  1553. // 查出总数量
  1554. if (is_array($creator_ids)) {
  1555. $cond['creator_id'] = ['IN', $creator_ids];
  1556. }
  1557. $fields = 'imei,device_name,device_type,battery_level,loc_mode,loc_ploy,online_time,longitude,latitude,wifi_online_time,wifi_longitude,wifi_latitude,alarm_state';
  1558. $list = M('devices')->field($fields)->where($cond)->select() ?: [];
  1559. $resp = [];
  1560. foreach($list as &$locationInfo){
  1561. //new end
  1562. //wifi_online_time
  1563. //wifi_longitude
  1564. //wifi_latitude
  1565. //addr
  1566. $locationInfo['isAlarm'] = $locationInfo['alarm_state'];
  1567. $isWifi = $locationInfo['wifi_online_time'] > $locationInfo['online_time'] || intval($locationInfo['latitude']) < 1 ;
  1568. $locationInfo['time'] = $isWifi ? $locationInfo['wifi_online_time'] : $locationInfo['online_time'];
  1569. $locationInfo['lat'] = $isWifi ? $locationInfo['wifi_latitude'] : $locationInfo['latitude'];
  1570. $locationInfo['lng'] = $isWifi ? $locationInfo['wifi_longitude'] : $locationInfo['longitude'];
  1571. if(!$locationInfo['time']){
  1572. $locationInfo['awayTime'] = '从未在线';
  1573. }else{
  1574. $timeInterval = time() - (int)$locationInfo['time'];
  1575. $locationInfo['awayTime'] = $this->getHumenTime($timeInterval);
  1576. }
  1577. $lngLatAlter = new \Jms\Algo\Geometry();
  1578. if(!$locationInfo['lat'] || !$locationInfo['lng']){
  1579. continue;
  1580. }
  1581. $latLng = $lngLatAlter->convertBd09ToGcj02($locationInfo['lat'], $locationInfo['lng']);
  1582. $locationInfo['lat'] = $latLng['lat'];
  1583. $locationInfo['lng'] = $latLng['lng'];
  1584. $locationInfo['date_time'] = date('Y-m-d H:i:s', $locationInfo['time']);
  1585. array_push($resp, $locationInfo);
  1586. }
  1587. json_success('获取成功', $resp);
  1588. }
  1589. public function getAllFences( ){
  1590. //user_has_students
  1591. header('Access-Control-Allow-Origin: *');
  1592. $userid =intval(I('get.userid'));
  1593. if(!$userid){
  1594. json_fail('获取不到你的用户标识,请重新登陆');
  1595. }
  1596. $field = 'id, name, fence_shape as shape, creator_id as userid, is_check_in as inAlarm, is_check_out as outAlarm, fence_info as info';
  1597. $cond = [
  1598. 'fence_type' => 0,
  1599. 'creator_id' => $userid,
  1600. '_logic' => 'OR'
  1601. ];
  1602. $res = M('fences')->field($field)->where($cond)->select();
  1603. if(!$res){
  1604. json_fail('查询不到可见的围栏');
  1605. }
  1606. foreach($res as &$v){
  1607. $v['inAlarm'] = (bool)($v['inAlarm']);
  1608. $v['outAlarm'] = (bool)($v['outAlarm']);
  1609. $v['info'] = json_decode($v['info'], true);
  1610. }
  1611. json_success('查询成功', $res);
  1612. }
  1613. public function editUserFence( ){
  1614. //user_has_students
  1615. header('Access-Control-Allow-Origin: *');
  1616. $data = json_decode( file_get_contents("php://input") ,true);
  1617. $userid =intval($data['userid']);
  1618. if(!$userid){
  1619. json_fail('获取不到你的用户标识,请重新登陆');
  1620. }
  1621. $fenceId = intval($data['fenceId']);
  1622. $fenceName = $data['fenceName'];
  1623. if(!$fenceName){
  1624. json_fail('获取不到围栏名');
  1625. }
  1626. $fenceInfo = $data['fenceInfo'];
  1627. if(!$fenceInfo){
  1628. json_fail('获取不到围栏信息');
  1629. }
  1630. $convPoint = (new \Jms\Algo\Geometry())->convertGcj02ToBd09($fenceInfo['center']['lat'], $fenceInfo['center']['lng']);
  1631. $fenceInfo['center']['lat'] = $convPoint['lat'];
  1632. $fenceInfo['center']['lng'] = $convPoint['lng'];
  1633. $saveData = [
  1634. 'name' => $fenceName,
  1635. 'fence_shape' => 'circle',
  1636. 'fence_info' => json_encode($fenceInfo),
  1637. 'updated_at' => time()
  1638. ];
  1639. $res = M('fences')->where(['id' => $fenceId])->save($saveData);
  1640. if(!$res){
  1641. json_fail('保存入库失败');
  1642. }
  1643. json_success('保存入库成功');
  1644. }
  1645. public function getRelationshipList( ){
  1646. header('Access-Control-Allow-Origin: *');
  1647. // 查出 Relationships id
  1648. $where = array('code' => 'Relationships');
  1649. $type_id = M('sys_dict_type')->where($where)->getField('id');
  1650. if (empty($type_id)) {
  1651. json_fail('获取失败');
  1652. }
  1653. $where = array('type_id' => $type_id);
  1654. $list = M('sys_dict_data')->field('code as id, value as text')->where($where)->select();
  1655. if (empty($list)) {
  1656. json_fail('获取失败');
  1657. }
  1658. json_success('获取成功', $list);
  1659. }
  1660. public function editProfile( ){
  1661. header('Access-Control-Allow-Origin: *');
  1662. $openid = I('get.openid');
  1663. $userid = I('get.userid');
  1664. //检测登录状态
  1665. $res = $this->checkLoginState($openid,$userid);
  1666. if(!$res['status']){
  1667. json_fail($res['message']);
  1668. }
  1669. $data = json_decode( file_get_contents("php://input") ,true);
  1670. $data = array_map(function($item){
  1671. return trim($item);
  1672. }, $data);
  1673. if (!$data['nickName']) {
  1674. json_fail('昵称不能为空');
  1675. }
  1676. if (!$data['phone']) {
  1677. json_fail('手机号码不能为空');
  1678. } else {
  1679. if (!preg_match('/^[-_a-zA-Z0-9]{6,16}?$/', $data['phone'])) {
  1680. json_fail('手机号码格式不正确');
  1681. }
  1682. }
  1683. // 修改密码
  1684. if ($data['oldPwd']) {
  1685. if (!$data['newPwd']) {
  1686. json_fail('新密码不能为空');
  1687. }
  1688. if (!$data['confirmNewPwd']) {
  1689. json_fail('确认密码不能为空');
  1690. }
  1691. if ($data['newPwd'] != $data['confirmNewPwd']) {
  1692. json_fail('两次新密码不一致');
  1693. }
  1694. }
  1695. $userCond = array( 'id' => $userid);
  1696. $user_info = M('users')->where($userCond)->find();
  1697. if(!$user_info){
  1698. json_fail('获取用户信息失败');
  1699. }
  1700. if ($user_info['wx_open_id'] != $openid) {
  1701. json_fail('账号可能被其他用户登录,请重新登录');
  1702. }
  1703. if ($data['oldPwd']) {
  1704. if(!password_verify($data['oldPwd'], $user_info['password'])){
  1705. json_fail('原密码不正确');
  1706. }
  1707. }
  1708. $saveData = [
  1709. 'realname' => $data['nickName'],
  1710. 'phone' => $data['phone'],
  1711. ];
  1712. // 有原密码才能修改
  1713. if ($data['oldPwd']) {
  1714. $saveData['password'] = password_hash($data['newPwd'], PASSWORD_DEFAULT);
  1715. }
  1716. $result = M('users')->createSave($userCond, $saveData);
  1717. if(!$result){
  1718. json_fail('修改失败');
  1719. }
  1720. $respData = [
  1721. 'id' => $user_info['id'],
  1722. 'realname' => $data['nickName'],
  1723. 'avatar' => $user_info['avatar'],
  1724. 'phone' => $data['phone'],
  1725. ];
  1726. json_success('修改成功', $respData);
  1727. }
  1728. public function getLastPositionSingle( ){
  1729. header('Access-Control-Allow-Origin: *');
  1730. $imei = I('get.imei');
  1731. if(!$imei){
  1732. json_fail('服务端未检测到设备编号');
  1733. }
  1734. $locationInfo = M('devices')->where(['imei' => $imei])->find();
  1735. if(!$locationInfo){
  1736. json_fail('查询不到该设备当前信息哦!');
  1737. }
  1738. //wifi_online_time
  1739. //wifi_longitude
  1740. //wifi_latitude
  1741. //addr
  1742. $locationInfo['isAlarm'] = $locationInfo['alarm_status'];
  1743. $isWifi = $locationInfo['wifi_online_time'] > $locationInfo['online_time'] || intval($locationInfo['latitude']) < 1 ;;
  1744. $locationInfo['time'] = $isWifi ? $locationInfo['wifi_online_time'] : $locationInfo['online_time'];
  1745. $locationInfo['lat'] = $isWifi ? $locationInfo['wifi_latitude'] : $locationInfo['latitude'];
  1746. $locationInfo['lng'] = $isWifi ? $locationInfo['wifi_longitude'] : $locationInfo['longitude'];
  1747. $locationInfo['address'] = $locationInfo['address'];
  1748. //
  1749. if(!$locationInfo['time']){
  1750. $locationInfo['awayTime'] = '从未在线';
  1751. }else{
  1752. $timeInterval = time() - (int)$locationInfo['time'];
  1753. $locationInfo['awayTime'] = $this->getHumenTime($timeInterval);
  1754. }
  1755. $lngLatAlter = new \Jms\Algo\Geometry();
  1756. $latLng = $lngLatAlter->convertBd09ToGcj02($locationInfo['lat'], $locationInfo['lng']);
  1757. $locationInfo['lat'] = $latLng['lat'];
  1758. $locationInfo['lng'] = $latLng['lng'];
  1759. $locationInfo['date_time'] = date('Y-m-d H:i:s', $locationInfo['time']);
  1760. json_success('查询成功', $locationInfo);
  1761. }
  1762. public function yysLogin( ){
  1763. header('Access-Control-Allow-Origin: *');
  1764. //json_fail('登录失败');
  1765. $openid = I('get.openid');
  1766. if(!$openid){
  1767. json_fail('未授权,请关闭当前页面重新进入');
  1768. }
  1769. $data = json_decode( file_get_contents("php://input") ,true);
  1770. // 微信运营角色
  1771. $where = ['identify' => 'wxyy'];
  1772. $role_id = M('roles')->where($where)->getField('id');
  1773. if (!$role_id) {
  1774. json_fail('未开放微信运营角色');
  1775. }
  1776. $cond = array(
  1777. 'username' => $data['username'],
  1778. );
  1779. $user_info = M('users')->alias('u')->where($cond)->join("INNER JOIN user_has_roles AS r ON u.id = r.uid AND r.role_id = {$role_id}")->find();
  1780. if(!$user_info){
  1781. json_fail('无登录权限或账号、密码错误');
  1782. }
  1783. if(!password_verify($data['password'], $user_info['password'])){
  1784. json_fail('账号或密码错误');
  1785. }
  1786. if($user_info['wx_open_id'] != $openid){
  1787. $update = array(
  1788. 'wx_open_id' => $openid,
  1789. 'last_login_ip' => $_SERVER['REMOTE_ADDR'],
  1790. 'last_login_time' => time(),
  1791. );
  1792. $result = M('users')->createSave(array('id'=>$user_info['uid']),$update);
  1793. if(!$result){
  1794. json_fail('登陆失败');
  1795. }
  1796. }
  1797. //如果当前openid与其他账号openid相同,清空其他表中openid
  1798. /*
  1799. $where = array(
  1800. 'wx_open_id' => $openid,
  1801. 'id' => ['NEQ', $user_info['id']],
  1802. );
  1803. $result = M('users')->createSave($where,['wx_open_id'=>'']);
  1804. if(!$result){
  1805. json_fail('登陆失败');
  1806. }
  1807. */
  1808. $res = array(
  1809. 'id'=>$user_info['uid'],
  1810. 'realname'=>$user_info['realname'],
  1811. 'avatar' => $user_info['avatar'],
  1812. 'phone'=>$user_info['phone'],
  1813. );
  1814. json_success('登录成功', $res);
  1815. }
  1816. public function getWaitHandleAlarmData( ){
  1817. header('Access-Control-Allow-Origin: *');
  1818. $post_data = json_decode(file_get_contents('php://input'), true);
  1819. $openid = $post_data['openid'];
  1820. $userid = $post_data['userid'];
  1821. //检测登录状态
  1822. $res = $this->checkLoginState($openid,$userid);
  1823. if(!$res['status']){
  1824. json_fail($res['message']);
  1825. }
  1826. // 获取登录账号部门下所有告警状态的学生数据
  1827. $user_model = M('users');
  1828. $where = ['id' => $userid];
  1829. $userinfo = $user_model->field('id,department_id')->where($where)->find();
  1830. // 获取权限范围内的用户id
  1831. $creator_ids = $this->getRightCreatorIds($userinfo);
  1832. if ($creator_ids === false) {
  1833. json_fail('获取数据失败');
  1834. }
  1835. $limit = isset($post_data['limit']) ? $post_data['limit'] : 10;
  1836. $page = isset($post_data['page']) ? $post_data['page'] : 1;
  1837. // 查出告警学生id
  1838. $cond = [
  1839. 'alarm_status' => 1,
  1840. ];
  1841. if (is_array($creator_ids)) {
  1842. $cond['creator_id'] = ['IN', $creator_ids];
  1843. }
  1844. // 查出总数量
  1845. $student_list = [];
  1846. $total = $user_model->where($cond)->count();
  1847. if ($total) {
  1848. $fields = 'id,avatar,realname,sex,age,active_rfid,student_no,online_time,last_station_mac,longitude,latitude';
  1849. $student_list = $user_model->field($fields)->where($cond)->limit($post_data['limit'])->page($post_data['page'])->select() ?: [];
  1850. }
  1851. // 返回
  1852. $data = [
  1853. 'total' => $total,
  1854. 'limit' => $limit,
  1855. 'page' => $page,
  1856. 'list' => $student_list,
  1857. ];
  1858. json_success('获取成功', $data);
  1859. }
  1860. private function getRightCreatorIds( $userinfo ){
  1861. $uid = $userinfo['id'];
  1862. $dept_id = $userinfo['department_id'];
  1863. // 非系统角色
  1864. $where = ['identify' => ['IN', 'personal,group_badge_user,group_card_user']];
  1865. $devides_user_ids = M('roles')->where($where)->getField('id', true);
  1866. // 查出拥有系统角色
  1867. $where = [
  1868. 'uid' => $uid,
  1869. 'role_id' => ['NOT IN', $devides_user_ids],
  1870. ];
  1871. $role_ids = M('user_has_roles')->where($where)->getField('role_id', true);
  1872. if (empty($role_ids)) {
  1873. return false;
  1874. }
  1875. $user_ids = [];
  1876. $is_all = false; // 全部数据
  1877. // 查出角色拥有权限
  1878. $where = ['id' => ['IN', $role_ids]];
  1879. $range_list = M('roles')->distinct(true)->where($where)->getField('data_range', true);
  1880. if (empty($range_list)) {
  1881. return false;
  1882. }
  1883. // 根据角色权限查出
  1884. $depart_model = M('departments');
  1885. foreach($range_list as $range) {
  1886. switch ($range) {
  1887. case '1': // 全部数据
  1888. $is_all = true;
  1889. break;
  1890. case '2': // 自定义数据
  1891. case '3': // 本人数据
  1892. $user_ids[] = $uid;
  1893. break;
  1894. case '4': // 部门数据
  1895. $user_ids = array_merge($user_ids, $this->getUserIdsByDepartmentId([$dept_id]));
  1896. break;
  1897. case '5': // 部门及以下数据
  1898. // 查一下下级部门
  1899. // REGEXP '(^76$)|(^76-)'
  1900. //$departmentIds = $depart_model->where(['parent_id' => $dept_id])->getField('id', true);
  1901. $cond = ['level' => ['EXP',"REGEXP '(^{$dept_id}$)|(^{$dept_id}-)'"]];
  1902. $departmentIds = $depart_model->where($cond)->getField('id', true) ?: [];
  1903. $departmentIds[] = $dept_id;
  1904. $user_ids = array_merge([$uid], $this->getUserIdsByDepartmentId($departmentIds));
  1905. break;
  1906. default:
  1907. break;
  1908. }
  1909. // 如果有全部数据 直接跳出
  1910. if ($is_all) {
  1911. break;
  1912. }
  1913. }
  1914. if ($is_all) {
  1915. return true;
  1916. }
  1917. return array_unique(array_filter($user_ids));
  1918. }
  1919. private function getUserIdsByDepartmentId( $id ){
  1920. // 取出非设备用户 (roles identify not in 'personal,group_badge_user,group_card_user')
  1921. $where = ['identify' => ['IN', 'personal,group_badge_user,group_card_user']];
  1922. $devide_role_ids = M('roles')->where($where)->getField('id', true);
  1923. $devide_role_ids = join(',', $devide_role_ids);
  1924. $cond = [
  1925. 'u.department_id' => ['IN', $id],
  1926. ];
  1927. $ids = M('users')->alias('u')
  1928. ->field('u.id')
  1929. ->where($cond)
  1930. ->join("INNER JOIN user_has_roles r ON u.id=r.uid AND r.role_id NOT IN ({$devide_role_ids})")
  1931. ->select() ? : [];
  1932. return array_unique(array_column($ids, 'id'));
  1933. }
  1934. public function getConfirmAlarmData( ){
  1935. header('Access-Control-Allow-Origin: *');
  1936. $post_data = json_decode(file_get_contents('php://input'), true);
  1937. $openid = $post_data['openid'];
  1938. if(!$openid){
  1939. json_fail('未获取到微信授权信息,请重新点击菜单进入并授权');
  1940. }
  1941. $limit = isset($post_data['limit']) ? $post_data['limit'] : 10;
  1942. $page = isset($post_data['page']) ? $post_data['page'] : 1;
  1943. // 获取登录账号部门下所有告警状态的学生数据
  1944. $where = ['wx_open_id' => $openid];
  1945. $userinfo = M('users')->field('id,department_id')->where($where)->find();
  1946. // 获取权限范围内的用户id
  1947. $creator_ids = $this->getRightCreatorIds($userinfo);
  1948. if ($creator_ids === false) {
  1949. json_fail('获取失败');
  1950. }
  1951. // 查出告警学生id
  1952. $cond = [
  1953. 'result' => 1,
  1954. ];
  1955. if (is_array($creator_ids)) {
  1956. $cond['creator_id'] = ['IN', $creator_ids];
  1957. }
  1958. // 查出总数量
  1959. $record_list = [];
  1960. $alarm_handle_records_model = M('alarm_handle_records');
  1961. $total = $alarm_handle_records_model->where($cond)->count();
  1962. if ($total) {
  1963. $record_list = $alarm_handle_records_model->where($cond)->order('created_at desc')->limit($post_data['limit'])->page($post_data['page'])->select() ?: [];
  1964. }
  1965. // 返回
  1966. $data = [
  1967. 'total' => $total,
  1968. 'limit' => $limit,
  1969. 'page' => $page,
  1970. 'list' => $record_list,
  1971. ];
  1972. json_success('获取成功', $data);
  1973. }
  1974. public function getCancelAlarmData( ){
  1975. header('Access-Control-Allow-Origin: *');
  1976. $post_data = json_decode(file_get_contents('php://input'), true);
  1977. $openid = $post_data['openid'];
  1978. if(!$openid){
  1979. json_fail('未获取到微信授权信息,请重新点击菜单进入并授权');
  1980. }
  1981. $limit = isset($post_data['limit']) ? $post_data['limit'] : 10;
  1982. $page = isset($post_data['page']) ? $post_data['page'] : 1;
  1983. // 获取登录账号部门下所有告警状态的学生数据
  1984. $where = ['wx_open_id' => $openid];
  1985. $userinfo = M('users')->field('id,department_id')->where($where)->find();
  1986. // 获取权限范围内的用户id
  1987. $creator_ids = $this->getRightCreatorIds($userinfo);
  1988. if ($creator_ids === false) {
  1989. json_fail('获取失败');
  1990. }
  1991. // 查出告警学生id
  1992. $cond = [
  1993. 'result' => 2,
  1994. ];
  1995. if (is_array($creator_ids)) {
  1996. $cond['creator_id'] = ['IN', $creator_ids];
  1997. }
  1998. // 查出总数量
  1999. $record_list = [];
  2000. $alarm_handle_records_model = M('alarm_handle_records');
  2001. $total = $alarm_handle_records_model->where($cond)->count();
  2002. if ($total) {
  2003. $record_list = $alarm_handle_records_model->where($cond)->order('created_at desc')->limit($post_data['limit'])->page($post_data['page'])->select() ?: [];
  2004. }
  2005. // 返回
  2006. $data = [
  2007. 'total' => $total,
  2008. 'limit' => $limit,
  2009. 'page' => $page,
  2010. 'list' => $record_list,
  2011. ];
  2012. json_success('获取成功', $data);
  2013. }
  2014. public function getFenceAlarmData( ){
  2015. header('Access-Control-Allow-Origin: *');
  2016. $post_data = json_decode(file_get_contents('php://input'), true);
  2017. $openid = $post_data['openid'];
  2018. if(!$openid){
  2019. json_fail('未获取到微信授权信息,请重新点击菜单进入并授权');
  2020. }
  2021. $limit = isset($post_data['limit']) ? $post_data['limit'] : 10;
  2022. $page = isset($post_data['page']) ? $post_data['page'] : 1;
  2023. // 获取登录账号部门下所有告警状态的学生数据
  2024. $where = ['wx_open_id' => $openid];
  2025. $userinfo = M('users')->field('id,department_id')->where($where)->find();
  2026. // 获取权限范围内的用户id
  2027. $creator_ids = $this->getRightCreatorIds($userinfo);
  2028. if ($creator_ids === false) {
  2029. json_fail('获取失败');
  2030. }
  2031. // 查出围栏
  2032. $cond = [];
  2033. if (!$post_data['type']) {
  2034. $cond['alarm_type'] = ['IN',['fence_in','fence_out']];
  2035. } elseif ($post_data['type'] == 'in') {
  2036. $cond['alarm_type'] = 'fence_in';
  2037. } elseif ($post_data['type'] == 'out') {
  2038. $cond['alarm_type'] = 'fence_out';
  2039. } else {
  2040. json_fail('未知的围栏类型');
  2041. }
  2042. if (is_array($creator_ids)) {
  2043. $cond['creator_id'] = ['IN', $creator_ids];
  2044. }
  2045. // 查出总数量
  2046. $list = [];
  2047. $alarm_report = M('alarm_report');
  2048. $total = $alarm_report->where($cond)->count();
  2049. if ($total) {
  2050. $list = $alarm_report->where($cond)->order('created_at desc')->limit($post_data['limit'])->page($post_data['page'])->select() ?: [];
  2051. }
  2052. // 返回
  2053. $data = [
  2054. 'total' => $total,
  2055. 'limit' => $limit,
  2056. 'page' => $page,
  2057. 'list' => $list,
  2058. ];
  2059. json_success('获取成功', $data);
  2060. }
  2061. public function getYysFences( ){
  2062. // 获取登录用户信息
  2063. $userinfo = $this->getYysLoginUserinfo();
  2064. // 获取权限范围内的用户id
  2065. $creator_ids = $this->getRightCreatorIds($userinfo);
  2066. if ($creator_ids === false) {
  2067. json_fail('获取失败');
  2068. }
  2069. $fence_type = I('get.type');
  2070. if (!$fence_type && $fence_type !== 0 && $fence_type !== '0') {
  2071. json_fail('未获取到围栏类型');
  2072. }
  2073. $cond = [
  2074. 'fence_type' => $fence_type,
  2075. ];
  2076. // 查出总数量
  2077. if (is_array($creator_ids)) {
  2078. $cond['creator_id'] = ['IN', $creator_ids];
  2079. }
  2080. $field = 'id, name, fence_shape as shape, creator_id as userid, is_check_in as inAlarm, is_check_out as outAlarm, fence_info as fenceInfo';
  2081. $list = M('fences')->field($field)->where($cond)->select();
  2082. if(!$list){
  2083. json_fail('暂无围栏');
  2084. }
  2085. $geometry = new \Jms\Algo\Geometry();
  2086. foreach($list as &$v){
  2087. $v['inAlarm'] = (bool)($v['inAlarm']);
  2088. $v['outAlarm'] = (bool)($v['outAlarm']);
  2089. // 坐标转换:GCJ-02 -> BD-09
  2090. $v['fenceInfo'] = json_decode($v['fenceInfo'], true) ?:[];
  2091. $convPoint = $geometry->convertBd09ToGcj02($v['fenceInfo']['center']['lat'], $v['fenceInfo']['center']['lng']);
  2092. $v['fenceInfo']['center']['lat'] = $convPoint['lat'];
  2093. $v['fenceInfo']['center']['lng'] = $convPoint['lng'];
  2094. }
  2095. json_success('获取成功', $list);
  2096. }
  2097. private function getRecSignature( $url ){
  2098. header('Access-Control-Allow-Origin: *');
  2099. $url = urldecode($url);
  2100. $accessToken = $this->getWeixinAccessToken();
  2101. if (!$accessToken) {
  2102. return [
  2103. 'c' => 99,
  2104. 'm' => '获取微信accesstoken失败'
  2105. ];
  2106. }
  2107. $apiTiket = $this->getJsapiTikcet($accessToken);
  2108. if(is_array($apiTiket)){
  2109. json_fail($apiTiket['errcode'].':'.$apiTiket['errmsg']);
  2110. return [
  2111. 'c' => $apiTiket['errcode'],
  2112. 'm' => $apiTiket['errmsg']
  2113. ];
  2114. }
  2115. $noncestr = substr(md5(time()), 0, 16);
  2116. $timestamp = time();
  2117. //jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value
  2118. $str = 'jsapi_ticket='.$apiTiket.'&noncestr='.$noncestr.'&timestamp='.$timestamp.'&url='.$url;
  2119. $signature = sha1($str);
  2120. return [
  2121. 'c' => 0,
  2122. 'm' => '',
  2123. 'v' => [
  2124. 'appid' => C('WECHAT_APPID'),
  2125. 'timestamp' => $timestamp,
  2126. 'noncestr' => $noncestr,
  2127. 'signature' => $signature,
  2128. ]
  2129. ];
  2130. }
  2131. public function addEditFence( ){
  2132. // 获取登录用户信息
  2133. $userinfo = $this->getYysLoginUserinfo();
  2134. $id = I('get.id');
  2135. $data = json_decode( file_get_contents("php://input") ,true) ?: [];
  2136. // 围栏类型
  2137. $fenceTypeArr = [
  2138. 'inout' => 0, // 机构安全围栏
  2139. 'person_inout' => 1, // 个人安全围栏
  2140. 'sos' => 2, // SOS围栏
  2141. ];
  2142. if ($data['name']) {
  2143. $data['name'] = trim($data['name']);
  2144. }
  2145. if ($data['fence_info']) {
  2146. // 坐标转换:GCJ-02 -> BD-09
  2147. $convPoint = (new \Jms\Algo\Geometry())->convertGcj02ToBd09($data['fence_info']['center']['lat'], $data['fence_info']['center']['lng']);
  2148. $data['fence_info']['center']['lat'] = $convPoint['lat'];
  2149. $data['fence_info']['center']['lng'] = $convPoint['lng'];
  2150. $data['fence_info'] = json_encode($data['fence_info']);
  2151. }
  2152. if ($data['in_fence_time_area'] && is_array($data['in_fence_time_area'])) {
  2153. $data['in_fence_time_area'] = json_encode($data['in_fence_time_area']);
  2154. }
  2155. if ($data['out_fence_time_area'] && is_array($data['out_fence_time_area'])) {
  2156. $data['out_fence_time_area'] = json_encode($data['out_fence_time_area']);
  2157. }
  2158. if ($data['push_users'] && is_array($data['push_users'])) {
  2159. foreach($data['push_users'] as &$v){
  2160. $v = intval($v);
  2161. }
  2162. $data['push_users'] = json_encode($data['push_users']);
  2163. }
  2164. // 新增
  2165. if (!$id) {
  2166. if($data['name'] === ''){
  2167. json_fail('围栏名称不能为空');
  2168. }
  2169. if(!$data['fence_info']){
  2170. json_fail('未获取到围栏信息');
  2171. }
  2172. if (!isset($fenceTypeArr[$data['fence_type']])) {
  2173. json_fail('未知的围栏类型');
  2174. }
  2175. $data['fence_shape'] = $data['fence_shape'] ?: 'circle';
  2176. $data['fence_type'] = $fenceTypeArr[$data['fence_type']];
  2177. $data['creator_id'] = $userinfo['id'];
  2178. $data['departments'] = $userinfo['department_id'];
  2179. $data['created_at'] = time();
  2180. $result = M('fences')->createAdd($data);
  2181. if (!$result) {
  2182. json_fail('添加失败');
  2183. }
  2184. json_success('添加成功', $result);
  2185. }
  2186. // 修改
  2187. // 获取权限范围内的用户id
  2188. $creatorIds = $this->getRightCreatorIds($userinfo);
  2189. $info = M('fences')->where(['id'=>$id])->find();
  2190. if (empty($info)) {
  2191. json_fail('获取围栏信息失败');
  2192. }
  2193. if (!in_array($info['creator_id'], $creatorIds)) {
  2194. //json_fail('无修改权限');
  2195. }
  2196. unset($data['fence_type']);
  2197. $cond = ['id'=>$id];
  2198. $result = M('fences')->createSave($cond, $data);
  2199. if(!$result){
  2200. json_fail('保存失败');
  2201. }
  2202. json_success('保存成功', $id);
  2203. }
  2204. public function deleteYysFences( ){
  2205. // 获取登录用户信息
  2206. $userinfo = $this->getYysLoginUserinfo();
  2207. // 获取权限范围内的用户id
  2208. $creator_ids = $this->getRightCreatorIds($userinfo);
  2209. if ($creator_ids === false) {
  2210. json_fail('获取失败');
  2211. }
  2212. $id = I('get.id');
  2213. if (!$id) {
  2214. json_fail('参数不合法');
  2215. }
  2216. $fence_info = M('fences')->where(['id'=>$id])->find();
  2217. if (!$fence_info) {
  2218. json_fail('围栏不存在');
  2219. }
  2220. if ($creator_ids !== true && !in_array($fence_info['creator_id'], $creator_ids)) {
  2221. json_fail('无权限删除该围栏');
  2222. }
  2223. $res = M('fences')->where(['id'=>$id])->delete();
  2224. if (!$res) {
  2225. json_fail('删除失败');
  2226. }
  2227. json_success('删除成功');
  2228. }
  2229. public function getFenceInfo( ){
  2230. // 获取登录用户信息
  2231. $userinfo = $this->getYysLoginUserinfo();
  2232. $id = I('get.id');
  2233. if (!$id) {
  2234. json_fail('缺少参数');
  2235. }
  2236. $info = M('fences')->where(['id'=>$id])->find();
  2237. if(!$info){
  2238. json_fail('获取失败');
  2239. }
  2240. // GCJ-02 -> BD-09
  2241. $info['fence_info'] = json_decode($info['fence_info'], true) ?: [];
  2242. $convPoint = (new \Jms\Algo\Geometry())->convertBd09ToGcj02($info['fence_info']['center']['lat'], $info['fence_info']['center']['lng']);
  2243. $info['fence_info']['center']['lat'] = $convPoint['lat'];
  2244. $info['fence_info']['center']['lng'] = $convPoint['lng'];
  2245. $info['in_fence_time_area'] = json_decode($info['in_fence_time_area'], true) ?: [];
  2246. $info['out_fence_time_area'] = json_decode($info['out_fence_time_area'], true) ?: [];
  2247. $info['push_users'] = json_decode($info['push_users'], true) ?: [];
  2248. json_success('获取成功', $info);
  2249. }
  2250. public function getFenceAlarmIntervals( ){
  2251. header('Access-Control-Allow-Origin: *');
  2252. $userid = I('get.userid');
  2253. $openid = I('get.openid');
  2254. if(!$userid || $userid == 'undefined' || $userid == 'null'){
  2255. json_fail('未获取到用户标识,请重新登陆');
  2256. }
  2257. //检测登录状态
  2258. $res = $this->checkLoginState($openid, $userid);
  2259. if(!$res['status']){
  2260. json_fail($res['message']);
  2261. }
  2262. try {
  2263. $typeid = M('sys_dict_type')->where(['code'=>'FenceSentInterval'])->getField('id');
  2264. $list = M('sys_dict_data')->field('value as text,code as value')->where(['type_id'=>$typeid])->select() ? : [];
  2265. } catch (\Exception $e) {
  2266. json_fail($e->getMessage());
  2267. }
  2268. json_success('获取成功', $list);
  2269. }
  2270. public function getRightUsers( ){
  2271. // 获取登录用户信息
  2272. $userinfo = $this->getYysLoginUserinfo();
  2273. // 获取权限范围内的用户id
  2274. $creator_ids = $this->getRightCreatorIds($userinfo);
  2275. if ($creator_ids === false) {
  2276. json_fail('获取失败');
  2277. }
  2278. $cond = [
  2279. 'username' => ['NOT IN', 'admin,manage']
  2280. ];
  2281. if (is_array($creator_ids)) {
  2282. $cond['id'] = ['IN', $creator_ids];
  2283. }
  2284. if ($creator_ids === true) {
  2285. $where = ['identify' => ['IN', 'personal,group_badge_user,group_card_user']];
  2286. $devide_user_ids = M('roles')->where($where)->getField('id', true);
  2287. $device_ids = join(',', $devide_user_ids);
  2288. $list = M('users')->alias('u')->field('u.id,u.realname,u.phone')
  2289. ->where($cond)
  2290. ->distinct(true)
  2291. ->join("INNER JOIN user_has_roles r ON u.id=r.uid AND r.role_id NOT IN ({$device_ids})")
  2292. ->select() ?:[];
  2293. } else {
  2294. $list = M('users')->field('id,realname,phone')->distinct(true)->where($cond)->select();
  2295. }
  2296. json_success('获取成功', $list);
  2297. }
  2298. public function getUserAlarmRecords( ){
  2299. header('Access-Control-Allow-Origin: *');
  2300. $post_data = json_decode(file_get_contents('php://input'), true);
  2301. $openid = $post_data['openid'];
  2302. $userid = $post_data['userid'];
  2303. //检测登录状态
  2304. $res = $this->checkLoginState($openid,$userid);
  2305. if(!$res['status']){
  2306. json_fail($res['message']);
  2307. }
  2308. $limit = isset($post_data['limit']) ? $post_data['limit'] : 10;
  2309. $page = isset($post_data['page']) ? $post_data['page'] : 1;
  2310. // 告警记录条件
  2311. $where = ['user_id' => $userid];
  2312. $device_numbers = M('devices')->where($where)->getField('imei', true);
  2313. if (empty($device_numbers)) {
  2314. json_fail('暂无设备,请先绑定设备');
  2315. }
  2316. // 初始化条件
  2317. $cond = [
  2318. 'device_number' => ['IN', $device_numbers],
  2319. ];
  2320. $reason = I('get.reason');
  2321. $state = I('get.state');
  2322. $result = I('get.result');
  2323. if ($reason) {
  2324. if ($reason == 'fence') {
  2325. $cond['alarm_reason'] = ['IN', ['fence_in', 'fence_out']];
  2326. } else {
  2327. $cond['alarm_reason'] = $reason;
  2328. }
  2329. } else {
  2330. // 默认只显示 SOS
  2331. $cond['alarm_reason'] = 'press';
  2332. }
  2333. if ($state) {
  2334. $cond['state'] = $state;
  2335. }
  2336. if ($result !== '' && is_numeric($result)) {
  2337. $cond['result'] = $result;
  2338. }
  2339. // 查出总数量
  2340. $list = [];
  2341. $total = M('alarm_records')->where($cond)->count();
  2342. if ($total) {
  2343. if ($state == 'start' || $state == 'end') {
  2344. $order = "{$state}_time desc";
  2345. } else {
  2346. $order = 'id desc';
  2347. }
  2348. $fields = 'id,device_number,alarm_reason,handler_id,start_time,end_time,state,comment,result';
  2349. $list = M('alarm_records')->field($fields)->where($cond)->limit($limit)->page($page)->order($order)->select() ?: [];
  2350. if (!empty($list)) {
  2351. // alarm_reason,handler_id,result
  2352. // 获取告警类型
  2353. $typeid = M('sys_dict_type')->where(['code' => 'AlarmType'])->getField('id');
  2354. $reason_arr = M('sys_dict_data')->where(['type_id' => $typeid])->getField('code, value');
  2355. // 处理结果
  2356. $result_arr = [
  2357. 0 => '待处理',
  2358. 1 => '已处理',
  2359. 2 => '误报',
  2360. ];
  2361. // 中文转换
  2362. foreach ($list as &$alarm) {
  2363. $alarm['start_time'] = $alarm['start_time'] ? date('Y-m-d H:i:s', $alarm['start_time']) : '';
  2364. $alarm['end_time'] = $alarm['end_time'] ? date('Y-m-d H:i:s', $alarm['end_time']) : '';
  2365. if (is_array($reason_arr)) {
  2366. $alarm['alarm_reason'] = $reason_arr[$alarm['alarm_reason']];
  2367. }
  2368. if (is_numeric($alarm['result'])) {
  2369. $alarm['result'] = $result_arr[$alarm['result']];
  2370. }
  2371. }
  2372. }
  2373. }
  2374. // 返回
  2375. $data = [
  2376. 'total' => $total,
  2377. 'limit' => $limit,
  2378. 'page' => $page,
  2379. 'list' => $list,
  2380. ];
  2381. json_success('获取成功', $data);
  2382. }
  2383. public function getUserAlarmDetail( ){
  2384. header('Access-Control-Allow-Origin: *');
  2385. $openid = I('get.openid');
  2386. $userid = I('get.userid');
  2387. if(!$userid || $userid == 'undefined' || $userid == 'null'){
  2388. json_fail('获取不到你的用户标识,请重新登陆');
  2389. }
  2390. //检测登录状态
  2391. $res = $this->checkLoginState($openid,$userid);
  2392. if(!$res['status']){
  2393. json_fail($res['message']);
  2394. }
  2395. $alarm_id = I('get.id');
  2396. if (!$alarm_id) {
  2397. json_fail('获取告警信息失败1');
  2398. }
  2399. // 查出告警数据
  2400. $where = ['id' => $alarm_id];
  2401. $alarm_info = M('alarm_records')->where($where)->find();
  2402. if (empty($alarm_info)) {
  2403. json_fail('获取告警信息失败2');
  2404. }
  2405. $report_id = I('get.rid');
  2406. if (!$report_id) {
  2407. json_fail('获取告警信息失败3');
  2408. }
  2409. $where = ['id' => $report_id];
  2410. $alarm_report = M('alarm_report')->where($where)->find();
  2411. if (empty($alarm_report)) {
  2412. json_fail('获取告警信息失败4');
  2413. }
  2414. $alarm_info['address']=$alarm_report['address'];
  2415. // 查出设备信息
  2416. $where = ['imei' => $alarm_info['device_number']];
  2417. $device_info = M('devices')->where($where)->find();
  2418. if (empty($alarm_info)) {
  2419. json_fail('获取告警设备信息失败');
  2420. }
  2421. if ($device_info['online_time'] > $device_info['wifi_online_time']) {
  2422. $device_info['last_online_time'] = date('Y-m-d H:i:s', $device_info['online_time']);
  2423. $device_info['last_location'] = $device_info['longitude'] .','. $device_info['latitude'];
  2424. $res = bmap_geocoding($device_info['latitude'], $device_info['longitude']);
  2425. if($res['success']){
  2426. $device_info['address'] = $res['address'];
  2427. }else{
  2428. $device_info['address']='';
  2429. }
  2430. } elseif ($device_info['online_time'] < $device_info['wifi_online_time']) {
  2431. $device_info['last_online_time'] = date('Y-m-d H:i:s', $device_info['wifi_online_time']);
  2432. $device_info['last_location'] = $device_info['wifi_longitude'] .','. $device_info['wifi_latitude'];
  2433. } else {
  2434. $device_info['last_online_time'] = '0000-00-00 00:00:00';
  2435. $device_info['last_location'] = '';
  2436. $device_info['address']='';
  2437. }
  2438. // 查出设备用户
  2439. if ($device_info['badge_user_id']) {
  2440. $where = ['id' => $device_info['badge_user_id']];
  2441. $user_info = M('badgeuser')->where($where)->find() ?: [];
  2442. } else {
  2443. $where = ['id' => $device_info['user_id']];
  2444. $user_info = M('users')->where($where)->find() ?: [];
  2445. }
  2446. //if (empty($user_info)) {
  2447. //json_fail('获取告警用户信息失败');
  2448. //}
  2449. // 获取紧急联系人
  2450. $where = ['device_id' => $device_info['id']];
  2451. $urgent_list = M('kq_urgent')->where($where)->select() ? : [];
  2452. if (!empty($urgent_list)) {
  2453. $type_id = M('sys_dict_type')->where(['code' => 'Relationships'])->getField('id');
  2454. $ships = M('sys_dict_data')->where(['type_id' => $type_id])->getField('code,value');
  2455. foreach ($urgent_list as $key => &$urgent) {
  2456. $urgent['relationship_text'] = $ships[$urgent['relationship']];
  2457. }
  2458. }
  2459. // 部门名称
  2460. $alarm_info['department_name'] = M('departments')->where(['id' => $user_info['department_id']])->getField('department_name');
  2461. $alarm_info['user_info'] = $user_info;
  2462. $alarm_info['urgent_list'] = $urgent_list;
  2463. $alarm_info['device_info'] = $device_info;
  2464. $alarm_info['device_info']['department_name'] = $alarm_info['department_name'];
  2465. json_success('获取成功', $alarm_info);
  2466. }
  2467. public function setFenceAlarmInterval( ){
  2468. //user_has_students
  2469. header('Access-Control-Allow-Origin: *');
  2470. $fenceId = I('get.fenceId');
  2471. $interval = intval(I('get.interval') );
  2472. if(!$fenceId){
  2473. json_fail('获取不到围栏标识,请刷新下');
  2474. }
  2475. if(!$interval){
  2476. json_fail('获取不到时间间隔,请重设重试');
  2477. }
  2478. if($interval < 1 || $interval > 720){
  2479. json_fail('推送间隔目前只支持720分钟以内');
  2480. }
  2481. $saveData = [
  2482. 'sent_interval' => $interval
  2483. ];
  2484. $saveData['sent_interval'] = $interval * 60;
  2485. $res = M('fences')->where(['id' => $fenceId])->save($saveData);
  2486. if($res === false){
  2487. json_fail('修改推送间隔失败');
  2488. }
  2489. json_success('修改推送间隔成功');
  2490. }
  2491. public function resetPwd( ){
  2492. header('Access-Control-Allow-Origin: *');
  2493. // 通过手机号和短信验证码注册
  2494. $data = json_decode( file_get_contents("php://input") ,true);
  2495. // 用户类型:个人(personal)、团体(group)
  2496. $userType = $data['userType'];
  2497. // 设备类型:卡牌(card)、徽章(badge)
  2498. $deviceType = $data['deviceType'];
  2499. // 团体卡牌用户(group_card_user) 不可注册
  2500. // 个人用户(personal),团体徽章用户(group_badge_user) 可注册
  2501. if ($userType == 'personal') { // 个人用户
  2502. $identify = 'personal';
  2503. } elseif ($userType == 'group' && $deviceType == 'badge') { // 团体徽章用户
  2504. $identify = 'group_badge_user';
  2505. } elseif ($userType == 'group' && $deviceType == 'card') { // 团体卡牌用户
  2506. $identify = 'group_card_user';
  2507. } else {
  2508. json_fail('未知用户类型');
  2509. }
  2510. if(!$data['phone']){
  2511. json_fail('手机号码不能为空');
  2512. }
  2513. if(!$data['smsCode']){
  2514. json_fail('短信验证码不能为空');
  2515. }
  2516. if(! $data['password']){
  2517. json_fail('密码不能为空');
  2518. }
  2519. if(! $data['confirmPassword']){
  2520. json_fail('确认密码不能为空');
  2521. }
  2522. if ($data['password'] != $data['confirmPassword']) {
  2523. json_fail('两次密码不一致');
  2524. }
  2525. // 获取角色id
  2526. $roleId = M('roles')->where(['identify' => $identify])->getField('id');
  2527. if (!$roleId) {
  2528. json_fail('未知角色类型');
  2529. }
  2530. // 判断角色、号码是否已注册
  2531. $userinfo = M('users')->alias('a')->field('a.id')->where(['username'=>$data['phone']])->join("INNER JOIN user_has_roles b ON a.id = b.uid AND b.role_id = {$roleId}")->find();
  2532. if (empty($userinfo)) {
  2533. json_fail('该号码未注册');
  2534. }
  2535. // 验证码有效性
  2536. $res = $this->isValidSmsCode($data['phone'], $data['smsCode']);
  2537. if (!$res['success']) {
  2538. json_fail($res['message']);
  2539. }
  2540. // 重置密码
  2541. $savePwd = password_hash($data['password'], PASSWORD_DEFAULT);
  2542. $cond = ['id' => $userinfo['id']];
  2543. $res = M('users')->where($cond)->setField('password', $savePwd);
  2544. if($res === false){
  2545. json_fail('重置失败');
  2546. }
  2547. json_success('重置成功');
  2548. }
  2549. public function checkSingleLogin( ){
  2550. header('Access-Control-Allow-Origin: *');
  2551. $userid = I('get.userid');
  2552. $openid = I('get.openid');
  2553. $where = [
  2554. 'id' => $userid,
  2555. 'wx_open_id'=> $openid
  2556. ];
  2557. $flag = M('users')->where($where)->find();
  2558. if($flag){
  2559. json_success('goon');
  2560. }
  2561. json_fail('relogin');
  2562. }
  2563. private function getMaxDbm( $avFile, $start ){
  2564. /*
  2565. $string = file_get_contents($avFile);
  2566. $bytes = array();
  2567. for($i = 0; $i < strlen($string); $i++){
  2568. $bytes[] = ord($string[$i]);
  2569. }
  2570. $counter = strlen($string);
  2571. */
  2572. $counter = 4;
  2573. $bytes = [1,2,3,4];
  2574. $absolute = 0;
  2575. $maximum = 0;
  2576. for ($i = $start; $i < $counter; $i++) {
  2577. // $absolute = abs(getShort(new byte[] {vector[i], vector[i + 1]}, 0));
  2578. $absolute = abs( $this->bytesToShort([$bytes[$i], $bytes[$i+1]], 0) ) ;
  2579. if ($absolute > $maximum) {
  2580. $maximum = $absolute;
  2581. }
  2582. $i++;
  2583. }
  2584. if ($maximum > 32767) {
  2585. $maximum = 32767;
  2586. }
  2587. return (int)$maximum;
  2588. }
  2589. public function test_cus_function( ){
  2590. phpinfo();exit;
  2591. $accessKeyId='LTAIOSQ4y09Jxbf3';
  2592. $accessKeySecret='LQm05sOLBss87lFG6jx9iq4lzKCAqA';
  2593. $config = new \Darabonba\OpenApi\Models\Config([
  2594. "accessKeyId" => $accessKeyId,
  2595. "accessKeySecret" => $accessKeySecret
  2596. ]);
  2597. // 访问的域名
  2598. $config->endpoint = "dysmsapi.aliyuncs.com";
  2599. $client= new \AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi($config);
  2600. $params = [
  2601. "signName" => "小友回收",
  2602. "templateCode" => "SMS_245515027",
  2603. "phoneNumbers" => 15706857065,
  2604. "templateParam" => json_encode(['code' => '1234'])
  2605. ];
  2606. // $client = self::createClient( $accessKeyId, $accessKeySecret);
  2607. $sendSmsRequest = new \AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendSmsRequest($params);
  2608. $runtime = new \AlibabaCloud\Tea\Utils\Utils\RuntimeOptions([]);
  2609. $res=$client->sendSmsWithOptions($sendSmsRequest, $runtime);
  2610. var_dump($res);
  2611. }
  2612. private function bytesToShort( $bytes, $position ){
  2613. $val = 0;
  2614. $val = $bytes[$position + 1] & 0xFF;
  2615. $val = $val << 8;
  2616. $val |= $bytes[$position] & 0xFF;
  2617. return $val;
  2618. }
  2619. public function getDeviceAvatar( ){
  2620. header('Access-Control-Allow-Origin: *');
  2621. $imei = I('get.imei');
  2622. if(!$imei){
  2623. json_fail('获取不到设备标识');
  2624. }
  2625. $avatar = M('devices')->where(['imei' => $imei])->getField('avatar');
  2626. if(!$avatar){
  2627. json_fail('获取头像失败');
  2628. }
  2629. json_success('获取头像成功',$avatar);
  2630. }
  2631. public function getUserAvatar( ){
  2632. header('Access-Control-Allow-Origin: *');
  2633. $uid = I('get.uid');
  2634. if(!$uid){
  2635. json_fail('获取不到用户标识');
  2636. }
  2637. $avatar = M('users')->where(['id' => $uid])->getField('avatar');
  2638. if(!$avatar){
  2639. json_fail('获取头像失败');
  2640. }
  2641. json_success('获取头像成功',$avatar);
  2642. }
  2643. public function saveDeviceAvatar( ){
  2644. header('Access-Control-Allow-Origin: *');
  2645. $postData = json_decode( file_get_contents('php://input'), true);
  2646. if(!$postData['imei']){
  2647. json_fail('获取不到设备标识');
  2648. }
  2649. if(!$postData['avatar64content']){
  2650. json_fail('获取不到头像信息');
  2651. }
  2652. $folder = realpath(__ROOT__).'/static/assets/avatar/'.date('Ymd').'/';
  2653. if (!is_dir($folder)){
  2654. $mres= mkdir($folder,0777,true);
  2655. if($mres === false){
  2656. json_fail('服务端创建目录权限不足');
  2657. }
  2658. }
  2659. $fileName = 'avatar-device-imei'.$postData['imei'] .'-'. time();
  2660. $saveFile = $this->base64_image_content($postData['avatar64content'], $folder, $fileName);
  2661. if(!$saveFile){
  2662. json_fail('服务端保存头像失败');
  2663. }
  2664. $res = M('devices')->where(['imei' => $postData['imei']])->save(['avatar' => $saveFile]);
  2665. if($res === false){
  2666. json_fail('保存头像地址失败');
  2667. }
  2668. json_success('保存成功');
  2669. }
  2670. public function saveUserAvatar( ){
  2671. header('Access-Control-Allow-Origin: *');
  2672. $postData = json_decode( file_get_contents('php://input'), true);
  2673. if(!$postData['uid']){
  2674. json_fail('获取不到用户标识');
  2675. }
  2676. if(!$postData['avatar64content']){
  2677. json_fail('获取不到头像信息');
  2678. }
  2679. $folder = realpath(__ROOT__).'/static/assets/avatar/'.date('Ymd').'/';
  2680. if (!is_dir($folder)){
  2681. $mres= mkdir($folder,0777,true);
  2682. if($mres === false){
  2683. json_fail('服务端创建目录权限不足');
  2684. }
  2685. }
  2686. $fileName = 'avatar-user-uid'.$postData['uid'] .'-'. time();
  2687. $saveFile = $this->base64_image_content($postData['avatar64content'], $folder, $fileName);
  2688. if(!$saveFile){
  2689. json_fail('服务端保存头像失败');
  2690. }
  2691. $res = M('users')->where(['id' => $postData['uid']])->save(['avatar' => $saveFile]);
  2692. if($res === false){
  2693. json_fail('保存头像地址失败');
  2694. }
  2695. json_success('保存成功');
  2696. }
  2697. private function base64_image_content( $base64_image_content, $path, $name ){
  2698. //匹配出图片的格式
  2699. if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)){
  2700. $type = $result[2];
  2701. $new_file = $path.$name.".{$type}";
  2702. $file = 'http://'.$_SERVER['HTTP_HOST'].'/static/assets/avatar/'.date('Ymd').'/'.$name.".{$type}";
  2703. if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_image_content)))){
  2704. return $file;
  2705. }else{
  2706. return false;
  2707. }
  2708. }else{
  2709. return false;
  2710. }
  2711. }
  2712. public function setLocModel( ){
  2713. /*
  2714. 请求url上带上 openid userid
  2715. post请求 参数: imei id(设备id) post_mode 定位模式 0-常规模式 1-追踪模式 2-定时模式
  2716. 定时模式:需要设置 定位采样间隔(stopped_rtc_invl) 定位上报间隔(stopped_rpt_invl)
  2717. */
  2718. header('Access-Control-Allow-Origin: *');
  2719. $openid = I('get.openid');
  2720. $userid = I('get.userid');
  2721. //检测登录状态
  2722. $res=$this->checkLoginState($openid,$userid);
  2723. if(!$res['status']){
  2724. json_fail($res['message']);
  2725. }
  2726. $data = json_decode( file_get_contents("php://input") ,true);
  2727. $imei=$data['imei'];
  2728. if(!$imei){
  2729. json_fail('缺少设备imei号');
  2730. }
  2731. $config['pos_mode']=$data['pos_mode'];
  2732. if(!isset($config['pos_mode']) || $config['pos_mode'] === ''){
  2733. json_fail('缺少定位模式');
  2734. }
  2735. $dev_id=$data['id'];
  2736. if(!$dev_id){
  2737. json_fail('缺少设备id');
  2738. }
  2739. $redis = Redis('c61_gps_device_configs_'.$imei,"queue");
  2740. //开启事务
  2741. M()->startTrans();
  2742. $config['msg_id'] = 0xAAAA0010;
  2743. //判断是不是定时模式
  2744. if ($config['pos_mode'] == 2) {
  2745. if(!$data['stopped_rtc_invl']){
  2746. json_fail('请设置定位采样间隔');
  2747. }
  2748. if(!$data['stopped_rpt_invl']){
  2749. json_fail('请设置定位上报间隔');
  2750. }
  2751. $config_arr = array(
  2752. 'stopped_rtc_invl' => intval($data['stopped_rtc_invl']),
  2753. 'stopped_rpt_invl' => intval($data['stopped_rpt_invl']),
  2754. 'msg_id' => 0xAAAA0007
  2755. );
  2756. //下发日志
  2757. $log_data = array(
  2758. 'send_contents' => json_encode($config_arr),
  2759. 'type'=>'sensor',
  2760. 'imei'=>$imei,
  2761. 'created_at' => time(),
  2762. 'creator_id' => $userid,
  2763. 'device_id' => $dev_id
  2764. );
  2765. $lg_id = M('send_config_log')->createAdd($log_data);
  2766. if (!$lg_id) {
  2767. json_fail('下发日志添加失败');
  2768. M()->rollback();
  2769. }
  2770. $config_arr['id'] = $lg_id;
  2771. $redis->push(json_encode($config_arr));
  2772. }else{//非定时模式 采样时间设为3000 上报间隔3600
  2773. $config_arr = array(
  2774. 'stopped_rtc_invl' => 3000,
  2775. 'stopped_rpt_invl' => 3600,
  2776. 'msg_id' => 0xAAAA0007
  2777. );
  2778. //下发日志
  2779. $log_data = array(
  2780. 'send_contents' => json_encode($config_arr),
  2781. 'type'=>'sensor',
  2782. 'imei'=>$imei,
  2783. 'created_at' => time(),
  2784. 'creator_id' => $userid,
  2785. 'device_id' => $dev_id
  2786. );
  2787. $lg_id = M('send_config_log')->createAdd($log_data);
  2788. if (!$lg_id) {
  2789. json_fail('下发日志添加失败');
  2790. M()->rollback();
  2791. }
  2792. $config_arr['id'] = $lg_id;
  2793. $redis->push(json_encode($config_arr));
  2794. }
  2795. //下发日志
  2796. $log_data = array(
  2797. 'send_contents' => json_encode($config),
  2798. 'type'=>'pos_mode',
  2799. 'imei'=>$imei,
  2800. 'created_at' => time(),
  2801. 'creator_id' => $userid,
  2802. 'device_id' => $dev_id
  2803. );
  2804. $config['id'] = M('send_config_log')->createAdd($log_data);
  2805. if (!$config['id']) {
  2806. json_fail('下发日志添加失败');
  2807. M()->rollback();
  2808. }
  2809. $redis->push(json_encode($config));
  2810. M()->commit();
  2811. json_success('设置成功');
  2812. }
  2813. public function delUserFence( ){
  2814. header('Access-Control-Allow-Origin: *');
  2815. $userid = I('get.userid');
  2816. if(!$userid){
  2817. json_fail('获取不到用户标识,尝试重登');
  2818. }
  2819. $fenceId =I('get.fenceId');
  2820. if(!$fenceId){
  2821. json_fail('获取不到围栏标识,尝试刷新');
  2822. }
  2823. $res = M('fences')->where(['id' => $fenceId, 'creator_id' => $userid, 'fence_type' => 1] )->delete();
  2824. if(!$res){
  2825. json_fail('删除失败');
  2826. }
  2827. json_success('删除成功');
  2828. }
  2829. public function sendReverveNotice( ){
  2830. header('Access-Control-Allow-Origin: *');
  2831. $voice_template_id=C('WX_VOICE_TEMPLATE_ID');
  2832. if(!$voice_template_id){
  2833. debug_log('voice_notice','WX_VOICE_TEMPLATE_ID not exist');
  2834. return false;
  2835. }
  2836. $data=$_POST;
  2837. $this->wxMsg = new \Jiaruan\WxTmp();
  2838. $access_token =$this->wxMsg->getAccessToken();
  2839. $msgArray= array(
  2840. "touser"=>$data['openid'],
  2841. "msgtype"=>"text",
  2842. "text"=>array(
  2843. "content"=>urlencode("测试啥是")
  2844. )
  2845. );
  2846. $json=urldecode(json_encode($msgArray));
  2847. //var_dump($json);exit;
  2848. #群发 文本消息
  2849. $ch = curl_init();
  2850. curl_setopt($ch, CURLOPT_URL, "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=".$access_token);
  2851. curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
  2852. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  2853. $res = json_decode(curl_exec($ch),true);
  2854. curl_close($ch);
  2855. json_success($res);
  2856. }
  2857. public function getMyInsureList( ){
  2858. header('Access-Control-Allow-Origin: *');
  2859. $openid = I('get.openid');
  2860. $userid = I('get.userid');
  2861. //检测登录状态
  2862. $res=$this->checkLoginState($openid,$userid);
  2863. if(!$res['status']){
  2864. json_fail($res['message']);
  2865. }
  2866. $vehiclesIds = M('vehicles')->where(['user_id' => $userid ])->getField('id',true);
  2867. $list=M('insure_records')->where(['vehicle_id' =>array('in',$vehiclesIds) ])->select();
  2868. foreach($list as &$val){
  2869. $start_at=strtotime(date('Y-m-d 00:00:00',$val['start_at']));
  2870. $end_at=strtotime(date('Y-m-d 23:59:59',$val['end_at']));
  2871. if(time()<$start_at){
  2872. $val['insure_state']=0;
  2873. $val['insure_state_text']='待生效';
  2874. }elseif(time()<=$end_at){
  2875. $val['insure_state']=1;
  2876. $val['insure_state_text']='生效中';
  2877. }else{
  2878. $val['insure_state']=2;
  2879. $val['insure_state_text']='已失效';
  2880. }
  2881. $val['vehicle_info']=M('vehicles')->where(['id' =>$val['vehicle_id']])->find();
  2882. $val['insure_info']=M('insurance')->where(['id' =>$val['insurance_id']])->find();
  2883. $val['start_at']=date('Y-m-d 00:00:00',$val['start_at']);
  2884. $val['end_at']=date('Y-m-d 23:59:59',$val['end_at']);
  2885. }
  2886. if(!$list){
  2887. json_fail('暂无保险');
  2888. }
  2889. json_success('查询成功',$list);
  2890. }
  2891. public function getInsureOptions( ){
  2892. header('Access-Control-Allow-Origin: *');
  2893. $list=M('insurance')->where(['enable' =>1])->field('*,name as text,id as value')->select();
  2894. foreach($list as &$val){
  2895. $val['price']=$val['price']*100;
  2896. }
  2897. json_success('查询成功',$list);
  2898. }
  2899. public function userByInsure( ){
  2900. header('Access-Control-Allow-Origin: *');
  2901. $openid = I('get.openid');
  2902. $userid = I('get.userid');
  2903. //检测登录状态
  2904. $res=$this->checkLoginState($openid,$userid);
  2905. if(!$res['status']){
  2906. json_fail($res['message']);
  2907. }
  2908. $data = json_decode( file_get_contents("php://input") ,true);
  2909. $insurance_data=M('insurance')->where(['id'=>$data['insure_id']])->find();
  2910. //添加保险记录信息
  2911. $insurance = array(
  2912. 'vehicle_id'=>$data['vehicle_id'],
  2913. 'insurance_id'=>$data['insure_id'],
  2914. 'start_at'=>strtotime(date('Y-m-d',strtotime('+1 day'))),
  2915. 'end_at'=>strtotime(date('Y-m-d',strtotime('+'.$insurance_data['years'].' year')))+24*3600-1,
  2916. 'creator_id'=>$userid,
  2917. 'created_at'=>time(),
  2918. 'updated_at'=>time()
  2919. );
  2920. if(!M('insure_records')->createAdd($insurance)){
  2921. json_fail('添加保险失败');
  2922. }
  2923. json_success('购买成功',$userid);
  2924. }
  2925. }