20260224:临时暂存(作废)
This commit is contained in:
parent
4e7d595893
commit
7ecc85ef83
@ -2,6 +2,8 @@ package com.fastbee.common.core.notify;
|
|||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,4 +47,9 @@ public class AlertPushParams {
|
|||||||
* 告警推送用户id
|
* 告警推送用户id
|
||||||
*/
|
*/
|
||||||
private Set<Long> userIdSet;
|
private Set<Long> userIdSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 告警推送参数
|
||||||
|
*/
|
||||||
|
private Map<String, String> deviceAlertParams = new HashMap<>(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,11 @@ public class SceneThingsModelItem {
|
|||||||
*/
|
*/
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物模型名称
|
||||||
|
*/
|
||||||
|
// private String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类型:1=属性, 2=功能,3=事件, 4=设备升级,5=设备上线,6=设备下线 ,
|
* 类型:1=属性, 2=功能,3=事件, 4=设备升级,5=设备上线,6=设备下线 ,
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -26,6 +26,9 @@ public class ThingsModelSimpleItem {
|
|||||||
*/
|
*/
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物模型名称
|
||||||
|
*/
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -20,6 +20,9 @@ public class ThingsModelValuesInput {
|
|||||||
**/
|
**/
|
||||||
private String deviceNumber;
|
private String deviceNumber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备类型
|
||||||
|
**/
|
||||||
private Integer deviceType;
|
private Integer deviceType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,10 +30,6 @@ public class ThingsModelValuesInput {
|
|||||||
**/
|
**/
|
||||||
private List<ThingsModelSimpleItem> thingsModelSimpleItem;
|
private List<ThingsModelSimpleItem> thingsModelSimpleItem;
|
||||||
|
|
||||||
/**
|
|
||||||
* 原始消息数据包(用于判断设备上电触发回包等)
|
|
||||||
**/
|
|
||||||
private Object sources;
|
|
||||||
|
|
||||||
public Long getDeviceId() {
|
public Long getDeviceId() {
|
||||||
return deviceId;
|
return deviceId;
|
||||||
@ -63,12 +62,4 @@ public class ThingsModelValuesInput {
|
|||||||
public void setThingsModelValueRemarkItem(List<ThingsModelSimpleItem> thingsModelSimpleItem) {
|
public void setThingsModelValueRemarkItem(List<ThingsModelSimpleItem> thingsModelSimpleItem) {
|
||||||
this.thingsModelSimpleItem = thingsModelSimpleItem;
|
this.thingsModelSimpleItem = thingsModelSimpleItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getSources() {
|
|
||||||
return sources;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSources(Object sources) {
|
|
||||||
this.sources = sources;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -122,7 +122,7 @@ public class SceneContext {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 执行动作,延迟执行,线程休眠 delay x 1000毫秒
|
// 执行动作,延迟执行,线程休眠 delay x 1000毫秒
|
||||||
Thread.sleep(scriptTemplate.getDelay() * 1000);
|
Thread.sleep(scriptTemplate.getDelay() * 1000L);
|
||||||
if (scriptTemplate.getSource() == 4) {
|
if (scriptTemplate.getSource() == 4) {
|
||||||
//存在相同未处理告警只记录 不触发告警通知和动作
|
//存在相同未处理告警只记录 不触发告警通知和动作
|
||||||
if (checkDeviceAlerting(scriptTemplate.getSceneId(), requestId, this.deviceNum)) {
|
if (checkDeviceAlerting(scriptTemplate.getSceneId(), requestId, this.deviceNum)) {
|
||||||
@ -520,6 +520,9 @@ public class SceneContext {
|
|||||||
}
|
}
|
||||||
alertPushParams.setAddress(address);
|
alertPushParams.setAddress(address);
|
||||||
alertPushParams.setAlertTime(DateUtils.parseDateToStr(DateUtils.YY_MM_DD_HH_MM_SS, new Date()));
|
alertPushParams.setAlertTime(DateUtils.parseDateToStr(DateUtils.YY_MM_DD_HH_MM_SS, new Date()));
|
||||||
|
|
||||||
|
// 设备告警参数
|
||||||
|
alertPushParams.getDeviceAlertParams().put(sceneThingsModelItem.getId(), sceneThingsModelItem.getValue());
|
||||||
return alertPushParams;
|
return alertPushParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -96,8 +96,6 @@ public class DataHandlerImpl implements IDataHandler {
|
|||||||
// 这里上报设备编号是转的大写,后面存缓存也是使用大写的,所以在查询物模型的值时添加把设备编号转大写后取值
|
// 这里上报设备编号是转的大写,后面存缓存也是使用大写的,所以在查询物模型的值时添加把设备编号转大写后取值
|
||||||
input.setDeviceNumber(bo.getSerialNumber().toUpperCase());
|
input.setDeviceNumber(bo.getSerialNumber().toUpperCase());
|
||||||
input.setThingsModelValueRemarkItem(thingsModelSimpleItems);
|
input.setThingsModelValueRemarkItem(thingsModelSimpleItems);
|
||||||
// 传递原始消息数据包,用于判断设备上电触发回包等
|
|
||||||
input.setSources(bo.getSources());
|
|
||||||
List<ThingsModelSimpleItem> result = deviceService.reportDeviceThingsModelValue(input, bo.getType(), bo.isShadow());
|
List<ThingsModelSimpleItem> result = deviceService.reportDeviceThingsModelValue(input, bo.getType(), bo.isShadow());
|
||||||
// 只有设备上报进入规则引擎流程
|
// 只有设备上报进入规则引擎流程
|
||||||
if (bo.isRuleEngine() && !bo.getSerialNumber().startsWith("server-")) {
|
if (bo.isRuleEngine() && !bo.getSerialNumber().startsWith("server-")) {
|
||||||
|
|||||||
@ -47,7 +47,7 @@ public class RuleEngineHandler implements IRuleEngine {
|
|||||||
// 场景联动处理
|
// 场景联动处理
|
||||||
this.sceneProcess(bo);
|
this.sceneProcess(bo);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("场景联动规则执行异常 message={}", e, e.getMessage());
|
log.error("场景联动规则执行异常 message={}", e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -163,6 +163,9 @@ public class NotifySendServiceImpl implements NotifySendService {
|
|||||||
map.put(variables.get(i), alertPushParams.getSerialNumber());
|
map.put(variables.get(i), alertPushParams.getSerialNumber());
|
||||||
} else if (i == 2) {
|
} else if (i == 2) {
|
||||||
map.put(variables.get(i), alertPushParams.getAddress());
|
map.put(variables.get(i), alertPushParams.getAddress());
|
||||||
|
} else if (i == 3) {
|
||||||
|
// 报警数值 变量id,告警值 / 变量id2,告警值2 / 变量id3,告警值3
|
||||||
|
map.put(variables.get(i), alertPushParams.getDeviceAlertParams().toString());
|
||||||
} else {
|
} else {
|
||||||
map.put(variables.get(i), alertPushParams.getAlertName());
|
map.put(variables.get(i), alertPushParams.getAlertName());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -139,6 +139,17 @@ public class WeChatController {
|
|||||||
return weChatService.getWxBindMsg(wxBindMsgId);
|
return weChatService.getWxBindMsg(wxBindMsgId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取微信服务号带参数二维码(用于绑定当前登录用户与服务号)
|
||||||
|
*
|
||||||
|
* @return 二维码信息(包含图片url)
|
||||||
|
*/
|
||||||
|
@ApiOperation("获取微信服务号绑定二维码")
|
||||||
|
@GetMapping("/getPublicAccountBindQr")
|
||||||
|
public AjaxResult getPublicAccountBindQr() {
|
||||||
|
return weChatService.getPublicAccountBindQr();
|
||||||
|
}
|
||||||
|
|
||||||
@ApiOperation("微信公众号验证url")
|
@ApiOperation("微信公众号验证url")
|
||||||
@GetMapping("/publicAccount/callback")
|
@GetMapping("/publicAccount/callback")
|
||||||
public void checkUrl(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
public void checkUrl(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||||
@ -151,7 +162,7 @@ public class WeChatController {
|
|||||||
// 随机字符串
|
// 随机字符串
|
||||||
String echostr = request.getParameter("echostr");
|
String echostr = request.getParameter("echostr");
|
||||||
// token
|
// token
|
||||||
String token = "fastbee";
|
String token = "yackfastbeeiot";
|
||||||
boolean check = SignUtils.checkSignature(token, signature, timestamp, nonce);
|
boolean check = SignUtils.checkSignature(token, signature, timestamp, nonce);
|
||||||
PrintWriter writer = response.getWriter();
|
PrintWriter writer = response.getWriter();
|
||||||
if (check) {
|
if (check) {
|
||||||
@ -175,7 +186,7 @@ public class WeChatController {
|
|||||||
response.setContentType("text/html;charset=utf-8");
|
response.setContentType("text/html;charset=utf-8");
|
||||||
response.getWriter().write(responseStr);
|
response.getWriter().write(responseStr);
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
log.error("微信回调回复信息回写失败:xmlStr:{},responseStr:{},e:{}", xmlStr, responseStr, e);
|
log.error("微信回调回复信息回写失败:xmlStr:{},responseStr:{},e:", xmlStr, responseStr, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -131,4 +131,13 @@ public interface SocialUserMapper {
|
|||||||
* @return java.util.List<com.fastbee.iot.domain.SocialUser>
|
* @return java.util.List<com.fastbee.iot.domain.SocialUser>
|
||||||
*/
|
*/
|
||||||
List<SocialUser> listWechatPublicAccountOpenId(@Param("userIdList") List<String> userIdList);
|
List<SocialUser> listWechatPublicAccountOpenId(@Param("userIdList") List<String> userIdList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据openId和来源查询绑定信息
|
||||||
|
*
|
||||||
|
* @param openId 微信openId
|
||||||
|
* @param sourceClient 来源平台标识
|
||||||
|
* @return com.fastbee.iot.domain.SocialUser
|
||||||
|
*/
|
||||||
|
SocialUser selectByOpenIdAndSourceClient(@Param("openId") String openId, @Param("sourceClient") String sourceClient);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -126,4 +126,13 @@ public interface ISocialUserService {
|
|||||||
* @return java.util.List<com.fastbee.iot.domain.SocialUser>
|
* @return java.util.List<com.fastbee.iot.domain.SocialUser>
|
||||||
*/
|
*/
|
||||||
List<SocialUser> listWechatPublicAccountOpenId(List<String> userIdList);
|
List<SocialUser> listWechatPublicAccountOpenId(List<String> userIdList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据openId和来源查询绑定信息
|
||||||
|
*
|
||||||
|
* @param openId 微信openId
|
||||||
|
* @param sourceClient 来源平台标识
|
||||||
|
* @return com.fastbee.iot.domain.SocialUser
|
||||||
|
*/
|
||||||
|
SocialUser selectByOpenIdAndSourceClient(String openId, String sourceClient);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -164,4 +164,9 @@ public class SocialUserServiceImpl implements ISocialUserService {
|
|||||||
public List<SocialUser> listWechatPublicAccountOpenId(List<String> userIdList) {
|
public List<SocialUser> listWechatPublicAccountOpenId(List<String> userIdList) {
|
||||||
return socialUserMapper.listWechatPublicAccountOpenId(userIdList);
|
return socialUserMapper.listWechatPublicAccountOpenId(userIdList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocialUser selectByOpenIdAndSourceClient(String openId, String sourceClient) {
|
||||||
|
return socialUserMapper.selectByOpenIdAndSourceClient(openId, sourceClient);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -73,4 +73,11 @@ public interface WeChatService {
|
|||||||
* @return msg
|
* @return msg
|
||||||
*/
|
*/
|
||||||
AjaxResult getWxBindMsg(String wxBindMsgId);
|
AjaxResult getWxBindMsg(String wxBindMsgId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取微信服务号带参数二维码(用于绑定当前登录用户)
|
||||||
|
*
|
||||||
|
* @return 二维码ticket和url
|
||||||
|
*/
|
||||||
|
AjaxResult getPublicAccountBindQr();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,7 +46,7 @@ public class WeChatCallbackServiceImpl implements WeChatCallbackService {
|
|||||||
Map<String, Object> map = XmlUtil.xmlToMap(xmlStr);
|
Map<String, Object> map = XmlUtil.xmlToMap(xmlStr);
|
||||||
wxCallBackXmlBO = JSONObject.parseObject(JSON.toJSONString(map), WxCallBackXmlBO.class);
|
wxCallBackXmlBO = JSONObject.parseObject(JSON.toJSONString(map), WxCallBackXmlBO.class);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("微信回调传递的xml解析报错:{},{}", xmlStr, e);
|
log.error("微信回调传递的xml解析报错:{}", xmlStr, e);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
if (ObjectUtil.isNull(wxCallBackXmlBO) || StringUtils.isEmpty(wxCallBackXmlBO.getMsgType())) {
|
if (ObjectUtil.isNull(wxCallBackXmlBO) || StringUtils.isEmpty(wxCallBackXmlBO.getMsgType())) {
|
||||||
@ -94,8 +94,9 @@ public class WeChatCallbackServiceImpl implements WeChatCallbackService {
|
|||||||
case "unsubscribe":
|
case "unsubscribe":
|
||||||
resMsg = this.handleEventUnSubscribe(wxCallBackXmlBo);
|
resMsg = this.handleEventUnSubscribe(wxCallBackXmlBo);
|
||||||
break;
|
break;
|
||||||
// 扫描二维码
|
// 已关注用户扫描带参数二维码
|
||||||
case "scan":
|
case "scan":
|
||||||
|
resMsg = this.handleEventScan(wxCallBackXmlBo);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -141,9 +142,98 @@ public class WeChatCallbackServiceImpl implements WeChatCallbackService {
|
|||||||
.setUnionId(weChatUserInfo.getUnionId()).setAccessToken(accessToken).setAvatar(weChatUserInfo.getHeadImgUrl())
|
.setUnionId(weChatUserInfo.getUnionId()).setAccessToken(accessToken).setAvatar(weChatUserInfo.getHeadImgUrl())
|
||||||
.setNickname(weChatUserInfo.getNickname()).setUuid(IdUtils.randomUUID()).setCreateBy("System");
|
.setNickname(weChatUserInfo.getNickname()).setUuid(IdUtils.randomUUID()).setCreateBy("System");
|
||||||
socialUser.setCreateTime(new Date());
|
socialUser.setCreateTime(new Date());
|
||||||
|
|
||||||
|
// 解析带参数二维码中的 EventKey,格式为 qrscene_bind_用户ID
|
||||||
|
Long bindSysUserId = parseBindUserIdFromEventKey(wxCallBackXmlBo.getEventKey());
|
||||||
|
if (bindSysUserId != null) {
|
||||||
|
socialUser.setSysUserId(bindSysUserId);
|
||||||
|
log.info("公众号关注事件:通过带参数二维码绑定用户,openId={},sysUserId={}", openId, bindSysUserId);
|
||||||
|
}
|
||||||
|
|
||||||
socialUserService.insertSocialUser(socialUser);
|
socialUserService.insertSocialUser(socialUser);
|
||||||
// 返回消息
|
// 返回消息
|
||||||
return WechatUtils.responseText(wxCallBackXmlBo, socialPlatform.getRemark());
|
String remark = socialPlatform.getRemark();
|
||||||
|
if (bindSysUserId != null) {
|
||||||
|
remark = "绑定成功!" + (StringUtils.isNotEmpty(remark) ? remark : "");
|
||||||
|
}
|
||||||
|
return WechatUtils.responseText(wxCallBackXmlBo, remark);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已关注用户扫描带参数二维码事件(SCAN事件)
|
||||||
|
* 用户已关注服务号,再扫描带参数二维码时触发,用于绑定系统用户
|
||||||
|
*/
|
||||||
|
private String handleEventScan(WxCallBackXmlBO wxCallBackXmlBo) {
|
||||||
|
String openId = wxCallBackXmlBo.getFromUserName();
|
||||||
|
// SCAN事件的 EventKey 不带 qrscene_ 前缀,直接就是场景值
|
||||||
|
String eventKey = wxCallBackXmlBo.getEventKey();
|
||||||
|
if (StringUtils.isEmpty(eventKey) || !eventKey.startsWith("bind_")) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
Long bindSysUserId = parseBindUserIdFromSceneValue(eventKey);
|
||||||
|
if (bindSysUserId == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String sourceClient = SocialPlatformType.WECHAT_OPEN_PUBLIC_ACCOUNT.getSourceClient();
|
||||||
|
// 查找该 openId 对应的公众号记录
|
||||||
|
SocialUser existUser = socialUserService.selectByOpenIdAndSourceClient(openId, sourceClient);
|
||||||
|
if (existUser != null) {
|
||||||
|
if (existUser.getSysUserId() != null && !existUser.getSysUserId().equals(bindSysUserId)) {
|
||||||
|
log.info("公众号SCAN事件:该微信已绑定其他用户,openId={},已绑定sysUserId={},请求绑定sysUserId={}",
|
||||||
|
openId, existUser.getSysUserId(), bindSysUserId);
|
||||||
|
return WechatUtils.responseText(wxCallBackXmlBo, "该微信已绑定其他账号,请先解绑后重试");
|
||||||
|
}
|
||||||
|
// 更新绑定
|
||||||
|
SocialUser updateUser = new SocialUser();
|
||||||
|
updateUser.setSocialUserId(existUser.getSocialUserId());
|
||||||
|
updateUser.setSysUserId(bindSysUserId);
|
||||||
|
updateUser.setStatus("1");
|
||||||
|
updateUser.setUpdateBy("System");
|
||||||
|
socialUserService.updateSocialUser(updateUser);
|
||||||
|
log.info("公众号SCAN事件:已关注用户绑定成功,openId={},sysUserId={}", openId, bindSysUserId);
|
||||||
|
return WechatUtils.responseText(wxCallBackXmlBo, "绑定成功!");
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 EventKey 中解析绑定的用户ID
|
||||||
|
* subscribe事件:EventKey 格式为 qrscene_bind_用户ID
|
||||||
|
*/
|
||||||
|
private Long parseBindUserIdFromEventKey(String eventKey) {
|
||||||
|
if (StringUtils.isEmpty(eventKey)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// subscribe事件中,带参数二维码的 EventKey 格式为 qrscene_bind_用户ID
|
||||||
|
String prefix = "qrscene_bind_";
|
||||||
|
if (eventKey.startsWith(prefix)) {
|
||||||
|
return parseUserId(eventKey.substring(prefix.length()));
|
||||||
|
}
|
||||||
|
// 兼容直接以 bind_ 开头的情况
|
||||||
|
if (eventKey.startsWith("bind_")) {
|
||||||
|
return parseUserId(eventKey.substring("bind_".length()));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从场景值中解析绑定的用户ID
|
||||||
|
* SCAN事件:EventKey 直接就是场景值,格式为 bind_用户ID
|
||||||
|
*/
|
||||||
|
private Long parseBindUserIdFromSceneValue(String sceneValue) {
|
||||||
|
if (StringUtils.isEmpty(sceneValue) || !sceneValue.startsWith("bind_")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return parseUserId(sceneValue.substring("bind_".length()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long parseUserId(String userIdStr) {
|
||||||
|
try {
|
||||||
|
return Long.parseLong(userIdStr);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.warn("解析绑定用户ID失败,userIdStr={}", userIdStr);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -435,4 +435,54 @@ public class WeChatServiceImpl implements WeChatService {
|
|||||||
return error(errorMsg);
|
return error(errorMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取微信服务号带参数二维码(用于绑定当前登录用户)
|
||||||
|
* 通过微信带参数临时二维码,用户扫码关注后自动绑定 sysUserId
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AjaxResult getPublicAccountBindQr() {
|
||||||
|
Long sysUserId = getUserId();
|
||||||
|
if (sysUserId == null) {
|
||||||
|
throw new ServiceException("请先登录后重试!");
|
||||||
|
}
|
||||||
|
// 查询服务号配置
|
||||||
|
SocialPlatform socialPlatform = socialPlatformService.selectSocialPlatformByPlatform(SocialPlatformType.WECHAT_OPEN_PUBLIC_ACCOUNT.sourceClient);
|
||||||
|
if (socialPlatform == null) {
|
||||||
|
throw new ServiceException("请先配置微信公众号信息");
|
||||||
|
}
|
||||||
|
// 获取accessToken
|
||||||
|
WeChatAppResult weChatAppResult = WechatUtils.getAccessToken(socialPlatform.getClientId(), socialPlatform.getSecretKey());
|
||||||
|
if (weChatAppResult == null || StringUtils.isEmpty(weChatAppResult.getAccessToken())) {
|
||||||
|
throw new ServiceException("获取微信AccessToken失败,请检查公众号配置");
|
||||||
|
}
|
||||||
|
// 调用微信带参数二维码接口,生成临时二维码,场景值为 bind_用户ID
|
||||||
|
String accessToken = weChatAppResult.getAccessToken();
|
||||||
|
String qrUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + accessToken;
|
||||||
|
cn.hutool.json.JSONObject sceneObj = new cn.hutool.json.JSONObject();
|
||||||
|
sceneObj.set("scene_str", "bind_" + sysUserId);
|
||||||
|
cn.hutool.json.JSONObject actionInfo = new cn.hutool.json.JSONObject();
|
||||||
|
actionInfo.set("scene", sceneObj);
|
||||||
|
cn.hutool.json.JSONObject reqBody = new cn.hutool.json.JSONObject();
|
||||||
|
reqBody.set("expire_seconds", 604800); // 7天有效
|
||||||
|
reqBody.set("action_name", "QR_STR_SCENE");
|
||||||
|
reqBody.set("action_info", actionInfo);
|
||||||
|
|
||||||
|
String response = com.fastbee.common.utils.http.HttpUtils.sendPost(qrUrl, reqBody.toString());
|
||||||
|
cn.hutool.json.JSONObject respJson = cn.hutool.json.JSONUtil.parseObj(response);
|
||||||
|
String ticket = respJson.getStr("ticket");
|
||||||
|
String qrCodeUrl = respJson.getStr("url");
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(ticket)) {
|
||||||
|
log.error("生成微信带参数二维码失败:{}", response);
|
||||||
|
throw new ServiceException("生成二维码失败:" + respJson.getStr("errmsg"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回二维码图片地址(通过ticket换取)
|
||||||
|
cn.hutool.json.JSONObject result = new cn.hutool.json.JSONObject();
|
||||||
|
result.set("qrCodeImgUrl", "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + ticket);
|
||||||
|
result.set("qrCodeUrl", qrCodeUrl);
|
||||||
|
result.set("ticket", ticket);
|
||||||
|
return success(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -151,6 +151,25 @@
|
|||||||
and s.del_flag = 0
|
and s.del_flag = 0
|
||||||
and s.`status` =1
|
and s.`status` =1
|
||||||
and s.source_client = 'wechat_open_public_account'
|
and s.source_client = 'wechat_open_public_account'
|
||||||
|
UNION
|
||||||
|
select DISTINCT sys_user_id, open_id
|
||||||
|
from iot_social_user
|
||||||
|
where sys_user_id in
|
||||||
|
<foreach collection="userIdList" item="userId" open="(" separator="," close=")">
|
||||||
|
#{userId}
|
||||||
|
</foreach>
|
||||||
|
and source_client = 'wechat_open_public_account'
|
||||||
|
and status = 1
|
||||||
|
and del_flag = 0
|
||||||
|
and sys_user_id is not null
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectByOpenIdAndSourceClient" resultType="com.fastbee.iot.domain.SocialUser">
|
||||||
|
<include refid="selectSocialUserVo"/>
|
||||||
|
where open_id = #{openId}
|
||||||
|
and source_client = #{sourceClient}
|
||||||
|
and del_flag = 0
|
||||||
|
limit 1
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -85,13 +85,20 @@ export function changeUserStatus(userId, status) {
|
|||||||
data: data,
|
data: data,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 获取微信二维码
|
// 获取微信二维码(开放平台网站应用)
|
||||||
export function getLoginParam() {
|
export function getLoginParam() {
|
||||||
return request({
|
return request({
|
||||||
url: '/wechat/getWxBindQr',
|
url: '/wechat/getWxBindQr',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// 获取微信服务号绑定二维码
|
||||||
|
export function getPublicAccountBindQr() {
|
||||||
|
return request({
|
||||||
|
url: '/wechat/getPublicAccountBindQr',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
}
|
||||||
// 解除绑定
|
// 解除绑定
|
||||||
export function secureBind(data) {
|
export function secureBind(data) {
|
||||||
return request({
|
return request({
|
||||||
|
|||||||
@ -11,8 +11,11 @@
|
|||||||
<el-button v-if="wxbind" type="warning" size="mini" @click="handleUnBindWeChat">{{ $t('user.profile.index.894502-7') }}</el-button>
|
<el-button v-if="wxbind" type="warning" size="mini" @click="handleUnBindWeChat">{{ $t('user.profile.index.894502-7') }}</el-button>
|
||||||
<el-button v-else type="primary" size="mini" @click="handleBindWeChat">{{ $t('user.profile.index.894502-8') }}</el-button>
|
<el-button v-else type="primary" size="mini" @click="handleBindWeChat">{{ $t('user.profile.index.894502-8') }}</el-button>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="消息推送">
|
||||||
|
<el-button type="success" size="mini" @click="handleBindPublicAccount">关注服务号</el-button>
|
||||||
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
<!-- 绑定微信 -->
|
<!-- 绑定微信(开放平台网站应用) -->
|
||||||
<el-dialog :title="'绑定微信'" :visible.sync="isBindWeChat" width="500px" append-to-body>
|
<el-dialog :title="'绑定微信'" :visible.sync="isBindWeChat" width="500px" append-to-body>
|
||||||
<div class="bindWeChatDialog">
|
<div class="bindWeChatDialog">
|
||||||
<div class="dec">请通过微信扫一扫,进行微信绑定。</div>
|
<div class="dec">请通过微信扫一扫,进行微信绑定。</div>
|
||||||
@ -24,6 +27,24 @@
|
|||||||
<el-button type="primary" size="small" @click="isBindWeChat = false">{{ $t('close') }}</el-button>
|
<el-button type="primary" size="small" @click="isBindWeChat = false">{{ $t('close') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
<!-- 关注服务号(带参数二维码) -->
|
||||||
|
<el-dialog title="关注服务号" :visible.sync="isBindPublicAccount" width="500px" append-to-body @close="onPublicAccountDialogClose">
|
||||||
|
<div class="bindWeChatDialog">
|
||||||
|
<div class="dec">请使用微信扫描下方二维码,关注服务号以接收告警等消息推送。</div>
|
||||||
|
<div class="weChat">
|
||||||
|
<div v-if="publicAccountQrLoading" style="height: 200px; display: flex; align-items: center; justify-content: center;">
|
||||||
|
<i class="el-icon-loading" style="font-size: 32px;"></i>
|
||||||
|
</div>
|
||||||
|
<img v-else-if="publicAccountQrUrl" :src="publicAccountQrUrl" alt="服务号二维码" style="width: 200px; height: 200px;" />
|
||||||
|
<div v-else style="height: 200px; display: flex; align-items: center; justify-content: center; color: #999;">
|
||||||
|
二维码加载失败,请关闭后重试
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button type="primary" size="small" @click="isBindPublicAccount = false">{{ $t('close') }}</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
<!-- 解除微信绑定 -->
|
<!-- 解除微信绑定 -->
|
||||||
<el-dialog :title="$t('user.profile.index.894502-11')" :visible.sync="isUnBindWeChat" width="600px" append-to-body>
|
<el-dialog :title="$t('user.profile.index.894502-11')" :visible.sync="isUnBindWeChat" width="600px" append-to-body>
|
||||||
<div class="unBindWeChatDialog">
|
<div class="unBindWeChatDialog">
|
||||||
@ -46,7 +67,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getLoginParam, secureBind } from '@/api/system/user';
|
import { getLoginParam, getPublicAccountBindQr, secureBind } from '@/api/system/user';
|
||||||
import { getWxBindMsg } from '@/api/login';
|
import { getWxBindMsg } from '@/api/login';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -71,12 +92,15 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isBindWeChat: false,
|
isBindWeChat: false,
|
||||||
|
isBindPublicAccount: false,
|
||||||
isUnBindWeChat: false,
|
isUnBindWeChat: false,
|
||||||
pwdtype: 'password',
|
pwdtype: 'password',
|
||||||
unBindWeChat: {
|
unBindWeChat: {
|
||||||
password: '',
|
password: '',
|
||||||
verifyType: 1,
|
verifyType: 1,
|
||||||
},
|
},
|
||||||
|
publicAccountQrUrl: '',
|
||||||
|
publicAccountQrLoading: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@ -90,7 +114,7 @@ export default {
|
|||||||
(script.type = 'text/javascript'), (script.src = 'http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js'), document.body.appendChild(script);
|
(script.type = 'text/javascript'), (script.src = 'http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js'), document.body.appendChild(script);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 绑定微信
|
// 绑定微信(开放平台网站应用 WxLogin)
|
||||||
handleBindWeChat() {
|
handleBindWeChat() {
|
||||||
getLoginParam().then((response) => {
|
getLoginParam().then((response) => {
|
||||||
const s = document.createElement('script');
|
const s = document.createElement('script');
|
||||||
@ -112,6 +136,23 @@ export default {
|
|||||||
});
|
});
|
||||||
this.isBindWeChat = true;
|
this.isBindWeChat = true;
|
||||||
},
|
},
|
||||||
|
// 关注服务号(获取带参数二维码)
|
||||||
|
handleBindPublicAccount() {
|
||||||
|
this.isBindPublicAccount = true;
|
||||||
|
this.publicAccountQrUrl = '';
|
||||||
|
this.publicAccountQrLoading = true;
|
||||||
|
getPublicAccountBindQr().then((response) => {
|
||||||
|
this.publicAccountQrUrl = response.data.qrCodeImgUrl;
|
||||||
|
this.publicAccountQrLoading = false;
|
||||||
|
}).catch(() => {
|
||||||
|
this.publicAccountQrUrl = '';
|
||||||
|
this.publicAccountQrLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 关闭服务号弹窗
|
||||||
|
onPublicAccountDialogClose() {
|
||||||
|
this.publicAccountQrUrl = '';
|
||||||
|
},
|
||||||
// 解除微信绑定
|
// 解除微信绑定
|
||||||
handleUnBindWeChat() {
|
handleUnBindWeChat() {
|
||||||
this.isUnBindWeChat = true;
|
this.isUnBindWeChat = true;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user