package jnpf.message.service;
|
|
import jnpf.base.UserInfo;
|
import jnpf.exception.DataException;
|
import jnpf.message.entity.MessageReceiveEntity;
|
import jnpf.message.entity.MessageTemplateConfigEntity;
|
import jnpf.message.mapper.DmsUpgradeMessageMapper;
|
import jnpf.message.model.DmsUpgradeMessage;
|
import jnpf.message.util.PushMessageUtil;
|
import lombok.RequiredArgsConstructor;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.support.TransactionSynchronization;
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
import org.springframework.web.util.HtmlUtils;
|
import java.util.*;
|
|
/** DMS专属可靠站内信分支;不改变其他消息的发送行为。 */
|
@Slf4j
|
@Service
|
@RequiredArgsConstructor
|
public class DmsUpgradeMessageService {
|
private final DmsUpgradeMessageMapper mapper;
|
|
@Transactional(rollbackFor = Exception.class)
|
public boolean send(DmsUpgradeMessage request) {
|
if (request == null || blank(request.getTenantId()) || blank(request.getTaskId())
|
|| request.getToUserIds() == null || request.getToUserIds().isEmpty()
|
|| request.getToUserIds().stream().anyMatch(DmsUpgradeMessageService::blank))
|
throw new DataException("升版通知缺少事件或接收人");
|
List<MessageTemplateConfigEntity> templates = mapper.templates(request.getTenantId());
|
if (templates.size() != 1) throw new DataException("请配置唯一且启用的站内信模板 dmsTemplateUpgrade");
|
MessageTemplateConfigEntity template = templates.get(0);
|
if (blank(template.getTitle()) || blank(template.getContent())) throw new DataException("升版消息模板标题或正文为空");
|
String title = render(template.getTitle(), request.getParameters(), false);
|
String content = render(template.getContent(), request.getParameters(), true);
|
Map<String,MessageReceiveEntity> inserted = new LinkedHashMap<>();
|
for (String user : new LinkedHashSet<>(request.getToUserIds())) {
|
if (mapper.claimDelivery(request.getTenantId(), request.getTaskId(), user) == 0) continue;
|
MessageReceiveEntity message = new MessageReceiveEntity();
|
message.setId(UUID.randomUUID().toString().replace("-", "")); message.setUserId(user);
|
message.setTitle(title); message.setBodyText(content); message.setType(3); message.setIsRead(0);
|
message.setCreatorUserId(request.getActorId()); message.setCreatorTime(new Date());
|
if (mapper.insertMessage(message, request.getTenantId()) != 1) throw new DataException("站内信保存失败");
|
inserted.put(user, message);
|
}
|
UserInfo actor = new UserInfo(); actor.setTenantId(request.getTenantId()); actor.setUserId(request.getActorId());
|
// 事务提交即为可靠送达;WebSocket仅刷新在线界面,不把离线或推送失败误判为丢消息。
|
if (!inserted.isEmpty()) TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
@Override public void afterCommit() {
|
try { PushMessageUtil.pushMessage(inserted, actor, 3); }
|
catch (RuntimeException error) { log.warn("升版站内信已保存,在线推送刷新失败", error); }
|
}
|
});
|
return true;
|
}
|
|
static String render(String template, Map<String,String> values, boolean html) {
|
java.util.regex.Matcher matcher = java.util.regex.Pattern.compile("\\{@([A-Za-z][A-Za-z0-9]*)}").matcher(template);
|
StringBuffer result = new StringBuffer();
|
while (matcher.find()) {
|
String value = values == null ? null : values.get(matcher.group(1));
|
if (value == null) throw new DataException("升版消息模板包含未知参数:" + matcher.group(1));
|
matcher.appendReplacement(result, java.util.regex.Matcher.quoteReplacement(html ? HtmlUtils.htmlEscape(value) : value));
|
}
|
matcher.appendTail(result); return result.toString();
|
}
|
private static boolean blank(String value) { return value == null || value.isBlank(); }
|
}
|