福利发消息整改
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package com.budwk.app.base.sms;
|
||||
|
||||
import com.budwk.app.sys.models.Sys_user;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -47,6 +48,15 @@ public interface SmsService {
|
||||
* @param content 消息正文
|
||||
* @param pcUrl PC端跳转链接
|
||||
* @param mobileUrl 手机端跳转链接
|
||||
* @return 统一消息平台返回的消息标识集合;每个标识可用于查询该批消息的最终发送结果
|
||||
*/
|
||||
void massSendByUsers(List<Sys_user> users, String title, String content, String pcUrl, String mobileUrl);
|
||||
List<String> massSendByUsers(List<Sys_user> users, String title, String content, String pcUrl, String mobileUrl);
|
||||
|
||||
/**
|
||||
* 查询学校统一消息平台的批量发送结果。
|
||||
*
|
||||
* @param messageId 批量发送接口返回的消息标识;同一批次的接收人使用该标识查询最终送达结果
|
||||
* @return 查询结果,包含消息总数、成功数、失败数及失败接收人数组;调用失败时抛出业务异常
|
||||
*/
|
||||
NutMap getMessageResult(String messageId);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.nutz.json.Json;
|
||||
import org.nutz.lang.Lang;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -66,12 +67,18 @@ public class SmsYpiServiceImpl implements SmsService {
|
||||
* 兼容统一消息V4新增的批量发送接口;旧版实现不再注册为发送服务,仅保留历史调用能力。
|
||||
*/
|
||||
@Override
|
||||
public void massSendByUsers(List<Sys_user> users, String title, String content, String pcUrl, String mobileUrl) {
|
||||
public List<String> massSendByUsers(List<Sys_user> users, String title, String content, String pcUrl, String mobileUrl) {
|
||||
List<String> loginNames = users.stream()
|
||||
.map(Sys_user::getLoginname)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.toList();
|
||||
massSend(loginNames, title, content, StrUtil.blankToDefault(mobileUrl, pcUrl));
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NutMap getMessageResult(String messageId) {
|
||||
throw new UnsupportedOperationException("旧版学校消息网关不支持统一消息V4发送结果查询");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.nutz.integration.jedis.RedisService;
|
||||
import org.nutz.ioc.impl.PropertiesProxy;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -63,9 +64,9 @@ public class UnifiedMessageV4ServiceImpl implements SmsService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void massSendByUsers(List<Sys_user> users, String title, String content, String pcUrl, String mobileUrl) {
|
||||
public List<String> massSendByUsers(List<Sys_user> users, String title, String content, String pcUrl, String mobileUrl) {
|
||||
if (users == null || users.isEmpty()) {
|
||||
return;
|
||||
return List.of();
|
||||
}
|
||||
List<Receiver> receivers = users.stream()
|
||||
.filter(user -> StrUtil.isNotBlank(user.getLoginname()) && StrUtil.isNotBlank(user.getUsername()))
|
||||
@@ -74,13 +75,14 @@ public class UnifiedMessageV4ServiceImpl implements SmsService {
|
||||
if (receivers.isEmpty()) {
|
||||
throw new BaseException("学校统一消息发送失败:接收人工号或姓名不能为空");
|
||||
}
|
||||
sendMessage(title, content, createReceivers(receivers), pcUrl, mobileUrl);
|
||||
return sendMessage(title, content, createReceivers(receivers), pcUrl, mobileUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用统一消息V4普通消息接口;有链接时按外链模式同时传递PC和手机端地址。
|
||||
* 返回值为平台入队后生成的消息标识集合,供业务侧随后查询最终逐人发送结果。
|
||||
*/
|
||||
private void sendMessage(String title, String content, JSONArray receivers, String pcUrl, String mobileUrl) {
|
||||
private List<String> sendMessage(String title, String content, JSONArray receivers, String pcUrl, String mobileUrl) {
|
||||
String token = getAccessToken();
|
||||
boolean hasLink = StrUtil.isNotBlank(pcUrl) || StrUtil.isNotBlank(mobileUrl);
|
||||
JSONObject body = JSONUtil.createObj();
|
||||
@@ -108,7 +110,20 @@ public class UnifiedMessageV4ServiceImpl implements SmsService {
|
||||
if (response.getInt("state", 0) != 200) {
|
||||
throw new BaseException("学校统一消息发送失败:{}", response.getStr("message", responseBody));
|
||||
}
|
||||
log.info("学校统一消息发送成功,接收人数量={},response={}", receivers.size(), responseBody);
|
||||
JSONArray messageIdArray = response.getJSONArray("data");
|
||||
if (messageIdArray == null || messageIdArray.isEmpty()) {
|
||||
throw new BaseException("学校统一消息发送失败:平台未返回消息标识");
|
||||
}
|
||||
List<String> messageIds = messageIdArray.stream()
|
||||
.map(String::valueOf)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.toList();
|
||||
if (messageIds.isEmpty()) {
|
||||
throw new BaseException("学校统一消息发送失败:平台返回的消息标识为空");
|
||||
}
|
||||
log.info("学校统一消息发送已入队,接收人数量={},messageIds={},response={}",
|
||||
receivers.size(), messageIds, responseBody);
|
||||
return messageIds;
|
||||
} catch (BaseException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
@@ -117,6 +132,47 @@ public class UnifiedMessageV4ServiceImpl implements SmsService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用统一消息V4结果查询接口。
|
||||
* 参数为批量发送返回的messageId;返回NutMap中的messageTotal、successCount、failCount、resultState和failedUsers
|
||||
* 分别表示平台统计的总人数、成功人数、失败人数、结果状态和失败用户明细。
|
||||
*/
|
||||
@Override
|
||||
public NutMap getMessageResult(String messageId) {
|
||||
if (StrUtil.isBlank(messageId)) {
|
||||
throw new BaseException("学校统一消息结果查询失败:消息标识不能为空");
|
||||
}
|
||||
String resultUrl = getRequiredConfig("school-message.result-url").replace("{messageId}", messageId);
|
||||
try {
|
||||
HttpRequest request = HttpRequest.post(resultUrl)
|
||||
.header("domain-name", getRequiredConfig("school-message.domain-name"))
|
||||
.header("token", getAccessToken());
|
||||
addInterceptDomainHeader(request);
|
||||
String responseBody = request.execute().body();
|
||||
JSONObject response = JSONUtil.parseObj(responseBody);
|
||||
if (response.getInt("state", 0) != 200 || response.getJSONObject("data") == null) {
|
||||
throw new BaseException("学校统一消息结果查询失败:{}", response.getStr("message", responseBody));
|
||||
}
|
||||
JSONObject data = response.getJSONObject("data");
|
||||
NutMap result = NutMap.NEW()
|
||||
.addv("messageId", messageId)
|
||||
.addv("messageTotal", data.getInt("msgTotal", 0))
|
||||
.addv("resultState", data.getStr("state"))
|
||||
.addv("successCount", data.getInt("successCount", 0))
|
||||
.addv("failCount", data.getInt("failCount", 0))
|
||||
.addv("failedUsers", data.getJSONArray("user"));
|
||||
log.info("学校统一消息结果查询成功,messageId={},messageTotal={},successCount={},failCount={},resultState={}",
|
||||
messageId, result.getInt("messageTotal", 0), result.getInt("successCount", 0),
|
||||
result.getInt("failCount", 0), result.getString("resultState"));
|
||||
return result;
|
||||
} catch (BaseException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.error("学校统一消息结果查询异常,url={},messageId={}", resultUrl, messageId, e);
|
||||
throw new BaseException("学校统一消息结果查询异常:{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取学校统一消息V4令牌;文档有效期为300秒,缓存270秒避免临界过期。
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.budwk.app.flow.param;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 学校OA批量待办创建参数。
|
||||
* 公共流程字段在本对象中传递,接收人差异字段放在userList中,对应学校OA的/handle/batch/insert接口。
|
||||
*/
|
||||
@Data
|
||||
public class SchoolOaTodoBatchCreateParam {
|
||||
|
||||
private String flowTypeName;
|
||||
private String flowId;
|
||||
private String title;
|
||||
private String stepName;
|
||||
private String creatorCode;
|
||||
private String creatorName;
|
||||
private String creatorTime;
|
||||
private String startPcPreviewUrl;
|
||||
private String startAppPreviewUrl;
|
||||
private List<SchoolOaTodoReceiverParam> userList;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.budwk.app.flow.param;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 学校OA批量待办中的单个接收人参数,对应批量接口userList数组的一个元素。
|
||||
*/
|
||||
@Data
|
||||
public class SchoolOaTodoReceiverParam {
|
||||
|
||||
private String pcUrl;
|
||||
private String appUrl;
|
||||
private String uniqueId;
|
||||
private String receiveCode;
|
||||
private String receiveName;
|
||||
private String receiveTime;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.budwk.app.flow.service;
|
||||
|
||||
import com.budwk.app.flow.entity.ProcessTask;
|
||||
import com.budwk.app.flow.param.SchoolOaTodoBatchCreateParam;
|
||||
|
||||
/**
|
||||
* 学校 OA 待办同步服务。
|
||||
@@ -43,30 +44,17 @@ public interface SchoolOaTodoService {
|
||||
void updateFlowFinishedStepName(Long processInstanceId);
|
||||
|
||||
/**
|
||||
* 创建福利选择提醒待办。
|
||||
* 创建学校OA批量待办。
|
||||
*
|
||||
* @param projectId 福利项目ID,用于构造学校OA业务标识
|
||||
* @param title 待办标题,学校OA接口没有独立正文时用于展示提醒内容
|
||||
* @param pcUrl PC端福利选择地址
|
||||
* @param appUrl 手机端福利选择地址
|
||||
* @param creatorId 待办创建人ID
|
||||
* @param receiverId 待办接收人ID
|
||||
* @return 学校OA待办唯一值
|
||||
* @param todoParam 批量待办公共字段及userList接收人数组
|
||||
*/
|
||||
String createWelfareReminderTodo(String projectId, String title, String pcUrl, String appUrl, String creatorId, String receiverId);
|
||||
void createBatchTodo(SchoolOaTodoBatchCreateParam todoParam);
|
||||
|
||||
/**
|
||||
* 将指定的学校OA福利提醒待办改为已办。
|
||||
* 根据待办唯一值将学校OA待办改为已办。
|
||||
*
|
||||
* @param uniqueId 创建待办时记录的学校OA唯一值
|
||||
* @param uniqueId 创建待办时传入的唯一标识
|
||||
*/
|
||||
void completeWelfareReminderTodo(String uniqueId);
|
||||
void completeTodoByUniqueId(String uniqueId);
|
||||
|
||||
/**
|
||||
* 删除用户已完成福利选择对应的学校OA提醒待办。
|
||||
*
|
||||
* @param projectId 福利项目ID
|
||||
* @param userId 完成选择的用户ID
|
||||
*/
|
||||
void deleteWelfareReminderTodo(String projectId, String userId);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ import com.budwk.app.flow.entity.ProcessInstance;
|
||||
import com.budwk.app.flow.entity.ProcessTask;
|
||||
import com.budwk.app.flow.entity.ProcessTaskActor;
|
||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||
import com.budwk.app.flow.param.SchoolOaTodoBatchCreateParam;
|
||||
import com.budwk.app.flow.param.SchoolOaTodoReceiverParam;
|
||||
import com.budwk.app.flow.service.SchoolOaTodoService;
|
||||
import com.budwk.app.sys.models.Sys_user;
|
||||
import com.budwk.app.web.commons.base.Globals;
|
||||
@@ -27,6 +29,7 @@ import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -201,48 +204,63 @@ public class SchoolOaTodoServiceImpl implements SchoolOaTodoService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createWelfareReminderTodo(String projectId, String title, String pcUrl, String appUrl, String creatorId, String receiverId) {
|
||||
if (!isSchoolOaEnabled("创建福利选择提醒待办", null, null)) {
|
||||
return null;
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void createBatchTodo(SchoolOaTodoBatchCreateParam todoParam) {
|
||||
if (!isSchoolOaEnabled("创建批量待办", null, null)) {
|
||||
throw new BaseException("学校OA待办开关状态已变化,本次待办未发送");
|
||||
}
|
||||
if (StrUtil.hasBlank(projectId, title, pcUrl, appUrl, creatorId, receiverId)) {
|
||||
throw new BaseException("学校OA福利选择提醒待办参数不完整");
|
||||
if (todoParam == null || StrUtil.hasBlank(todoParam.getFlowTypeName(), todoParam.getFlowId(), todoParam.getTitle(),
|
||||
todoParam.getStepName(), todoParam.getCreatorCode(), todoParam.getCreatorName(), todoParam.getCreatorTime(),
|
||||
todoParam.getStartPcPreviewUrl(), todoParam.getStartAppPreviewUrl())
|
||||
|| todoParam.getUserList() == null || todoParam.getUserList().isEmpty()) {
|
||||
throw new BaseException("学校OA批量待办创建参数不完整");
|
||||
}
|
||||
|
||||
Sys_user creator = dao.fetch(Sys_user.class, creatorId);
|
||||
if (creator == null || StrUtil.hasBlank(creator.getLoginname(), creator.getUsername())) {
|
||||
throw new BaseException("学校OA福利选择提醒待办创建人工号或姓名为空,userId={}", creatorId);
|
||||
List<JSONObject> userList = new ArrayList<>();
|
||||
for (SchoolOaTodoReceiverParam receiverParam : todoParam.getUserList()) {
|
||||
if (receiverParam == null || StrUtil.hasBlank(receiverParam.getPcUrl(), receiverParam.getAppUrl(),
|
||||
receiverParam.getUniqueId(), receiverParam.getReceiveCode(), receiverParam.getReceiveName(),
|
||||
receiverParam.getReceiveTime())) {
|
||||
throw new BaseException("学校OA批量待办接收人参数不完整");
|
||||
}
|
||||
JSONObject receiverBody = new JSONObject();
|
||||
receiverBody.set("pcUrl", receiverParam.getPcUrl());
|
||||
receiverBody.set("appUrl", receiverParam.getAppUrl());
|
||||
receiverBody.set("uniqueId", receiverParam.getUniqueId());
|
||||
receiverBody.set("receiveCode", receiverParam.getReceiveCode());
|
||||
receiverBody.set("receiveName", receiverParam.getReceiveName());
|
||||
receiverBody.set("receiveTime", receiverParam.getReceiveTime());
|
||||
userList.add(receiverBody);
|
||||
}
|
||||
|
||||
Sys_user receiver = dao.fetch(Sys_user.class, receiverId);
|
||||
if (receiver == null || StrUtil.hasBlank(receiver.getLoginname(), receiver.getUsername())) {
|
||||
throw new BaseException("学校OA福利选择提醒待办接收人工号或姓名为空,userId={}", receiverId);
|
||||
}
|
||||
return sendWelfareReminderTodo(projectId, title, pcUrl, appUrl, creator, receiver,
|
||||
formatTime(System.currentTimeMillis()));
|
||||
// 学校OA批量接口的公共流程字段在根节点,接收人差异字段仅放在userList中。
|
||||
JSONObject body = new JSONObject();
|
||||
body.set("flowTypeName", todoParam.getFlowTypeName());
|
||||
body.set("flowId", todoParam.getFlowId());
|
||||
body.set("title", todoParam.getTitle());
|
||||
body.set("stepName", todoParam.getStepName());
|
||||
body.set("creatorCode", todoParam.getCreatorCode());
|
||||
body.set("creatorName", todoParam.getCreatorName());
|
||||
body.set("creatorTime", todoParam.getCreatorTime());
|
||||
body.set("startPcPreviewUrl", todoParam.getStartPcPreviewUrl());
|
||||
body.set("startAppPreviewUrl", todoParam.getStartAppPreviewUrl());
|
||||
body.set("userList", userList);
|
||||
|
||||
String batchInsertUrl = requireConfig("school-oa.todo.batch-insert-url");
|
||||
String responseBody = sendTodoRequest(batchInsertUrl, body, "学校OA批量待办创建失败", "学校OA批量待办创建异常");
|
||||
log.info("学校OA批量待办创建成功,flowId={},receiverCount={},response={}",
|
||||
todoParam.getFlowId(), userList.size(), responseBody);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completeWelfareReminderTodo(String uniqueId) {
|
||||
if (!isSchoolOaEnabled("完成福利选择提醒待办", null, null) || StrUtil.isBlank(uniqueId)) {
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void completeTodoByUniqueId(String uniqueId) {
|
||||
if (!isSchoolOaEnabled("完成待办", null, null) || StrUtil.isBlank(uniqueId)) {
|
||||
return;
|
||||
}
|
||||
String updateUrl = requireConfig("school-oa.todo.update-url").replace("{uniqueId}", uniqueId);
|
||||
String responseBody = sendTodoRequest(updateUrl,
|
||||
"学校OA福利选择提醒待办完成失败", "学校OA福利选择提醒待办完成异常");
|
||||
log.info("学校OA福利选择提醒待办完成成功,uniqueId={},response={}", uniqueId, responseBody);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteWelfareReminderTodo(String projectId, String userId) {
|
||||
if (!isSchoolOaEnabled("删除福利选择提醒待办", null, null) || StrUtil.hasBlank(projectId, userId)) {
|
||||
return;
|
||||
}
|
||||
// 兼容删除改造前按项目和用户生成的固定唯一值,新的重复提醒不再调用删除逻辑。
|
||||
String uniqueId = buildWelfareReminderFlowId(projectId, userId);
|
||||
String deleteUrl = requireConfig("school-oa.todo.delete-url").replace("{uniqueId}", uniqueId);
|
||||
sendTodoRequest(deleteUrl, "学校OA福利选择提醒待办删除失败", "学校OA福利选择提醒待办删除异常");
|
||||
log.info("学校OA福利选择提醒待办删除成功,projectId={},userId={},uniqueId={}", projectId, userId, uniqueId);
|
||||
String responseBody = sendTodoRequest(updateUrl, "学校OA待办完成失败", "学校OA待办完成异常");
|
||||
log.info("学校OA待办完成成功,uniqueId={},response={}", uniqueId, responseBody);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -273,29 +291,8 @@ public class SchoolOaTodoServiceImpl implements SchoolOaTodoService {
|
||||
body.set("receiveTime", receiveTime);
|
||||
|
||||
String insertUrl = requireConfig("school-oa.todo.insert-url");
|
||||
String requestBody = JSONUtil.toJsonStr(body);
|
||||
log.info("学校OA待办创建请求,url={},taskId={},processInstanceId={},receiveCode={},body={}",
|
||||
insertUrl, task.getId(), instance.getId(), actor.getActorAccount(), requestBody);
|
||||
try {
|
||||
HttpRequest request = HttpUtil.createPost(insertUrl);
|
||||
setTodoRequestHeaders(request);
|
||||
request.body(requestBody);
|
||||
|
||||
String responseBody = request.execute().body();
|
||||
log.info("学校OA待办创建响应,taskId={},receiveCode={},response={}", task.getId(), actor.getActorAccount(), responseBody);
|
||||
JSONObject response = JSONUtil.parseObj(responseBody);
|
||||
if (response.getInt("state", 0) != 200) {
|
||||
log.warn("学校OA待办创建失败响应,taskId={},receiveCode={},response={}", task.getId(), actor.getActorAccount(), responseBody);
|
||||
throw new BaseException("学校OA待办创建失败:{}", response.getStr("message", responseBody));
|
||||
}
|
||||
log.info("学校OA待办创建成功,taskId={},receiveCode={},response={}", task.getId(), actor.getActorAccount(), responseBody);
|
||||
} catch (BaseException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.error("学校OA待办创建异常,url={},taskId={},processInstanceId={},receiveCode={},body={}",
|
||||
insertUrl, task.getId(), instance.getId(), actor.getActorAccount(), requestBody, e);
|
||||
throw new BaseException("学校OA待办创建异常:{}", e.getMessage());
|
||||
}
|
||||
String responseBody = sendTodoRequest(insertUrl, body, "学校OA待办创建失败", "学校OA待办创建异常");
|
||||
log.info("学校OA待办创建成功,taskId={},receiveCode={},response={}", task.getId(), actor.getActorAccount(), responseBody);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -309,9 +306,8 @@ public class SchoolOaTodoServiceImpl implements SchoolOaTodoService {
|
||||
}
|
||||
|
||||
String uniqueId = task.getId() + "_" + actor.getActorId();
|
||||
String updateUrl = requireConfig("school-oa.todo.update-url").replace("{uniqueId}", uniqueId);
|
||||
String responseBody = sendTodoRequest(updateUrl, "学校OA待办完成失败", "学校OA待办完成异常");
|
||||
log.info("学校OA待办完成成功,taskId={},receiveCode={},uniqueId={},response={}", task.getId(), actor.getActorAccount(), uniqueId, responseBody);
|
||||
completeTodoByUniqueId(uniqueId);
|
||||
log.info("学校OA待办完成成功,taskId={},receiveCode={},uniqueId={}", task.getId(), actor.getActorAccount(), uniqueId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -399,79 +395,6 @@ public class SchoolOaTodoServiceImpl implements SchoolOaTodoService {
|
||||
return baseUrl + separator + "taskId=" + task.getId() + "&instanceId=" + task.getProcessInstanceId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 按学校OA固定待办格式创建福利选择提醒,标题承载自定义提醒内容。
|
||||
*/
|
||||
private String sendWelfareReminderTodo(String projectId, String title, String pcUrl, String appUrl,
|
||||
Sys_user creator, Sys_user receiver, String creatorTime) {
|
||||
String uniqueId = buildWelfareReminderUniqueId(projectId, receiver.getId());
|
||||
JSONObject body = new JSONObject();
|
||||
body.set("flowTypeName", "福利选择");
|
||||
body.set("flowId", buildWelfareReminderFlowId(projectId, receiver.getId()));
|
||||
body.set("title", title);
|
||||
body.set("stepName", "福利选择提醒");
|
||||
body.set("creatorCode", creator.getLoginname());
|
||||
body.set("creatorName", creator.getUsername());
|
||||
body.set("creatorTime", creatorTime);
|
||||
body.set("pcUrl", pcUrl);
|
||||
body.set("appUrl", appUrl);
|
||||
body.set("pcPreviewUrl", pcUrl);
|
||||
body.set("appPreviewUrl", appUrl);
|
||||
// 同一项目和用户固定使用一个唯一值,确保学校OA最多存在一条福利提醒待办。
|
||||
body.set("uniqueId", uniqueId);
|
||||
body.set("receiveCode", receiver.getLoginname());
|
||||
body.set("receiveName", receiver.getUsername());
|
||||
body.set("receiveTime", creatorTime);
|
||||
|
||||
String insertUrl = requireConfig("school-oa.todo.insert-url");
|
||||
String requestBody = JSONUtil.toJsonStr(body);
|
||||
log.info("学校OA福利选择提醒待办创建请求,url={},projectId={},receiveCode={},body={}",
|
||||
insertUrl, projectId, receiver.getLoginname(), requestBody);
|
||||
JSONObject response = executeWelfareReminderTodoRequest(insertUrl, requestBody, projectId, receiver.getLoginname());
|
||||
String responseMessage = response.getStr("message", "");
|
||||
if (response.getInt("state", 0) != 200) {
|
||||
// 历史待办已存在时视为创建成功,由本系统补记待办记录并阻止后续重复创建。
|
||||
if (StrUtil.contains(responseMessage, "已存在")) {
|
||||
log.info("学校OA福利选择提醒待办已存在,按发送成功处理,projectId={},receiveCode={},uniqueId={}",
|
||||
projectId, receiver.getLoginname(), uniqueId);
|
||||
return uniqueId;
|
||||
}
|
||||
throw new BaseException("学校OA福利选择提醒待办创建失败:{}", StrUtil.blankToDefault(responseMessage, JSONUtil.toJsonStr(response)));
|
||||
}
|
||||
log.info("学校OA福利选择提醒待办创建成功,projectId={},receiveCode={},response={}",
|
||||
projectId, receiver.getLoginname(), JSONUtil.toJsonStr(response));
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用学校OA插入待办接口并返回原始响应;网络和解析异常统一转换为业务异常。
|
||||
*/
|
||||
private JSONObject executeWelfareReminderTodoRequest(String insertUrl, String requestBody, String projectId, String receiverLoginName) {
|
||||
try {
|
||||
HttpRequest request = HttpUtil.createPost(insertUrl);
|
||||
setTodoRequestHeaders(request);
|
||||
request.body(requestBody);
|
||||
String responseBody = request.execute().body();
|
||||
log.info("学校OA福利选择提醒待办创建响应,projectId={},receiveCode={},response={}",
|
||||
projectId, receiverLoginName, responseBody);
|
||||
return JSONUtil.parseObj(responseBody);
|
||||
} catch (Exception e) {
|
||||
log.error("学校OA福利选择提醒待办创建异常,url={},projectId={},receiveCode={},body={}",
|
||||
insertUrl, projectId, receiverLoginName, requestBody, e);
|
||||
throw new BaseException("学校OA福利选择提醒待办创建异常:{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/** 同一项目和用户共用固定流程标识。 */
|
||||
private String buildWelfareReminderFlowId(String projectId, String userId) {
|
||||
return "welfare_reminder_" + projectId + "_" + userId;
|
||||
}
|
||||
|
||||
/** 同一项目和用户固定使用一个待办唯一值。 */
|
||||
private String buildWelfareReminderUniqueId(String projectId, String userId) {
|
||||
return buildWelfareReminderFlowId(projectId, userId);
|
||||
}
|
||||
|
||||
private String buildAppTaskUrl(String h5FormKey, ProcessTask task) {
|
||||
// 部分流程没有配置 H5 审核页,学校 OA 的移动端地址为空时按要求传固定域名兜底。
|
||||
if (StrUtil.isBlank(h5FormKey)) {
|
||||
|
||||
+1
@@ -107,6 +107,7 @@ public class WelfareSelectionSituationController {
|
||||
}
|
||||
|
||||
@At
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SLog(type = "welfare", tag = "选择情况", msg = "发送福利选择提醒")
|
||||
@SaCheckPermission("welfare.selection.situation")
|
||||
@ApiOperation("发送福利选择提醒")
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.budwk.app.zhgh.welfare.model;
|
||||
|
||||
import com.budwk.app.base.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.nutz.dao.entity.annotation.ColDefine;
|
||||
import org.nutz.dao.entity.annotation.ColType;
|
||||
import org.nutz.dao.entity.annotation.Column;
|
||||
import org.nutz.dao.entity.annotation.Comment;
|
||||
import org.nutz.dao.entity.annotation.Index;
|
||||
import org.nutz.dao.entity.annotation.Name;
|
||||
import org.nutz.dao.entity.annotation.Table;
|
||||
import org.nutz.dao.entity.annotation.TableIndexes;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 福利选择学校统一消息发送记录。
|
||||
* 每次提醒批次中的每位接收人各保存一条记录,用于回写统一消息平台的最终成功或失败结果。
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Table("welfare_reminder_message")
|
||||
@Comment("福利选择学校统一消息发送记录")
|
||||
@TableIndexes({
|
||||
@Index(name = "UK_WELFARE_REMINDER_MESSAGE_BATCH_USER", fields = {"messageBatchId", "userId"}, unique = true),
|
||||
@Index(name = "IDX_WELFARE_REMINDER_MESSAGE_PROJECT_STATUS", fields = {"projectId", "messageStatus"}, unique = false)
|
||||
})
|
||||
public class WelfareReminderMessage extends BaseModel {
|
||||
|
||||
/** 已提交统一消息平台,等待查询最终结果。 */
|
||||
public static final int STATUS_WAITING_RESULT = 0;
|
||||
/** 统一消息平台返回该接收人发送成功。 */
|
||||
public static final int STATUS_SUCCESS = 1;
|
||||
/** 统一消息平台返回该接收人发送失败,或发送前参数校验失败。 */
|
||||
public static final int STATUS_FAILED = 2;
|
||||
/** 统一消息结果查询异常,尚未能确认接收人的最终发送状态。 */
|
||||
public static final int STATUS_RESULT_QUERY_FAILED = 3;
|
||||
|
||||
@Name
|
||||
@Comment("ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
@Comment("消息发送批次ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String messageBatchId;
|
||||
|
||||
@Column
|
||||
@Comment("福利项目ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String projectId;
|
||||
|
||||
@Column
|
||||
@Comment("接收用户ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String userId;
|
||||
|
||||
@Column
|
||||
@Comment("统一消息平台消息标识,多个标识以英文逗号分隔")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 500)
|
||||
private String messageId;
|
||||
|
||||
@Column
|
||||
@Comment("接收人工号")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String receiverCode;
|
||||
|
||||
@Column
|
||||
@Comment("接收人姓名")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String receiverName;
|
||||
|
||||
@Column
|
||||
@Comment("发送人ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String senderId;
|
||||
|
||||
@Column
|
||||
@Comment("发送人工号")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String senderCode;
|
||||
|
||||
@Column
|
||||
@Comment("发送人姓名")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String senderName;
|
||||
|
||||
@Column
|
||||
@Comment("消息标题")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String title;
|
||||
|
||||
@Column
|
||||
@Comment("消息内容")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 1000)
|
||||
private String content;
|
||||
|
||||
@Column
|
||||
@Comment("状态:0等待结果、1成功、2失败、3结果查询异常")
|
||||
@ColDefine(type = ColType.INT)
|
||||
private Integer messageStatus;
|
||||
|
||||
@Column
|
||||
@Comment("提交到统一消息平台时间")
|
||||
@ColDefine(type = ColType.DATETIME)
|
||||
private Date sendTime;
|
||||
|
||||
@Column
|
||||
@Comment("查询到最终结果时间")
|
||||
@ColDefine(type = ColType.DATETIME)
|
||||
private Date resultTime;
|
||||
|
||||
@Column
|
||||
@Comment("发送或结果查询失败原因")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 1000)
|
||||
private String failMessage;
|
||||
}
|
||||
+435
-38
@@ -6,14 +6,21 @@ import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||
import cn.afterturn.easypoi.excel.export.ExcelExportService;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||
import com.budwk.app.base.utils.ManyAddOrRenewUtil;
|
||||
import com.budwk.app.base.utils.PageUtil;
|
||||
//import com.budwk.app.sys.models.Sys_file;
|
||||
import com.budwk.app.base.sms.SmsService;
|
||||
import com.budwk.app.flow.param.SchoolOaTodoBatchCreateParam;
|
||||
import com.budwk.app.flow.param.SchoolOaTodoReceiverParam;
|
||||
import com.budwk.app.flow.service.SchoolOaTodoService;
|
||||
import com.budwk.app.sys.models.Sys_user;
|
||||
import com.budwk.app.sys.services.SysFileService;
|
||||
@@ -25,6 +32,7 @@ import com.budwk.app.zhgh.dayofficework.message.strategy.impl.LocalMessageSendSt
|
||||
import com.budwk.app.zhgh.welfare.model.WelfareList;
|
||||
import com.budwk.app.zhgh.welfare.model.WelfareProject;
|
||||
import com.budwk.app.zhgh.welfare.model.WelfareProjectSubjectOption;
|
||||
import com.budwk.app.zhgh.welfare.model.WelfareReminderMessage;
|
||||
import com.budwk.app.zhgh.welfare.model.WelfareReminderTodo;
|
||||
import com.budwk.app.zhgh.welfare.model.WelfareUserSelection;
|
||||
import com.budwk.app.zhgh.welfare.param.WelfareSelectionSituationPageForm;
|
||||
@@ -37,8 +45,11 @@ import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.random.R;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
@@ -65,6 +76,8 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
private SmsService smsService;
|
||||
@Inject
|
||||
private SchoolOaTodoService schoolOaTodoService;
|
||||
@Inject
|
||||
private ManyAddOrRenewUtil manyAddOrRenewUtil;
|
||||
|
||||
@Override
|
||||
public String getPreferredMobile(String userId) {
|
||||
@@ -168,11 +181,13 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
}
|
||||
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public NutMap sendReminder(WelfareSelectionSituationPageForm pageForm, String[] userIds, String content) {
|
||||
List<String> recipientIds = getReminderRecipientIds(pageForm, userIds);
|
||||
if (recipientIds.isEmpty()) {
|
||||
return buildReminderResult(0, 0, 0, 0, 0,
|
||||
Boolean.TRUE.equals(Globals.MyConfig.getBoolean("AppSchoolOa")));
|
||||
return buildReminderResult(0, 0, 0, 0, 0, 0,
|
||||
Boolean.TRUE.equals(Globals.MyConfig.getBoolean("AppSms")),
|
||||
Boolean.TRUE.equals(Globals.MyConfig.getBoolean("AppSchoolOa")), 0, 0);
|
||||
}
|
||||
// 各消息渠道统一使用福利业务标题,学校OA再拼接自定义正文作为待办标题。
|
||||
String title = "智慧工会职工福利:";
|
||||
@@ -183,20 +198,41 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
localMessageSendStrategy.send(title, content, 2, recipientIds, null);
|
||||
|
||||
List<Sys_user> receiverUsers = dao().query(Sys_user.class, Cnd.where(Sys_user::getId, "in", recipientIds));
|
||||
boolean messageEnabled = Boolean.TRUE.equals(Globals.MyConfig.getBoolean("AppSms"));
|
||||
boolean todoEnabled = Boolean.TRUE.equals(Globals.MyConfig.getBoolean("AppSchoolOa"));
|
||||
String senderId = SecurityUtil.getUserId();
|
||||
Sys_user sender = null;
|
||||
if (messageEnabled || todoEnabled) {
|
||||
sender = dao().fetch(Sys_user.class, senderId);
|
||||
if (sender == null || StrUtil.hasBlank(sender.getId(), sender.getLoginname(), sender.getUsername())) {
|
||||
throw new IllegalStateException("福利选择提醒创建人信息不完整");
|
||||
}
|
||||
}
|
||||
|
||||
int messageSuccessCount = 0;
|
||||
int messageFailedCount = 0;
|
||||
int messageResultQueryFailedCount = 0;
|
||||
// AppSms 控制学校消息平台发送,消息链接跳转到手机端福利选择列表。
|
||||
if (Boolean.TRUE.equals(Globals.MyConfig.getBoolean("AppSms")) && !receiverUsers.isEmpty()) {
|
||||
smsService.massSendByUsers(receiverUsers, title, content, pcUrl, appUrl);
|
||||
if (messageEnabled) {
|
||||
NutMap messageResult = sendReminderMessageBatch(pageForm.getProjectId(), recipientIds, receiverUsers,
|
||||
sender, title, content, pcUrl, appUrl);
|
||||
messageSuccessCount = messageResult.getInt("successCount", 0);
|
||||
messageFailedCount = messageResult.getInt("failedCount", 0);
|
||||
messageResultQueryFailedCount = messageResult.getInt("resultQueryFailedCount", 0);
|
||||
}
|
||||
|
||||
boolean todoEnabled = Boolean.TRUE.equals(Globals.MyConfig.getBoolean("AppSchoolOa"));
|
||||
int todoSuccessCount = 0;
|
||||
int existingTodoCount = 0;
|
||||
int todoFailedCount = 0;
|
||||
if (todoEnabled) {
|
||||
Map<String, Sys_user> receiverUserMap = receiverUsers.stream()
|
||||
.collect(Collectors.toMap(Sys_user::getId, user -> user, (left, right) -> left));
|
||||
Map<String, WelfareReminderTodo> reminderTodoMap = getReminderTodoMap(pageForm.getProjectId(), recipientIds);
|
||||
List<WelfareReminderTodo> newSendingReminderTodos = new ArrayList<>();
|
||||
List<WelfareReminderTodo> retrySendingReminderTodos = new ArrayList<>();
|
||||
List<String> sendingReceiverIds = new ArrayList<>();
|
||||
for (String recipientId : recipientIds) {
|
||||
WelfareReminderTodo reminderTodo = getReminderTodo(pageForm.getProjectId(), recipientId);
|
||||
WelfareReminderTodo reminderTodo = reminderTodoMap.get(recipientId);
|
||||
if (isExistingReminderTodo(reminderTodo)) {
|
||||
existingTodoCount++;
|
||||
continue;
|
||||
@@ -204,21 +240,15 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
|
||||
Sys_user receiver = receiverUserMap.get(recipientId);
|
||||
try {
|
||||
// 发送前先落库为“发送中”,确保每一次实际发起的OA待办都可追溯。
|
||||
reminderTodo = saveSendingReminderTodo(reminderTodo, pageForm.getProjectId(), receiver,
|
||||
SecurityUtil.getUserId(), title + content, content);
|
||||
String uniqueId = schoolOaTodoService.createWelfareReminderTodo(pageForm.getProjectId(), title + content,
|
||||
pcUrl, appUrl, SecurityUtil.getUserId(), recipientId);
|
||||
if (StrUtil.isBlank(uniqueId)) {
|
||||
throw new IllegalStateException("学校OA待办开关状态已变化,本次待办未发送");
|
||||
// 仅在内存中组装记录,随后按“新增”和“重试”分别执行批量数据库写入。
|
||||
reminderTodo = prepareSendingReminderTodo(reminderTodo, pageForm.getProjectId(), receiver,
|
||||
sender, title + content, content);
|
||||
sendingReceiverIds.add(recipientId);
|
||||
if (reminderTodoMap.containsKey(recipientId)) {
|
||||
retrySendingReminderTodos.add(reminderTodo);
|
||||
} else {
|
||||
newSendingReminderTodos.add(reminderTodo);
|
||||
}
|
||||
reminderTodo.setOaUniqueId(uniqueId);
|
||||
reminderTodo.setTodoStatus(WelfareReminderTodo.STATUS_PENDING);
|
||||
reminderTodo.setSendTime(new Date());
|
||||
reminderTodo.setFinishTime(null);
|
||||
reminderTodo.setFailMessage(null);
|
||||
dao().update(reminderTodo);
|
||||
todoSuccessCount++;
|
||||
} catch (Exception e) {
|
||||
todoFailedCount++;
|
||||
saveReminderTodoFailure(reminderTodo, pageForm.getProjectId(), recipientId, receiver,
|
||||
@@ -227,12 +257,42 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
pageForm.getProjectId(), recipientId, e);
|
||||
}
|
||||
}
|
||||
if (!sendingReceiverIds.isEmpty()) {
|
||||
persistSendingReminderTodos(pageForm.getProjectId(), newSendingReminderTodos,
|
||||
retrySendingReminderTodos, senderId);
|
||||
log.info("福利选择提醒待办批量写入发送中完成,projectId={},接收人总数={},已有待办跳过={},新增记录={},失败重试记录={}",
|
||||
pageForm.getProjectId(), recipientIds.size(), existingTodoCount,
|
||||
newSendingReminderTodos.size(), retrySendingReminderTodos.size());
|
||||
try {
|
||||
SchoolOaTodoBatchCreateParam todoParam = buildWelfareReminderBatchTodoParam(
|
||||
pageForm.getProjectId(), title + content, pcUrl, appUrl, sender,
|
||||
sendingReceiverIds, receiverUserMap);
|
||||
schoolOaTodoService.createBatchTodo(todoParam);
|
||||
} catch (Exception e) {
|
||||
int updatedCount = updateReminderTodoBatchStatus(pageForm.getProjectId(), sendingReceiverIds,
|
||||
senderId, WelfareReminderTodo.STATUS_FAILED, null, limitFailureMessage(e.getMessage()));
|
||||
todoFailedCount += sendingReceiverIds.size();
|
||||
log.error("福利选择提醒待办批量发送失败并批量更新状态,projectId={},待办人数={},数据库更新行数={},状态={},失败原因={}",
|
||||
pageForm.getProjectId(), sendingReceiverIds.size(), updatedCount,
|
||||
WelfareReminderTodo.STATUS_FAILED, e.getMessage(), e);
|
||||
return buildReminderResult(recipientIds.size(), recipientIds.size(), messageSuccessCount,
|
||||
messageFailedCount, messageResultQueryFailedCount, todoSuccessCount,
|
||||
messageEnabled, todoEnabled, existingTodoCount, todoFailedCount);
|
||||
}
|
||||
int updatedCount = updateReminderTodoBatchStatus(pageForm.getProjectId(), sendingReceiverIds,
|
||||
senderId, WelfareReminderTodo.STATUS_PENDING, new Date(), null);
|
||||
todoSuccessCount = sendingReceiverIds.size();
|
||||
log.info("福利选择提醒待办批量发送成功并批量更新状态,projectId={},待办人数={},数据库更新行数={},状态={}",
|
||||
pageForm.getProjectId(), todoSuccessCount, updatedCount, WelfareReminderTodo.STATUS_PENDING);
|
||||
}
|
||||
}
|
||||
return buildReminderResult(recipientIds.size(), recipientIds.size(), todoSuccessCount,
|
||||
existingTodoCount, todoFailedCount, todoEnabled);
|
||||
return buildReminderResult(recipientIds.size(), recipientIds.size(), messageSuccessCount,
|
||||
messageFailedCount, messageResultQueryFailedCount, todoSuccessCount,
|
||||
messageEnabled, todoEnabled, existingTodoCount, todoFailedCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void completeReminderTodo(String projectId, String userId) {
|
||||
WelfareReminderTodo reminderTodo = getReminderTodo(projectId, userId);
|
||||
if (reminderTodo == null || !Objects.equals(reminderTodo.getTodoStatus(), WelfareReminderTodo.STATUS_PENDING)
|
||||
@@ -240,7 +300,7 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
return;
|
||||
}
|
||||
try {
|
||||
schoolOaTodoService.completeWelfareReminderTodo(reminderTodo.getOaUniqueId());
|
||||
schoolOaTodoService.completeTodoByUniqueId(reminderTodo.getOaUniqueId());
|
||||
reminderTodo.setTodoStatus(WelfareReminderTodo.STATUS_COMPLETED);
|
||||
reminderTodo.setFinishTime(new Date());
|
||||
reminderTodo.setFailMessage(null);
|
||||
@@ -253,6 +313,209 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量发送福利选择统一消息并回写逐人结果。
|
||||
* 每名接收人先落一条等待结果记录;统一消息平台接收整批请求后,使用返回的消息标识查询结果,
|
||||
* 再依据失败用户工号批量更新本地成功、失败或查询异常状态。
|
||||
*
|
||||
* @param projectId 福利项目ID
|
||||
* @param recipientIds 本次提醒的全部接收用户ID
|
||||
* @param receiverUsers 已查询到的接收人用户信息
|
||||
* @param sender 发起提醒的系统用户,用于记录发送人信息
|
||||
* @param title 统一消息标题,长度不得超过学校接口要求的100个字符
|
||||
* @param content 统一消息正文
|
||||
* @param pcUrl PC端福利选择链接
|
||||
* @param mobileUrl 移动端福利选择链接
|
||||
* @return 包含成功数、失败数和结果查询异常数的统计结果
|
||||
*/
|
||||
private NutMap sendReminderMessageBatch(String projectId, List<String> recipientIds, List<Sys_user> receiverUsers,
|
||||
Sys_user sender, String title, String content, String pcUrl, String mobileUrl) {
|
||||
if (StrUtil.hasBlank(projectId, title, content) || recipientIds.isEmpty()
|
||||
|| sender == null || StrUtil.hasBlank(sender.getId(), sender.getLoginname(), sender.getUsername())) {
|
||||
throw new IllegalArgumentException("福利选择统一消息批量发送参数不完整");
|
||||
}
|
||||
if (title.length() > 100) {
|
||||
throw new IllegalArgumentException("福利选择统一消息标题长度不能超过100个字符");
|
||||
}
|
||||
|
||||
String senderId = sender.getId();
|
||||
String messageBatchId = R.UU32();
|
||||
long now = System.currentTimeMillis();
|
||||
Map<String, Sys_user> receiverUserMap = receiverUsers.stream()
|
||||
.collect(Collectors.toMap(Sys_user::getId, user -> user, (left, right) -> left));
|
||||
List<WelfareReminderMessage> records = new ArrayList<>();
|
||||
List<WelfareReminderMessage> validRecords = new ArrayList<>();
|
||||
List<Sys_user> validUsers = new ArrayList<>();
|
||||
for (String recipientId : recipientIds) {
|
||||
Sys_user receiver = receiverUserMap.get(recipientId);
|
||||
WelfareReminderMessage record = createReminderMessageRecord(messageBatchId, projectId, recipientId,
|
||||
receiver, sender, title, content, now);
|
||||
records.add(record);
|
||||
if (receiver == null || StrUtil.hasBlank(receiver.getLoginname(), receiver.getUsername())) {
|
||||
record.setMessageStatus(WelfareReminderMessage.STATUS_FAILED);
|
||||
record.setFailMessage("学校统一消息发送失败:接收人工号或姓名为空");
|
||||
} else {
|
||||
validRecords.add(record);
|
||||
validUsers.add(receiver);
|
||||
}
|
||||
}
|
||||
log.info("福利选择统一消息记录已在内存组装完成,projectId={},messageBatchId={},接收人总数={},可发送人数={},接收人信息失败人数={}",
|
||||
projectId, messageBatchId, records.size(), validUsers.size(), records.size() - validUsers.size());
|
||||
|
||||
if (validUsers.isEmpty()) {
|
||||
persistReminderMessageRecordsAsync(records, projectId, messageBatchId);
|
||||
return NutMap.NEW().addv("successCount", 0).addv("failedCount", records.size()).addv("resultQueryFailedCount", 0);
|
||||
}
|
||||
|
||||
List<String> messageIds;
|
||||
String messageIdText;
|
||||
try {
|
||||
messageIds = smsService.massSendByUsers(validUsers, title, content, pcUrl, mobileUrl);
|
||||
if (messageIds == null || messageIds.isEmpty()) {
|
||||
throw new IllegalStateException("学校统一消息平台未返回消息标识");
|
||||
}
|
||||
messageIdText = String.join(",", messageIds);
|
||||
Date sendTime = new Date();
|
||||
validRecords.forEach(record -> {
|
||||
record.setMessageId(messageIdText);
|
||||
record.setMessageStatus(WelfareReminderMessage.STATUS_WAITING_RESULT);
|
||||
record.setSendTime(sendTime);
|
||||
record.setFailMessage(null);
|
||||
record.setUpdatedBy(senderId);
|
||||
record.setUpdatedAt(System.currentTimeMillis());
|
||||
});
|
||||
log.info("福利选择统一消息批量发送已入队,等待结果查询后异步写入记录,projectId={},messageBatchId={},messageIds={},接收人数={}",
|
||||
projectId, messageBatchId, messageIds, validRecords.size());
|
||||
} catch (Exception e) {
|
||||
markReminderMessageRecords(validRecords, senderId, WelfareReminderMessage.STATUS_FAILED,
|
||||
null, null, limitFailureMessage(e.getMessage()));
|
||||
persistReminderMessageRecordsAsync(records, projectId, messageBatchId);
|
||||
log.error("福利选择统一消息批量发送失败,已提交异步入库记录,projectId={},messageBatchId={},接收人数={},失败原因={}",
|
||||
projectId, messageBatchId, validRecords.size(), e.getMessage(), e);
|
||||
return NutMap.NEW().addv("successCount", 0).addv("failedCount", records.size()).addv("resultQueryFailedCount", 0);
|
||||
}
|
||||
|
||||
try {
|
||||
Map<String, String> failedMessageByCode = queryFailedMessageByReceiverCode(messageIds);
|
||||
Date resultTime = new Date();
|
||||
for (WelfareReminderMessage record : validRecords) {
|
||||
String failMessage = failedMessageByCode.get(record.getReceiverCode());
|
||||
record.setMessageStatus(StrUtil.isBlank(failMessage)
|
||||
? WelfareReminderMessage.STATUS_SUCCESS : WelfareReminderMessage.STATUS_FAILED);
|
||||
record.setResultTime(resultTime);
|
||||
record.setFailMessage(failMessage);
|
||||
record.setUpdatedBy(senderId);
|
||||
record.setUpdatedAt(System.currentTimeMillis());
|
||||
}
|
||||
int externalFailedCount = (int) validRecords.stream()
|
||||
.filter(record -> failedMessageByCode.containsKey(record.getReceiverCode()))
|
||||
.count();
|
||||
int failedCount = records.size() - validRecords.size() + externalFailedCount;
|
||||
int successCount = validRecords.size() - externalFailedCount;
|
||||
persistReminderMessageRecordsAsync(records, projectId, messageBatchId);
|
||||
log.info("福利选择统一消息结果查询完成,已提交异步入库记录,projectId={},messageBatchId={},成功人数={},失败人数={},messageIds={}",
|
||||
projectId, messageBatchId, successCount, failedCount, messageIds);
|
||||
return NutMap.NEW().addv("successCount", successCount).addv("failedCount", failedCount).addv("resultQueryFailedCount", 0);
|
||||
} catch (Exception e) {
|
||||
markReminderMessageRecords(validRecords, senderId, WelfareReminderMessage.STATUS_RESULT_QUERY_FAILED,
|
||||
messageIdText, new Date(), limitFailureMessage(e.getMessage()));
|
||||
persistReminderMessageRecordsAsync(records, projectId, messageBatchId);
|
||||
log.error("福利选择统一消息结果查询异常,已提交异步入库记录,projectId={},messageBatchId={},messageIds={},接收人数={},失败原因={}",
|
||||
projectId, messageBatchId, messageIds, validRecords.size(), e.getMessage(), e);
|
||||
return NutMap.NEW().addv("successCount", 0).addv("failedCount", records.size() - validRecords.size())
|
||||
.addv("resultQueryFailedCount", validRecords.size());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建统一消息接收人记录,并显式补齐fastInsert不会执行的主键和审计字段。
|
||||
*/
|
||||
private WelfareReminderMessage createReminderMessageRecord(String messageBatchId, String projectId, String userId,
|
||||
Sys_user receiver, Sys_user sender, String title,
|
||||
String content, long now) {
|
||||
WelfareReminderMessage record = new WelfareReminderMessage();
|
||||
record.setId(R.UU32());
|
||||
record.setMessageBatchId(messageBatchId);
|
||||
record.setProjectId(projectId);
|
||||
record.setUserId(userId);
|
||||
if (receiver != null) {
|
||||
record.setReceiverCode(receiver.getLoginname());
|
||||
record.setReceiverName(receiver.getUsername());
|
||||
}
|
||||
record.setSenderId(sender.getId());
|
||||
record.setSenderCode(sender.getLoginname());
|
||||
record.setSenderName(sender.getUsername());
|
||||
record.setTitle(limitText(title, 100));
|
||||
record.setContent(limitText(content, 1000));
|
||||
record.setMessageStatus(WelfareReminderMessage.STATUS_WAITING_RESULT);
|
||||
record.setCreatedBy(sender.getId());
|
||||
record.setCreatedAt(now);
|
||||
record.setUpdatedBy(sender.getId());
|
||||
record.setUpdatedAt(now);
|
||||
record.setDelFlag(false);
|
||||
return record;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有消息标识的结果并汇总失败用户工号与失败原因。
|
||||
* 当前配置仅使用一个发送渠道,通常只返回一个消息标识;多标识场景仍逐个查询并按工号合并失败结果。
|
||||
*/
|
||||
private Map<String, String> queryFailedMessageByReceiverCode(List<String> messageIds) {
|
||||
Map<String, String> failedMessageByCode = new HashMap<>();
|
||||
for (String messageId : messageIds) {
|
||||
NutMap messageResult = smsService.getMessageResult(messageId);
|
||||
Object failedUsers = messageResult.get("failedUsers");
|
||||
if (failedUsers instanceof JSONArray failedUserArray) {
|
||||
for (Object failedUserValue : failedUserArray) {
|
||||
JSONObject failedUser = JSONUtil.parseObj(failedUserValue);
|
||||
String userCode = failedUser.getStr("userCode");
|
||||
if (StrUtil.isNotBlank(userCode)) {
|
||||
failedMessageByCode.put(userCode, limitFailureMessage(failedUser.getStr("errorInfo")));
|
||||
}
|
||||
}
|
||||
}
|
||||
if ("0".equals(messageResult.getString("resultState")) && failedMessageByCode.isEmpty()) {
|
||||
throw new IllegalStateException("学校统一消息平台返回发送失败,但未返回失败人员明细,messageId=" + messageId);
|
||||
}
|
||||
}
|
||||
return failedMessageByCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在内存中更新一批统一消息记录状态;所有结果明确后再统一异步插入,避免异步插入和同步更新发生竞争。
|
||||
*/
|
||||
private void markReminderMessageRecords(List<WelfareReminderMessage> records, String senderId, int messageStatus,
|
||||
String messageId, Date resultTime, String failMessage) {
|
||||
if (records.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Date sendTime = messageId == null ? null : new Date();
|
||||
records.forEach(record -> {
|
||||
if (messageId != null) {
|
||||
record.setMessageId(messageId);
|
||||
record.setSendTime(sendTime);
|
||||
}
|
||||
record.setMessageStatus(messageStatus);
|
||||
record.setResultTime(resultTime);
|
||||
record.setFailMessage(failMessage);
|
||||
record.setUpdatedBy(senderId);
|
||||
record.setUpdatedAt(System.currentTimeMillis());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用项目线程池异步分批插入最终消息记录。记录已显式设置主键和审计字段,
|
||||
* 因此可安全使用fastInsert;本方法只提交任务,不等待数据库写入完成。
|
||||
*/
|
||||
private void persistReminderMessageRecordsAsync(List<WelfareReminderMessage> records, String projectId, String messageBatchId) {
|
||||
if (records.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
manyAddOrRenewUtil.asyncExecuteFastInsert(records, 200);
|
||||
log.info("福利选择统一消息记录已提交异步批量入库,projectId={},messageBatchId={},记录数={},batchSize={}",
|
||||
projectId, messageBatchId, records.size(), 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询项目和用户对应的唯一提醒待办记录。
|
||||
*/
|
||||
@@ -264,6 +527,24 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
.and(WelfareReminderTodo::getUserId, "=", userId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量查询当前项目的提醒待办,避免发送前按接收人逐条访问数据库。
|
||||
*
|
||||
* @param projectId 福利项目ID
|
||||
* @param userIds 本次实际接收人ID集合
|
||||
* @return 以用户ID为键的待办记录;未创建过待办的用户不包含在结果中
|
||||
*/
|
||||
private Map<String, WelfareReminderTodo> getReminderTodoMap(String projectId, List<String> userIds) {
|
||||
if (StrUtil.isBlank(projectId) || userIds.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return dao().query(WelfareReminderTodo.class, Cnd.where(WelfareReminderTodo::getProjectId, "=", projectId)
|
||||
.and(WelfareReminderTodo::getUserId, "in", userIds))
|
||||
.stream()
|
||||
.collect(Collectors.toMap(WelfareReminderTodo::getUserId, reminderTodo -> reminderTodo,
|
||||
(left, right) -> left));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送中、待办和已办记录均表示该项目已创建过OA待办,重复提醒时不再创建第二条。
|
||||
* 发送失败记录允许沿用原唯一值重试。
|
||||
@@ -288,24 +569,31 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
}
|
||||
|
||||
/**
|
||||
* 新建或重置待办发送记录。固定的流程ID和唯一值保证同一项目、同一用户最多一条OA待办。
|
||||
* 组装发送中的待办记录。新增记录补齐批量插入所需主键和审计字段,失败重试记录保留原主键。
|
||||
*/
|
||||
private WelfareReminderTodo saveSendingReminderTodo(WelfareReminderTodo reminderTodo, String projectId,
|
||||
Sys_user receiver, String senderId, String title, String content) {
|
||||
private WelfareReminderTodo prepareSendingReminderTodo(WelfareReminderTodo reminderTodo, String projectId,
|
||||
Sys_user receiver, Sys_user sender, String title, String content) {
|
||||
if (receiver == null || StrUtil.hasBlank(receiver.getId(), receiver.getLoginname(), receiver.getUsername())) {
|
||||
throw new IllegalArgumentException("学校OA福利选择提醒接收人信息不完整");
|
||||
}
|
||||
Sys_user sender = dao().fetch(Sys_user.class, senderId);
|
||||
if (sender == null || StrUtil.hasBlank(sender.getLoginname(), sender.getUsername())) {
|
||||
if (sender == null || StrUtil.hasBlank(sender.getId(), sender.getLoginname(), sender.getUsername())) {
|
||||
throw new IllegalArgumentException("学校OA福利选择提醒创建人信息不完整");
|
||||
}
|
||||
|
||||
boolean newRecord = reminderTodo == null;
|
||||
WelfareReminderTodo record = newRecord ? new WelfareReminderTodo() : reminderTodo;
|
||||
long now = System.currentTimeMillis();
|
||||
String uniqueId = buildWelfareReminderUniqueId(projectId, receiver.getId());
|
||||
if (newRecord) {
|
||||
// fastInsert不会触发实体的PrevInsert,主键和审计字段需在批量入库前显式赋值。
|
||||
record.setId(R.UU32());
|
||||
record.setCreatedBy(sender.getId());
|
||||
record.setCreatedAt(now);
|
||||
record.setDelFlag(false);
|
||||
}
|
||||
record.setProjectId(projectId);
|
||||
record.setUserId(receiver.getId());
|
||||
record.setOaFlowId(uniqueId);
|
||||
record.setOaFlowId(buildWelfareReminderBatchFlowId(projectId));
|
||||
record.setOaUniqueId(uniqueId);
|
||||
record.setReceiverCode(receiver.getLoginname());
|
||||
record.setReceiverName(receiver.getUsername());
|
||||
@@ -318,14 +606,48 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
record.setSendTime(null);
|
||||
record.setFinishTime(null);
|
||||
record.setFailMessage(null);
|
||||
if (newRecord) {
|
||||
dao().insert(record);
|
||||
} else {
|
||||
dao().update(record);
|
||||
}
|
||||
record.setUpdatedBy(sender.getId());
|
||||
record.setUpdatedAt(now);
|
||||
return record;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量持久化发送中状态:新记录使用fastInsert,历史失败记录使用DAO批量更新。
|
||||
*/
|
||||
private void persistSendingReminderTodos(String projectId, List<WelfareReminderTodo> newRecords,
|
||||
List<WelfareReminderTodo> retryRecords, String senderId) {
|
||||
if (!newRecords.isEmpty()) {
|
||||
dao().fastInsert(newRecords);
|
||||
log.info("福利选择提醒待办批量新增记录完成,projectId={},新增数量={},状态={}",
|
||||
projectId, newRecords.size(), WelfareReminderTodo.STATUS_SENDING);
|
||||
}
|
||||
if (!retryRecords.isEmpty()) {
|
||||
dao().update(retryRecords,
|
||||
"oaFlowId|oaUniqueId|receiverCode|receiverName|senderId|senderCode|senderName|title|content|todoStatus|sendTime|finishTime|failMessage|updatedBy|updatedAt");
|
||||
log.info("福利选择提醒待办批量重试记录更新完成,projectId={},重试数量={},状态={},操作人={}",
|
||||
projectId, retryRecords.size(), WelfareReminderTodo.STATUS_SENDING, senderId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按本批用户统一更新待办状态。成功时写入发送时间,失败时写入统一失败原因。
|
||||
*/
|
||||
private int updateReminderTodoBatchStatus(String projectId, List<String> userIds, String senderId,
|
||||
int todoStatus, Date sendTime, String failMessage) {
|
||||
if (StrUtil.isBlank(projectId) || userIds.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
Chain chain = Chain.make("todoStatus", todoStatus)
|
||||
.add("sendTime", sendTime)
|
||||
.add("finishTime", null)
|
||||
.add("failMessage", failMessage)
|
||||
.add("updatedBy", senderId)
|
||||
.add("updatedAt", System.currentTimeMillis());
|
||||
return dao().update(WelfareReminderTodo.class, chain,
|
||||
Cnd.where(WelfareReminderTodo::getProjectId, "=", projectId)
|
||||
.and(WelfareReminderTodo::getUserId, "in", userIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存OA待办发送失败原因;若发送前校验失败导致记录尚未创建,则补建一条失败记录。
|
||||
*/
|
||||
@@ -336,7 +658,7 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
record = new WelfareReminderTodo();
|
||||
record.setProjectId(projectId);
|
||||
record.setUserId(userId);
|
||||
record.setOaFlowId(buildWelfareReminderUniqueId(projectId, userId));
|
||||
record.setOaFlowId(buildWelfareReminderBatchFlowId(projectId));
|
||||
record.setOaUniqueId(buildWelfareReminderUniqueId(projectId, userId));
|
||||
record.setSenderId(SecurityUtil.getUserId());
|
||||
if (receiver != null) {
|
||||
@@ -363,9 +685,21 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
/**
|
||||
* 组装发送统计和前端提示,消息与OA待办分别计数,避免把重复跳过误报为发送成功。
|
||||
*/
|
||||
private NutMap buildReminderResult(int recipientCount, int messageSuccessCount, int todoSuccessCount,
|
||||
int existingTodoCount, int todoFailedCount, boolean todoEnabled) {
|
||||
StringBuilder summary = new StringBuilder("消息发送成功").append(messageSuccessCount).append("人");
|
||||
private NutMap buildReminderResult(int recipientCount, int localMessageSuccessCount, int messageSuccessCount,
|
||||
int messageFailedCount, int messageResultQueryFailedCount, int todoSuccessCount,
|
||||
boolean messageEnabled, boolean todoEnabled, int existingTodoCount, int todoFailedCount) {
|
||||
StringBuilder summary = new StringBuilder("本地消息发送成功").append(localMessageSuccessCount).append("人");
|
||||
if (messageEnabled) {
|
||||
summary.append(",学校统一消息发送成功").append(messageSuccessCount).append("人");
|
||||
if (messageFailedCount > 0) {
|
||||
summary.append(",学校统一消息发送失败").append(messageFailedCount).append("人");
|
||||
}
|
||||
if (messageResultQueryFailedCount > 0) {
|
||||
summary.append(",学校统一消息结果查询异常").append(messageResultQueryFailedCount).append("人");
|
||||
}
|
||||
} else {
|
||||
summary.append(",学校统一消息开关未开启");
|
||||
}
|
||||
if (todoEnabled) {
|
||||
summary.append(",OA待办发送成功").append(todoSuccessCount).append("人");
|
||||
if (existingTodoCount > 0) {
|
||||
@@ -379,7 +713,11 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
}
|
||||
return NutMap.NEW()
|
||||
.addv("recipientCount", recipientCount)
|
||||
.addv("localMessageSuccessCount", localMessageSuccessCount)
|
||||
.addv("messageSuccessCount", messageSuccessCount)
|
||||
.addv("messageFailedCount", messageFailedCount)
|
||||
.addv("messageResultQueryFailedCount", messageResultQueryFailedCount)
|
||||
.addv("messageEnabled", messageEnabled)
|
||||
.addv("todoSuccessCount", todoSuccessCount)
|
||||
.addv("existingTodoCount", existingTodoCount)
|
||||
.addv("todoFailedCount", todoFailedCount)
|
||||
@@ -401,6 +739,65 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
return safeText.length() > maxLength ? safeText.substring(0, maxLength) : safeText;
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装福利选择的学校OA批量待办参数。
|
||||
* 公共OA服务只负责校验参数和调用接口;福利项目标识、标题、链接及接收人信息均在此处按福利业务规则生成。
|
||||
*
|
||||
* @param projectId 福利项目ID,用于生成学校OA批次流程标识和每个接收人的唯一值
|
||||
* @param title 学校OA待办标题,包含福利提醒正文
|
||||
* @param pcUrl 福利选择PC端跳转地址
|
||||
* @param appUrl 福利选择移动端跳转地址
|
||||
* @param sender 发起提醒的系统用户,提供学校OA创建人工号和姓名
|
||||
* @param receiverIds 本次实际发送的接收人ID集合
|
||||
* @param receiverUserMap 接收人ID与系统用户信息的映射
|
||||
* @return 可直接传给学校OA批量待办接口的参数对象
|
||||
*/
|
||||
private SchoolOaTodoBatchCreateParam buildWelfareReminderBatchTodoParam(String projectId, String title,
|
||||
String pcUrl, String appUrl, Sys_user sender,
|
||||
List<String> receiverIds,
|
||||
Map<String, Sys_user> receiverUserMap) {
|
||||
if (StrUtil.hasBlank(projectId, title, pcUrl, appUrl)
|
||||
|| sender == null || StrUtil.hasBlank(sender.getLoginname(), sender.getUsername())
|
||||
|| receiverIds == null || receiverIds.isEmpty()) {
|
||||
throw new IllegalArgumentException("学校OA福利选择提醒批量待办参数不完整");
|
||||
}
|
||||
|
||||
String sendTime = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
|
||||
List<SchoolOaTodoReceiverParam> userList = new ArrayList<>();
|
||||
for (String receiverId : receiverIds) {
|
||||
Sys_user receiver = receiverUserMap.get(receiverId);
|
||||
if (receiver == null || StrUtil.hasBlank(receiver.getLoginname(), receiver.getUsername())) {
|
||||
throw new IllegalArgumentException("学校OA福利选择提醒接收人信息不完整,userId=" + receiverId);
|
||||
}
|
||||
SchoolOaTodoReceiverParam receiverParam = new SchoolOaTodoReceiverParam();
|
||||
receiverParam.setPcUrl(pcUrl);
|
||||
receiverParam.setAppUrl(appUrl);
|
||||
receiverParam.setUniqueId(buildWelfareReminderUniqueId(projectId, receiverId));
|
||||
receiverParam.setReceiveCode(receiver.getLoginname());
|
||||
receiverParam.setReceiveName(receiver.getUsername());
|
||||
receiverParam.setReceiveTime(sendTime);
|
||||
userList.add(receiverParam);
|
||||
}
|
||||
|
||||
SchoolOaTodoBatchCreateParam todoParam = new SchoolOaTodoBatchCreateParam();
|
||||
todoParam.setFlowTypeName("福利选择");
|
||||
todoParam.setFlowId(buildWelfareReminderBatchFlowId(projectId));
|
||||
todoParam.setTitle(title);
|
||||
todoParam.setStepName("福利选择提醒");
|
||||
todoParam.setCreatorCode(sender.getLoginname());
|
||||
todoParam.setCreatorName(sender.getUsername());
|
||||
todoParam.setCreatorTime(sendTime);
|
||||
todoParam.setStartPcPreviewUrl(pcUrl);
|
||||
todoParam.setStartAppPreviewUrl(appUrl);
|
||||
todoParam.setUserList(userList);
|
||||
return todoParam;
|
||||
}
|
||||
|
||||
/** 同一项目的一批福利提醒共用学校OA流程标识,接收人通过uniqueId区分。 */
|
||||
private String buildWelfareReminderBatchFlowId(String projectId) {
|
||||
return "welfare_reminder_" + projectId;
|
||||
}
|
||||
|
||||
/** 同一项目和用户固定使用一个OA待办唯一值。 */
|
||||
private String buildWelfareReminderUniqueId(String projectId, String userId) {
|
||||
return "welfare_reminder_" + projectId + "_" + userId;
|
||||
|
||||
@@ -167,7 +167,7 @@ layout("/layouts/platform.html"){
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-descriptions-item>-->
|
||||
|
||||
<template v-if="['1', '2'].includes(formData.typeCode)">
|
||||
<template v-if="(chooseType.name || formData.typeName || '').includes('住院')">
|
||||
<el-descriptions-item label="入院时间">
|
||||
<el-form-item label="入院时间" prop="hospitalizationTime">
|
||||
<el-date-picker
|
||||
|
||||
@@ -23,7 +23,7 @@ const condolenceInfo = {
|
||||
<!-- <el-descriptions-item label="收款账户">{{ viewData.bankCardNumber }}</el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="户名">{{ viewData.bankUserName }}</el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="开户行">{{ viewData.bankOfDeposit }}</el-descriptions-item>-->
|
||||
<template v-if="['1', '2'].includes(viewData.typeCode)">
|
||||
<template v-if="(viewData.typeName || '').includes('住院')">
|
||||
<el-descriptions-item label="入院时间">{{ viewData.hospitalizationTime }}</el-descriptions-item>
|
||||
<el-descriptions-item label="出院时间">{{ viewData.leaveHospitalTime }}</el-descriptions-item>
|
||||
<el-descriptions-item label="当年第几次住院">{{ viewData.thisYearHospitalizationNum }}
|
||||
|
||||
@@ -279,7 +279,7 @@ layout("/layouts/platform_h5.html"){
|
||||
<!-- name="bankOfDeposit"-->
|
||||
<!-- ></van-field>-->
|
||||
|
||||
<template v-if="['1', '2'].includes(formData.typeCode)">
|
||||
<template v-if="(chooseType.name || formData.typeName || '').includes('住院')">
|
||||
<van-field
|
||||
v-model="formData.hospitalizationTime"
|
||||
name="hospitalizationTime"
|
||||
|
||||
@@ -23,7 +23,7 @@ const condolenceInfo = {
|
||||
<!-- <van-cell class="direction-column-cell" title="开户行">-->
|
||||
<!-- {{ viewData.bankOfDeposit || '暂无' }}-->
|
||||
<!-- </van-cell>-->
|
||||
<template v-if="['1', '2'].includes(viewData.typeCode)">
|
||||
<template v-if="(viewData.typeName || '').includes('住院')">
|
||||
<van-cell title="入院时间">{{ viewData.hospitalizationTime }}</van-cell>
|
||||
<van-cell title="出院时间">{{ viewData.leaveHospitalTime }}</van-cell>
|
||||
<van-cell title="当年第几次住院(次)">{{ viewData.thisYearHospitalizationNum }}</van-cell>
|
||||
|
||||
Reference in New Issue
Block a user