赞
踩
何为数据字典?数据字典就是管理系统常用的分类数据或者一些固定数据,例如:省市区三级联动数据、民族数据、行业数据、学历数据等,由于该系统大量使用这种数据,所以我们要做一个数据管理方便管理系统数据,一般系统基本都会做数据管理。
service下创建service_cmn模块,将dict表逆向工程,配置分页以及swagger
数据库字典分析
parent_id:
上级id,通过id与parent_id构建上下级关系,例如:我们要获取所有行业数据,那么只需要查询parent_id=20000的数据
name:名称,例如:填写用户信息,我们要select标签选择民族,“汉族”就是数据字典的名称
value:值,例如:填写用户信息,我们要select标签选择民族,“1”(汉族的标识)就是数据字典的值
dict_code:编码,编码是我们自定义的,全局唯一,例如:我们要获取行业数据,我们可以通过parent_id获取,但是parent_id是不确定的,所以我们可以根据编码来获取行业数据
假如要获取民族的数据,dict_code = “民族”
element ui 树形表格数据
二、数据字典
这里只写service 实现类
@Service public class DictServiceImpl extends ServiceImpl<DictMapper, Dict> implements DictService { @Autowired private DictMapper dictMapper; //根据数据id查询子数据列表 @Override @Cacheable(value = "dict",keyGenerator = "keyGenerator") //添加缓存 public List<Dict> findChildData(Long id) { QueryWrapper<Dict> wrapper = new QueryWrapper<>(); wrapper.eq("parent_id", id); List<Dict> dictList = baseMapper.selectList(wrapper); //向list每个dict对象中设置hasChildren值 for (Dict dict : dictList) { Long dictId = dict.getId(); boolean ischild = this.ischildren(dictId); dict.setHasChildren(ischild); } return dictList; } //判断id下面是否有子节点 private boolean ischildren(Long id) { QueryWrapper<Dict> wrapper = new QueryWrapper<>(); wrapper.eq("parent_id", id); Integer count = baseMapper.selectCount(wrapper); return count > 0; } //导出数据字典接口 @Override public void exportDictData(HttpServletResponse response) { //设置下载信息 response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); String fileName = "dict"; response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); //查询数据库 List<Dict> dictList = baseMapper.selectList(null); //把Dict对象转换成DictEeVo对象 List<DictEeVo> dictVoList = new ArrayList<>(dictList.size()); for(Dict dict :dictList){ DictEeVo dictEeVo = new DictEeVo(); BeanUtils.copyProperties(dict,dictEeVo); dictVoList.add(dictEeVo); } //调用方法进行写操作 try { EasyExcel.write(response.getOutputStream(), DictEeVo.class) .sheet("dict") .doWrite(dictVoList); } catch (IOException e) { e.printStackTrace(); } } //导入数据字典 @Override @CacheEvict(value = "dict", allEntries=true) //表示清空缓存中的所有内容 public void importDictData(MultipartFile file) { try { EasyExcel.read(file.getInputStream(),DictEeVo.class,new DictListener(dictMapper)) .sheet().doRead(); } catch (IOException e) { e.printStackTrace(); } } //查询名称 @Override public String getDictName(String dictCode, String value) { //如果dictCode为空,直接根据value查询 if(StringUtils.isEmpty(dictCode)){ QueryWrapper queryWrapper = new QueryWrapper(); queryWrapper.eq("value",value); Dict dict = dictMapper.selectOne(queryWrapper); return dict.getName(); }else{//如果dictCode不为空,根据dictCode和value查询 //根据dictcode查询dict对象,目的是得到dict的id值,在根据此id值查询此id下的子id QueryWrapper<Dict> queryWrapper1 = new QueryWrapper(); queryWrapper1.eq("dict_code",dictCode); Dict codeDict = dictMapper.selectOne(queryWrapper1); Long parent_id = codeDict.getId(); //根据parentId和value值进行查询 QueryWrapper<Dict> queryWrapper2 = new QueryWrapper(); queryWrapper2.eq("parent_id",parent_id).eq("value",value); Dict finalDict = baseMapper.selectOne(queryWrapper2); return finalDict.getName(); } } //根据dictcode查询查询子节点 @Override public List<Dict> findByDictCode(String dictCode) { //根据dictcode获取对应的id QueryWrapper<Dict> queryWrapper1 = new QueryWrapper(); queryWrapper1.eq("dict_code",dictCode); Dict codeDict = dictMapper.selectOne(queryWrapper1); //根据id获取子节点 List<Dict> childData = this.findChildData(codeDict.getId()); return childData; }
Spring Cache 是一个非常优秀的缓存组件。自Spring 3.1起,提供了类似于@Transactional注解事务的注解Cache支持,且提供了Cache抽象,方便切换各种底层Cache(如:redis)
使用Spring Cache的好处:
1,提供基本的Cache抽象,方便切换各种底层Cache;
2,通过注解Cache可以实现类似于事务一样,缓存逻辑透明的应用到我们的业务代码上,且只需要更少的代码就可以完成;
3,提供事务回滚时也自动回滚缓存;
4,支持比较复杂的缓存逻辑;
service_util配置redis
package com.atguigu.yygh.common.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.lang.reflect.Method; import java.time.Duration; /** * @author wangyihui * @create 2021-04-25 15:40 */ @Configuration @EnableCaching // 开启缓存处理 public class RedisConfig { private RedisCacheManager build; /** * 自定义key规则 * * @return */ @Bean public KeyGenerator keyGenerator() { return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()); sb.append(method.getName()); for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); } }; } /** * 设置RedisTemplate规则 * * @param redisConnectionFactory * @return */ @Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); //解决查询缓存转换异常的问题 ObjectMapper om = new ObjectMapper(); // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); //序列号key value redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } /** * 设置CacheManager缓存规则 * * @param factory * @return */ @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisSerializer<String> redisSerializer = new StringRedisSerializer(); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); //解决查询缓存转换异常的问题 ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); // 配置序列化(解决乱码的问题),过期时间600秒 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofSeconds(600)) .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) .disableCachingNullValues(); RedisCacheManager cacheManager = RedisCacheManager.builder(factory) .cacheDefaults(config) .build(); return cacheManager; } }
Spring Cache相当于自动缓存,对于redis需要用RedisTemplate不需要手动set,get
常用注解
根据方法对其返回结果进行缓存,下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上。
使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据,而不需要再去查询数据库。一般用在新增方法上。
使用该注解标志的方法,会清空指定的缓存。
1、对于redis的缓存,springcache只支持String,其它的Hash、List、Set、Zset都不支持,所以对于Hash、List、Set、Zset只能用RedisTemplate
2、Spring cache 只支持单表的数据缓存,Redis支持多表的数据缓存
docker安装mongodb 这里不要配置用用户密码使用mongo
直接原生启动容器
docker run -d --restart=always -p 27017:27017 --name mymongo -v /data/db:/data/db -d mongo
配置mongodb连接,你的mongodb数据库没有yygh_hosp也可以配置连接
#mongodb
spring.data.mongodb.uri=mongodb://47.108.170.87:27017/yygh_hosp
**注意:**这里尽量别使用需要密码验证才能使用mongoDb数据库,不然你远程配置连接贼鸡儿烦
mongodb用来存储医院相关的数据信息
这里要自定义三个MongoDb的dao层,分别对应医院、科室、排版
@Repository
public interface HospitalRepository extends MongoRepository<Hospital,String> {
//判断是否存在数据
Hospital getHospitalByHoscode(String hoscode); //MongoRepository有一套规范,直接按照规范命名,会直接调用写好的方法
//根据医院名称查询
List<Hospital> findHospitalByHosnameLike(String hosname);
}
import com.wang.yygh.model.hosp.Department;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
/**
* @author wangyihui
* @create 2021-11-11 10:03
*/
@Repository
public interface DepartmentRepository extends MongoRepository<Department,String> {
Department getDepartmentByHoscodeAndDepcode(String hoscode, String depcode);
}
import com.wang.yygh.model.hosp.Schedule; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Repository; import java.util.Date; import java.util.List; /** * @author wangyihui * @create 2021-11-11 15:51 */ @Repository public interface ScheduleRepository extends MongoRepository<Schedule,String> { //根据医院编号和排班编号进行查询 Schedule getScheduleByHoscodeAndHosScheduleId(String hoscode, String hosScheduleId); //根据医院编号、科室编号和工作日期,查询排班详情信息 List<Schedule> findScheduleByHoscodeAndDepcodeAndWorkDate(String hoscode, String depcode, Date toDate); }
service impl
@Service public class HospitalSevriceImpl implements HospitalService { @Autowired private HospitalRepository hospitalRepository; @Autowired private DictFeignClient dictFeignClient; @Override public void save(Map<String, Object> parapMap) { //把参数的map集合转换成对象Hospital,方便操作 String mapString = JSONObject.toJSONString(parapMap); //先把map转换成字符串 Hospital hospital = JSONObject.parseObject(mapString, Hospital.class); // 把字符串转换成Hospital对象 //判断是否存在相同数据 String hoscode = hospital.getHoscode(); Hospital hospitalExist = hospitalRepository.getHospitalByHoscode(hoscode); //如果存在,进行修改 if(hospitalExist != null){ hospital.setStatus(hospitalExist.getStatus()); hospital.setCreateTime(hospitalExist.getCreateTime()); hospital.setUpdateTime(new Date()); hospital.setIsDeleted(0); hospitalRepository.save(hospital); }else{ //如果不存在,进行添加 hospital.setStatus(0); hospital.setCreateTime(new Date()); hospital.setUpdateTime(new Date()); hospital.setIsDeleted(0); hospitalRepository.save(hospital); } } //实现根据医院编号查询 @Override public Hospital getByHoscode(String hoscode) { Hospital hospital = hospitalRepository.getHospitalByHoscode(hoscode); return hospital; } //医院列表(条件查询分页) @Override public Page<Hospital> selectHospPage(Integer page, Integer limit, HospitalQueryVo hospitalQueryVo) { //创建pageable对象 Pageable pageable = PageRequest.of(page - 1,limit); //创建条件匹配器 ExampleMatcher matcher = ExampleMatcher.matching() .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) .withIgnoreCase(true); //hospitalSetQueryVo转换成hospital对象 Hospital hospital = new Hospital(); BeanUtils.copyProperties(hospitalQueryVo,hospital); //创建Example对象 Example<Hospital> example = Example.of(hospital,matcher); //调用方法实现查询 Page<Hospital> pages = hospitalRepository.findAll(example, pageable); //查询到所有医院集合并遍历,然后获取到医院等级信息 //采用流的方式 pages.getContent().stream().forEach(item -> { this.setHospitalHosType(item); }); return pages; } //更新医院的上线状态 @Override public void updateStatus(String id, Integer status) { //根据id查询医院信息 Hospital hospital = hospitalRepository.findById(id).get(); hospital.setStatus(status); hospital.setUpdateTime(new Date()); hospitalRepository.save(hospital); } //查询医院详情 @Override public Map<String, Object> getHospById(String id) { Map<String, Object> result = new HashMap<>(); //根据id查询医院信息并将等级信息也封装进去 Hospital hospital = this.setHospitalHosType(hospitalRepository.findById(id).get()); result.put("hospital",hospital); //单独处理更直观 result.put("bookingRule", hospital.getBookingRule()); //不需要重复返回 hospital.setBookingRule(null); return result; } //获取医院名称 @Override public String getHospName(String hoscode) { Hospital hospital = hospitalRepository.getHospitalByHoscode(hoscode); if(hospital != null){ return hospital.getHosname(); } return null; } //根据医院名称查询 @Override public List<Hospital> findByHosname(String hosname) { List<Hospital> list = hospitalRepository.findHospitalByHosnameLike(hosname); return list; } //根据医院编号获取预约挂号详情 @Override public Map<String, Object> item(String hoscode) { Map<String, Object> result = new HashMap<>(); //医院详情 Hospital hospital = this.setHospitalHosType(this.getByHoscode(hoscode)); result.put("hospital", hospital); //预约规则 result.put("bookingRule", hospital.getBookingRule()); //不需要重复返回 hospital.setBookingRule(null); return result; } //获取查询到的医院集合,遍历进行医院等级封装 private Hospital setHospitalHosType(Hospital hospital) { //根据dictCode和value获取医院等级名称 String hostypeString = dictFeignClient.getName("Hostype", hospital.getHostype()); //查询省,市,地区 String provinceString = dictFeignClient.getName(hospital.getProvinceCode()); String cityString = dictFeignClient.getName(hospital.getCityCode()); String districtString = dictFeignClient.getName(hospital.getDistrictCode()); hospital.getParam().put("hostypeString",hostypeString); hospital.getParam().put("fullAddress",provinceString + cityString + districtString); return hospital; } }
@Service public class DepartmentServiceImpl implements DepartmentService { @Autowired private DepartmentRepository departmentRepository; //上传科室接口 @Override public void save(Map<String, Object> parampMap) { //parampMap转换成Department对象 String parampMapString = JSONObject.toJSONString(parampMap); Department department = JSONObject.parseObject(parampMapString, Department.class); //根据医院编号和科室信息进行查询 Department departmentExist = departmentRepository .getDepartmentByHoscodeAndDepcode(department.getHoscode(),department.getDepcode()); //取名采取spring DATA规范 //判断科室是否存在 if(departmentExist != null){ //如果存在,做更改 departmentExist.setUpdateTime(new Date()); departmentExist.setIsDeleted(0); departmentRepository.save(departmentExist); }else{ department.setCreateTime(new Date()); department.setUpdateTime(new Date()); department.setIsDeleted(0); departmentRepository.save(department); } } //查询科室 @Override public Page<Department> finPageDepartment(int page, int limit, DepartmentQueryVo departmentQueryVo) { //MongoRepository开发CRUD //创建Pageble对象,里面设置当前页和每页记录数 Pageable pageable = PageRequest.of(page - 1,limit); // 当前页从0开始,但是我们从1开始传的 //将departmentQueryVo对象转换为department对象 Department department = new Department(); BeanUtils.copyProperties(departmentQueryVo,department); department.setIsDeleted(0); //创建Example对象 ExampleMatcher matcher = ExampleMatcher.matching() .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) .withIgnoreCase(true); Example<Department> example = Example.of(department,matcher); Page<Department> all = departmentRepository.findAll(example,pageable); return all; } //删除科室 @Override public void remove(String hoscode, String depcode) { //根据医院编号和科室编号查询科室信息 Department department = departmentRepository.getDepartmentByHoscodeAndDepcode(hoscode, depcode); if(depcode != null){ //删除 departmentRepository.deleteById(department.getId()); } } //根据医院编号,查询所有科室列表 @Override public List<DepartmentVo> findDepTree(String hoscode) { //创建List集合,用于最终数据封装 List<DepartmentVo> result = new ArrayList<>(); //根据医院编号,查询所有科室信息 Department departmentQuery = new Department(); departmentQuery.setHoscode(hoscode); Example<Department> example = Example.of(departmentQuery); //所有科室列表信息 List<Department> departmentList = departmentRepository.findAll(example); //根据大科室编号bigcode进行分组,获取每个大科室里面的下级子科室 Map<String, List<Department>> departmentMap = departmentList.stream().collect(Collectors.groupingBy(Department::getBigcode)); //遍历map集合 for(Map.Entry<String,List<Department>> entry : departmentMap.entrySet()){ //大科室编号 String bigcode = entry.getKey(); //大科室编号对应的全部数据 List<Department> department1List = entry.getValue(); //封装大科室 DepartmentVo departmentVo1 = new DepartmentVo(); departmentVo1.setDepcode(bigcode); departmentVo1.setDepname(department1List.get(0).getBigname()); //封装小科室 List<DepartmentVo> children = new ArrayList<>(); for(Department department : department1List){ DepartmentVo departmentVo2 = new DepartmentVo(); departmentVo2.setDepcode(department.getDepcode()); departmentVo2.setDepname(department.getDepname()); //封装到List集合 children.add(departmentVo2); } //把小科室list集合放到大科室children里面 departmentVo1.setChildren(children); //放到最终result里面 result.add(departmentVo1); } return result; } //根据医院编号和科室编号查询科室名称 @Override public String getDepName(String hoscode, String depcode) { Department department = departmentRepository.getDepartmentByHoscodeAndDepcode(hoscode, depcode); if(department != null){ return department.getDepname(); } return null; } //根据医院编号和科室编号查询科室 @Override public Department getDepartment(String hoscode, String depcode) { return departmentRepository.getDepartmentByHoscodeAndDepcode(hoscode, depcode); } }
@Service public class ScheduleServiceImpl extends ServiceImpl<ScheduleMapper,Schedule> implements ScheduleService { @Autowired private ScheduleRepository scheduleRepository; @Autowired private MongoTemplate mongoTemplate; @Autowired private HospitalService hospitalService; @Autowired private DepartmentService departmentService; //上传排班 @Override public void save(Map<String, Object> parampMap) { //parampMap转换成Department对象 String parampMapString = JSONObject.toJSONString(parampMap); Schedule schedule = JSONObject.parseObject(parampMapString, Schedule.class); //根据医院编号和排班编号进行查询 Schedule scheduleExist = scheduleRepository .getScheduleByHoscodeAndHosScheduleId(schedule.getHoscode(),schedule.getHosScheduleId()); //取名采取spring DATA规范 //判断排班是否存在 if(scheduleExist != null){ //如果存在,做更改 scheduleExist.setUpdateTime(new Date()); scheduleExist.setIsDeleted(0); scheduleExist.setStatus(1); scheduleRepository.save(scheduleExist); }else{ schedule.setCreateTime(new Date()); schedule.setUpdateTime(new Date()); schedule.setIsDeleted(0); schedule.setStatus(1); scheduleRepository.save(schedule); } } //查询科室 @Override public Page<Schedule> finPageSchedule(int page, int limit, ScheduleQueryVo scheduleQueryVo) { //MongoRepository开发CRUD //创建Pageble对象,里面设置当前页和每页记录数 Pageable pageable = PageRequest.of(page - 1,limit); // 当前页从0开始,但是我们从1开始传的 //将departmentQueryVo对象转换为department对象 Schedule schedule = new Schedule(); BeanUtils.copyProperties(scheduleQueryVo,schedule); schedule.setIsDeleted(0); schedule.setStatus(1); //创建Example对象 ExampleMatcher matcher = ExampleMatcher.matching() .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) .withIgnoreCase(true); Example<Schedule> example = Example.of(schedule,matcher); Page<Schedule> all = scheduleRepository.findAll(example,pageable); return all; } //删除排班 @Override public void remove(String hoscode, String hosScheduleId) { //根据医院编号和排班编号查询相关信息 Schedule schedule = scheduleRepository.getScheduleByHoscodeAndHosScheduleId(hoscode, hosScheduleId); if(schedule != null){ scheduleRepository.deleteById(schedule.getId()); } } //根据医院编号和科室编号,查询排班规则数据 @Override public Map<String, Object> getReleSchedule(Long page, Long limit, String hoscode, String depcode) { //根据医院编号和科室编号查询 Criteria criteria = Criteria.where("hoscode").is(hoscode).and("depcode").is(depcode); //根据工作日期workdate进行分组 采用MongoTemplate方式 Aggregation agg = Aggregation.newAggregation( Aggregation.match(criteria), //匹配条件 Aggregation.group("workDate") //分组字段 .first("workDate").as("workDate") //统计号源数量 .count().as("docCount") .sum("reservedNumber").as("reservedNumber") //科室可预约数 .sum("availableNumber").as("availableNumber"), //科室剩余预约数 Aggregation.sort(Sort.Direction.DESC,"workDate"), //实现分页 Aggregation.skip((page - 1) * limit), Aggregation.limit(limit) ); //调用方法,最终执行 //BookingScheduleRuleVo封装返回数据 AggregationResults<BookingScheduleRuleVo> aggResults = mongoTemplate.aggregate(agg, Schedule.class, BookingScheduleRuleVo.class); List<BookingScheduleRuleVo> bookingScheduleRuleVoList = aggResults.getMappedResults(); //分组查询的总记录数 Aggregation totalAgg = Aggregation.newAggregation( Aggregation.match(criteria), Aggregation.group("workDate") ); AggregationResults<BookingScheduleRuleVo> totalAggResultS = mongoTemplate.aggregate(totalAgg, Schedule.class, BookingScheduleRuleVo.class); int total = totalAggResultS.getMappedResults().size(); //把workDate日期对应的星期获取 for(BookingScheduleRuleVo bookingScheduleRuleVo : bookingScheduleRuleVoList){ Date workDate = bookingScheduleRuleVo.getWorkDate(); String dayOfWeek = this.getDayOfWeek(new DateTime(workDate)); bookingScheduleRuleVo.setDayOfWeek(dayOfWeek); } //设置最终数据进行返回 Map<String,Object> result = new HashMap<>(); result.put("bookingScheduleRuleList",bookingScheduleRuleVoList); result.put("total",total); //获取医院名称 String hosName = hospitalService.getHospName(hoscode); //其他基础数据(医院名称) Map<String, String> baseMap = new HashMap<>(); baseMap.put("hosname",hosName); result.put("baseMap",baseMap); return result; } //根据医院编号、科室编号和工作日期,查询排班详情信息 @Override public List<Schedule> getDetailSchedule(String hoscode, String depcode, String workDate) { //根据参数查询mongodb,得到数据 List<Schedule> scheduleList = scheduleRepository.findScheduleByHoscodeAndDepcodeAndWorkDate(hoscode,depcode,new DateTime(workDate).toDate()); //把得到的list遍历,向其中添加医院名称、科室名称、日期对应的星期 scheduleList.stream().forEach(item -> { this.packageSchedule(item); }); return scheduleList; } //获取可预约排班数据 @Override public Map<String,Object> getBookingScheduleRule(Integer page, Integer limit, String hoscode, String depcode) { Map<String,Object> result = new HashMap<>(); //根据医院编号获取预约规则 Hospital hospital = hospitalService.getByHoscode(hoscode); if(hospital == null){ throw new YyghException(ResultCodeEnum.DATA_ERROR); } BookingRule bookingRule = hospital.getBookingRule(); //根据预约规则获取可预约数据(分页) IPage iPage = this.getListData(page,limit,bookingRule); //获取当前可预约日期 List<Date> dateList = iPage.getRecords(); //获取可预约日期里面科室的剩余数据 Criteria criteria = Criteria.where("hoscode").is(hoscode).and("depcode").is(depcode).and("workDate").in(dateList); Aggregation agg = Aggregation.newAggregation( Aggregation.match(criteria), Aggregation.group("workDate").first("workDate").as("workDate") .count().as("docCount") .sum("availableNumber").as("availableNumber") .sum("reservedNumber").as("reservedNumber") ); AggregationResults<BookingScheduleRuleVo> aggregateResult = mongoTemplate.aggregate(agg, Schedule.class, BookingScheduleRuleVo.class); List<BookingScheduleRuleVo> scheduleVoList = aggregateResult.getMappedResults(); //合并数据 map集合 key:日期 value:预约规则和剩余数量等 Map<Date, BookingScheduleRuleVo> scheduleVoMap = new HashMap<>(); if(!CollectionUtils.isEmpty(scheduleVoList)) { scheduleVoMap = scheduleVoList.stream().collect(Collectors.toMap(BookingScheduleRuleVo::getWorkDate, BookingScheduleRuleVo -> BookingScheduleRuleVo)); } //获取可预约排版规则 List<BookingScheduleRuleVo> bookingScheduleRuleVoList = new ArrayList<>(); for(int i=0, len=dateList.size(); i<len; i++) { Date date = dateList.get(i); //从map集合中根据key日期获取value值 BookingScheduleRuleVo bookingScheduleRuleVo = scheduleVoMap.get(date); if(bookingScheduleRuleVo == null){ bookingScheduleRuleVo = new BookingScheduleRuleVo(); //就诊医生人数 bookingScheduleRuleVo.setDocCount(0); //科室剩余预约数 -1表示无号 bookingScheduleRuleVo.setAvailableNumber(-1); } bookingScheduleRuleVo.setWorkDate(date); bookingScheduleRuleVo.setWorkDateMd(date); //计算当前预约日期对应的星期 String dayOfWeek = this.getDayOfWeek(new DateTime(date)); bookingScheduleRuleVo.setDayOfWeek(dayOfWeek); //最后一页最后一条记录为即将预约 状态 0:正常 1:即将放号 -1:当天已停止挂号 if(i == len-1 && page == iPage.getPages()) { bookingScheduleRuleVo.setStatus(1); } else { bookingScheduleRuleVo.setStatus(0); } //当天预约如果过了停号时间, 不能预约 if(i == 0 && page == 1) { DateTime stopTime = this.getDateTime(new Date(), bookingRule.getStopTime()); if(stopTime.isBeforeNow()) { //停止预约 bookingScheduleRuleVo.setStatus(-1); } } bookingScheduleRuleVoList.add(bookingScheduleRuleVo); } //可预约日期规则数据 result.put("bookingScheduleList", bookingScheduleRuleVoList); result.put("total", iPage.getTotal()); //其他基础数据 Map<String, String> baseMap = new HashMap<>(); //医院名称 baseMap.put("hosname", hospitalService.getHospName(hoscode)); //科室 Department department =departmentService.getDepartment(hoscode, depcode); //大科室名称 baseMap.put("bigname", department.getBigname()); //科室名称 baseMap.put("depname", department.getDepname()); //月 baseMap.put("workDateString", new DateTime().toString("yyyy年MM月")); //放号时间 baseMap.put("releaseTime", bookingRule.getReleaseTime()); //停号时间 baseMap.put("stopTime", bookingRule.getStopTime()); result.put("baseMap", baseMap); return result; } //根据排班id获取排班数据 @Override public Schedule getScheduleId(String scheduleId) { Optional<Schedule> optional = scheduleRepository.findById(scheduleId); Schedule schedule = optional.get(); return this.packageSchedule(schedule); } //根据排班id获取预约下单数据 @Override public ScheduleOrderVo getScheduleOrderVo(String scheduleId) { ScheduleOrderVo scheduleOrderVo = new ScheduleOrderVo(); Schedule schedule = this.getScheduleId(scheduleId); // Schedule schedule = baseMapper.selectById(scheduleId); if(schedule == null){ throw new YyghException(ResultCodeEnum.PARAM_ERROR); } //获取预约规则信息,从hospital中获取 Hospital hospital = hospitalService.getByHoscode(schedule.getHoscode()); if(hospital == null){ throw new YyghException(ResultCodeEnum.PARAM_ERROR); } BookingRule bookingRule = hospital.getBookingRule(); if(bookingRule == null){ throw new YyghException(ResultCodeEnum.PARAM_ERROR); } //把获取的数据设置到scheduleOrderVo中 scheduleOrderVo.setHoscode(schedule.getHoscode()); scheduleOrderVo.setHosname(hospitalService.getHospName(schedule.getHoscode())); scheduleOrderVo.setDepcode(schedule.getDepcode()); scheduleOrderVo.setDepname(departmentService.getDepName(schedule.getHoscode(), schedule.getDepcode())); scheduleOrderVo.setHosScheduleId(schedule.getHosScheduleId()); scheduleOrderVo.setAvailableNumber(schedule.getAvailableNumber()); scheduleOrderVo.setTitle(schedule.getTitle()); scheduleOrderVo.setReserveDate(schedule.getWorkDate()); scheduleOrderVo.setReserveTime(schedule.getWorkTime()); scheduleOrderVo.setAmount(schedule.getAmount()); //退号截止天数(如:就诊前一天为-1,当天为0) int quitDay = bookingRule.getQuitDay(); DateTime quitTime = this.getDateTime(new DateTime(schedule.getWorkDate()).plusDays(quitDay).toDate(), bookingRule.getQuitTime()); scheduleOrderVo.setQuitTime(quitTime.toDate()); //预约开始时间 DateTime startTime = this.getDateTime(new Date(), bookingRule.getReleaseTime()); scheduleOrderVo.setStartTime(startTime.toDate()); //预约截止时间 DateTime endTime = this.getDateTime(new DateTime().plusDays(bookingRule.getCycle()).toDate(), bookingRule.getStopTime()); scheduleOrderVo.setEndTime(endTime.toDate()); //当天停止挂号时间 DateTime stopTime = this.getDateTime(new Date(), bookingRule.getStopTime()); scheduleOrderVo.setStartTime(stopTime.toDate()); return scheduleOrderVo; } //更新排班,用于mq @Override public void update(Schedule schedule) { schedule.setUpdateTime(new Date()); scheduleRepository.save(schedule); } //根据预约规则获取可预约数据(分页) private IPage getListData(Integer page, Integer limit, BookingRule bookingRule) { //获取当天放号时间 yyyy-MM-dd HH:mm DateTime releaseTime = this.getDateTime(new Date(), bookingRule.getReleaseTime()); //获取预约周期 Integer cycle = bookingRule.getCycle(); //如果当天放号时间已过,预约周期从后一天开始计算,周期+1 if(releaseTime.isBeforeNow()){ cycle += 1; } //获取可预约所有日期,最后一天显示即将放号 List<Date> dateList = new ArrayList<>(); for(int i = 0;i < cycle;i++){ DateTime curDateTime = new DateTime().plusDays(i); String dateString = curDateTime.toString("yyyy-MM-dd"); dateList.add(new DateTime(dateString).toDate()); } //因为预约周期不同,每页最多显示7天,预约周期大于7天的要进行分页 List<Date> pageDateList = new ArrayList<>(); int start = (page-1) * limit; int end = (page -1) * limit + limit; //如果预约周期<=7,直接显示 if(dateList.size() < end){ end = dateList.size(); } for(int i = start;i < end;i++){ pageDateList.add(dateList.get(i)); } //如果>7,则进行分页 IPage<Date> iPage = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(page,7,dateList.size()); iPage.setRecords(pageDateList); return iPage; } /** * 将Date日期(yyyy-MM-dd HH:mm)转换为DateTime */ private DateTime getDateTime(Date date, String timeString) { String dateTimeString = new DateTime(date).toString("yyyy-MM-dd") + " "+ timeString; DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm").parseDateTime(dateTimeString); return dateTime; } //把医院名称、科室名称、日期对应的星期封装到排班详情 private Schedule packageSchedule(Schedule schedule) { //设置医院名称 schedule.getParam().put("hosname",hospitalService.getHospName(schedule.getHoscode())); //设置科室名称 schedule.getParam().put("depname",departmentService.getDepName(schedule.getHoscode(),schedule.getDepcode())); //设置日期对应星期 schedule.getParam().put("dayOfWeek",this.getDayOfWeek(new DateTime(schedule.getWorkDate()))); return schedule; } /** * 根据日期获取周几数据 * @param dateTime * @return */ private String getDayOfWeek(DateTime dateTime) { String dayOfWeek = ""; switch (dateTime.getDayOfWeek()) { case DateTimeConstants.SUNDAY: dayOfWeek = "周日"; break; case DateTimeConstants.MONDAY: dayOfWeek = "周一"; break; case DateTimeConstants.TUESDAY: dayOfWeek = "周二"; break; case DateTimeConstants.WEDNESDAY: dayOfWeek = "周三"; break; case DateTimeConstants.THURSDAY: dayOfWeek = "周四"; break; case DateTimeConstants.FRIDAY: dayOfWeek = "周五"; break; case DateTimeConstants.SATURDAY: dayOfWeek = "周六"; default: break; } return dayOfWeek; } }
controller:由于统一预约平台要提供接口给外面数据上传形象所以这里弄个api供给外部使用
@RestController @RequestMapping("/api/hosp") public class ApiController { @Autowired private HospitalService hospitalService; @Autowired private HospitalSetService hospitalSetService; @Autowired private DepartmentService departmentService; @Autowired private ScheduleService scheduleService; //上传医院接口 @PostMapping("saveHospital") public Result saveHosp(HttpServletRequest request){ //获取医院传递过来的信息 Map<String, String[]> parameterMap = request.getParameterMap(); //为避免后面遍历,将map中的String[]转换成Object Map<String, Object> parampMap = HttpRequestHelper.switchMap(parameterMap); //核验签名是否一致 //1.获取医院系统传递过来的签名 String hospSign = (String) parampMap.get("sign"); //2.根据传递过来的医院编码,查询数据库,查询签名 String hoscode = (String) parampMap.get("hoscode"); String signKey = hospitalSetService.getSignKey(hoscode); //3.把查询出来的签名进行MD5加密 String signKeyMD5 = MD5.encrypt(signKey); //4.判断签名是否一致 if(!hospSign.equals(signKeyMD5)){ throw new YyghException(ResultCodeEnum.SIGN_ERROR); } //图片数据采取base64工具类传输,在传输过程中“+”转换为了“ ”,因此我们要转换回来 String logoData = (String) parampMap.get("logoData"); logoData = logoData.replace(" ","+"); parampMap.put("logoData",logoData); //调用service的方法 hospitalService.save(parampMap); return Result.ok(); } //查询医院接口 @PostMapping("hospital/show") public Result getHospital(HttpServletRequest request){ //获取医院传递过来的信息 Map<String, String[]> parameterMap = request.getParameterMap(); //为避免后面遍历,将map中的String[]转换成Object Map<String, Object> parampMap = HttpRequestHelper.switchMap(parameterMap); //获取传递过来的医院编号 String hoscode = (String) parampMap.get("hoscode"); //签名校验 String hospSign = (String) parampMap.get("sign"); String signKey = hospitalSetService.getSignKey(hoscode); String signKeyMD5 = MD5.encrypt(signKey); if(!hospSign.equals(signKeyMD5)){ throw new YyghException(ResultCodeEnum.SIGN_ERROR); } //调用service方法 Hospital hospital = hospitalService.getByHoscode(hoscode); return Result.ok(hospital); } //上传科室接口 @PostMapping("saveDepartment") public Result saveDepartment(HttpServletRequest request){ //获取传递过来的科室信息 Map<String, String[]> parameterMap = request.getParameterMap(); Map<String, Object> parampMap = HttpRequestHelper.switchMap(parameterMap); //核验签名是否一致 String hospSign = (String) parampMap.get("sign"); String hoscode = (String) parampMap.get("hoscode"); String signKey = hospitalSetService.getSignKey(hoscode); String signKeyMD5 = MD5.encrypt(signKey); if(!hospSign.equals(signKeyMD5)){ throw new YyghException(ResultCodeEnum.SIGN_ERROR); } //调用service方法 departmentService.save(parampMap); return Result.ok(); } //科室查询接口 @PostMapping("department/list") public Result findDepartment(HttpServletRequest request){ //获取传递过来的科室信息 Map<String, String[]> parameterMap = request.getParameterMap(); Map<String, Object> parampMap = HttpRequestHelper.switchMap(parameterMap); //医院编号 String hoscode = (String) parampMap.get("hoscode"); //当前页 int page = Integer.parseInt((String) parampMap.get("page")); if(StringUtils.isEmpty(page)){ page = 1; } //每页显示记录数 int limit = Integer.parseInt((String) parampMap.get("limit")); if(StringUtils.isEmpty(limit)){ limit = 1; } //签名校验 String hospSign = (String) parampMap.get("sign"); String signKey = hospitalSetService.getSignKey(hoscode); String signKeyMD5 = MD5.encrypt(signKey); if(!hospSign.equals(signKeyMD5)){ throw new YyghException(ResultCodeEnum.SIGN_ERROR); } //调用service查询 //查询条件的值封装到departmentQueryVo中 DepartmentQueryVo departmentQueryVo = new DepartmentQueryVo(); departmentQueryVo.setHoscode(hoscode); Page<Department> pageModel = departmentService.finPageDepartment(page,limit,departmentQueryVo); return Result.ok(pageModel); } //删除科室接口 @PostMapping("department/remove") public Result removeDepartment(HttpServletRequest request){ //获取传递过来的科室信息 Map<String, String[]> parameterMap = request.getParameterMap(); Map<String, Object> parampMap = HttpRequestHelper.switchMap(parameterMap); //获取医院编号和科室编号 String hoscode = (String) parampMap.get("hoscode"); String depcode = (String) parampMap.get("depcode"); //签名校验 String hospSign = (String) parampMap.get("sign"); String signKey = hospitalSetService.getSignKey(hoscode); String signKeyMD5 = MD5.encrypt(signKey); if(!hospSign.equals(signKeyMD5)){ throw new YyghException(ResultCodeEnum.SIGN_ERROR); } departmentService.remove(hoscode,depcode); return Result.ok(); } //上传排班 @PostMapping("saveSchedule") public Result saveSchedule(HttpServletRequest request){ //获取传递过来的科室信息 Map<String, String[]> parameterMap = request.getParameterMap(); Map<String, Object> parampMap = HttpRequestHelper.switchMap(parameterMap); //签名校验 String hospSign = (String) parampMap.get("sign"); String hoscode = (String) parampMap.get("hoscode"); String signKey = hospitalSetService.getSignKey(hoscode); String signKeyMD5 = MD5.encrypt(signKey); if(!hospSign.equals(signKeyMD5)){ throw new YyghException(ResultCodeEnum.SIGN_ERROR); } //调用service方法 scheduleService.save(parampMap); return Result.ok(); } //查询排班 @PostMapping("schedule/list") public Result findSchedule(HttpServletRequest request) { //获取传递过来的科室信息 Map<String, String[]> parameterMap = request.getParameterMap(); Map<String, Object> parampMap = HttpRequestHelper.switchMap(parameterMap); //医院编号 String hoscode = (String) parampMap.get("hoscode"); //科室编号 String depcode = (String) parampMap.get("depcode"); //当前页 int page = Integer.parseInt((String) parampMap.get("page")); if (StringUtils.isEmpty(page)) { page = 1; } //每页显示记录数 int limit = Integer.parseInt((String) parampMap.get("limit")); if (StringUtils.isEmpty(limit)) { limit = 1; } //签名校验 String hospSign = (String) parampMap.get("sign"); String signKey = hospitalSetService.getSignKey(hoscode); String signKeyMD5 = MD5.encrypt(signKey); if (!hospSign.equals(signKeyMD5)) { throw new YyghException(ResultCodeEnum.SIGN_ERROR); } //调用service查询 //查询条件的值封装到departmentQueryVo中 ScheduleQueryVo scheduleQueryVo = new ScheduleQueryVo(); scheduleQueryVo.setHoscode(hoscode); scheduleQueryVo.setDepcode(depcode); Page<Schedule> pageModel = scheduleService.finPageSchedule(page, limit, scheduleQueryVo); return Result.ok(pageModel); } //删除排班 @PostMapping("schedule/remove") public Result remove(HttpServletRequest request){ //获取传递过来的科室信息 Map<String, String[]> parameterMap = request.getParameterMap(); Map<String, Object> parampMap = HttpRequestHelper.switchMap(parameterMap); //获取医院编号和排班编号 String hoscode = (String) parampMap.get("hoscode"); String hosScheduleId = (String) parampMap.get("hosScheduleId"); //签名校验 String hospSign = (String) parampMap.get("sign"); String signKey = hospitalSetService.getSignKey(hoscode); String signKeyMD5 = MD5.encrypt(signKey); if(!hospSign.equals(signKeyMD5)){ throw new YyghException(ResultCodeEnum.SIGN_ERROR); } scheduleService.remove(hoscode,hosScheduleId); return Result.ok(); } }
@Api("医院管理接口") @RestController @RequestMapping("/api/hosp/hospital") public class HospitalApiController { @Autowired private HospitalService hospitalService; @Autowired private DepartmentService departmentService; @Autowired private ScheduleService scheduleService; @Autowired private HospitalSetService hospitalSetService; //查询医院列表 @ApiOperation("查询医院列表") @GetMapping("findHospList/{page}/{limit}") public Result findHospList(@PathVariable("page") Integer page, @PathVariable("limit") Integer limit, HospitalQueryVo hospitalQueryVo){ Page<Hospital> hospitals = hospitalService.selectHospPage(page, limit, hospitalQueryVo); List<Hospital> content = hospitals.getContent(); //供前端调用 int totalPages = hospitals.getTotalPages(); //供前端调用 return Result.ok(hospitals); } //根据医院名称查询 @ApiOperation("根据医院名称查询") @GetMapping("findByHosname/{hosname}") public Result findHospList(@PathVariable("hosname") String hosname){ List<Hospital> list = hospitalService.findByHosname(hosname); //模糊查询 可能返回多个,用list接收 return Result.ok(list); } //根据医院编号获取科室列表 @ApiOperation("根据医院编号获取科室列表") @GetMapping("department/{hoscode}") public Result index(@PathVariable("hoscode") String hoscode){ List<DepartmentVo> list = departmentService.findDepTree(hoscode); return Result.ok(list); } //根据医院编号获取预约挂号详情 @ApiOperation(value = "根据医院编号获取预约挂号详情") @GetMapping("findHospDetail/{hoscode}") public Result item(@PathVariable("hoscode") String hoscode){ Map<String,Object> map = hospitalService.item(hoscode); return Result.ok(map); } //获取可预约排班数据 @ApiOperation(value = "获取可预约排班数据") @GetMapping("auth/getBookingScheduleRule/{page}/{limit}/{hoscode}/{depcode}") public Result getBookingSchedule( @ApiParam(name = "page", value = "当前页码", required = true) @PathVariable Integer page, @ApiParam(name = "limit", value = "每页记录数", required = true) @PathVariable Integer limit, @ApiParam(name = "hoscode", value = "医院code", required = true) @PathVariable String hoscode, @ApiParam(name = "depcode", value = "科室code", required = true) @PathVariable String depcode) { return Result.ok(scheduleService.getBookingScheduleRule(page, limit, hoscode, depcode)); } //获取排班具体数据 @ApiOperation(value = "获取排班具体数据") @GetMapping("auth/findScheduleList/{hoscode}/{depcode}/{workDate}") public Result findScheduleList( @ApiParam(name = "hoscode", value = "医院code", required = true) @PathVariable String hoscode, @ApiParam(name = "depcode", value = "科室code", required = true) @PathVariable String depcode, @ApiParam(name = "workDate", value = "排班日期", required = true) @PathVariable String workDate) { return Result.ok(scheduleService.getDetailSchedule(hoscode, depcode, workDate)); } //根据排班id获取排班数据 @ApiOperation(value = "根据排班id获取排班数据") @GetMapping("getSchedule/{scheduleId}") public Result getSchedule(@PathVariable("scheduleId") String scheduleId){ Schedule schedule = scheduleService.getScheduleId(scheduleId); return Result.ok(schedule); } //根据排班id获取预约下单数据 @ApiOperation(value = "根据排班id获取预约下单数据") @GetMapping("inner/getScheduleOrderVo/{scheduleId}") public ScheduleOrderVo getScheduleOrderVo(@PathVariable("scheduleId") String scheduleId) { return scheduleService.getScheduleOrderVo(scheduleId); } //获取医院签名信息 @ApiOperation(value = "获取医院签名信息") @GetMapping("inner/getSignInfoVo/{hoscode}") public SignInfoVo getSignInfoVo(@PathVariable("hoscode") String hoscode) { return hospitalSetService.getSignInfoVo(hoscode); } }
上传医院、上传科室,上传排班的信息是在预约统一平台实现的接口,然后由每个医院来调用预约统一平台的接口,上床自己医院的相关信息
这里用hosp_manager来模拟医院上传医院信息
这里有个bug 你的hospital_set表必须有一条id为1的数据
上传医院信息是吧医院的json字符串解析为map 对象然后通过地址保存在mongodb 数据库中
JSONObject respone = HttpRequestHelper.sendRequest(paramMap,this.getApiUrl()+"/api/hosp/saveHospital")
注意这里api 地址是service_hosp里面的端口然后service_hosp实现这里controller 的/api/hosp/saveHospital
service
import com.wang.yygh.model.hosp.Hospital; import com.wang.yygh.vo.hosp.HospitalQueryVo; import org.springframework.data.domain.Page; import java.util.List; import java.util.Map; /** * @author wangyihui * @create 2021-11-11 18:16 */ public interface HospitalService { //上传医院接口 void save(Map<String, Object> parapMap); //实现根据医院编号查询 Hospital getByHoscode(String hoscode); //医院列表(条件查询分页) Page<Hospital> selectHospPage(Integer page, Integer limit, HospitalQueryVo hospitalQueryVo); //更新医院的上限状态 void updateStatus(String id, Integer status); //查询医院详情 Map<String, Object> getHospById(String id); //获取医院名称 String getHospName(String hoscode); //根据医院名称查询 List<Hospital> findByHosname(String hosname); //根据医院编号获取预约挂号详情 Map<String, Object> item(String hoscode); }
service impl
@Service public class HospitalSevriceImpl implements HospitalService { @Autowired private HospitalRepository hospitalRepository; @Autowired private DictFeignClient dictFeignClient; @Override public void save(Map<String, Object> parapMap) { //把参数的map集合转换成对象Hospital,方便操作 String mapString = JSONObject.toJSONString(parapMap); //先把map转换成字符串 Hospital hospital = JSONObject.parseObject(mapString, Hospital.class); // 把字符串转换成Hospital对象 //判断是否存在相同数据 String hoscode = hospital.getHoscode(); Hospital hospitalExist = hospitalRepository.getHospitalByHoscode(hoscode); //如果存在,进行修改 if(hospitalExist != null){ hospital.setStatus(hospitalExist.getStatus()); hospital.setCreateTime(hospitalExist.getCreateTime()); hospital.setUpdateTime(new Date()); hospital.setIsDeleted(0); hospitalRepository.save(hospital); }else{ //如果不存在,进行添加 hospital.setStatus(0); hospital.setCreateTime(new Date()); hospital.setUpdateTime(new Date()); hospital.setIsDeleted(0); hospitalRepository.save(hospital); } } //实现根据医院编号查询 @Override public Hospital getByHoscode(String hoscode) { Hospital hospital = hospitalRepository.getHospitalByHoscode(hoscode); return hospital; } //医院列表(条件查询分页) @Override public Page<Hospital> selectHospPage(Integer page, Integer limit, HospitalQueryVo hospitalQueryVo) { //创建pageable对象 Pageable pageable = PageRequest.of(page - 1,limit); //创建条件匹配器 ExampleMatcher matcher = ExampleMatcher.matching() .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) .withIgnoreCase(true); //hospitalSetQueryVo转换成hospital对象 Hospital hospital = new Hospital(); BeanUtils.copyProperties(hospitalQueryVo,hospital); //创建Example对象 Example<Hospital> example = Example.of(hospital,matcher); //调用方法实现查询 Page<Hospital> pages = hospitalRepository.findAll(example, pageable); //查询到所有医院集合并遍历,然后获取到医院等级信息 //采用流的方式 pages.getContent().stream().forEach(item -> { this.setHospitalHosType(item); }); return pages; } //更新医院的上线状态 @Override public void updateStatus(String id, Integer status) { //根据id查询医院信息 Hospital hospital = hospitalRepository.findById(id).get(); hospital.setStatus(status); hospital.setUpdateTime(new Date()); hospitalRepository.save(hospital); } //查询医院详情 @Override public Map<String, Object> getHospById(String id) { Map<String, Object> result = new HashMap<>(); //根据id查询医院信息并将等级信息也封装进去 Hospital hospital = this.setHospitalHosType(hospitalRepository.findById(id).get()); result.put("hospital",hospital); //单独处理更直观 result.put("bookingRule", hospital.getBookingRule()); //不需要重复返回 hospital.setBookingRule(null); return result; } //获取医院名称 @Override public String getHospName(String hoscode) { Hospital hospital = hospitalRepository.getHospitalByHoscode(hoscode); if(hospital != null){ return hospital.getHosname(); } return null; } //根据医院名称查询 @Override public List<Hospital> findByHosname(String hosname) { List<Hospital> list = hospitalRepository.findHospitalByHosnameLike(hosname); return list; } //根据医院编号获取预约挂号详情 @Override public Map<String, Object> item(String hoscode) { Map<String, Object> result = new HashMap<>(); //医院详情 Hospital hospital = this.setHospitalHosType(this.getByHoscode(hoscode)); result.put("hospital", hospital); //预约规则 result.put("bookingRule", hospital.getBookingRule()); //不需要重复返回 hospital.setBookingRule(null); return result; } //获取查询到的医院集合,遍历进行医院等级封装 private Hospital setHospitalHosType(Hospital hospital) { //根据dictCode和value获取医院等级名称 String hostypeString = dictFeignClient.getName("Hostype", hospital.getHostype()); //查询省,市,地区 String provinceString = dictFeignClient.getName(hospital.getProvinceCode()); String cityString = dictFeignClient.getName(hospital.getCityCode()); String districtString = dictFeignClient.getName(hospital.getDistrictCode()); hospital.getParam().put("hostypeString",hostypeString); hospital.getParam().put("fullAddress",provinceString + cityString + districtString); return hospital; } }
controller
@RestController @RequestMapping("/api/hosp") public class ApiController { @Autowired private HospitalService hospitalService; @Autowired private HospitalSetService hospitalSetService; @Autowired private DepartmentService departmentService; @Autowired private ScheduleService scheduleService; //上传医院接口 @PostMapping("saveHospital") public Result saveHosp(HttpServletRequest request){ //获取医院传递过来的信息 Map<String, String[]> parameterMap = request.getParameterMap(); //为避免后面遍历,将map中的String[]转换成Object Map<String, Object> parampMap = HttpRequestHelper.switchMap(parameterMap); //核验签名是否一致 //1.获取医院系统传递过来的签名 String hospSign = (String) parampMap.get("sign"); //2.根据传递过来的医院编码,查询数据库,查询签名 String hoscode = (String) parampMap.get("hoscode"); String signKey = hospitalSetService.getSignKey(hoscode); //3.把查询出来的签名进行MD5加密 String signKeyMD5 = MD5.encrypt(signKey); //4.判断签名是否一致 if(!hospSign.equals(signKeyMD5)){ throw new YyghException(ResultCodeEnum.SIGN_ERROR); } //图片数据采取base64工具类传输,在传输过程中“+”转换为了“ ”,因此我们要转换回来 String logoData = (String) parampMap.get("logoData"); logoData = logoData.replace(" ","+"); parampMap.put("logoData",logoData); //调用service的方法 hospitalService.save(parampMap); return Result.ok(); } //查询医院接口 @PostMapping("hospital/show") public Result getHospital(HttpServletRequest request){ //获取医院传递过来的信息 Map<String, String[]> parameterMap = request.getParameterMap(); //为避免后面遍历,将map中的String[]转换成Object Map<String, Object> parampMap = HttpRequestHelper.switchMap(parameterMap); //获取传递过来的医院编号 String hoscode = (String) parampMap.get("hoscode"); //签名校验 String hospSign = (String) parampMap.get("sign"); String signKey = hospitalSetService.getSignKey(hoscode); String signKeyMD5 = MD5.encrypt(signKey); if(!hospSign.equals(signKeyMD5)){ throw new YyghException(ResultCodeEnum.SIGN_ERROR); } //调用service方法 Hospital hospital = hospitalService.getByHoscode(hoscode); return Result.ok(hospital); } //上传科室接口 @PostMapping("saveDepartment") public Result saveDepartment(HttpServletRequest request){ //获取传递过来的科室信息 Map<String, String[]> parameterMap = request.getParameterMap(); Map<String, Object> parampMap = HttpRequestHelper.switchMap(parameterMap); //核验签名是否一致 String hospSign = (String) parampMap.get("sign"); String hoscode = (String) parampMap.get("hoscode"); String signKey = hospitalSetService.getSignKey(hoscode); String signKeyMD5 = MD5.encrypt(signKey); if(!hospSign.equals(signKeyMD5)){ throw new YyghException(ResultCodeEnum.SIGN_ERROR); } //调用service方法 departmentService.save(parampMap); return Result.ok(); } //科室查询接口 @PostMapping("department/list") public Result findDepartment(HttpServletRequest request){ //获取传递过来的科室信息 Map<String, String[]> parameterMap = request.getParameterMap(); Map<String, Object> parampMap = HttpRequestHelper.switchMap(parameterMap); //医院编号 String hoscode = (String) parampMap.get("hoscode"); //当前页 int page = Integer.parseInt((String) parampMap.get("page")); if(StringUtils.isEmpty(page)){ page = 1; } //每页显示记录数 int limit = Integer.parseInt((String) parampMap.get("limit")); if(StringUtils.isEmpty(limit)){ limit = 1; } //签名校验 String hospSign = (String) parampMap.get("sign"); String signKey = hospitalSetService.getSignKey(hoscode); String signKeyMD5 = MD5.encrypt(signKey); if(!hospSign.equals(signKeyMD5)){ throw new YyghException(ResultCodeEnum.SIGN_ERROR); } //调用service查询 //查询条件的值封装到departmentQueryVo中 DepartmentQueryVo departmentQueryVo = new DepartmentQueryVo(); departmentQueryVo.setHoscode(hoscode); Page<Department> pageModel = departmentService.finPageDepartment(page,limit,departmentQueryVo); return Result.ok(pageModel); } //删除科室接口 @PostMapping("department/remove") public Result removeDepartment(HttpServletRequest request){ //获取传递过来的科室信息 Map<String, String[]> parameterMap = request.getParameterMap(); Map<String, Object> parampMap = HttpRequestHelper.switchMap(parameterMap); //获取医院编号和科室编号 String hoscode = (String) parampMap.get("hoscode"); String depcode = (String) parampMap.get("depcode"); //签名校验 String hospSign = (String) parampMap.get("sign"); String signKey = hospitalSetService.getSignKey(hoscode); String signKeyMD5 = MD5.encrypt(signKey); if(!hospSign.equals(signKeyMD5)){ throw new YyghException(ResultCodeEnum.SIGN_ERROR); } departmentService.remove(hoscode,depcode); return Result.ok(); } //上传排班 @PostMapping("saveSchedule") public Result saveSchedule(HttpServletRequest request){ //获取传递过来的科室信息 Map<String, String[]> parameterMap = request.getParameterMap(); Map<String, Object> parampMap = HttpRequestHelper.switchMap(parameterMap); //签名校验 String hospSign = (String) parampMap.get("sign"); String hoscode = (String) parampMap.get("hoscode"); String signKey = hospitalSetService.getSignKey(hoscode); String signKeyMD5 = MD5.encrypt(signKey); if(!hospSign.equals(signKeyMD5)){ throw new YyghException(ResultCodeEnum.SIGN_ERROR); } //调用service方法 scheduleService.save(parampMap); return Result.ok(); } //查询排班 @PostMapping("schedule/list") public Result findSchedule(HttpServletRequest request) { //获取传递过来的科室信息 Map<String, String[]> parameterMap = request.getParameterMap(); Map<String, Object> parampMap = HttpRequestHelper.switchMap(parameterMap); //医院编号 String hoscode = (String) parampMap.get("hoscode"); //科室编号 String depcode = (String) parampMap.get("depcode"); //当前页 int page = Integer.parseInt((String) parampMap.get("page")); if (StringUtils.isEmpty(page)) { page = 1; } //每页显示记录数 int limit = Integer.parseInt((String) parampMap.get("limit")); if (StringUtils.isEmpty(limit)) { limit = 1; } //签名校验 String hospSign = (String) parampMap.get("sign"); String signKey = hospitalSetService.getSignKey(hoscode); String signKeyMD5 = MD5.encrypt(signKey); if (!hospSign.equals(signKeyMD5)) { throw new YyghException(ResultCodeEnum.SIGN_ERROR); } //调用service查询 //查询条件的值封装到departmentQueryVo中 ScheduleQueryVo scheduleQueryVo = new ScheduleQueryVo(); scheduleQueryVo.setHoscode(hoscode); scheduleQueryVo.setDepcode(depcode); Page<Schedule> pageModel = scheduleService.finPageSchedule(page, limit, scheduleQueryVo); return Result.ok(pageModel); } //删除排班 @PostMapping("schedule/remove") public Result remove(HttpServletRequest request){ //获取传递过来的科室信息 Map<String, String[]> parameterMap = request.getParameterMap(); Map<String, Object> parampMap = HttpRequestHelper.switchMap(parameterMap); //获取医院编号和排班编号 String hoscode = (String) parampMap.get("hoscode"); String hosScheduleId = (String) parampMap.get("hosScheduleId"); //签名校验 String hospSign = (String) parampMap.get("sign"); String signKey = hospitalSetService.getSignKey(hoscode); String signKeyMD5 = MD5.encrypt(signKey); if(!hospSign.equals(signKeyMD5)){ throw new YyghException(ResultCodeEnum.SIGN_ERROR); } scheduleService.remove(hoscode,hosScheduleId); return Result.ok(); } }
医院接口模拟系统 测试数据
{ "hoscode": "1000_0", "hosname": "北京协和医院", "hostype": "1", "provinceCode": "110000", "cityCode": "110100", "districtCode": "110102", "address": "大望路", "intro": "北京协和医院是集医疗、教学、科研于一体的大型三级甲等综合医院,是国家卫生计生委指定的全国疑难重症诊治指导中心,也是最早承担高干保健和外宾医疗任务的医院之一,以学科齐全、技术力量雄厚、特色专科突出、多学科综合优势强大享誉海内外。在2010、2011、2012、2013、2014年复旦大学医院管理研究所公布的“中国最佳医院排行榜”中连续五年名列榜首。\n\n医院建成于1921年,由洛克菲勒基金会创办。建院之初,就志在“建成亚洲最好的医学中心”。90余年来,医院形成了“严谨、求精、勤奋、奉献”的协和精神和兼容并蓄的特色文化风格,创立了“三基”、“三严”的现代医学教育理念,形成了以“教授、病案、图书馆”著称的协和“三宝”,培养造就了张孝骞、林巧稚等一代医学大师和多位中国现代医学的领军人物,并向全国输送了大批的医学管理人才,创建了当今知名的10余家大型综合及专科医院。2011年在总结90年发展经验的基础上,创新性提出了“待病人如亲人,提高病人满意度;待同事如家人,提高员工幸福感”新办院理念。\n\n目前,医院共有2个院区、总建筑面积53万平方米,在职职工4000余名、两院院士5人、临床和医技科室53个、国家级重点学科20个、国家临床重点专科29个、博士点16个、硕士点29个、国家级继续医学教育基地6个、二级学科住院医师培养基地18个、三级学科专科医师培养基地15个。开放住院床位2000余张,单日最高门诊量约1.5万人次、年出院病人约8万余人次。被评为“全国文明单位”、“全国创先争优先进基层党组织”、“全国卫生系统先进集体”、“首都卫生系统文明单位”、“最受欢迎三甲医院”,荣获全国五一劳动奖章。同时,医院还承担着支援老少边穷地区、国家重要活动和突发事件主力医疗队的重任,在2008年北京奥运工作中荣获“特别贡献奖”。\n\n90多年来,协和人以执着的医志、高尚的医德、精湛的医术和严谨的学风书写了辉煌的历史,今天的协和人正为打造“国际知名、国内一流”医院的目标而继续努力。", "route": "东院区乘车路线:106、108、110、111、116、684、685路到东单路口北;41、104快、814路到东单路口南;1、52、802路到东单路口西;20、25、37、39路到东单路口东;103、104、420、803路到新东安市场;地铁1、5号线到东单。\n西院区乘车路线:68路到辟才胡同东口;更多乘车路线详见须知。", "logoData": "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", "bookingRule": { "cycle": "10", "releaseTime": "08:30", "stopTime": "11:30", "quitDay": "-1", "quitTime": "15:30", "rule": [ "西院区预约号取号地点:西院区门诊楼一层大厅挂号窗口取号", "东院区预约号取号地点:东院区老门诊楼一层大厅挂号窗口或新门诊楼各楼层挂号/收费窗口取号" ] } }
注意这里上传的医院信息以及模拟系统和统一挂号的医院信息一致
上传科室与上传医院信息一样,先本地处理然后交割统一预约平台进行保存
@Override public boolean saveDepartment(String data) { JSONArray jsonArray = new JSONArray(); if(!data.startsWith("[")) { JSONObject jsonObject = JSONObject.parseObject(data); jsonArray.add(jsonObject); } else { jsonArray = JSONArray.parseArray(data); } for(int i=0, len=jsonArray.size(); i<len; i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); Map<String, Object> paramMap = new HashMap<>(); paramMap.put("hoscode",this.getHoscode()); paramMap.put("depcode",jsonObject.getString("depcode")); paramMap.put("depname",jsonObject.getString("depname")); paramMap.put("intro",jsonObject.getString("intro")); paramMap.put("bigcode", jsonObject.getString("bigcode")); paramMap.put("bigname",jsonObject.getString("bigname")); paramMap.put("timestamp", HttpRequestHelper.getTimestamp()); paramMap.put("sign",MD5.encrypt(this.getSignKey())); JSONObject respone = HttpRequestHelper.sendRequest(paramMap,this.getApiUrl()+"/api/hosp/saveDepartment"); System.out.println(respone.toJSONString()); if(null == respone || 200 != respone.getIntValue("code")) { throw new YyghException(respone.getString("message"), 201); } } return true; }
发送过去之前进行自定义MD5加密,预约统一挂号平台接受之后又拿出签名进行解密,然后从数据库里面进行比对如果有,则将科室保存在mongodb数据库中
map转换为科室对象,添加之前根据医院编号和科室编号查询,有就更新,没有就添加
医院的排班信息,一个科室里面有很多医生,每个医生的出诊时间都是不一样,
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。