体检统计:"给未选发送消息"bug整改,改成分批发送用户
This commit is contained in:
@@ -107,6 +107,20 @@ public interface SmsService {
|
|||||||
*/
|
*/
|
||||||
void massSendTextCard(List<String> loginNames, String title, String content, String pcUrl, String mobileUrl);
|
void massSendTextCard(List<String> loginNames, String title, String content, String pcUrl, String mobileUrl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群发短信文本卡片消息
|
||||||
|
* @param loginNames 接收人工号列表(必填,不能为空列表)
|
||||||
|
* @param content 卡片内容(必填)
|
||||||
|
* @param pcUrl PC端跳转链接(必填)
|
||||||
|
* @param mobileUrl 移动端跳转链接(必填)
|
||||||
|
* @param type 类型(如:体检管理)
|
||||||
|
* @param projectName 项目名称
|
||||||
|
* @param remark 备注信息
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void massSendTextCard(List<String> loginNames, String content, String pcUrl, String mobileUrl, String type, String projectName, String remark);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 群发图文卡片消息
|
* 群发图文卡片消息
|
||||||
* @param loginNames 接收人工号列表(必填,不能为空列表)
|
* @param loginNames 接收人工号列表(必填,不能为空列表)
|
||||||
|
|||||||
@@ -1,21 +1,29 @@
|
|||||||
package com.budwk.app.base.sms.impl.ncu;
|
package com.budwk.app.base.sms.impl.ncu;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.ListUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.http.HttpUtil;
|
import cn.hutool.http.HttpUtil;
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.budwk.app.base.sms.SmsService;
|
import com.budwk.app.base.sms.SmsService;
|
||||||
import com.budwk.app.base.sms.impl.ncu.util.SmsTokenUtil;
|
import com.budwk.app.base.sms.impl.ncu.util.SmsTokenUtil;
|
||||||
|
import com.budwk.app.sys.models.Sys_msg;
|
||||||
|
import com.budwk.app.sys.models.Sys_msg_user;
|
||||||
|
import com.budwk.app.sys.views.View_user;
|
||||||
|
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||||
import com.budwk.app.web.commons.base.Globals;
|
import com.budwk.app.web.commons.base.Globals;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.poi.ss.formula.functions.T;
|
||||||
|
import org.nutz.dao.Cnd;
|
||||||
|
import org.nutz.dao.Dao;
|
||||||
import org.nutz.ioc.loader.annotation.Inject;
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
import org.nutz.json.Json;
|
import org.nutz.json.Json;
|
||||||
import org.nutz.lang.Lang;
|
import org.nutz.lang.Lang;
|
||||||
|
import org.nutz.lang.Times;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@@ -29,6 +37,8 @@ public class SmsNcuServiceImpl implements SmsService {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private SmsTokenUtil smsTokenUtil;
|
private SmsTokenUtil smsTokenUtil;
|
||||||
|
@Inject
|
||||||
|
private Dao dao;
|
||||||
|
|
||||||
private static final String SEND_MSG_URL = "https://poa.ncu.edu.cn/apis/messagecenter/v1/poaMessage/messageSend";
|
private static final String SEND_MSG_URL = "https://poa.ncu.edu.cn/apis/messagecenter/v1/poaMessage/messageSend";
|
||||||
private static final String APP_ID = "72e34a101d3011f1a74cbae5193504f4";
|
private static final String APP_ID = "72e34a101d3011f1a74cbae5193504f4";
|
||||||
@@ -71,8 +81,7 @@ public class SmsNcuServiceImpl implements SmsService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void massSendMessage(List<String> loginNames, String title, String content) {
|
public void massSendMessage(List<String> loginNames, String title, String content) {
|
||||||
String list = String.join(",", loginNames);
|
this.doSend("text", loginNames, title, content, null, null, null);
|
||||||
this.doSend("text", list, title, content, null, null, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -82,8 +91,12 @@ public class SmsNcuServiceImpl implements SmsService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void massSendTextCard(List<String> loginNames, String title, String content, String pcUrl, String mobileUrl) {
|
public void massSendTextCard(List<String> loginNames, String title, String content, String pcUrl, String mobileUrl) {
|
||||||
String list = String.join(",", loginNames);
|
this.doSend("textCard", loginNames, title, content, pcUrl, mobileUrl, null);
|
||||||
this.doSend("textCard", list, title, content, pcUrl, mobileUrl, null);
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void massSendTextCard(List<String> loginNames, String content, String pcUrl, String mobileUrl, String type, String projectName, String remark) {
|
||||||
|
this.doSendAndMessageRecordByType("textCard", loginNames, "智慧工会", content, pcUrl, mobileUrl, null, type, projectName, remark);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -93,12 +106,11 @@ public class SmsNcuServiceImpl implements SmsService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void massSendPicTextCard(List<String> loginNames, String title, String content, String pcUrl, String mobileUrl, String picUrl) {
|
public void massSendPicTextCard(List<String> loginNames, String title, String content, String pcUrl, String mobileUrl, String picUrl) {
|
||||||
String list = String.join(",", loginNames);
|
this.doSend("news", loginNames, title, content, pcUrl, mobileUrl, picUrl);
|
||||||
this.doSend("news", list, title, content, pcUrl, mobileUrl, picUrl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doSend(String sendType,
|
private void doSend(String sendType,
|
||||||
String receivers,
|
List<String> loginNames,
|
||||||
String title,
|
String title,
|
||||||
String content,
|
String content,
|
||||||
String pcUrl,
|
String pcUrl,
|
||||||
@@ -113,6 +125,7 @@ public class SmsNcuServiceImpl implements SmsService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String receivers = String.join(",", loginNames);
|
||||||
if (Lang.isEmpty(receivers)) {
|
if (Lang.isEmpty(receivers)) {
|
||||||
log.error("【log】send fail by receivers is null");
|
log.error("【log】send fail by receivers is null");
|
||||||
return;
|
return;
|
||||||
@@ -168,4 +181,168 @@ public class SmsNcuServiceImpl implements SmsService {
|
|||||||
log.error("【log】发送消息通知失败", e);
|
log.error("【log】发送消息通知失败", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息发送 成功后记录消息信息
|
||||||
|
*
|
||||||
|
* @param sendType
|
||||||
|
* @param loginNames
|
||||||
|
* @param title
|
||||||
|
* @param content
|
||||||
|
* @param pcUrl
|
||||||
|
* @param mobileUrl
|
||||||
|
* @param projectName
|
||||||
|
* @param type
|
||||||
|
* @param remark
|
||||||
|
*/
|
||||||
|
private void doSendAndMessageRecordByType(String sendType, List<String> loginNames, String title,
|
||||||
|
String content, String pcUrl, String mobileUrl, String picUrl, String type, String projectName, String remark) {
|
||||||
|
if (!Globals.sso) {
|
||||||
|
log.error("【log】本地开发模式不允许调用消息接口");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Globals.MyConfig.getBoolean("AppNotify", false)) {
|
||||||
|
log.error("【log】消息配置未开启");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//消息推送记录
|
||||||
|
long time = Times.getTS();
|
||||||
|
String userId = SecurityUtil.getUserId();
|
||||||
|
Sys_msg sysMsg = new Sys_msg();
|
||||||
|
sysMsg.setType(type);
|
||||||
|
sysMsg.setTitle(projectName);
|
||||||
|
sysMsg.setNote(content);
|
||||||
|
sysMsg.setSendAt(time);
|
||||||
|
sysMsg.setCreatedBy(userId);
|
||||||
|
sysMsg.setCreatedAt(time);
|
||||||
|
sysMsg.setUpdatedBy(userId);
|
||||||
|
sysMsg.setUpdatedAt(time);
|
||||||
|
sysMsg.setDelFlag(false);
|
||||||
|
sysMsg.setSendType("show");
|
||||||
|
List<Sys_msg_user> sysMsgUsersInsert = new ArrayList<>();
|
||||||
|
|
||||||
|
List<List<String>> loginNameLists = chunkList(loginNames, 50);
|
||||||
|
for (List<String> loginNameList : loginNameLists) {
|
||||||
|
String receivers = String.join(",", loginNameList);
|
||||||
|
if (Lang.isEmpty(receivers)) {
|
||||||
|
log.error("【log】send fail by receivers is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Sys_msg_user> sysMsgUsers = loginNameList.stream().map(loginName -> {
|
||||||
|
Sys_msg_user sysMsgUser = new Sys_msg_user();
|
||||||
|
sysMsgUser.setLoginname(loginName);
|
||||||
|
sysMsgUser.setReadAt(Times.getTS());
|
||||||
|
sysMsgUser.setCreatedAt(time);
|
||||||
|
sysMsgUser.setCreatedBy(userId);
|
||||||
|
sysMsgUser.setUpdatedAt(time);
|
||||||
|
sysMsgUser.setUpdatedBy(userId);
|
||||||
|
sysMsgUser.setDelFlag(false);
|
||||||
|
return sysMsgUser;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
try {
|
||||||
|
String token = smsTokenUtil.getToken();
|
||||||
|
if (Lang.isEmpty(token)) {
|
||||||
|
log.error("【log】send fail by token is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("appId", APP_ID);
|
||||||
|
params.put("sendId", "");
|
||||||
|
params.put("sendType", Stream.of("WECHAT").toArray());
|
||||||
|
params.put("messageTypeCode", TEMPLATE_ID);
|
||||||
|
params.put("promise", false);
|
||||||
|
params.put("importantIdentity", false);
|
||||||
|
params.put("toPersons", receivers);
|
||||||
|
|
||||||
|
Map<String, Object> dataParams = new HashMap<>();
|
||||||
|
dataParams.put("title", title);
|
||||||
|
dataParams.put("paramValueJson", Map.of("content", content));
|
||||||
|
|
||||||
|
if ("textCard".equals(sendType)) {
|
||||||
|
dataParams.put("url", pcUrl);
|
||||||
|
dataParams.put("mobileUrl", mobileUrl);
|
||||||
|
}
|
||||||
|
if ("news".equals(sendType)) {
|
||||||
|
dataParams.put("url", pcUrl);
|
||||||
|
dataParams.put("mobileUrl", mobileUrl);
|
||||||
|
dataParams.put("coverImageUrl", picUrl);
|
||||||
|
}
|
||||||
|
params.put("data", dataParams);
|
||||||
|
|
||||||
|
log.info("【log】发送消息通知,请求参数:{}", Json.toJson(params));
|
||||||
|
String body = HttpUtil.createPost(SEND_MSG_URL)
|
||||||
|
.header("Authorization", token)
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.body(Json.toJson(params)).execute().body();
|
||||||
|
JSONObject resultJsonBody = JSONUtil.parseObj(body);
|
||||||
|
log.info("【log】发送消息通知,接口响应数据:{}", body);
|
||||||
|
Integer codeStatus = resultJsonBody.getInt("code");
|
||||||
|
|
||||||
|
if (codeStatus == 0) {
|
||||||
|
log.info("【log】发送消息通知成功");
|
||||||
|
for (Sys_msg_user sysMsgUser : sysMsgUsers) {
|
||||||
|
sysMsgUser.setBackStatus(codeStatus);
|
||||||
|
sysMsgUser.setBackText("发送成功");
|
||||||
|
}
|
||||||
|
sysMsgUsersInsert.addAll(sysMsgUsers);
|
||||||
|
} else {
|
||||||
|
String message = resultJsonBody.getStr("message");
|
||||||
|
for (Sys_msg_user sysMsgUser : sysMsgUsers) {
|
||||||
|
sysMsgUser.setBackStatus(codeStatus);
|
||||||
|
sysMsgUser.setBackText(message);
|
||||||
|
}
|
||||||
|
sysMsgUsersInsert.addAll(sysMsgUsers);
|
||||||
|
log.info("【log】发送消息通知失败:{}", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
String message = "发送失败,接口异常:"+e.getMessage();
|
||||||
|
for (Sys_msg_user sysMsgUser : sysMsgUsers) {
|
||||||
|
sysMsgUser.setBackStatus(500);
|
||||||
|
sysMsgUser.setBackText(message);
|
||||||
|
}
|
||||||
|
sysMsgUsersInsert.addAll(sysMsgUsers);
|
||||||
|
log.error("【log】发送消息通知失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//记录发送状态及消息
|
||||||
|
Set<String> loginNameSet = sysMsgUsersInsert.stream().map(Sys_msg_user::getLoginname).collect(Collectors.toSet());
|
||||||
|
List<View_user> viewUsers = dao.query(View_user.class, Cnd.where("loginname", "in", loginNameSet));
|
||||||
|
for (Sys_msg_user sysMsgUser : sysMsgUsersInsert) {
|
||||||
|
String loginname = sysMsgUser.getLoginname();
|
||||||
|
View_user viewUser = viewUsers.stream().filter(e -> e.getLoginname().equals(loginname)).findFirst().orElse(null);
|
||||||
|
if(ObjectUtil.isNotEmpty(viewUser)) {
|
||||||
|
sysMsgUser.setUserName(viewUser.getUsername());
|
||||||
|
sysMsgUser.setUnitId(viewUser.getUnitId());
|
||||||
|
sysMsgUser.setUnitName(viewUser.getUnitName());
|
||||||
|
sysMsgUser.setUnionId(viewUser.getUnionId());
|
||||||
|
sysMsgUser.setUnionName(viewUser.getUnionName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sys_msg sys_msg = dao.insert(sysMsg);
|
||||||
|
for (Sys_msg_user sysMsgUser : sysMsgUsersInsert) {
|
||||||
|
sysMsgUser.setMsgId(sys_msg.getId());
|
||||||
|
}
|
||||||
|
dao.insert(sysMsgUsersInsert);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不安全的集合
|
||||||
|
*
|
||||||
|
* @param list 需要拆分的集合
|
||||||
|
* @param chunkSize 以多少条数据进行拆分; 每个新集合多少条数据
|
||||||
|
* @param <T>
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static <T> List<List<T>> chunkList(List<T> list, int chunkSize) {
|
||||||
|
List<List<T>> chunks = new CopyOnWriteArrayList<>();
|
||||||
|
for (int i = 0; i < list.size(); i += chunkSize) {
|
||||||
|
chunks.add(list.subList(i, Math.min(i + chunkSize, list.size())));
|
||||||
|
}
|
||||||
|
return chunks;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.nutz.dao.interceptor.annotation.PrevInsert;
|
|||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
@@ -72,4 +73,9 @@ public class Sys_msg extends BaseModel implements Serializable {
|
|||||||
@ColDefine(type = ColType.VARCHAR, width = 10)
|
@ColDefine(type = ColType.VARCHAR, width = 10)
|
||||||
private String sendType;
|
private String sendType;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("备注")
|
||||||
|
@ColDefine(type = ColType.TEXT)
|
||||||
|
private String remarks;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,11 @@ public class Sys_msg_user extends BaseModel implements Serializable {
|
|||||||
@One(field = "msgId")
|
@One(field = "msgId")
|
||||||
private Sys_msg msg;
|
private Sys_msg msg;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("发送状态")
|
||||||
|
@ColDefine(type = ColType.INT)
|
||||||
|
private Integer backStatus;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("反馈内容")
|
@Comment("反馈内容")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 500)
|
@ColDefine(type = ColType.VARCHAR, width = 500)
|
||||||
|
|||||||
+4
-1
@@ -447,7 +447,10 @@ public class HealthCheckupSingleController {
|
|||||||
smsService.massSendTextCard(loginNameList,
|
smsService.massSendTextCard(loginNameList,
|
||||||
smsMessage,
|
smsMessage,
|
||||||
"#",
|
"#",
|
||||||
Globals.AppDomain);
|
Globals.AppDomain,
|
||||||
|
"healthCheckup",
|
||||||
|
project.getName(),
|
||||||
|
"未体检人员消息提醒");
|
||||||
return Result.success("提醒成功");
|
return Result.success("提醒成功");
|
||||||
} else {
|
} else {
|
||||||
return Result.success("不存在未体检人员");
|
return Result.success("不存在未体检人员");
|
||||||
|
|||||||
Reference in New Issue
Block a user