commit
This commit is contained in:
@@ -32,6 +32,7 @@ public class RedisConstant {
|
|||||||
public final static String REDIS_KEY_API_SIGN_DEPLOY_NONCE = PLATFORM_REDIS_PREFIX + "api:sign:deploy:nonce:";
|
public final static String REDIS_KEY_API_SIGN_DEPLOY_NONCE = PLATFORM_REDIS_PREFIX + "api:sign:deploy:nonce:";
|
||||||
public final static String REDIS_KEY_API_SIGN_OPEN_NONCE = PLATFORM_REDIS_PREFIX + "api:sign:open:nonce:";
|
public final static String REDIS_KEY_API_SIGN_OPEN_NONCE = PLATFORM_REDIS_PREFIX + "api:sign:open:nonce:";
|
||||||
|
|
||||||
|
public final static String REDIS_WECHAT_ENTERPRISE_TOKEN_KEY = PLATFORM_REDIS_PREFIX + "platfrom:wechatenterprise:token:";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Token 缓存前缀
|
* Token 缓存前缀
|
||||||
|
|||||||
@@ -0,0 +1,135 @@
|
|||||||
|
package com.budwk.app.base.sms;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName WechatEnterpriseService
|
||||||
|
* @Author JyuHsin
|
||||||
|
* @Date 2026/3/19 15:48
|
||||||
|
* @Version 1.0
|
||||||
|
* @Description TODO
|
||||||
|
*/
|
||||||
|
public interface WechatEnterpriseService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单发普通消息(无标题)
|
||||||
|
* @param loginName 接收人工号(必填)
|
||||||
|
* @param content 消息内容(必填)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void sendSingleMessage(String loginName, String content);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单发普通消息(带标题)
|
||||||
|
* @param loginName 接收人工号(必填)
|
||||||
|
* @param title 消息标题(可选,可为null)
|
||||||
|
* @param content 消息内容(必填)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void sendSingleMessage(String loginName, String title, String content);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单发文本卡片消息
|
||||||
|
* @param loginName 接收人工号(必填)
|
||||||
|
* @param content 卡片内容(必填)
|
||||||
|
* @param pcUrl PC端跳转链接(必填)
|
||||||
|
* @param mobileUrl 移动端跳转链接(必填)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void sendSingleTextCard(String loginName, String content, String pcUrl, String mobileUrl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单发文本卡片消息(带标题)
|
||||||
|
* @param loginName 接收人工号(必填)
|
||||||
|
* @param title 卡片标题(可选,可为null)
|
||||||
|
* @param content 卡片内容(必填)
|
||||||
|
* @param pcUrl PC端跳转链接(必填)
|
||||||
|
* @param mobileUrl 移动端跳转链接(必填)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void sendSingleTextCard(String loginName, String title, String content, String pcUrl, String mobileUrl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单发图文卡片消息
|
||||||
|
* @param loginName 接收人工号(必填)
|
||||||
|
* @param content 卡片内容(必填)
|
||||||
|
* @param pcUrl PC端跳转链接(必填)
|
||||||
|
* @param mobileUrl 移动端跳转链接(必填)
|
||||||
|
* @param picUrl 图片链接(必填)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void sendSinglePicTextCard(String loginName, String content, String pcUrl, String mobileUrl, String picUrl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单发图文卡片消息(带标题)
|
||||||
|
* @param loginName 接收人工号(必填)
|
||||||
|
* @param title 卡片标题(可选,可为null)
|
||||||
|
* @param content 卡片内容(必填)
|
||||||
|
* @param pcUrl PC端跳转链接(必填)
|
||||||
|
* @param mobileUrl 移动端跳转链接(必填)
|
||||||
|
* @param picUrl 图片链接(必填)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void sendSinglePicTextCard(String loginName, String title, String content, String pcUrl, String mobileUrl, String picUrl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群发普通消息(多人接收相同内容)
|
||||||
|
* @param loginNames 接收人工号列表(必填,不能为空列表)
|
||||||
|
* @param content 消息内容(必填)
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
void massSendMessage(List<String> loginNames, String content);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群发普通消息(多人接收相同内容)
|
||||||
|
* @param loginNames 接收人工号列表(必填,不能为空列表)
|
||||||
|
* @param title 消息标题(可选,可为null)
|
||||||
|
* @param content 消息内容(必填)
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
void massSendMessage(List<String> loginNames, String title, String content);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群发短信文本卡片消息
|
||||||
|
* @param loginNames 接收人工号列表(必填,不能为空列表)
|
||||||
|
* @param content 卡片内容(必填)
|
||||||
|
* @param pcUrl PC端跳转链接(必填)
|
||||||
|
* @param mobileUrl 移动端跳转链接(必填)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void massSendTextCard(List<String> loginNames, String content, String pcUrl, String mobileUrl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群发短信文本卡片消息
|
||||||
|
* @param loginNames 接收人工号列表(必填,不能为空列表)
|
||||||
|
* @param title 卡片标题(可选,可为null)
|
||||||
|
* @param content 卡片内容(必填)
|
||||||
|
* @param pcUrl PC端跳转链接(必填)
|
||||||
|
* @param mobileUrl 移动端跳转链接(必填)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void massSendTextCard(List<String> loginNames, String title, String content, String pcUrl, String mobileUrl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群发图文卡片消息
|
||||||
|
* @param loginNames 接收人工号列表(必填,不能为空列表)
|
||||||
|
* @param content 卡片内容(必填)
|
||||||
|
* @param pcUrl PC端跳转链接(必填)
|
||||||
|
* @param mobileUrl 移动端跳转链接(必填)
|
||||||
|
* @param picUrl 图片链接(必填)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void massSendPicTextCard(List<String> loginNames, String content, String pcUrl, String mobileUrl, String picUrl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群发图文卡片消息
|
||||||
|
* @param loginNames 接收人工号列表(必填,不能为空列表)
|
||||||
|
* @param title 卡片标题(可选,可为null)
|
||||||
|
* @param content 卡片内容(必填)
|
||||||
|
* @param pcUrl PC端跳转链接(必填)
|
||||||
|
* @param mobileUrl 移动端跳转链接(必填)
|
||||||
|
* @param picUrl 图片链接(必填)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void massSendPicTextCard(List<String> loginNames, String title, String content, String pcUrl, String mobileUrl, String picUrl);
|
||||||
|
}
|
||||||
@@ -45,6 +45,10 @@ public class SmsWhcpServiceImpl implements SmsService {
|
|||||||
log.info("【log】本地开发环境,不允许调用短信消息接口");
|
log.info("【log】本地开发环境,不允许调用短信消息接口");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(!Globals.MyConfig.getBoolean("AppSms", false)) {
|
||||||
|
log.error("【log】消息配置未开启");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String urls = "https://api-shss.zthysms.com/v2/sendSms";
|
String urls = "https://api-shss.zthysms.com/v2/sendSms";
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,171 @@
|
|||||||
|
package com.budwk.app.base.sms.impl;
|
||||||
|
|
||||||
|
import cn.hutool.http.HttpUtil;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.budwk.app.base.sms.WechatEnterpriseService;
|
||||||
|
import com.budwk.app.base.sms.util.WechatEnterpriseTokenUtil;
|
||||||
|
import com.budwk.app.web.commons.base.Globals;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.json.Json;
|
||||||
|
import org.nutz.lang.Lang;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName WechatEnterpriseServiceImpl
|
||||||
|
* @Author JyuHsin
|
||||||
|
* @Date 2026/3/19 15:48
|
||||||
|
* @Version 1.0
|
||||||
|
* @Description TODO
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@IocBean
|
||||||
|
public class WechatEnterpriseServiceImpl implements WechatEnterpriseService {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private WechatEnterpriseTokenUtil tokenUtil;
|
||||||
|
private static final String SEND_MSG_URL = "http://xxzx.whcp.edu.cn/api/v4/oauth/message";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendSingleMessage(String loginName, String content) {
|
||||||
|
this.sendSingleMessage(loginName, "智慧工会", content);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendSingleMessage(String loginName, String title, String content) {
|
||||||
|
this.massSendMessage(List.of(loginName), title, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendSingleTextCard(String loginName, String content, String pcUrl, String mobileUrl) {
|
||||||
|
this.sendSingleTextCard(loginName, "智慧工会", content, pcUrl, mobileUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendSingleTextCard(String loginName, String title, String content, String pcUrl, String mobileUrl) {
|
||||||
|
this.massSendTextCard(List.of(loginName), title, content, pcUrl, mobileUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendSinglePicTextCard(String loginName, String content, String pcUrl, String mobileUrl, String picUrl) {
|
||||||
|
this.sendSinglePicTextCard(loginName, "智慧工会", content, pcUrl, mobileUrl, picUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendSinglePicTextCard(String loginName, String title, String content, String pcUrl, String mobileUrl, String picUrl) {
|
||||||
|
this.massSendPicTextCard(List.of(loginName), title, content, pcUrl, mobileUrl, picUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void massSendMessage(List<String> loginNames, String content) {
|
||||||
|
this.massSendMessage(loginNames, "智慧工会", content);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void massSendMessage(List<String> loginNames, String title, String content) {
|
||||||
|
List<Map<String, String>> list = loginNames.stream().map(loginName -> Map.of("id", loginName)).toList();
|
||||||
|
this.doSend("text", list, title, content, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void massSendTextCard(List<String> loginNames, String content, String pcUrl, String mobileUrl) {
|
||||||
|
this.massSendTextCard(loginNames, "智慧工会", content, pcUrl, mobileUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void massSendTextCard(List<String> loginNames, String title, String content, String pcUrl, String mobileUrl) {
|
||||||
|
List<Map<String, String>> list = loginNames.stream().map(loginName -> Map.of("id", loginName)).toList();
|
||||||
|
this.doSend("textCard", list, title, content, pcUrl, mobileUrl, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void massSendPicTextCard(List<String> loginNames, String content, String pcUrl, String mobileUrl, String picUrl) {
|
||||||
|
this.massSendPicTextCard(loginNames, "智慧工会", content, pcUrl, mobileUrl, picUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void massSendPicTextCard(List<String> loginNames, String title, String content, String pcUrl, String mobileUrl, String picUrl) {
|
||||||
|
List<Map<String, String>> list = loginNames.stream().map(loginName -> Map.of("id", loginName)).toList();
|
||||||
|
this.doSend("news", list, title, content, pcUrl, mobileUrl, picUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doSend(String sendType,
|
||||||
|
List<Map<String, String>> receivers,
|
||||||
|
String title,
|
||||||
|
String content,
|
||||||
|
String pcUrl,
|
||||||
|
String mobileUrl,
|
||||||
|
String picUrl) {
|
||||||
|
|
||||||
|
if (!Globals.sso) {
|
||||||
|
log.error("【log】开发模式不允许发送企业微信通知");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!Globals.MyConfig.getBoolean("AppSms", false)) {
|
||||||
|
log.error("【log】消息配置未开启");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Lang.isEmpty(receivers)) {
|
||||||
|
log.error("send fail by receivers is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
String token = tokenUtil.getToken();
|
||||||
|
if (Lang.isEmpty(token)) {
|
||||||
|
log.error("【log】send fail by token is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("title", title);
|
||||||
|
params.put("content", content);
|
||||||
|
params.put("timing", true);
|
||||||
|
params.put("channels", List.of("ly_qywx"));
|
||||||
|
params.put("receiver", receivers);
|
||||||
|
params.put("crowdType", "C");
|
||||||
|
params.put("applyMsgType", "ghxx");
|
||||||
|
|
||||||
|
if ("text".equals(sendType)) {
|
||||||
|
params.put("msgType", "T");
|
||||||
|
}
|
||||||
|
if ("textCard".equals(sendType)) {
|
||||||
|
params.put("msgType", "TC");
|
||||||
|
params.put("fileType", "TC");
|
||||||
|
params.put("fileTitle", title);
|
||||||
|
params.put("description", content);
|
||||||
|
params.put("url", mobileUrl);
|
||||||
|
params.put("btntxt", "查看详情");
|
||||||
|
}
|
||||||
|
if ("news".equals(sendType)) {
|
||||||
|
params.put("msgType", "M");
|
||||||
|
params.put("fileType", "M");
|
||||||
|
params.put("fileTitle", title);
|
||||||
|
params.put("url", mobileUrl);
|
||||||
|
params.put("filePath", picUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("【log】发送企业微信通知,请求参数:{}", Json.toJson(params));
|
||||||
|
String body = HttpUtil.createPost(SEND_MSG_URL + "?token=" + token)
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.body(Json.toJson(params)).execute().body();
|
||||||
|
JSONObject resultJsonBody = JSONUtil.parseObj(body);
|
||||||
|
log.info("【log】发送企业微信通知,接口响应数据:{}", body);
|
||||||
|
|
||||||
|
if (resultJsonBody.getInt("code") == 200) {
|
||||||
|
log.info("【log】发送企业微信通知成功");
|
||||||
|
String msgId = resultJsonBody.getStr("data");
|
||||||
|
System.out.println(msgId);
|
||||||
|
} else {
|
||||||
|
log.info("【log】发送企业微信通知失败:{}", resultJsonBody.getStr("message"));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("发送企业微信通知失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package com.budwk.app.base.sms.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUnit;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.http.HttpUtil;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.budwk.app.base.constant.RedisConstant;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.nutz.integration.jedis.RedisService;
|
||||||
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.json.Json;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName WechatEnterpriseTokenUtil
|
||||||
|
* @Author JyuHsin
|
||||||
|
* @Date 2026/3/19 15:51
|
||||||
|
* @Version 1.0
|
||||||
|
* @Description TODO
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@IocBean
|
||||||
|
public class WechatEnterpriseTokenUtil {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private RedisService redisService;
|
||||||
|
|
||||||
|
private static final String TOKEN_URL = "http://xxzx.whcp.edu.cn/api/v4/oauth/token";
|
||||||
|
private static final String CLINT_ID = "gh";
|
||||||
|
private static final String CLINT_SECRET = "0a5fb006ee64060799aec6403707eb4d";
|
||||||
|
private static final String GRANT_TYPE = "authorization_code";
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
String key = RedisConstant.REDIS_WECHAT_ENTERPRISE_TOKEN_KEY;
|
||||||
|
String token = redisService.get(key);
|
||||||
|
if (StrUtil.isBlank(token)) {
|
||||||
|
// 构造表单参数
|
||||||
|
Map<String, String> param = new HashMap<>();
|
||||||
|
param.put("client_id", CLINT_ID);
|
||||||
|
param.put("client_secret", CLINT_SECRET);
|
||||||
|
param.put("grant_type", GRANT_TYPE);
|
||||||
|
|
||||||
|
String body = HttpUtil.createGet(TOKEN_URL).formStr(param).execute().body();
|
||||||
|
|
||||||
|
JSONObject resultJsonBody = JSONUtil.parseObj(body);
|
||||||
|
log.info("【log】获取企业微信消息token接口回调数据:{}", Json.toJson(resultJsonBody));
|
||||||
|
if (resultJsonBody.getInt("code") == 200) {
|
||||||
|
|
||||||
|
JSONObject entries = resultJsonBody.getJSONObject("data");
|
||||||
|
|
||||||
|
String accessToken = entries.getStr("access_token");
|
||||||
|
String refreshToken = entries.getStr("refresh_token");
|
||||||
|
Long expiresIn = entries.getLong("expires_in");
|
||||||
|
|
||||||
|
int seconds = (int) DateUtil.between(DateUtil.date(), DateUtil.date(expiresIn), DateUnit.SECOND);
|
||||||
|
redisService.setex(key, seconds, accessToken);
|
||||||
|
return accessToken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.budwk.app.flow.listenter;
|
package com.budwk.app.flow.listenter;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
import com.budwk.app.flow.constant.FlowConst;
|
import com.budwk.app.flow.constant.FlowConst;
|
||||||
import com.budwk.app.flow.engine.event.ProcessEvent;
|
import com.budwk.app.flow.engine.event.ProcessEvent;
|
||||||
import com.budwk.app.flow.engine.event.ProcessEventListener;
|
import com.budwk.app.flow.engine.event.ProcessEventListener;
|
||||||
@@ -8,6 +9,7 @@ import com.budwk.app.flow.entity.ProcessInstance;
|
|||||||
import com.budwk.app.flow.entity.ProcessTask;
|
import com.budwk.app.flow.entity.ProcessTask;
|
||||||
import com.budwk.app.flow.entity.ProcessTaskActor;
|
import com.budwk.app.flow.entity.ProcessTaskActor;
|
||||||
import com.budwk.app.flow.enums.ProcessEventTypeEnum;
|
import com.budwk.app.flow.enums.ProcessEventTypeEnum;
|
||||||
|
import com.budwk.app.web.commons.base.Globals;
|
||||||
import com.budwk.app.zhgh.dayofficework.message.service.GlobalMessageSendService;
|
import com.budwk.app.zhgh.dayofficework.message.service.GlobalMessageSendService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
@@ -58,10 +60,22 @@ public class ProcessTaskStartEventListener implements ProcessEventListener {
|
|||||||
List<ProcessTaskActor> taskActors = dao.query(ProcessTaskActor.class, Cnd.where(ProcessTaskActor::getProcessTaskId, "=", task.getId()));
|
List<ProcessTaskActor> taskActors = dao.query(ProcessTaskActor.class, Cnd.where(ProcessTaskActor::getProcessTaskId, "=", task.getId()));
|
||||||
|
|
||||||
for (ProcessTaskActor taskActor : taskActors) {
|
for (ProcessTaskActor taskActor : taskActors) {
|
||||||
|
|
||||||
|
JSONObject config = new JSONObject();
|
||||||
|
config.set("pcUrl", Globals.AppDomain + task.getFormKey());
|
||||||
|
|
||||||
// 模拟发送消息
|
// 模拟发送消息
|
||||||
String message = StrUtil.format("您有一条待办任务,实例:{},处理环节:{}", instanceName, taskDisplayName);
|
String message = "";
|
||||||
|
if(StrUtil.isNotBlank(task.getH5FormKey())) {
|
||||||
|
config.set("mobileUrl", Globals.AppDomain + task.getH5FormKey());
|
||||||
|
message = StrUtil.format("您有一条待办任务,实例:{},处理环节:{}。", instanceName, taskDisplayName);
|
||||||
|
} else {
|
||||||
|
config.set("mobileUrl", Globals.AppDomain + "/platform/tooltip/h5");
|
||||||
|
message = StrUtil.format("您有一条待办任务,实例:{},处理环节:{},请到电脑端智慧工会系统审核。", instanceName, taskDisplayName);
|
||||||
|
}
|
||||||
log.info(message);
|
log.info(message);
|
||||||
globalMessageSendService.sendMessage(taskDisplayName, message, 2, List.of(taskActor.getActorId()), null);
|
|
||||||
|
globalMessageSendService.sendMessage(taskDisplayName, message, 2, List.of(taskActor.getActorId()), config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+88
@@ -0,0 +1,88 @@
|
|||||||
|
package com.budwk.app.zhgh.dayofficework.message.strategy.impl;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import com.budwk.app.base.sms.SmsService;
|
||||||
|
import com.budwk.app.base.sms.WechatEnterpriseService;
|
||||||
|
import com.budwk.app.sys.models.Sys_user;
|
||||||
|
import com.budwk.app.zhgh.dayofficework.message.enums.GlobalMessageChannel;
|
||||||
|
import com.budwk.app.zhgh.dayofficework.message.strategy.GlobalMessageSendStrategy;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.nutz.dao.Cnd;
|
||||||
|
import org.nutz.dao.Dao;
|
||||||
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.lang.Lang;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName WechatEnterpriseMessageSendStrategy
|
||||||
|
* @Author JyuHsin
|
||||||
|
* @Date 2026/2/27 15:42
|
||||||
|
* @Version 1.0
|
||||||
|
* @Description TODO
|
||||||
|
*/
|
||||||
|
@IocBean
|
||||||
|
@Slf4j
|
||||||
|
public class WechatEnterpriseMessageSendStrategy implements GlobalMessageSendStrategy {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Dao dao;
|
||||||
|
@Inject
|
||||||
|
private WechatEnterpriseService wechatService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GlobalMessageChannel getChannel() {
|
||||||
|
return GlobalMessageChannel.WECHAT_ENTERPRISE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportAsync() {
|
||||||
|
return GlobalMessageSendStrategy.super.supportAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void send(String title, String content, Integer type, List<String> receiverIds, JSONObject config) {
|
||||||
|
try {
|
||||||
|
log.info("开始发送企业微信消息,标题:{},接收人数量:{}", title, receiverIds.size());
|
||||||
|
|
||||||
|
// 查询用户手机号
|
||||||
|
List<Sys_user> users = dao.query(Sys_user.class, Cnd.where(Sys_user::getId, "in", receiverIds));
|
||||||
|
sendMessage(title, content, type, users, config);
|
||||||
|
|
||||||
|
log.info("企业微信消息发送完成,标题:{},接收人数量:{}", title, users.size());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("企业微信消息发送失败,标题:{},错误:{}", title, e.getMessage(), e);
|
||||||
|
throw new RuntimeException("企业微信消息发送失败:" + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendByLoginName(String title, String content, Integer type, List<String> receiverLoginNames, JSONObject config) {
|
||||||
|
try {
|
||||||
|
log.info("开始发送企业微信消息(按登录名),标题:{},接收人数量:{}", title, receiverLoginNames.size());
|
||||||
|
|
||||||
|
// 查询用户手机号
|
||||||
|
List<Sys_user> users = dao.query(Sys_user.class, Cnd.where(Sys_user::getLoginname, "in", receiverLoginNames));
|
||||||
|
sendMessage(title, content, type, users, config);
|
||||||
|
|
||||||
|
log.info("企业微信消息发送完成(按登录名),标题:{},接收人数量:{}", title, users.size());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("企业微信消息发送失败(按登录名),标题:{},错误:{}", title, e.getMessage(), e);
|
||||||
|
throw new RuntimeException("企业微信消息发送失败:" + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendMessage(String title, String content, Integer type, List<Sys_user> users, JSONObject config) {
|
||||||
|
if(Lang.isEmpty(users)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<String> list = users.stream().map(Sys_user::getLoginname).toList();
|
||||||
|
wechatService.massSendTextCard(list, "智慧工会", content, config.getStr("pcUrl"), config.getStr("mobileUrl"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.budwk.app.zhgh.tooltip.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.mvc.annotation.At;
|
||||||
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName TooltipCommonController
|
||||||
|
* @Author JyuHsin
|
||||||
|
* @Date 2026/3/10 16:14
|
||||||
|
* @Version 1.0
|
||||||
|
* @Description TODO
|
||||||
|
*/
|
||||||
|
@IocBean
|
||||||
|
@Ok("json:full")
|
||||||
|
@At("/platform/tooltip")
|
||||||
|
public class TooltipCommonController {
|
||||||
|
|
||||||
|
@At("/h5")
|
||||||
|
@Ok("beetl:platform/zhghh5/tooltip/index.html")
|
||||||
|
@SaCheckLogin
|
||||||
|
public void index() {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
<!--#
|
||||||
|
layout("/layouts/platform_h5.html"){
|
||||||
|
#-->
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
body {
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
.weui-msg {
|
||||||
|
background: white;
|
||||||
|
height: auto;
|
||||||
|
min-height: auto;
|
||||||
|
}
|
||||||
|
.weui-msg__title {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
.weui-msg__msg {
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="app">
|
||||||
|
<div class="weui-msg">
|
||||||
|
<div class="weui-msg__icon-area">
|
||||||
|
<i class="weui-icon-info weui-icon_msg"></i>
|
||||||
|
</div>
|
||||||
|
<div class="weui-msg__text-area">
|
||||||
|
<div class="weui-msg__title">温馨提醒</div>
|
||||||
|
<div class="weui-msg__msg">请到电脑端智慧工会系统审核</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script nonce="${cspNonce!}">
|
||||||
|
const vue = new Vue({
|
||||||
|
el: "#app",
|
||||||
|
store,
|
||||||
|
components: {},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--#
|
||||||
|
}
|
||||||
|
#-->
|
||||||
Reference in New Issue
Block a user