|
@ -0,0 +1,244 @@
|
|
|
package com.yihu.jw.hospital.module.common.service;
|
|
|
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import java.text.DecimalFormat;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
|
|
|
/**
|
|
|
* Created by yeshijie on 2024/6/3.
|
|
|
*/
|
|
|
@Service
|
|
|
public class StatisticsService {
|
|
|
@Autowired
|
|
|
private JdbcTemplate jdbcTemplate;
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 智能设备分析
|
|
|
* 1、统计智能设备总数、设备上传次数、投放科室数量;
|
|
|
* 2、智能设备总数:展示添加时间为查询时间内的设备总数,展示各类型的设备数量及占比比例;
|
|
|
* 3、设备上传次数:展示查询时间段内所有设备的上传次数,展示各类型设备的上传次数及占总数的比例;
|
|
|
* 4、投放科室数量:展示添加时间为查询时间内的设备分配给科室的科室数量,需去重;
|
|
|
* 5、设备总数取值:医生PC端—设备信息管理中添加时间为查询时间段内设备数量(已删除的不算在内);
|
|
|
* 6、上传总数取值:医生PC端—体征数据查询中,上传时间为查询时间段内的记录数量;
|
|
|
* 7、投放科室数量取值:医生PC端—设备信息管理中已维护的设备中选择的科室的数量,按添加时间进行查询注:(一个科室只计算一次)
|
|
|
*/
|
|
|
public JSONObject deviceAnalysis(String startDate,String endDate) throws Exception{
|
|
|
JSONObject json = new JSONObject();
|
|
|
String filterDevice = "";
|
|
|
String filterUpload = "";
|
|
|
String filterDept = "";
|
|
|
String filterDeptUse = "";
|
|
|
if(StringUtils.isNotBlank(startDate)){
|
|
|
filterDevice += " and d.apply_date>='"+startDate+"' ";
|
|
|
filterDept += " and apply_date>='"+startDate+"' ";
|
|
|
filterDeptUse += " and d.apply_date>='"+startDate+"' and i.czrq>='"+startDate+"' ";
|
|
|
filterUpload += " and czrq>='"+startDate+"' ";
|
|
|
}
|
|
|
if(StringUtils.isNotBlank(endDate)){
|
|
|
filterDevice += " and d.apply_date<='"+endDate+" 23:59:59' ";
|
|
|
filterDept += " and apply_date<='"+endDate+" 23:59:59' ";
|
|
|
filterDeptUse += " and d.apply_date<='"+endDate+" 23:59:59' and i.czrq<='"+endDate+" 23:59:59' ";
|
|
|
filterUpload += " and czrq<='"+endDate+" 23:59:59' ";
|
|
|
}
|
|
|
|
|
|
//智能设备总数
|
|
|
int devcieTotal = 0;
|
|
|
int devcieXt = 0;//血糖仪数
|
|
|
int devcieXy = 0;//血压计数
|
|
|
String deviceSql = "SELECT dm.category_code type,COUNT(d.id) num FROM " +
|
|
|
"wlyy_devices d INNER JOIN dm_device dm ON d.category_code = dm.id " +
|
|
|
"where 1=1 " + filterDevice +
|
|
|
"GROUP BY dm.category_code";
|
|
|
List<Map<String,Object>> deviceList = jdbcTemplate.queryForList(deviceSql);
|
|
|
for (Map<String,Object> map:deviceList){
|
|
|
String type = map.get("type")+"";
|
|
|
if("1".equals(type)){
|
|
|
devcieXt = Integer.parseInt(map.get("num")+"");
|
|
|
}
|
|
|
if("3".equals(type)){
|
|
|
devcieXy = Integer.parseInt(map.get("num")+"");
|
|
|
}
|
|
|
}
|
|
|
devcieTotal = devcieXt+devcieXy;
|
|
|
json.put("devcieTotal",devcieTotal);
|
|
|
json.put("devcieXt",devcieXt);
|
|
|
json.put("devcieXy",devcieXy);
|
|
|
//设备上传次数
|
|
|
int uploadTotal = 0;
|
|
|
int uploadXt = 0;//
|
|
|
int uploadXy = 0;//
|
|
|
String uploadSql = "select type,count(id) num from wlyy_patient_health_index where 1=1 "+filterUpload+" group by type";
|
|
|
List<Map<String,Object>> uploadList = jdbcTemplate.queryForList(uploadSql);
|
|
|
for (Map<String,Object> map:uploadList){
|
|
|
String type = map.get("type")+"";
|
|
|
if("1".equals(type)){
|
|
|
uploadXt = Integer.parseInt(map.get("num")+"");
|
|
|
}
|
|
|
if("3".equals(type)){
|
|
|
uploadXy = Integer.parseInt(map.get("num")+"");
|
|
|
}
|
|
|
}
|
|
|
uploadTotal = uploadXt+uploadXy;
|
|
|
json.put("uploadTotal",uploadTotal);
|
|
|
json.put("uploadXt",uploadXt);
|
|
|
json.put("uploadXy",uploadXy);
|
|
|
//投放科室数量
|
|
|
String deptSql = "select count(DISTINCT dept) from wlyy_devices where dept is not null "+filterDept;
|
|
|
String deptUseSql = "SELECT count(DISTINCT d.dept) from wlyy_devices d,wlyy_patient_health_index i " +
|
|
|
"WHERE d.dept is not null and d.device_code=i.device_sn and i.del=1 "+filterDeptUse;
|
|
|
int deptTotal = jdbcTemplate.queryForObject(deptSql,Integer.class);
|
|
|
int deptUse = jdbcTemplate.queryForObject(deptUseSql,Integer.class);
|
|
|
if(deptUse>deptTotal){
|
|
|
deptUse = deptTotal;
|
|
|
}
|
|
|
int deptUnUse = deptTotal-deptUse;
|
|
|
json.put("deptTotal",deptTotal);
|
|
|
json.put("deptUse",deptUse);
|
|
|
json.put("deptUnUse",deptUnUse);
|
|
|
return json;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 设备使用情况
|
|
|
* type 1血糖 2血压
|
|
|
* 1、图表说明
|
|
|
* X轴:时间-默认按日期汇总,切换为近半年、今年时,改为按月份汇总支
|
|
|
* Y轴:次数
|
|
|
* 2、用不同颜色代表绑定次数及上传次数,鼠标停留在柱形图后,显示该条的具体数据;
|
|
|
* 3、支持进行血压计、血糖仪的使用情况切换。
|
|
|
*/
|
|
|
public JSONObject deviceUseInfo(String type,String startDate,String endDate){
|
|
|
JSONObject json = new JSONObject();
|
|
|
String bindSql = "SELECT COUNT(*) num,DATE_FORMAT(czrq,'%Y-%m-%d') date from wlyy_patient_device " +
|
|
|
" where category_code = '"+type+"' ";
|
|
|
String useSql = "SELECT COUNT(*) num,DATE_FORMAT(czrq,'%Y-%m-%d') date from wlyy_patient_health_index " +
|
|
|
" where type = '"+type+"' and del=1 ";
|
|
|
if(StringUtils.isNotBlank(startDate)){
|
|
|
bindSql += " and czrq>='"+startDate+"' ";
|
|
|
useSql += " and czrq>='"+startDate+"' ";
|
|
|
}
|
|
|
if(StringUtils.isNotBlank(endDate)){
|
|
|
bindSql += " and czrq<='"+endDate+" 23:59:59' ";
|
|
|
useSql += " and czrq<='"+endDate+" 23:59:59' ";
|
|
|
}
|
|
|
bindSql += " GROUP BY date ORDER BY date ";
|
|
|
useSql += " GROUP BY date ORDER BY date ";
|
|
|
|
|
|
List<Map<String,Object>> bindList = jdbcTemplate.queryForList(bindSql);
|
|
|
List<Map<String,Object>> useList = jdbcTemplate.queryForList(useSql);
|
|
|
json.put("bindList",bindList);
|
|
|
json.put("useList",useList);
|
|
|
return json;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 设备使用情况明细
|
|
|
* 1、展示查询时间段内各科室的使用情况列表;
|
|
|
* 2、支持导出该表格;
|
|
|
* 3、默认按照科室名称的拼音字母进行排序;
|
|
|
* 4、支持通过点击字段名称旁边的排序符号切换排序规则。
|
|
|
* 设备数量按最新的投放科室进行统计;绑定次数按绑定时的投放科室进行统计;上传次数按照上传时的投放科室进行统计
|
|
|
*/
|
|
|
public List<Map<String,Object>> deviceUseDetail(String sort,String startDate,String endDate){
|
|
|
if(StringUtils.isNotBlank(sort)){
|
|
|
sort = "deptName";
|
|
|
}
|
|
|
String filter = "";
|
|
|
String filterUse = "";
|
|
|
String filterBind = "";
|
|
|
if(StringUtils.isNotBlank(startDate)){
|
|
|
filter += " and d.apply_date>='"+startDate+"' ";
|
|
|
filterUse += " and czrq>='"+startDate+"' ";
|
|
|
filterBind += " and czrq>='"+startDate+"' ";
|
|
|
}
|
|
|
if(StringUtils.isNotBlank(endDate)){
|
|
|
filter += " and d.apply_date<='"+endDate+" 23:59:59' ";
|
|
|
filterUse += " and czrq<='"+endDate+" 23:59:59' ";
|
|
|
filterBind += " and czrq<='"+endDate+" 23:59:59' ";
|
|
|
}
|
|
|
|
|
|
|
|
|
String sql = "SELECT d.code dept,d.`name` deptName,IFNULL(t1.xtNum,0) xtNum,IFNULL(t1.xyNum,0) xyNum " +
|
|
|
",IFNULL(t2.xtUseNum,0) xtUseNum,IFNULL(t2.xyUseNum,0) xyUseNum " +
|
|
|
",IFNULL(t3.xtBindNum,0) xtBindNum,IFNULL(t3.xyBindNum,0) xyBindNum from dict_hospital_dept d " +
|
|
|
"LEFT JOIN (SELECT d.dept,d.dept_name,COUNT(if(dm.category_code=1,1,null)) xtNum,COUNT(if(dm.category_code=2,1,null)) xyNum " +
|
|
|
" from wlyy_devices d,dm_device dm " +
|
|
|
"WHERE d.category_code=dm.id " + filter +
|
|
|
"GROUP BY d.dept) t1 on d.code=t1.dept " +
|
|
|
"LEFT JOIN (SELECT dept,dept_name,COUNT(if(type=1,1,null)) xtUseNum,COUNT(if(type=2,1,null)) xyUseNum from " +
|
|
|
"wlyy_patient_health_index where del=1 " + filterUse +
|
|
|
"GROUP BY dept) t2 on d.code=t2.dept " +
|
|
|
"LEFT JOIN (SELECT dept,dept_name,COUNT(if(category_code=1,1,null)) xtBindNum,COUNT(if(category_code=2,1,null)) xyBindNum " +
|
|
|
"from wlyy_patient_device where 1=1 " + filterBind+
|
|
|
"GROUP BY dept) t3 on d.code=t3.dept " +
|
|
|
"WHERE (xtNum+xyNum+xtUseNum+xyUseNum+xtBindNum+xyBindNum)>0 ORDER BY '"+sort+"' desc";
|
|
|
List<Map<String,Object>> list = jdbcTemplate.queryForList(sql);
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 科室使用情况排名
|
|
|
* 1、默认展示投放科室排名,展示设备添加时间为查询时间段内,各科室的的血糖仪、血压计数量;
|
|
|
* 2、使用科室排名,展示所有在查询时间段内,有使用设备的科室排名(有用户绑定、数据上传的科室),展示“绑定次数”、“上传次数”,默认按照上传次数进行倒序排序
|
|
|
* type 1投放科室 2使用科室
|
|
|
*/
|
|
|
public List<Map<String,Object>> deptRanking(String type,String startDate,String endDate){
|
|
|
String filter = "";
|
|
|
String filterUse = "";
|
|
|
String filterBind = "";
|
|
|
if(StringUtils.isNotBlank(startDate)){
|
|
|
filter += " and d.apply_date>='"+startDate+"' ";
|
|
|
filterUse += " and czrq>='"+startDate+"' ";
|
|
|
filterBind += " and czrq>='"+startDate+"' ";
|
|
|
}
|
|
|
if(StringUtils.isNotBlank(endDate)){
|
|
|
filter += " and d.apply_date<='"+endDate+" 23:59:59' ";
|
|
|
filterUse += " and czrq<='"+endDate+" 23:59:59' ";
|
|
|
filterBind += " and czrq<='"+endDate+" 23:59:59' ";
|
|
|
}
|
|
|
|
|
|
//使用科室排名
|
|
|
String sql = "SELECT d.dept,d.dept_name,COUNT(if(dm.category_code=1,1,null)) xtNum,COUNT(if(dm.category_code=2,1,null)) xyNum " +
|
|
|
" from wlyy_devices d,dm_device dm " +
|
|
|
"WHERE d.category_code=dm.id " + filter +
|
|
|
"GROUP BY d.dept order by xtNum desc ";
|
|
|
|
|
|
//投放科室排名
|
|
|
String sql2 = "SELECT d.code dept,d.`name` deptName,IFNULL(t2.useNum,0) useNum " +
|
|
|
",IFNULL(t3.bindNum,0) bindNum from dict_hospital_dept d " +
|
|
|
"LEFT JOIN (SELECT dept,dept_name,COUNT(id) useNum from " +
|
|
|
"wlyy_patient_health_index where del=1 " + filterUse +
|
|
|
"GROUP BY dept) t2 on d.code=t2.dept " +
|
|
|
"LEFT JOIN (SELECT dept,dept_name,COUNT(id) bindNum " +
|
|
|
"from wlyy_patient_device where 1=1 " + filterBind +
|
|
|
"GROUP BY dept) t3 on d.code=t3.dept " +
|
|
|
"WHERE (useNum+bindNum)>0 " +
|
|
|
"ORDER BY useNum desc ";
|
|
|
List<Map<String,Object>> list = null;
|
|
|
if("1".equals(type)){
|
|
|
list = jdbcTemplate.queryForList(sql);
|
|
|
}else {
|
|
|
list = jdbcTemplate.queryForList(sql2);
|
|
|
}
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
public String getRange(int first, int second) {
|
|
|
if (second == 0 && first > 0) {
|
|
|
return "100%";
|
|
|
} else if (second == 0 && first == 0) {
|
|
|
return "0%";
|
|
|
}
|
|
|
float size = (float) (first * 100) / second;
|
|
|
DecimalFormat df = new DecimalFormat("0");//格式化小数,不足的补0
|
|
|
String filesize = df.format(size);
|
|
|
return filesize + "%";
|
|
|
}
|
|
|
}
|