1、新增生成公众号二维码

2、名医馆功能新增,调整查询医生和查询号源的数据返回。
3、扫码缴费新增无数据时跳转到页面进行提示。
4、医共体患者信息同步和删除调整。
5、武定忠爱医院和景洪第三人民医院新增关注返回消息,服务号可以生成二维码,扫码后推送消息。
debug
王绍全 2 weeks ago
parent 683d29bae8
commit c692f7fef5
  1. 40
      src/main/java/com/ynxbd/common/action/ApiAction.java
  2. 1
      src/main/java/com/ynxbd/common/action/HealthCodeAction.java
  3. 6
      src/main/java/com/ynxbd/common/action/PatientAction.java
  4. 3
      src/main/java/com/ynxbd/common/bean/Doctor.java
  5. 35
      src/main/java/com/ynxbd/common/dao/PatientDao.java
  6. 104
      src/main/java/com/ynxbd/common/dao/his/HisRegisterDao.java
  7. 1
      src/main/java/com/ynxbd/common/helper/common/QRCodeHelper.java
  8. 6
      src/main/java/com/ynxbd/common/result/JsonResult.java
  9. 117
      src/main/java/com/ynxbd/common/service/GMCService.java
  10. 150
      src/main/java/com/ynxbd/common/service/PatientService.java
  11. 1
      src/main/java/com/ynxbd/common/service/RecipeService.java
  12. 1
      src/main/java/com/ynxbd/wx/config/HospConfigEnum.java
  13. 10
      src/main/java/com/ynxbd/wx/servlet/QServlet.java
  14. 1
      src/main/java/com/ynxbd/wx/servlet/WxServlet.java
  15. 138
      src/main/java/com/ynxbd/wx/utils/QRCodeUtil.java
  16. 22
      src/main/java/com/ynxbd/wx/wxfactory/WxAuthHelper.java
  17. 17
      src/main/java/com/ynxbd/wx/wxfactory/WxPassiveReplyHelper.java
  18. 7
      src/main/java/com/ynxbd/wx/wxfactory/WxPayHelper.java
  19. 32
      src/main/java/com/ynxbd/wx/wxfactory/base/auth/Client.java
  20. 20
      src/main/java/com/ynxbd/wx/wxfactory/base/auth/models/QRCodeInfo.java
  21. 2
      src/main/resources/webservice.properties
  22. 19
      src/main/resources/wx.properties

@ -12,13 +12,14 @@ import com.ynxbd.wx.config.WeChatConfig;
import com.ynxbd.wx.utils.DesEncryptHelper;
import com.ynxbd.wx.wxfactory.AesWxHelper;
import com.ynxbd.wx.wxfactory.WxCacheHelper;
import com.ynxbd.wx.wxfactory.WxFactory;
import com.ynxbd.wx.wxfactory.base.auth.models.AccessToken;
import com.ynxbd.wx.wxfactory.base.auth.models.QRCodeInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
@ -47,7 +48,7 @@ public class ApiAction extends BaseAction {
if (accessToken == null) {
return Result.error();
}
log.warn(accessToken);
System.out.println(accessToken);
accessToken = DesEncryptHelper.enCode(accessToken);
if (accessToken == null) {
@ -59,6 +60,41 @@ public class ApiAction extends BaseAction {
}
/**
*
* @return 公钥
*/
@Action("getQRCode")
public Result getQRCode(String accessToken, Integer size) {
if (accessToken == null) {
return Result.error(ResultEnum.PARAM_IS_DEFECT);
}
accessToken = DesEncryptHelper.deCode(accessToken);
if (ObjectUtils.isEmpty(accessToken)) {
return Result.error(ResultEnum.PARAM_IS_INVALID);
}
if (size == null) {
size = 430;
} else if (size == 8) { // 厘米
size = 258;
} else if (size == 12) {
size = 344;
} else if (size == 15) {
size = 430;
} else if (size == 30) {
size = 860;
} else if (size == 50) {
size = 1028;
}
QRCodeInfo qrcode = WxFactory.Base.OAuth().getQRCode(accessToken, "WX001");
if (qrcode != null && !ObjectUtils.isEmpty(qrcode.getUrl())) {
qrcode.setQrcode(QRCodeHelper.encodeToBase64(qrcode.getUrl(), size, size));
}
return Result.success(qrcode);
}
@Action("getWxJsapiTicket")
public Result getWxJsapiTicket() {
String ticket = WxCacheHelper.getJsapiTicket();

@ -237,7 +237,6 @@ public class HealthCodeAction extends BaseAction {
return Result.error(ResultEnum.PARAM_ADDRESS_ERROR);
}
String uuid = null;
if (HCodeService.isEnableHCode() && isHealthCard && healthCardId == null) { // 没有禁用电子健康卡
log.info("[电子健康卡]绑定 wechatCode={}", wechatCode);

@ -13,6 +13,7 @@ import com.ynxbd.common.result.JsonResult;
import com.ynxbd.common.result.Result;
import com.ynxbd.common.result.ResultEnum;
import com.ynxbd.common.result.ServiceException;
import com.ynxbd.common.service.GMCService;
import com.ynxbd.common.service.PatientService;
import com.ynxbd.wx.config.WeChatConfig;
import com.ynxbd.wx.wxfactory.WxCacheHelper;
@ -320,6 +321,11 @@ public class PatientAction extends BaseAction {
return Result.error(ResultEnum.PARAM_IS_DEFECT);
}
try {
if (WeChatConfig.IS_ENABLE_GMC && !WeChatConfig.IS_GMC_SERVER) { // 开启医共体 && 不是医共体主体
boolean isOK = new GMCService().unBindGmcServer(request, openid, patientId);
return Result.success(isOK);
}
Patient patient = new PatientDao().selectByOpenidAndPatientId(openid, patientId);
if (patient == null) {
log.info("[患者解绑]失败,库中不存在该患者 patientId={}", patientId);

@ -68,6 +68,9 @@ public class Doctor implements Serializable {
private Integer skillState;
// 0 显示微官网,1:显示HIS
private Integer descriptionState;
private String famousGroupCode;
private String famousGroupName;
}

@ -458,7 +458,7 @@ public class PatientDao {
*
* @return list
*/
public List<Patient> selectNoneGmcList() {
public synchronized List<Patient> selectNoneGmcList() {
if (!WeChatConfig.IS_ENABLE_GMC) {
log.warn("[医共体]功能未开启-禁止查询不是医共体的用户信息");
return new ArrayList<>();
@ -467,23 +467,40 @@ public class PatientDao {
return DataBase.select(sql, Patient.class, null);
}
public boolean updateGmcInfo(boolean hasCard, Integer id, String gmcPatientId, String hisPatientId) {
if (!hasCard) { // 无证绑定->标记为已删除
String sql = "update patientBase set deletedState= 1 where id=?";
public boolean removePatient(Integer id, String remark){
String sql = "update patientBase set deletedState=1, remark=? where id=?";
return DataBase.update(sql, ps -> {
ps.setLong(1, id);
ps.setString(1, remark);
ps.setLong(2, id);
}) > 0;
}
public boolean updateGmcInfo(boolean hasCard, Integer id, String gmcPatientId, String hisPatientId) {
if (!hasCard) { // 无证绑定->标记为已删除
return removePatient(id, "无证绑定");
}
if (ObjectUtils.isEmpty(gmcPatientId)) {
return false;
}
String sql = "update patientBase set gmcBindState= 1, patientId=?, hisPatientId=? where id=?";
int gmcBindState = WeChatConfig.IS_ENABLE_GMC && WeChatConfig.IS_GMC_SERVER ? 1 : 0; // 医共体主服务器直接标识为1,其他医院的服务器同步时为0,后续使用时同步
String sql = "update patientBase set gmcBindState=?, patientId=?, hisPatientId=? where id=?";
return DataBase.update(sql, ps -> {
ps.setInt(1, gmcBindState);
ps.setString(2, gmcPatientId);
ps.setString(3, hisPatientId);
// 条件
ps.setLong(4, id);
}) > 0;
}
public boolean updateGmcBindState(String gmcUniqueId, Integer id, String gmcPatientId) {
String sql = "update patientBase set gmcBindState= 1, gmcUniqueId=? where id=? and patientId=?";
return DataBase.update(sql, ps -> {
ps.setString(1, gmcPatientId);
ps.setString(2, hisPatientId);
ps.setString(1, gmcUniqueId);
// 条件
ps.setLong(3, id);
ps.setLong(2, id);
ps.setString(3, gmcPatientId);
}) > 0;
}
}

@ -757,6 +757,7 @@ public class HisRegisterDao {
JSONArray doctorJsonList;
for (int i = 0; i < deptJsonList.size(); i++) {
deptJson = deptJsonList.getJSONObject(i);
deptCode = ParamHelper.spaceFormat(deptJson.getString("DeptCode"));
deptName = ParamHelper.spaceFormat(deptJson.getString("DeptName"));
doctorJsonList = deptJson.getJSONArray("Doct");
@ -873,6 +874,8 @@ public class HisRegisterDao {
return dataList;
}
/**
* [分时段]根据科室code和医生code查询医生号源
*
@ -906,42 +909,88 @@ public class HisRegisterDao {
}
try {
JSONArray jsonArray = jsonResult.getJsonArray("Dept", "Doct", "TimeInterval");
JSONObject timeNode, sourceNode;
JSONArray deptJsonArr = jsonResult.getJsonArray("Dept");
if (deptJsonArr == null || deptJsonArr.isEmpty()) {
return dataList;
}
JSONObject deptJsonItem, doctJsonItem, timeJsonItem, sourceJsonItem;
JSONArray doctJsonArr, timeJsonArr, sourceJsonArr;
Register sourceItem;
JSONArray sourceArr;
BigDecimal regMoney;
String tid, tName;
for (int i = 0; i < jsonArray.size(); i++) {
timeNode = jsonArray.getJSONObject(i);
tid = timeNode.getString("TID");
tid = tid == null ? null : tid.trim();
tName = timeNode.getString("TName");
tName = tName == null ? null : tName.trim();
String sourceDeptCode, sourceDeptName, sourceDoctName, sourceDoctCode, sourceTId, sourceTName;
for (int deptIndex = 0; deptIndex < deptJsonArr.size(); deptIndex++) {
deptJsonItem = deptJsonArr.getJSONObject(deptIndex);
if (deptJsonItem == null) {
continue;
}
sourceDeptCode = ParamHelper.spaceFormat(deptJsonItem.getString("DeptCode"));
sourceDeptName = ParamHelper.spaceFormat(deptJsonItem.getString("DeptName"));
sourceArr = timeNode.getJSONArray("Source");
for (int k = 0; k < sourceArr.size(); k++) {
sourceNode = sourceArr.getJSONObject(k);
regMoney = sourceNode.getBigDecimal("RegistPrice");
doctJsonArr = deptJsonItem.getJSONArray("Doct");
if (doctJsonArr == null || doctJsonArr.isEmpty()) {
continue;
}
for (int doctIndex = 0; doctIndex < doctJsonArr.size(); doctIndex++) {
doctJsonItem = doctJsonArr.getJSONObject(doctIndex);
if (doctJsonItem == null) {
continue;
}
sourceDoctCode = ParamHelper.spaceFormat(doctJsonItem.getString("DoctCode"));
sourceDoctName = ParamHelper.spaceFormat(doctJsonItem.getString("DoctName"));
timeJsonArr = doctJsonItem.getJSONArray("TimeInterval");
if (timeJsonArr == null || timeJsonArr.isEmpty()) {
continue;
}
for (int timeIndex = 0; timeIndex < timeJsonArr.size(); timeIndex++) {
timeJsonItem = timeJsonArr.getJSONObject(timeIndex);
if (timeJsonItem == null) {
continue;
}
sourceTId = ParamHelper.spaceFormat(timeJsonItem.getString("TID"));
sourceTName = ParamHelper.spaceFormat(timeJsonItem.getString("TName"));
sourceJsonArr = timeJsonItem.getJSONArray("Source");
if (sourceJsonArr == null || sourceJsonArr.isEmpty()) {
continue;
}
for (int sourceIndex = 0; sourceIndex < sourceJsonArr.size(); sourceIndex++) {
sourceJsonItem = sourceJsonArr.getJSONObject(sourceIndex);
if (sourceJsonItem == null) {
continue;
}
regMoney = sourceJsonItem.getBigDecimal("RegistPrice");
if (regMoney == null) {
regMoney = BigDecimal.ZERO;
}
sourceItem = new Register();
sourceItem.setTid(tid);
sourceItem.setTName(tName);
sourceItem.setDeptCode(sourceDeptCode);
sourceItem.setDeptName(sourceDeptName);
sourceItem.setDoctCode(sourceDoctCode);
sourceItem.setDoctName(sourceDoctName);
sourceItem.setTid(sourceTId);
sourceItem.setTName(sourceTName);
sourceItem.setRegFee(regMoney);
// -----------------------
sourceItem.setSourceId(sourceNode.getString("SourceId"));
sourceItem.setQueueNum(sourceNode.getString("QueueNumber"));
sourceItem.setBegTime(sourceNode.getString("BegTime"));
sourceItem.setEndTime(sourceNode.getString("EndTime"));
sourceItem.setRegCode(sourceNode.getString("RegistCode"));
sourceItem.setRegName(sourceNode.getString("RegistName"));
sourceItem.setRegDate(sourceNode.getString("RegistDate"));
sourceItem.setAddress(sourceNode.getString("ClinicAddress"));
sourceItem.setAllowReg(sourceNode.getInteger("AllowOnline"));
sourceItem.setIsUsed(sourceNode.getInteger("IsUsed"));
sourceItem.setSourceId(sourceJsonItem.getString("SourceId"));
sourceItem.setQueueNum(sourceJsonItem.getString("QueueNumber"));
sourceItem.setBegTime(sourceJsonItem.getString("BegTime"));
sourceItem.setEndTime(sourceJsonItem.getString("EndTime"));
sourceItem.setRegCode(sourceJsonItem.getString("RegistCode"));
sourceItem.setRegName(sourceJsonItem.getString("RegistName"));
sourceItem.setRegDate(sourceJsonItem.getString("RegistDate"));
sourceItem.setAddress(sourceJsonItem.getString("ClinicAddress"));
sourceItem.setAllowReg(sourceJsonItem.getInteger("AllowOnline"));
sourceItem.setIsUsed(sourceJsonItem.getInteger("IsUsed"));
sourceItem.setTotalFee(regMoney);
sourceItem.setPayMoney(regMoney);
@ -949,6 +998,8 @@ public class HisRegisterDao {
dataList.add(sourceItem);
}
}
}
}
} catch (Exception e) {
ErrorHelper.println(e);
}
@ -1180,5 +1231,4 @@ public class HisRegisterDao {
return HisHelper.getJsonResult(HisEnum.TPP_QR_Reg, params);
}
}

@ -94,7 +94,6 @@ public class QRCodeHelper {
//输出二维码图片流
ImageIO.write(image, "png", outputStream);
return "data:image/png;base64," + Base64.encodeBase64String(outputStream.toByteArray());
} catch (Exception e) {
e.printStackTrace();
}

@ -10,6 +10,7 @@ import com.ynxbd.common.helper.common.ErrorHelper;
import com.ynxbd.common.helper.common.JsonHelper;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
@ -116,7 +117,7 @@ public class JsonResult {
*/
public static JsonResult xmlToBean(String xml, JsonResultEnum jsonResultEnum, String... ignoreParams) {
try {
if (xml == null || "".equals(xml)) {
if (ObjectUtils.isEmpty(xml)) {
log.info("【{}】 response xml is null", jsonResultEnum.getSYS());
return null; // 不能判断是否为调用超时
}
@ -528,6 +529,9 @@ public class JsonResult {
}
// public static void main(String[] args) {
// String test = "<?xml version=\"1.0\" encoding=\"GB2312\"?><Response><TransactionCode>7009</TransactionCode><ResponseCode>0</ResponseCode><ResponseMessage>成功</ResponseMessage><Items><Item><MZNum>3605059</MZNum><PatientId>297520</PatientId><PatientName>余艳聪</PatientName><DeptCode>0312</DeptCode><DeptName>心病科</DeptName><DoctCode>0721</DoctCode><DoctName>李曰富</DoctName><ScheduleDate>2024-12-10</ScheduleDate><BegTime>14:42:00</BegTime><EndTime>14:45:00</EndTime><RegistDate>2024-12-10 12:36:20</RegistDate></Item><Item><MZNum>3605213</MZNum><PatientId>411671</PatientId><PatientName>杨丽麟</PatientName><DeptCode>2101</DeptCode><DeptName>精神科(神志病科)</DeptName><DoctCode>0970</DoctCode><DoctName>付丽娜</DoctName><ScheduleDate>2024-12-10</ScheduleDate><BegTime>15:57:00</BegTime><EndTime>16:00:00</EndTime><RegistDate>2024-12-10 14:55:11</RegistDate></Item><Item><MZNum>3605216</MZNum><PatientId>821300</PatientId><PatientName>段贵成</PatientName><DeptCode>1201</DeptCode><DeptName>口腔科</DeptName><DoctCode></DoctCode><DoctName>任意医师</DoctName><ScheduleDate>2024-12-10</ScheduleDate><BegTime>14:51:00</BegTime><EndTime>14:58:00</EndTime><RegistDate>2024-12-10 14:56:29</RegistDate></Item><Item><MZNum>3605336</MZNum><PatientId>679882</PatientId><PatientName>段李情</PatientName><DeptCode>1201</DeptCode><DeptName>口腔科</DeptName><DoctCode>1599</DoctCode><DoctName>唐德芝</DoctName><ScheduleDate>2024-12-10</ScheduleDate><BegTime>15:42:00</BegTime><EndTime>15:45:00</EndTime><RegistDate>2024-12-10 15:42:31</RegistDate></Item><Item><MZNum>3605339</MZNum><PatientId>509469</PatientId><PatientName>李进才</PatientName><DeptCode>0403</DeptCode><DeptName>骨伤科</DeptName><DoctCode>1272</DoctCode><DoctName>沈自启</DoctName><ScheduleDate>2024-12-10</ScheduleDate><BegTime>17:27:00</BegTime><EndTime>17:30:00</EndTime><RegistDate>2024-12-10 15:44:00</RegistDate></Item><Item><MZNum>3605381</MZNum><PatientId>372552</PatientId><PatientName>思安翠</PatientName><DeptCode>0403</DeptCode><DeptName>骨伤科</DeptName><DoctCode>1272</DoctCode><DoctName>沈自启</DoctName><ScheduleDate>2024-12-10</ScheduleDate><BegTime>16:03:00</BegTime><EndTime>16:06:00</EndTime><RegistDate>2024-12-10 16:00:41</RegistDate></Item><Item><MZNum>3605454</MZNum><PatientId>811419</PatientId><PatientName>胡铭城</PatientName><DeptCode>1102</DeptCode><DeptName>眼耳鼻喉科</DeptName><DoctCode>1254</DoctCode><DoctName>安兴有</DoctName><ScheduleDate>2024-12-10</ScheduleDate><BegTime>16:33:26</BegTime><EndTime>16:36:00</EndTime><RegistDate>2024-12-10 16:35:04</RegistDate></Item></Items></Response>";
// JsonResult jsonResult = JsonResult.xmlToBean(test,JsonResultEnum.SYS_HIS);

@ -1,7 +1,10 @@
package com.ynxbd.common.service;
import com.alibaba.fastjson.JSONObject;
import com.ynxbd.common.bean.GMCUser;
import com.ynxbd.common.bean.Patient;
import com.ynxbd.common.bean.enums.HCardTypeEnum;
import com.ynxbd.common.dao.GMCUserDao;
import com.ynxbd.common.dao.PatientDao;
import com.ynxbd.common.helper.common.JsonHelper;
import com.ynxbd.common.helper.http.OkHttpHelper;
@ -17,7 +20,6 @@ import org.apache.commons.lang3.ObjectUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Slf4j
public class GMCService {
@ -38,10 +40,10 @@ public class GMCService {
if (!WeChatConfig.IS_ENABLE_GMC || WeChatConfig.IS_GMC_SERVER) { // 医共体开关未开启 || 是主服务器
return new ArrayList<>();
}
String enGmcOpenId = AesWxHelper.encode(gmcOpenId);
long begTime = System.currentTimeMillis();
JsonResult jsonResult = postFormGMC(request, "/patient/queryPatientList", params -> {
params.put("openId", AesWxHelper.encode(gmcOpenId));
params.put("openId", enGmcOpenId);
params.put("hospAppId", AesWxHelper.encode(WeChatConfig.GMC_APP_ID));
}, null);
if (!jsonResult.success()) {
@ -51,10 +53,11 @@ public class GMCService {
}
List<Patient> gmcPatients = jsonResult.getDataMapList(Patient.class, "data");
List<Integer> removeIds = new ArrayList<>(); // 需删除用户ids
List<Patient> addList = new ArrayList<>(); // 需添加用户
List<Integer> removeIds = new ArrayList<>(); // 需删除用户ids
List<Patient> dbPatients = new PatientDao().selectListByToken(wxOpenId, unionId);
for (Patient item : gmcPatients) {
item.setId(null);
item.setOpenid(wxOpenId);
@ -64,6 +67,7 @@ public class GMCService {
Patient findDBItem = dbPatients.isEmpty() ? null : dbPatients.stream().filter(o -> (
!ObjectUtils.isEmpty(o.getPatientId()) && o.getPatientId().equals(item.getPatientId())
&& !ObjectUtils.isEmpty(o.getIdCardNo()) && o.getIdCardNo().equals(item.getIdCardNo())
)).findFirst().orElse(null);
if (findDBItem == null) { // 需新增
@ -78,9 +82,39 @@ public class GMCService {
}
for (Patient item : dbPatients) {
Patient findItem = gmcPatients.stream().filter(o -> (!ObjectUtils.isEmpty(o.getPatientId()) && o.getPatientId().equals(item.getPatientId()))).findFirst().orElse(null);
if (findItem == null) { // 本地数据多余->移除
Patient findItem = gmcPatients.stream().filter(o -> (
!ObjectUtils.isEmpty(o.getPatientId()) && o.getPatientId().equals(item.getPatientId()))
&& !ObjectUtils.isEmpty(o.getIdCardNo()) && o.getIdCardNo().equals(item.getIdCardNo())
).findFirst().orElse(null);
if (findItem == null) { // 本地数据多余->发送给主体医院=>进行绑定
Integer gmcBindState = item.getGmcBindState();
if (gmcBindState == null || gmcBindState == 0) { // 未与主体医院交互校验过
System.out.println("[医共体]向主体医院同步数据...");
System.out.println(JsonHelper.toJsonString(item));
item.setEnGmcOpenId(enGmcOpenId);
Patient patient = new GMCService().bindGmcServer(request, item);
if (patient == null) {
log.error("[医共体]同步用户数据,返回数据为空 id:{}", item.getId());
continue;
}
String gmcPatientId = patient.getPatientId();
String gmcUniqueId = patient.getGmcUniqueId();
if (ObjectUtils.isEmpty(gmcUniqueId) || ObjectUtils.isEmpty(gmcPatientId)) {
log.error("[医共体]同步用户数据,返回唯一键为空 id:{}", item.getId());
continue;
}
if (!gmcPatientId.equals(item.getPatientId())) {
removeIds.add(item.getId());
continue;
}
if (new PatientDao().updateGmcBindState(gmcUniqueId, item.getId(), item.getPatientId())) {
log.error("[医共体]同步用户数据,修改医共体绑定状态失败 id:{}", item.getId());
item.setGmcUniqueId(gmcUniqueId);
gmcPatients.add(item);
}
} else { // 已校验过=>多余数据=>移除
removeIds.add(item.getId());
}
}
}
@ -105,15 +139,26 @@ public class GMCService {
* @param request request
* @param bindInfo 绑定信息
*/
public Map<String, Object> bindGmcServer(HttpServletRequest request, Patient bindInfo) throws ServiceException {
public Patient bindGmcServer(HttpServletRequest request, Patient bindInfo) throws ServiceException {
String enGmcOpenId = bindInfo.getEnGmcOpenId(); // 只有子服务器有主服务器的openId
String gmcOpenId = AesWxHelper.decode(enGmcOpenId);
log.info("[转发]enGmcOpenId={}, gmcOpenId={}", enGmcOpenId, gmcOpenId);
log.info("[医共体绑定-转发]enGmcOpenId={}, gmcOpenId={}", enGmcOpenId, gmcOpenId);
if (ObjectUtils.isEmpty(gmcOpenId)) {
throw new ServiceException("医共体非主体公众号ID参数异常");
}
String idCardNo = bindInfo.getIdCardNo();
if (ObjectUtils.isEmpty(idCardNo)) {
throw new ServiceException("[医共体绑定]证件号缺失");
}
String areaCode = bindInfo.getAreaCode();
if (ObjectUtils.isEmpty(areaCode)) {
areaCode = idCardNo.substring(0, 6);
}
String finalAreaCode = areaCode;
JsonResult jsonResult = postFormGMC(request, "/healthCode/bind", params -> {
params.put("isAreaCode", false);
params.put("isFace", false);
@ -121,7 +166,7 @@ public class GMCService {
params.put("openid", gmcOpenId); // 主服务器的openId
params.put("address", bindInfo.getAddress());
params.put("areaCode", bindInfo.getAreaCode());
params.put("areaCode", finalAreaCode);
params.put("areaAddress", bindInfo.getAreaAddress());
params.put("tel", bindInfo.getTel());
params.put("sex", bindInfo.getSex());
@ -136,10 +181,60 @@ public class GMCService {
if (!jsonResult.success()) {
throw new ServiceException(jsonResult.getMessage());
}
log.info("[医供体]绑定转发 resp={}", JsonHelper.toJsonString(jsonResult));
return jsonResult.getDataMap();
JSONObject resp = jsonResult.dataMapGetNodeToJsonObj();
log.info("[医供体]绑定转发 resp={}", JsonHelper.toJsonString(resp));
if (resp == null) {
return null;
}
String gmcUniqueId = resp.getString("gmcUniqueId");
String enPatientId = resp.getString("enPatientId");
String enOpenId = resp.getString("enOpenId");
if (ObjectUtils.isEmpty(gmcUniqueId) || ObjectUtils.isEmpty(enPatientId) || ObjectUtils.isEmpty(enOpenId)) {
return null;
}
String patientId = AesWxHelper.decode(enPatientId);
if (ObjectUtils.isEmpty(patientId)) {
log.error("[医共体]主体绑定,返回patientId解密失败");
return null;
}
Patient patient = new Patient();
patient.setPatientId(patientId);
patient.setEnPatientId(enPatientId);
patient.setEnOpenId(enOpenId);
patient.setGmcUniqueId(gmcUniqueId);
return patient;
}
/**
* 医共体解绑
*
* @param request request
*/
public boolean unBindGmcServer(HttpServletRequest request, String openId, String patientId) throws ServiceException {
log.info("[医共体解绑-转发]openId={}, patientId={}", openId, patientId);
if (ObjectUtils.isEmpty(openId) || ObjectUtils.isEmpty(patientId)) {
throw new ServiceException("[医共体解绑-转发]参数缺失");
}
GMCUser gmcUser = new GMCUserDao().selectByOpenId(openId);
if (gmcUser == null) {
throw new ServiceException("[医共体解绑-转发]未匹配到用户id");
}
String gmcOpenId = gmcUser.getGmcOpenId();
JsonResult jsonResult = postFormGMC(request, "/patient/unBind", params -> {
params.put("openid", gmcOpenId);
params.put("patientId", patientId);
params.put("hospAppId", WeChatConfig.APP_ID);
}, null);
if (!jsonResult.success()) {
throw new ServiceException(jsonResult.getMessage());
}
return true;
}
public static JsonResult postForm(String url, OkHttpHelper.MapParams params, OkHttpHelper.Header header) {
return OkHttpHelper.postForm(url, params, header, JsonResultEnum.SYS_COMMON);

@ -20,6 +20,9 @@ import org.apache.commons.lang3.ObjectUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
@ -132,13 +135,13 @@ public class PatientService {
if (WeChatConfig.IS_ENABLE_GMC && !WeChatConfig.IS_GMC_SERVER) { // 开启医共体 && 不是医共体主体
try {
Map<String, Object> dataMap = new GMCService().bindGmcServer(request, bindInfo);
if (dataMap == null) {
return Result.error("[医共体]绑定返回空map");
Patient patient = new GMCService().bindGmcServer(request, bindInfo);
if (patient == null) {
return Result.error("[医共体]绑定返回数据为空");
}
WxCacheHelper.removeUser(openid);
Map<String, Object> map = new HashMap<>();
map.put("gmcUniqueId", dataMap.get("gmcUniqueId"));
map.put("gmcUniqueId", patient.getGmcUniqueId());
map.put("enOpenId", AesWxHelper.encode(openid));
return Result.success(map);
} catch (Exception e) {
@ -185,7 +188,7 @@ public class PatientService {
bindInfo.setHisTransNo(hisTransNo);
// bindInfo.setGmcHospId(gmcHospId);
// 判断是否已有数据
try {
List<Patient> dbPatients = patientDao.selectByOpenIdAndCardNo(openid, idCardNo);
if (dbPatients.isEmpty()) { // 数据库没有-->添加
@ -223,6 +226,7 @@ public class PatientService {
Map<String, Object> map = new HashMap<>();
map.put("gmcUniqueId", bindInfo.getGmcUniqueId());
map.put("enOpenId", AesWxHelper.encode(openid));
map.put("enPatientId", AesWxHelper.encode(patientId));
return Result.success(map);
}
@ -437,19 +441,15 @@ public class PatientService {
* [维护]替换患者id为医共体id
*
*/
public void wh_gmc_patient_ids() {
List<Patient> patients = new PatientDao().selectNoneGmcList();
public void replaceHisGmcId(List<Patient> patients) {
if (patients.isEmpty()) {
return;
}
log.warn("[医共体]患者id替换开始......共:[{}]条", patients.size());
PatientDao patientDao = new PatientDao();
int errNum = 0;
int index = 0;
log.warn("[医共体][线程]患者id替换开始......共:[{}]条", patients.size());
PatientDao patientDao = new PatientDao();
HisPatientDao hisPatientDao = new HisPatientDao();
for (Patient patient : patients) {
index = index + 1;
log.warn("[医共体替换]index={}", index);
if (HCardTypeEnum.NO_CARD.WX_CODE.equals(patient.getCardType()) || ObjectUtils.isEmpty(patient.getIdCardNo())) { // 无证绑定
continue;
}
@ -461,17 +461,104 @@ public class PatientService {
boolean hasCard = !HCardTypeEnum.NO_CARD.WX_CODE.equals(patient.getCardType()) && !ObjectUtils.isEmpty(patient.getIdCardNo());
if (hasCard) {
gmcPatientId = new HisPatientDao().getGMCPatientId(hisPatientId); // 医共体患者id
gmcPatientId = hisPatientDao.getGMCPatientId(hisPatientId); // 医共体患者id
if (ObjectUtils.isEmpty(gmcPatientId)) {
patientDao.removePatient(id, "医共体");
log.warn("[医共体id]替换失败 hisPatientId={}", hisPatientId);
continue;
}
}
boolean isUpdate = patientDao.updateGmcInfo(hasCard, id, gmcPatientId, hisPatientId);
if (!isUpdate) {
errNum = errNum + 1;
log.warn("[医共体]患者id替换更新数据失败 id={}, hisPatientId={}", id, hisPatientId);
}
}
log.warn("[医共体]患者id替换 共:[{}]条, 失败:[{}]条", patients.size(), errNum);
}
/**
* [维护][多线程]替换患者id为医共体id
*
*/
public synchronized void wh_gmc_patient_ids() {
if (!WeChatConfig.IS_ENABLE_GMC) {
log.info("[医共体]数据同步开关未开启...");
return;
}
List<Patient> patients = new PatientDao().selectNoneGmcList();
if (patients.isEmpty()) {
return;
}
log.warn("[医共体]患者id替换开始......共:[{}]条", patients.size());
int threadCount = 22; // 线程数量
if (patients.size() <= threadCount) {
replaceHisGmcId(patients);
return;
}
List<List<Patient>> partitions = splitList(patients, threadCount);
// 2. 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
// 3. 每个线程处理一份数据
for (List<Patient> part : partitions) {
executor.submit(() -> replaceHisGmcId(part));
}
try {
// 关闭线程池并等待所有线程执行完毕
executor.shutdown();
boolean isResult = executor.awaitTermination(120, TimeUnit.MINUTES);// 最多等待120分钟
System.out.println(isResult);
} catch (InterruptedException e) {
log.error("线程等待异常", e);
Thread.currentThread().interrupt();
}
}
// ==================== 工具方法:把大集合平均分成 N 份 ====================
private <T> List<List<T>> splitList(List<T> list, int partitionSize) {
List<List<T>> partitions = new ArrayList<>();
int size = list.size();
int chunk = size / partitionSize;
int remainder = size % partitionSize;
int fromIndex = 0;
for (int i = 0; i < partitionSize; i++) {
int toIndex = fromIndex + chunk + (remainder-- > 0 ? 1 : 0);
if (fromIndex < toIndex) {
partitions.add(list.subList(fromIndex, toIndex));
}
fromIndex = toIndex;
}
return partitions;
}
// /**
// * [维护]替换患者id为医共体id
// *
// */
// public void wh_gmc_bind() {
// List<Patient> patients = new PatientDao().selectNoneGmcList();
// log.warn("[医共体]患者id替换开始......共:[{}]条", patients.size());
// PatientDao patientDao = new PatientDao();
//
// int errNum = 0;
// for (Patient patient : patients) {
// String gmcPatientId = null; // 医共体患者id
//
// Integer id = patient.getId();
// String hisPatientId = patient.getPatientId(); // 旧id
// Patient hisPatient;
// if (!HCardTypeEnum.NO_CARD.WX_CODE.equals(patient.getCardType())) { // 不为无证绑定
// try {
// hisPatient = new HisPatientDao().getGMCPatientId(false, patient);
// hisPatient = new HisPatientDao().bind(false, patient);
// if (hisPatient == null || ObjectUtils.isEmpty(hisPatient.getPatientId())) {
// log.warn("[医共体]患者id替换-调用HIS绑定接口异常,未返回患者信息 id={}, hisPatientId={}", id, hisPatientId);
// continue;
@ -481,15 +568,30 @@ public class PatientService {
// log.warn(e.getMessage());
// continue;
// }
// }
//
// boolean isUpdate = patientDao.updateGmcInfo(patient.getId(), patient.getIdCardNo(), patient.getCardType(), gmcPatientId, hisPatientId);
// if (!isUpdate) {
// errNum = errNum + 1;
// log.warn("[医共体]患者id替换更新数据失败 id={}, hisPatientId={}", id, hisPatientId);
// }
//
// log.warn("[医共体]患者id替换 共:[{}]条, 失败:[{}]条", patients.size(), errNum);
// }
// }
boolean isUpdate = patientDao.updateGmcInfo(hasCard ,id, gmcPatientId, hisPatientId);
if (!isUpdate) {
errNum = errNum + 1;
log.warn("[医共体]患者id替换更新数据失败 id={}, hisPatientId={}", id, hisPatientId);
}
}
log.warn("[医共体]患者id替换 共:[{}]条, 失败:[{}]条", patients.size(), errNum);
}
// Patient hisPatient;
// if (!HCardTypeEnum.NO_CARD.WX_CODE.equals(patient.getCardType())) { // 不为无证绑定
// try {
// hisPatient = new HisPatientDao().getGMCPatientId(false, patient);
// if (hisPatient == null || ObjectUtils.isEmpty(hisPatient.getPatientId())) {
// log.warn("[医共体]患者id替换-调用HIS绑定接口异常,未返回患者信息 id={}, hisPatientId={}", id, hisPatientId);
// continue;
// }
// gmcPatientId = hisPatient.getPatientId();
// } catch (Exception e) {
// log.warn(e.getMessage());
// continue;
// }
// }
}

@ -469,7 +469,6 @@ public class RecipeService {
QuickDrugDispenseHelper.quickDrug(drugInfo, invoiceTransNo);
}
// 更新支付信息
if (!recipeDao.updateHisPaidByTradeNo(tradeNo, hisTransNo, invoiceTransNo)) {
log.info("[处方]更新HIS返回数据失败 outTradeNo={}, tradeNo={}, recipeId={}", outTradeNo, tradeNo, recipeId);

@ -14,6 +14,7 @@ public enum HospConfigEnum {
巍山县人民医院("巍山县人民医院", "wx1e30610a28d189a8", null, null),
芒市人民医院("芒市人民医院", "wxca97aaeb3c40c0d0", null, null),
玉龙县人民医院("玉龙县人民医院", "wx1f1e9d29f9b44c36", null, null),
景洪第三人民医院("景洪第三人民医院", "wxd19b076c0695589b", null, null),
;
public final String NAME;

@ -59,17 +59,20 @@ public class QServlet extends HttpServlet {
log.info("{} [patientId={} {}]多张处方扫码请求,开始解析...", merchantEnum.NAME, patientId, hasTreatNum ? (", treatNum=" + groupTreatNum) : "");
if (ObjectUtils.isEmpty(patientId) && ObjectUtils.isEmpty(cardNo)) {
log.info("[支付] 多张扫码请求 patientId is null and idCardNo is null");
log.info("[支付]多张处方扫码请求 patientId is null and idCardNo is null");
if (MerchantEnum.WX.equals(merchantEnum)) {
response.sendRedirect(WeChatConfig.getWebReqURL() + "pay-qr-recipe.html");
}
return;
}
// 新版体检缴费patientId赋值为0
// 新版体检缴费patientId赋值为0
if (!ObjectUtils.isEmpty(cardNo) && ObjectUtils.isEmpty(patientId)) {
patientId = "0"; //patientId 赋值0
}
if (patientId.contains(".") || patientId.contains("/") || patientId.contains("http")) {
log.info("[支付] 多张扫码请求 参数无效");
log.info("[支付]多张处方扫码请求 参数无效");
return;
}
cardNo = ObjectUtils.isEmpty(cardNo) ? "" : Base64Helper.decode(cardNo);
@ -80,7 +83,6 @@ public class QServlet extends HttpServlet {
groupTreatNum = hasTreatNum ? ("&treatNum=" + groupTreatNum) : "";
String params = "?p=" + patientId + "&enp=" + AesWxHelper.encode(patientId) + cardNo + groupTreatNum;
if (MerchantEnum.WX.equals(merchantEnum)) {
response.sendRedirect(WeChatConfig.getWebReqURL() + "pay-qr-recipe.html" + params);
}

@ -1,5 +1,6 @@
package com.ynxbd.wx.servlet;
import com.alibaba.fastjson.JSON;
import com.ynxbd.common.result.Result;
import com.ynxbd.wx.config.WeChatConfig;
import com.ynxbd.wx.config.WxEventEnum;

@ -1,138 +0,0 @@
package com.ynxbd.wx.utils;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Map;
/**
* @author 张剑峰
* @date 2018年6月4日下午12:38:39
* @version v1.0.0
* @Copyright: 2018云南新八达科技有限公司 All rights reserved.
*/
public class QRCodeUtil {
private static final int BLACK = 0xFF000000;
private static final int WHITE = 0xFFFFFFFF;
private static final int GREEN = 0xFFAAAAAA;
private static BufferedImage toBufferedImage(BitMatrix matrix) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
}
}
return image;
}
private static void writeToFile(BitMatrix matrix, String format, File file) throws IOException {
BufferedImage image = toBufferedImage(matrix);
if (!ImageIO.write(image, format, file)) {
throw new IOException("Could not write an image of format " + format + " to " + file);
}
}
/**
* 将内容contents生成长宽均为width的图片图片路径由imgPath指定
*/
public static File getQRCodeImage(String contents, int size, String imgPath) {
return getQRCodeImage(contents, size, size, imgPath);
}
/**
* 将内容contents生成长为width宽为width的图片图片路径由imgPath指定
*/
public static File getQRCodeImage(String contents, int width, int height, String imgPath) {
try {
Map<EncodeHintType, Object> hints = new Hashtable<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
hints.put(EncodeHintType.CHARACTER_SET, "UTF8");
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints);
File imageFile = new File(imgPath);
writeToFile(bitMatrix, "png", imageFile);
return imageFile;
} catch (Exception e) {
return null;
}
}
/**
* 将内容contents生成长为width宽为width的图片图片路径由imgPath指定
*/
public static String getQRCodeImgBase64(String contents, int width, int height) {
String resultBase64 = null;
try {
Map<EncodeHintType, Object> hints = new Hashtable<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
hints.put(EncodeHintType.CHARACTER_SET, "UTF8");
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints);
// File imageFile = new File(imgPath);
// writeToFile(bitMatrix, "svg", imageFile);
return resultBase64;
} catch (Exception e) {
return null;
}
}
public static void main(String[] args) {
// String product_id = "999981XBD100XBD200XBD0.01XBD1";
// // product_id = MD5Util.MD5Encode(product_id, "UTF-8");
// String sec = Long.toString(System.currentTimeMillis());
// String timeStamp = Long.toString(System.currentTimeMillis() / 1000);
// SimpleDateFormat formatter = new SimpleDateFormat("yyyy年-MM月dd日-HH时mm分ss秒");
// Date date = new Date(System.currentTimeMillis());
// String s = formatter.format(date);
// String nonceStr = Long.toString(System.currentTimeMillis());
// Map<String, String> packageParams = new HashMap<>();
// packageParams.put("appid", WeChatConfig.getAppId());
// packageParams.put("mch_id", WeChatConfig.getMchId());
// packageParams.put("product_id", product_id);
// packageParams.put("time_stamp", timeStamp);
// packageParams.put("nonce_str", nonceStr);
// String sign = SignatureUtil.generateSign(packageParams, WeChatConfig.getMchKey());
// String url = "weixin://wxpay/bizpayurl?sign=" + sign + "&appid=" +
// WxConfig.getInstance().getAppId()
// + "&mch_id=" + WxConfig.getInstance().getMchId() + "&product_id=" +
// product_id + "&time_stamp="
// + timeStamp + "&nonce_str=" + nonceStr;
//// String url = "http://lhxrmyy1.natapp1.cc/wx/q?p=10000005";
// // String url =
// // "weixin:/pay/bizpayurl?sign=38128468EEFC56C19EDEAD077E8BD38B&appid=wx940ec0975be0daf4&mchid=1354195702&product_id=123815|814994|2074382|0.90|1&time_stamp=1533309475&nonce_str=1533309475421&";
//
// // String[] array = product_id.split("\\|");
// // String patientId = array[0];
// // String mzNum = array[1];
// // String recipeId = array[2];
// // String payMoney = array[3];
// // if (patientId.equals("") || mzNum.equals("") || recipeId.equals("")
// // || payMoney.equals("")) {
// // System.out.println("扫码支付:参数中有空值,不允许支付!product_id=" + product_id);
// // return;
// // }
getQRCodeImage("http://www.wsxrmyy.cn/wx/qr-questionnaire.html", 300, "C:\\Users\\Administrator\\Desktop\\qr_questionnaire");
}
}

@ -61,7 +61,7 @@ public class WxAuthHelper {
log.info("[认证授权-解码] authSessionId={}, param={}", authSessionId, param);
SnsOath2AccessToken snsToken = WxFactory.Base.OAuth().oauth2AccessToken(WeChatConfig.APP_ID, WeChatConfig.APP_SECRET, code);
log.info("[认证授权]信息 snsToken={}", JsonHelper.toJsonString(snsToken));
// log.info("[认证授权]信息 snsToken={}", JsonHelper.toJsonString(snsToken));
if (snsToken != null) {
String openid = snsToken.getOpenid();
String unionId = snsToken.getUnionid();
@ -147,7 +147,7 @@ public class WxAuthHelper {
AuthTokenData authTokenData = new AuthTokenData();
String cacheTokenOpenId = authTokenData.decodeToken(token, WeChatConfig.APP_ID);
log.warn("[授权is_auth] has_token={}, state={}, isUserInfo={}, deState={}", !ObjectUtils.isEmpty(token), state, isUserInfo, deState);
log.info("[授权is_auth] has_token={}, state={}, isUserInfo={}, deState={}", !ObjectUtils.isEmpty(token), state, isUserInfo, deState);
String authSessionId = null;
if (WeChatConfig.IS_ENABLE_GMC) { // 开启医共体开关
@ -206,8 +206,6 @@ public class WxAuthHelper {
String gmcOpenId = sessionGmcOpenId == null ? null : sessionGmcOpenId.toString();
log.info("[向主服务器请求认证] gmcOpenId={}", gmcOpenId);
if (gmcOpenId == null) {
GMCUser gmcUser = new GMCUserService().queryInfoByOpenId(openId);
if (gmcUser != null) {
@ -331,12 +329,12 @@ public class WxAuthHelper {
/**
* 从缓存获取数据
*
* @param request
* @param openId
* @param state
* @param isUserInfo
* @param authSessionId
* @return
* @param request request
* @param openId openId
* @param state state
* @param isUserInfo isUserInfo
* @param authSessionId authSessionId
* @return AuthResultData
*/
public static AuthResultData getCacheUserData(HttpServletRequest request, String openId, String state, String isUserInfo, String authSessionId) throws ServiceException {
log.info("[微信认证]openid={}", openId);
@ -408,7 +406,7 @@ public class WxAuthHelper {
? WeChatConfig.getBackupURL(isHttpsWithProxy(request))
: WeChatConfig.getBaseURL(WeChatConfig.HAS_HTTPS_BY_BASE_URL || isHttpsWithProxy(request));
log.warn("[微信认证][getAuthUrl] baseURL={}, serverName={}, state={}, authState={}", baseURL, serverName, state, authState);
// log.info("[微信认证][getAuthUrl] baseURL={}, serverName={}, state={}, authState={}", baseURL, serverName, state, authState);
state = OAUTH_URL + baseURL +
"wx_auth/" + api +
"?p=" + state + // 发起认证的网页链接
@ -417,7 +415,7 @@ public class WxAuthHelper {
"&forcePopup=true" +
"&state=" + authState + // state位置固定
"#wechat_redirect";
log.warn("[认证授权链接]{}", state);
// log.info("[认证授权链接]{}", state);
return Base64Helper.encode(state);
}

@ -157,6 +157,9 @@ public class WxPassiveReplyHelper {
case 武定忠爱医院:
return WxPassiveReplyHelper.武定忠爱医院(response, reqContent, msgType, fromUserName, toUserName, eventKey, event);
case 景洪第三人民医院:
return WxPassiveReplyHelper.景洪第三人民医院(response, reqContent, msgType, fromUserName, toUserName, eventKey, event);
case 华坪县人民医院:
return WxPassiveReplyHelper.华坪县人民医院(response, reqContent, msgType, fromUserName, toUserName, eventKey, event);
@ -177,7 +180,7 @@ public class WxPassiveReplyHelper {
private static Boolean 武定忠爱医院(HttpServletResponse response, String reqContent, String msgType, String fromUserName, String toUserName, String eventKey, String event) {
if (WxEventEnum.MSG_TYPE_EVENT.CODE.equals(msgType)) {
if (WxEventEnum.EVENT_SUBSCRIBE.CODE.equals(event)) {
if (WxEventEnum.EVENT_SUBSCRIBE.CODE.equals(event) || WxEventEnum.EVENT_SCAN.CODE.equals(event)) { // 关注 || 扫描接口生成公众号的二维码
String content = "欢迎关注武定忠爱医院!" +
"\n\uD83D\uDD17 <a href='" + WeChatConfig.getWebReqURL() + "reg-today.html" + "'>今日挂号</a>" +
"\n\uD83D\uDD17 <a href='" + WeChatConfig.getWebReqURL() + "reg-reserve.html" + "'>预约挂号</a>";
@ -187,6 +190,18 @@ public class WxPassiveReplyHelper {
return true;
}
private static Boolean 景洪第三人民医院(HttpServletResponse response, String reqContent, String msgType, String fromUserName, String toUserName, String eventKey, String event) {
if (WxEventEnum.MSG_TYPE_EVENT.CODE.equals(msgType)) {
if (WxEventEnum.EVENT_SUBSCRIBE.CODE.equals(event) || WxEventEnum.EVENT_SCAN.CODE.equals(event)) {
String content = "首次预约心理治疗/咨询,或六从上未进行心理治疗/咨询的来访请务必先挂号“心理门诊”。" +
"\n\uD83D\uDD17 <a href='" + WeChatConfig.getWebReqURL() + "reg-today.html" + "'>今日挂号</a>" +
"\n\uD83D\uDD17 <a href='" + WeChatConfig.getWebReqURL() + "reg-reserve.html" + "'>预约挂号</a>";
WxFactory.Base.PassiveMsg().createXmlTextMsg(response, fromUserName, toUserName, content);
}
}
return true;
}
public static boolean 芒市人民医院(HttpServletResponse response, String content, String msgType, String fromUserName, String toUserName, String eventKey, String event) {

@ -266,17 +266,20 @@ public class WxPayHelper {
try {
refundResult = PayMchAPI.secapiPayRefund(refund, WeChatConfig.MCH_KEY);
if (refundResult == null) {
log.error("【微信】退款返回为空");
throw new Exception(ResultEnum.INTERFACE_WX_INVOKE_ERROR.message);
}
} catch (Exception e) {
log.error("【微信】退接口调用异常 outTradeNo={}", outTradeNo);
log.error("【微信】退费证书过期或接口调用异常 outTradeNo={}", outTradeNo);
order.setErrorMsg(ResultEnum.INTERFACE_WX_INVOKE_ERROR.message);
order.setRefundResult("退费证书过期或接口调用异常");
return order;
}
String code = refundResult.getReturn_code();
String message = refundResult.getReturn_msg();
String resultCode = refundResult.getResult_code();
if (!SUCCESS.equals(resultCode)) {
String errCode = refundResult.getErr_code();
String errCodeDesc = refundResult.getErr_code_des();
@ -351,7 +354,7 @@ public class WxPayHelper {
long endTime = System.currentTimeMillis(); // 结束时间
long takeTime = endTime - begTime;
if (takeTime > 6000) {
log.warn("【微信】[扫码盒子]下单耗时超过6s [{}]", outTradeNo);
log.warn("【微信】[扫码盒子]下单耗时超过6s 耗时[{}][{}]", (takeTime + "ms"), outTradeNo);
}
log.info("【微信】[扫码盒子]下单完成-耗时:[{}] [{}]", (takeTime + "ms"), outTradeNo);

@ -1,16 +1,17 @@
package com.ynxbd.wx.wxfactory.base.auth;
import com.alibaba.fastjson.JSONObject;
import com.ynxbd.common.helper.common.JsonHelper;
import com.ynxbd.common.helper.http.OkHttpHelper;
import com.ynxbd.wx.wxfactory.WxCacheHelper;
import com.ynxbd.wx.wxfactory.base.auth.models.RespAccessToken;
import com.ynxbd.wx.wxfactory.base.auth.models.RespJsapiTicket;
import com.ynxbd.wx.wxfactory.base.auth.models.SnsOath2AccessToken;
import com.ynxbd.wx.wxfactory.base.auth.models.SnsUserInfo;
import com.ynxbd.wx.wxfactory.base.auth.models.*;
import com.ynxbd.wx.wxfactory.utils.EmojiHelper;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@NoArgsConstructor
public class Client {
@ -111,6 +112,29 @@ public class Client {
}
/**
* 获取微信token
*
* @return accessToken
*/
public synchronized QRCodeInfo getQRCode(String token, String scene_str) {
Map<String, Object> action_info = new HashMap<>();
Map<String, Object> scene = new HashMap<>();
scene.put("scene_str", scene_str); // 字符串类型,长度限制为1到64
action_info.put("scene", scene);
System.out.println(JsonHelper.toJsonString(action_info));
String respJson = OkHttpHelper.postJsonStr("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + token, params -> {
params.put("action_name", "QR_LIMIT_STR_SCENE"); // 二维码类型:QR_SCENE(临时整型)/QR_STR_SCENE(临时字符串)/QR_LIMIT_SCENE(永久整型)/QR_LIMIT_STR_SCENE(永久字符串)
params.put("action_info", action_info);
}, null);
log.info("[创建公众号二维码]{}", respJson);
if(respJson == null) {
return null;
}
return JsonHelper.parseObject(respJson, QRCodeInfo.class);
}
// public static String getSnsToken() {
// if (ACCESS_TOKEN_CACHE == null) {
// createAccessTokenCache();

@ -0,0 +1,20 @@
package com.ynxbd.wx.wxfactory.base.auth.models;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
@Getter
@Setter
@ToString
@NoArgsConstructor
@Slf4j
public class QRCodeInfo {
private String ticket;
private String url;
private String qrcode;
}

@ -1 +1 @@
# \u5F00\u542F\u5904\u65B9\u9884\u7ED3\u7B97\uFF08\u7B2C2\u5F00\u5173\uFF09\uFF08\u6CE8\u610F\u8BE5\u914D\u7F6E\u9700\u8054\u7CFBhis\u5F00\u53D1\u8005\u786E\u8BA4\u652F\u6301\u624D\u80FD\u5F00\u542F\uFF0C\u5426\u5219\u5B58\u5728\u98CE\u9669\uFF01\uFF09 his.is_recipe_prepay=false # \u672C\u5730 #his.url=127.0.0.1:8888 # HIS\u662F\u5426\u5F00\u542F\u652F\u4ED8\u5B9D\u5206\u5F00\u5BF9\u8D26 his.is_ali_mer=false # \u662F\u5426\u5F3A\u5236\u6253\u5370webservice\u7684xml\u8FD4\u56DE\u6570\u636E his.is_log_resp=true # \u662F\u5426\u4F20\u9012openid\u7ED9his\u63A8\u9001\u6D88\u606F his.is_push_msg=false #------------------------------- # \u6D4B\u8BD5\u73AF\u5883 his.dev_url=200.200.200.105:8888 # \u533B\u4FDD=========================== # \u65E7\u914D\u7F6E his.md_url=127.0.0.1:7777 # \u5FAE\u4FE1\u533B\u4FDD his.wx_med_url=10.20.10.7:7885 # \u652F\u4ED8\u5B9D\u533B\u4FDD his.ali_med_url=10.20.10.7:7885 # \u516C\u53F8\u6D4B\u8BD5 #his.url=192.168.12.10:8888 # \u77F3\u6797\u6D4B\u8BD5 #his.url=200.200.200.105:8888 # \u6D4B\u8BD5============================================================ # \u5FB7\u5B8F\u4E2D\u533B #his.url=200.200.200.60:8888 # \u7EA2\u6CB3\u5DDE\u533B\u9662 #his.url=10.20.10.6:8888 # \u8292\u5E02\u5987\u5E7C #his.url=192.168.11.7:8888 # \u5B81\u8497\u5987\u5E7C #his.url=172.19.3.15:8888 # \u516C\u53F8\u6D4B\u8BD5 #his.url=192.168.12.39:8888 # \u516C\u53F8\u6D4B\u8BD5 #his.url=192.168.12.10:8888 # \u7EA2\u6CB3 #his.url=10.20.10.6:8888 # \u7EA2\u6CB3\u533B\u4FDD #his.url=10.20.10.6:8888 #his.url=192.168.12.10:8888 #his.md_url=192.168.1.128:7885 #his.dev_url=10.20.10.6:9988 # \u6C38\u80DC #his.url=200.200.200.20:8888 # \u5FB7\u5B8F\u4E2D\u533B #his.url=200.200.200.60:8888 # \u534E\u576A #his.url=192.168.1.115:8888 # \u8499\u81EA\u4E2D\u533B #his.url=192.168.0.228:8888 # \u7389\u9F99 his.url=192.168.0.17:8888 # #his.url=172.16.10.15:8888 # \u7984\u529D\u949F\u7231 #his.url=200.200.200.5:8888 # \u8499\u81EA\u5E02\u4EBA\u6C11\u533B\u9662 #his.url=200.200.200.174:8080 # \u5143\u8C0B #his.url=200.200.200.29:8888 # \u5143\u8C0B\u533B\u4FDD #his.dev_url=200.200.200.36:9999 # \u8292\u5E02 #his.url=192.168.100.8:8888 # \u7EA2\u6CB3\u5987\u5E7C\u4FDD\u5065\u9662 #his.url=192.168.1.204:8888 # \u8292\u5E02\u5987\u5E7C #his.url=192.168.11.7:8888 # #his.url=10.10.11.23:8888 # \u77F3\u6797 #his.url=192.168.10.10:8888 # \u5BCC\u6C11 #his.url=200.200.201.27:8888 # \u897F\u53CC\u7248\u7EB3 #his.url=10.10.11.23:8888 #wx.password=ynxbd@6910
# \u5F00\u542F\u5904\u65B9\u9884\u7ED3\u7B97\uFF08\u7B2C2\u5F00\u5173\uFF09\uFF08\u6CE8\u610F\u8BE5\u914D\u7F6E\u9700\u8054\u7CFBhis\u5F00\u53D1\u8005\u786E\u8BA4\u652F\u6301\u624D\u80FD\u5F00\u542F\uFF0C\u5426\u5219\u5B58\u5728\u98CE\u9669\uFF01\uFF09 his.is_recipe_prepay=false # \u672C\u5730 #his.url=127.0.0.1:8888 # HIS\u662F\u5426\u5F00\u542F\u652F\u4ED8\u5B9D\u5206\u5F00\u5BF9\u8D26 his.is_ali_mer=false # \u662F\u5426\u5F3A\u5236\u6253\u5370webservice\u7684xml\u8FD4\u56DE\u6570\u636E his.is_log_resp=false # \u662F\u5426\u4F20\u9012openid\u7ED9his\u63A8\u9001\u6D88\u606F his.is_push_msg=false #------------------------------- # \u6D4B\u8BD5\u73AF\u5883 his.dev_url=200.200.200.105:8888 # \u533B\u4FDD=========================== # \u65E7\u914D\u7F6E his.md_url=127.0.0.1:7777 # \u5FAE\u4FE1\u533B\u4FDD his.wx_med_url=10.20.10.7:7885 # \u652F\u4ED8\u5B9D\u533B\u4FDD his.ali_med_url=10.20.10.7:7885 # \u516C\u53F8\u6D4B\u8BD5 #his.url=192.168.12.10:8888 # \u77F3\u6797\u6D4B\u8BD5 #his.url=200.200.200.105:8888 # \u6D4B\u8BD5============================================================ # \u5FB7\u5B8F\u4E2D\u533B his.url=200.200.200.60:9999 # \u7EA2\u6CB3\u5DDE\u533B\u9662 #his.url=10.20.10.6:8888 # \u8292\u5E02\u5987\u5E7C #his.url=192.168.11.7:8888 # \u5B81\u8497\u5987\u5E7C #his.url=172.19.3.15:8888 # \u516C\u53F8\u6D4B\u8BD5 #his.url=192.168.12.39:8888 # \u516C\u53F8\u6D4B\u8BD5 #his.url=192.168.12.10:8888 # \u7EA2\u6CB3 #his.url=10.20.10.6:8888 # \u7EA2\u6CB3\u533B\u4FDD #his.url=10.20.10.6:8888 #his.url=192.168.12.10:8888 #his.md_url=192.168.1.128:7885 #his.dev_url=10.20.10.6:9988 # \u6C38\u80DC #his.url=200.200.200.20:8888 # \u5FB7\u5B8F\u4E2D\u533B #his.url=200.200.200.60:8888 # \u534E\u576A #his.url=192.168.1.115:8888 # \u8499\u81EA\u4E2D\u533B #his.url=192.168.0.228:8888 # \u7389\u9F99 #his.url=192.168.0.17:8888 # #his.url=172.16.10.15:8888 # \u7984\u529D\u949F\u7231 #his.url=200.200.200.5:8888 # \u8499\u81EA\u5E02\u4EBA\u6C11\u533B\u9662 #his.url=200.200.200.174:8080 # \u5143\u8C0B #his.url=200.200.200.29:8888 # \u5143\u8C0B\u533B\u4FDD #his.dev_url=200.200.200.36:9999 # \u8292\u5E02 #his.url=192.168.100.8:8888 # \u7EA2\u6CB3\u5987\u5E7C\u4FDD\u5065\u9662 #his.url=192.168.1.204:8888 # \u8292\u5E02\u5987\u5E7C #his.url=192.168.11.7:8888 # #his.url=10.10.11.23:8888 # \u77F3\u6797 #his.url=192.168.10.10:8888 # \u5BCC\u6C11 #his.url=200.200.201.27:8888 # \u897F\u53CC\u7248\u7EB3 #his.url=10.10.11.23:8888 #wx.password=ynxbd@6910

@ -5,7 +5,9 @@ wx.aes_key=
wx.mch_id=
wx.mch_key=
# \u57DF\u540D
wx.domain=
wx.domain=http://www.baidu.com
# \u5907\u7528\u57DF\u540D\uFF08\u4E3B\u8981\u7528\u4E8E\u533B\u5171\u4F53\u8BA4\u8BC1\u6216\u4F5C\u4E3A\u7B2C\u4E8C\u57DF\u540D\uFF09
wx.backup_domain=
# \u9879\u76EE\u90E8\u7F72\u670D\u52A1\u540D
wx.deploy_server_name=wx
# \u9759\u6001\u8D44\u6E90\u8DEF\u5F84
@ -14,13 +16,16 @@ wx.web_static_path=/web
wx.password=ynxbd@6910
# \u662F\u5426\u4E3A\u6D4B\u8BD5\u73AF\u5883
# \u662F\u5426\u4E3A\u6D4B\u8BD5\u73AF\u5883=================================
wx.is_dev=true
# \u7528\u4E8E\u6388\u6743\u7684\u533B\u5171\u4F53\u516C\u4F17\u53F7\u914D\u7F6E=======================
wx.gmc.is_enable=
wx.gmc.auth_domain=
wx.gmc.app_id=
# \u5C0F\u7A0B\u5E8F\u4E3B\u4F53AppId
wx.gmc.mini.app_id=
wx.gmc.is_enable=false
wx.gmc.auth_domain=https://www.slxrmyy.cn
# \u516C\u4F17\u53F7\u4E3B\u4F53AppId\uFF08\u53BF\u533B\u9662\u516C\u4F17\u53F7AppId\uFF0C\u4E3B\u4F53\u533B\u9662\u65E0\u9700\u914D\u7F6E\uFF09
wx.gmc.app_id=wxe53f0f528bb16d9f
# \u5C0F\u7A0B\u5E8F\u4E3B\u4F53AppId[\u7528\u4E8E\u652F\u4ED8]========================
wx.gmc.mini.app_id=wx80685a7daa772a0b
# \u5C0F\u7A0B\u5E8F\u4E3B\u4F53AppSecret\uFF08\u4EC5\u9700\u4E3B\u4F53\u53BF\u533B\u9662\u914D\u7F6E\uFF09
wx.gmc.mini.app_secret=
Loading…
Cancel
Save