diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/RedisConfig.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/RedisConfig.java
index 7363c8a4..8226a52d 100644
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/RedisConfig.java
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/RedisConfig.java
@@ -8,6 +8,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
@@ -40,4 +41,17 @@ public class RedisConfig extends CachingConfigurerSupport
template.afterPropertiesSet();
return template;
}
+
+ @Bean
+ /**
+ * 获取监听容器
+ * @param connectionFactory
+ * @return
+ */
+ public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) {
+ RedisMessageListenerContainer container = new RedisMessageListenerContainer();
+ container.setConnectionFactory(connectionFactory);
+ return container;
+
+ }
}
diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/GenUtils.java b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/GenUtils.java
index 2c1c5317..b22d6aec 100644
--- a/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/GenUtils.java
+++ b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/GenUtils.java
@@ -40,6 +40,10 @@ public class GenUtils
column.setCreateBy(table.getCreateBy());
// 设置java字段名
column.setJavaField(StringUtils.toCamelCase(columnName));
+ // 如果字段全部是大写,说明字段配置成大写。要改成小写。例如:TITLE -> title
+ if(StringUtils.isAllUpperCase(column.getJavaField())) {
+ column.setJavaField(column.getJavaField().toLowerCase());
+ }
// 设置默认类型
column.setJavaType(GenConstants.TYPE_STRING);
column.setQueryType(GenConstants.QUERY_EQ);
diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domain.java.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domain.java.vm
index 3e6be024..5387f784 100644
--- a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domain.java.vm
+++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domain.java.vm
@@ -40,8 +40,8 @@ public class ${ClassName} extends ${Entity}
#if($parentheseIndex != -1)
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
#elseif($column.javaType == 'Date')
- @JsonFormat(pattern = "yyyy-MM-dd")
- @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
#else
@Excel(name = "${comment}")
#end
@@ -62,11 +62,18 @@ public class ${ClassName} extends ${Entity}
#else
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
#end
+ /**
+ * 设置 ${AttrName}
+ * @param $column.columnComment
+ */
public void set${AttrName}($column.javaType $column.javaField)
{
this.$column.javaField = $column.javaField;
}
-
+ /**
+ * 获取 $column.columnComment
+ * @return
+ */
public $column.javaType get${AttrName}()
{
return $column.javaField;
diff --git a/ruoyi-modules/ruoyi-system/pom.xml b/ruoyi-modules/ruoyi-system/pom.xml
index 46baaddb..13c64721 100644
--- a/ruoyi-modules/ruoyi-system/pom.xml
+++ b/ruoyi-modules/ruoyi-system/pom.xml
@@ -77,6 +77,35 @@
com.ruoyi
ruoyi-common-swagger
+
+
+ org.nutz
+ nutz
+ 1.r.69.20210929
+
+
+
+ org.springframework.boot
+ spring-boot-starter-cache
+
+
+ net.sf.ehcache
+ ehcache
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+ com.vaadin.external.google
+ android-json
+
+
+ test
+
+
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/annotation/OrgCacheKey.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/annotation/OrgCacheKey.java
new file mode 100644
index 00000000..0524ee07
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/annotation/OrgCacheKey.java
@@ -0,0 +1,25 @@
+package com.ruoyi.cache.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 缓存的关键字ID
+ * @author Administrator
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+@Documented
+public @interface OrgCacheKey {
+ String id() default "user";
+ /**
+ * 缓存的类型:目前可以是CacheStaffInfo,CacheDeptInfo,CacheCompanyInfo
+ * @return
+ */
+ OrgCacheTypeNum type() default OrgCacheTypeNum.CacheUserInfo;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/annotation/OrgCacheTypeNum.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/annotation/OrgCacheTypeNum.java
new file mode 100644
index 00000000..aa88eb28
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/annotation/OrgCacheTypeNum.java
@@ -0,0 +1,11 @@
+package com.ruoyi.cache.annotation;
+/**
+ * 缓存的类型
+ * @author Administrator
+ *
+ */
+public enum OrgCacheTypeNum {
+ CacheUserInfo, //员工的cache
+ CacheDeptInfo,//部门的cache
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/annotation/OrgCacheValue.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/annotation/OrgCacheValue.java
new file mode 100644
index 00000000..2ad432ca
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/annotation/OrgCacheValue.java
@@ -0,0 +1,25 @@
+/**
+ *
+ */
+package com.ruoyi.cache.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 获取组织架构的缓存,声明一个pojo的属性映射值
+ * @author Condy
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+@Documented
+public @interface OrgCacheValue {
+ //CacheValueNum value() default CacheStaffInfoNum.staffId;
+ String value() default "";
+ String id() default "user";
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/domain/BaseCache.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/domain/BaseCache.java
new file mode 100644
index 00000000..1db3d618
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/domain/BaseCache.java
@@ -0,0 +1,34 @@
+package com.ruoyi.cache.domain;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.nutz.dao.entity.annotation.Column;
+import org.nutz.lang.Mirror;
+
+public class BaseCache {
+
+ /**
+ * POJO转换成Map
+ * @return
+ */
+ public Map toMap(){
+ Mirror> mirror = Mirror.me(getClass());
+ Field[] flds = mirror.getFields();
+ Map pojoMap=new HashMap();
+ for (Field fld : flds) {
+ Object v = mirror.getValue(this, fld);
+ if (null == v) {//等与null就不生成map
+ continue;
+ } else if(fld.isAnnotationPresent(Column.class)){
+ String cv = fld.getAnnotation(Column.class).value();
+ pojoMap.put(cv, v.toString());
+ } else{
+ pojoMap.put(fld.getName(), v.toString());
+ }
+ }
+ return pojoMap;
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/domain/CacheSysDept.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/domain/CacheSysDept.java
new file mode 100644
index 00000000..3edf8849
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/domain/CacheSysDept.java
@@ -0,0 +1,70 @@
+package com.ruoyi.cache.domain;
+
+import com.ruoyi.system.api.domain.SysDept;
+
+public class CacheSysDept extends BaseCache{
+ /**
+ * @OrgCacheValue的 value类型
+ */
+ public final static String ANNOTAION_DEPT_ID="deptId";
+ public final static String ANNOTAION_PARENT_ID="parentId";
+ public final static String ANNOTAION_DEPT_NAME="deptName";
+ public final static String ANNOTAION_PARENT_NAME="parentName";
+
+ /** 部门ID */
+ private Long deptId;
+
+ /** 父部门ID */
+ private Long parentId;
+
+ /** 部门名称 */
+ private String deptName;
+
+ /** 父部门名称 */
+ private String parentName;
+
+ public CacheSysDept(SysDept dept) {
+ this.deptId=dept.getDeptId();
+ this.parentId=dept.getParentId();
+ this.deptName=dept.getDeptName();
+ this.parentName=dept.getParentName();
+ }
+
+ public CacheSysDept() {
+
+ }
+
+ public Long getDeptId() {
+ return deptId;
+ }
+
+ public void setDeptId(Long deptId) {
+ this.deptId = deptId;
+ }
+
+ public Long getParentId() {
+ return parentId;
+ }
+
+ public void setParentId(Long parentId) {
+ this.parentId = parentId;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getParentName() {
+ return parentName;
+ }
+
+ public void setParentName(String parentName) {
+ this.parentName = parentName;
+ }
+
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/domain/CacheSysUser.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/domain/CacheSysUser.java
new file mode 100644
index 00000000..4fd5a6d6
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/domain/CacheSysUser.java
@@ -0,0 +1,77 @@
+package com.ruoyi.cache.domain;
+
+import com.ruoyi.system.api.domain.SysUser;
+/**
+ * 存储在redis上的用户缓存
+ * @author condy
+ *
+ */
+public class CacheSysUser extends BaseCache {
+ /**
+ * @OrgCacheValue的 value类型
+ */
+ public final static String ANNOTAION_USER_ID="userId";
+ public final static String ANNOTAION_USER_NAME="userName";
+ public final static String ANNOTAION_DEPT_ID="deptId";
+ public final static String ANNOTAION_EMAIL="email";
+ public final static String ANNOTAION_PHONENUMBER="phonenumber";
+
+
+
+ private Long userId;
+ private String userName;
+ private Long deptId;
+ private String nickName;
+ private String email;
+ private String phonenumber;
+
+ public CacheSysUser(SysUser user) {
+ this.userId=user.getUserId();
+ this.userName=user.getUserName();
+ this.deptId=user.getDeptId();
+ this.nickName=user.getNickName();
+ this.email=user.getEmail();
+ this.phonenumber=user.getEmail();
+ }
+ public CacheSysUser()
+ {
+
+ }
+ public Long getUserId() {
+ return userId;
+ }
+ public void setUserId(Long userId) {
+ this.userId = userId;
+ }
+ public String getUserName() {
+ return userName;
+ }
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+ public Long getDeptId() {
+ return deptId;
+ }
+ public void setDeptId(Long deptId) {
+ this.deptId = deptId;
+ }
+ public String getNickName() {
+ return nickName;
+ }
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+ public String getEmail() {
+ return email;
+ }
+ public void setEmail(String email) {
+ this.email = email;
+ }
+ public String getPhonenumber() {
+ return phonenumber;
+ }
+ public void setPhonenumber(String phonenumber) {
+ this.phonenumber = phonenumber;
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/service/CacheCallBack.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/service/CacheCallBack.java
new file mode 100644
index 00000000..a7b43d7e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/service/CacheCallBack.java
@@ -0,0 +1,179 @@
+package com.ruoyi.cache.service;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.nutz.lang.ContinueLoop;
+import org.nutz.lang.Each;
+import org.nutz.lang.ExitLoop;
+import org.nutz.lang.LoopException;
+import org.nutz.lang.Mirror;
+import org.nutz.log.Log;
+import org.nutz.log.Logs;
+
+import com.ruoyi.cache.annotation.OrgCacheKey;
+import com.ruoyi.cache.annotation.OrgCacheTypeNum;
+import com.ruoyi.cache.annotation.OrgCacheValue;
+import com.ruoyi.cache.domain.BaseCache;
+import com.ruoyi.cache.domain.CacheSysDept;
+import com.ruoyi.cache.domain.CacheSysUser;
+import com.ruoyi.common.core.utils.SpringUtils;
+
+/**
+ * @OrgCacheKey
+ * @OrgCacheValue的注解的处理类
+ * @author
+ *
+ * @param
+ */
+public class CacheCallBack implements Each {
+ private Log log=Logs.get();
+ private class InnerCacheCallBack {
+ //@OrgCacheKey的注解的属性
+ private Field orgCacheKeyField;
+ private OrgCacheKey orgCacheKey;// @OrgCacheKey对象
+ //与OrgCacheKey的key相关的OrgCacheValue注解对象及对象的Field
+ private Map orgCacheValueFieldMap=new HashMap();
+ //CacheStaffInfo,CacheDeptInfo,CacheCopanyInfo的放射封装类
+ private Mirror> cacheBaseMirror;
+ public Field getOrgCacheKeyField() {
+ return orgCacheKeyField;
+ }
+ public void setOrgCacheKeyField(Field orgCacheKeyField) {
+ this.orgCacheKeyField = orgCacheKeyField;
+ }
+
+ public Mirror> getCacheBaseMirror() {
+ return cacheBaseMirror;
+ }
+ public void setCacheBaseMirror(Mirror> cacheBaseMirror) {
+ this.cacheBaseMirror = cacheBaseMirror;
+ }
+ public OrgCacheKey getOrgCacheKey() {
+ return orgCacheKey;
+ }
+ public void setOrgCacheKey(OrgCacheKey orgCacheKey) {
+ this.orgCacheKey = orgCacheKey;
+ }
+
+ public void addOrgCacheValueField(OrgCacheValue orgCacheValue,Field orgCacheValueField){
+ orgCacheValueFieldMap.put(orgCacheValue,orgCacheValueField);
+ }
+ public Map getOrgCacheValueFieldMap() {
+ return orgCacheValueFieldMap;
+ }
+
+ }
+
+ /**
+ * 采用默认的orgCacheService类
+ */
+ public CacheCallBack(){
+ this.orgCacheService=SpringUtils.getBean(IOrgCacheService.class);
+ }
+ /**
+ * 通过传递参数的方式.
+ * @param orgCacheService
+ */
+ public CacheCallBack(IOrgCacheService orgCacheService){
+ this.orgCacheService=orgCacheService;
+ }
+ private IOrgCacheService orgCacheService;
+ private Mirror> elemirror=null;
+ private Map innerCacheCallBackMap=new HashMap();
+
+ /**
+ * 初始化循环映射的参数.
+ * @param ele
+ */
+ private void init(T ele){
+ elemirror = Mirror.me(ele.getClass());//获取ele对象的反射类
+ //获取含有:OrgCacheKey的属性对象,初始化InnerCacheCallBack对象.
+ Field[] orgCacheKeyField=elemirror.getFields(OrgCacheKey.class);
+ for (int i = 0; i < orgCacheKeyField.length; i++) {
+ InnerCacheCallBack innerCacheCallBack=new InnerCacheCallBack();
+ innerCacheCallBack.setOrgCacheKeyField(orgCacheKeyField[i]);
+ innerCacheCallBack.setOrgCacheKey(orgCacheKeyField[i].getAnnotation(OrgCacheKey.class));
+ innerCacheCallBackMap.put(innerCacheCallBack.getOrgCacheKey().id(), innerCacheCallBack);
+ OrgCacheTypeNum typeNum=innerCacheCallBack.getOrgCacheKey().type();
+ switch(typeNum){
+ case CacheUserInfo:
+ innerCacheCallBack.setCacheBaseMirror( Mirror.me(CacheSysUser.class));
+ break;
+ case CacheDeptInfo:
+ innerCacheCallBack.setCacheBaseMirror( Mirror.me(CacheSysDept.class));
+ break;
+ default:
+ log.warnf("无法识别的枚举类型:%s",typeNum.toString());
+ continue;
+ }
+ }
+ Field[] aOrgCacheValueField=elemirror.getFields(OrgCacheValue.class);
+ for (int i = 0; i < aOrgCacheValueField.length; i++) {
+ OrgCacheValue orgCacheValue=aOrgCacheValueField[i].getAnnotation(OrgCacheValue.class);
+ if(innerCacheCallBackMap.containsKey(orgCacheValue.id())){
+ innerCacheCallBackMap.get(orgCacheValue.id()).addOrgCacheValueField(orgCacheValue,aOrgCacheValueField[i]);
+ } else{
+ log.warnf("找不到id:%s对应的Cache对象.请检查的@OrgCacheValue注解 id值,类:%s,属性:%s注解",
+ orgCacheValue.id(),ele.getClass(),aOrgCacheValueField[i].getName());
+ }
+ }
+ }
+ @Override
+ public void invoke(int index, T ele, int length) throws ExitLoop, ContinueLoop, LoopException {
+ if(elemirror==null){
+ init(ele);
+ }
+ for (Iterator> iterator = innerCacheCallBackMap.entrySet().iterator(); iterator.hasNext();) {
+ /**
+ * 获取BaseCache对象.
+ */
+ Map.Entry type = iterator.next();
+ InnerCacheCallBack innerCacheCallBack=type.getValue();
+ Mirror> cacheBaseMirror=innerCacheCallBack.getCacheBaseMirror();
+ Object orgCacheKeyFieldValue=cacheBaseMirror.getValue(ele, innerCacheCallBack.getOrgCacheKeyField());
+ if(orgCacheKeyFieldValue==null)//获取的orgCacheKeyFieldValue 对应的值为null 就不需要在进入后续的循环了.
+ continue;
+ OrgCacheTypeNum typeNum=innerCacheCallBack.getOrgCacheKey().type();
+ BaseCache baseCache=null;
+ switch(typeNum){
+ case CacheUserInfo:
+ baseCache=orgCacheService.getSysUser((Long)orgCacheKeyFieldValue).orElse(null);
+ if(baseCache==null){
+ log.warnf("userId:%s获取到CacheStaffInfo的缓存数据是空。请检查Redis服务器.",orgCacheKeyFieldValue);
+ continue;
+ }
+ break;
+ case CacheDeptInfo:
+ baseCache=orgCacheService.getDeptInfo((Long)orgCacheKeyFieldValue).orElse(null);
+ if(baseCache==null){
+ log.warnf("deptId:%s获取到CacheDeptInfo的缓存数据是空。请检查Redis服务器.",orgCacheKeyFieldValue);
+ continue;
+ }
+ break;
+ default:
+ log.warnf("无法识别的枚举类型:%s",typeNum.toString());
+ continue;
+
+ }
+ /**
+ * 将BaseCache对象的值设置到ele对象里面.
+ */
+ for (Iterator> iterator2 = innerCacheCallBack.getOrgCacheValueFieldMap().entrySet().iterator(); iterator2.hasNext();) {
+ Map.Entry type2 = iterator2.next();
+ OrgCacheValue orgCacheValue=type2.getKey();
+ Field orgCacheValueField=type2.getValue();
+ Object orgCacheValueFieldValue=cacheBaseMirror.getValue(baseCache, orgCacheValue.value());
+ elemirror.setValue(ele, orgCacheValueField, orgCacheValueFieldValue);
+
+ }
+
+
+ }
+
+
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/service/IOrgCacheService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/service/IOrgCacheService.java
new file mode 100644
index 00000000..fa66db1a
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/cache/service/IOrgCacheService.java
@@ -0,0 +1,58 @@
+package com.ruoyi.cache.service;
+
+import java.util.Optional;
+
+import com.ruoyi.cache.domain.CacheSysDept;
+import com.ruoyi.cache.domain.CacheSysUser;
+
+/**
+ * 组织架构的缓存类
+ * 一级缓存,本地ecache缓存. 二级缓存:redis缓存.
+ * @author Condy
+ *
+ */
+public interface IOrgCacheService {
+
+ /**
+ * 把员工信息存储到redis服务器上.
+ * @param staffInfo
+ * @return
+ */
+ public CacheSysUser saveSysUser(CacheSysUser cacheSysUser);
+
+ /**
+ * 删除员工
+ * @param userId
+ */
+ public void deleteSysUser(Long userId);
+
+ /**
+ * 从redis上获取员工信息,先读取ecache缓存,没有的话到redis服务器读取.
+ * @param staffId
+ * @return CacheStaffInfo 取不到staffId对应的信息时会返回null
+ */
+ public Optional getSysUser(long userId);
+
+ /**
+ * 从redis服务器中获取部门信息.
+ * @param deptId
+ * @return 如果取不到部门信息会返回null
+ */
+ public Optional getDeptInfo(long deptId);
+
+ /**
+ * 将部门数据存储到redis缓存中
+ * @param cacheDeptInfo
+ * @return
+ */
+ public CacheSysDept saveDeptInfo(CacheSysDept cacheDeptInfo);
+ /**
+ * 删除部分
+ * @param deptId
+ */
+ public void deleteDeptInfo(Long deptId);
+
+
+
+
+}
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/CacheConfigurer.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/CacheConfigurer.java
new file mode 100644
index 00000000..6eb24d6d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/CacheConfigurer.java
@@ -0,0 +1,29 @@
+package com.ruoyi.system;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+
+import com.ruoyi.common.redis.service.RedisService;
+import com.ruoyi.util.RedisNotifyService;
+import com.ruoyi.util.SpringLoadComplete;
+
+@Configuration
+@EnableCaching
+@Component
+public class CacheConfigurer {
+ @Autowired
+ private RedisService redisService;
+ @Bean
+ public SpringLoadComplete getSpringLoadComplete() {
+ return new SpringLoadComplete();
+ }
+ @Bean
+ public RedisNotifyService getRedisNotifyService() {
+ RedisNotifyService notifyService= new RedisNotifyService(redisService);
+ return notifyService;
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/BulletinInfoController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/BulletinInfoController.java
new file mode 100644
index 00000000..31833b0d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/BulletinInfoController.java
@@ -0,0 +1,173 @@
+package com.ruoyi.system.controller;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.log.annotation.Log;
+import com.ruoyi.common.log.enums.BusinessType;
+import com.ruoyi.common.security.annotation.RequiresPermissions;
+import com.ruoyi.system.domain.BulletinInfo;
+import com.ruoyi.system.domain.BulletinRecive;
+import com.ruoyi.system.service.IBulletinInfoService;
+import com.ruoyi.system.service.IBulletinReciveService;
+import com.ruoyi.common.core.web.controller.BaseController;
+import com.ruoyi.common.core.web.domain.AjaxResult;
+import com.ruoyi.common.core.web.page.TableDataInfo;
+
+/**
+ * 公告栏Controller
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+@RestController
+@RequestMapping("/bulletin")
+public class BulletinInfoController extends BaseController
+{
+ @Autowired
+ private IBulletinInfoService bulletinInfoService;
+
+ @Autowired
+ private IBulletinReciveService bulletinReciveService;
+
+ /**
+ * 查询公告栏列表
+ */
+ @RequiresPermissions("system:bulletin:list")
+ @GetMapping("/list")
+ public TableDataInfo list(BulletinInfo bulletinInfo)
+ {
+ startPage();
+ List list = bulletinInfoService.selectBulletinInfoList(bulletinInfo);
+ return getDataTable(list);
+ }
+
+ /**
+ * 获取公告栏详细信息
+ */
+ @RequiresPermissions("system:bulletin:query")
+ @GetMapping(value = "/{bulletinId}")
+ public AjaxResult getInfo(@PathVariable("bulletinId") String bulletinId)
+ {
+ return success(bulletinInfoService.selectBulletinInfoByBulletinId(bulletinId));
+ }
+
+ /**
+ * 发送公告栏
+ */
+ @RequiresPermissions("system:bulletin:add")
+ @Log(title = "公告栏", businessType = BusinessType.OTHER)
+ @PostMapping("/batchSend/{bulletinIds}")
+ public AjaxResult batchSend(@PathVariable String[] bulletinIds)
+ {
+ return toAjax(bulletinInfoService.sendBulletinInfo(bulletinIds));
+ }
+
+ /**
+ * 新增或发送 公告栏
+ */
+ @RequiresPermissions("system:bulletin:add")
+ @Log(title = "公告栏", businessType = BusinessType.INSERT)
+ @PostMapping
+ public AjaxResult add(@Validated @RequestBody BulletinInfo bulletinInfo)
+ {
+ return toAjax(bulletinInfoService.insertBulletinInfo(bulletinInfo));
+ }
+
+
+
+ /**
+ * 修改公告栏
+ */
+ @RequiresPermissions("system:bulletin:edit")
+ @Log(title = "公告栏", businessType = BusinessType.UPDATE)
+ @PutMapping
+ public AjaxResult edit(@RequestBody BulletinInfo bulletinInfo)
+ {
+ return toAjax(bulletinInfoService.updateBulletinInfo(bulletinInfo));
+ }
+
+ /**
+ * 物理删除公告栏
+ */
+ @RequiresPermissions("system:bulletin:remove")
+ @Log(title = "公告栏", businessType = BusinessType.DELETE)
+ @DeleteMapping("/delete/{bulletinIds}")
+ public AjaxResult removePysical(@PathVariable String[] bulletinIds)
+ {
+ return toAjax(bulletinInfoService.deleteBulletinInfoByBulletinIds(bulletinIds,"D"));
+ }
+
+ /**
+ * 逻辑删除公告栏
+ */
+ @RequiresPermissions("system:bulletin:remove")
+ @Log(title = "公告栏", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{bulletinIds}")
+ public AjaxResult remove(@PathVariable String[] bulletinIds)
+ {
+ return toAjax(bulletinInfoService.deleteBulletinInfoByBulletinIds(bulletinIds,"B"));
+ }
+
+ /**
+ * 批量阅读成功
+ */
+ @RequiresPermissions("system:bulletin:edit")
+ @PutMapping("/recive/batchRead/{reciveIds}")
+ public AjaxResult batchRead(@PathVariable String[] reciveIds)
+ {
+ return toAjax(bulletinReciveService.batchRead(reciveIds));
+ }
+
+ /**
+ * 查询公告接收者列表
+ */
+ @RequiresPermissions("system:bulletin:list")
+ @GetMapping("/recive/list")
+ public TableDataInfo reciveList(BulletinRecive bulletinRecive)
+ {
+ startPage();
+ List list = bulletinReciveService.selectBulletinReciveList(bulletinRecive);
+ return getDataTable(list);
+ }
+
+ /**
+ * 逻辑删除公告接收者
+ */
+ @RequiresPermissions("system:bulletin:remove")
+ @Log(title = "公告接收者", businessType = BusinessType.DELETE)
+ @DeleteMapping("/recive/{reciveIds}")
+ public AjaxResult reciveRemove(@PathVariable String[] reciveIds)
+ {
+ return toAjax(bulletinReciveService.deleteBulletinReciveByReciveIds(reciveIds));
+ }
+
+ /**
+ * 物理删除公告接收者
+ */
+ @RequiresPermissions("system:bulletin:remove")
+ @Log(title = "公告接收者", businessType = BusinessType.DELETE)
+ @DeleteMapping("/recive/delete/{reciveIds}")
+ public AjaxResult recivePhysicalRemove(@PathVariable String[] reciveIds)
+ {
+ return toAjax(bulletinReciveService.deletePhysicalBulletinReciveByReciveIds(reciveIds));
+ }
+
+ /**
+ * 获取公告接收者详细信息
+ */
+ @RequiresPermissions("system:bulletin:query")
+ @GetMapping(value = "/recive/{reciveId}")
+ public AjaxResult getReciveInfo(@PathVariable("reciveId") String reciveId)
+ {
+ return success(bulletinReciveService.selectBulletinReciveByReciveId(reciveId));
+ }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/BulletinInfo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/BulletinInfo.java
new file mode 100644
index 00000000..b43b1ef6
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/BulletinInfo.java
@@ -0,0 +1,242 @@
+package com.ruoyi.system.domain;
+
+import java.util.List;
+
+import javax.validation.constraints.NotEmpty;
+
+import java.util.Collections;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.core.annotation.Excel;
+import com.ruoyi.common.core.web.domain.BaseEntity;
+
+/**
+ * 公告栏对象 t_bulletin_info
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+public class BulletinInfo extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 公告ID */
+ private String bulletinId;
+
+ /** 公告标题 */
+ @Excel(name = "公告标题")
+ @NotEmpty(message = "公告标题不允许为空")
+ private String title;
+
+ /** 公告内容 */
+ @Excel(name = "公告内容")
+ private String content;
+
+ /** 已读人数 */
+ @Excel(name = "已读人数")
+ private Long readNum;
+
+ /** 公告的发送时间 */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Excel(name = "公告的发送时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+ private Date sendTime;
+
+ /** 员工ID */
+ @Excel(name = "员工ID")
+ private Long createUserId;
+
+ /** 更新员工 */
+ @Excel(name = "更新员工")
+ private Long updateUserId;
+
+ /** 状态 */
+ @Excel(name = "状态")
+ @NotEmpty(message = "状态不允许为空")
+ private String sts;
+
+ /** 公告接收者信息 */
+ private List bulletinReciveList;
+ /**
+ * 给前端过渡,用于生成BulletinRecive
+ */
+ private List receiveStaffIds;
+ /**
+ * 接收人员,以逗号分隔
+ */
+ private String reciveStaffNames;
+
+
+ public String getReciveStaffNames() {
+ return reciveStaffNames;
+ }
+ public void setReciveStaffNames(String reciveStaffNames) {
+ this.reciveStaffNames = reciveStaffNames;
+ }
+ public List getReceiveStaffIds() {
+ if(receiveStaffIds==null) {
+ receiveStaffIds=Collections.emptyList();
+ }
+ return receiveStaffIds;
+ }
+ public void setReceiveStaffIds(List receiveStaffIds) {
+ this.receiveStaffIds = receiveStaffIds;
+ }
+ /**
+ * 设置 BulletinId
+ * @param 公告ID
+ */
+ public void setBulletinId(String bulletinId)
+ {
+ this.bulletinId = bulletinId;
+ }
+ /**
+ * 获取 公告ID
+ * @return
+ */
+ public String getBulletinId()
+ {
+ return bulletinId;
+ }
+ /**
+ * 设置 Title
+ * @param 公告标题
+ */
+ public void setTitle(String title)
+ {
+ this.title = title;
+ }
+ /**
+ * 获取 公告标题
+ * @return
+ */
+ public String getTitle()
+ {
+ return title;
+ }
+ /**
+ * 设置 Content
+ * @param 公告内容
+ */
+ public void setContent(String content)
+ {
+ this.content = content;
+ }
+ /**
+ * 获取 公告内容
+ * @return
+ */
+ public String getContent()
+ {
+ return content;
+ }
+ /**
+ * 设置 ReadNum
+ * @param 已读人数
+ */
+ public void setReadNum(Long readNum)
+ {
+ this.readNum = readNum;
+ }
+ /**
+ * 获取 已读人数
+ * @return
+ */
+ public Long getReadNum()
+ {
+ return readNum;
+ }
+ /**
+ * 设置 SendTime
+ * @param 公告的发送时间
+ */
+ public void setSendTime(Date sendTime)
+ {
+ this.sendTime = sendTime;
+ }
+ /**
+ * 获取 公告的发送时间
+ * @return
+ */
+ public Date getSendTime()
+ {
+ return sendTime;
+ }
+ /**
+ * 设置 CreateUserId
+ * @param 员工ID
+ */
+ public void setCreateUserId(Long createUserId)
+ {
+ this.createUserId = createUserId;
+ }
+ /**
+ * 获取 员工ID
+ * @return
+ */
+ public Long getCreateUserId()
+ {
+ return createUserId;
+ }
+ /**
+ * 设置 UpdateUserId
+ * @param 更新员工
+ */
+ public void setUpdateUserId(Long updateUserId)
+ {
+ this.updateUserId = updateUserId;
+ }
+ /**
+ * 获取 更新员工
+ * @return
+ */
+ public Long getUpdateUserId()
+ {
+ return updateUserId;
+ }
+ /**
+ * 设置 Sts
+ * @param 状态
+ */
+ public void setSts(String sts)
+ {
+ this.sts = sts;
+ }
+ /**
+ * 获取 状态
+ * @return
+ */
+ public String getSts()
+ {
+ return sts;
+ }
+
+ public List getBulletinReciveList()
+ {
+ return bulletinReciveList;
+ }
+
+ public void setBulletinReciveList(List bulletinReciveList)
+ {
+ this.bulletinReciveList = bulletinReciveList;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+ .append("bulletinId", getBulletinId())
+ .append("title", getTitle())
+ .append("content", getContent())
+ .append("createTime", getCreateTime())
+ .append("readNum", getReadNum())
+ .append("sendTime", getSendTime())
+ .append("createUserId", getCreateUserId())
+ .append("updateUserId", getUpdateUserId())
+ .append("updateTime", getUpdateTime())
+ .append("remark", getRemark())
+ .append("sts", getSts())
+ .append("bulletinReciveList", getBulletinReciveList())
+ .toString();
+ }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/BulletinRecive.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/BulletinRecive.java
new file mode 100644
index 00000000..25524a46
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/BulletinRecive.java
@@ -0,0 +1,209 @@
+package com.ruoyi.system.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.core.annotation.Excel;
+import com.ruoyi.common.core.web.domain.BaseEntity;
+
+/**
+ * 公告接收者对象 t_bulletin_recive
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+public class BulletinRecive extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 接收ID */
+ private String reciveId;
+
+ /** 接收员工ID */
+ @Excel(name = "接收员工ID")
+ private Long reciveUserId;
+ /**
+ * 接收部门ID
+ */
+ private Long reciveDeptId;
+
+ /** 阅读时间 */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Excel(name = "阅读时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+ private Date readTime;
+
+ /** 阅读次数 */
+ @Excel(name = "阅读次数")
+ private Long readNum;
+
+ /** 员工ID */
+ @Excel(name = "员工ID")
+ private Long createUserId;
+
+ /** 更新员工 */
+ @Excel(name = "更新员工")
+ private Long updateUserId;
+
+ /** 公告ID */
+ @Excel(name = "公告ID")
+ private String bulletinId;
+
+ /** A:已阅读,B:已删除 C:未阅读 */
+ @Excel(name = "A:已阅读,B:已删除 C:未阅读")
+ private String sts;
+
+
+
+ public Long getReciveDeptId() {
+ return reciveDeptId;
+ }
+ public void setReciveDeptId(Long reciveDeptId) {
+ this.reciveDeptId = reciveDeptId;
+ }
+ /**
+ * 设置 ReciveId
+ * @param 接收ID
+ */
+ public void setReciveId(String reciveId)
+ {
+ this.reciveId = reciveId;
+ }
+ /**
+ * 获取 接收ID
+ * @return
+ */
+ public String getReciveId()
+ {
+ return reciveId;
+ }
+ /**
+ * 设置 ReciveUserId
+ * @param 接收员工ID
+ */
+ public void setReciveUserId(Long reciveUserId)
+ {
+ this.reciveUserId = reciveUserId;
+ }
+ /**
+ * 获取 接收员工ID
+ * @return
+ */
+ public Long getReciveUserId()
+ {
+ return reciveUserId;
+ }
+ /**
+ * 设置 ReadTime
+ * @param 阅读时间
+ */
+ public void setReadTime(Date readTime)
+ {
+ this.readTime = readTime;
+ }
+ /**
+ * 获取 阅读时间
+ * @return
+ */
+ public Date getReadTime()
+ {
+ return readTime;
+ }
+ /**
+ * 设置 ReadNum
+ * @param 阅读次数
+ */
+ public void setReadNum(Long readNum)
+ {
+ this.readNum = readNum;
+ }
+ /**
+ * 获取 阅读次数
+ * @return
+ */
+ public Long getReadNum()
+ {
+ return readNum;
+ }
+ /**
+ * 设置 CreateUserId
+ * @param 员工ID
+ */
+ public void setCreateUserId(Long createUserId)
+ {
+ this.createUserId = createUserId;
+ }
+ /**
+ * 获取 员工ID
+ * @return
+ */
+ public Long getCreateUserId()
+ {
+ return createUserId;
+ }
+ /**
+ * 设置 UpdateUserId
+ * @param 更新员工
+ */
+ public void setUpdateUserId(Long updateUserId)
+ {
+ this.updateUserId = updateUserId;
+ }
+ /**
+ * 获取 更新员工
+ * @return
+ */
+ public Long getUpdateUserId()
+ {
+ return updateUserId;
+ }
+ /**
+ * 设置 BulletinId
+ * @param 公告ID
+ */
+ public void setBulletinId(String bulletinId)
+ {
+ this.bulletinId = bulletinId;
+ }
+ /**
+ * 获取 公告ID
+ * @return
+ */
+ public String getBulletinId()
+ {
+ return bulletinId;
+ }
+ /**
+ * 设置 Sts
+ * @param A:已阅读,B:已删除 C:未阅读
+ */
+ public void setSts(String sts)
+ {
+ this.sts = sts;
+ }
+ /**
+ * 获取 A:已阅读,B:已删除 C:未阅读
+ * @return
+ */
+ public String getSts()
+ {
+ return sts;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+ .append("reciveId", getReciveId())
+ .append("reciveUserId", getReciveUserId())
+ .append("readTime", getReadTime())
+ .append("readNum", getReadNum())
+ .append("createTime", getCreateTime())
+ .append("createUserId", getCreateUserId())
+ .append("updateUserId", getUpdateUserId())
+ .append("updateTime", getUpdateTime())
+ .append("remark", getRemark())
+ .append("bulletinId", getBulletinId())
+ .append("sts", getSts())
+ .toString();
+ }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/BulletinInfoMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/BulletinInfoMapper.java
new file mode 100644
index 00000000..cd8a16dd
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/BulletinInfoMapper.java
@@ -0,0 +1,95 @@
+package com.ruoyi.system.mapper;
+
+import java.util.List;
+
+
+import com.ruoyi.system.domain.BulletinInfo;
+import com.ruoyi.system.domain.BulletinRecive;
+
+/**
+ * 公告栏Mapper接口
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+public interface BulletinInfoMapper
+{
+ /**
+ * 查询公告栏
+ *
+ * @param bulletinId 公告栏主键
+ * @return 公告栏
+ */
+ public BulletinInfo selectBulletinInfoByBulletinId(String bulletinId);
+
+ /**
+ * 查询公告栏列表
+ *
+ * @param bulletinInfo 公告栏
+ * @return 公告栏集合
+ */
+ public List selectBulletinInfoList(BulletinInfo bulletinInfo);
+
+ /**
+ * 根据bulletinId查询公告栏列表
+ * @param bulletinIds
+ * @return
+ */
+ public List selectBulletinInfoListbyBulletinIds(String[] bulletinIds);
+ /**
+ * 新增公告栏
+ *
+ * @param bulletinInfo 公告栏
+ * @return 结果
+ */
+ public int insertBulletinInfo(BulletinInfo bulletinInfo);
+
+ /**
+ * 修改公告栏
+ *
+ * @param bulletinInfo 公告栏
+ * @return 结果
+ */
+ public int updateBulletinInfo(BulletinInfo bulletinInfo);
+
+ /**
+ * 删除公告栏
+ *
+ * @param bulletinId 公告栏主键
+ * @return 结果
+ */
+ public int deleteBulletinInfoByBulletinId(String bulletinId);
+
+ /**
+ * 批量删除公告栏
+ *
+ * @param bulletinIds 需要删除的数据主键集合
+ * @return 结果
+ */
+ public int deleteBulletinInfoByBulletinIds(String[] bulletinIds);
+
+ /**
+ * 批量删除公告接收者
+ *
+ * @param bulletinIds 需要删除的数据主键集合
+ * @return 结果
+ */
+ public int deleteBulletinReciveByBulletinIds(String[] bulletinIds);
+
+ /**
+ * 批量新增公告接收者
+ *
+ * @param bulletinReciveList 公告接收者列表
+ * @return 结果
+ */
+ public int batchBulletinRecive(List bulletinReciveList);
+
+
+ /**
+ * 通过公告栏主键删除公告接收者信息
+ *
+ * @param bulletinId 公告栏ID
+ * @return 结果
+ */
+ public int deleteBulletinReciveByBulletinId(String bulletinId);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/BulletinReciveMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/BulletinReciveMapper.java
new file mode 100644
index 00000000..207cfe61
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/BulletinReciveMapper.java
@@ -0,0 +1,74 @@
+package com.ruoyi.system.mapper;
+
+import java.util.List;
+import com.ruoyi.system.domain.BulletinRecive;
+
+/**
+ * 公告接收者Mapper接口
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+public interface BulletinReciveMapper
+{
+
+ /**
+ * 批量更新已阅读
+ * @param bulletinRecive
+ * @return
+ */
+ public int batchUpdateRead(String[] reciveIds);
+ /**
+ * 只查询出bulletinId和接收的reciveUserId
+ * @param bulletinIds
+ * @return
+ */
+ public List selectBulletinReciveUserIdByBulletinIds(String[] bulletinIds);
+ /**
+ * 查询公告接收者
+ *
+ * @param reciveId 公告接收者主键
+ * @return 公告接收者
+ */
+ public BulletinRecive selectBulletinReciveByReciveId(String reciveId);
+
+ /**
+ * 查询公告接收者列表
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 公告接收者集合
+ */
+ public List selectBulletinReciveList(BulletinRecive bulletinRecive);
+
+ /**
+ * 新增公告接收者
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 结果
+ */
+ public int insertBulletinRecive(BulletinRecive bulletinRecive);
+
+ /**
+ * 修改公告接收者
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 结果
+ */
+ public int updateBulletinRecive(BulletinRecive bulletinRecive);
+
+ /**
+ * 删除公告接收者
+ *
+ * @param reciveId 公告接收者主键
+ * @return 结果
+ */
+ public int deleteBulletinReciveByReciveId(String reciveId);
+
+ /**
+ * 批量删除公告接收者
+ *
+ * @param reciveIds 需要删除的数据主键集合
+ * @return 结果
+ */
+ public int deleteBulletinReciveByReciveIds(String[] reciveIds);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IBulletinInfoService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IBulletinInfoService.java
new file mode 100644
index 00000000..c383c6b7
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IBulletinInfoService.java
@@ -0,0 +1,69 @@
+package com.ruoyi.system.service;
+
+import java.util.List;
+import com.ruoyi.system.domain.BulletinInfo;
+
+/**
+ * 公告栏Service接口
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+public interface IBulletinInfoService
+{
+ /**
+ * 查询公告栏
+ *
+ * @param bulletinId 公告栏主键
+ * @return 公告栏
+ */
+ public BulletinInfo selectBulletinInfoByBulletinId(String bulletinId);
+
+ /**
+ * 查询公告栏列表
+ *
+ * @param bulletinInfo 公告栏
+ * @return 公告栏集合
+ */
+ public List selectBulletinInfoList(BulletinInfo bulletinInfo);
+
+ /**
+ * 新增公告栏
+ *
+ * @param bulletinInfo 公告栏
+ * @return 结果
+ */
+ public int insertBulletinInfo(BulletinInfo bulletinInfo);
+
+ /**
+ * 修改公告栏
+ *
+ * @param bulletinInfo 公告栏
+ * @return 结果
+ */
+ public int updateBulletinInfo(BulletinInfo bulletinInfo);
+
+ /**
+ * 批量删除公告栏
+ *
+ * @param bulletinIds 需要删除的公告栏主键集合
+ * @param sts B:逻辑删除,D:物理删除
+ * @return 结果
+ */
+ public int deleteBulletinInfoByBulletinIds(String[] bulletinIds,String sts);
+
+ /**
+ * 删除公告栏信息
+ *
+ * @param bulletinId 公告栏主键
+ * @return 结果
+ */
+ public int deleteBulletinInfoByBulletinId(String bulletinId);
+
+ /**
+ * 批量发送公告
+ * @param bulletinIds
+ * @return
+ */
+ int sendBulletinInfo(String[] bulletinIds);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IBulletinReciveService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IBulletinReciveService.java
new file mode 100644
index 00000000..b2ca63f6
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IBulletinReciveService.java
@@ -0,0 +1,78 @@
+package com.ruoyi.system.service;
+
+import java.util.List;
+
+import com.ruoyi.system.domain.BulletinInfo;
+import com.ruoyi.system.domain.BulletinRecive;
+
+/**
+ * 公告接收者Service接口
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+public interface IBulletinReciveService
+{
+ /**
+ * 查询公告接收者
+ *
+ * @param reciveId 公告接收者主键
+ * @return 公告接收者
+ */
+ public BulletinRecive selectBulletinReciveByReciveId(String reciveId);
+
+ /**
+ * 查询公告接收者列表
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 公告接收者集合
+ */
+ public List selectBulletinReciveList(BulletinRecive bulletinRecive);
+
+ /**
+ * 新增公告接收者
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 结果
+ */
+ public int insertBulletinRecive(BulletinRecive bulletinRecive);
+
+ /**
+ * 修改公告接收者
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 结果
+ */
+ public int updateBulletinRecive(BulletinRecive bulletinRecive);
+
+ /**
+ * 批量删除公告接收者
+ *
+ * @param reciveIds 需要删除的公告接收者主键集合
+ * @return 结果
+ */
+ public int deleteBulletinReciveByReciveIds(String[] reciveIds);
+
+ /**
+ * 删除公告接收者信息
+ *
+ * @param reciveId 公告接收者主键
+ * @return 结果
+ */
+ public int deleteBulletinReciveByReciveId(String reciveId);
+
+ /**
+ * 批量更新已阅读
+ * @param reciveIds
+ * @return
+ */
+ int batchRead(String[] reciveIds);
+
+ /**
+ * 批量物理删除公告接收者
+ *
+ * @param reciveIds 需要删除的公告接收者主键
+ * @return 结果
+ */
+ int deletePhysicalBulletinReciveByReciveIds(String[] reciveIds);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/BulletinInfoServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/BulletinInfoServiceImpl.java
new file mode 100644
index 00000000..12a407af
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/BulletinInfoServiceImpl.java
@@ -0,0 +1,239 @@
+package com.ruoyi.system.service.impl;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import com.ruoyi.cache.service.IOrgCacheService;
+import com.ruoyi.common.core.utils.DateUtils;
+
+import org.apache.commons.lang3.StringUtils;
+import org.nutz.lang.util.NutMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+
+import com.ruoyi.common.security.utils.SecurityUtils;
+
+import org.springframework.transaction.annotation.Transactional;
+import com.ruoyi.system.domain.BulletinRecive;
+import com.ruoyi.system.mapper.BulletinInfoMapper;
+import com.ruoyi.system.mapper.BulletinReciveMapper;
+import com.ruoyi.system.domain.BulletinInfo;
+import com.ruoyi.system.service.IBulletinInfoService;
+import com.ruoyi.util.IDUtil;
+
+/**
+ * 公告栏Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+@Service
+public class BulletinInfoServiceImpl implements IBulletinInfoService
+{
+ private Logger log=LoggerFactory.getLogger(BulletinInfoServiceImpl.class);
+ @Autowired
+ private BulletinInfoMapper bulletinInfoMapper;
+ @Autowired
+ private BulletinReciveMapper bulletinReciveMapper;
+ @Autowired
+ private IOrgCacheService orgCacheService;
+
+ /**
+ * 查询公告栏
+ *
+ * @param bulletinId 公告栏主键
+ * @return 公告栏
+ */
+ @Override
+ public BulletinInfo selectBulletinInfoByBulletinId(String bulletinId)
+ {
+ List reciveUserIdAndbulletinId=bulletinReciveMapper.selectBulletinReciveUserIdByBulletinIds(new String[] {bulletinId});
+ BulletinInfo info= bulletinInfoMapper.selectBulletinInfoByBulletinId(bulletinId);
+ info.setCreateBy(orgCacheService.getSysUser(info.getCreateUserId()).map(sysUser->sysUser.getUserName()).orElse(""));
+ info.setUpdateBy(orgCacheService.getSysUser(info.getUpdateUserId()).map(sysUser->sysUser.getUserName()).orElse(""));
+ List reciveUserIdList=reciveUserIdAndbulletinId.stream().map(userId->userId.getReciveUserId()).collect(Collectors.toList());
+ info.setReceiveStaffIds(reciveUserIdList);
+ info.setReciveStaffNames(StringUtils.join(reciveUserIdList.iterator(), ","));
+ return info;
+ }
+
+ /**
+ * 查询公告栏列表
+ *
+ * @param bulletinInfo 公告栏
+ * @return 公告栏
+ */
+ @Override
+ public List selectBulletinInfoList(BulletinInfo bulletinInfo)
+ {
+ bulletinInfo.setCreateUserId(SecurityUtils.getUserId());
+ List list=bulletinInfoMapper.selectBulletinInfoList(bulletinInfo);
+ String[] bulletinIds=list.stream().map(info->info.getBulletinId()).toArray(String[]::new);
+ if(bulletinIds.length>0) {
+ final NutMap reciveUserNameMap=NutMap.NEW();
+ final NutMap reciveBulletinReciveMap=NutMap.NEW();
+ List reciveUserIdAndbulletinIdList=bulletinReciveMapper.selectBulletinReciveUserIdByBulletinIds(bulletinIds);
+ reciveUserIdAndbulletinIdList.forEach(reciveUserIdAndBulletinId->{
+ String reciveUserName=orgCacheService.getSysUser(reciveUserIdAndBulletinId.getReciveUserId()).map(sysUser->sysUser.getUserName()).orElse("");
+ reciveUserNameMap.addv2(reciveUserIdAndBulletinId.getBulletinId(), reciveUserName);
+ reciveBulletinReciveMap.addv2(reciveUserIdAndBulletinId.getBulletinId(), reciveUserIdAndBulletinId);
+ });
+ list.forEach(info->{
+ String reciveStaffNames=String.join(",", reciveUserNameMap.getList(info.getBulletinId(), String.class, Collections.emptyList()));
+ info.setReciveStaffNames(reciveStaffNames);
+ info.setCreateBy(orgCacheService.getSysUser(info.getCreateUserId()).map(sysUser->sysUser.getUserName()).orElse(""));
+ info.setBulletinReciveList(reciveBulletinReciveMap.getList(info.getBulletinId(), BulletinRecive.class,Collections.emptyList()));
+ });
+ }
+ return list;
+ }
+
+ /**
+ * 批量发送公告
+ * @param bulletinIds
+ * @return
+ */
+ @Override
+ public int sendBulletinInfo(String[] bulletinIds) {
+ int updateCount=0;
+ for (String bulletinId : bulletinIds) {
+ log.info("发送公告,bulletinId:{}",bulletinId);
+ BulletinInfo info=new BulletinInfo();
+ info.setBulletinId(bulletinId);
+ info.setSendTime(DateUtils.getNowDate());
+ info.setUpdateUserId(SecurityUtils.getUserId());
+ info.setUpdateTime(info.getSendTime());
+ info.setSts("A");
+
+ updateCount+=bulletinInfoMapper.updateBulletinInfo(info);
+ }
+ return updateCount;
+ }
+ /**
+ * 推送公告给客户端
+ * @param bulletinId
+ * @return
+ */
+ private boolean pushBulletinToClient(String bulletinId) {
+ //TODO 发送公告的业务逻辑还没做,需要获取在线用户,推送给对方
+ log.info("发送公告,bulletinId:{} 业务逻辑还是空的",bulletinId);
+ return true;
+ }
+ /**
+ * 新增公告栏
+ *
+ * @param bulletinInfo 公告栏
+ * @return 结果
+ */
+ @Transactional
+ @Override
+ public int insertBulletinInfo(BulletinInfo bulletinInfo)
+ {
+ bulletinInfo.setBulletinId(IDUtil.getStrId());
+ Long userId=SecurityUtils.getUserId();
+ bulletinInfo.setCreateUserId(userId);
+ Date currDate=DateUtils.getNowDate();
+ bulletinInfo.setCreateTime(currDate);
+ bulletinInfo.setUpdateTime(currDate);
+ bulletinInfo.setUpdateUserId(userId);
+ if("A".equals(bulletinInfo.getSts())) {
+ bulletinInfo.setSendTime(bulletinInfo.getCreateTime());
+ }
+ bulletinInfo.setReadNum(0L);
+ int rows = bulletinInfoMapper.insertBulletinInfo(bulletinInfo);
+ insertBulletinRecive(bulletinInfo);
+ pushBulletinToClient(bulletinInfo.getBulletinId());
+ return rows;
+ }
+
+ /**
+ * 修改公告栏
+ *
+ * @param bulletinInfo 公告栏
+ * @return 结果
+ */
+ @Transactional
+ @Override
+ public int updateBulletinInfo(BulletinInfo bulletinInfo)
+ {
+ bulletinInfo.setUpdateTime(DateUtils.getNowDate());
+ bulletinInfo.setUpdateUserId(SecurityUtils.getUserId());
+ if(!bulletinInfo.getReceiveStaffIds().isEmpty()) {
+ bulletinInfoMapper.deleteBulletinReciveByBulletinId(bulletinInfo.getBulletinId());
+ insertBulletinRecive(bulletinInfo);
+ }
+ return bulletinInfoMapper.updateBulletinInfo(bulletinInfo);
+ }
+
+ /**
+ * 批量逻辑删除公告栏
+ *
+ * @param bulletinIds 需要删除的公告栏主键
+ * @return 结果
+ */
+ @Transactional
+ @Override
+ public int deleteBulletinInfoByBulletinIds(String[] bulletinIds,String sts)
+ {
+ int iCount=0;
+ for (String bulletinId : bulletinIds) {
+ BulletinInfo bulletinInfo=new BulletinInfo();
+ bulletinInfo.setBulletinId(bulletinId);
+ bulletinInfo.setUpdateTime(DateUtils.getNowDate());
+ bulletinInfo.setUpdateUserId(SecurityUtils.getUserId());
+ bulletinInfo.setSts(sts);
+ iCount+=bulletinInfoMapper.updateBulletinInfo(bulletinInfo);
+ }
+ return iCount;
+ }
+
+ /**
+ * 逻辑删除公告栏信息
+ *
+ * @param bulletinId 公告栏主键
+ * @return 结果
+ */
+ @Transactional
+ @Override
+ public int deleteBulletinInfoByBulletinId(String bulletinId)
+ {
+ return deleteBulletinInfoByBulletinIds(new String[] {bulletinId},"B");
+ }
+
+ /**
+ * 新增公告接收者信息
+ *
+ * @param bulletinInfo 公告栏对象
+ */
+ public void insertBulletinRecive(BulletinInfo bulletinInfo)
+ {
+ List reciveUserIdList=bulletinInfo.getReceiveStaffIds();
+ String bulletinId = bulletinInfo.getBulletinId();
+ List reciveList=new ArrayList<>(reciveUserIdList.size());
+ Date now=DateUtils.getNowDate();
+ bulletinInfo.setBulletinReciveList(reciveList);
+ Long userId=SecurityUtils.getUserId();
+ for (Long reciveUserId : reciveUserIdList) {
+ BulletinRecive bulletinRecive=new BulletinRecive();
+ bulletinRecive.setBulletinId(bulletinId);
+ bulletinRecive.setCreateTime(now);
+ bulletinRecive.setCreateUserId(userId);
+ bulletinRecive.setUpdateTime(now);
+ bulletinRecive.setUpdateUserId(userId);
+ bulletinRecive.setReadNum(0L);
+ bulletinRecive.setSts("C");
+ bulletinRecive.setReciveUserId(reciveUserId);
+ bulletinRecive.setReciveId(IDUtil.getStrId());
+ reciveList.add(bulletinRecive);
+ }
+ if (reciveList.size() > 0)
+ {
+ bulletinInfoMapper.batchBulletinRecive(reciveList);
+ }
+ }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/BulletinReciveServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/BulletinReciveServiceImpl.java
new file mode 100644
index 00000000..5c12f3e9
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/BulletinReciveServiceImpl.java
@@ -0,0 +1,166 @@
+package com.ruoyi.system.service.impl;
+
+import java.util.Collections;
+import java.util.List;
+
+import com.ruoyi.cache.service.IOrgCacheService;
+import com.ruoyi.common.core.utils.DateUtils;
+import com.ruoyi.common.security.utils.SecurityUtils;
+
+import org.nutz.lang.util.NutMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.ruoyi.system.mapper.BulletinInfoMapper;
+import com.ruoyi.system.mapper.BulletinReciveMapper;
+import com.ruoyi.system.domain.BulletinInfo;
+import com.ruoyi.system.domain.BulletinRecive;
+import com.ruoyi.system.service.IBulletinReciveService;
+
+/**
+ * 公告接收者Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+@Service
+public class BulletinReciveServiceImpl implements IBulletinReciveService
+{
+ @Autowired
+ private BulletinReciveMapper bulletinReciveMapper;
+ @Autowired
+ private BulletinInfoMapper bulletinInfoMapper;
+ @Autowired
+ private IOrgCacheService orgCacheService;
+
+ @Transactional
+ /**
+ * 批量更新已阅读
+ * @param reciveIds
+ * @return
+ */
+ @Override
+ public int batchRead(String[] reciveIds) {
+ return bulletinReciveMapper.batchUpdateRead(reciveIds);
+ }
+ /**
+ * 查询公告接收者
+ *
+ * @param reciveId 公告接收者主键
+ * @return 公告接收者
+ */
+ @Override
+ public BulletinRecive selectBulletinReciveByReciveId(String reciveId)
+ {
+ return bulletinReciveMapper.selectBulletinReciveByReciveId(reciveId);
+ }
+
+ /**
+ * 查询公告接收者列表
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 公告接收者
+ */
+ @Override
+ public List selectBulletinReciveList(BulletinRecive bulletinRecive)
+ {
+ bulletinRecive.setReciveUserId(SecurityUtils.getUserId());
+ List reciveList= bulletinReciveMapper.selectBulletinReciveList(bulletinRecive);
+ if(reciveList.isEmpty()) {
+ return Collections.emptyList();
+ }
+ reciveList.forEach(recive->{
+ orgCacheService.getSysUser(recive.getReciveUserId()).ifPresent(cacheSysUser->{
+ recive.setCreateBy(cacheSysUser.getUserName());
+ recive.setReciveDeptId(cacheSysUser.getDeptId());
+ });
+ });
+ NutMap map=NutMap.NEW();
+ String[] bulletinIds=new String[reciveList.size()];
+ for (int i = 0; i < bulletinIds.length; i++) {
+ BulletinRecive recive=reciveList.get(i);
+ map.addv2(recive.getBulletinId(), recive);
+ bulletinIds[i]=recive.getBulletinId();
+ }
+ List infoList=bulletinInfoMapper.selectBulletinInfoListbyBulletinIds(bulletinIds);
+ infoList.forEach(info->{
+ info.setBulletinReciveList(map.getList(info.getBulletinId(), BulletinRecive.class,Collections.emptyList()));
+ });
+ return infoList;
+ }
+
+ /**
+ * 新增公告接收者
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 结果
+ */
+ @Override
+ public int insertBulletinRecive(BulletinRecive bulletinRecive)
+ {
+ bulletinRecive.setCreateTime(DateUtils.getNowDate());
+ return bulletinReciveMapper.insertBulletinRecive(bulletinRecive);
+ }
+
+ /**
+ * 修改公告接收者
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 结果
+ */
+ @Override
+ public int updateBulletinRecive(BulletinRecive bulletinRecive)
+ {
+ bulletinRecive.setUpdateTime(DateUtils.getNowDate());
+ bulletinRecive.setUpdateUserId(SecurityUtils.getUserId());
+ return bulletinReciveMapper.updateBulletinRecive(bulletinRecive);
+ }
+
+ /**
+ * 批量物理删除公告接收者
+ *
+ * @param reciveIds 需要删除的公告接收者主键
+ * @return 结果
+ */
+ @Override
+ public int deletePhysicalBulletinReciveByReciveIds(String[] reciveIds)
+ {
+ return bulletinReciveMapper.deleteBulletinReciveByReciveIds(reciveIds);
+ }
+
+
+ /**
+ * 批量逻辑删除公告接收者
+ *
+ * @param reciveIds 需要删除的公告接收者主键
+ * @return 结果
+ */
+ @Override
+ @Transactional
+ public int deleteBulletinReciveByReciveIds(String[] reciveIds)
+ {
+ int iCount=0;
+ for (String reciveId : reciveIds) {
+ BulletinRecive bulletinRecive=new BulletinRecive();
+ bulletinRecive.setReciveId(reciveId);
+ bulletinRecive.setSts("B");
+ bulletinRecive.setUpdateTime(DateUtils.getNowDate());
+ bulletinRecive.setUpdateUserId(SecurityUtils.getUserId());
+ iCount+=bulletinReciveMapper.updateBulletinRecive(bulletinRecive);
+ }
+ return iCount;
+ }
+
+ /**
+ * 删除公告接收者信息
+ *
+ * @param reciveId 公告接收者主键
+ * @return 结果
+ */
+ @Override
+ public int deleteBulletinReciveByReciveId(String reciveId)
+ {
+ return bulletinReciveMapper.deleteBulletinReciveByReciveId(reciveId);
+ }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrgCacheServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrgCacheServiceImpl.java
new file mode 100644
index 00000000..4ad9ea6e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrgCacheServiceImpl.java
@@ -0,0 +1,160 @@
+package com.ruoyi.system.service.impl;
+
+import java.util.Optional;
+
+import org.nutz.lang.util.NutMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Component;
+
+import com.ruoyi.cache.domain.CacheSysDept;
+import com.ruoyi.cache.domain.CacheSysUser;
+import com.ruoyi.cache.service.IOrgCacheService;
+import com.ruoyi.common.redis.service.RedisService;
+import com.ruoyi.system.api.domain.SysDept;
+import com.ruoyi.system.api.domain.SysUser;
+import com.ruoyi.system.mapper.SysDeptMapper;
+import com.ruoyi.system.mapper.SysUserMapper;
+import com.ruoyi.util.IDUtil;
+import com.ruoyi.util.IRedisNotifyHandle;
+import com.ruoyi.util.RedisNotifyService;
+@Component
+/**
+ * 处理组织架构的缓存
+ * @author condy
+ *
+ */
+public class OrgCacheServiceImpl implements IOrgCacheService,IRedisNotifyHandle {
+
+ @Autowired
+ private RedisService redisService;
+ @Autowired
+ private RedisNotifyService redisNotifyService;
+ @Autowired
+ private CacheManager cacheManager;
+ @Autowired
+ private SysDeptMapper sysDeptMapper;
+ @Autowired
+ private SysUserMapper sysUserMapper;
+
+ private final String USER_PRE="RUOYI_USER:";
+ private final String DEPT_PRE="RUOYI_DEPT:";
+
+ private long selfId=IDUtil.getId();
+ private Logger log=LoggerFactory.getLogger(getClass());
+ public OrgCacheServiceImpl() {
+ RedisNotifyService.register(this);
+ }
+
+ @Override
+ @CachePut(value="org",key="'RUOYI_USER:'+#cacheSysUser.getUserId()")
+ public CacheSysUser saveSysUser(CacheSysUser cacheSysUser) {
+ if(cacheSysUser==null || cacheSysUser.getUserId()==null) {
+ log.warn("保存员工到缓存错误, 员工ID是空的");
+ return null;
+ }
+ redisService.setCacheObject(USER_PRE+cacheSysUser.getUserId(), cacheSysUser);
+ NutMap params=NutMap.NEW().addv("type", "RUOYI_USER").addv("userId", cacheSysUser.getUserId());
+ params.addv("selfId", selfId);
+ redisNotifyService.publish(getRegisterId(), params);
+ return cacheSysUser;
+ }
+
+ @Override
+ @Cacheable(value="org",key="'RUOYI_USER:'+#userId")
+ public Optional getSysUser(long userId) {
+ CacheSysUser cacheSysUser=redisService.getCacheObject(USER_PRE+userId);
+ if(cacheSysUser==null) {
+ SysUser sysUser=sysUserMapper.selectUserById(userId);
+ if(sysUser!=null) {
+ cacheSysUser=new CacheSysUser(sysUser);
+ saveSysUser(cacheSysUser);
+ }
+ }
+ return Optional.ofNullable(cacheSysUser);
+ }
+
+ //除非,#result是空,就不缓存
+ @Override
+ @Cacheable(value="org",key="'RUOYI_DEPT:'+#deptId")
+ public Optional getDeptInfo(long deptId) {
+ CacheSysDept cacheSysDept=redisService.getCacheObject(DEPT_PRE+deptId);
+ if(cacheSysDept==null) {
+ SysDept sysDept=sysDeptMapper.selectDeptById(deptId);
+ if(sysDept!=null) {
+ cacheSysDept=new CacheSysDept(sysDept);
+ saveDeptInfo(cacheSysDept);
+ }
+ }
+ return Optional.ofNullable(cacheSysDept);
+ }
+
+ @Override
+ @CachePut(value="org",key="'RUOYI_DEPT:'+#cacheDeptInfo.getDeptId()")
+ public CacheSysDept saveDeptInfo(CacheSysDept cacheDeptInfo) {
+ if(cacheDeptInfo==null || cacheDeptInfo.getDeptId()==null) {
+ log.warn("保存部门到缓存错误, 部门ID是空的");
+ return null;
+ }
+ redisService.setCacheObject(DEPT_PRE+cacheDeptInfo.getDeptId(), cacheDeptInfo);
+ NutMap params=NutMap.NEW().addv("type", "RUOYI_DEPT").addv("deptId", cacheDeptInfo.getDeptId());
+ params.addv("selfId", selfId);
+ redisNotifyService.publish(getRegisterId(), params);
+ return cacheDeptInfo;
+ }
+
+ @Override
+ public void handle(String methodName,NutMap params) {
+ String type=params.getString("type");
+ long notifySelfId=params.getLong("selfId");
+ if(notifySelfId==selfId) {
+ log.info("selfId:{} 是自己发出的,不做任何处理");
+ return ;
+ }
+ if(USER_PRE.substring(0, USER_PRE.length()-1).equals(type)) {
+ log.info("把组织架构的staffId:{}的缓存作废",params.getLong("userId"));
+ cacheManager.getCache("org").evict(USER_PRE+params.getLong("userId"));
+ } else if (DEPT_PRE.substring(0, DEPT_PRE.length()-1).equals(type)) {
+ //把某个部门缓存作废.
+ log.info("把组织架构的deptId:{}的缓存作废",params.getLong("deptId"));
+ cacheManager.getCache("org").evict(DEPT_PRE+params.getLong("deptId"));
+ } else {
+ log.warn("无法识别的type:{}", type);
+ }
+ }
+
+ @Override
+ public String getRegisterId() {
+ return "OrgCacheService";
+ }
+
+ @Override
+ @CacheEvict(value="org",key="'RUOYI_USER:'+#userId")
+ public void deleteSysUser(Long userId) {
+ if(userId==null) {
+ return ;
+ }
+ redisService.deleteObject(USER_PRE+userId);
+ NutMap params=NutMap.NEW().addv("type", "RUOYI_USER").addv("userId", userId);
+ params.addv("selfId", selfId);
+ redisNotifyService.publish(getRegisterId(), params);
+ }
+
+ @Override
+ @CacheEvict(value="org",key="'RUOYI_DEPT:'+#deptId")
+ public void deleteDeptInfo(Long deptId) {
+ if(deptId==null) {
+ return ;
+ }
+ redisService.deleteObject(DEPT_PRE+deptId);
+ NutMap params=NutMap.NEW().addv("type", "RUOYI_DEPT").addv("deptId", deptId);
+ params.addv("selfId", selfId);
+ redisNotifyService.publish(getRegisterId(), params);
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
index 67161180..28ff668b 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
@@ -6,6 +6,9 @@ import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+
+import com.ruoyi.cache.domain.CacheSysDept;
+import com.ruoyi.cache.service.IOrgCacheService;
import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.text.Convert;
@@ -34,6 +37,8 @@ public class SysDeptServiceImpl implements ISysDeptService
@Autowired
private SysRoleMapper roleMapper;
+ @Autowired
+ private IOrgCacheService orgCacheService;
/**
* 查询部门管理数据
@@ -218,7 +223,12 @@ public class SysDeptServiceImpl implements ISysDeptService
throw new ServiceException("部门停用,不允许新增");
}
dept.setAncestors(info.getAncestors() + "," + dept.getParentId());
- return deptMapper.insertDept(dept);
+ int updateCount= deptMapper.insertDept(dept);
+ if(updateCount>0) {
+ CacheSysDept cacheDept=new CacheSysDept(dept);
+ orgCacheService.saveDeptInfo(cacheDept);
+ }
+ return updateCount;
}
/**
@@ -246,6 +256,10 @@ public class SysDeptServiceImpl implements ISysDeptService
// 如果该部门是启用状态,则启用该部门的所有上级部门
updateParentDeptStatusNormal(dept);
}
+ if(result>0) {
+ CacheSysDept cacheDept=new CacheSysDept(dept);
+ orgCacheService.saveDeptInfo(cacheDept);
+ }
return result;
}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/IDUtil.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/IDUtil.java
new file mode 100644
index 00000000..6ae20abf
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/IDUtil.java
@@ -0,0 +1,45 @@
+package com.ruoyi.util;
+
+import java.util.Random;
+
+/**
+ * 自动生成ID的工具类
+ * @author Condy
+ *
+ */
+public class IDUtil {
+ static private SnowflakeIdWorker id;
+ static {
+ Random random=new Random();
+ int workId=random.nextInt(32);
+ int datacenterId=random.nextInt(32);
+ id=new SnowflakeIdWorker(workId,datacenterId);
+ }
+ /**
+ * 获取18位的唯一主键
+ * @return
+ */
+ static public long getId(){
+ try {
+ return id.nextId();
+ }catch(RuntimeException e) {
+ //时间被调整回去了,可能是时间同步引起的
+ if(e.toString().contains("Clock moved backwards")) {
+ try {Thread.sleep(50);} catch (InterruptedException e1) {}
+ return id.nextId();
+ } else {
+ throw e;
+ }
+ }
+
+ }
+
+ /**
+ * 返回18位字符串的唯一ID
+ * @return
+ */
+ static public String getStrId(){
+ return id.nextId()+"";
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/IRedisNotifyHandle.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/IRedisNotifyHandle.java
new file mode 100644
index 00000000..874d6b7e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/IRedisNotifyHandle.java
@@ -0,0 +1,22 @@
+package com.ruoyi.util;
+
+import org.nutz.lang.util.NutMap;
+
+/**
+ * 接收到HttpServerRedis消息的处理类
+ * @author 林桦
+ *
+ */
+public interface IRedisNotifyHandle {
+ /**
+ * 处理json格式的消息
+ * @param jsonMessage
+ */
+ public void handle(String method,NutMap params);
+ /**
+ * 获取注册的ID,不同的ID之间不能重复.
+ * @return
+ */
+ public String getRegisterId();
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/ISpringLoadComplete.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/ISpringLoadComplete.java
new file mode 100644
index 00000000..3b358447
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/ISpringLoadComplete.java
@@ -0,0 +1,12 @@
+package com.ruoyi.util;
+
+import org.springframework.context.ApplicationContext;
+
+public interface ISpringLoadComplete {
+ /**
+ * 回调实现类
+ * @param applicationContext
+ */
+ void callback(ApplicationContext applicationContext);
+
+}
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/RedisNotifyService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/RedisNotifyService.java
new file mode 100644
index 00000000..9171debb
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/RedisNotifyService.java
@@ -0,0 +1,142 @@
+package com.ruoyi.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.nutz.json.Json;
+import org.nutz.lang.util.NutMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.data.redis.connection.Message;
+import org.springframework.data.redis.connection.MessageListener;
+import org.springframework.data.redis.listener.PatternTopic;
+import org.springframework.data.redis.listener.RedisMessageListenerContainer;
+import org.springframework.stereotype.Component;
+
+import com.ruoyi.common.redis.service.RedisService;
+
+
+/**
+ * 应用服务器监听从redis上发过来的消息,例如:重读服务的参数,以及一些命令.
+ * @author 林桦
+ *
+ */
+@Component
+public class RedisNotifyService implements MessageListener,ISpringLoadComplete {
+ private static Map registerMap=new HashMap();
+ private static Logger LOGGER=LoggerFactory.getLogger(RedisNotifyService.class);
+ public static final String CHANNEL="ruoyiMessageNotify";
+
+ private RedisService redisService;
+ public RedisNotifyService(RedisService redisService) {
+ this.redisService=redisService;
+ SpringLoadComplete.addCallBack(this);
+ }
+
+ /**
+ * 注册具体方法
+ * @param redisHandle
+ * @return
+ */
+ public static boolean register(IRedisNotifyHandle redisHandle){
+ if(registerMap.containsKey(redisHandle.getRegisterId())){
+ LOGGER.info("已经存在:"+redisHandle.getRegisterId()+",无法注册成功!");
+ return false;
+ }else{
+ LOGGER.info("注册ID:"+redisHandle.getRegisterId()+",注册成功,处理类:"+redisHandle.getClass());
+ registerMap.put(redisHandle.getRegisterId(), redisHandle);
+ return true;
+ }
+
+ }
+ /**
+ * 取消注册.
+ * @param redisHandle
+ * @return
+ */
+ public static boolean unRegister(IRedisNotifyHandle redisHandle){
+ return unRegister(redisHandle.getRegisterId());
+ }
+ /**
+ * 取消注册
+ * @param registerId
+ * @return
+ */
+ public static boolean unRegister(String registerId){
+ if(registerId==null)
+ return false;
+ if(registerMap.containsKey(registerId)){
+ LOGGER.info("注册ID:"+registerId+",取消注册成功!");
+ registerMap.remove(registerId);
+ return true;
+ } else{
+ return false;
+ }
+ }
+ /**
+ * 判断是否有注册
+ * @param registerId
+ * @return
+ */
+ public static boolean containRedisHandle(String registerId){
+ if(registerId==null)
+ return false;
+ return registerMap.containsKey(registerId);
+ }
+ /**
+ * 判断是否有注册.
+ * @param redisHandle
+ * @return
+ */
+ public static boolean containRedisHandle(IRedisNotifyHandle redisHandle){
+ return containRedisHandle(redisHandle.getRegisterId());
+ }
+ /**
+ * 发送JsonRpc
+ * @param method 方法名
+ * @param params params的参数
+ */
+ public void publish(String method,NutMap params) {
+ NutMap jsonRpc=NutMap.NEW().addv("method", method).addv("params", params);
+ redisService.redisTemplate.convertAndSend(CHANNEL,Json.toJson(jsonRpc) );
+ }
+
+
+ @Override
+ public void onMessage(Message message, byte[] pattern) {
+ /**
+ * Message的消息类型:{ "method": "sayHello", "params": ["Hello JSON-RPC"], "id": 1}
+ */
+ try {
+ NutMap jsonMessage=Json.fromJson(NutMap.class,new String(message.getBody(),"UTF-8"));
+ String registerId=jsonMessage.getString("method",null);
+ if(containRedisHandle(registerId)){
+ IRedisNotifyHandle redisHandle=registerMap.get(registerId);
+ if("casLogout".equals(registerId)) //签出的消息比多,更改为debug级别.
+ LOGGER.debug("recive httpServerRedis message:"+message+",submit to handle class:"+redisHandle.getClass());
+ else
+ LOGGER.info("recive httpServerRedis message:"+message+",submit to handle class:"+redisHandle.getClass());
+ NutMap params=Json.fromJson(NutMap.class,jsonMessage.getString("params","{}"));
+ redisHandle.handle(registerId,params);
+ } else{
+ if("casLogout".equals(registerId))
+ LOGGER.debug("recive httpServerRedis message:"+message+",but not find any handle class");
+ else
+ LOGGER.info("recive httpServerRedis message:"+message+",but not find any handle class");
+ }
+ } catch(Exception e) {
+ LOGGER.error("recive httpServerRedis handle error:"+message,e);
+ }
+
+ }
+
+ @Override
+ public void callback(ApplicationContext applicationContext) {
+ RedisMessageListenerContainer redisMessageListenerContainer=applicationContext.getBean(RedisMessageListenerContainer.class);
+ redisMessageListenerContainer.addMessageListener(this, new PatternTopic(CHANNEL));
+ LOGGER.info("启动监听redis,channel:"+CHANNEL);
+
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/SnowflakeIdWorker.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/SnowflakeIdWorker.java
new file mode 100644
index 00000000..30a29eb1
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/SnowflakeIdWorker.java
@@ -0,0 +1,146 @@
+package com.ruoyi.util;
+
+/**
+ * Twitter_Snowflake
+ * SnowFlake的结构如下(每部分用-分开):
+ * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
+ * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0
+ * 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)
+ * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69
+ * 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId
+ * 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号
+ * 加起来刚好64位,为一个Long型。
+ * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。
+ */
+public class SnowflakeIdWorker {
+
+ // ==============================Fields===========================================
+ /** 开始时间截 (2015-01-01) */
+ private final long twepoch = 1420041600000L;
+
+ /** 机器id所占的位数 */
+ private final long workerIdBits = 5L;
+
+ /** 数据标识id所占的位数 */
+ private final long datacenterIdBits = 5L;
+
+ /** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */
+ private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
+
+ /** 支持的最大数据标识id,结果是31 */
+ private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+
+ /** 序列在id中占的位数 */
+ private final long sequenceBits = 12L;
+
+ /** 机器ID向左移12位 */
+ private final long workerIdShift = sequenceBits;
+
+ /** 数据标识id向左移17位(12+5) */
+ private final long datacenterIdShift = sequenceBits + workerIdBits;
+
+ /** 时间截向左移22位(5+5+12) */
+ private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+
+ /** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */
+ private final long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+ /** 工作机器ID(0~31) */
+ private long workerId;
+
+ /** 数据中心ID(0~31) */
+ private long datacenterId;
+
+ /** 毫秒内序列(0~4095) */
+ private long sequence = 0L;
+
+ /** 上次生成ID的时间截 */
+ private long lastTimestamp = -1L;
+
+ //==============================Constructors=====================================
+ /**
+ * 构造函数
+ * @param workerId 工作ID (0~31)
+ * @param datacenterId 数据中心ID (0~31)
+ */
+ public SnowflakeIdWorker(long workerId, long datacenterId) {
+ if (workerId > maxWorkerId || workerId < 0) {
+ throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
+ }
+ if (datacenterId > maxDatacenterId || datacenterId < 0) {
+ throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+ }
+ this.workerId = workerId;
+ this.datacenterId = datacenterId;
+ }
+
+ // ==============================Methods==========================================
+ /**
+ * 获得下一个ID (该方法是线程安全的)
+ * @return SnowflakeId
+ */
+ public synchronized long nextId() {
+ long timestamp = timeGen();
+
+ //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
+ if (timestamp < lastTimestamp) {
+ throw new RuntimeException(
+ String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
+ }
+
+ //如果是同一时间生成的,则进行毫秒内序列
+ if (lastTimestamp == timestamp) {
+ sequence = (sequence + 1) & sequenceMask;
+ //毫秒内序列溢出
+ if (sequence == 0) {
+ //阻塞到下一个毫秒,获得新的时间戳
+ timestamp = tilNextMillis(lastTimestamp);
+ }
+ }
+ //时间戳改变,毫秒内序列重置
+ else {
+ sequence = 0L;
+ }
+
+ //上次生成ID的时间截
+ lastTimestamp = timestamp;
+
+ //移位并通过或运算拼到一起组成64位的ID
+ return ((timestamp - twepoch) << timestampLeftShift) //
+ | (datacenterId << datacenterIdShift) //
+ | (workerId << workerIdShift) //
+ | sequence;
+ }
+
+ /**
+ * 阻塞到下一个毫秒,直到获得新的时间戳
+ * @param lastTimestamp 上次生成ID的时间截
+ * @return 当前时间戳
+ */
+ protected long tilNextMillis(long lastTimestamp) {
+ long timestamp = timeGen();
+ while (timestamp <= lastTimestamp) {
+ timestamp = timeGen();
+ }
+ return timestamp;
+ }
+
+ /**
+ * 返回以毫秒为单位的当前时间
+ * @return 当前时间(毫秒)
+ */
+ protected long timeGen() {
+ return System.currentTimeMillis();
+ }
+
+ //==============================Test=============================================
+ /** 测试 */
+ public static void main(String[] args) {
+ SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0);
+ for (int i = 0; i < 1000; i++) {
+ long id = idWorker.nextId();
+ System.out.println(Long.toBinaryString(id));
+ System.out.println(id);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/SpringLoadComplete.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/SpringLoadComplete.java
new file mode 100644
index 00000000..e8b01492
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/util/SpringLoadComplete.java
@@ -0,0 +1,45 @@
+package com.ruoyi.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.stereotype.Component;
+
+@Component
+/**
+ * spring启动完成,调用回调类
+ * @author condy
+ *
+ */
+public class SpringLoadComplete implements ApplicationListener{
+
+ private static List callbackList=new ArrayList<>();
+ private Logger log=LoggerFactory.getLogger(SpringLoadComplete.class);
+ /**
+ * 将回调方法加入到回调队列
+ * @param callback
+ */
+ public static void addCallBack(ISpringLoadComplete callback) {
+ if(!callbackList.contains(callback))
+ callbackList.add(callback);
+ }
+ @Override
+ public void onApplicationEvent(ContextRefreshedEvent event) {
+ if(event.getApplicationContext().getParent() == null){
+ try {
+ for (ISpringLoadComplete callback : callbackList) {
+ log.info("Spring启动完成,调用回调处理类:{}",callback);
+ callback.callback(event.getApplicationContext());
+ }
+ } catch(Exception e) {
+ log.error("初始化回调方法错误",e);
+ }
+ }
+
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/ehcache.xml b/ruoyi-modules/ruoyi-system/src/main/resources/ehcache.xml
new file mode 100644
index 00000000..9842a844
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/ehcache.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/logback.xml b/ruoyi-modules/ruoyi-system/src/main/resources/logback.xml
index 96bc0bbe..4e8f564c 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/logback.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/logback.xml
@@ -3,7 +3,10 @@
-
+
+
@@ -11,6 +14,29 @@
${log.pattern}
+
+
+
+ ${log.path}/debug.log
+
+
+
+ ${log.path}/debug.%d{yyyy-MM-dd}.log
+
+ 4
+
+
+ ${log.pattern}
+
+
+
+ DEBUG
+
+ ACCEPT
+
+ DENY
+
+
@@ -61,14 +87,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/BulletinInfoMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/BulletinInfoMapper.xml
new file mode 100644
index 00000000..e70c6be2
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/BulletinInfoMapper.xml
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ select BULLETIN_ID, TITLE, CONTENT, CREATE_TIME, READ_NUM, SEND_TIME, CREATE_USER_ID, UPDATE_USER_ID, UPDATE_TIME, REMARK, STS from t_bulletin_info
+
+
+
+
+
+
+
+
+
+
+
+ insert into t_bulletin_info
+
+ BULLETIN_ID,
+ TITLE,
+ CONTENT,
+ CREATE_TIME,
+ READ_NUM,
+ SEND_TIME,
+ CREATE_USER_ID,
+ UPDATE_USER_ID,
+ UPDATE_TIME,
+ REMARK,
+ STS,
+
+
+ #{bulletinId},
+ #{title},
+ #{content},
+ #{createTime},
+ #{readNum},
+ #{sendTime},
+ #{createUserId},
+ #{updateUserId},
+ #{updateTime},
+ #{remark},
+ #{sts},
+
+
+
+
+ update t_bulletin_info
+
+ TITLE = #{title},
+ CONTENT = #{content},
+ CREATE_TIME = #{createTime},
+ READ_NUM = #{readNum},
+ SEND_TIME = #{sendTime},
+ CREATE_USER_ID = #{createUserId},
+ UPDATE_USER_ID = #{updateUserId},
+ UPDATE_TIME = #{updateTime},
+ REMARK = #{remark},
+ STS = #{sts},
+
+ where BULLETIN_ID = #{bulletinId}
+
+
+
+ delete from t_bulletin_info where BULLETIN_ID = #{bulletinId}
+
+
+
+ delete from t_bulletin_info where BULLETIN_ID in
+
+ #{bulletinId}
+
+
+
+
+ delete from t_bulletin_recive where BULLETIN_ID in
+
+ #{bulletinId}
+
+
+
+
+ delete from t_bulletin_recive where BULLETIN_ID = #{bulletinId}
+
+
+
+ insert into t_bulletin_recive( RECIVE_ID, RECIVE_USER_ID, READ_TIME, READ_NUM, CREATE_TIME, CREATE_USER_ID, UPDATE_USER_ID, UPDATE_TIME, REMARK, BULLETIN_ID, STS) values
+
+ ( #{item.reciveId}, #{item.reciveUserId}, #{item.readTime}, #{item.readNum}, #{item.createTime}, #{item.createUserId}, #{item.updateUserId}, #{item.updateTime}, #{item.remark}, #{item.bulletinId}, #{item.sts})
+
+
+
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/BulletinReciveMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/BulletinReciveMapper.xml
new file mode 100644
index 00000000..4c697327
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/BulletinReciveMapper.xml
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ select RECIVE_ID, RECIVE_USER_ID, READ_TIME, READ_NUM, CREATE_TIME, CREATE_USER_ID, UPDATE_USER_ID, UPDATE_TIME, REMARK, BULLETIN_ID, STS from t_bulletin_recive
+
+
+
+
+
+
+
+
+
+ insert into t_bulletin_recive
+
+ RECIVE_ID,
+ RECIVE_USER_ID,
+ READ_TIME,
+ READ_NUM,
+ CREATE_TIME,
+ CREATE_USER_ID,
+ UPDATE_USER_ID,
+ UPDATE_TIME,
+ REMARK,
+ BULLETIN_ID,
+ STS,
+
+
+ #{reciveId},
+ #{reciveUserId},
+ #{readTime},
+ #{readNum},
+ #{createTime},
+ #{createUserId},
+ #{updateUserId},
+ #{updateTime},
+ #{remark},
+ #{bulletinId},
+ #{sts},
+
+
+
+
+ update t_bulletin_recive
+
+ RECIVE_USER_ID = #{reciveUserId},
+ READ_TIME = #{readTime},
+ READ_NUM = #{readNum},
+ CREATE_TIME = #{createTime},
+ CREATE_USER_ID = #{createUserId},
+ UPDATE_USER_ID = #{updateUserId},
+ UPDATE_TIME = #{updateTime},
+ REMARK = #{remark},
+ BULLETIN_ID = #{bulletinId},
+ STS = #{sts},
+
+ where RECIVE_ID = #{reciveId}
+
+
+
+ update t_bulletin_recive set
+ READ_TIME = sysdate() ,
+ READ_NUM = READ_NUM+1,
+ sts ='A',
+ UPDATE_TIME=sysdate(),
+ UPDATE_USER_ID = RECIVE_USER_ID
+ where RECIVE_ID in
+
+ #{reciveId}
+
+
+
+
+ delete from t_bulletin_recive where RECIVE_ID = #{reciveId}
+
+
+
+ delete from t_bulletin_recive where RECIVE_ID in
+
+ #{reciveId}
+
+
+
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-system/src/test/java/com/ruoyi/system/service/CacheCallBackPojo.java b/ruoyi-modules/ruoyi-system/src/test/java/com/ruoyi/system/service/CacheCallBackPojo.java
new file mode 100644
index 00000000..a6008cb2
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/test/java/com/ruoyi/system/service/CacheCallBackPojo.java
@@ -0,0 +1,56 @@
+package com.ruoyi.system.service;
+
+import com.ruoyi.cache.annotation.OrgCacheKey;
+import com.ruoyi.cache.annotation.OrgCacheTypeNum;
+import com.ruoyi.cache.annotation.OrgCacheValue;
+import com.ruoyi.cache.domain.CacheSysUser;
+
+public class CacheCallBackPojo {
+ @OrgCacheKey
+ private Long userId;
+ @OrgCacheValue(value = CacheSysUser.ANNOTAION_DEPT_ID)
+ private Long deptId;
+ @OrgCacheValue(value = CacheSysUser.ANNOTAION_USER_NAME)
+ private String userName;
+ @OrgCacheValue(value = CacheSysUser.ANNOTAION_PHONENUMBER)
+ private String phoneNumber;
+ private String detpName;
+ public Long getUserId() {
+ return userId;
+ }
+ public void setUserId(Long userId) {
+ this.userId = userId;
+ }
+ public Long getDeptId() {
+ return deptId;
+ }
+ public void setDeptId(Long deptId) {
+ this.deptId = deptId;
+ }
+ public String getUserName() {
+ return userName;
+ }
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+ public String getPhoneNumber() {
+ return phoneNumber;
+ }
+ public void setPhoneNumber(String phoneNumber) {
+ this.phoneNumber = phoneNumber;
+ }
+ public String getDetpName() {
+ return detpName;
+ }
+ public void setDetpName(String detpName) {
+ this.detpName = detpName;
+ }
+ @Override
+ public String toString() {
+ return "CacheCallBackPojo [userId=" + userId + ", deptId=" + deptId + ", userName=" + userName
+ + ", phoneNumber=" + phoneNumber + ", detpName=" + detpName + "]";
+ }
+
+
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/test/java/com/ruoyi/system/service/CacheCallBackPojo2.java b/ruoyi-modules/ruoyi-system/src/test/java/com/ruoyi/system/service/CacheCallBackPojo2.java
new file mode 100644
index 00000000..b878ce43
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/test/java/com/ruoyi/system/service/CacheCallBackPojo2.java
@@ -0,0 +1,59 @@
+package com.ruoyi.system.service;
+
+import com.ruoyi.cache.annotation.OrgCacheKey;
+import com.ruoyi.cache.annotation.OrgCacheTypeNum;
+import com.ruoyi.cache.annotation.OrgCacheValue;
+import com.ruoyi.cache.domain.CacheSysDept;
+import com.ruoyi.cache.domain.CacheSysUser;
+
+public class CacheCallBackPojo2 {
+ @OrgCacheKey(id = "user",type = OrgCacheTypeNum.CacheUserInfo)
+ private Long userId;
+ @OrgCacheValue(value = CacheSysUser.ANNOTAION_DEPT_ID)
+ @OrgCacheKey(id = "dept",type = OrgCacheTypeNum.CacheDeptInfo)
+ private Long deptId;
+ @OrgCacheValue(value = CacheSysUser.ANNOTAION_USER_NAME)
+ private String userName;
+ @OrgCacheValue(value = CacheSysUser.ANNOTAION_PHONENUMBER)
+ private String phoneNumber;
+ @OrgCacheValue(id="dept",value = CacheSysDept.ANNOTAION_DEPT_NAME)
+ private String detpName;
+ public Long getUserId() {
+ return userId;
+ }
+ public void setUserId(Long userId) {
+ this.userId = userId;
+ }
+ public Long getDeptId() {
+ return deptId;
+ }
+ public void setDeptId(Long deptId) {
+ this.deptId = deptId;
+ }
+ public String getUserName() {
+ return userName;
+ }
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+ public String getPhoneNumber() {
+ return phoneNumber;
+ }
+ public void setPhoneNumber(String phoneNumber) {
+ this.phoneNumber = phoneNumber;
+ }
+ public String getDetpName() {
+ return detpName;
+ }
+ public void setDetpName(String detpName) {
+ this.detpName = detpName;
+ }
+ @Override
+ public String toString() {
+ return "CacheCallBackPojo [userId=" + userId + ", deptId=" + deptId + ", userName=" + userName
+ + ", phoneNumber=" + phoneNumber + ", detpName=" + detpName + "]";
+ }
+
+
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/test/java/com/ruoyi/system/service/CacheCallBackTest.java b/ruoyi-modules/ruoyi-system/src/test/java/com/ruoyi/system/service/CacheCallBackTest.java
new file mode 100644
index 00000000..f1f1c746
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/test/java/com/ruoyi/system/service/CacheCallBackTest.java
@@ -0,0 +1,36 @@
+package com.ruoyi.system.service;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+import org.nutz.lang.Lang;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import com.ruoyi.cache.service.CacheCallBack;
+import com.ruoyi.cache.service.IOrgCacheService;
+@SpringBootTest
+class CacheCallBackTest {
+
+ @Autowired
+ private IOrgCacheService orgCacheService;
+ @Test
+ void testInvoke() {
+ CacheCallBackPojo pojo=new CacheCallBackPojo();
+ pojo.setUserId(1L);
+ Lang.each(Lang.list(pojo), new CacheCallBack<>());
+ assertNotNull(pojo.getUserName());
+ System.out.println(pojo.toString());
+ }
+
+ @Test
+ void testInvoke2() {
+ CacheCallBackPojo2 pojo=new CacheCallBackPojo2();
+ pojo.setUserId(1L);
+ pojo.setDeptId(103L);
+ Lang.each(Lang.list(pojo), new CacheCallBack<>());
+ assertNotNull(pojo.getUserName());
+ System.out.println(pojo.toString());
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/test/java/com/ruoyi/system/service/impl/BulletinInfoServiceImplTest.java b/ruoyi-modules/ruoyi-system/src/test/java/com/ruoyi/system/service/impl/BulletinInfoServiceImplTest.java
new file mode 100644
index 00000000..2799fe91
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/test/java/com/ruoyi/system/service/impl/BulletinInfoServiceImplTest.java
@@ -0,0 +1,35 @@
+package com.ruoyi.system.service.impl;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.List;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import com.ruoyi.common.core.constant.SecurityConstants;
+import com.ruoyi.common.core.context.SecurityContextHolder;
+import com.ruoyi.system.domain.BulletinInfo;
+import com.ruoyi.system.service.IBulletinInfoService;
+@SpringBootTest
+class BulletinInfoServiceImplTest {
+
+ @Autowired
+ private IBulletinInfoService bulletinInfoService;
+ @BeforeEach
+ void setUser() {
+ SecurityContextHolder.set(SecurityConstants.DETAILS_USER_ID, 1);
+
+ }
+ @Test
+ void testSelectBulletinInfoList() {
+ BulletinInfo bulletinInfo=new BulletinInfo();
+ bulletinInfo.setSts("C");
+ List list=bulletinInfoService.selectBulletinInfoList(bulletinInfo);
+ assertTrue(list.size()>0);
+ System.out.println("aaaaaaaaaaaaaaaa:"+list.get(0).getCreateUserId()+"="+list.get(0).getCreateBy());
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/test/resources/bootstrap.yml b/ruoyi-modules/ruoyi-system/src/test/resources/bootstrap.yml
new file mode 100644
index 00000000..32364a97
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/test/resources/bootstrap.yml
@@ -0,0 +1,25 @@
+# Tomcat
+server:
+ port: 9201
+
+# Spring
+spring:
+ application:
+ # 应用名称
+ name: ruoyi-system
+ profiles:
+ # 环境配置
+ active: dev
+ cloud:
+ nacos:
+ discovery:
+ # 服务注册地址
+ server-addr: 192.168.0.17:8848
+ config:
+ # 配置中心地址
+ server-addr: 192.168.0.17:8848
+ # 配置文件格式
+ file-extension: yml
+ # 共享配置
+ shared-configs:
+ - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}