feat: 完成消息通知中心全功能开发
1. 新增消息通知相关实体、Mapper、Service、控制器与前端页面 2. 实现审批通知、报价到期提醒等通知发送逻辑 3. 完成通知菜单配置与路由注册 4. 修复通知数据与跳转路径问题 5. 新增配套SQL脚本与定时任务
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
package com.ruoyi.system.domain.bid;
|
||||
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 消息通知 biz_notify_message
|
||||
*/
|
||||
public class BizNotifyMessage extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long messageId;
|
||||
private Long tenantId;
|
||||
private Long userId;
|
||||
private String noticeType;
|
||||
private Integer priority;
|
||||
private String title;
|
||||
private String content;
|
||||
private String bizType;
|
||||
private Long bizId;
|
||||
private String bizUrl;
|
||||
private String isRead;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date readTime;
|
||||
|
||||
public Long getMessageId() { return messageId; }
|
||||
public void setMessageId(Long messageId) { this.messageId = messageId; }
|
||||
public Long getTenantId() { return tenantId; }
|
||||
public void setTenantId(Long tenantId) { this.tenantId = tenantId; }
|
||||
public Long getUserId() { return userId; }
|
||||
public void setUserId(Long userId) { this.userId = userId; }
|
||||
public String getNoticeType() { return noticeType; }
|
||||
public void setNoticeType(String noticeType) { this.noticeType = noticeType; }
|
||||
public Integer getPriority() { return priority; }
|
||||
public void setPriority(Integer priority) { this.priority = priority; }
|
||||
public String getTitle() { return title; }
|
||||
public void setTitle(String title) { this.title = title; }
|
||||
public String getContent() { return content; }
|
||||
public void setContent(String content) { this.content = content; }
|
||||
public String getBizType() { return bizType; }
|
||||
public void setBizType(String bizType) { this.bizType = bizType; }
|
||||
public Long getBizId() { return bizId; }
|
||||
public void setBizId(Long bizId) { this.bizId = bizId; }
|
||||
public String getBizUrl() { return bizUrl; }
|
||||
public void setBizUrl(String bizUrl) { this.bizUrl = bizUrl; }
|
||||
public String getIsRead() { return isRead; }
|
||||
public void setIsRead(String isRead) { this.isRead = isRead; }
|
||||
public Date getReadTime() { return readTime; }
|
||||
public void setReadTime(Date readTime) { this.readTime = readTime; }
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.ruoyi.system.domain.bid;
|
||||
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 通知规则配置 biz_notify_rule
|
||||
*/
|
||||
public class BizNotifyRule extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long ruleId;
|
||||
private Long tenantId;
|
||||
private String ruleName;
|
||||
private String noticeType;
|
||||
private String bizType;
|
||||
private String triggerCondition;
|
||||
private Integer advanceDays;
|
||||
private String enabled;
|
||||
|
||||
public Long getRuleId() { return ruleId; }
|
||||
public void setRuleId(Long ruleId) { this.ruleId = ruleId; }
|
||||
public Long getTenantId() { return tenantId; }
|
||||
public void setTenantId(Long tenantId) { this.tenantId = tenantId; }
|
||||
public String getRuleName() { return ruleName; }
|
||||
public void setRuleName(String ruleName) { this.ruleName = ruleName; }
|
||||
public String getNoticeType() { return noticeType; }
|
||||
public void setNoticeType(String noticeType) { this.noticeType = noticeType; }
|
||||
public String getBizType() { return bizType; }
|
||||
public void setBizType(String bizType) { this.bizType = bizType; }
|
||||
public String getTriggerCondition() { return triggerCondition; }
|
||||
public void setTriggerCondition(String triggerCondition) { this.triggerCondition = triggerCondition; }
|
||||
public Integer getAdvanceDays() { return advanceDays; }
|
||||
public void setAdvanceDays(Integer advanceDays) { this.advanceDays = advanceDays; }
|
||||
public String getEnabled() { return enabled; }
|
||||
public void setEnabled(String enabled) { this.enabled = enabled; }
|
||||
}
|
||||
@@ -16,4 +16,24 @@ public interface BizApprovalActionMapper {
|
||||
@Param("pk") String pk,
|
||||
@Param("statusCol") String statusCol,
|
||||
@Param("id") Long id);
|
||||
|
||||
/** 查询业务单据的 create_by(提交人用户名) */
|
||||
java.util.Map<String, Object> selectBizCreateInfo(@Param("table") String table,
|
||||
@Param("pk") String pk,
|
||||
@Param("id") Long id);
|
||||
|
||||
/** 查询采购订单详情(含供应商名称、询价标题、金额) */
|
||||
java.util.Map<String, Object> selectPurchaseOrderInfo(@Param("id") Long id);
|
||||
|
||||
/** 查询客户报价详情(含客户名称、询价标题、金额) */
|
||||
java.util.Map<String, Object> selectClientQuoteInfo(@Param("id") Long id);
|
||||
|
||||
/** 查询供应商报价详情(含供应商名称、询价标题、金额) */
|
||||
java.util.Map<String, Object> selectQuotationInfo(@Param("id") Long id);
|
||||
|
||||
/** 查询发货单详情(含供应商/客户名称、金额) */
|
||||
java.util.Map<String, Object> selectDeliveryOrderInfo(@Param("id") Long id);
|
||||
|
||||
/** 查询订单异议详情(含供应商名称、采购单号) */
|
||||
java.util.Map<String, Object> selectObjectionInfo(@Param("id") Long id);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.ruoyi.system.mapper.bid;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.ruoyi.system.domain.bid.BizNotifyMessage;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
public interface BizNotifyMessageMapper {
|
||||
public List<BizNotifyMessage> selectNotifyMessageList(BizNotifyMessage query);
|
||||
|
||||
public BizNotifyMessage selectNotifyMessageById(Long messageId);
|
||||
|
||||
public int insertNotifyMessage(BizNotifyMessage message);
|
||||
|
||||
public int batchInsertNotifyMessage(@Param("list") List<BizNotifyMessage> list);
|
||||
|
||||
public int updateNotifyMessage(BizNotifyMessage message);
|
||||
|
||||
public int markAsRead(@Param("messageId") Long messageId, @Param("userId") Long userId);
|
||||
|
||||
public int markAllAsRead(@Param("userId") Long userId);
|
||||
|
||||
public int deleteNotifyMessageByIds(@Param("ids") Long[] ids);
|
||||
|
||||
public int selectUnreadCount(@Param("userId") Long userId);
|
||||
|
||||
public List<Map<String, Object>> selectNotifyStats(@Param("userId") Long userId);
|
||||
|
||||
public List<BizNotifyMessage> selectTopUnread(@Param("userId") Long userId, @Param("limit") int limit);
|
||||
|
||||
public List<BizNotifyMessage> selectTopNotify(@Param("userId") Long userId, @Param("limit") int limit);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.ruoyi.system.mapper.bid;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.system.domain.bid.BizNotifyRule;
|
||||
|
||||
public interface BizNotifyRuleMapper {
|
||||
public List<BizNotifyRule> selectNotifyRuleList(BizNotifyRule query);
|
||||
|
||||
public BizNotifyRule selectNotifyRuleById(Long ruleId);
|
||||
|
||||
public int insertNotifyRule(BizNotifyRule rule);
|
||||
|
||||
public int updateNotifyRule(BizNotifyRule rule);
|
||||
|
||||
public int deleteNotifyRuleByIds(Long[] ids);
|
||||
|
||||
public List<BizNotifyRule> selectEnabledRules();
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.ruoyi.system.service.bid;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.ruoyi.system.domain.bid.BizNotifyMessage;
|
||||
|
||||
/**
|
||||
* 消息通知服务接口
|
||||
*/
|
||||
public interface IBizNotifyMessageService {
|
||||
public List<BizNotifyMessage> selectNotifyMessageList(BizNotifyMessage query);
|
||||
|
||||
public BizNotifyMessage selectNotifyMessageById(Long messageId);
|
||||
|
||||
public int insertNotifyMessage(BizNotifyMessage message);
|
||||
|
||||
public int batchInsertNotifyMessage(List<BizNotifyMessage> list);
|
||||
|
||||
public int markAsRead(Long messageId, Long userId);
|
||||
|
||||
public int markAllAsRead(Long userId);
|
||||
|
||||
public int deleteNotifyMessageByIds(Long[] ids);
|
||||
|
||||
public int selectUnreadCount(Long userId);
|
||||
|
||||
public List<Map<String, Object>> selectNotifyStats(Long userId);
|
||||
|
||||
public List<BizNotifyMessage> selectTopUnread(Long userId, int limit);
|
||||
|
||||
/**
|
||||
* 查询最近N条通知(含已读和未读),用于铃铛面板
|
||||
*/
|
||||
public List<BizNotifyMessage> selectTopNotify(Long userId, int limit);
|
||||
|
||||
/**
|
||||
* 发送审批结果通知
|
||||
* @param bizType 业务类型
|
||||
* @param bizId 业务ID
|
||||
* @param bizTitle 业务标题
|
||||
* @param approved 是否通过
|
||||
* @param reason 驳回原因
|
||||
* @param submitUserId 提交人用户ID
|
||||
* @param approverName 审批人姓名
|
||||
*/
|
||||
public void sendApprovalNotification(String bizType, Long bizId, String bizTitle,
|
||||
boolean approved, String reason, Long submitUserId, String approverName);
|
||||
|
||||
/**
|
||||
* 发送报价到期提醒
|
||||
* @param quotationId 报价单ID
|
||||
* @param quotationNo 报价单号
|
||||
* @param supplierName 供应商名称
|
||||
* @param daysRemaining 剩余天数
|
||||
* @param userId 接收人用户ID
|
||||
*/
|
||||
public void sendQuotationExpireNotification(Long quotationId, String quotationNo,
|
||||
String supplierName, int daysRemaining, Long userId);
|
||||
|
||||
/**
|
||||
* 发送报价到期提醒(含详情)
|
||||
* @param quotationId 报价单ID
|
||||
* @param quotationNo 报价单号
|
||||
* @param supplierName 供应商名称
|
||||
* @param rfqTitle 询价标题
|
||||
* @param totalAmount 报价金额
|
||||
* @param daysRemaining 剩余天数
|
||||
* @param userId 接收人用户ID
|
||||
*/
|
||||
public void sendQuotationExpireNotification(Long quotationId, String quotationNo,
|
||||
String supplierName, String rfqTitle, java.math.BigDecimal totalAmount,
|
||||
int daysRemaining, Long userId);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.ruoyi.system.service.bid;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.system.domain.bid.BizNotifyRule;
|
||||
|
||||
public interface IBizNotifyRuleService {
|
||||
public List<BizNotifyRule> selectNotifyRuleList(BizNotifyRule query);
|
||||
public BizNotifyRule selectNotifyRuleById(Long ruleId);
|
||||
public int insertNotifyRule(BizNotifyRule rule);
|
||||
public int updateNotifyRule(BizNotifyRule rule);
|
||||
public int deleteNotifyRuleByIds(Long[] ids);
|
||||
public List<BizNotifyRule> selectEnabledRules();
|
||||
}
|
||||
@@ -4,6 +4,11 @@ import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.system.mapper.bid.BizApprovalActionMapper;
|
||||
import com.ruoyi.system.service.bid.IBizApprovalActionService;
|
||||
import com.ruoyi.system.service.bid.IBizApprovalConfigService;
|
||||
import com.ruoyi.system.service.bid.IBizNotifyMessageService;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.system.domain.bid.BizApprovalConfig;
|
||||
import com.ruoyi.system.domain.bid.BizNotifyMessage;
|
||||
import com.ruoyi.system.mapper.SysUserMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -18,24 +23,26 @@ public class BizApprovalActionServiceImpl implements IBizApprovalActionService {
|
||||
|
||||
@Autowired private BizApprovalActionMapper mapper;
|
||||
@Autowired private IBizApprovalConfigService configService;
|
||||
@Autowired private IBizNotifyMessageService notifyMessageService;
|
||||
@Autowired private SysUserMapper sysUserMapper;
|
||||
|
||||
/** 业务类型 -> 表/主键/状态列/审批通过的目标状态/可提交的初始状态 */
|
||||
/** 业务类型 -> 表/主键/状态列/审批通过的目标状态/可提交的初始状态/业务名称 */
|
||||
static class Meta {
|
||||
final String table, pk, statusCol, approvedStatus;
|
||||
final String table, pk, statusCol, approvedStatus, bizName;
|
||||
final List<String> draftStatuses;
|
||||
Meta(String t, String pk, String sc, String approved, List<String> drafts) {
|
||||
Meta(String t, String pk, String sc, String approved, List<String> drafts, String bizName) {
|
||||
this.table = t; this.pk = pk; this.statusCol = sc;
|
||||
this.approvedStatus = approved; this.draftStatuses = drafts;
|
||||
this.approvedStatus = approved; this.draftStatuses = drafts; this.bizName = bizName;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Map<String, Meta> META = new HashMap<>();
|
||||
static {
|
||||
META.put("PURCHASE_ORDER", new Meta("biz_purchase_order", "po_id", "status", "confirmed", Arrays.asList("draft")));
|
||||
META.put("CLIENT_QUOTE", new Meta("biz_client_quote", "quote_id", "status", "confirmed", Arrays.asList("draft")));
|
||||
META.put("QUOTATION", new Meta("biz_quotation", "quotation_id", "status", "accepted", Arrays.asList("draft", "submitted")));
|
||||
META.put("DELIVERY_ORDER", new Meta("biz_delivery_order", "do_id", "delivery_status", "confirmed", Arrays.asList("pending")));
|
||||
META.put("ORDER_OBJECTION", new Meta("biz_order_objection", "objection_id", "status", "resolved", Arrays.asList("pending")));
|
||||
META.put("PURCHASE_ORDER", new Meta("biz_purchase_order", "po_id", "status", "confirmed", Arrays.asList("draft"), "采购订单"));
|
||||
META.put("CLIENT_QUOTE", new Meta("biz_client_quote", "quote_id", "status", "confirmed", Arrays.asList("draft"), "客户报价"));
|
||||
META.put("QUOTATION", new Meta("biz_quotation", "quotation_id", "status", "accepted", Arrays.asList("draft", "submitted"), "供应商报价"));
|
||||
META.put("DELIVERY_ORDER", new Meta("biz_delivery_order", "do_id", "delivery_status", "confirmed", Arrays.asList("pending"), "发货单"));
|
||||
META.put("ORDER_OBJECTION", new Meta("biz_order_objection", "objection_id", "status", "resolved", Arrays.asList("pending"), "订单异议"));
|
||||
}
|
||||
|
||||
private Meta meta(String bizType) {
|
||||
@@ -49,6 +56,13 @@ public class BizApprovalActionServiceImpl implements IBizApprovalActionService {
|
||||
Meta m = meta(bizType);
|
||||
int rows = mapper.updateStatus(m.table, m.pk, m.statusCol, id, "10", m.draftStatuses, username);
|
||||
if (rows == 0) throw new ServiceException("当前状态不允许提交审批");
|
||||
|
||||
// 通知审批人:有新的待审批申请
|
||||
try {
|
||||
sendSubmitNotification(bizType, m, id, username);
|
||||
} catch (Exception e) {
|
||||
// 通知发送失败不影响审批操作
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
@@ -61,6 +75,13 @@ public class BizApprovalActionServiceImpl implements IBizApprovalActionService {
|
||||
int rows = mapper.updateStatus(m.table, m.pk, m.statusCol, id,
|
||||
m.approvedStatus, Collections.singletonList("10"), username);
|
||||
if (rows == 0) throw new ServiceException("单据非审批中, 无法通过");
|
||||
|
||||
// 发送审批通过通知给提交人
|
||||
try {
|
||||
sendApprovalNotification(bizType, m, id, true, null, username);
|
||||
} catch (Exception e) {
|
||||
// 通知发送失败不影响审批操作
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
@@ -73,6 +94,203 @@ public class BizApprovalActionServiceImpl implements IBizApprovalActionService {
|
||||
int rows = mapper.updateStatus(m.table, m.pk, m.statusCol, id,
|
||||
"rejected", Collections.singletonList("10"), username);
|
||||
if (rows == 0) throw new ServiceException("单据非审批中, 无法驳回");
|
||||
|
||||
// 发送审批驳回通知给提交人
|
||||
try {
|
||||
sendApprovalNotification(bizType, m, id, false, reason, username);
|
||||
} catch (Exception e) {
|
||||
// 通知发送失败不影响审批操作
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询业务详情,返回统一格式: bizNo, partnerName, bizTitle, totalAmount, currency, createTime, createBy
|
||||
*/
|
||||
private Map<String, Object> getBizDetail(String bizType, Long bizId) {
|
||||
switch (bizType) {
|
||||
case "PURCHASE_ORDER": return mapper.selectPurchaseOrderInfo(bizId);
|
||||
case "CLIENT_QUOTE": return mapper.selectClientQuoteInfo(bizId);
|
||||
case "QUOTATION": return mapper.selectQuotationInfo(bizId);
|
||||
case "DELIVERY_ORDER": return mapper.selectDeliveryOrderInfo(bizId);
|
||||
case "ORDER_OBJECTION": return mapper.selectObjectionInfo(bizId);
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建审批通知内容(包含单号、客户/供应商、金额等关键信息)
|
||||
*/
|
||||
private String buildApprovalContent(String bizType, Meta m, Map<String, Object> detail,
|
||||
boolean approved, String reason, String approverName) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("您提交的【").append(m.bizName).append("】");
|
||||
|
||||
// 单号
|
||||
if (detail.get("bizNo") != null) {
|
||||
sb.append("(单号: ").append(detail.get("bizNo")).append(")");
|
||||
}
|
||||
|
||||
if (approved) {
|
||||
sb.append("已审批通过。");
|
||||
} else {
|
||||
sb.append("被驳回。");
|
||||
}
|
||||
|
||||
// 客户/供应商名称
|
||||
String partnerLabel = getPartnerLabel(bizType);
|
||||
if (detail.get("partnerName") != null) {
|
||||
sb.append(partnerLabel).append(": ").append(detail.get("partnerName")).append(";");
|
||||
}
|
||||
// 发货单额外显示客户名称
|
||||
if ("DELIVERY_ORDER".equals(bizType) && detail.get("clientName") != null) {
|
||||
sb.append("客户: ").append(detail.get("clientName")).append(";");
|
||||
}
|
||||
|
||||
// 询价标题/异议原因
|
||||
if (detail.get("bizTitle") != null) {
|
||||
sb.append("标题: ").append(detail.get("bizTitle")).append(";");
|
||||
}
|
||||
|
||||
// 金额
|
||||
if (detail.get("totalAmount") != null) {
|
||||
sb.append("金额: ").append(detail.get("totalAmount"));
|
||||
if (detail.get("currency") != null) {
|
||||
sb.append(" ").append(detail.get("currency"));
|
||||
}
|
||||
sb.append(";");
|
||||
}
|
||||
|
||||
sb.append("审批人: ").append(approverName);
|
||||
|
||||
// 驳回原因
|
||||
if (!approved && reason != null && !reason.isEmpty()) {
|
||||
sb.append(";驳回原因: ").append(reason);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建提交审批通知内容(发给审批人)
|
||||
*/
|
||||
private String buildSubmitContent(String bizType, Meta m, Map<String, Object> detail, String submitterName) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("您有新的【").append(m.bizName).append("】审批申请待处理。");
|
||||
|
||||
if (detail.get("bizNo") != null) {
|
||||
sb.append("单号: ").append(detail.get("bizNo")).append(";");
|
||||
}
|
||||
|
||||
String partnerLabel = getPartnerLabel(bizType);
|
||||
if (detail.get("partnerName") != null) {
|
||||
sb.append(partnerLabel).append(": ").append(detail.get("partnerName")).append(";");
|
||||
}
|
||||
if ("DELIVERY_ORDER".equals(bizType) && detail.get("clientName") != null) {
|
||||
sb.append("客户: ").append(detail.get("clientName")).append(";");
|
||||
}
|
||||
|
||||
if (detail.get("bizTitle") != null) {
|
||||
sb.append("标题: ").append(detail.get("bizTitle")).append(";");
|
||||
}
|
||||
|
||||
if (detail.get("totalAmount") != null) {
|
||||
sb.append("金额: ").append(detail.get("totalAmount"));
|
||||
if (detail.get("currency") != null) {
|
||||
sb.append(" ").append(detail.get("currency"));
|
||||
}
|
||||
sb.append(";");
|
||||
}
|
||||
|
||||
sb.append("提交人: ").append(submitterName);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/** 根据业务类型返回关联方标签 */
|
||||
private String getPartnerLabel(String bizType) {
|
||||
switch (bizType) {
|
||||
case "PURCHASE_ORDER":
|
||||
case "QUOTATION":
|
||||
case "DELIVERY_ORDER":
|
||||
case "ORDER_OBJECTION":
|
||||
return "供应商";
|
||||
case "CLIENT_QUOTE":
|
||||
return "客户";
|
||||
default:
|
||||
return "关联方";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送审批结果通知
|
||||
*/
|
||||
private void sendApprovalNotification(String bizType, Meta m, Long bizId, boolean approved, String reason, String approverName) {
|
||||
Map<String, Object> detail = getBizDetail(bizType, bizId);
|
||||
if (detail == null || detail.get("createBy") == null) return;
|
||||
|
||||
String createBy = (String) detail.get("createBy");
|
||||
SysUser submitUser = sysUserMapper.selectUserByUserName(createBy);
|
||||
if (submitUser == null) return;
|
||||
|
||||
String bizNo = detail.get("bizNo") != null ? String.valueOf(detail.get("bizNo")) : String.valueOf(bizId);
|
||||
String titlePrefix = approved ? "审批通过" : "审批驳回";
|
||||
String title = titlePrefix + ": " + m.bizName + " " + bizNo;
|
||||
|
||||
String content = buildApprovalContent(bizType, m, detail, approved, reason, approverName);
|
||||
|
||||
BizNotifyMessage msg = new BizNotifyMessage();
|
||||
msg.setUserId(submitUser.getUserId());
|
||||
msg.setNoticeType("approval");
|
||||
msg.setPriority(approved ? 1 : 2);
|
||||
msg.setBizType(bizType);
|
||||
msg.setBizId(bizId);
|
||||
msg.setBizUrl(getBizUrl(bizType, bizId));
|
||||
msg.setCreateBy(approverName);
|
||||
msg.setTitle(title);
|
||||
msg.setContent(content);
|
||||
msg.setIsRead("0");
|
||||
notifyMessageService.insertNotifyMessage(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送提交审批通知给审批人
|
||||
*/
|
||||
private void sendSubmitNotification(String bizType, Meta m, Long bizId, String submitterName) {
|
||||
BizApprovalConfig config = configService.selectByBizType(bizType);
|
||||
if (config == null || config.getUserIds() == null || config.getUserIds().isEmpty()) return;
|
||||
|
||||
Map<String, Object> detail = getBizDetail(bizType, bizId);
|
||||
String bizNo = (detail != null && detail.get("bizNo") != null) ? String.valueOf(detail.get("bizNo")) : String.valueOf(bizId);
|
||||
String title = "审批待处理: " + m.bizName + " " + bizNo;
|
||||
String content = (detail != null) ? buildSubmitContent(bizType, m, detail, submitterName)
|
||||
: "您有新的【" + m.bizName + "】审批申请待处理,提交人: " + submitterName;
|
||||
|
||||
for (Long approverUserId : config.getUserIds()) {
|
||||
if (approverUserId == null) continue;
|
||||
BizNotifyMessage msg = new BizNotifyMessage();
|
||||
msg.setUserId(approverUserId);
|
||||
msg.setNoticeType("approval");
|
||||
msg.setPriority(1);
|
||||
msg.setBizType(bizType);
|
||||
msg.setBizId(bizId);
|
||||
msg.setCreateBy(submitterName);
|
||||
msg.setTitle(title);
|
||||
msg.setContent(content);
|
||||
msg.setBizUrl(getBizUrl(bizType, bizId));
|
||||
msg.setIsRead("0");
|
||||
notifyMessageService.insertNotifyMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private String getBizUrl(String bizType, Long bizId) {
|
||||
if (bizType == null || bizId == null) return null;
|
||||
switch (bizType) {
|
||||
case "PURCHASE_ORDER": return "/quote/purchaseorder?id=" + bizId;
|
||||
case "CLIENT_QUOTE": return "/bid/clientquote/detail?id=" + bizId;
|
||||
case "QUOTATION": return "/quote/quotation?quotationId=" + bizId;
|
||||
case "DELIVERY_ORDER": return "/bid/order/pending?id=" + bizId;
|
||||
case "ORDER_OBJECTION": return "/bid/order/objection?id=" + bizId;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
package com.ruoyi.system.service.bid.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.ruoyi.system.domain.bid.BizNotifyMessage;
|
||||
import com.ruoyi.system.mapper.bid.BizNotifyMessageMapper;
|
||||
import com.ruoyi.system.service.bid.IBizNotifyMessageService;
|
||||
|
||||
@Service
|
||||
public class BizNotifyMessageServiceImpl implements IBizNotifyMessageService {
|
||||
|
||||
@Autowired
|
||||
private BizNotifyMessageMapper notifyMessageMapper;
|
||||
|
||||
@Override
|
||||
public List<BizNotifyMessage> selectNotifyMessageList(BizNotifyMessage query) {
|
||||
return notifyMessageMapper.selectNotifyMessageList(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BizNotifyMessage selectNotifyMessageById(Long messageId) {
|
||||
return notifyMessageMapper.selectNotifyMessageById(messageId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertNotifyMessage(BizNotifyMessage message) {
|
||||
return notifyMessageMapper.insertNotifyMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batchInsertNotifyMessage(List<BizNotifyMessage> list) {
|
||||
return notifyMessageMapper.batchInsertNotifyMessage(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int markAsRead(Long messageId, Long userId) {
|
||||
return notifyMessageMapper.markAsRead(messageId, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int markAllAsRead(Long userId) {
|
||||
return notifyMessageMapper.markAllAsRead(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteNotifyMessageByIds(Long[] ids) {
|
||||
return notifyMessageMapper.deleteNotifyMessageByIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int selectUnreadCount(Long userId) {
|
||||
return notifyMessageMapper.selectUnreadCount(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> selectNotifyStats(Long userId) {
|
||||
return notifyMessageMapper.selectNotifyStats(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BizNotifyMessage> selectTopUnread(Long userId, int limit) {
|
||||
return notifyMessageMapper.selectTopUnread(userId, limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BizNotifyMessage> selectTopNotify(Long userId, int limit) {
|
||||
return notifyMessageMapper.selectTopNotify(userId, limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendApprovalNotification(String bizType, Long bizId, String bizTitle,
|
||||
boolean approved, String reason, Long submitUserId, String approverName) {
|
||||
BizNotifyMessage msg = new BizNotifyMessage();
|
||||
msg.setUserId(submitUserId);
|
||||
msg.setNoticeType("approval");
|
||||
msg.setPriority(approved ? 1 : 2);
|
||||
msg.setBizType(bizType);
|
||||
msg.setBizId(bizId);
|
||||
msg.setCreateBy(approverName);
|
||||
|
||||
if (approved) {
|
||||
msg.setTitle("审批通过: " + bizTitle);
|
||||
msg.setContent("您提交的【" + bizTitle + "】已审批通过。审批人: " + approverName);
|
||||
} else {
|
||||
msg.setTitle("审批驳回: " + bizTitle);
|
||||
msg.setContent("您提交的【" + bizTitle + "】被驳回。审批人: " + approverName + ";驳回原因: " + (reason != null ? reason : "无"));
|
||||
}
|
||||
|
||||
msg.setIsRead("0");
|
||||
msg.setBizUrl(getBizUrl(bizType, bizId));
|
||||
notifyMessageMapper.insertNotifyMessage(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendQuotationExpireNotification(Long quotationId, String quotationNo,
|
||||
String supplierName, int daysRemaining, Long userId) {
|
||||
sendQuotationExpireNotification(quotationId, quotationNo, supplierName, null, null, daysRemaining, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendQuotationExpireNotification(Long quotationId, String quotationNo,
|
||||
String supplierName, String rfqTitle, java.math.BigDecimal totalAmount,
|
||||
int daysRemaining, Long userId) {
|
||||
BizNotifyMessage msg = new BizNotifyMessage();
|
||||
msg.setUserId(userId);
|
||||
msg.setNoticeType("quotation_expire");
|
||||
msg.setBizType("QUOTATION");
|
||||
msg.setBizId(quotationId);
|
||||
msg.setBizUrl("/quote/quotation?quotationId=" + quotationId);
|
||||
msg.setCreateBy("system");
|
||||
|
||||
if (daysRemaining <= 0) {
|
||||
msg.setPriority(2);
|
||||
msg.setTitle("报价已过期: " + quotationNo);
|
||||
} else if (daysRemaining <= 1) {
|
||||
msg.setPriority(2);
|
||||
msg.setTitle("报价今日到期: " + quotationNo);
|
||||
} else {
|
||||
msg.setPriority(1);
|
||||
msg.setTitle("报价即将到期: " + quotationNo);
|
||||
}
|
||||
|
||||
StringBuilder content = new StringBuilder();
|
||||
content.append("供应商【").append(supplierName).append("】的报价单【").append(quotationNo).append("】");
|
||||
if (daysRemaining <= 0) {
|
||||
content.append("已过期,请及时处理。");
|
||||
} else {
|
||||
content.append("将在").append(daysRemaining).append("天后到期。");
|
||||
}
|
||||
if (rfqTitle != null && !rfqTitle.isEmpty()) {
|
||||
content.append("询价标题: ").append(rfqTitle).append(";");
|
||||
}
|
||||
if (totalAmount != null) {
|
||||
content.append("报价金额: ").append(totalAmount).append(";");
|
||||
}
|
||||
|
||||
msg.setContent(content.toString());
|
||||
msg.setIsRead("0");
|
||||
notifyMessageMapper.insertNotifyMessage(msg);
|
||||
}
|
||||
|
||||
private String getBizUrl(String bizType, Long bizId) {
|
||||
if (bizType == null || bizId == null) return null;
|
||||
switch (bizType) {
|
||||
case "PURCHASE_ORDER": return "/quote/purchaseorder?id=" + bizId;
|
||||
case "CLIENT_QUOTE": return "/bid/clientquote/detail?id=" + bizId;
|
||||
case "QUOTATION": return "/quote/quotation?quotationId=" + bizId;
|
||||
case "DELIVERY_ORDER": return "/bid/order/pending?id=" + bizId;
|
||||
case "ORDER_OBJECTION": return "/bid/order/objection?id=" + bizId;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.ruoyi.system.service.bid.impl;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.ruoyi.system.domain.bid.BizNotifyRule;
|
||||
import com.ruoyi.system.mapper.bid.BizNotifyRuleMapper;
|
||||
import com.ruoyi.system.service.bid.IBizNotifyRuleService;
|
||||
|
||||
@Service
|
||||
public class BizNotifyRuleServiceImpl implements IBizNotifyRuleService {
|
||||
|
||||
@Autowired
|
||||
private BizNotifyRuleMapper notifyRuleMapper;
|
||||
|
||||
@Override
|
||||
public List<BizNotifyRule> selectNotifyRuleList(BizNotifyRule query) {
|
||||
return notifyRuleMapper.selectNotifyRuleList(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BizNotifyRule selectNotifyRuleById(Long ruleId) {
|
||||
return notifyRuleMapper.selectNotifyRuleById(ruleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertNotifyRule(BizNotifyRule rule) {
|
||||
return notifyRuleMapper.insertNotifyRule(rule);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateNotifyRule(BizNotifyRule rule) {
|
||||
return notifyRuleMapper.updateNotifyRule(rule);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteNotifyRuleByIds(Long[] ids) {
|
||||
return notifyRuleMapper.deleteNotifyRuleByIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BizNotifyRule> selectEnabledRules() {
|
||||
return notifyRuleMapper.selectEnabledRules();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.ruoyi.system.task;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.system.mapper.SysUserMapper;
|
||||
import com.ruoyi.system.service.bid.IBizNotifyMessageService;
|
||||
import com.ruoyi.system.mapper.bid.BizQuotationMapper;
|
||||
import com.ruoyi.system.domain.bid.BizQuotation;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* 定时任务 - 报价到期提醒
|
||||
* 每日执行,检查即将到期和已过期的报价单,发送站内通知
|
||||
*
|
||||
* Quartz 调用示例: quotationExpireTask.checkQuotationExpire()
|
||||
* 推荐表达式: 0 0 9 * * ? (每天上午9点执行)
|
||||
*/
|
||||
@Component("quotationExpireTask")
|
||||
public class QuotationExpireTask {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(QuotationExpireTask.class);
|
||||
|
||||
@Autowired
|
||||
private BizQuotationMapper quotationMapper;
|
||||
|
||||
@Autowired
|
||||
private IBizNotifyMessageService notifyMessageService;
|
||||
|
||||
@Autowired
|
||||
private SysUserMapper sysUserMapper;
|
||||
|
||||
/**
|
||||
* 每日报价到期检查
|
||||
* 检查所有未完成报价单(草稿、审批中),基于 submitTime + validDays 计算到期日,
|
||||
* 在到期前3天、1天、到期当天发送提醒。
|
||||
*/
|
||||
public void checkQuotationExpire() {
|
||||
log.info("=== 开始执行报价到期检查 ===");
|
||||
|
||||
// 查询所有报价单(不限制状态),在循环中过滤已完成的
|
||||
BizQuotation query = new BizQuotation();
|
||||
List<BizQuotation> quotations = quotationMapper.selectBizQuotationList(query);
|
||||
|
||||
int remindCount = 0;
|
||||
for (BizQuotation q : quotations) {
|
||||
// 跳过已完成的报价单
|
||||
if ("accepted".equals(q.getStatus()) || "rejected".equals(q.getStatus())) {
|
||||
continue;
|
||||
}
|
||||
// 必须设置了有效期
|
||||
if (q.getValidDays() == null || q.getValidDays() <= 0) continue;
|
||||
|
||||
// 使用 submitTime 计算到期,草稿单据用 createTime 回退
|
||||
java.util.Date baseTime = q.getSubmitTime() != null ? q.getSubmitTime() : q.getCreateTime();
|
||||
if (baseTime == null) continue;
|
||||
|
||||
long expireTime = baseTime.getTime() + (long) q.getValidDays() * 24 * 60 * 60 * 1000L;
|
||||
long now = System.currentTimeMillis();
|
||||
int daysRemaining = (int) Math.ceil((expireTime - now) / (24.0 * 60 * 60 * 1000));
|
||||
|
||||
// 提前3天、1天提醒,过期当天提醒
|
||||
if (daysRemaining == 3 || daysRemaining == 1 || daysRemaining == 0) {
|
||||
try {
|
||||
if (StringUtils.isNotEmpty(q.getCreateBy())) {
|
||||
SysUser createUser = sysUserMapper.selectUserByUserName(q.getCreateBy());
|
||||
if (createUser != null) {
|
||||
String supplierName = q.getSupplierName() != null ? q.getSupplierName() : "供应商-" + q.getSupplierId();
|
||||
String rfqTitle = q.getRfqTitle();
|
||||
BigDecimal totalAmount = q.getTotalAmount();
|
||||
notifyMessageService.sendQuotationExpireNotification(
|
||||
q.getQuotationId(),
|
||||
q.getQuoteNo(),
|
||||
supplierName,
|
||||
rfqTitle,
|
||||
totalAmount,
|
||||
daysRemaining,
|
||||
createUser.getUserId()
|
||||
);
|
||||
remindCount++;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("报价到期提醒发送失败, quotationId={}", q.getQuotationId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.info("=== 报价到期检查完成, 共发送 {} 条提醒 ===", remindCount);
|
||||
}
|
||||
}
|
||||
@@ -17,4 +17,58 @@
|
||||
<select id="selectStatus" resultType="java.lang.String">
|
||||
SELECT ${statusCol} FROM ${table} WHERE ${pk}=#{id}
|
||||
</select>
|
||||
|
||||
<select id="selectBizCreateInfo" resultType="java.util.Map">
|
||||
SELECT t.create_by AS createBy FROM ${table} t WHERE ${pk}=#{id}
|
||||
</select>
|
||||
|
||||
<!-- 查询采购订单详情 -->
|
||||
<select id="selectPurchaseOrderInfo" resultType="java.util.Map">
|
||||
SELECT p.po_no AS bizNo, s.supplier_name AS partnerName, r.rfq_title AS bizTitle,
|
||||
p.total_amount AS totalAmount, p.currency, p.create_time AS createTime, p.create_by AS createBy
|
||||
FROM biz_purchase_order p
|
||||
LEFT JOIN biz_supplier s ON p.supplier_id = s.supplier_id
|
||||
LEFT JOIN biz_rfq r ON p.rfq_id = r.rfq_id
|
||||
WHERE p.po_id = #{id}
|
||||
</select>
|
||||
|
||||
<!-- 查询客户报价详情 -->
|
||||
<select id="selectClientQuoteInfo" resultType="java.util.Map">
|
||||
SELECT q.quote_no AS bizNo, q.client_name AS partnerName, q.rfq_title AS bizTitle,
|
||||
q.total_amount AS totalAmount, q.currency, q.create_time AS createTime, q.create_by AS createBy
|
||||
FROM biz_client_quote q
|
||||
WHERE q.quote_id = #{id}
|
||||
</select>
|
||||
|
||||
<!-- 查询供应商报价详情 -->
|
||||
<select id="selectQuotationInfo" resultType="java.util.Map">
|
||||
SELECT q.quote_no AS bizNo, s.supplier_name AS partnerName, r.rfq_title AS bizTitle,
|
||||
q.total_amount AS totalAmount, q.currency, q.submit_time AS createTime, q.create_by AS createBy
|
||||
FROM biz_quotation q
|
||||
LEFT JOIN biz_supplier s ON q.supplier_id = s.supplier_id
|
||||
LEFT JOIN biz_rfq r ON q.rfq_id = r.rfq_id
|
||||
WHERE q.quotation_id = #{id}
|
||||
</select>
|
||||
|
||||
<!-- 查询发货单详情 -->
|
||||
<select id="selectDeliveryOrderInfo" resultType="java.util.Map">
|
||||
SELECT d.do_no AS bizNo, s.supplier_name AS partnerName,
|
||||
COALESCE(cl.client_name, cq.client_name) AS clientName,
|
||||
d.total_amount AS totalAmount, d.currency, d.create_time AS createTime, d.create_by AS createBy
|
||||
FROM biz_delivery_order d
|
||||
LEFT JOIN biz_supplier s ON d.supplier_id = s.supplier_id
|
||||
LEFT JOIN biz_client_quote cq ON d.client_quote_id = cq.quote_id
|
||||
LEFT JOIN biz_client cl ON cq.client_id = cl.client_id
|
||||
WHERE d.do_id = #{id}
|
||||
</select>
|
||||
|
||||
<!-- 查询订单异议详情 -->
|
||||
<select id="selectObjectionInfo" resultType="java.util.Map">
|
||||
SELECT o.reason AS bizTitle, s.supplier_name AS partnerName, p.po_no AS bizNo,
|
||||
o.create_time AS createTime, o.create_by AS createBy
|
||||
FROM biz_order_objection o
|
||||
LEFT JOIN biz_supplier s ON o.supplier_id = s.supplier_id
|
||||
LEFT JOIN biz_purchase_order p ON o.po_id = p.po_id
|
||||
WHERE o.objection_id = #{id}
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.system.mapper.bid.BizNotifyMessageMapper">
|
||||
|
||||
<resultMap id="NotifyMessageRM" type="com.ruoyi.system.domain.bid.BizNotifyMessage">
|
||||
<id property="messageId" column="message_id"/>
|
||||
<result property="tenantId" column="tenant_id"/>
|
||||
<result property="userId" column="user_id"/>
|
||||
<result property="noticeType" column="notice_type"/>
|
||||
<result property="priority" column="priority"/>
|
||||
<result property="title" column="title"/>
|
||||
<result property="content" column="content"/>
|
||||
<result property="bizType" column="biz_type"/>
|
||||
<result property="bizId" column="biz_id"/>
|
||||
<result property="bizUrl" column="biz_url"/>
|
||||
<result property="isRead" column="is_read"/>
|
||||
<result property="readTime" column="read_time"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectColumns">
|
||||
message_id, tenant_id, user_id, notice_type, priority, title, content,
|
||||
biz_type, biz_id, biz_url, is_read, read_time, create_by, create_time
|
||||
</sql>
|
||||
|
||||
<select id="selectNotifyMessageList" parameterType="com.ruoyi.system.domain.bid.BizNotifyMessage" resultMap="NotifyMessageRM">
|
||||
SELECT <include refid="selectColumns"/>
|
||||
FROM biz_notify_message
|
||||
<where>
|
||||
<if test="userId != null"> AND user_id = #{userId} </if>
|
||||
<if test="noticeType != null and noticeType != ''"> AND notice_type = #{noticeType} </if>
|
||||
<if test="isRead != null and isRead != ''"> AND is_read = #{isRead} </if>
|
||||
<if test="bizType != null and bizType != ''"> AND biz_type = #{bizType} </if>
|
||||
<if test="priority != null"> AND priority = #{priority} </if>
|
||||
<if test="params.beginTime != null and params.beginTime != ''"> AND create_time >= #{params.beginTime} </if>
|
||||
<if test="params.endTime != null and params.endTime != ''"> AND create_time <= #{params.endTime} </if>
|
||||
</where>
|
||||
ORDER BY create_time DESC
|
||||
</select>
|
||||
|
||||
<select id="selectNotifyMessageById" parameterType="Long" resultMap="NotifyMessageRM">
|
||||
SELECT <include refid="selectColumns"/> FROM biz_notify_message WHERE message_id = #{messageId}
|
||||
</select>
|
||||
|
||||
<insert id="insertNotifyMessage" parameterType="com.ruoyi.system.domain.bid.BizNotifyMessage" useGeneratedKeys="true" keyProperty="messageId">
|
||||
INSERT INTO biz_notify_message
|
||||
(tenant_id, user_id, notice_type, priority, title, content, biz_type, biz_id, biz_url, is_read, create_by, create_time)
|
||||
VALUES
|
||||
(#{tenantId}, #{userId}, #{noticeType}, #{priority}, #{title}, #{content}, #{bizType}, #{bizId}, #{bizUrl}, #{isRead}, #{createBy}, sysdate())
|
||||
</insert>
|
||||
|
||||
<insert id="batchInsertNotifyMessage" parameterType="java.util.List">
|
||||
INSERT INTO biz_notify_message
|
||||
(tenant_id, user_id, notice_type, priority, title, content, biz_type, biz_id, biz_url, is_read, create_by, create_time)
|
||||
VALUES
|
||||
<foreach collection="list" item="m" separator=",">
|
||||
(#{m.tenantId}, #{m.userId}, #{m.noticeType}, #{m.priority}, #{m.title}, #{m.content}, #{m.bizType}, #{m.bizId}, #{m.bizUrl}, '0', #{m.createBy}, sysdate())
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<update id="updateNotifyMessage" parameterType="com.ruoyi.system.domain.bid.BizNotifyMessage">
|
||||
UPDATE biz_notify_message
|
||||
<set>
|
||||
<if test="isRead != null and isRead != ''"> is_read = #{isRead}, </if>
|
||||
<if test="readTime != null"> read_time = #{readTime}, </if>
|
||||
</set>
|
||||
WHERE message_id = #{messageId}
|
||||
</update>
|
||||
|
||||
<update id="markAsRead">
|
||||
UPDATE biz_notify_message SET is_read = '1', read_time = sysdate()
|
||||
WHERE message_id = #{messageId} AND user_id = #{userId} AND is_read = '0'
|
||||
</update>
|
||||
|
||||
<update id="markAllAsRead">
|
||||
UPDATE biz_notify_message SET is_read = '1', read_time = sysdate()
|
||||
WHERE user_id = #{userId} AND is_read = '0'
|
||||
</update>
|
||||
|
||||
<delete id="deleteNotifyMessageByIds">
|
||||
DELETE FROM biz_notify_message WHERE message_id IN
|
||||
<foreach collection="ids" item="id" open="(" separator="," close=")"> #{id} </foreach>
|
||||
</delete>
|
||||
|
||||
<select id="selectUnreadCount" resultType="int">
|
||||
SELECT COUNT(*) FROM biz_notify_message WHERE user_id = #{userId} AND is_read = '0'
|
||||
</select>
|
||||
|
||||
<select id="selectNotifyStats" resultType="java.util.Map">
|
||||
SELECT
|
||||
notice_type AS noticeType,
|
||||
SUM(CASE WHEN is_read = '0' THEN 1 ELSE 0 END) AS unreadCount,
|
||||
COUNT(*) AS totalCount
|
||||
FROM biz_notify_message
|
||||
WHERE user_id = #{userId}
|
||||
GROUP BY notice_type
|
||||
</select>
|
||||
|
||||
<select id="selectTopUnread" resultMap="NotifyMessageRM">
|
||||
SELECT <include refid="selectColumns"/>
|
||||
FROM biz_notify_message
|
||||
WHERE user_id = #{userId} AND is_read = '0'
|
||||
ORDER BY priority DESC, create_time DESC
|
||||
LIMIT #{limit}
|
||||
</select>
|
||||
|
||||
<select id="selectTopNotify" resultMap="NotifyMessageRM">
|
||||
SELECT <include refid="selectColumns"/>
|
||||
FROM biz_notify_message
|
||||
WHERE user_id = #{userId}
|
||||
ORDER BY priority DESC, create_time DESC
|
||||
LIMIT #{limit}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.system.mapper.bid.BizNotifyRuleMapper">
|
||||
|
||||
<resultMap id="NotifyRuleRM" type="com.ruoyi.system.domain.bid.BizNotifyRule">
|
||||
<id property="ruleId" column="rule_id"/>
|
||||
<result property="tenantId" column="tenant_id"/>
|
||||
<result property="ruleName" column="rule_name"/>
|
||||
<result property="noticeType" column="notice_type"/>
|
||||
<result property="bizType" column="biz_type"/>
|
||||
<result property="triggerCondition" column="trigger_condition"/>
|
||||
<result property="advanceDays" column="advance_days"/>
|
||||
<result property="enabled" column="enabled"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="selectNotifyRuleList" parameterType="com.ruoyi.system.domain.bid.BizNotifyRule" resultMap="NotifyRuleRM">
|
||||
SELECT rule_id, tenant_id, rule_name, notice_type, biz_type, trigger_condition, advance_days, enabled, create_by, create_time
|
||||
FROM biz_notify_rule
|
||||
<where>
|
||||
<if test="noticeType != null and noticeType != ''"> AND notice_type = #{noticeType} </if>
|
||||
<if test="bizType != null and bizType != ''"> AND biz_type = #{bizType} </if>
|
||||
<if test="enabled != null and enabled != ''"> AND enabled = #{enabled} </if>
|
||||
</where>
|
||||
ORDER BY rule_id
|
||||
</select>
|
||||
|
||||
<select id="selectNotifyRuleById" parameterType="Long" resultMap="NotifyRuleRM">
|
||||
SELECT rule_id, tenant_id, rule_name, notice_type, biz_type, trigger_condition, advance_days, enabled, create_by, create_time
|
||||
FROM biz_notify_rule WHERE rule_id = #{ruleId}
|
||||
</select>
|
||||
|
||||
<insert id="insertNotifyRule" parameterType="com.ruoyi.system.domain.bid.BizNotifyRule" useGeneratedKeys="true" keyProperty="ruleId">
|
||||
INSERT INTO biz_notify_rule (tenant_id, rule_name, notice_type, biz_type, trigger_condition, advance_days, enabled, create_by, create_time)
|
||||
VALUES (#{tenantId}, #{ruleName}, #{noticeType}, #{bizType}, #{triggerCondition}, #{advanceDays}, #{enabled}, #{createBy}, sysdate())
|
||||
</insert>
|
||||
|
||||
<update id="updateNotifyRule" parameterType="com.ruoyi.system.domain.bid.BizNotifyRule">
|
||||
UPDATE biz_notify_rule
|
||||
<set>
|
||||
<if test="ruleName != null and ruleName != ''"> rule_name = #{ruleName}, </if>
|
||||
<if test="noticeType != null and noticeType != ''"> notice_type = #{noticeType}, </if>
|
||||
<if test="bizType != null"> biz_type = #{bizType}, </if>
|
||||
<if test="triggerCondition != null"> trigger_condition = #{triggerCondition}, </if>
|
||||
<if test="advanceDays != null"> advance_days = #{advanceDays}, </if>
|
||||
<if test="enabled != null and enabled != ''"> enabled = #{enabled}, </if>
|
||||
</set>
|
||||
WHERE rule_id = #{ruleId}
|
||||
</update>
|
||||
|
||||
<delete id="deleteNotifyRuleByIds">
|
||||
DELETE FROM biz_notify_rule WHERE rule_id IN
|
||||
<foreach collection="array" item="id" open="(" separator="," close=")"> #{id} </foreach>
|
||||
</delete>
|
||||
|
||||
<select id="selectEnabledRules" resultMap="NotifyRuleRM">
|
||||
SELECT rule_id, tenant_id, rule_name, notice_type, biz_type, trigger_condition, advance_days, enabled, create_by, create_time
|
||||
FROM biz_notify_rule WHERE enabled = '1'
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user