Merge branch 'dev-8.0-event' into dev-8.0

pull/57/head
fengshuonan 2023-07-14 16:43:38 +08:00
commit 6d615425d5
25 changed files with 763 additions and 15 deletions

View File

@ -6,7 +6,6 @@ import cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum;
import cn.stylefeng.roses.kernel.auth.api.expander.AuthConfigExpander;
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
/**
@ -42,20 +41,6 @@ public class CommonLoginUserUtil {
return authToken;
}
// 3. 从cookie中获取token
String sessionCookieName = AuthConfigExpander.getSessionCookieName();
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
// 如果cookie有对应的值并且不为空
if (sessionCookieName.equals(cookie.getName())
&& StrUtil.isNotBlank(cookie.getValue())) {
return cookie.getValue();
}
}
}
// 获取不到token直接告诉用户
throw new AuthException(AuthExceptionEnum.TOKEN_GET_ERROR);
}

1
kernel-d-event/README.md Normal file
View File

@ -0,0 +1 @@
# 业务事件

View File

@ -0,0 +1 @@
# api模块存放接口、常量、异常、枚举等模块规则相关类

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>kernel-d-event</artifactId>
<version>8.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>event-api</artifactId>
<packaging>jar</packaging>
<dependencies>
<!--config模块的api-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>config-api</artifactId>
<version>${roses.version}</version>
</dependency>
<!--参数校验模块-->
<!--用在控制器,参数校验-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>validator-api</artifactId>
<version>${roses.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,45 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.event.api.annotation;
import java.lang.annotation.*;
/**
*
*
* @author fengshuonan
* @since 2023/7/14 15:12
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface BusinessListener {
/**
*
*/
String businessCode() default "";
}

View File

@ -0,0 +1,45 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.event.api.constants;
/**
*
*
* @author fengshuonan
* @date 2023-07-14 15:05:54
*/
public interface EventConstants {
/**
*
*/
String EVENT_MODULE_NAME = "kernel-s-event";
/**
*
*/
String EVENT_EXCEPTION_STEP_CODE = "99";
}

View File

@ -0,0 +1,33 @@
package cn.stylefeng.roses.kernel.event.api.enums;
import lombok.Getter;
/**
*
*
* @author fengshuonan
* @date 2023-07-14 15:05:54
*/
@Getter
public enum DemoEnum {
/**
* markdown
*/
MARKDOWN(1, "markdown格式"),
/**
*
*/
TEXT(2, "富文本格式");
private final Integer code;
private final String message;
DemoEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.event.api.exception;
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.roses.kernel.event.api.constants.EventConstants;
import cn.stylefeng.roses.kernel.rule.exception.AbstractExceptionEnum;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
/**
*
*
* @author fengshuonan
* @date 2023-07-14 15:05:54
*/
public class EventException extends ServiceException {
public EventException(AbstractExceptionEnum exception, Object... params) {
super(EventConstants.EVENT_MODULE_NAME, exception.getErrorCode(), StrUtil.format(exception.getUserTip(), params));
}
public EventException(AbstractExceptionEnum exception) {
super(EventConstants.EVENT_MODULE_NAME, exception);
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.event.api.exception.enums;
import cn.stylefeng.roses.kernel.event.api.constants.EventConstants;
import cn.stylefeng.roses.kernel.rule.constants.RuleConstants;
import cn.stylefeng.roses.kernel.rule.exception.AbstractExceptionEnum;
import lombok.Getter;
/**
*
*
* @author fengshuonan
* @date 2023-07-14 15:05:54
*/
@Getter
public enum EventExceptionEnum implements AbstractExceptionEnum {
/**
*
*/
CANT_FIND_EVENT(RuleConstants.BUSINESS_ERROR_TYPE_CODE + EventConstants.EVENT_EXCEPTION_STEP_CODE + "01", "查询不到对应业务事件,具体信息:{}");
/**
*
*/
private final String errorCode;
/**
*
*/
private final String userTip;
EventExceptionEnum(String errorCode, String userTip) {
this.errorCode = errorCode;
this.userTip = userTip;
}
}

View File

@ -0,0 +1 @@
# SDK模块存放一些本模块通用的工具处理类等

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>kernel-d-event</artifactId>
<version>8.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>event-sdk</artifactId>
<packaging>jar</packaging>
<dependencies>
<!--业务事件api-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>event-api</artifactId>
<version>${roses.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,128 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.event.sdk;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.roses.kernel.event.api.annotation.BusinessListener;
import cn.stylefeng.roses.kernel.event.sdk.container.EventContainer;
import cn.stylefeng.roses.kernel.event.sdk.pojo.BusinessListenerDetail;
import cn.stylefeng.roses.kernel.rule.util.AopTargetUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* Event
*
* @author fengshuonan
* @since 2023/7/14 15:09
*/
@Slf4j
public class EventAnnotationScanner implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 如果controller是代理对象,则需要获取原始类的信息
Object aopTarget = AopTargetUtils.getTarget(bean);
if (aopTarget == null) {
aopTarget = bean;
}
Class<?> clazz = aopTarget.getClass();
// 判断类中是否有@BusinessListener注解
this.doScan(clazz, beanName);
return bean;
}
/**
* @BusinessListener
*
* @author fengshuonan
* @since 2023/7/14 15:24
*/
private void doScan(Class<?> clazz, String beanName) {
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
BusinessListener businessListener = declaredMethod.getAnnotation(BusinessListener.class);
log.debug("扫描到业务事件监听: " + businessListener);
if (businessListener != null) {
createEventDetail(beanName, declaredMethod, businessListener);
}
}
}
/**
* BusinessListenerDetail
*
* @author fengshuonan
* @since 2023/7/14 15:27
*/
private void createEventDetail(String beanName, Method method, BusinessListener businessListener) {
// 获取注解上的业务编码标识
String businessCode = businessListener.businessCode();
// 从容器中获取本业务标识是否创建
List<BusinessListenerDetail> listener = EventContainer.getListener(businessCode);
if (ObjectUtil.isEmpty(listener)) {
listener = new ArrayList<>();
}
// 创建当前方法的调用信息
BusinessListenerDetail businessListenerDetail = new BusinessListenerDetail();
businessListenerDetail.setBeanName(beanName);
businessListenerDetail.setListenerMethod(method);
// 获取方法参数信息
int parameterCount = method.getParameterCount();
if (parameterCount == 0) {
businessListenerDetail.setParameterClassType(null);
} else {
businessListenerDetail.setParameterClassType(method.getParameterTypes()[0]);
}
listener.add(businessListenerDetail);
// 放到事件容器中
EventContainer.addListenerList(businessCode, listener);
}
}

View File

@ -0,0 +1,44 @@
package cn.stylefeng.roses.kernel.event.sdk.container;
import cn.stylefeng.roses.kernel.event.sdk.pojo.BusinessListenerDetail;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
*
* @author fengshuonan
* @since 2023/7/14 15:08
*/
public class EventContainer {
/**
* keyORG_ADD
* <p>
* value
*/
private static final Map<String, List<BusinessListenerDetail>> CONTEXT = new HashMap<>();
/**
*
*
* @author fengshuonan
* @since 2023/7/14 15:21
*/
public static List<BusinessListenerDetail> getListener(String businessCode) {
return CONTEXT.get(businessCode);
}
/**
*
*
* @author fengshuonan
* @since 2023/7/14 15:22
*/
public static void addListenerList(String businessCode, List<BusinessListenerDetail> businessListenerItemList) {
CONTEXT.put(businessCode, businessListenerItemList);
}
}

View File

@ -0,0 +1,33 @@
package cn.stylefeng.roses.kernel.event.sdk.pojo;
import lombok.Data;
import java.lang.reflect.Method;
/**
*
*
* @author fengshuonan
* @since 2023/7/14 15:18
*/
@Data
public class BusinessListenerDetail {
/**
* SpringBean
*/
private String beanName;
/**
*
*/
private Method listenerMethod;
/**
*
* <p>
* null
*/
private Class<?> parameterClassType;
}

View File

@ -0,0 +1,76 @@
package cn.stylefeng.roses.kernel.event.sdk.publish;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.stylefeng.roses.kernel.event.sdk.container.EventContainer;
import cn.stylefeng.roses.kernel.event.sdk.pojo.BusinessListenerDetail;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
/**
*
*
* @author fengshuonan
* @since 2023/7/14 16:21
*/
public class BusinessEventPublisher {
/**
*
* <p>
* @BusinessListener
*
* @author fengshuonan
* @since 2023/7/14 15:37
*/
public static <T> void publishEvent(String businessCode, T businessObject) {
// 获取该业务是否有监听器
List<BusinessListenerDetail> listener = EventContainer.getListener(businessCode);
// 没有监听器则直接返回
if (ObjectUtil.isEmpty(listener)) {
return;
}
// 依次调用监听器方法,进行回调调用
for (BusinessListenerDetail businessListenerDetail : listener) {
// 监听器的Spring Bean
String beanName = businessListenerDetail.getBeanName();
Object bean = SpringUtil.getBean(beanName);
// 监听器的具体方法
Method listenerMethod = businessListenerDetail.getListenerMethod();
Class<?> parameterClassType = businessListenerDetail.getParameterClassType();
// 如果发布事件的时候参数是空的,则直接调用无参的方法
if (ObjectUtil.isEmpty(businessObject)) {
// 如果方法的参数数量为0则直接调用如果不为0则跳过执行下个
if (parameterClassType == null) {
try {
listenerMethod.invoke(businessObject);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
// 如果发布事件的时候包含参数则判断method的第一个参数是否和businessObject的class一样不一样则不调用
else {
if (parameterClassType != null && parameterClassType.equals(businessObject.getClass())) {
try {
listenerMethod.invoke(bean, businessObject);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
}
}
}

View File

@ -0,0 +1,2 @@
# Spring Boot自动装配

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>kernel-d-event</artifactId>
<version>8.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>event-spring-boot-starter</artifactId>
<packaging>jar</packaging>
<dependencies>
<!--业务事件业务模块-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>event-sdk</artifactId>
<version>${roses.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,51 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.event.starter;
import cn.stylefeng.roses.kernel.event.sdk.EventAnnotationScanner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
*
*
* @author fengshuonan
* @date 2023-07-14 15:05:54
*/
@Configuration
public class EventAutoConfiguration {
/**
*
*
* @author fengshuonan
* @since 2023/7/14 16:00
*/
@Bean
public EventAnnotationScanner eventAnnotationScanner() {
return new EventAnnotationScanner();
}
}

View File

@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.stylefeng.roses.kernel.event.starter.EventAutoConfiguration

35
kernel-d-event/pom.xml Normal file
View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>roses-kernel</artifactId>
<version>8.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>kernel-d-event</artifactId>
<packaging>pom</packaging>
<modules>
<module>event-api</module>
<module>event-sdk</module>
<module>event-spring-boot-starter</module>
</modules>
<dependencies>
<!-- 开发规则 -->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>kernel-a-rule</artifactId>
<version>${roses.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -17,6 +17,13 @@
<dependencies>
<!-- 事件模块 -->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>event-spring-boot-starter</artifactId>
<version>${roses.version}</version>
</dependency>
<!--基础核心业务api-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>

View File

@ -37,4 +37,9 @@ public interface OrgConstants {
*/
String NONE_PARENT_ORG = "无上级机构";
/**
*
*/
String ADD_ORG_EVENT = "ADD_ORG_EVENT";
}

View File

@ -0,0 +1,43 @@
package cn.stylefeng.roses.kernel.sys.modular.org.listener;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi;
import cn.stylefeng.roses.kernel.event.api.annotation.BusinessListener;
import cn.stylefeng.roses.kernel.sys.modular.org.constants.OrgConstants;
import cn.stylefeng.roses.kernel.sys.modular.org.entity.HrOrganization;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
*
*
* @author fengshuonan
* @since 2023/7/14 14:19
*/
@Service
public class OrgOperateListener {
@Resource(name = "sysOrgSubFlagCache")
private CacheOperatorApi<Boolean> sysOrgSubFlagCache;
/**
*
*
* @author fengshuonan
* @since 2023/7/14 16:22
*/
@BusinessListener(businessCode = OrgConstants.ADD_ORG_EVENT)
public void addOrgCallback(HrOrganization businessObject) {
if (ObjectUtil.isNotEmpty(businessObject.getOrgId())) {
sysOrgSubFlagCache.remove(String.valueOf(businessObject.getOrgId()));
}
if (ObjectUtil.isNotEmpty(businessObject.getOrgParentId())) {
sysOrgSubFlagCache.remove(String.valueOf(businessObject.getOrgParentId()));
}
}
}

View File

@ -12,6 +12,7 @@ import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.entity.BaseEntity;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.event.sdk.publish.BusinessEventPublisher;
import cn.stylefeng.roses.kernel.rule.constants.TreeConstants;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.roses.kernel.rule.tree.factory.DefaultTreeBuildFactory;
@ -76,6 +77,9 @@ public class HrOrganizationServiceImpl extends ServiceImpl<HrOrganizationMapper,
OrganizationFactory.fillParentIds(hrOrganization);
this.save(hrOrganization);
// 发布一个新增组织机构的事件
BusinessEventPublisher.publishEvent(OrgConstants.ADD_ORG_EVENT, hrOrganization);
}
@Override

View File

@ -40,6 +40,9 @@
<!--邮件发送模块-->
<module>kernel-d-email</module>
<!--业务事件模块-->
<module>kernel-d-event</module>
<!--文件操作模块-->
<module>kernel-d-file</module>