通知站内信

This commit is contained in:
ran.shang
2025-06-26 17:36:59 +08:00
parent 8a77c9179b
commit 881f196ef1
8 changed files with 507 additions and 79 deletions

View File

@@ -1,58 +0,0 @@
CREATE TABLE "xs_chat"
(
"id" BIGINT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
"org_id" BIGINT,
"org_user_id" BIGINT,
"person_user_id" BIGINT,
"type" VARCHAR(32),
"status" TINYINT,
"deleted" BIT DEFAULT 0 NOT NULL,
"create_by" BIGINT NOT NULL,
"create_time" TIMESTAMP(0) NOT NULL,
"update_by" BIGINT,
"update_time" TIMESTAMP(0),
"proxy_by" BIGINT
) ;
COMMENT ON TABLE "xs_chat" IS '聊天表';
COMMENT ON COLUMN "xs_chat"."org_id" IS '机构id';
COMMENT ON COLUMN "xs_chat"."org_user_id" IS '机构用户id';
COMMENT ON COLUMN "xs_chat"."person_user_id" IS '个人用户id';
COMMENT ON COLUMN "xs_chat"."type" IS '类型(chat_type)';
COMMENT ON COLUMN "xs_chat"."status" IS '状态:1有效,2关闭';
COMMENT ON COLUMN "xs_chat"."create_by" IS '创建人';
COMMENT ON COLUMN "xs_chat"."create_time" IS '创建时间';
COMMENT ON COLUMN "xs_chat"."deleted" IS '是否逻辑删除';
COMMENT ON COLUMN "xs_chat"."proxy_by" IS '代理人';
COMMENT ON COLUMN "xs_chat"."update_by" IS '更新人';
COMMENT ON COLUMN "xs_chat"."update_time" IS '更新时间';
CREATE TABLE "xs_chat_msg"
(
"id" BIGINT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
"chat_id" BIGINT,
"sender_id" BIGINT,
"msg_type" VARCHAR(16),
"content" VARCHAR(1024),
"msg_status" TINYINT,
"deleted" BIT DEFAULT 0 NOT NULL,
"create_by" BIGINT NOT NULL,
"create_time" TIMESTAMP(0) NOT NULL,
"update_by" BIGINT,
"update_time" TIMESTAMP(0),
"proxy_by" BIGINT
) ;
COMMENT ON TABLE "xs_chat_msg" IS '聊天消息表';
COMMENT ON COLUMN "xs_chat_msg"."chat_id" IS '聊天id';
COMMENT ON COLUMN "xs_chat_msg"."sender_id" IS '发送用户id';
COMMENT ON COLUMN "xs_chat_msg"."msg_type" IS '消息类型(chat_msg_type):text等';
COMMENT ON COLUMN "xs_chat_msg"."content" IS '个人用户id';
COMMENT ON COLUMN "xs_chat_msg"."msg_status" IS '消息状态:1未读,2已读';
COMMENT ON COLUMN "xs_chat_msg"."create_by" IS '创建人';
COMMENT ON COLUMN "xs_chat_msg"."create_time" IS '创建时间';
COMMENT ON COLUMN "xs_chat_msg"."deleted" IS '是否逻辑删除';
COMMENT ON COLUMN "xs_chat_msg"."proxy_by" IS '代理人';
COMMENT ON COLUMN "xs_chat_msg"."update_by" IS '更新人';
COMMENT ON COLUMN "xs_chat_msg"."update_time" IS '更新时间';

408
db/聊天通知功能.sql Normal file
View File

@@ -0,0 +1,408 @@
CREATE TABLE "xs_chat"
(
"id" BIGINT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
"org_id" BIGINT,
"org_user_id" BIGINT,
"person_user_id" BIGINT,
"type" VARCHAR(32),
"status" TINYINT,
"deleted" BIT DEFAULT 0 NOT NULL,
"create_by" BIGINT NOT NULL,
"create_time" TIMESTAMP(0) NOT NULL,
"update_by" BIGINT,
"update_time" TIMESTAMP(0),
"proxy_by" BIGINT
) ;
COMMENT ON TABLE "xs_chat" IS '聊天表';
COMMENT ON COLUMN "xs_chat"."org_id" IS '机构id';
COMMENT ON COLUMN "xs_chat"."org_user_id" IS '机构用户id';
COMMENT ON COLUMN "xs_chat"."person_user_id" IS '个人用户id';
COMMENT ON COLUMN "xs_chat"."type" IS '类型(chat_type)';
COMMENT ON COLUMN "xs_chat"."status" IS '状态:1有效,2关闭';
COMMENT ON COLUMN "xs_chat"."create_by" IS '创建人';
COMMENT ON COLUMN "xs_chat"."create_time" IS '创建时间';
COMMENT ON COLUMN "xs_chat"."deleted" IS '是否逻辑删除';
COMMENT ON COLUMN "xs_chat"."proxy_by" IS '代理人';
COMMENT ON COLUMN "xs_chat"."update_by" IS '更新人';
COMMENT ON COLUMN "xs_chat"."update_time" IS '更新时间';
CREATE TABLE "xs_chat_msg"
(
"id" BIGINT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
"chat_id" BIGINT,
"sender_id" BIGINT,
"msg_type" VARCHAR(16),
"content" VARCHAR(1024),
"msg_status" TINYINT,
"deleted" BIT DEFAULT 0 NOT NULL,
"create_by" BIGINT NOT NULL,
"create_time" TIMESTAMP(0) NOT NULL,
"update_by" BIGINT,
"update_time" TIMESTAMP(0),
"proxy_by" BIGINT
) ;
COMMENT ON TABLE "xs_chat_msg" IS '聊天消息表';
COMMENT ON COLUMN "xs_chat_msg"."chat_id" IS '聊天id';
COMMENT ON COLUMN "xs_chat_msg"."sender_id" IS '发送用户id';
COMMENT ON COLUMN "xs_chat_msg"."msg_type" IS '消息类型(chat_msg_type):text等';
COMMENT ON COLUMN "xs_chat_msg"."content" IS '个人用户id';
COMMENT ON COLUMN "xs_chat_msg"."msg_status" IS '消息状态:1未读,2已读';
COMMENT ON COLUMN "xs_chat_msg"."create_by" IS '创建人';
COMMENT ON COLUMN "xs_chat_msg"."create_time" IS '创建时间';
COMMENT ON COLUMN "xs_chat_msg"."deleted" IS '是否逻辑删除';
COMMENT ON COLUMN "xs_chat_msg"."proxy_by" IS '代理人';
COMMENT ON COLUMN "xs_chat_msg"."update_by" IS '更新人';
COMMENT ON COLUMN "xs_chat_msg"."update_time" IS '更新时间';
CREATE TABLE "notice_content_template"
(
"id" BIGINT AUTO_INCREMENT NOT NULL,
"template_id" BIGINT,
"channel_type" TINYINT,
"title" VARCHAR(64),
"content_template" TEXT,
"enabled" BIT DEFAULT 1,
"link" VARCHAR(128),
"deleted" BIT DEFAULT 0,
"create_by" BIGINT,
"create_time" TIMESTAMP(0),
"update_by" BIGINT,
"update_time" TIMESTAMP(0),
"proxy_by" BIGINT,
NOT CLUSTER PRIMARY KEY("id")) STORAGE(ON "MAIN", CLUSTERBTR);
COMMENT ON TABLE "notice_content_template" IS '通知消息体模版';
COMMENT ON COLUMN "notice_content_template"."channel_type" IS '消息通道类型:1站内信,2短信,3钉钉,4企业微信,5邮件(见notice_channel_type)';
COMMENT ON COLUMN "notice_content_template"."content_template" IS '内容模版';
COMMENT ON COLUMN "notice_content_template"."create_by" IS '创建人';
COMMENT ON COLUMN "notice_content_template"."create_time" IS '创建时间';
COMMENT ON COLUMN "notice_content_template"."deleted" IS '是否逻辑删除';
COMMENT ON COLUMN "notice_content_template"."enabled" IS '是否启用';
COMMENT ON COLUMN "notice_content_template"."id" IS '主键';
COMMENT ON COLUMN "notice_content_template"."proxy_by" IS '代理人';
COMMENT ON COLUMN "notice_content_template"."template_id" IS '通知模版id';
COMMENT ON COLUMN "notice_content_template"."title" IS '标题';
COMMENT ON COLUMN "notice_content_template"."update_by" IS '更新人';
COMMENT ON COLUMN "notice_content_template"."update_time" IS '更新时间';
CREATE TABLE "notice_receiver_setting"
(
"id" BIGINT AUTO_INCREMENT NOT NULL,
"template_id" BIGINT,
"org_id" BIGINT,
"receiver_union_type" TINYINT,
"receiver_union_id" BIGINT,
"deleted" BIT DEFAULT 0,
"create_by" BIGINT,
"create_time" TIMESTAMP(0),
"update_by" BIGINT,
"update_time" TIMESTAMP(0),
"proxy_by" BIGINT,
NOT CLUSTER PRIMARY KEY("id")) STORAGE(ON "MAIN", CLUSTERBTR) ;
COMMENT ON TABLE "notice_receiver_setting" IS '通知接收人设置';
COMMENT ON COLUMN "notice_receiver_setting"."create_by" IS '创建人';
COMMENT ON COLUMN "notice_receiver_setting"."create_time" IS '创建时间';
COMMENT ON COLUMN "notice_receiver_setting"."deleted" IS '是否逻辑删除';
COMMENT ON COLUMN "notice_receiver_setting"."id" IS '主键';
COMMENT ON COLUMN "notice_receiver_setting"."org_id" IS '机构id';
COMMENT ON COLUMN "notice_receiver_setting"."proxy_by" IS '代理人';
COMMENT ON COLUMN "notice_receiver_setting"."receiver_union_id" IS '接收人关联id:用户id,角色id,标准角色id';
COMMENT ON COLUMN "notice_receiver_setting"."receiver_union_type" IS '接收人关联类型:1用户id,2角色,3标准角色(见notice_receiver_type)';
COMMENT ON COLUMN "notice_receiver_setting"."template_id" IS '通知模版id';
COMMENT ON COLUMN "notice_receiver_setting"."update_by" IS '更新人';
COMMENT ON COLUMN "notice_receiver_setting"."update_time" IS '更新时间';
CREATE TABLE "notice_send_record"
(
"id" BIGINT AUTO_INCREMENT NOT NULL,
"template_id" BIGINT,
"sender_org_id" BIGINT,
"receiver_org_id" BIGINT,
"content_template_id" BIGINT,
"content_param_data" VARCHAR(512),
"content" TEXT,
"appointed" BIT,
"link" VARCHAR(128),
"content_template" TEXT,
"title" VARCHAR(64),
"channel_type" TINYINT,
"status" TINYINT,
"deleted" BIT DEFAULT 0,
"create_by" BIGINT,
"create_time" TIMESTAMP(0),
"update_by" BIGINT,
"update_time" TIMESTAMP(0),
"proxy_by" BIGINT,
NOT CLUSTER PRIMARY KEY("id")) STORAGE(ON "MAIN", CLUSTERBTR) ;
COMMENT ON TABLE "notice_send_record" IS '通知发送记录(内容模版级)';
COMMENT ON COLUMN "notice_send_record"."appointed" IS '是否指定接收方(非预先设定)';
COMMENT ON COLUMN "notice_send_record"."channel_type" IS '消息通道类型:1站内信,2短信,3钉钉,4企业微信,5邮件(见notice_channel_type)';
COMMENT ON COLUMN "notice_send_record"."content" IS '消息体';
COMMENT ON COLUMN "notice_send_record"."content_param_data" IS '消息体参数';
COMMENT ON COLUMN "notice_send_record"."content_template" IS '内容模版';
COMMENT ON COLUMN "notice_send_record"."content_template_id" IS '消息体模版id';
COMMENT ON COLUMN "notice_send_record"."create_by" IS '创建人';
COMMENT ON COLUMN "notice_send_record"."create_time" IS '创建时间';
COMMENT ON COLUMN "notice_send_record"."deleted" IS '是否逻辑删除';
COMMENT ON COLUMN "notice_send_record"."id" IS '主键';
COMMENT ON COLUMN "notice_send_record"."proxy_by" IS '代理人';
COMMENT ON COLUMN "notice_send_record"."receiver_org_id" IS '接收方机构id';
COMMENT ON COLUMN "notice_send_record"."sender_org_id" IS '发送方机构id';
COMMENT ON COLUMN "notice_send_record"."status" IS '状态:1待处理,2已处理 等(见notice_send_status)';
COMMENT ON COLUMN "notice_send_record"."template_id" IS '通知模版id';
COMMENT ON COLUMN "notice_send_record"."title" IS '标题';
COMMENT ON COLUMN "notice_send_record"."update_by" IS '更新人';
COMMENT ON COLUMN "notice_send_record"."update_time" IS '更新时间';
CREATE TABLE "notice_send_record_detail"
(
"id" BIGINT AUTO_INCREMENT NOT NULL,
"record_id" BIGINT,
"user_id" BIGINT,
"receiver_account_no" VARCHAR(32),
"receiver_status" TINYINT,
"deleted" BIT DEFAULT 0,
"create_by" BIGINT,
"create_time" TIMESTAMP(0),
"update_by" BIGINT,
"update_time" TIMESTAMP(0),
"proxy_by" BIGINT,
NOT CLUSTER PRIMARY KEY("id")) STORAGE(ON "MAIN", CLUSTERBTR) ;
COMMENT ON TABLE "notice_send_record_detail" IS '通知发送记录明细(接收人)';
COMMENT ON COLUMN "notice_send_record_detail"."create_by" IS '创建人';
COMMENT ON COLUMN "notice_send_record_detail"."create_time" IS '创建时间';
COMMENT ON COLUMN "notice_send_record_detail"."deleted" IS '是否逻辑删除';
COMMENT ON COLUMN "notice_send_record_detail"."id" IS '主键';
COMMENT ON COLUMN "notice_send_record_detail"."proxy_by" IS '代理人';
COMMENT ON COLUMN "notice_send_record_detail"."receiver_account_no" IS '接收方帐号';
COMMENT ON COLUMN "notice_send_record_detail"."receiver_status" IS '接收状态:1待发送,2已发送,3发送失败,4接收已读(见notice_receiver_status)';
COMMENT ON COLUMN "notice_send_record_detail"."record_id" IS '发送记录id';
COMMENT ON COLUMN "notice_send_record_detail"."update_by" IS '更新人';
COMMENT ON COLUMN "notice_send_record_detail"."update_time" IS '更新时间';
COMMENT ON COLUMN "notice_send_record_detail"."user_id" IS '接收人id';
CREATE TABLE "notice_template"
(
"id" BIGINT AUTO_INCREMENT NOT NULL,
"template_code" VARCHAR(32),
"template_name" VARCHAR(64),
"module_type" TINYINT,
"biz_type" TINYINT,
"level" TINYINT,
"enabled" BIT DEFAULT 1,
"deleted" BIT DEFAULT 0,
"create_by" BIGINT,
"create_time" TIMESTAMP(0),
"update_by" BIGINT,
"update_time" TIMESTAMP(0),
"proxy_by" BIGINT,
NOT CLUSTER PRIMARY KEY("id")) STORAGE(ON "MAIN", CLUSTERBTR) ;
COMMENT ON TABLE "notice_template" IS '通知模版';
COMMENT ON COLUMN "notice_template"."biz_type" IS '业务分类:';
COMMENT ON COLUMN "notice_template"."create_by" IS '创建人';
COMMENT ON COLUMN "notice_template"."create_time" IS '创建时间';
COMMENT ON COLUMN "notice_template"."deleted" IS '是否逻辑删除';
COMMENT ON COLUMN "notice_template"."enabled" IS '是否启用';
COMMENT ON COLUMN "notice_template"."id" IS '主键';
COMMENT ON COLUMN "notice_template"."level" IS '级别:1平台,2机构(见notice_level)';
COMMENT ON COLUMN "notice_template"."module_type" IS '模块分类:1业务,2监控/预警(见notice_module_type)';
COMMENT ON COLUMN "notice_template"."proxy_by" IS '代理人';
COMMENT ON COLUMN "notice_template"."template_code" IS '通知模版code';
COMMENT ON COLUMN "notice_template"."template_name" IS '通知模版名称';
COMMENT ON COLUMN "notice_template"."update_by" IS '更新人';
COMMENT ON COLUMN "notice_template"."update_time" IS '更新时间';

View File

@@ -7,6 +7,7 @@ import com.newyetai.recruit.position.entity.PositionRegistration;
import com.newyetai.recruit.position.dto.PositionRegistrationDTO;
import com.newyetai.recruit.position.dto.PositionRegistrationPageQueryDTO;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -27,4 +28,7 @@ public interface PositionRegistrationMapper extends MyMapper<PositionRegistratio
List<UserPositionRegistrationResDTO> userPage(@Param("param") UserPositionRegistrationPageQueryDTO queryDTO);
Map<String, Object> noticeInvite(Long positionRegistrationId, Long orgUserId);
Map<String, Object> noticeInterview(Long positionRegistrationId, Long orgUserId);
}

View File

@@ -244,4 +244,46 @@
</if>
ORDER BY t.id DESC
</sql>
<select id="noticeInvite" resultType="map">
select p.position_name positionName,
pr.create_time createTime,
pr.interview_time interviewTime,
pr.interview_location interviewLocation,
ou.phone interviewPhone,
o.org_name orgName,
u.real_name realName
from hr_position_registration pr
inner join hr_position p on pr.position_id = p.id and p.deleted = 0
inner join xs_org o on p.org_id = o.id and o.deleted = 0
inner join uc_user u on pr.user_id = u.id and u.deleted = 0
inner join uc_user ou on ou.id = #{orgUserId}
where pr.id = #{positionRegistrationId}
and pr.deleted = 0
</select>
<select id="noticeInterview" resultType="map">
select p.position_name positionName,
pr.create_time createTime,
pr.interview_time interviewTime,
pr.interview_location interviewLocation,
pr.induction_time inductionTime,
pr.remark,
ou.phone interviewPhone,
pa.detail_address positionAddress,
o.org_name orgName,
u.real_name realName
from hr_position_registration pr
inner join hr_position p on pr.position_id = p.id and p.deleted = 0
inner join xs_org o on p.org_id = o.id and o.deleted = 0
inner join uc_user u on pr.user_id = u.id and u.deleted = 0
inner join uc_user ou on ou.id = #{orgUserId}
left join hr_position_address pa on p.address_id = pa.id and pa.deleted = 0
where pr.id = #{positionRegistrationId}
and pr.deleted = 0
</select>
</mapper>

View File

@@ -4,6 +4,10 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import cn.hutool.core.date.DateUtil;
import com.newyetai.usercenter.notice.constant.NoticeChannelTypeEnum;
import com.newyetai.usercenter.notice.constant.NoticeTemplateCodeEnum;
import com.newyetai.usercenter.notice.dto.NoticeSendRecordOperateDTO;
import com.newyetai.usercenter.notice.service.NoticeSendRecordService;
import lombok.extern.slf4j.Slf4j;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -97,6 +101,8 @@ public class PositionRegistrationServiceImpl implements PositionRegistrationServ
@Autowired
private OrgService orgService;
@Autowired
private NoticeSendRecordService noticeSendRecordService;
@AutoUnLock
@@ -325,8 +331,11 @@ public class PositionRegistrationServiceImpl implements PositionRegistrationServ
ActionUtils.diff(operatorDTO.getId(), PositionRegistration.builder().status(PositionRegistrationStatusEnum.ALREADY_REGISTERED.getStatus()).build()
, PositionRegistration.builder().status(PositionRegistrationStatusEnum.WAIT_FOR_AN_INTERVIEW.getStatus()).build());
// 发送通知
sendNotice(NoticeTemplateCodeEnum.POSITION_INVITE, positionRegistrationMapper.noticeInvite(operatorDTO.getId(), UserContextHolder.getLoginUserId()));
}
@Override
public void termination(PositionRegistrationOperatorDTO operatorDTO) {
Assert.notNull(operatorDTO.getId(), "id不能为空");
@@ -376,7 +385,27 @@ public class PositionRegistrationServiceImpl implements PositionRegistrationServ
ActionUtils.diff(operatorDTO.getId(), PositionRegistration.builder().status(PositionRegistrationStatusEnum.WAIT_FOR_AN_INTERVIEW.getStatus()).build()
, PositionRegistration.builder().status(operatorDTO.getStatus()).build());
// 发送通知
if (PositionRegistrationStatusEnum.FAIL_THE_INTERVIEW.getStatus().equals(operatorDTO.getStatus())){
sendNotice(NoticeTemplateCodeEnum.POSITION_INTERVIEW_FAIL, positionRegistrationMapper.noticeInterview(operatorDTO.getId(), UserContextHolder.getLoginUserId()));
} else {
sendNotice(NoticeTemplateCodeEnum.POSITION_INTERVIEW_PASS, positionRegistrationMapper.noticeInterview(operatorDTO.getId(), UserContextHolder.getLoginUserId()));
}
}
//发送站内信
private void sendNotice(NoticeTemplateCodeEnum templateCodeEnum, Map<String, Object> contentParamDataMap) {
String templateCode = templateCodeEnum.getType();
try {
NoticeSendRecordOperateDTO sendRecordOperateDTO = NoticeSendRecordOperateDTO.builder()
.templateCode(templateCode)
.channelType(NoticeChannelTypeEnum.SITE.getType())
.contentParamDataMap(contentParamDataMap)
.build();
noticeSendRecordService.create(sendRecordOperateDTO);
} catch (Exception e) {
log.info("发送[{}]站内信失败:{}", templateCode, e.getMessage());
}
}
@Transactional(rollbackFor = Exception.class)

View File

@@ -1,21 +0,0 @@
package com.newyetai.usercenter.notice.constant;
public enum NoticeBizTypeEnum {
/** 岗位报名-邀请面试 */
POSITION_INVITE("position_invite"),
/** 岗位报名-面试结果 */
POSITION_INVITE_result("position_invite_result"),
;
private String type;
NoticeBizTypeEnum(String type) {
this.type = type;
}
public String getType() {
return type;
}
}

View File

@@ -0,0 +1,23 @@
package com.newyetai.usercenter.notice.constant;
public enum NoticeTemplateCodeEnum {
/** 岗位报名-邀请面试 */
POSITION_INVITE("position_invite"),
/** 岗位报名-面试通过 */
POSITION_INTERVIEW_PASS("position_interview_pass"),
/** 岗位报名-面试不通过 */
POSITION_INTERVIEW_FAIL("position_interview_fail"),
;
private String type;
NoticeTemplateCodeEnum(String type) {
this.type = type;
}
public String getType() {
return type;
}
}

View File

@@ -90,6 +90,7 @@ public class NoticeSendRecordServiceImpl implements NoticeSendRecordService {
noticeTemplateMapper.listNoticeTemplateDTO(noticeTemplateQueryDTO);
Assert.isTrue(!noticeTemplateDTOs.isEmpty(), "未找到对应通知模版");
NoticeTemplateDTO noticeTemplateDTO = noticeTemplateDTOs.get(0);
Assert.isTrue(noticeTemplateDTO.getEnabled(), "通知模版未开启");
tempOperateDto.setTemplateId(noticeTemplateDTO.getId());
// 平台模版指定接收人机构为平台
Long receiverOrgId =