feat(sg-notice): 添加公告首次查看反馈功能

main
zhaokai 2026-06-26 15:18:11 +08:00
parent 73f14a0d72
commit 8f3715cb2c
12 changed files with 144 additions and 52 deletions

View File

@ -57,16 +57,17 @@ openapi:
sg: sg:
enabled: true enabled: true
url: http://10.168.11.13:8080/ url: http://10.168.11.13:8080
# url: http://safety.ngrok.shebaocard.com/ # url: http://safety.ngrok.shebaocard.com/
token_url: /admin/login token_url: /admin/login
reference_url: /safety/experience/receive reference_url: /safety/experience/receive
notice_feedback_url: /system/notice/feedback
supervise_url: /safety/superviseInfo/feedback supervise_url: /safety/superviseInfo/feedback
duty_url: /safety/statistics/receiveDutyStatistics duty_url: /safety/statistics/receiveDutyStatistics
calendar_url: /safety/safetyCalendar/receive calendar_url: /safety/safetyCalendar/receive
accident_url: /safety/accidentReport/receive accident_url: /safety/accidentReport/receive
levelxgf_url: safety/firstRelevantParty/receive levelxgf_url: /safety/firstRelevantParty/receive
supervise_offline_url: safety/superviseInfo/offline/feedback supervise_offline_url: /safety/superviseInfo/offline/feedback
message: message:
code: code:
forward: MS000116 forward: MS000116

View File

@ -61,6 +61,7 @@ sg:
# url: http://safety.ngrok.shebaocard.com/ # url: http://safety.ngrok.shebaocard.com/
token_url: /admin/login token_url: /admin/login
reference_url: /safety/experience/receive reference_url: /safety/experience/receive
notice_feedback_url: /system/notice/feedback
supervise_url: /safety/superviseInfo/feedback supervise_url: /safety/superviseInfo/feedback
duty_url: /safety/statistics/receiveDutyStatistics duty_url: /safety/statistics/receiveDutyStatistics
calendar_url: /safety/safetyCalendar/receive calendar_url: /safety/safetyCalendar/receive

View File

@ -61,6 +61,7 @@ sg:
# url: http://safety.ngrok.shebaocard.com/ # url: http://safety.ngrok.shebaocard.com/
token_url: /admin/login token_url: /admin/login
reference_url: /safety/experience/receive reference_url: /safety/experience/receive
notice_feedback_url: /system/notice/feedback
supervise_url: /safety/superviseInfo/feedback supervise_url: /safety/superviseInfo/feedback
duty_url: /safety/statistics/receiveDutyStatistics duty_url: /safety/statistics/receiveDutyStatistics
calendar_url: /safety/safetyCalendar/receive calendar_url: /safety/safetyCalendar/receive

View File

@ -78,7 +78,7 @@ public class SgNoticeAddExe {
deleteOldImages(byNoticeId.getNoticeId(), files); deleteOldImages(byNoticeId.getNoticeId(), files);
log.info("检测到已存在公告数据,执行更新,公告业务主键:{}", noticeId); log.info("检测到已存在公告数据,执行更新,公告业务主键:{}", noticeId);
} else { } else {
sgNoticeE.setNoticeId(Tools.get32UUID()); sgNoticeE.setNoticeId(noticeId);
log.info("检测到首次接收公告数据,执行新增,公告业务主键:{}", noticeId); log.info("检测到首次接收公告数据,执行新增,公告业务主键:{}", noticeId);
} }
} else { } else {

View File

@ -0,0 +1,92 @@
package com.zcloud.safety.command;
import com.zcloud.safety.domain.config.SgProperties;
import com.zcloud.safety.domain.enums.PushSourceEnum;
import com.zcloud.safety.domain.gateway.SgNoticeGateway;
import com.zcloud.safety.domain.model.SgNoticeE;
import com.zcloud.safety.domain.utils.TokenUtils;
import com.zcloud.safety.persistence.dataobject.SgNoticeDO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.HashMap;
import java.util.Map;
/**
*
*/
@Slf4j
@Component
@AllArgsConstructor
public class SgNoticeFeedbackSupport {
private static final PushSourceEnum DEFAULT_SOURCE = PushSourceEnum.QINGANG_GUFEN;
private final SgProperties sgProperties;
private final SgNoticeGateway sgNoticeGateway;
/**
*
*
*/
public void feedbackOnFirstView(SgNoticeDO sgNoticeDO) {
if (sgNoticeDO == null || sgNoticeDO.getId() == null || !StringUtils.hasText(sgNoticeDO.getNoticeId())) {
return;
}
if (Integer.valueOf(1).equals(sgNoticeDO.getReadingFlag())) {
log.info("公告已读状态已是已阅读,跳过首次查看反馈,公告主键:{},公告业务主键:{}",
sgNoticeDO.getId(), sgNoticeDO.getNoticeId());
return;
}
if (!StringUtils.hasText(sgProperties.getNoticeFeedbackUrl())) {
log.warn("公告首次查看反馈地址未配置,跳过反馈,公告主键:{},公告业务主键:{}",
sgNoticeDO.getId(), sgNoticeDO.getNoticeId());
return;
}
String source = DEFAULT_SOURCE.getCode();
Map<String, Object> requestData = buildRequestData(sgNoticeDO, source);
try {
String token = resolveToken();
log.info("开始执行公告首次查看反馈,公告主键:{},公告业务主键:{},来源:{},请求数据:{}",
sgNoticeDO.getId(), sgNoticeDO.getNoticeId(), source, requestData);
if (Boolean.TRUE.equals(sgProperties.getEnabled())) {
TokenUtils.sendDataToThirdParty(sgProperties.getNoticeFeedbackUrl(), requestData, token);
} else {
log.info("模拟公告首次查看反馈,公告主键:{},公告业务主键:{},来源:{}url{},请求数据:{}",
sgNoticeDO.getId(), sgNoticeDO.getNoticeId(), source, sgProperties.getNoticeFeedbackUrl(), requestData);
}
updateReadingFlag(sgNoticeDO);
log.info("公告首次查看反馈成功,并已更新阅读状态,公告主键:{},公告业务主键:{}",
sgNoticeDO.getId(), sgNoticeDO.getNoticeId());
} catch (Exception e) {
log.error("公告首次查看反馈失败,将在下次查看时继续重试,公告主键:{},公告业务主键:{}",
sgNoticeDO.getId(), sgNoticeDO.getNoticeId(), e);
}
}
private Map<String, Object> buildRequestData(SgNoticeDO sgNoticeDO, String source) {
Map<String, Object> requestData = new HashMap<>();
requestData.put("source", source);
requestData.put("noticeId", sgNoticeDO.getNoticeId());
return requestData;
}
private String resolveToken() throws Exception {
if (!Boolean.TRUE.equals(sgProperties.getEnabled())) {
return "tokenAAAA";
}
return TokenUtils.getTokenFromThirdParty(sgProperties.getTokenUrl());
}
private void updateReadingFlag(SgNoticeDO sgNoticeDO) {
SgNoticeE sgNoticeE = new SgNoticeE();
sgNoticeE.setId(sgNoticeDO.getId());
sgNoticeE.setNoticeId(sgNoticeDO.getNoticeId());
sgNoticeE.setReadingFlag(1);
sgNoticeGateway.update(sgNoticeE);
sgNoticeDO.setReadingFlag(1);
}
}

View File

@ -2,6 +2,7 @@ package com.zcloud.safety.command.query;
import com.alibaba.cola.dto.PageResponse; import com.alibaba.cola.dto.PageResponse;
import com.zcloud.gbscommon.utils.PageQueryHelper; import com.zcloud.gbscommon.utils.PageQueryHelper;
import com.zcloud.safety.command.SgNoticeFeedbackSupport;
import com.zcloud.safety.command.convertor.ImgFilesCoConvertor; import com.zcloud.safety.command.convertor.ImgFilesCoConvertor;
import com.zcloud.safety.command.convertor.SgNoticeCoConvertor; import com.zcloud.safety.command.convertor.SgNoticeCoConvertor;
import com.zcloud.safety.dto.SgNoticePageQry; import com.zcloud.safety.dto.SgNoticePageQry;
@ -29,6 +30,7 @@ public class SgNoticeQueryExe {
private final ImgFilesRepository imgFilesRepository; private final ImgFilesRepository imgFilesRepository;
private final SgNoticeCoConvertor sgNoticeCoConvertor; private final SgNoticeCoConvertor sgNoticeCoConvertor;
private final ImgFilesCoConvertor imgFilesCoConvertor; private final ImgFilesCoConvertor imgFilesCoConvertor;
private final SgNoticeFeedbackSupport sgNoticeFeedbackSupport;
/** /**
* *
@ -49,6 +51,9 @@ public class SgNoticeQueryExe {
return null; return null;
} }
// 公告详情首次查看时,同步向数港发送查看反馈,并把公告表阅读状态更新为已阅读。
sgNoticeFeedbackSupport.feedbackOnFirstView(sgNoticeDO);
SgNoticeCO sgNoticeCO = sgNoticeCoConvertor.converDOToCO(sgNoticeDO); SgNoticeCO sgNoticeCO = sgNoticeCoConvertor.converDOToCO(sgNoticeDO);
if (sgNoticeDO.getNoticeId() == null || sgNoticeDO.getNoticeId().isEmpty()) { if (sgNoticeDO.getNoticeId() == null || sgNoticeDO.getNoticeId().isEmpty()) {
sgNoticeCO.setImgFilesList(Collections.emptyList()); sgNoticeCO.setImgFilesList(Collections.emptyList());

View File

@ -8,65 +8,63 @@ import lombok.Data;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
/** /**
* web-client *
*
* @Author zhaokai
* @Date 2026-06-01 16:20:44
*/ */
@Data @Data
public class SgNoticeCO extends ClientObject { public class SgNoticeCO extends ClientObject {
//主键
@ApiModelProperty(value = "主键") @ApiModelProperty(value = "主键")
private Long id; private Long id;
//业务主键id
@ApiModelProperty(value = "业务主键id") @ApiModelProperty(value = "业务主键id")
private String noticeId; private String noticeId;
//公告标题
@ApiModelProperty(value = "公告标题") @ApiModelProperty(value = "公告标题")
private String noticeTitle; private String noticeTitle;
//公告内容
@ApiModelProperty(value = "公告内容") @ApiModelProperty(value = "公告内容")
private String noticeContent; private String noticeContent;
//乐观锁
@ApiModelProperty(value = "是否阅读01是")
private Integer readingFlag;
@ApiModelProperty(value = "乐观锁") @ApiModelProperty(value = "乐观锁")
private Integer version; private Integer version;
//创建人
@ApiModelProperty(value = "创建人") @ApiModelProperty(value = "创建人")
private Long createId; private Long createId;
//创建人姓名
@ApiModelProperty(value = "创建人名") @ApiModelProperty(value = "创建人")
private String createName; private String createName;
//创建时间
@ApiModelProperty(value = "创建时间") @ApiModelProperty(value = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime; private LocalDateTime createTime;
//更新人
@ApiModelProperty(value = "更新人") @ApiModelProperty(value = "更新人")
private Long updateId; private Long updateId;
//修改人名称
@ApiModelProperty(value = "修改人名称") @ApiModelProperty(value = "修改人名称")
private String updateName; private String updateName;
//更新时间
@ApiModelProperty(value = "更新时间") @ApiModelProperty(value = "更新时间")
private LocalDateTime updateTime; private LocalDateTime updateTime;
//描述
@ApiModelProperty(value = "描述") @ApiModelProperty(value = "描述")
private String remarks; private String remarks;
//是否删除
@ApiModelProperty(value = "是否删除") @ApiModelProperty(value = "是否删除")
private String deleteEnum; private String deleteEnum;
//租户ID
@ApiModelProperty(value = "租户ID") @ApiModelProperty(value = "租户ID")
private Long tenantId; private Long tenantId;
//机构ID
@ApiModelProperty(value = "机构ID") @ApiModelProperty(value = "机构ID")
private Long orgId; private Long orgId;
//环境
@ApiModelProperty(value = "环境") @ApiModelProperty(value = "环境")
private String env; private String env;
@ApiModelProperty(value = "图片列表") @ApiModelProperty(value = "图片列表")
private List<ImgFilesCO> imgFilesList; private List<ImgFilesCO> imgFilesList;
} }

View File

@ -40,6 +40,10 @@ public class SgProperties {
* *
*/ */
private String referenceUrl; private String referenceUrl;
/**
*
*/
private String noticeFeedbackUrl;
/** /**
* *

View File

@ -6,44 +6,28 @@ import lombok.Data;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/** /**
* web-domain *
*
* @Author zhaokai
* @Date 2026-06-01 16:20:44
*/ */
@Data @Data
public class SgNoticeE extends BaseE { public class SgNoticeE extends BaseE {
//主键
private Long id; private Long id;
//业务主键id
private String noticeId; private String noticeId;
//公告标题
private String noticeTitle; private String noticeTitle;
//公告内容
private String noticeContent; private String noticeContent;
//乐观锁 /**
* 01
*/
private Integer readingFlag;
private Integer version; private Integer version;
//创建人
private Long createId; private Long createId;
//创建人姓名
private String createName; private String createName;
//创建时间
private LocalDateTime createTime; private LocalDateTime createTime;
//更新人
private Long updateId; private Long updateId;
//修改人名称
private String updateName; private String updateName;
//更新时间
private LocalDateTime updateTime; private LocalDateTime updateTime;
//描述
private String remarks; private String remarks;
//是否删除
private String deleteEnum; private String deleteEnum;
//租户ID
private Long tenantId; private Long tenantId;
//机构ID
private Long orgId; private Long orgId;
//环境
private String env; private String env;
} }

View File

@ -101,7 +101,7 @@ public class TokenUtils {
// SM4加密准备 // SM4加密准备
SM4 sm4 = SmUtil.sm4(); SM4 sm4 = SmUtil.sm4();
SecretKey secretKey = sm4.getSecretKey(); // 自动生成随机密钥 SecretKey secretKey = sm4.getSecretKey(); // 自动生成随机密钥
System.out.println("发送到第三方接口的参数: " + JSON.toJSONString(data)); log.info("发送到第三方接口的参数: {}", JSON.toJSONString(data));
// 构造并加密请求参数 // 构造并加密请求参数
String encryptedValue = sm4.encryptHex(JSON.toJSONString(data)); // 请求参数加密 String encryptedValue = sm4.encryptHex(JSON.toJSONString(data)); // 请求参数加密

View File

@ -27,6 +27,10 @@ public class SgNoticeDO extends BaseDO {
//公告内容 //公告内容
@ApiModelProperty(value = "公告内容") @ApiModelProperty(value = "公告内容")
private String noticeContent; private String noticeContent;
//是否阅读01
@ApiModelProperty(value = "是否阅读01是")
private Integer readingFlag;
public SgNoticeDO(String noticeId) { public SgNoticeDO(String noticeId) {
this.noticeId = noticeId; this.noticeId = noticeId;

View File

@ -10,6 +10,7 @@
notice_id AS noticeId, notice_id AS noticeId,
notice_title AS noticeTitle, notice_title AS noticeTitle,
notice_content AS noticeContent, notice_content AS noticeContent,
reading_flag AS readingFlag,
version, version,
create_id AS createId, create_id AS createId,
create_name AS createName, create_name AS createName,
@ -33,6 +34,7 @@
notice_id AS noticeId, notice_id AS noticeId,
notice_title AS noticeTitle, notice_title AS noticeTitle,
notice_content AS noticeContent, notice_content AS noticeContent,
reading_flag AS readingFlag,
version, version,
create_id AS createId, create_id AS createId,
create_name AS createName, create_name AS createName,