Merge remote-tracking branch 'origin' into macode20240818

This commit is contained in:
sxu 2024-08-19 10:54:45 +08:00
commit 14bd9d1642
10 changed files with 469 additions and 11 deletions

View File

@ -67,11 +67,32 @@ public class SysDept extends BaseEntity
/** 子部门 */ /** 子部门 */
@ApiModelProperty(value = "子部门") @ApiModelProperty(value = "子部门")
private List<SysDept> children = new ArrayList<SysDept>(); private List<SysDept> children = new ArrayList<>();
/** 备注信息 */ /** 备注信息 */
private String remark; private String remark;
/** 所属组织id */
private Long companyId;
@Override
public String getRemark() {
return remark;
}
@Override
public void setRemark(String remark) {
this.remark = remark;
}
public Long getCompanyId() {
return companyId;
}
public void setCompanyId(Long companyId) {
this.companyId = companyId;
}
public Long getDeptId() public Long getDeptId()
{ {
return deptId; return deptId;
@ -215,6 +236,7 @@ public class SysDept extends BaseEntity
.append("createTime", getCreateTime()) .append("createTime", getCreateTime())
.append("updateBy", getUpdateBy()) .append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime()) .append("updateTime", getUpdateTime())
.append("companyId", getCompanyId())
.append("remark", getRemark()) .append("remark", getRemark())
.toString(); .toString();
} }

View File

@ -78,6 +78,17 @@ public class SysRole extends BaseEntity
/** 数据所属组织 */ /** 数据所属组织 */
private String deptName; private String deptName;
/** 所属组织id */
private Long companyId;
public Long getCompanyId() {
return companyId;
}
public void setCompanyId(Long companyId) {
this.companyId = companyId;
}
public SysRole() public SysRole()
{ {
@ -259,6 +270,7 @@ public class SysRole extends BaseEntity
.append("updateTime", getUpdateTime()) .append("updateTime", getUpdateTime())
.append("remark", getRemark()) .append("remark", getRemark())
.append("deptName", getDeptName()) .append("deptName", getDeptName())
.append("companyId", getCompanyId())
.toString(); .toString();
} }
} }

View File

@ -0,0 +1,28 @@
package com.bonus.sgzb.common.core.exception;
import com.bonus.sgzb.common.core.utils.HttpCodeEnum;
public class BusinessException extends RuntimeException {
private int code;
//使用枚举构造
public BusinessException(HttpCodeEnum httpCodeEnum){
super(httpCodeEnum.getMsg());
this.code=httpCodeEnum.getCode();
}
//使用自定义消息体
public BusinessException(HttpCodeEnum httpCodeEnum, String msg){
super(msg);
this.code=httpCodeEnum.getCode();
}
//根据异常构造
public BusinessException(HttpCodeEnum httpCodeEnum, Throwable msg){
super(msg);
this.code=httpCodeEnum.getCode();
}
}

View File

@ -0,0 +1,38 @@
package com.bonus.sgzb.common.core.utils;
public enum HttpCodeEnum {
// 成功
SUCCESS(200, "操作成功"),
// 登录
NEED_LOGIN(401, "需要登录后操作"),
NO_OPERATOR_AUTH(403, "无权限操作"),
SYSTEM_ERROR(500, "出现错误"),
USERNAME_EXIST(501, "用户名已存在"),
PHONENUMBER_EXIST(502, "手机号已存在"),
EMAIL_EXIST(503, "邮箱已存在"),
REQUIRE_USERNAME(504, "必需填写用户名"),
CONTENT_NOT_NULL(506, "评论内容不能为空"),
FILE_TYPE_ERROR(507, "文件类型错误"),
USERNAME_NOT_NULL(508, "用户名不能为空"),
NICKNAME_NOT_NULL(509, "昵称不能为空"),
PASSWORD_NOT_NULL(510, "密码不能为空"),
EMAIL_NOT_NULL(511, "邮箱不能为空"),
NICKNAME_EXIST(512, "昵称已存在"),
LOGIN_ERROR(505, "用户名或密码错误"),
REPEATE_ERROR(600, "不允许重复提交,请稍候再试");
int code;
String msg;
HttpCodeEnum(int code, String errorMessage) {
this.code = code;
this.msg = errorMessage;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
}

View File

@ -0,0 +1,24 @@
package com.bonus.sgzb.common.security.annotation;
import java.lang.annotation.*;
/**
* 自定义注解防止表单重复提交
*
*/
@Inherited
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PreventRepeatSubmit
{
/**
* 间隔时间(s)小于此时间视为重复提交
*/
public int interval() default 3;
/**
* 提示消息
*/
public String message() default "不允许重复提交,请稍候再试";
}

View File

@ -0,0 +1,71 @@
package com.bonus.sgzb.common.security.aspect;
import com.alibaba.fastjson2.JSON;
import com.bonus.sgzb.common.core.exception.BusinessException;
import com.bonus.sgzb.common.core.utils.HttpCodeEnum;
import com.bonus.sgzb.common.security.annotation.PreventRepeatSubmit;
import com.bonus.sgzb.common.security.utils.RedisCache;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
@Aspect
@Component
public class PreventRepeatSubmitAspect {
private static final Logger LOG = LoggerFactory.getLogger(PreventRepeatSubmitAspect.class);
private static final String header = "Authorization";
@Autowired
private RedisCache redisCache;
// 定义一个切入点
@Pointcut("@annotation(com.bonus.sgzb.common.security.annotation.PreventRepeatSubmit)")
public void preventRepeatSubmit() {
}
@Around("preventRepeatSubmit()")
public Object checkPrs(ProceedingJoinPoint pjp) throws Throwable {
LOG.info("进入preventRepeatSubmit切面");
//得到request对象
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String requestURI = request.getRequestURI();
LOG.info("防重复提交的请求地址:{} ,请求方式:{}",requestURI,request.getMethod());
LOG.info("防重复提交拦截到的类名:{} ,方法:{}",pjp.getTarget().getClass().getSimpleName(),pjp.getSignature().getName());
//获取请求参数
Object[] args = pjp.getArgs();
String argStr = JSON.toJSONString(args);
//这里替换是为了在redis可视化工具中方便查看
argStr=argStr.replace(":","#");
// 唯一值没有消息头则使用请求地址
String submitKey = request.getHeader(header).trim();
// 唯一标识指定key + url +参数+token
String cacheRepeatKey = "repeat_submit:" + requestURI+":" +argStr+":"+ submitKey;
MethodSignature ms = (MethodSignature) pjp.getSignature();
Method method=ms.getMethod();
PreventRepeatSubmit preventRepeatSubmit=method.getAnnotation(PreventRepeatSubmit.class);
int interval = preventRepeatSubmit.interval();
LOG.info("获取到preventRepeatSubmit的有效期时间"+interval);
//redis分布式锁
Boolean aBoolean = redisCache.setNxCacheObject(cacheRepeatKey, 1, preventRepeatSubmit.interval(), TimeUnit.SECONDS);
//aBoolean为true则证明没有重复提交
if(!aBoolean){
throw new BusinessException(HttpCodeEnum.REPEATE_ERROR);
}
return pjp.proceed();
}
}

View File

@ -0,0 +1,269 @@
package com.bonus.sgzb.common.security.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* spring redis 工具类
*
**/
@Component
public class RedisCache
{
@Autowired
public RedisTemplate redisTemplate;
//添加分布式锁
public <T> Boolean setNxCacheObject(final String key, final T value,long lt,TimeUnit tu)
{
return redisTemplate.opsForValue().setIfAbsent(key,value,lt,tu);
}
/**
* 缓存基本的对象IntegerString实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
*/
public <T> void setCacheObject(final String key, final T value)
{
redisTemplate.opsForValue().set(key, value);
}
/**
* 缓存基本的对象IntegerString实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
* @param timeout 时间
* @param timeUnit 时间颗粒度
*/
public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit)
{
redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
}
/**
* 设置有效时间
*
* @param key Redis键
* @param timeout 超时时间
* @return true=设置成功false=设置失败
*/
public boolean expire(final String key, final long timeout)
{
return expire(key, timeout, TimeUnit.SECONDS);
}
/**
* 设置有效时间
*
* @param key Redis键
* @param timeout 超时时间
* @param unit 时间单位
* @return true=设置成功false=设置失败
*/
public boolean expire(final String key, final long timeout, final TimeUnit unit)
{
return redisTemplate.expire(key, timeout, unit);
}
/**
* 获取有效时间
*
* @param key Redis键
* @return 有效时间
*/
public long getExpire(final String key)
{
return redisTemplate.getExpire(key);
}
/**
* 判断 key是否存在
*
* @param key
* @return true 存在 false不存在
*/
public Boolean hasKey(String key)
{
return redisTemplate.hasKey(key);
}
/**
* 获得缓存的基本对象
*
* @param key 缓存键值
* @return 缓存键值对应的数据
*/
public <T> T getCacheObject(final String key)
{
ValueOperations<String, T> operation = redisTemplate.opsForValue();
return operation.get(key);
}
/**
* 删除单个对象
*
* @param key
*/
public boolean deleteObject(final String key)
{
return redisTemplate.delete(key);
}
/**
* 删除集合对象
*
* @param collection 多个对象
* @return
*/
public boolean deleteObject(final Collection collection)
{
return redisTemplate.delete(collection) > 0;
}
/**
* 缓存List数据
*
* @param key 缓存的键值
* @param dataList 待缓存的List数据
* @return 缓存的对象
*/
public <T> long setCacheList(final String key, final List<T> dataList)
{
Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
return count == null ? 0 : count;
}
/**
* 获得缓存的list对象
*
* @param key 缓存的键值
* @return 缓存键值对应的数据
*/
public <T> List<T> getCacheList(final String key)
{
return redisTemplate.opsForList().range(key, 0, -1);
}
/**
* 缓存Set
*
* @param key 缓存键值
* @param dataSet 缓存的数据
* @return 缓存数据的对象
*/
public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet)
{
BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
Iterator<T> it = dataSet.iterator();
while (it.hasNext())
{
setOperation.add(it.next());
}
return setOperation;
}
/**
* 获得缓存的set
*
* @param key
* @return
*/
public <T> Set<T> getCacheSet(final String key)
{
return redisTemplate.opsForSet().members(key);
}
/**
* 缓存Map
*
* @param key
* @param dataMap
*/
public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
{
if (dataMap != null) {
redisTemplate.opsForHash().putAll(key, dataMap);
}
}
/**
* 获得缓存的Map
*
* @param key
* @return
*/
public <T> Map<String, T> getCacheMap(final String key)
{
return redisTemplate.opsForHash().entries(key);
}
/**
* 往Hash中存入数据
*
* @param key Redis键
* @param hKey Hash键
* @param value
*/
public <T> void setCacheMapValue(final String key, final String hKey, final T value)
{
redisTemplate.opsForHash().put(key, hKey, value);
}
/**
* 获取Hash中的数据
*
* @param key Redis键
* @param hKey Hash键
* @return Hash中的对象
*/
public <T> T getCacheMapValue(final String key, final String hKey)
{
HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
return opsForHash.get(key, hKey);
}
/**
* 获取多个Hash中的数据
*
* @param key Redis键
* @param hKeys Hash键集合
* @return Hash对象集合
*/
public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
{
return redisTemplate.opsForHash().multiGet(key, hKeys);
}
/**
* 删除Hash中的某条数据
*
* @param key Redis键
* @param hKey Hash键
* @return 是否成功
*/
public boolean deleteCacheMapValue(final String key, final String hKey)
{
return redisTemplate.opsForHash().delete(key, hKey) > 0;
}
/**
* 获得缓存的基本对象列表
*
* @param pattern 字符串前缀
* @return 对象列表
*/
public Collection<String> keys(final String pattern)
{
return redisTemplate.keys(pattern);
}
}

View File

@ -1,23 +1,17 @@
package com.bonus.sgzb.material.controller; package com.bonus.sgzb.material.controller;
import com.bonus.sgzb.common.core.utils.poi.ExcelUtil;
import com.bonus.sgzb.common.core.web.controller.BaseController; import com.bonus.sgzb.common.core.web.controller.BaseController;
import com.bonus.sgzb.common.core.web.domain.AjaxResult; import com.bonus.sgzb.common.core.web.domain.AjaxResult;
import com.bonus.sgzb.common.core.web.page.TableDataInfo; import com.bonus.sgzb.common.core.web.page.TableDataInfo;
import com.bonus.sgzb.common.log.annotation.Log; import com.bonus.sgzb.common.security.annotation.PreventRepeatSubmit;
import com.bonus.sgzb.common.log.enums.BusinessType;
import com.bonus.sgzb.material.domain.AgreementInfo;
import com.bonus.sgzb.material.domain.ToDoBean; import com.bonus.sgzb.material.domain.ToDoBean;
import com.bonus.sgzb.material.service.AgreementInfoService;
import com.bonus.sgzb.material.service.ToDoService; import com.bonus.sgzb.material.service.ToDoService;
import com.bonus.sgzb.material.vo.NoticeInfoVO; import com.bonus.sgzb.material.vo.NoticeInfoVO;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List; import java.util.List;
/** /**
@ -45,6 +39,7 @@ public class ToDoController extends BaseController {
} }
@ApiOperation(value = "代办事件下拉") @ApiOperation(value = "代办事件下拉")
@PreventRepeatSubmit
@PostMapping("/getTaskType") @PostMapping("/getTaskType")
public AjaxResult getTaskType(ToDoBean bean){ public AjaxResult getTaskType(ToDoBean bean){
return toDoService.getTaskType(bean); return toDoService.getTaskType(bean);

View File

@ -36,7 +36,7 @@ public class SysNoticeController extends BaseController
/** /**
* 获取通知公告列表 * 获取通知公告列表
*/ */
@RequiresPermissions("system:notice:list") //@RequiresPermissions("system:notice:list")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(SysNotice notice) public TableDataInfo list(SysNotice notice)
{ {
@ -48,7 +48,7 @@ public class SysNoticeController extends BaseController
/** /**
* 根据通知公告编号获取详细信息 * 根据通知公告编号获取详细信息
*/ */
@RequiresPermissions("system:notice:query") //@RequiresPermissions("system:notice:query")
@GetMapping(value = "/{noticeId}") @GetMapping(value = "/{noticeId}")
public AjaxResult getInfo(@PathVariable Long noticeId) public AjaxResult getInfo(@PathVariable Long noticeId)
{ {

View File

@ -4,7 +4,6 @@ import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.util.Arrays; import java.util.Arrays;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import com.bonus.sgzb.common.core.constant.Constants; import com.bonus.sgzb.common.core.constant.Constants;
import com.bonus.sgzb.common.core.domain.R; import com.bonus.sgzb.common.core.domain.R;