ThirdConsultFacadeRepository.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. <?php
  2. namespace App\Repositories\Eloquent;
  3. use App\Repositories\Contracts\ThirdConsultInterface;
  4. use GuzzleHttp\Client as httpClient;
  5. use App\Models\Doctor;
  6. use App\Facades\HisApiFacade;
  7. use App\Models\DoctorVisity;
  8. use App\Models\DoctorVisityExtend;
  9. use Carbon\Carbon;
  10. /**
  11. * ThirdConsult
  12. *
  13. */
  14. class ThirdConsultFacadeRepository extends BaseRepository implements ThirdConsultInterface
  15. {
  16. /**
  17. * 诊间状态 1正常
  18. * @var integer
  19. */
  20. const STATUS_1 = 1;
  21. /**
  22. * 诊间状态 2停诊
  23. * @var integer
  24. */
  25. const STATUS_2 = 2;
  26. /**
  27. * 时间划分 1上午
  28. * @var integer
  29. */
  30. const DAY_TYPE_1 = 1;
  31. /**
  32. * 时间划分 2下午
  33. * @var integer
  34. */
  35. const DAY_TYPE_2 = 2;
  36. public function appLogin(string $open_id, string $order_id)
  37. {
  38. $ap = 'mobile';
  39. $op = 'core';
  40. $task = 'appLogin';
  41. $postArr = [
  42. 'open_id' => $open_id,
  43. 'order_id' => $order_id,
  44. 's_timestamp' => time(),
  45. 'call_back' => 'stjsby'
  46. ];
  47. $this->setLog(self::TYPENAME.'量表测评地址 进入', $this->startTime, $postArr, 'debug');
  48. $url = $this->_makeUrl($op, $task, $postArr, $ap, '1.1.0');
  49. return $url;
  50. }
  51. public function jssdkGetMedia(string $media_id)
  52. {
  53. $this->setLog(self::TYPENAME.'获取微信语音文件 进入', $this->startTime(), ['media_id'=>$media_id], 'debug');
  54. $op = 'core';
  55. $task = 'jssdkGetMedia';
  56. $url = 'http://wechat.qingerai.com/index.php';
  57. $secret = 'a1f073170fa3e945365ba15746861e141';
  58. $weid = '36';
  59. $token = md5(md5($secret . $weid . $media_id));
  60. $getArr = [
  61. 'ap' => 'api',
  62. 'op' => $op,
  63. 'task' => $task,
  64. 'weid' => $weid,
  65. 'media_id' => $media_id,
  66. 'token' => $token
  67. ];
  68. try {
  69. $client = new httpClient();
  70. $res = $client->request('get', $url, ['query'=>$getArr]);
  71. $body = $res->getBody();
  72. $data = (object)json_decode($body);
  73. $this->setLog(self::TYPENAME.'_curl 远程请求到的数据', $this->startTime, [$data]);
  74. if ($data->status === TRUE) {
  75. //获取到的微信语音地址
  76. $wxMediaUrl = $data->datas->url;
  77. $this->setLog(self::TYPENAME.'_curl 微信语音下载的URL', $this->startTime, [$wxMediaUrl]);
  78. //将语音文件下载到本地并转为mav格式
  79. $client = new httpClient();
  80. $response = $client->get($wxMediaUrl);
  81. $body = $response->getBody();
  82. $this->setLog(self::TYPENAME.'_curl 微信远程请求到的数据', $this->startTime, [$body]);
  83. $name = array_slice(explode('=', $wxMediaUrl), -1)[0];
  84. $fileName = public_path() . '/storage/speex/' .$name.'.speex';
  85. $outFileName = public_path() . '/storage/speex/out_' .$name.'.wav';
  86. file_put_contents($fileName, $body);
  87. exec("speex2wav $fileName $outFileName");
  88. return $this->response('out_' .$name.'.wav');
  89. }else{
  90. $this->error()->fail($data->message);
  91. }
  92. } catch (\Exception $e) {
  93. $this->setLog(self::TYPENAME.'_curl 远程请求失败', $this->startTime, [$e->getMessage()]);
  94. $this->error()->fail($e->getMessage());
  95. }
  96. }
  97. public function hospMyOutModule(string $open_id)
  98. {
  99. $op = 'hosp';
  100. $task = 'hospMyOutModule';
  101. $postArr = [
  102. 'open_id' => $open_id,
  103. 'start' => 0,
  104. 'count' => 10000
  105. ];
  106. $this->setLog(self::TYPENAME.'量表记录 进入', $this->startTime, $postArr, 'debug');
  107. $url = $this->_makeUrl($op, $task, $postArr);
  108. $curlData = $this->_curl($url, $postArr);
  109. return $this->response($curlData);
  110. }
  111. public function orderSync(string $order_id, int $status, string $prepay_id, int $pay_money, string $pay_time, string $refund_id, string $refund_datetime, int $refund_money)
  112. {
  113. $op = 'hosp';
  114. $task = 'orderSync';
  115. $postArr = [
  116. 'order_id' => $order_id,
  117. 'status' => $status,
  118. 'prepay_id' => $prepay_id,
  119. 'pay_money' => $pay_money,
  120. 'pay_time' => $pay_time,
  121. 'refund_id' => $refund_id,
  122. 'refund_datetime' => $refund_datetime,
  123. 'refund_money' => $refund_money
  124. ];
  125. $this->setLog(self::TYPENAME.'门诊付费同步 进入', $this->startTime, $postArr, 'debug');
  126. $url = $this->_makeUrl($op, $task, $postArr);
  127. $curlData = $this->_curl($url, $postArr);
  128. return $this->response($curlData);
  129. }
  130. public function orderSelect(string $openId, int $payStatus = 0, int $orderType = 0)
  131. {
  132. $op = 'hosp';
  133. $task = 'orderSelect';
  134. $postArr = [
  135. 'open_id' => $openId,
  136. 'pay_status' => $payStatus,
  137. 'order_type' => $orderType,
  138. 'start' => 0,
  139. 'count' => 10000
  140. ];
  141. $this->setLog(self::TYPENAME.'查询指定患者门诊缴费情况 进入', $this->startTime, $postArr, 'debug');
  142. $url = $this->_makeUrl($op, $task, $postArr);
  143. $curlData = $this->_curl($url, $postArr);
  144. return $this->response($curlData);
  145. }
  146. public function moduleList(int $start, int $count, string $keyword='',string $mid='')
  147. {
  148. $op = 'module';
  149. $task = 'moduleList';
  150. $postArr = [
  151. 'start' => $start,
  152. 'count' => $count,
  153. 'keyword' => $keyword,
  154. 'mid' => $mid
  155. ];
  156. $this->setLog(self::TYPENAME.'获取量表列表 进入', $this->startTime, $postArr, 'debug');
  157. $url = $this->_makeUrl($op, $task, $postArr);
  158. $curlData = $this->_curl($url, $postArr);
  159. return $this->response($curlData);
  160. }
  161. public function uploadFile(string $open_id, $filename, int $file_type)
  162. {
  163. $op = 'hosp';
  164. $task = 'uploadFile';
  165. $file = fopen($filename, 'r');
  166. $postArr = [
  167. 'file_type' => $file_type,
  168. 'open_id' => $open_id
  169. ];
  170. $postArr2 = [
  171. [
  172. 'name' => 'file_path',
  173. 'contents' => $file
  174. ],
  175. [
  176. 'name' => 'file_type',
  177. 'contents' => $file_type
  178. ],
  179. [
  180. 'name' => 'open_id',
  181. 'contents' => $open_id
  182. ],
  183. ];
  184. $url = $this->_makeUrl($op, $task, $postArr);
  185. $curlData = $this->_curl($url, $postArr2, 'multipart');
  186. $curlData->res = true;
  187. return $curlData;
  188. }
  189. public function outCancel(string $apply_open_id)
  190. {
  191. $op = 'hosp';
  192. $task = 'outCancel';
  193. $postArr = [
  194. 'apply_open_id' => $apply_open_id,
  195. ];
  196. $this->setLog(self::TYPENAME.'取消未付款预约 进入', $this->startTime, $postArr, 'debug');
  197. $url = $this->_makeUrl($op, $task, $postArr);
  198. $curlData = $this->_curl($url, $postArr);
  199. return $this->response($curlData);
  200. }
  201. public function outConfirm(string $apply_open_id, string $visit_card_no, string $prepay_id, int $pay_money, string $pay_time)
  202. {
  203. $op = 'hosp';
  204. $task = 'outConfirm';
  205. $postArr = [
  206. 'apply_open_id' => $apply_open_id,
  207. 'visit_card_no' => $visit_card_no,
  208. 'prepay_id' => $prepay_id,
  209. 'pay_money' => $pay_money,
  210. 'pay_time' => $pay_time
  211. ];
  212. $this->setLog(self::TYPENAME.'门诊确认预约/已付款 进入', $this->startTime, $postArr, 'debug');
  213. $url = $this->_makeUrl($op, $task, $postArr);
  214. $curlData = $this->_curl($url, $postArr);
  215. return $this->response($curlData);
  216. }
  217. public function outApply(string $open_id, string $work_open_id, int $time_select)
  218. {
  219. $op = 'hosp';
  220. $task = 'outApply';
  221. $postArr = [
  222. 'open_id' => $open_id,
  223. 'work_open_id' => $work_open_id,
  224. 'time_select' => $time_select
  225. ];
  226. $this->setLog(self::TYPENAME.'门诊预约锁号 进入', $this->startTime, $postArr, 'debug');
  227. $url = $this->_makeUrl($op, $task, $postArr);
  228. $curlData = $this->_curl($url, $postArr);
  229. return $this->response($curlData);
  230. }
  231. public function hospWork(string $dockor_open_id, string $work_date_start, string $work_date_end)
  232. {
  233. $op = 'hosp';
  234. $task = 'hospWork';
  235. $postArr = [
  236. 'dockor_open_id' => $dockor_open_id,
  237. 'work_date_start' => $work_date_start,
  238. 'work_date_end' => $work_date_end
  239. ];
  240. $this->setLog(self::TYPENAME.'排班信息获取 进入', $this->startTime, $postArr, 'debug');
  241. $url = $this->_makeUrl($op, $task, $postArr);
  242. $curlData = $this->_curl($url, $postArr);
  243. return $this->response($curlData);
  244. }
  245. public function hospWorkSave(string $day)
  246. {
  247. $op = 'hosp';
  248. $task = 'hospWorkSave';
  249. $status = self::STATUS_2;
  250. //排班日期
  251. $registerDate = $day;
  252. //取出需要更新排除的医生
  253. $fields = ['doctors.id','doctors.third_openid','doctors.third_type','doctors.his_employeecode','his_deptcode','third_section_open_id'];
  254. $doctors = Doctor::leftJoin('sections','sections.id','doctors.sectionId1')->where('third_type',1)->get($fields);
  255. //医生排班日期
  256. $doctorVisitieData = ['week'=>$registerDate,'is_visit'=>$status];
  257. //医生排班时间段
  258. $doctorVisityExtendData = [
  259. ['title'=>'09:00-10:00', 'quantity'=>0,'end_time'=>$registerDate.' 09:00:00'],
  260. ['title'=>'10:30-11:30', 'quantity'=>0,'end_time'=>$registerDate.' 10:30:00'],
  261. ['title'=>'14:30-15:30', 'quantity'=>0,'end_time'=>$registerDate.' 14:30:00'],
  262. ['title'=>'16:30-17:30', 'quantity'=>0,'end_time'=>$registerDate.' 16:30:00']
  263. ];
  264. //组合杨总数据
  265. $postArr = [
  266. 'doctor_open_id' => 0,
  267. 'work_date' => $registerDate,
  268. 'work_is_ol' => 2, // 门诊类型 1线下 2线上
  269. 'work_ol_type' => 2, // 诊间模式 1 医护模式 2纯医模式
  270. 'day_type' => 1, // 时间划分 1上午 2下午
  271. 'status' => $status, // 诊间状态 1正常 2停诊
  272. 'is_type' => 2, // 排班方式 1 顺序模式 2固定时间
  273. 'order_start_datetime' => '',
  274. 'order_estimate_time' => 60, //每个患者预估时间
  275. 'order_max_num' => 2,
  276. // 'rest_time_start' => '11:30:59',
  277. // 'rest_time_end' => '14:29:59'
  278. ];
  279. foreach ($doctors as $doctor){
  280. //一天两条,上午一条和下午一条
  281. $postArrs = [
  282. $postArr,
  283. $postArr
  284. ];
  285. //加入医生id
  286. $doctorVisitieData['doctorId'] = $doctor->id;
  287. $doctorVisityExtendData[0]['doctor_id'] = $doctor->id;
  288. $doctorVisityExtendData[1]['doctor_id'] = $doctor->id;
  289. $doctorVisityExtendData[2]['doctor_id'] = $doctor->id;
  290. $doctorVisityExtendData[3]['doctor_id'] = $doctor->id;
  291. $postArrs[0]['doctor_open_id'] = $doctor->third_openid;
  292. $postArrs[1]['doctor_open_id'] = $doctor->third_openid;
  293. //从HIS获取排班数据
  294. $hisDatas = HisApiFacade::useableNumQuery($registerDate, $doctor->his_deptcode, $doctor->his_employeecode);
  295. if ($hisDatas->getData()->code == self::SUCCESS_CODE && $hisDatas->getData()->data) {
  296. $hisDatas = $hisDatas->getData()->data;
  297. }elseif ($hisDatas->getData()->code == self::SUCCESS_CODE && $hisDatas->getData()->data == null){
  298. $this->setLog(self::TYPENAME.'从HIS获取到的排班信息为空', $this->startTime,['doctorid'=>$doctor->id,'registerDate'=>$registerDate],'error');
  299. continue;
  300. // $this->error()->dataDoesNotExist('从HIS获取到的排班信息为空');
  301. }
  302. foreach ($hisDatas as $hisData){
  303. if ($hisData->workTimeName == '上午班' && $hisData->useableNum > 0) {
  304. //有数据表示医生坐诊
  305. $status = self::STATUS_1;
  306. $doctorVisityExtendData[0]['quantity'] = 1;
  307. $doctorVisityExtendData[1]['quantity'] = 1;
  308. $doctorVisityExtendData[0]['his_worktime_code'] = $hisData->workTimeCode;
  309. $doctorVisityExtendData[1]['his_worktime_code'] = $hisData->workTimeCode;
  310. $doctorVisityExtendData[0]['his_fee'] = $hisData->numFee;
  311. $doctorVisityExtendData[1]['his_fee'] = $hisData->numFee;
  312. $postArrs[0]['day_type'] = self::DAY_TYPE_1;
  313. $postArrs[0]['status'] = self::STATUS_1;
  314. // $postArrs[0]['order_start_datetime'] = '09:00';
  315. $postArrs[0]['fixed_json'] = '[{"start_time":"09:00:00","end_time":"09:59:59"},{"start_time":"10:30:00","end_time":"11:29:59"}]';
  316. }elseif ($hisData->workTimeName == '下午班' && $hisData->useableNum > 0) {
  317. //有数据表示医生坐诊
  318. $status = self::STATUS_1;
  319. $doctorVisityExtendData[2]['quantity'] = 1;
  320. $doctorVisityExtendData[3]['quantity'] = 1;
  321. $doctorVisityExtendData[2]['his_worktime_code'] = $hisData->workTimeCode;
  322. $doctorVisityExtendData[3]['his_worktime_code'] = $hisData->workTimeCode;
  323. $doctorVisityExtendData[2]['his_fee'] = $hisData->numFee;
  324. $doctorVisityExtendData[3]['his_fee'] = $hisData->numFee;
  325. $postArrs[1]['day_type'] = self::DAY_TYPE_2;
  326. $postArrs[1]['status'] = self::STATUS_1;
  327. // $postArrs[1]['order_start_datetime'] = '14:30';
  328. $postArrs[1]['fixed_json'] = '[{"start_time":"14:30:00","end_time":"15:29:59"},{"start_time":"16:30:00","end_time":"17:29:59"}]';
  329. }
  330. }
  331. //重新给医生赋值坐诊状态
  332. $doctorVisitieData['is_visit'] = $status;
  333. $doctorVisity = DoctorVisity::create($doctorVisitieData);
  334. foreach ($postArrs as $postKey=>$post){
  335. if (!isset($post['fixed_json'])) {
  336. continue;
  337. }
  338. $this->setLog(self::TYPENAME.'创建排班 进入', $this->startTime, $post, 'debug');
  339. $url = $this->_makeUrl($op, $task, $post);
  340. $thirdData = $this->_curl($url, $post);
  341. if ($thirdData) {
  342. foreach ($doctorVisityExtendData as $key=>$extend){
  343. $extend['third_work_open_id'] = $thirdData->work_open_id;
  344. $extend['doctor_visity_id'] = $doctorVisity->id;
  345. if ($postKey===0 && $key<2) {
  346. $extend['third_work_index'] = $key;
  347. DoctorVisityExtend::create($extend);
  348. }
  349. if ($postKey===1 && $key>=2) {
  350. $extend['third_work_index'] = $key-2;
  351. DoctorVisityExtend::create($extend);
  352. }
  353. }
  354. }
  355. }
  356. }
  357. }
  358. public function customerCreate(string $open_id, string $id_card, string $name, int $sex, int $marry_type, int $age, string $contact, $wechat_uid, $face_path='')
  359. {
  360. $op = 'customer';
  361. $task = 'customerCreate';
  362. $postArr = [
  363. 'open_id' => $open_id,
  364. 'name' => $name,
  365. 'sex' => $sex,
  366. 'marry_type' => $marry_type,
  367. 'age' => $age,
  368. 'contact' => $contact,
  369. 'wechat_uid' => $wechat_uid,
  370. 'face_path' => ''
  371. ];
  372. $this->setLog(self::TYPENAME.'创建患者 进入', $this->startTime, $postArr, 'debug');
  373. $url = $this->_makeUrl($op, $task, $postArr);
  374. $url = $this->_makeUrl($op, $task, $postArr);
  375. $curlType = 'form_params';
  376. if($face_path == true){
  377. $curlType = 'multipart';
  378. $file = fopen($face_path, 'r');
  379. $postArr = [['name'=>'open_id','contents'=>$open_id],['name'=>'name','contents'=>$name],['name'=>'sex','contents'=>$sex],['name'=>'marry_type','contents'=>$marry_type],['name'=>'age','contents'=>$age],['name'=>'contact','contents'=>$contact],['name'=>'wechat_uid','contents'=>$wechat_uid]];
  380. }
  381. $curlData = $this->_curl($url, $postArr, $curlType);
  382. return $this->response($curlData);
  383. }
  384. public function getDoctor(array $postArr)
  385. {
  386. $op = 'hosp';
  387. $task = 'doctor';
  388. $url = $this->_makeUrl($op, $task, $postArr);
  389. $datas = $this->_curl($url, $postArr);
  390. return $this->response($datas);
  391. }
  392. public function getDepartment(array $postArr)
  393. {
  394. $op = 'hosp';
  395. $task = 'department';
  396. $url = $this->_makeUrl($op, $task, $postArr);
  397. $datas = $this->_curl($url, $postArr);
  398. return $this->response($datas);
  399. }
  400. /**
  401. * 请求接口
  402. *
  403. * @param string $url 请求地址
  404. * @param array $postArr 请求参数
  405. * @param string $paramType 请求类型 form_params multipart
  406. * @return array
  407. */
  408. private function _curl(string $url, array $postArr, string $paramType = 'form_params')
  409. {
  410. $this->setLog(self::TYPENAME.'_curl 进入', $this->startTime(), ['url'=>$url, 'postArr'=>$postArr]);
  411. try {
  412. $client = new httpClient();
  413. $res = $client->request('post', $url, [$paramType=>$postArr]);
  414. $body = $res->getBody();
  415. $data = (object)json_decode($body);
  416. $this->setLog(self::TYPENAME.'_curl 远程请求到的数据', $this->startTime, [$data]);
  417. if ($data->status === TRUE && $data->code == 9000) {
  418. return $data->data;
  419. }else{
  420. $this->error()->fail($data->message);
  421. }
  422. } catch (\Exception $e) {
  423. $this->setLog(self::TYPENAME.'_curl 远程请求失败', $this->startTime, [$e->getMessage()]);
  424. $this->error()->fail($e->getMessage());
  425. }
  426. }
  427. private function _makeUrl(string $op, string $task, array $postArr, string $ap='', string $version='1.0.0')
  428. {
  429. self::setLog(self::TYPENAME.'加密 进入');
  430. //按键排序
  431. ksort($postArr);
  432. //取出值并拼接字符串
  433. $postStr = implode('', array_values($postArr));
  434. $appId = config('console.third_consult.appid');
  435. //按规则拼接加密字符串 APPID + op + task + 接口版本号 + post数据按键排序连接字符串 + 秘钥
  436. $signStr = $appId.$op.$task.$version.$postStr.config('console.third_consult.secret');
  437. $md5Sign = md5($signStr);
  438. self::setLog(self::TYPENAME.'加密得到字符串',$this->startTime,['拼接后的字符串'=>$signStr,'md5后结果'=>$md5Sign]);
  439. $querys = [
  440. 'op=' . $op,
  441. 'task=' . $task,
  442. 'version=' . $version,
  443. 'appid=' . urlencode($appId),
  444. 'sign=' . $md5Sign
  445. ];
  446. //在线咨询的地址
  447. $url = config('console.third_consult.url');
  448. if ($ap != '') {
  449. //在线测评的地址
  450. $url = config('console.third_consult.scale_url');
  451. $querys[] = 'ap='.$ap;
  452. $querys[] = 'open_id='.urlencode($postArr['open_id']);
  453. $querys[] = 'order_id='.urlencode($postArr['order_id']);
  454. $querys[] = 's_timestamp='.$postArr['s_timestamp'];
  455. $querys[] = 'call_back='.$postArr['call_back'];
  456. }
  457. return $url.'?'.implode('&', array_values($querys));
  458. }
  459. }