浏览代码

添加预约亲冠疫苗接种功能。

lighter 4 年之前
父节点
当前提交
34509264aa

+ 1 - 1
pom.xml

@@ -10,7 +10,7 @@
     </parent>
     <groupId>thyyxxk</groupId>
     <artifactId>wxservice-server</artifactId>
-    <version>4.4</version>
+    <version>4.5</version>
     <name>wxservice-server</name>
     <description>server for wxservice-web</description>
 

+ 8 - 2
src/main/java/thyyxxk/wxservice_server/config/exception/GlobalExceptionHandler.java

@@ -17,9 +17,15 @@ public class GlobalExceptionHandler {
 
     @ExceptionHandler(value = MethodArgumentNotValidException.class)
     public ResultVo<String> bindException(MethodArgumentNotValidException e) {
+        String method = "未知";
+        String[] from = e.getMessage().split(".controller.");
+        if (from.length > 1) {
+            method = from[1].split("\\(")[0];
+        }
         BindingResult bindingResult = e.getBindingResult();
-        log.info("参数校验不通过:{}", Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
-        return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
+        String message = Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage();
+        log.info("请求【{}】,参数校验不通过:{}", method, message);
+        return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, message);
     }
 
     @ExceptionHandler(value = BizException.class)

+ 29 - 0
src/main/java/thyyxxk/wxservice_server/controller/CovidVaccinateAppointmentController.java

@@ -0,0 +1,29 @@
+package thyyxxk.wxservice_server.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import thyyxxk.wxservice_server.pojo.ResultVo;
+import thyyxxk.wxservice_server.pojo.covidvaccinate.VaccinatePojo;
+import thyyxxk.wxservice_server.service.CovidVaccinateAppointmentService;
+
+@RestController
+@RequestMapping("/covidVaccinateAppointment")
+public class CovidVaccinateAppointmentController {
+    private final CovidVaccinateAppointmentService service;
+
+    @Autowired
+    public CovidVaccinateAppointmentController(CovidVaccinateAppointmentService service) {
+        this.service = service;
+    }
+
+    @GetMapping("/getPatientInfoAndJobCategories")
+    public ResultVo<VaccinatePojo> getPatientInfoAndJobCategories(@RequestParam("patientId") String patientId) {
+        return service.getPatientInfoAndJobCategories(patientId);
+    }
+
+    @PostMapping("/submitVaccinateAppointment")
+    public synchronized ResultVo<String> submitVaccinateAppointment(@Validated @RequestBody VaccinatePojo param) {
+        return service.submitVaccinateAppointment(param);
+    }
+}

+ 36 - 0
src/main/java/thyyxxk/wxservice_server/dao/CovidVaccinateAppointmentDao.java

@@ -0,0 +1,36 @@
+package thyyxxk.wxservice_server.dao;
+
+import org.apache.ibatis.annotations.*;
+import thyyxxk.wxservice_server.pojo.PureCodeName;
+import thyyxxk.wxservice_server.pojo.covidvaccinate.VaccinatePojo;
+
+import java.util.Date;
+import java.util.List;
+
+@Mapper
+public interface CovidVaccinateAppointmentDao {
+
+    @Select("select top 1 name,phone,social_no from t_wechat_patient_bind where patient_id=#{patientId}")
+    VaccinatePojo selectPatientInfo(@Param("patientId") String patientId);
+
+    @Select("select id as code,name from t_covid_appointment_job_category_dict order by id")
+    List<PureCodeName> selectJobCategories();
+
+    @Update("update t_wechat_patient_bind set phone=#{phone},social_no=#{socialNo} where patient_id=#{patientId}")
+    void updatePhoneAndSocialNo(@Param("patientId") String patientId,
+                                @Param("socialNo") String socialNo,
+                                @Param("phone") String phone);
+
+    @Insert("insert into t_covid_vaccinate_appointment (patient_id, name, sex, phone, social_no, age, corp_name, " +
+            "job_category, create_datetime, execute_date) values " +
+            "(#{patientId},#{name},#{sex},#{phone},#{socialNo},#{age},#{corpName},#{jobCategory},#{createDatetime},#{executeDate})")
+    void insertNewAppointment(VaccinatePojo param);
+
+    @Select("select count(1) from t_covid_vaccinate_appointment where social_no=#{socialNo} and execute_date=#{executeDate} " +
+            "and isnull(del_flag,0)!=1")
+    int selectValidAppointment(@Param("socialNo") String socialNo,
+                               @Param("executeDate") Date executeDate);
+
+    @Select("select count(1) from t_covid_vaccinate_appointment where execute_date=#{executeDate} and isnull(del_flag,0)!=1")
+    int selectTotalCountByDate(@Param("executeDate") Date executeDate);
+}

+ 3 - 0
src/main/java/thyyxxk/wxservice_server/dao/WxApiDao.java

@@ -46,6 +46,9 @@ public interface WxApiDao {
     @Select("select * from t_wechat_pay_order where pay_status in (99, 0, 5, 6) and isnull(query_state_times,0) < 3")
     List<WxPayOrderPojo> selectOrdersForScheduleTask();
 
+    @Select("select open_id from t_wechat_patient_bind where patient_id=#{cardNo} and del_flag=0")
+    List<String> selectOpenIdByPatientId(@Param("cardNo") String cardNo);
+
     @Select("select open_id from t_wechat_patient_bind where ic_card_no=#{cardNo} and del_flag=0")
     List<String> selectOpenIdByIcCardNo(@Param("cardNo") String cardNo);
 

+ 35 - 0
src/main/java/thyyxxk/wxservice_server/pojo/covidvaccinate/VaccinatePojo.java

@@ -0,0 +1,35 @@
+package thyyxxk.wxservice_server.pojo.covidvaccinate;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+import thyyxxk.wxservice_server.pojo.PureCodeName;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+import java.util.List;
+
+@Data
+public class VaccinatePojo {
+    private String patientId;
+    @NotBlank(message = "请填写姓名!")
+    private String name;
+    private Integer sex;
+    @NotBlank(message = "请填写手机号!")
+    private String phone;
+    @NotBlank(message = "请填写身份证号!")
+    private String socialNo;
+    private Integer age;
+    @NotBlank(message = "请填写工作单位,没有工作单位请填‘无’!")
+    private String corpName;
+    @NotNull(message = "请选择工作性质,如不确定请选‘其他人员’,如无工作请选择‘家务及待业人员’")
+    private Integer jobCategory;
+    private Date createDatetime;
+    @NotNull(message = "请选择预约接种的日期!")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date executeDate;
+
+    private List<PureCodeName> jobCategories;
+}

+ 1 - 0
src/main/java/thyyxxk/wxservice_server/pojo/wxapi/PushMessageParam.java

@@ -12,4 +12,5 @@ public class PushMessageParam {
     private String cardNo;
     @NotNull(message = "消息内容不能为空。")
     private JSONObject msgContext;
+    private boolean isCardNoPatientId = false;
 }

+ 2 - 5
src/main/java/thyyxxk/wxservice_server/service/AppointmentService.java

@@ -16,10 +16,7 @@ import thyyxxk.wxservice_server.pojo.assessment.CovidPojo;
 import thyyxxk.wxservice_server.pojo.hrgresponse.SourcesRes;
 import thyyxxk.wxservice_server.pojo.hrgresponse.GhFeeRes;
 import thyyxxk.wxservice_server.pojo.hrgresponse.MzClassRes;
-import thyyxxk.wxservice_server.utils.DateUtil;
-import thyyxxk.wxservice_server.utils.PropertiesUtil;
-import thyyxxk.wxservice_server.utils.ResultVoUtil;
-import thyyxxk.wxservice_server.utils.ThmzUrls;
+import thyyxxk.wxservice_server.utils.*;
 
 import java.text.SimpleDateFormat;
 import java.util.*;
@@ -199,7 +196,7 @@ public class AppointmentService {
         if (sexSocial.getCode().equals("1") && mzClass.equals("03")) {
             return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "男性无法在妇产科挂号,请选择其他科室。");
         }
-        if (deptCode.equals("1040000") && DateUtil.getAgeBySocialNo(sexSocial.getName()) >= 18) {
+        if (deptCode.equals("1040000") && IdCardUtil.calAgeBySocialNo(sexSocial.getName()) >= 18) {
             return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "成年人无法在儿科挂号,请选择其他科室。");
         }
         CovidPojo covid = dao.validCovidAssessment(patientId);

+ 95 - 0
src/main/java/thyyxxk/wxservice_server/service/CovidVaccinateAppointmentService.java

@@ -0,0 +1,95 @@
+package thyyxxk.wxservice_server.service;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import thyyxxk.wxservice_server.config.exception.ExceptionEnum;
+import thyyxxk.wxservice_server.dao.CovidVaccinateAppointmentDao;
+import thyyxxk.wxservice_server.pojo.ResultVo;
+import thyyxxk.wxservice_server.pojo.covidvaccinate.VaccinatePojo;
+import thyyxxk.wxservice_server.pojo.wxapi.PushMessageParam;
+import thyyxxk.wxservice_server.utils.DateUtil;
+import thyyxxk.wxservice_server.utils.IdCardUtil;
+import thyyxxk.wxservice_server.utils.ResultVoUtil;
+
+import java.util.Date;
+
+@Slf4j
+@Service
+public class CovidVaccinateAppointmentService {
+    private final CovidVaccinateAppointmentDao dao;
+    private final WxApiService wxApiService;
+
+    @Autowired
+    public CovidVaccinateAppointmentService(CovidVaccinateAppointmentDao dao, WxApiService wxApiService) {
+        this.dao = dao;
+        this.wxApiService = wxApiService;
+    }
+
+    public ResultVo<VaccinatePojo> getPatientInfoAndJobCategories(String patientId) {
+        VaccinatePojo info = dao.selectPatientInfo(patientId);
+        if (null == info) {
+            info = new VaccinatePojo();
+        } else {
+            info.setPatientId(patientId);
+            String phone = info.getPhone();
+            String socialNo = info.getSocialNo();
+            if (null != phone) {
+                if (phone.length() != 11) {
+                    info.setPhone(null);
+                }
+            }
+            if (null != socialNo) {
+                if (socialNo.startsWith("K") || socialNo.length() != 18) {
+                    info.setSocialNo(null);
+                }
+            }
+        }
+        info.setJobCategories(dao.selectJobCategories());
+        return ResultVoUtil.success(info);
+    }
+
+    public ResultVo<String> submitVaccinateAppointment(VaccinatePojo param) {
+        param.setCreateDatetime(new Date());
+        int age = IdCardUtil.calAgeBySocialNo(param.getSocialNo());
+        if (age < 18 || age > 59) {
+            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "可接种的年龄区间为【18岁 - 59岁】," +
+                    "您的年龄不满足此条件,敬请谅解。");
+        }
+        param.setAge(age);
+        param.setSex(IdCardUtil.calSexByIdCard(param.getSocialNo()));
+        if (dao.selectValidAppointment(param.getSocialNo(), param.getExecuteDate()) > 0) {
+            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "您在【" +
+                    DateUtil.formatDatetime(param.getExecuteDate(), "yyyy-MM-dd") +
+                    "】已存在有效的预约,请勿重复预约。");
+        }
+        int count = dao.selectTotalCountByDate(param.getExecuteDate());
+        if (count >= 150) {
+            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "【" +
+                    DateUtil.formatDatetime(param.getExecuteDate(), "yyyy-MM-dd") +
+                    "】的预约名额已满,请选择其他预约日期。");
+        }
+        dao.insertNewAppointment(param);
+        if (null != param.getPatientId() && !param.getPatientId().trim().equals("")) {
+            dao.updatePhoneAndSocialNo(param.getPatientId(), param.getSocialNo(), param.getPhone());
+            String msgContent = "{\"touser\":\"\",\"data\":" +
+                    "{\"keyword2\":{\"color\":\"#173177\",\"value\":\"" +
+                    DateUtil.formatDatetime(param.getExecuteDate(), "yyyy-MM-dd") + "\"}," +
+                    "\"keyword1\":{\"color\":\"#173177\",\"value\":\"" + param.getName() + "\"}," +
+                    "\"keyword3\":{\"color\":\"#173177\",\"value\":\"" + (++count) + "\"}," +
+                    "\"remark\":{\"color\":\"#FF0000\",\"value\":\"感谢您的使用,祝您健康!\"}," +
+                    "\"first\":{\"color\":\"#FF0000\",\"value\":\"您已成功预约新冠疫苗接种服务。" +
+                    "请在预约日期当天凭本人身份证在【泰和医院门诊大楼五楼体检中心】接种新冠疫苗。\"}}," +
+                    "\"template_id\":\"zVSzbYLmdqq_h1IcTPSwi6X4qFm0j9aTVeLZPxR03Bs\"," +
+                    "\"url\":\"\"}";
+            PushMessageParam pojo = new PushMessageParam();
+            pojo.setCardNo(param.getPatientId());
+            pojo.setCardNoPatientId(true);
+            pojo.setMsgContext(JSONObject.parseObject(msgContent));
+            wxApiService.pushMessage(pojo);
+        }
+        log.info("预约新冠疫苗接种:{}", JSONObject.toJSONStringWithDateFormat(param, "yyyy-MM-dd HH:mm:ss"));
+        return ResultVoUtil.success("您已成功预约新冠疫苗接种服务。请在预约日期当天凭本人身份证在【泰和医院门诊大楼五楼体检中心】接种新冠疫苗。");
+    }
+}

+ 2 - 2
src/main/java/thyyxxk/wxservice_server/service/OrderCovidExamService.java

@@ -12,7 +12,7 @@ import thyyxxk.wxservice_server.pojo.covid.OrderCovidExamParam;
 import thyyxxk.wxservice_server.pojo.hrgresponse.SaveMzFeeRes;
 import thyyxxk.wxservice_server.utils.ThmzUrls;
 import thyyxxk.wxservice_server.utils.ResultVoUtil;
-import thyyxxk.wxservice_server.utils.ValidateIdCardUtil;
+import thyyxxk.wxservice_server.utils.IdCardUtil;
 
 @Slf4j
 @Service
@@ -35,7 +35,7 @@ public class OrderCovidExamService {
 
     public ResultVo<String> savePrescription(String patientId) {
         String socialNo = dao.selectSocialNo(patientId);
-        if (!ValidateIdCardUtil.isValidatedIdcard(socialNo)) {
+        if (!IdCardUtil.isValidatedIdCard(socialNo)) {
             log.info("不合法的身份证:{}", socialNo);
             return ResultVoUtil.fail(ExceptionEnum.SLIGHTLY_ERROR, "您在我院绑定的身份证号不是有效的身份证号,请重新填写。");
         }

+ 2 - 1
src/main/java/thyyxxk/wxservice_server/service/WxApiService.java

@@ -448,7 +448,8 @@ public class WxApiService {
         JSONObject content = param.getMsgContext();
         String wxUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" +
                 PropertiesUtil.getProperty("access_token");
-        List<String> openIds = dao.selectOpenIdByIcCardNo(param.getCardNo());
+        List<String> openIds = param.isCardNoPatientId() ?
+                dao.selectOpenIdByPatientId(param.getCardNo()) : dao.selectOpenIdByIcCardNo(param.getCardNo());
         if (null == openIds || openIds.isEmpty()) {
             log.info("未找到卡号【{}】的openId。", param.getCardNo());
             return;

+ 0 - 34
src/main/java/thyyxxk/wxservice_server/utils/DateUtil.java

@@ -11,38 +11,4 @@ public class DateUtil {
         SimpleDateFormat sdf = new SimpleDateFormat(pattern);
         return sdf.format(date);
     }
-
-    public static int getAgeBySocialNo(String socialNo) {
-        if (socialNo.startsWith("K") || socialNo.length() != 18) {
-            return 0;
-        }
-        String birthDay = socialNo.substring(6, 14);
-        String time = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
-        String yearStr = time.split("-")[0];
-        String monthStr = time.split("-")[1];
-        String dayStr = time.split("-")[2];
-        String yearBirthStr = birthDay.substring(0, 4);
-        String monthBirthStr = birthDay.substring(4, 6);
-        String dayBirthStr = birthDay.substring(6);
-        int year = Integer.parseInt(yearStr);
-        int yearBirth = Integer.parseInt(yearBirthStr);
-        if (year - yearBirth <= 0) {
-            return 0;
-        }
-        int age = year - yearBirth;
-        int month = Integer.parseInt(monthStr);
-        int monthBirth = Integer.parseInt(monthBirthStr);
-        if (month - monthBirth > 0) {
-            return age;
-        }
-        if (month - monthBirth < 0) {
-            return --age;
-        }
-        int day = Integer.parseInt(dayStr);
-        int dayBirth = Integer.parseInt(dayBirthStr);
-        if (day - dayBirth >= 0) {
-            return age;
-        }
-        return --age;
-    }
 }

+ 61 - 19
src/main/java/thyyxxk/wxservice_server/utils/ValidateIdCardUtil.java → src/main/java/thyyxxk/wxservice_server/utils/IdCardUtil.java

@@ -5,7 +5,7 @@ import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Date;
 
-public class ValidateIdCardUtil {
+public class IdCardUtil {
 
     // 每位加权因子
     private static final int[] power = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
@@ -13,28 +13,28 @@ public class ValidateIdCardUtil {
     /**
      * 验证所有的身份证的合法性
      */
-    public static boolean isValidatedIdcard(String idcard) {
-        if (null == idcard || idcard.trim().equals("")) {
+    public static boolean isValidatedIdCard(String idCard) {
+        if (null == idCard || idCard.trim().equals("")) {
             return false;
         }
-        if (idcard.length() == 15) {
-            idcard = convertIdcarBy15bit(idcard);
+        if (idCard.length() == 15) {
+            idCard = convertIdcarBy15bit(idCard);
         }
-        if (null == idcard || idcard.trim().equals("")) {
+        if (null == idCard || idCard.trim().equals("")) {
             return false;
         }
-        return isValidate18Idcard(idcard);
+        return isValidate18IdCard(idCard);
     }
 
-    private static boolean isValidate18Idcard(String idcard) {
+    private static boolean isValidate18IdCard(String idCard) {
         // 非18位为假
-        if (idcard.length() != 18) {
+        if (idCard.length() != 18) {
             return false;
         }
         // 获取前17位
-        String idcard17 = idcard.substring(0, 17);
+        String idcard17 = idCard.substring(0, 17);
         // 获取第18位
-        String idcard18Code = idcard.substring(17, 18);
+        String idcard18Code = idCard.substring(17, 18);
         char[] c;
         String checkCode;
         // 是否都为数字
@@ -46,7 +46,7 @@ public class ValidateIdCardUtil {
 
         int[] bit;
 
-        bit = converCharToInt(c);
+        bit = convertCharToInt(c);
 
         int sum17;
 
@@ -64,15 +64,15 @@ public class ValidateIdCardUtil {
     /**
      * 将15位的身份证转成18位身份证
      */
-    private static String convertIdcarBy15bit(String idcard) {
+    private static String convertIdcarBy15bit(String idCard) {
         String idcard17;
         // 非15位身份证
-        if (idcard.length() != 15) {
+        if (idCard.length() != 15) {
             return null;
         }
-        if (isDigital(idcard)) {
+        if (isDigital(idCard)) {
             // 获取出生年月日
-            String birthday = idcard.substring(6, 12);
+            String birthday = idCard.substring(6, 12);
             Date birthdate = null;
             try {
                 birthdate = new SimpleDateFormat("yyMMdd").parse(birthday);
@@ -86,7 +86,7 @@ public class ValidateIdCardUtil {
             cday.setTime(birthdate);
             String year = String.valueOf(cday.get(Calendar.YEAR));
 
-            idcard17 = idcard.substring(0, 6) + year + idcard.substring(8);
+            idcard17 = idCard.substring(0, 6) + year + idCard.substring(8);
 
             char[] c = idcard17.toCharArray();
             String checkCode;
@@ -94,7 +94,7 @@ public class ValidateIdCardUtil {
             int[] bit;
 
             // 将字符数组转为整型数组
-            bit = converCharToInt(c);
+            bit = convertCharToInt(c);
             int sum17;
             sum17 = getPowerSum(bit);
 
@@ -186,7 +186,7 @@ public class ValidateIdCardUtil {
     /**
      * 将字符数组转为整型数组
      */
-    private static int[] converCharToInt(char[] c) throws NumberFormatException {
+    private static int[] convertCharToInt(char[] c) throws NumberFormatException {
         int[] a = new int[c.length];
         int k = 0;
         for (char temp : c) {
@@ -194,4 +194,46 @@ public class ValidateIdCardUtil {
         }
         return a;
     }
+
+    /**
+     * 根据身份证号计算年龄
+     * */
+    public static int calAgeBySocialNo(String idCard) {
+        if (idCard.startsWith("K") || idCard.length() != 18) {
+            return 0;
+        }
+        String birthDay = idCard.substring(6, 14);
+        String time = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
+        String yearStr = time.split("-")[0];
+        String monthStr = time.split("-")[1];
+        String dayStr = time.split("-")[2];
+        String yearBirthStr = birthDay.substring(0, 4);
+        String monthBirthStr = birthDay.substring(4, 6);
+        String dayBirthStr = birthDay.substring(6);
+        int year = Integer.parseInt(yearStr);
+        int yearBirth = Integer.parseInt(yearBirthStr);
+        if (year - yearBirth <= 0) {
+            return 0;
+        }
+        int age = year - yearBirth;
+        int month = Integer.parseInt(monthStr);
+        int monthBirth = Integer.parseInt(monthBirthStr);
+        if (month - monthBirth > 0) {
+            return age;
+        }
+        if (month - monthBirth < 0) {
+            return --age;
+        }
+        int day = Integer.parseInt(dayStr);
+        int dayBirth = Integer.parseInt(dayBirthStr);
+        if (day - dayBirth >= 0) {
+            return age;
+        }
+        return --age;
+    }
+
+    public static int calSexByIdCard(String idCard) {
+        String gender = idCard.substring(16, 17);
+        return Integer.parseInt(gender) % 2 == 0 ? 2 : 1;
+    }
 }