committed by
							
								 GitHub
								GitHub
							
						
					
				
				 25 changed files with 428 additions and 40 deletions
			
			
		| @ -0,0 +1,14 @@ | |||
| package com.databasir.api.common; | |||
| 
 | |||
| import com.databasir.api.config.security.DatabasirUserDetails; | |||
| import org.springframework.security.core.context.SecurityContextHolder; | |||
| 
 | |||
| public class LoginUserContext { | |||
| 
 | |||
|     public static Integer getLoginUserId() { | |||
|         DatabasirUserDetails principal = (DatabasirUserDetails) SecurityContextHolder.getContext() | |||
|                 .getAuthentication() | |||
|                 .getPrincipal(); | |||
|         return principal.getUserPojo().getId(); | |||
|     } | |||
| } | |||
| @ -1,6 +1,6 @@ | |||
| package com.databasir.core.domain.remark.converter; | |||
| package com.databasir.core.domain.discussion.converter; | |||
| 
 | |||
| import com.databasir.core.domain.remark.data.DiscussionResponse; | |||
| import com.databasir.core.domain.discussion.data.DiscussionResponse; | |||
| import com.databasir.dao.tables.pojos.DocumentDiscussionPojo; | |||
| import com.databasir.dao.tables.pojos.UserPojo; | |||
| import org.mapstruct.Mapper; | |||
| @ -1,4 +1,4 @@ | |||
| package com.databasir.core.domain.remark.data; | |||
| package com.databasir.core.domain.discussion.data; | |||
| 
 | |||
| import lombok.Data; | |||
| 
 | |||
| @ -1,4 +1,4 @@ | |||
| package com.databasir.core.domain.remark.data; | |||
| package com.databasir.core.domain.discussion.data; | |||
| 
 | |||
| import com.databasir.dao.Tables; | |||
| import lombok.Data; | |||
| @ -1,4 +1,4 @@ | |||
| package com.databasir.core.domain.remark.data; | |||
| package com.databasir.core.domain.discussion.data; | |||
| 
 | |||
| import lombok.Data; | |||
| 
 | |||
| @ -0,0 +1,28 @@ | |||
| package com.databasir.core.domain.discussion.event; | |||
| 
 | |||
| import lombok.Data; | |||
| 
 | |||
| import java.time.LocalDateTime; | |||
| import java.util.Optional; | |||
| 
 | |||
| @Data | |||
| public class DiscussionCreated { | |||
| 
 | |||
|     private Integer discussionId; | |||
| 
 | |||
|     private Integer createByUserId; | |||
| 
 | |||
|     private String content; | |||
| 
 | |||
|     private Integer projectId; | |||
| 
 | |||
|     private String tableName; | |||
| 
 | |||
|     private String columnName; | |||
| 
 | |||
|     private LocalDateTime createAt; | |||
| 
 | |||
|     public Optional<String> getColumnName() { | |||
|         return Optional.of(columnName); | |||
|     } | |||
| } | |||
| @ -0,0 +1,14 @@ | |||
| package com.databasir.core.domain.discussion.event.converter; | |||
| 
 | |||
| import com.databasir.core.domain.discussion.event.DiscussionCreated; | |||
| import com.databasir.dao.tables.pojos.DocumentDiscussionPojo; | |||
| import org.mapstruct.Mapper; | |||
| import org.mapstruct.Mapping; | |||
| 
 | |||
| @Mapper(componentModel = "spring") | |||
| public interface DiscussionEventConverter { | |||
| 
 | |||
|     @Mapping(target = "createByUserId", source = "pojo.userId") | |||
|     DiscussionCreated of(DocumentDiscussionPojo pojo, Integer discussionId); | |||
| 
 | |||
| } | |||
| @ -0,0 +1,30 @@ | |||
| package com.databasir.core.domain.document.event; | |||
| 
 | |||
| import com.databasir.core.diff.data.RootDiff; | |||
| import lombok.AllArgsConstructor; | |||
| import lombok.Data; | |||
| import lombok.NoArgsConstructor; | |||
| 
 | |||
| import java.util.Optional; | |||
| 
 | |||
| @Data | |||
| @NoArgsConstructor | |||
| @AllArgsConstructor | |||
| public class DocumentUpdated { | |||
| 
 | |||
|     private RootDiff diff; | |||
| 
 | |||
|     private Long newVersion; | |||
| 
 | |||
|     private Long oldVersion; | |||
| 
 | |||
|     private Integer projectId; | |||
| 
 | |||
|     public Optional<Long> getOldVersion() { | |||
|         return Optional.ofNullable(oldVersion); | |||
|     } | |||
| 
 | |||
|     public Optional<RootDiff> getDiff() { | |||
|         return Optional.ofNullable(diff); | |||
|     } | |||
| } | |||
| @ -0,0 +1,12 @@ | |||
| package com.databasir.core.domain.user.data; | |||
| 
 | |||
| import java.util.Objects; | |||
| 
 | |||
| public interface UserSource { | |||
| 
 | |||
|     String MANUAL = "manual"; | |||
| 
 | |||
|     static boolean isManual(String source) { | |||
|         return Objects.equals(source, MANUAL); | |||
|     } | |||
| } | |||
| @ -0,0 +1,23 @@ | |||
| package com.databasir.core.domain.user.event; | |||
| 
 | |||
| import lombok.Builder; | |||
| import lombok.Getter; | |||
| import lombok.ToString; | |||
| 
 | |||
| @Getter | |||
| @Builder | |||
| @ToString | |||
| public class UserCreated { | |||
| 
 | |||
|     private Integer userId; | |||
| 
 | |||
|     private String nickname; | |||
| 
 | |||
|     private String email; | |||
| 
 | |||
|     private String username; | |||
| 
 | |||
|     private String rawPassword; | |||
| 
 | |||
|     private String source; | |||
| } | |||
| @ -0,0 +1,21 @@ | |||
| package com.databasir.core.domain.user.event; | |||
| 
 | |||
| import lombok.Builder; | |||
| import lombok.Getter; | |||
| 
 | |||
| import java.time.LocalDateTime; | |||
| 
 | |||
| @Getter | |||
| @Builder | |||
| public class UserPasswordRenewed { | |||
| 
 | |||
|     private Integer renewByUserId; | |||
| 
 | |||
|     private String nickname; | |||
| 
 | |||
|     private String email; | |||
| 
 | |||
|     private String newPassword; | |||
| 
 | |||
|     private LocalDateTime renewTime; | |||
| } | |||
| @ -0,0 +1,21 @@ | |||
| package com.databasir.core.domain.user.event.converter; | |||
| 
 | |||
| import com.databasir.core.domain.user.event.UserCreated; | |||
| import com.databasir.core.domain.user.event.UserPasswordRenewed; | |||
| import com.databasir.dao.tables.pojos.UserPojo; | |||
| import org.mapstruct.Mapper; | |||
| import org.mapstruct.Mapping; | |||
| 
 | |||
| import java.time.LocalDateTime; | |||
| 
 | |||
| @Mapper(componentModel = "spring") | |||
| public interface UserEventConverter { | |||
| 
 | |||
|     UserPasswordRenewed userPasswordRenewed(UserPojo pojo, | |||
|                                             Integer renewByUserId, | |||
|                                             LocalDateTime renewTime, | |||
|                                             String newPassword); | |||
| 
 | |||
|     @Mapping(target = "userId", source = "userId") | |||
|     UserCreated userCreated(UserPojo pojo, String source, String rawPassword, Integer userId); | |||
| } | |||
| @ -0,0 +1,16 @@ | |||
| package com.databasir.core.infrastructure.event; | |||
| 
 | |||
| import lombok.RequiredArgsConstructor; | |||
| import org.springframework.context.ApplicationEventPublisher; | |||
| import org.springframework.stereotype.Component; | |||
| 
 | |||
| @Component | |||
| @RequiredArgsConstructor | |||
| public class EventPublisher { | |||
| 
 | |||
|     private final ApplicationEventPublisher applicationEventPublisher; | |||
| 
 | |||
|     public void publish(Object event) { | |||
|         applicationEventPublisher.publishEvent(event); | |||
|     } | |||
| } | |||
| @ -0,0 +1,18 @@ | |||
| package com.databasir.core.infrastructure.event.subscriber; | |||
| 
 | |||
| import com.databasir.core.domain.discussion.event.DiscussionCreated; | |||
| import lombok.RequiredArgsConstructor; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.context.event.EventListener; | |||
| import org.springframework.stereotype.Component; | |||
| 
 | |||
| @Component | |||
| @RequiredArgsConstructor | |||
| @Slf4j | |||
| public class DiscussionEventSubscriber { | |||
| 
 | |||
|     @EventListener(classes = DiscussionCreated.class) | |||
|     public void onDiscussionCreated(DiscussionCreated created) { | |||
|         // TODO notification group member who subscribe this event
 | |||
|     } | |||
| } | |||
| @ -0,0 +1,84 @@ | |||
| package com.databasir.core.infrastructure.event.subscriber; | |||
| 
 | |||
| import com.databasir.core.diff.data.DiffType; | |||
| import com.databasir.core.diff.data.RootDiff; | |||
| import com.databasir.core.domain.document.event.DocumentUpdated; | |||
| import com.databasir.core.infrastructure.mail.MailSender; | |||
| import com.databasir.dao.impl.ProjectDao; | |||
| import com.databasir.dao.impl.SysMailDao; | |||
| import com.databasir.dao.impl.UserDao; | |||
| import com.databasir.dao.impl.UserRoleDao; | |||
| import com.databasir.dao.tables.pojos.ProjectPojo; | |||
| import com.databasir.dao.tables.pojos.UserPojo; | |||
| import lombok.RequiredArgsConstructor; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.context.event.EventListener; | |||
| import org.springframework.stereotype.Component; | |||
| 
 | |||
| import java.util.List; | |||
| import java.util.stream.Collectors; | |||
| 
 | |||
| @Component | |||
| @RequiredArgsConstructor | |||
| @Slf4j | |||
| public class DocumentEventSubscriber { | |||
| 
 | |||
|     private final ProjectDao projectDao; | |||
| 
 | |||
|     private final MailSender mailSender; | |||
| 
 | |||
|     private final UserRoleDao userRoleDao; | |||
| 
 | |||
|     private final UserDao userDao; | |||
| 
 | |||
|     private final SysMailDao sysMailDao; | |||
| 
 | |||
|     @EventListener(classes = DocumentUpdated.class) | |||
|     public void onDocumentUpdated(DocumentUpdated created) { | |||
|         ProjectPojo project = projectDao.selectById(created.getProjectId()); | |||
|         List<String> to = userDao.selectEnabledGroupMembers(project.getGroupId()) | |||
|                 .stream() | |||
|                 .map(UserPojo::getEmail) | |||
|                 .filter(mail -> mail.contains("@")) | |||
|                 .collect(Collectors.toList()); | |||
|         sysMailDao.selectOptionTopOne().ifPresent(mail -> { | |||
|             String subject = project.getName() + " 文档有新的版本"; | |||
|             String message = created.getDiff() | |||
|                     .map(diff -> build(diff)) | |||
|                     .orElseGet(() -> "首次文档同步常规"); | |||
|             mailSender.batchSend(mail, to, subject, message); | |||
|         }); | |||
|     } | |||
| 
 | |||
|     private String build(RootDiff diff) { | |||
|         if (diff.getDiffType() == DiffType.NONE) { | |||
|             return ""; | |||
|         } else { | |||
|             return diff.getFields() | |||
|                     .stream() | |||
|                     .filter(field -> field.getFieldName().equals("tables")) | |||
|                     .flatMap(f -> f.getFields().stream()) | |||
|                     .map(table -> { | |||
|                         String tableName = table.getFieldName(); | |||
|                         String change = toDescription(table.getDiffType()); | |||
|                         return tableName + " " + change; | |||
|                     }) | |||
|                     .collect(Collectors.joining("\n")); | |||
|         } | |||
|     } | |||
| 
 | |||
|     private String toDescription(DiffType diffType) { | |||
|         switch (diffType) { | |||
|             case NONE: | |||
|                 return "无变化"; | |||
|             case ADDED: | |||
|                 return "新增"; | |||
|             case REMOVED: | |||
|                 return "删除"; | |||
|             case MODIFIED: | |||
|                 return "修改"; | |||
|             default: | |||
|                 return diffType.name(); | |||
|         } | |||
|     } | |||
| } | |||
| @ -0,0 +1,61 @@ | |||
| package com.databasir.core.infrastructure.event.subscriber; | |||
| 
 | |||
| import com.databasir.core.domain.user.data.UserSource; | |||
| import com.databasir.core.domain.user.event.UserCreated; | |||
| import com.databasir.core.domain.user.event.UserPasswordRenewed; | |||
| import com.databasir.core.infrastructure.mail.MailSender; | |||
| import com.databasir.dao.impl.SysMailDao; | |||
| import com.databasir.dao.impl.UserDao; | |||
| import com.databasir.dao.tables.pojos.UserPojo; | |||
| import lombok.RequiredArgsConstructor; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.context.event.EventListener; | |||
| import org.springframework.stereotype.Component; | |||
| 
 | |||
| /** | |||
|  * TODO use html template instead of simple message | |||
|  */ | |||
| @Component | |||
| @RequiredArgsConstructor | |||
| @Slf4j | |||
| public class UserEventSubscriber { | |||
| 
 | |||
|     private final MailSender mailSender; | |||
| 
 | |||
|     private final SysMailDao sysMailDao; | |||
| 
 | |||
|     private final UserDao userDao; | |||
| 
 | |||
|     @EventListener(classes = UserPasswordRenewed.class) | |||
|     public void onPasswordRenewed(UserPasswordRenewed event) { | |||
|         UserPojo operator = userDao.selectById(event.getRenewByUserId()); | |||
|         sysMailDao.selectOptionTopOne() | |||
|                 .ifPresent(mailPojo -> { | |||
|                     String renewBy = operator.getNickname(); | |||
|                     String subject = "Databasir 密码重置提醒"; | |||
|                     String message = String.format("Hi %s,\r\n 您的密码已被 %s 重置,新密码为 %s", | |||
|                             event.getNickname(), | |||
|                             renewBy, | |||
|                             event.getNewPassword()); | |||
|                     mailSender.send(mailPojo, event.getEmail(), subject, message); | |||
|                 }); | |||
|     } | |||
| 
 | |||
|     @EventListener(classes = UserCreated.class) | |||
|     public void onUserCreated(UserCreated event) { | |||
|         String subject = "Databasir 账户创建成功"; | |||
|         String message; | |||
|         if (UserSource.isManual(event.getSource())) { | |||
|             message = String.format("Hi %s\r\n您的 Databasir 账户已创建成功,用户名:%s,密码:%s", | |||
|                     event.getNickname(), event.getUsername(), event.getRawPassword()); | |||
|         } else { | |||
|             message = String.format("Hi %s\r\n您的 Databasir 账户已创建成功,用户名:%s", | |||
|                     event.getNickname(), event.getUsername()); | |||
|         } | |||
|         sysMailDao.selectOptionTopOne() | |||
|                 .ifPresent(mailPojo -> { | |||
|                     mailSender.send(mailPojo, event.getEmail(), subject, message); | |||
|                 }); | |||
|     } | |||
| 
 | |||
| } | |||
					Loading…
					
					
				
		Reference in new issue