1、二维码的生成
通过rpc 调用base的 eh.qrInfoService 接口
接口在base-api中
调到了 NgariQrInfoService 类
需要拼接的数据
可以看到 QRInfoConstant 表示二维码的类型
同意存放在 BusQrInfoBean 对象中
String sceneStr = QRInfoConstant.QRTYPE_NGARICHECKLIST + "_" + ngariChecklistInfo;
sceneStr就是传入的 类型 + 参数
QRInfoBean qrInfoBean = createBriefQRInfoFromOpbase(busQrInfoBean, clientConfigDTO);
之后调用 createBriefQRInfoFromOpbase 方法 去获取二维码的参数
@RpcService
public QRInfoBean createBriefQRInfoFromOpbase(BusQrInfoBean busQrInfoBean, ClientConfigDTO clientConfig) {
Integer organId = busQrInfoBean.getOrganId();
String SceneStr=busQrInfoBean.getSceneStr();
Integer qrType=busQrInfoBean.getQrType();
LOGGER.info("生成临时二维码 SceneStr={}," +
"organId={},createWay={},clientConfigId={}",
SceneStr, organId, busQrInfoBean.getCreateWay(),
clientConfig.getId());
if (SceneStr == null || qrType==null) {
LOGGER.info("SceneStr为空或qrType未空,无法获取二维码,clientConfigId={}", clientConfig.getId());
return null;
}
//设置二维码类型和参数
Integer clientConfigId = clientConfig.getId() == null ?
QRInfoConstant.CLIENTCONFIGID_NGARI : clientConfig.getId();
//生成业务相关二维码[永久]
QRInfo qr=null;
//针对营销页面,纳里健康终端生成临时二维码
if (busQrInfoBean.getQrType() == QRInfoConstant.QRTYPE_MARKETINGPAGE && "wx870abf50c6bc6da3".equals(clientConfig.getAppKey())) {
//获取有效时间
if (busQrInfoBean.getExpireSeconds() == null) {
String expireSecondsStr = ParamUtils.getParam(ParameterConstant.KEY_QRCODE_EXPIRE_SECONDS, "2592000");
busQrInfoBean.setExpireSeconds(Long.valueOf(expireSecondsStr));
}
List<QRInfo> infos = qrDao.findBriefQRInfoAndQRCategory(clientConfigId, SceneStr,new Date(), qrType);
if (infos.isEmpty()) {
qr = qrCodeService.createBriefQRInfo(busQrInfoBean, clientConfig);
} else {
qr = infos.get(0);
}
return getBean(qr,QRInfoBean.class);
}
//针对营销页面,除纳里健康终端,生成二维码时依旧生成永久二维码
if (busQrInfoBean.getQrType() == QRInfoConstant.QRTYPE_MARKETINGPAGE){
List<QRInfo> infos = qrDao.findQRInfoByClientConfigId(clientConfigId, SceneStr, qrType);
if (infos.isEmpty()) {
qr = qrCodeService.createPermanentQRInfo(busQrInfoBean, clientConfig);
} else {
qr = infos.get(0);
}
return getBean(qr,QRInfoBean.class);
}
if ("WX".equals(busQrInfoBean.getCreateWay())) {
//只有当是微信端时,采用临时二维码
LOGGER.info("wx client loading qrCode");
//获取有效时间
if (busQrInfoBean.getExpireSeconds() == null) {
String expireSecondsStr = ParamUtils.getParam(ParameterConstant.KEY_QRCODE_EXPIRE_SECONDS, "2592000");
busQrInfoBean.setExpireSeconds(Long.valueOf(expireSecondsStr));
}
//先查询有没有永久二维码,如果有,直接返回,如果没有,则生成临时二维码
List<QRInfo> infos = qrDao.findQRInfoByClientConfigIdAndQRCategory(clientConfigId, SceneStr, qrType);
if (infos.isEmpty()) {
//查询有没有没过期的临时二维码,如果没有,则生成新的二维码
List<QRInfo> briefQRInfo = qrDao.findBriefQRInfoAndQRCategory(clientConfigId, SceneStr, new Date(), qrType);
LOGGER.info("qrCodeCount count={},clientConfigId={},sceneStr={},qrType={}",briefQRInfo.size(),clientConfigId,SceneStr,qrType);
if (briefQRInfo.isEmpty()) {
qr = qrCodeService.createBriefQRInfo(busQrInfoBean, clientConfig);
}else {
qr = briefQRInfo.get(0);
}
} else {
qr = infos.get(0);
}
}else {
LOGGER.info("other client loading qrCode");
List<QRInfo> infos = qrDao.findQRInfoByClientConfigId(clientConfigId, SceneStr, qrType);
if (infos.isEmpty()) {
qr = qrCodeService.createPermanentQRInfo(busQrInfoBean, clientConfig);
} else {
qr = infos.get(0);
}
}
return getBean(qr,QRInfoBean.class);
}
2、二维码的解析
二维码的解析 大部分是在wxservice 和 base项目
在WXCallbackListenerImpl 类中进行微信扫码后的回调
进入onEvent 方法中
String msgType = arg0.getMsgType();
String event = arg0.getEvent();
String openId = arg0.getFromUser();
String appId = arg0.getAppid();
String content = arg0.getEventKey();
if (!msgType.equals(getAppEvent().getKey())) {
return msgType;
}
if (getAppEvent().getSubscribe().equals(event) || getAppEvent().getScan().equals(event)) {//临时二维码执行web登录
try {
if (arg0.getTicket() != null) {
IWebLoginInfoService webLoginInfoService = AppContextHolder.getBean("eh.webLoginInfoService", IWebLoginInfoService.class);
String hashCode = Integer.toHexString(arg0.getTicket().hashCode());
webLoginInfoService.putLoginInfo(hashCode, openId);
}
}
}
WXService wxService = AppContextHolder.getBean("wx.wxService", WXService.class);
//未关注公众号时
if (getAppEvent().getSubscribe().equals(event)) {
// 关注自动回复消息
replyOnSubscribe(appId, openId);
// 更新关注标记
subscribePubPlatform(appId, openId, event);
//保存或更新
this.subscribeUserInfo(openId,appId);
// 扫描医生二维码关注时
String subscribeStr = StringUtils.substringAfter(arg0.getEventKey(), "qrscene_");
log.info("没关注公众号的情况扫码:" + JSONUtils.toString(subscribeStr));
IConfigurationCenterUtilsService configurationCenterUtilsService = AppContextHolder.getBean("eh.configurationCenterUtils",IConfigurationCenterUtilsService.class);
Boolean ngariQrcode = (Boolean) configurationCenterUtilsService.getPropertyByAppKey(appId,"ngariQrcode");
//ngariQrcode为true只支持有ngari_qrcode_前缀的 false 支持有ngari_qrcode_前缀和纯数字
if (ngariQrcode && subscribeStr.matches(reg)){
log.info("ngariQrcode为true只支持有ngari_qrcode_前缀:" + JSONUtils.toString(subscribeStr));
return null;
}
if (subscribeStr.startsWith(QRInfoConstant.QRCODE_PREFIX)){
subscribeStr = StringUtils.substringAfter(arg0.getEventKey(), QRInfoConstant.QRCODE_PREFIX);
}
if (subscribeStr.matches(reg) && !StringUtils.equals(subscribeStr, "0")) {
saveWxSubscribeAndSendMsg(appId, openId, subscribeStr);
}
if (!subscribeStr.matches(reg) ){
sendMessage(appId, openId, subscribeStr);
}
wxService.saveQRRecords(appId, subscribeStr, openId, false,ClientConfigConstant.APP_CLIENTTYPE_WX);
} else if (getAppEvent().getUnsubscribe().equals(event)) {
//取消关注公众号时
subscribePubPlatform(appId, openId, event);
//更新扫码关注记录
wxService.updateQRRecords(appId, openId, ClientConfigConstant.APP_CLIENTTYPE_WX);
//更新关注表
this.unSubscribeUserInfo(openId);
} else if (getAppEvent().getClick().equals(event)) {
//点击公众号菜单时
String eventKey = arg0.getEventKey();
if("CALL_NUMBER_MESSAGE".equals(eventKey)){
ICallNumberServiceInterface callNumberService = AppContextHolder.getBean("eh.callNumberService", ICallNumberServiceInterface.class);
String callNumberReplyMsg = callNumberService.getCallInfoString(appId, openId, "CALLMSG");
log.info("click event[{}] with response[{}]", eventKey, callNumberReplyMsg);
sendCustomerMessage(appId, openId, callNumberReplyMsg);
} else {
WxMenuMsgInterface menuMsgInterface = AppContextHolder.getBean("eh.wxMsgConfigService", WxMenuMsgInterface.class);
List<WXMsgConfig> menuMsgList = menuMsgInterface.findWXMsgConfigByAppId(appId, 1);//1:未过期消息
for (WXMsgConfig wxMsgConfig : menuMsgList) {
if (StringUtils.equals(wxMsgConfig.getMsgKey(), eventKey)) {
//处理带参数的事件,替换参数
WxEventUtils.packageEventMsg(new WxEventParam(openId), wxMsgConfig);
sendCustomerMessage(appId, openId, wxMsgConfig.getMsg());
}
}
}
} else if (getAppEvent().getLocation().equals(event)) {
//获取地理位置时
WXLocationEvent wxLocationEvent = (WXLocationEvent) arg0;
Double latitude = wxLocationEvent.getLatitude();
Double longitude = wxLocationEvent.getLongitude();
String id = new StringBuilder().append(openId).append("@").append(appId).toString();
String location = "location";
Map map = ClientStore.instance().get(id);
if (!map.containsKey(location)) {
String result = LocationRevertUtils.parse(latitude.toString(), longitude.toString());
JSONObject object = JSONObject.parseObject(result);
JSONObject locationObject = object.getJSONObject("result");
Map ad_info = locationObject.getJSONObject("ad_info");
map.put(location, ad_info);
ClientStore.instance().put(id, map);
//将地理位置放在静态常量里面,由于解绑返回到注册页面需要试用,因此不进行判断是否已关注
OAuthWeixinMPDAO dao = DAOFactory.getDAO(OAuthWeixinMPDAO.class);
OAuthWeixinMP oAuthWeixinMP = dao.getByAppIdAndOpenId(appId, openId);
if (oAuthWeixinMP != null) {
updateUserCache(oAuthWeixinMP.getUserId(), ad_info);
}
log.info("id[{}], location[{}]", id, ad_info);
}
} else if (getAppEvent().getScan().equals(event)) {
//已关注公众号时
String subscribeStr = arg0.getEventKey();
log.info("已关注公众号的情况扫码:" + JSONUtils.toString(subscribeStr));
IConfigurationCenterUtilsService configurationCenterUtilsService = AppContextHolder.getBean("eh.configurationCenterUtils",IConfigurationCenterUtilsService.class);
Boolean ngariQrcode = (Boolean) configurationCenterUtilsService.getPropertyByAppKey(appId,"ngariQrcode");
//ngariQrcode为true只支持有ngari_qrcode_前缀的 false 支持有ngari_qrcode_前缀和纯数字
if (ngariQrcode && subscribeStr.matches(reg)){
log.info("ngariQrcode为true只支持有ngari_qrcode_前缀:" + JSONUtils.toString(subscribeStr));
return null;
}
if (subscribeStr.startsWith(QRInfoConstant.QRCODE_PREFIX)){
subscribeStr = StringUtils.substringAfter(arg0.getEventKey(), QRInfoConstant.QRCODE_PREFIX);
}
if (subscribeStr.matches(reg) && !StringUtils.equals(subscribeStr, "0")) {
saveWxSubscribeAndSendMsg(appId, openId, subscribeStr);
}
if (!subscribeStr.matches(reg)){
if(subscribeStr.contains("jobNumber")){
//如果包含医生工号信息,则为出院小结推送
sendHospitalSummaryMessage(appId, openId, subscribeStr);
}else {
sendMessage(appId, openId, subscribeStr);
}
}
wxService.saveQRRecords(appId, subscribeStr, openId, true,ClientConfigConstant.APP_CLIENTTYPE_WX);
进入 sendMessage(appId, openId, subscribeStr); 方法中
进入sendMessage