package cn.iocoder.yudao.module.wxcp.service.notify;
|
|
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO;
|
import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper;
|
import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserMapper;
|
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
|
import jakarta.annotation.Resource;
|
import lombok.extern.slf4j.Slf4j;
|
import me.chanjar.weixin.cp.api.WxCpService;
|
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult;
|
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.stereotype.Service;
|
|
import java.time.LocalDateTime;
|
import java.time.format.DateTimeFormatter;
|
|
/**
|
* 企业微信消息通知服务
|
*
|
* @author 超级管理员
|
*/
|
@Service
|
@Slf4j
|
public class WxCpNotifyService {
|
|
@Resource
|
private WxCpService wxCpService;
|
|
@Resource
|
private SocialUserBindMapper socialUserBindMapper;
|
|
@Resource
|
private SocialUserMapper socialUserMapper;
|
|
/**
|
* 发送登录通知消息到企业微信
|
*
|
* @param userId 系统用户 ID
|
* @param username 用户登录名
|
* @param loginType 登录方式(如:账号密码、短信、社交)
|
*/
|
@Async
|
public void sendLoginNotification(Long userId, String username, String loginType) {
|
try {
|
// 1. 查询用户绑定的企业微信
|
String wxUserId = getWxUserId(userId);
|
if (wxUserId == null) {
|
log.info("[sendLoginNotification][用户({})未绑定企业微信,跳过通知]", userId);
|
return;
|
}
|
|
// 2. 构造文本消息
|
// 注意:不能用 TEXTCARD —— 企业微信要求 textcard 的 url 必填,
|
// 留空会返回 41010 missing url,导致通知全部发送失败
|
String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
WxCpMessage message = WxCpMessage.TEXT()
|
.toUser(wxUserId)
|
.content(String.format(
|
"【登录通知】您的账号于 %s 通过「%s」方式登录系统。\n如非本人操作,请立即修改密码。",
|
time, loginType))
|
.build();
|
|
// 3. 发送消息
|
WxCpMessageSendResult result = wxCpService.getMessageService().send(message);
|
if (result.getErrCode() == 0) {
|
log.info("[sendLoginNotification][企业微信登录通知发送成功 userId={} wxUserId={}]", userId, wxUserId);
|
} else {
|
log.warn("[sendLoginNotification][企业微信登录通知发送失败 userId={} wxUserId={} errCode={} errMsg={}]",
|
userId, wxUserId, result.getErrCode(), result.getErrMsg());
|
}
|
} catch (Exception e) {
|
log.error("[sendLoginNotification][企业微信登录通知发送异常 userId={}]", userId, e);
|
}
|
}
|
|
/**
|
* 发送普通文本消息到企业微信
|
*
|
* @param userId 系统用户 ID
|
* @param content 消息内容
|
*/
|
@Async
|
public void sendTextMessage(Long userId, String content) {
|
try {
|
String wxUserId = getWxUserId(userId);
|
if (wxUserId == null) {
|
return;
|
}
|
|
WxCpMessage message = WxCpMessage.TEXT()
|
.toUser(wxUserId)
|
.content(content)
|
.build();
|
|
WxCpMessageSendResult result = wxCpService.getMessageService().send(message);
|
if (result.getErrCode() == 0) {
|
log.info("[sendTextMessage][企业微信文本消息发送成功 userId={}]", userId);
|
} else {
|
log.warn("[sendTextMessage][企业微信文本消息发送失败 userId={} errCode={} errMsg={}]",
|
userId, result.getErrCode(), result.getErrMsg());
|
}
|
} catch (Exception e) {
|
log.error("[sendTextMessage][企业微信文本消息发送异常 userId={}]", userId, e);
|
}
|
}
|
|
/**
|
* 根据系统用户 ID 获取企业微信 UserId
|
*
|
* @param userId 系统用户 ID
|
* @return 企业微信 UserId(即 openid)
|
*/
|
private String getWxUserId(Long userId) {
|
// 1. 查绑定关系
|
SocialUserBindDO bind = socialUserBindMapper.selectByUserIdAndUserTypeAndSocialType(
|
userId, UserTypeEnum.ADMIN.getValue(), SocialTypeEnum.WECHAT_ENTERPRISE.getType());
|
if (bind == null) {
|
return null;
|
}
|
|
// 2. 查社交用户信息
|
SocialUserDO socialUser = socialUserMapper.selectById(bind.getSocialUserId());
|
if (socialUser == null) {
|
return null;
|
}
|
|
return socialUser.getOpenid();
|
}
|
|
}
|