修复了添加项目组成员时可以添加root的问题,不会直接处理已存在成员的问题,可以更新不存在成员的问题;更改了下载导入模板的接口,登入banIP的存储方式,get公告时的返回参数;在跨域拦截器中添加了测试用代码
parent
056a5ee8f7
commit
f5d8a436de
|
@ -6,6 +6,7 @@ import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
@ -36,4 +37,11 @@ public class RedisConfig {
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public StringRedisTemplate stringRedisTemplate() {
|
||||||
|
StringRedisTemplate template = new StringRedisTemplate();
|
||||||
|
template.setConnectionFactory(factory);
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package cn.edu.hfut.rmdjzz.projectmanagement.config;
|
package cn.edu.hfut.rmdjzz.projectmanagement.config;
|
||||||
|
|
||||||
|
import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.IPAddress;
|
||||||
import com.fasterxml.jackson.core.JsonGenerator;
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
import com.fasterxml.jackson.core.JsonParser;
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
import com.fasterxml.jackson.databind.*;
|
import com.fasterxml.jackson.databind.*;
|
||||||
|
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -25,11 +27,32 @@ public class SerializeConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public ObjectMapper objectMapper() {
|
public ObjectMapper objectMapper() {
|
||||||
|
|
||||||
ObjectMapper om = new ObjectMapper();
|
ObjectMapper om = new ObjectMapper();
|
||||||
|
om.registerModule(javaTimeModule());
|
||||||
|
om.registerModule(customClassModule());
|
||||||
|
return om;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"Convert2Diamond", "NullableProblems", "rawtypes"})
|
||||||
|
@Bean
|
||||||
|
public Converter<String, Map> mapConverter() {
|
||||||
|
return new Converter<String, Map>() {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
@Override
|
||||||
|
public Map convert(String source) {
|
||||||
|
return objectMapper.readValue(source, Map.class);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private JavaTimeModule javaTimeModule() {
|
||||||
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
||||||
|
|
||||||
//LocalDataTime
|
//LocalDateTime
|
||||||
javaTimeModule.addSerializer(LocalDateTime.class, new JsonSerializer<>() {
|
javaTimeModule.addSerializer(LocalDateTime.class, new JsonSerializer<>() {
|
||||||
@Override
|
@Override
|
||||||
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||||
|
@ -77,24 +100,27 @@ public class SerializeConfig {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
om.registerModule(javaTimeModule);
|
return javaTimeModule;
|
||||||
return om;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"Convert2Diamond", "NullableProblems", "rawtypes"})
|
//TODO: Redis可能改成tostringSerializer
|
||||||
@Bean
|
private SimpleModule customClassModule() {
|
||||||
public Converter<String, Map> mapConverter() {
|
SimpleModule customClassModule = new SimpleModule("CustomClassModule");
|
||||||
return new Converter<String, Map>() {
|
customClassModule.addSerializer(IPAddress.class, new JsonSerializer<>() {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ObjectMapper objectMapper;
|
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
@Override
|
@Override
|
||||||
public Map convert(String source) {
|
public void serialize(IPAddress value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||||
return objectMapper.readValue(source, Map.class);
|
if (value != null) {
|
||||||
|
gen.writeString(value.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
customClassModule.addDeserializer(IPAddress.class, new JsonDeserializer<>() {
|
||||||
|
@Override
|
||||||
|
public IPAddress deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||||
|
return IPAddress.of(Long.decode(p.getValueAsString()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return customClassModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ public class WebConfig implements WebMvcConfigurer {
|
||||||
.excludePathPatterns("/hello", "/error") //测试
|
.excludePathPatterns("/hello", "/error") //测试
|
||||||
.excludePathPatterns("/staff/login") //登录
|
.excludePathPatterns("/staff/login") //登录
|
||||||
.excludePathPatterns("/swagger-ui.html", "/swagger-resources/**", "/swagger-ui/**",
|
.excludePathPatterns("/swagger-ui.html", "/swagger-resources/**", "/swagger-ui/**",
|
||||||
"/v2/**", "/v3/**", "/webjars/**", "/doc.html"); //swagger
|
"/v2/**", "/v3/**", "/webjars/**", "/doc.html") //swagger
|
||||||
|
.excludePathPatterns("/favicon.ico", "/public/**"); //静态资源
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -46,7 +46,7 @@ public class AnnouncementController {
|
||||||
if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) {
|
if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) {
|
||||||
throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT);
|
throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT);
|
||||||
}
|
}
|
||||||
return ResponseMap.ofSuccess(announcementService.getAnnouncementById(announcementId));
|
return ResponseMap.ofSuccess(announcementService.getAnnouncementById(projectId, announcementId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
|
|
|
@ -2,7 +2,6 @@ package cn.edu.hfut.rmdjzz.projectmanagement.controller;
|
||||||
|
|
||||||
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff;
|
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff;
|
||||||
import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
|
import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
|
||||||
import cn.edu.hfut.rmdjzz.projectmanagement.exception.ForbiddenException;
|
|
||||||
import cn.edu.hfut.rmdjzz.projectmanagement.exception.TokenException;
|
import cn.edu.hfut.rmdjzz.projectmanagement.exception.TokenException;
|
||||||
import cn.edu.hfut.rmdjzz.projectmanagement.service.IStaffService;
|
import cn.edu.hfut.rmdjzz.projectmanagement.service.IStaffService;
|
||||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.FileUtils;
|
import cn.edu.hfut.rmdjzz.projectmanagement.utils.FileUtils;
|
||||||
|
@ -12,12 +11,12 @@ import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.ResponseMap;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.util.DigestUtils;
|
import org.springframework.util.DigestUtils;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,7 +71,8 @@ public class StaffController {
|
||||||
return ResponseMap.ofSuccess("成功导入" + successCount + "条数据");
|
return ResponseMap.ofSuccess("成功导入" + successCount + "条数据");
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
//取消功能
|
||||||
|
/*@SneakyThrows
|
||||||
@GetMapping("/import/template")
|
@GetMapping("/import/template")
|
||||||
public void downloadTemplate(
|
public void downloadTemplate(
|
||||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||||
|
@ -81,9 +81,18 @@ public class StaffController {
|
||||||
if (TokenUtils.getStaffGlobalLevel(token) > 2) {
|
if (TokenUtils.getStaffGlobalLevel(token) > 2) {
|
||||||
throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE);
|
throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE);
|
||||||
}
|
}
|
||||||
if (FileUtils.downloadResource("static/账户导入模板.xlsx", response)) {
|
if (FileUtils.downloadResource("static/public/账户导入模板.xlsx", response)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw new BadRequestException(BadRequestException.OPERATE_FAILED);
|
throw new BadRequestException(BadRequestException.OPERATE_FAILED);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
@GetMapping("/import/template")
|
||||||
|
@ResponseStatus(HttpStatus.SEE_OTHER)
|
||||||
|
public ResponseMap downloadTemplate() {
|
||||||
|
return ResponseMap.of(HttpStatus.SEE_OTHER.value(),
|
||||||
|
HttpStatus.SEE_OTHER.getReasonPhrase())
|
||||||
|
.put("URI","/public/账户导入模板.xlsx");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ public class AnnouncementDTO {
|
||||||
private Long announcementId;
|
private Long announcementId;
|
||||||
private Integer announcementPublisherId;
|
private Integer announcementPublisherId;
|
||||||
private String announcementPublisherName;
|
private String announcementPublisherName;
|
||||||
|
private Integer announcementPublisherAccessLevel;
|
||||||
private LocalDateTime announcementPublishTime;
|
private LocalDateTime announcementPublishTime;
|
||||||
private String announcementTitle;
|
private String announcementTitle;
|
||||||
private String announcementContent;
|
private String announcementContent;
|
||||||
|
|
|
@ -7,6 +7,8 @@ import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author 张韬
|
* @author 张韬
|
||||||
|
@ -20,7 +22,15 @@ public class CorsInterceptor implements HandlerInterceptor {
|
||||||
response.setHeader("Access-Control-Allow-Origin", "*");
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
||||||
response.setHeader("Access-Control-Allow-Methods", "*");
|
response.setHeader("Access-Control-Allow-Methods", "*");
|
||||||
response.setHeader("Access-Control-Allow-Headers", "Content-Type,Token");
|
response.setHeader("Access-Control-Allow-Headers", "Content-Type,Token");
|
||||||
response.setHeader("Access-Control-Allow-Credentials","false");
|
response.setHeader("Access-Control-Allow-Credentials", "false");
|
||||||
|
|
||||||
|
//test
|
||||||
|
Enumeration<String> headerNames = request.getHeaderNames();
|
||||||
|
Iterator<String> nameIter = headerNames.asIterator();
|
||||||
|
while (nameIter.hasNext()) {
|
||||||
|
System.out.println(nameIter.next());
|
||||||
|
}
|
||||||
|
|
||||||
// 如果是OPTIONS则结束请求
|
// 如果是OPTIONS则结束请求
|
||||||
if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
|
if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
|
||||||
response.setStatus(HttpStatus.OK.value());
|
response.setStatus(HttpStatus.OK.value());
|
||||||
|
|
|
@ -14,5 +14,5 @@ import java.util.List;
|
||||||
public interface AnnouncementMapper extends BaseMapper<Announcement> {
|
public interface AnnouncementMapper extends BaseMapper<Announcement> {
|
||||||
List<AnnouncementDTO> selectAnnouncementList(@Param("projectId") Integer projectId);
|
List<AnnouncementDTO> selectAnnouncementList(@Param("projectId") Integer projectId);
|
||||||
|
|
||||||
AnnouncementDTO selectAnnouncementById(@Param("announcementId") Long announcementId);
|
AnnouncementDTO selectAnnouncementById(@Param("projectId") Integer projectId, @Param("announcementId") Long announcementId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ public interface IAnnouncementService extends IService<Announcement> {
|
||||||
|
|
||||||
List<AnnouncementDTO> getAnnouncementList(Integer projectId);
|
List<AnnouncementDTO> getAnnouncementList(Integer projectId);
|
||||||
|
|
||||||
AnnouncementDTO getAnnouncementById(Long announcementId);
|
AnnouncementDTO getAnnouncementById(Integer projectId, Long announcementId);
|
||||||
|
|
||||||
Boolean updateAnnouncement(String token, Integer projectId, Announcement announcement) throws ForbiddenException, BadRequestException;
|
Boolean updateAnnouncement(String token, Integer projectId, Announcement announcement) throws ForbiddenException, BadRequestException;
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ public interface IProjectGroupService extends IService<ProjectGroup> {
|
||||||
|
|
||||||
Boolean removeMember(String token, Integer projectId, Integer targetId) throws ForbiddenException, BadRequestException;
|
Boolean removeMember(String token, Integer projectId, Integer targetId) throws ForbiddenException, BadRequestException;
|
||||||
|
|
||||||
Boolean updateStaffPositions(String token, Integer projectId, Integer targetId, String positions) throws ForbiddenException;
|
Boolean updateStaffPositions(String token, Integer projectId, Integer targetId, String positions) throws ForbiddenException, BadRequestException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return 如果不存在就返回0,否则返回AccessLevel;对于全局权限为1的用户,直接返回1
|
* @return 如果不存在就返回0,否则返回AccessLevel;对于全局权限为1的用户,直接返回1
|
||||||
|
|
|
@ -31,8 +31,8 @@ public class AnnouncementServiceImpl extends ServiceImpl<AnnouncementMapper, Ann
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AnnouncementDTO getAnnouncementById(Long announcementId) {
|
public AnnouncementDTO getAnnouncementById(Integer projectId, Long announcementId) {
|
||||||
return baseMapper.selectAnnouncementById(announcementId);
|
return baseMapper.selectAnnouncementById(projectId, announcementId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -64,8 +64,7 @@ public class AnnouncementServiceImpl extends ServiceImpl<AnnouncementMapper, Ann
|
||||||
throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE);
|
throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE);
|
||||||
}
|
}
|
||||||
Announcement rawAnnouncement = baseMapper.selectOne(Wrappers.<Announcement>lambdaQuery()
|
Announcement rawAnnouncement = baseMapper.selectOne(Wrappers.<Announcement>lambdaQuery()
|
||||||
.select(Announcement::getProjectId)
|
.select(Announcement::getProjectId, Announcement::getAnnouncementPublisherId)
|
||||||
.select(Announcement::getAnnouncementPublisherId)
|
|
||||||
.eq(Announcement::getAnnouncementId, announcementId)
|
.eq(Announcement::getAnnouncementId, announcementId)
|
||||||
);
|
);
|
||||||
if (!Objects.equals(projectId, rawAnnouncement.getProjectId())) {
|
if (!Objects.equals(projectId, rawAnnouncement.getProjectId())) {
|
||||||
|
|
|
@ -44,6 +44,9 @@ public class ProjectGroupServiceImpl extends ServiceImpl<ProjectGroupMapper, Pro
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean insertNewMember(String token, Integer projectId, String targetUsername, String positions) throws ForbiddenException, BadRequestException {
|
public Boolean insertNewMember(String token, Integer projectId, String targetUsername, String positions) throws ForbiddenException, BadRequestException {
|
||||||
|
if (targetUsername.equals("root")) {
|
||||||
|
throw new BadRequestException(IStaffService.STAFF_DOES_NOT_EXIST);
|
||||||
|
}
|
||||||
int accessLevel = getProjectAccessLevel(token, projectId);
|
int accessLevel = getProjectAccessLevel(token, projectId);
|
||||||
int targetLevel = 3;
|
int targetLevel = 3;
|
||||||
|
|
||||||
|
@ -51,6 +54,9 @@ public class ProjectGroupServiceImpl extends ServiceImpl<ProjectGroupMapper, Pro
|
||||||
if (targetStaff == null) {
|
if (targetStaff == null) {
|
||||||
throw new BadRequestException(IStaffService.STAFF_DOES_NOT_EXIST);
|
throw new BadRequestException(IStaffService.STAFF_DOES_NOT_EXIST);
|
||||||
}
|
}
|
||||||
|
if (getProjectAccessLevelIgnoreGlobalLevel(targetStaff.getStaffId(), projectId) != 0) {
|
||||||
|
throw new BadRequestException("该成员已经在本项目中");
|
||||||
|
}
|
||||||
|
|
||||||
if (accessLevel == 0) {
|
if (accessLevel == 0) {
|
||||||
throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT);
|
throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT);
|
||||||
|
@ -91,9 +97,12 @@ public class ProjectGroupServiceImpl extends ServiceImpl<ProjectGroupMapper, Pro
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean updateStaffPositions(String token, Integer projectId, Integer targetId, String positions) throws ForbiddenException {
|
public Boolean updateStaffPositions(String token, Integer projectId, Integer targetId, String positions) throws ForbiddenException, BadRequestException {
|
||||||
int accessLevel = getProjectAccessLevel(token, projectId);
|
int accessLevel = getProjectAccessLevel(token, projectId);
|
||||||
int originTargetLevel = getProjectAccessLevelIgnoreGlobalLevel(targetId, projectId);
|
int originTargetLevel = getProjectAccessLevelIgnoreGlobalLevel(targetId, projectId);
|
||||||
|
if (originTargetLevel == 0) {
|
||||||
|
throw new BadRequestException("该项目中不存在该成员");
|
||||||
|
}
|
||||||
int targetLevel = 3;
|
int targetLevel = 3;
|
||||||
|
|
||||||
if (accessLevel == 0) {
|
if (accessLevel == 0) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import cn.edu.hfut.rmdjzz.projectmanagement.utils.BeanUtils;
|
||||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.MapBuilder;
|
import cn.edu.hfut.rmdjzz.projectmanagement.utils.MapBuilder;
|
||||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.TimeUtils;
|
import cn.edu.hfut.rmdjzz.projectmanagement.utils.TimeUtils;
|
||||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils;
|
import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils;
|
||||||
|
import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.IPAddress;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
@ -45,34 +46,35 @@ public class StaffServiceImpl extends ServiceImpl<StaffMapper, Staff> implements
|
||||||
@SuppressWarnings("ConstantConditions")
|
@SuppressWarnings("ConstantConditions")
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> login(String requestIpAddress, String staffUsername, String password) throws BadRequestException, ForbiddenException {
|
public Map<String, Object> login(String requestIpAddress, String staffUsername, String password) throws BadRequestException, ForbiddenException {
|
||||||
if (Boolean.FALSE.equals(redisTemplate.hasKey(requestIpAddress))) {
|
String requestIpAddressHex = IPAddress.of(requestIpAddress).toString();
|
||||||
redisTemplate.opsForValue().set(requestIpAddress, 0, LOGIN_TRY_COUNT_TIMEOUT, TimeUnit.MINUTES);
|
if (Boolean.FALSE.equals(redisTemplate.hasKey(requestIpAddressHex))) {
|
||||||
|
redisTemplate.opsForValue().set(requestIpAddressHex, 0, LOGIN_TRY_COUNT_TIMEOUT, TimeUnit.MINUTES);
|
||||||
}
|
}
|
||||||
int loginCount = (int) redisTemplate.opsForValue().get(requestIpAddress);
|
int loginCount = (int) redisTemplate.opsForValue().get(requestIpAddressHex);
|
||||||
|
|
||||||
if (loginCount >= LOGIN_MAX_TRY_COUNT) {
|
if (loginCount >= LOGIN_MAX_TRY_COUNT) {
|
||||||
throw new ForbiddenException(String.format("还需要等待%s才能登录"
|
throw new ForbiddenException(String.format("还需要等待%s才能登录"
|
||||||
, TimeUtils.secondsFormat(redisTemplate.getExpire(requestIpAddress))));
|
, TimeUtils.secondsFormat(redisTemplate.getExpire(requestIpAddressHex))));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (staffUsername == null || staffUsername.strip().length() == 0)
|
if (staffUsername == null || staffUsername.strip().length() == 0)
|
||||||
//throw new BadRequestException("用户名为空");
|
//throw new BadRequestException("用户名为空");
|
||||||
throwLoginException(requestIpAddress, loginCount);
|
throw loginException(requestIpAddressHex, loginCount);
|
||||||
if (!staffUsername.equals(staffUsername.replaceAll("[^a-zA-Z0-9]", "")))
|
if (!staffUsername.equals(staffUsername.replaceAll("[^a-zA-Z0-9]", "")))
|
||||||
//throw new BadRequestException("用户名格式错误");
|
//throw new BadRequestException("用户名格式错误");
|
||||||
throwLoginException(requestIpAddress, loginCount);
|
throw loginException(requestIpAddressHex, loginCount);
|
||||||
if (password == null || password.trim().length() != 32)
|
if (password == null || password.trim().length() != 32)
|
||||||
//throw new BadRequestException("密码格式错误");
|
//throw new BadRequestException("密码格式错误");
|
||||||
throwLoginException(requestIpAddress, loginCount);
|
throw loginException(requestIpAddressHex, loginCount);
|
||||||
|
|
||||||
Staff staff = getOne(Wrappers.<Staff>lambdaQuery().eq(Staff::getStaffUsername, staffUsername));
|
Staff staff = getOne(Wrappers.<Staff>lambdaQuery().eq(Staff::getStaffUsername, staffUsername));
|
||||||
if (staff == null)
|
if (staff == null)
|
||||||
//throw new BadRequestException(STAFF_DOES_NOT_EXIST);
|
//throw new BadRequestException(STAFF_DOES_NOT_EXIST);
|
||||||
throwLoginException(requestIpAddress, loginCount);
|
throw loginException(requestIpAddressHex, loginCount);
|
||||||
|
|
||||||
password = DigestUtils.md5DigestAsHex((password + staff.getStaffSalt()).getBytes());
|
password = DigestUtils.md5DigestAsHex((password + staff.getStaffSalt()).getBytes());
|
||||||
if (!staff.getStaffPassword().equals(password)) {
|
if (!staff.getStaffPassword().equals(password)) {
|
||||||
throwLoginException(requestIpAddress, loginCount);
|
throw loginException(requestIpAddressHex, loginCount);
|
||||||
}
|
}
|
||||||
String token = TokenUtils.getToken(staff.getStaffUsername(), staff.getStaffId(), staff.getStaffGlobalLevel(), tokenDuration);
|
String token = TokenUtils.getToken(staff.getStaffUsername(), staff.getStaffId(), staff.getStaffGlobalLevel(), tokenDuration);
|
||||||
redisTemplate.opsForValue().set(
|
redisTemplate.opsForValue().set(
|
||||||
|
@ -80,15 +82,16 @@ public class StaffServiceImpl extends ServiceImpl<StaffMapper, Staff> implements
|
||||||
token,
|
token,
|
||||||
Objects.requireNonNull(TokenUtils.getDuration(token)), TimeUnit.SECONDS
|
Objects.requireNonNull(TokenUtils.getDuration(token)), TimeUnit.SECONDS
|
||||||
);
|
);
|
||||||
|
redisTemplate.delete(requestIpAddressHex);
|
||||||
return new MapBuilder()
|
return new MapBuilder()
|
||||||
.put(TokenUtils.HEADER_TOKEN, token)
|
.put(TokenUtils.HEADER_TOKEN, token)
|
||||||
.putAll(BeanUtils.beanToMap(staff, false))
|
.putAll(BeanUtils.beanToMap(staff, false))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void throwLoginException(String requestIpAddress, int loginCount) throws BadRequestException {
|
private BadRequestException loginException(String requestIpAddress, int loginCount) {
|
||||||
redisTemplate.opsForValue().set(requestIpAddress, ++loginCount, LOGIN_TRY_COUNT_TIMEOUT, TimeUnit.MINUTES);
|
redisTemplate.opsForValue().set(requestIpAddress, ++loginCount, LOGIN_TRY_COUNT_TIMEOUT, TimeUnit.MINUTES);
|
||||||
throw new BadRequestException(String.format("登录失败,%d分钟内还有%d次登录机会", LOGIN_TRY_COUNT_TIMEOUT, LOGIN_MAX_TRY_COUNT - loginCount));
|
return new BadRequestException(String.format("登录失败,%d分钟内还有%d次登录机会", LOGIN_TRY_COUNT_TIMEOUT, LOGIN_MAX_TRY_COUNT - loginCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package cn.edu.hfut.rmdjzz.projectmanagement.utils.http;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 佘语殊
|
||||||
|
* @since 2022/7/12 17:12
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor(staticName = "of")
|
||||||
|
public class IPAddress {
|
||||||
|
private long ipHex;
|
||||||
|
|
||||||
|
public static IPAddress of(String ip) {
|
||||||
|
long ipHex = 0;
|
||||||
|
String[] split = ip.split("\\.");
|
||||||
|
for (String s : split) {
|
||||||
|
ipHex = (ipHex << 8) + Integer.parseInt(s);
|
||||||
|
}
|
||||||
|
return new IPAddress(ipHex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIpString() {
|
||||||
|
List<String> ipSectionList = new LinkedList<>();
|
||||||
|
long tempHex = ipHex;
|
||||||
|
int section;
|
||||||
|
while (tempHex > 0) {
|
||||||
|
section = (int) (tempHex & 0xFF);
|
||||||
|
ipSectionList.add(String.valueOf(section));
|
||||||
|
tempHex >>= 8;
|
||||||
|
}
|
||||||
|
Collections.reverse(ipSectionList);
|
||||||
|
return String.join(".", ipSectionList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "#" + Long.toHexString(ipHex);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,7 @@
|
||||||
announcement_publish_time,
|
announcement_publish_time,
|
||||||
announcement_title
|
announcement_title
|
||||||
FROM announcement
|
FROM announcement
|
||||||
JOIN (SELECT staff_id, staff_fullname FROM staff) s
|
JOIN (SELECT staff_id, staff_fullname FROM staff) AS s
|
||||||
ON staff_id = announcement.announcement_publisher_id
|
ON staff_id = announcement.announcement_publisher_id
|
||||||
WHERE is_deleted = 0
|
WHERE is_deleted = 0
|
||||||
AND project_id = #{projectId}
|
AND project_id = #{projectId}
|
||||||
|
@ -21,13 +21,18 @@
|
||||||
<select id="selectAnnouncementById" resultMap="announcementDto">
|
<select id="selectAnnouncementById" resultMap="announcementDto">
|
||||||
SELECT announcement_id,
|
SELECT announcement_id,
|
||||||
announcement_publisher_id,
|
announcement_publisher_id,
|
||||||
s.staff_fullname AS announcement_publisher_name,
|
s.staff_fullname AS announcement_publisher_name,
|
||||||
|
IFNULL(pg.project_access_level, 1) AS announcement_publisher_access_level,
|
||||||
announcement_publish_time,
|
announcement_publish_time,
|
||||||
announcement_title,
|
announcement_title,
|
||||||
announcement_content
|
announcement_content
|
||||||
FROM announcement
|
FROM announcement
|
||||||
JOIN (SELECT staff_id, staff_fullname FROM staff) s
|
JOIN (SELECT staff_id, staff_fullname FROM staff) AS s
|
||||||
ON staff_id = announcement.announcement_publisher_id
|
ON s.staff_id = announcement.announcement_publisher_id
|
||||||
|
LEFT JOIN (SELECT staff_id, project_access_level
|
||||||
|
FROM project_group
|
||||||
|
WHERE project_id = #{projectId}) AS pg
|
||||||
|
ON pg.staff_id = announcement_publisher_id
|
||||||
WHERE is_deleted = 0
|
WHERE is_deleted = 0
|
||||||
AND announcement_id = #{announcementId};
|
AND announcement_id = #{announcementId};
|
||||||
</select>
|
</select>
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package cn.edu.hfut.rmdjzz.projectmanagement;
|
package cn.edu.hfut.rmdjzz.projectmanagement;
|
||||||
|
|
||||||
|
import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.IPAddress;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@ -15,14 +17,21 @@ import java.time.LocalDateTime;
|
||||||
public class RedisTests {
|
public class RedisTests {
|
||||||
@Autowired
|
@Autowired
|
||||||
private RedisTemplate<Object, Object> redisTemplate;
|
private RedisTemplate<Object, Object> redisTemplate;
|
||||||
|
@Autowired
|
||||||
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void test() {
|
void test() {
|
||||||
System.out.println(redisTemplate.opsForValue().get("l1"));
|
System.out.println(redisTemplate.opsForValue().get(0x15A2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testValue() {
|
void testValue() {
|
||||||
redisTemplate.opsForValue().set("time", LocalDateTime.now());
|
redisTemplate.opsForValue().set("time", LocalDateTime.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void stringTest() {
|
||||||
|
stringRedisTemplate.opsForValue().set(IPAddress.of("192.168.0.1").toString(),String.valueOf(2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package cn.edu.hfut.rmdjzz.projectmanagement;
|
package cn.edu.hfut.rmdjzz.projectmanagement;
|
||||||
|
|
||||||
|
import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.IPAddress;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,4 +24,13 @@ public class SerializeTests {
|
||||||
public void serializeTime() {
|
public void serializeTime() {
|
||||||
System.out.println(objectMapper.readValue("1657166400", LocalDateTime.class));
|
System.out.println(objectMapper.readValue("1657166400", LocalDateTime.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
@Test
|
||||||
|
public void serializeIPTest() {
|
||||||
|
IPAddress ip = IPAddress.of("192.108.1.1");
|
||||||
|
System.out.println(objectMapper.writeValueAsString(ip));
|
||||||
|
System.out.println(ip.getIpString());
|
||||||
|
System.out.println(objectMapper.readValue("0xc06c0101",IPAddress.class));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue