Exams.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. <?php
  2. namespace app\admin\controller\statistics;
  3. use app\admin\model\exams\ExamsModel;
  4. use app\common\controller\Backend;
  5. use PhpOffice\PhpSpreadsheet\IOFactory;
  6. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  7. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  8. use think\Db;
  9. use think\Debug;
  10. /**
  11. *
  12. *
  13. * @icon fa fa-circle-o
  14. */
  15. class Exams extends Backend
  16. {
  17. /**
  18. * Remote模型对象
  19. * @var \app\admin\model\remote\Remote
  20. */
  21. protected $model = null;
  22. protected $noNeedRight = ['getPositive','getExcel'];
  23. public function _initialize()
  24. {
  25. parent::_initialize();
  26. $this->model = new ExamsModel();
  27. }
  28. public function index()
  29. {
  30. //设置过滤方法
  31. $this->request->filter(['strip_tags']);
  32. if ($this->request->isAjax()) {
  33. if(!(strlen($this->request->request('filter')) > 2))
  34. {
  35. return json(['code'=>200,'msg'=>'请输入搜索条件进行查询']);
  36. }
  37. //如果发送的来源是Selectpage,则转发到Selectpage
  38. list($where, $sort, $order, $offset, $limit) = $this->buildparams($this->searchFields, true);
  39. $field = [
  40. // 'exam.*', 'i.name as institution_name','province','pb.id as pb_id'
  41. 'exam.*', 'i.name as institution_name','ris_province as province','ris_city as city'
  42. ];
  43. $status = ['exam.status' => '1'];
  44. // 过滤机构
  45. $childInsIds = $this->auth->getMyInsId();
  46. if($childInsIds == false){
  47. $more = false;
  48. } else {
  49. $more['exam.institution_id'] = ['in',$this->auth->getMyInsId()];
  50. }
  51. $bind_where = false;
  52. $param = $this->request->param();
  53. if(isset($param['is_bind'])){
  54. $filter = $this->request->get("filter", '');
  55. $filter = json_decode($filter, TRUE);
  56. $ins = $filter['institution_id'] ?? '';
  57. if(empty($ins))
  58. {
  59. $this->error('请选择医院进行查询患者绑定信息');
  60. }
  61. // $bind_arr = Db::table('patient_search')
  62. // ->where('institution_id',$ins)
  63. // ->where('search_result', '1')
  64. // ->column('exam_id');
  65. // $bind_arr = array_filter($bind_arr);
  66. // $bind_arr = array_keys(array_flip($bind_arr));
  67. $cond = $param['is_bind'] === '1' ? 'in' : 'not in';
  68. // $bind_where['exam.id'] = [
  69. // $cond, $bind_arr
  70. // ];
  71. $total = $this->model->alias('exam')
  72. ->join(['institution'=>'i'],'exam.institution_id = i.id','left')
  73. ->where('exam.id',$cond,function ($query)use($filter){
  74. $query->table('patient_search')
  75. ->where('institution_id',$filter['institution_id'])
  76. ->where('search_result', '1')
  77. ->field('exam_id');
  78. })
  79. ->where($where)
  80. ->where($bind_where)
  81. ->where($more)
  82. ->where($status)
  83. ->count();
  84. if($offset === 0 && $limit === 00 && $total > 10000){
  85. $this->error('超出10000条记录,请分批导出!');
  86. }
  87. $sql = $this->model->alias('exam')
  88. ->join(['institution'=>'i'],'exam.institution_id = i.id','left')
  89. ->where('exam.id',$cond,function ($query)use($filter){
  90. $query->table('patient_search')
  91. ->where('institution_id',$filter['institution_id'] ?? '')
  92. ->where('search_result', '1')
  93. ->field('exam_id');
  94. })
  95. ->field($field)
  96. ->order($sort, $order)
  97. ->limit($offset, $limit)
  98. ->where($where)
  99. ->where($bind_where)
  100. ->where($more)
  101. ->where($status)
  102. ->buildSql();
  103. $list = Db::table($sql.'t')
  104. ->join(['patient_search'=>'pb'],'pb.exam_id=t.id and pb.search_result=1','left')
  105. ->field('t.*, count(pb.id) as c')
  106. ->group('t.id')
  107. ->select();
  108. foreach ($list as $k=>$v){
  109. if($v['c'] == 0){
  110. $list[$k]['is_bind'] = 0;
  111. }else{
  112. $list[$k]['is_bind'] = 1;
  113. }
  114. }
  115. }else{
  116. $total = $this->model->alias('exam')
  117. ->join(['institution'=>'i'],'exam.institution_id = i.id','left')
  118. ->where($where)
  119. ->where($bind_where)
  120. ->where($more)
  121. ->where($status)
  122. ->count();
  123. if($offset === 0 && $limit === 00 && $total > 10000){
  124. $this->error('超出10000条记录,请分批导出!');
  125. }
  126. $sql = $this->model->alias('exam')
  127. ->join(['institution'=>'i'],'exam.institution_id = i.id','left')
  128. ->field($field)
  129. ->order($sort, $order)
  130. ->limit($offset, $limit)
  131. ->where($where)
  132. ->where($bind_where)
  133. ->where($more)
  134. ->where($status)
  135. ->buildSql();
  136. $list = Db::table($sql.'t')
  137. ->join(['patient_search'=>'pb'],'pb.exam_id=t.id and pb.search_result=1','left')
  138. ->field('t.*, count(pb.id) as c')
  139. ->group('t.id')
  140. ->select();
  141. foreach ($list as $k=>$v){
  142. if($v['c'] == 0){
  143. $list[$k]['is_bind'] = 0;
  144. }else{
  145. $list[$k]['is_bind'] = 1;
  146. }
  147. }
  148. }
  149. // 计算阳性率
  150. $list = collection($list)->toArray();
  151. $result = array("total" => $total, "rows" => $list);
  152. return json($result);
  153. }
  154. return $this->view->fetch();
  155. }
  156. public function getPositive()
  157. {
  158. list($where) = $this->buildparams($this->searchFields, true);
  159. $more = ['exam.status' => '1',];
  160. $record = $this->model->alias('exam')
  161. ->join([
  162. ['institution i', 'exam.institution_id = i.id','LEFT'],
  163. ['report r', 'exam.id = r.exam_id','LEFT'],
  164. ])
  165. ->where($where)
  166. ->where($more)
  167. ->where(function ($query){
  168. $query->where('r.report_result',"1")
  169. ->whereOr('r.report_result',"2");
  170. })
  171. ->column('r.report_result');
  172. $num = 0;
  173. $positive = 0;
  174. foreach ($record as $val){
  175. $positive += $val === '2' ? 1 : 0;
  176. }
  177. if($positive != 0){
  178. $num = round(($positive / count($record)) * 100, 2);
  179. }
  180. $this->success('','',[
  181. 'centage' => $num,
  182. 'positive' => $positive
  183. ]);
  184. }
  185. public function getFilm()
  186. {
  187. list($where) = $this->buildparams($this->searchFields, true);
  188. $more = ['exam.status' => '1',];
  189. $record = $this->model->alias('exam')
  190. ->join([
  191. ['report r', 'exam.id = r.exam_id and r.type=1'],
  192. ['quality_control q', 'q.report_id = r.id'],
  193. ])
  194. ->where($where)
  195. ->where($more)
  196. ->column('q.pic_quality');
  197. $you = 0;
  198. $liang = 0;
  199. $hege = 0;
  200. $cha = 0;
  201. foreach ($record as $val){
  202. switch ($val)
  203. {
  204. case 1:
  205. $you++;
  206. break;
  207. case 2:
  208. $liang++;
  209. break;
  210. case 3:
  211. $hege++;
  212. break;
  213. case 4:
  214. $cha++;
  215. break;
  216. }
  217. }
  218. $you = round(($you / count($record)) * 100, 2);
  219. $liang = round(($liang / count($record)) * 100, 2);
  220. $hege = round(($hege / count($record)) * 100, 2);
  221. $cha = round(($cha / count($record)) * 100, 2);
  222. $this->success('','',[
  223. 'you' => $you,
  224. 'liang' => $liang,
  225. 'hege' => $hege,
  226. 'cha' => $cha
  227. ]);
  228. }
  229. public function getExcel()
  230. {
  231. $filter = $this->request->get("filter", '');
  232. $filter = json_decode($filter, TRUE);
  233. if(empty($filter['createdAt']) && empty($filter['exam_datetime']))
  234. {
  235. $this->error('创建时间不能为空');
  236. }
  237. if(empty($filter['exam_class']))
  238. {
  239. $this->error('检查类型不能为空');
  240. }
  241. if(empty($filter['institution_id']))
  242. {
  243. $this->error('请选择医院');
  244. }
  245. if($filter['institution_id'] == '06300010')
  246. {
  247. $this->excel2($filter);
  248. exit;
  249. }
  250. if(empty($filter['createdAt']))
  251. {
  252. $createTime = explode(',',$filter['exam_datetime']);
  253. $key = 'exam_datetime';
  254. }else{
  255. $createTime = explode(' - ',$filter['createdAt']);
  256. $key = 'createdAt';
  257. }
  258. $examClass = $filter['exam_class'];
  259. list($where) = $this->buildparams($this->searchFields, true);
  260. $more = ['e.status' => '1'];
  261. $exam = $this->model->alias('e')
  262. ->where($where)
  263. ->where($more)
  264. ->field('id,exam_class')
  265. ->buildSql();
  266. $allCount = [];
  267. foreach ($examClass as $v)
  268. {
  269. $num = Db::table('exams')->where('exam_class',$v)->where('institution_id',$filter['institution_id'])->where("$key between '$createTime[0]' and '$createTime[1]'")
  270. // ->where("patient_num is not null or patient_num != ''")
  271. ->field('patient_num,exam_datetime,count(*)')->group('patient_num,exam_datetime')->select();
  272. // $num = Db::table('exams')->where('exam_class',$v)->where('institution_id',$filter['institution_id'])->where("$key between '$createTime[0]' and '$createTime[1]'")->where("accession_num is not null and accession_num != ''")->distinct(true)->field('accession_num')->select();
  273. // $num1 = Db::table('exams')->where('exam_class',$v)->where('institution_id',$filter['institution_id'])->where("$key between '$createTime[0]' and '$createTime[1]'")->where("accession_num is null or accession_num = ''")->select();
  274. // $allCount[$v] = count($num)+count($num1);
  275. $allCount[$v] = count($num);
  276. }
  277. $d = Db::table($exam.'t')
  278. ->join(['wechat_visit'=>'wv'],'wv.exam_id=t.id','left')
  279. ->field('t.id,t.exam_class, count(wv.id) AS c')
  280. ->group('t.id')
  281. ->select();
  282. if(empty($d))
  283. {
  284. $this->error('没有数据');
  285. }
  286. // $class = [];
  287. // foreach ($examClass as $type) {
  288. // $all = 0;
  289. // $bind = 0;
  290. // foreach ($d as $k => $v) {
  291. // if ($v['exam_class'] == $type) {
  292. // $all++;
  293. // if ($v['c'] != '0') {
  294. // // 已绑定
  295. // $bind++;
  296. // }
  297. // }
  298. // }
  299. // $class[$type] = ['all'=>$all,'bind'=>$bind];
  300. // }
  301. $fileName = '检查统计'.date('YmdHis').'.xlsx';
  302. import('phpexcel.PHPExcel', EXTEND_PATH);
  303. $path = ROOT_PATH.'public/excel.xlsx';
  304. $reader = IOFactory::createReader('Xlsx');
  305. $excal= $reader->load($path);
  306. $sheet = $excal->getActiveSheet();
  307. $b7Class = $sheet->getCell('B7')->getValue();
  308. $b8Class = $sheet->getCell('B8')->getValue();
  309. $ins = Db::table('institution')->where('id',$filter['institution_id'])->value('name');
  310. $price = Db::table('institution')->where('id',$filter['institution_id'])->value('film_price');
  311. $ins_name = $ins.'云胶片收费单';
  312. $sheet->setCellValue ('A1', $ins_name);
  313. $sheet->setCellValue ('D2', $createTime[0]);
  314. $sheet->setCellValue ('F2', $createTime[1]);
  315. $sheet->setCellValue ('F3', $price/100);
  316. $sheet->setCellValue ('C7', $allCount[$b7Class] ?? 0);
  317. $sheet->setCellValue ('C8', $allCount[$b8Class] ?? 0);
  318. //获取打印人次
  319. $time1 = date('Y-m-d 00:00:00',strtotime($createTime[0]));
  320. $time2 = date('Y-m-d 23:59:59',strtotime($createTime[1]));
  321. // $all = Db::table('print_sync')
  322. // ->where('institution_id',$filter['institution_id'])
  323. // ->where("print_time between '$time1' and '$time2'")
  324. // ->field("COUNT(*) as times,code,name,DATE_FORMAT(print_time,'%Y-%m-%d') as c,institution_id")
  325. // ->group("code,name,DATE_FORMAT(print_time,'%Y-%m-%d'),institution_id")
  326. // ->select();
  327. // $d7_times = count($all);
  328. // $sheet->setCellValue ('D7', $d7_times);
  329. // $sheet->setCellValue ('F7', ($class[$b7Class]['bind'] ?? 0)+($class[$b8Class]['bind'] ?? 0));
  330. //获取打印胶片量
  331. $h7_times = Db::table('print_sync')->where("print_time between '$time1' and '$time2'")->where('institution_id',$filter['institution_id'])->sum('times');
  332. $sheet->setCellValue ('H7', $h7_times);
  333. header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  334. header('Content-Disposition: attachment;filename="'.$fileName.'"');
  335. header('Cache-Control: max-age=0');
  336. $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($excal, 'Xlsx');
  337. $writer->save('php://output');
  338. exit;
  339. }
  340. public function excel2($filter)
  341. {
  342. if(empty($filter['createdAt']))
  343. {
  344. $createTime = explode(',',$filter['exam_datetime']);
  345. $key = 'exam_datetime';
  346. }else{
  347. $createTime = explode(' - ',$filter['createdAt']);
  348. $key = 'createdAt';
  349. }
  350. $examClass = $filter['exam_class'];
  351. list($where) = $this->buildparams($this->searchFields, true);
  352. $more = ['e.status' => '1'];
  353. $exam = $this->model->alias('e')
  354. ->where($where)
  355. ->where($more)
  356. ->field('id,exam_class')
  357. ->buildSql();
  358. // $allCount = [];
  359. $noDisCount = [];
  360. foreach ($examClass as $v)
  361. {
  362. // $num = Db::table('exams')->where('exam_class',$v)->where('institution_id',$filter['institution_id'])->where("$key between '$createTime[0]' and '$createTime[1]'")
  363. // ->field('patient_num,exam_datetime,count(*)')->group('patient_num,exam_datetime')->select();
  364. // $allCount[$v] = count($num);
  365. $noDisCount[$v] = Db::table('exams')->where('exam_class',$v)->where('institution_id',$filter['institution_id'])->where("$key between '$createTime[0]' and '$createTime[1]'")->count();
  366. }
  367. $d = Db::table($exam.'t')
  368. ->join(['wechat_visit'=>'wv'],'wv.exam_id=t.id','left')
  369. ->field('t.id,t.exam_class, count(wv.id) AS c')
  370. ->group('t.id')
  371. ->select();
  372. if(empty($d))
  373. {
  374. $this->error('没有数据');
  375. }
  376. $class = [];
  377. foreach ($examClass as $type) {
  378. $all = 0;
  379. $bind = 0;
  380. foreach ($d as $k => $v) {
  381. if ($v['exam_class'] == $type) {
  382. $all++;
  383. if ($v['c'] != '0') {
  384. // 已绑定
  385. $bind++;
  386. }
  387. }
  388. }
  389. $class[$type] = ['all'=>$all,'bind'=>$bind];
  390. }
  391. $fileName = '检查统计'.date('YmdHis').'.xlsx';
  392. import('phpexcel.PHPExcel', EXTEND_PATH);
  393. $path = ROOT_PATH.'public/excel2.xlsx';
  394. $reader = IOFactory::createReader('Xlsx');
  395. $excal= $reader->load($path);
  396. $sheet = $excal->getActiveSheet();
  397. $b7Class = $sheet->getCell('B7')->getValue();
  398. $b8Class = $sheet->getCell('B8')->getValue();
  399. $b9Class = $sheet->getCell('B9')->getValue();
  400. if($b9Class == 'DR')
  401. {
  402. $b9Class = 'DX';
  403. }
  404. $ins = Db::table('institution')->where('id',$filter['institution_id'])->value('name');
  405. $price = Db::table('institution')->where('id',$filter['institution_id'])->value('film_price');
  406. $ins_name = $ins.'云胶片收费单';
  407. $sheet->setCellValue ('A1', $ins_name);
  408. $sheet->setCellValue ('D2', $createTime[0]);
  409. $sheet->setCellValue ('F2', $createTime[1]);
  410. $sheet->setCellValue ('F3', $price/100);
  411. $sheet->setCellValue ('C7', $noDisCount[$b7Class] ?? 0);
  412. $sheet->setCellValue ('C8', $noDisCount[$b8Class] ?? 0);
  413. $sheet->setCellValue ('C9', ($noDisCount[$b9Class] ?? 0)+($noDisCount['CR'] ?? 0));
  414. // $sheet->setCellValue ('G7', ($allCount[$b7Class] ?? 0)+($allCount[$b8Class] ?? 0));
  415. $sheet->setCellValue ('G7', ($noDisCount[$b7Class] ?? 0)+($noDisCount[$b8Class] ?? 0));
  416. //获取打印人次
  417. $time1 = date('Y-m-d 00:00:00',strtotime($createTime[0]));
  418. $time2 = date('Y-m-d 23:59:59',strtotime($createTime[1]));
  419. $all = Db::table('print_sync')
  420. ->where('institution_id',$filter['institution_id'])
  421. ->where("print_time between '$time1' and '$time2'")
  422. ->field("COUNT(*) as times,code,name,DATE_FORMAT(print_time,'%Y-%m-%d') as c,institution_id")
  423. ->group("code,name,DATE_FORMAT(print_time,'%Y-%m-%d'),institution_id")
  424. ->select();
  425. $d7_times = count($all);
  426. $sheet->setCellValue ('D7', $d7_times);
  427. header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  428. header('Content-Disposition: attachment;filename="'.$fileName.'"');
  429. header('Cache-Control: max-age=0');
  430. $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($excal, 'Xlsx');
  431. $writer->save('php://output');
  432. exit;
  433. }
  434. }