后端-数据接口-上传医院信息环境搭建及实现

后端-数据接口-上传医院信息接口环境搭建

  • 1、添加公共基础类
    • 1.1、添加基础工具类
  • 2、集成mongoDB
    • 2.1、添加依赖
    • 2.2、添加配置
  • 3、 上传医院信息基础环境搭建
    • 3.1、创建实体类
    • 3.2、创建Repository,用于使用mongoDB
    • 3.3、创建service接口及实现类
    • 3.4、创建控制层
  • 4、上传医院信息接口实现
    • 4.1、控制层
    • 4.2、业务层
    • 4.3、在HospitalRepository编写方法进行数据操作
  • 5、参数签名校验
    • 5.1、在上传医院方法中添加签名校验
  • 6、 图片base64编码
    • 6.1、 图片base64说明
    • 6.2、 图片base64工具类
    • 6.3、 上传医院接口修正
  • 7、集成测试

参考《尚医通API接口文档.docx》业务接口4.1上传医院
参考《医院接口模拟系统.docx》进行接口测试与数据上传

1、添加公共基础类

1.1、添加基础工具类

后端-数据接口-上传医院信息环境搭建及实现_第1张图片
HttpUtil:

package com.study.yygh.common.utils;

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 *
 */
@Slf4j
public final class HttpUtil {

	static final String POST = "POST";
	static final String GET = "GET";
	static final int CONN_TIMEOUT = 30000;// ms
	static final int READ_TIMEOUT = 30000;// ms

	/**
	 * post 方式发送http请求.
	 * 
	 * @param strUrl
	 * @param reqData
	 * @return
	 */
	public static byte[] doPost(String strUrl, byte[] reqData) {
		return send(strUrl, POST, reqData);
	}

	/**
	 * get方式发送http请求.
	 * 
	 * @param strUrl
	 * @return
	 */
	public static byte[] doGet(String strUrl) {
		return send(strUrl, GET, null);
	}

	/**
	 * @param strUrl
	 * @param reqmethod
	 * @param reqData
	 * @return
	 */
	public static byte[] send(String strUrl, String reqmethod, byte[] reqData) {
		try {
			URL url = new URL(strUrl);
			HttpURLConnection httpcon = (HttpURLConnection) url.openConnection();
			httpcon.setDoOutput(true);
			httpcon.setDoInput(true);
			httpcon.setUseCaches(false);
			httpcon.setInstanceFollowRedirects(true);
			httpcon.setConnectTimeout(CONN_TIMEOUT);
			httpcon.setReadTimeout(READ_TIMEOUT);
			httpcon.setRequestMethod(reqmethod);
			httpcon.connect();
			if (reqmethod.equalsIgnoreCase(POST)) {
				OutputStream os = httpcon.getOutputStream();
				os.write(reqData);
				os.flush();
				os.close();
			}
			BufferedReader in = new BufferedReader(new InputStreamReader(httpcon.getInputStream(),"utf-8"));
			String inputLine;
			StringBuilder bankXmlBuffer = new StringBuilder();
			while ((inputLine = in.readLine()) != null) {  
			    bankXmlBuffer.append(inputLine);  
			}  
			in.close();  
			httpcon.disconnect();
			return bankXmlBuffer.toString().getBytes();
		} catch (Exception ex) {
			log.error(ex.toString(), ex);
			return null;
		}
	}
	
	/**
	 * 从输入流中读取数据
	 * 
	 * @param inStream
	 * @return
	 * @throws Exception
	 */
	public static byte[] readInputStream(InputStream inStream) throws Exception {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = inStream.read(buffer)) != -1) {
			outStream.write(buffer, 0, len);
		}
		byte[] data = outStream.toByteArray();// 网页的二进制数据
		outStream.close();
		inStream.close();
		return data;
	}
}

HttpRequestHelper:

package com.study.yygh.common.helper;

import com.alibaba.fastjson.JSONObject;
import com.study.yygh.common.utils.HttpUtil;
import com.study.yygh.common.utils.MD5;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

@Slf4j
public class HttpRequestHelper {

    public static void main(String[] args) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("d", "4");
        paramMap.put("b", "2");
        paramMap.put("c", "3");
        paramMap.put("a", "1");
        paramMap.put("timestamp", getTimestamp());
        log.info(getSign(paramMap, "111111111"));
    }

    /**
     *
     * @param paramMap
     * @return
     */
    public static Map<String, Object> switchMap(Map<String, String[]> paramMap) {
        Map<String, Object> resultMap = new HashMap<>();
        for (Map.Entry<String, String[]> param : paramMap.entrySet()) {
            resultMap.put(param.getKey(), param.getValue()[0]);
        }
        return resultMap;
    }

    /**
     * 请求数据获取签名
     * @param paramMap
     * @param signKey
     * @return
     */
    public static String getSign(Map<String, Object> paramMap, String signKey) {
        if(paramMap.containsKey("sign")) {
            paramMap.remove("sign");
        }
        TreeMap<String, Object> sorted = new TreeMap<>(paramMap);
        StringBuilder str = new StringBuilder();
        for (Map.Entry<String, Object> param : sorted.entrySet()) {
            str.append(param.getValue()).append("|");
        }
        str.append(signKey);
        log.info("加密前:" + str.toString());
        String md5Str = MD5.encrypt(str.toString());
        log.info("加密后:" + md5Str);
        return md5Str;
    }

    /**
     * 签名校验
     * @param paramMap
     * @param signKey
     * @return
     */
    public static boolean isSignEquals(Map<String, Object> paramMap, String signKey) {
        String sign = (String)paramMap.get("sign");
        String md5Str = getSign(paramMap, signKey);
        if(!sign.equals(md5Str)) {
            return false;
        }
        return true;
    }

    /**
     * 获取时间戳
     * @return
     */
    public static long getTimestamp() {
        return new Date().getTime();
    }

    /**
     * 封装同步请求
     * @param paramMap
     * @param url
     * @return
     */
    public static JSONObject sendRequest(Map<String, Object> paramMap, String url){
        String result = "";
        try {
            //封装post参数
            StringBuilder postdata = new StringBuilder();
            for (Map.Entry<String, Object> param : paramMap.entrySet()) {
                postdata.append(param.getKey()).append("=")
                        .append(param.getValue()).append("&");
            }
            log.info(String.format("--> 发送请求:post data %1s", postdata));
            byte[] reqData = postdata.toString().getBytes("utf-8");
            byte[] respdata = HttpUtil.doPost(url,reqData);
            result = new String(respdata);
            log.info(String.format("--> 应答结果:result data %1s", result));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return JSONObject.parseObject(result);
    }
}

2、集成mongoDB

2.1、添加依赖

service-hosp模块pom.xml添加依赖

<!--springboot整合mongodb-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

2.2、添加配置

在application.properties文件添加配置

# mongoDB
spring.data.mongodb.uri=mongodb://127.0.0.1:27017/yygh_hosp

说明:改为自己安装mongodb的ip地址

3、 上传医院信息基础环境搭建

3.1、创建实体类

后端-数据接口-上传医院信息环境搭建及实现_第2张图片BaseMongoEntity:

package com.study.yygh.model.base;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.data.annotation.Id;
import lombok.Data;
import org.springframework.data.annotation.Transient;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Data
public class BaseMongoEntity implements Serializable {

    @ApiModelProperty(value = "id")
    @Id
    private String id;

    @ApiModelProperty(value = "创建时间")
    private Date createTime;

    @ApiModelProperty(value = "更新时间")
    private Date updateTime;

    @ApiModelProperty(value = "逻辑删除(1:已删除,0:未删除)")
    private Integer isDeleted;

    @ApiModelProperty(value = "其他参数")
    @Transient //被该注解标注的,将不会被录入到数据库中。只作为普通的javaBean属性
    private Map<String,Object> param = new HashMap<>();
}

BookingRule:

package com.study.yygh.model.hosp;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.study.yygh.model.base.BaseEntity;
import com.study.yygh.model.base.BaseMongoEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;

/**
 * 

* RegisterRule *

* * @author qy */
@Data @ApiModel(description = "预约规则") @Document("BookingRule") public class BookingRule { @ApiModelProperty(value = "预约周期") private Integer cycle; @ApiModelProperty(value = "放号时间") private String releaseTime; @ApiModelProperty(value = "停挂时间") private String stopTime; @ApiModelProperty(value = "退号截止天数(如:就诊前一天为-1,当天为0)") private Integer quitDay; @ApiModelProperty(value = "退号时间") private String quitTime; @ApiModelProperty(value = "预约规则") private List<String> rule; /** * * @param rule */ public void setRule(String rule) { if(!StringUtils.isEmpty(rule)) { this.rule = JSONArray.parseArray(rule, String.class); } } }

Hospital:

package com.study.yygh.model.hosp;

import com.alibaba.fastjson.JSONObject;
import com.study.yygh.model.base.BaseEntity;
import com.study.yygh.model.base.BaseMongoEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;

/**
 * 

* Hospital *

* * @author qy */
@Data @ApiModel(description = "Hospital") @Document("Hospital") public class Hospital extends BaseMongoEntity { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "医院编号") @Indexed(unique = true) //唯一索引 private String hoscode; @ApiModelProperty(value = "医院名称") @Indexed //普通索引 private String hosname; @ApiModelProperty(value = "医院类型") private String hostype; @ApiModelProperty(value = "省code") private String provinceCode; @ApiModelProperty(value = "市code") private String cityCode; @ApiModelProperty(value = "区code") private String districtCode; @ApiModelProperty(value = "详情地址") private String address; @ApiModelProperty(value = "医院logo") private String logoData; @ApiModelProperty(value = "医院简介") private String intro; @ApiModelProperty(value = "坐车路线") private String route; @ApiModelProperty(value = "状态 0:未上线 1:已上线") private Integer status; //预约规则 @ApiModelProperty(value = "预约规则") private BookingRule bookingRule; public void setBookingRule(String bookingRule) { this.bookingRule = JSONObject.parseObject(bookingRule, BookingRule.class); } }

3.2、创建Repository,用于使用mongoDB

后端-数据接口-上传医院信息环境搭建及实现_第3张图片

@Repository
public interface HospitalRepository extends MongoRepository<Hospital,String> {
}

3.3、创建service接口及实现类

service接口
后端-数据接口-上传医院信息环境搭建及实现_第4张图片

public interface HospitalService {
}

接口实现类:
后端-数据接口-上传医院信息环境搭建及实现_第5张图片

@Service
public class HospitalServiceImpl implements HospitalService {

    @Autowired
    private HospitalRepository hospitalRepository;
}

3.4、创建控制层

后端-数据接口-上传医院信息环境搭建及实现_第6张图片

@RestController
@RequestMapping("/api/hosp")
public class ApiController {

    @Autowired
    private HospitalService hospitalService;
}

4、上传医院信息接口实现

4.1、控制层

编写控制层方法,实现医院信息上传。
后端-数据接口-上传医院信息环境搭建及实现_第7张图片

@RestController
@RequestMapping("/api/hosp")
public class ApiController {

    @Autowired
    private HospitalService hospitalService;

    //上传医院信息
    @PostMapping("/saveHospital")
    public Result saveHospital(HttpServletRequest request){
        //获取传递过来的医院信息
        Map<String, String[]> requestMap = request.getParameterMap();
        //将Map 形式转换成Map方便后续使用
        Map<String, Object>  paramMap = HttpRequestHelper.switchMap(requestMap);
        //调用service方法
        hospitalService.save(paramMap);
        return Result.ok();
    }
}

4.2、业务层

接口:
后端-数据接口-上传医院信息环境搭建及实现_第8张图片实现类:
后端-数据接口-上传医院信息环境搭建及实现_第9张图片

@Service
public class HospitalServiceImpl implements HospitalService {

    @Autowired
    private HospitalRepository hospitalRepository;

    //上传医院信息
    @Override
    public void save(Map<String, Object> paramMap) {
        //将map集合转换成字符串
        String mapString = JSONObject.toJSONString(paramMap);
        //将字符串转成Hospital对象
        Hospital hospital = JSONObject.parseObject(mapString, Hospital.class);

        //判断MongoDB中是否存在数据
        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);
        }
        
    }
}

4.3、在HospitalRepository编写方法进行数据操作

我们只要按照spring data规范编写方法,就可以不用写相关sql。
后端-数据接口-上传医院信息环境搭建及实现_第10张图片

Spring Data提供了对mongodb数据访问的支持,我们只需要继承MongoRepository类,按照Spring Data规范就可以了。
SpringData 方法定义规范
后端-数据接口-上传医院信息环境搭建及实现_第11张图片
后端-数据接口-上传医院信息环境搭建及实现_第12张图片
注意:
1、、不是随便声明的,而需要符合一定的规范
2、 查询方法以find | read | get开头
3、 涉及条件查询时,条件的属性用条件关键字连接
4、 要注意的是:条件属性首字母需要大写
5、 支持属性的级联查询,但若当前类有符合条件的属性则优先使用,而不使用级联属性,若需要使用级联属性,则属性之间使用_强制进行连接

5、参数签名校验

5.1、在上传医院方法中添加签名校验

我们在医院设置的时候,为每个医院生成了医院编码与签名key,因此在验证签名时要根据医院编码去动态获取签名key,然后再做签名校验。

在医院信息上传接口中做医院签名信息的校验:
后端-数据接口-上传医院信息环境搭建及实现_第13张图片

//上传医院信息
@PostMapping("/saveHospital")
public Result saveHospital(HttpServletRequest request){
    //获取传递过来的医院信息
    Map<String, String[]> requestMap = request.getParameterMap();
    //将Map 形式转换成Map方便后续使用
    Map<String, Object>  paramMap = HttpRequestHelper.switchMap(requestMap);

    //1、获取医院传递过来的签名,签名进行MD5加密
    String hospSign = (String)paramMap.get("sign");

    //2、根据传递过来的医院编码,查询数据库,查询签名
    String hoscode = (String)paramMap.get("hoscode");
    String signKey = hospitalSetService.getSignKey(hoscode);

    //3、把数据库拆线呢的签名进行加密
    String signKeyMD5 = MD5.encrypt(signKey);

    //3、判断签名是否一致
    if(!hospSign.equals(signKeyMD5)){
        throw new YyghException(ResultCodeEnum.SIGN_ERROR);
    }

    //传输过程中 “+” 转换为了“ ”,因此我们要转换回来
    String logoData = (String)paramMap.get("logoData");
    logoData = logoData.replaceAll(" ","+");
    paramMap.put("logoData",logoData);
    
    //调用service方法
    hospitalService.save(paramMap);
    return Result.ok();
}

6、 图片base64编码

6.1、 图片base64说明

图片的base64编码就是可以将一张图片数据编码成一串字符串,使用该字符串代替图像地址url
在前端页面中常见的base64图片的引入方式:
后端-数据接口-上传医院信息环境搭建及实现_第14张图片

@RestController
@RequestMapping("/api/hosp")
public class ApiController {

    @Autowired
    private HospitalService hospitalService;

    @Autowired
    private HospitalSetService hospitalSetService;
    
    //上传医院信息
    @PostMapping("/saveHospital")
    public Result saveHospital(HttpServletRequest request){
        //获取传递过来的医院信息
        Map<String, String[]> requestMap = request.getParameterMap();
        //将Map 形式转换成Map方便后续使用
        Map<String, Object>  paramMap = HttpRequestHelper.switchMap(requestMap);

        //1、获取医院传递过来的签名,签名进行MD5加密
        String hospSign = (String)paramMap.get("sign");

        //2、根据传递过来的医院编码,查询数据库,查询签名
        String hoscode = (String)paramMap.get("hoscode");
        String signKey = hospitalSetService.getSignKey(hoscode);

        //3、把数据库拆线呢的签名进行加密
        String signKeyMD5 = MD5.encrypt(signKey);

        //3、判断签名是否一致
        if(!hospSign.equals(signKeyMD5)){
            throw new YyghException(ResultCodeEnum.SIGN_ERROR);
        }

        //传输过程中 “+” 转换为了“ ”,因此我们要转换回来
        String logoData = (String)paramMap.get("logoData");
        logoData = logoData.replaceAll(" ","+");
        paramMap.put("logoData",logoData);

        //调用service方法
        hospitalService.save(paramMap);
        return Result.ok();
    }
}

7、集成测试

参考《医院接口模拟系统.docx》进行接口测试与数据上传,后续不做说明,需要测试时即可使用

你可能感兴趣的:(医院挂号系统)