master
mfay 4 years ago
parent 7049d8fe02
commit b3ba31c91f
  1. 34
      IOReportSysBE/src/main/java/edu/ncst/ioreport/config/CustomAccessDeniedHandler.java
  2. 30
      IOReportSysBE/src/main/java/edu/ncst/ioreport/config/FileIOConfig.java
  3. 119
      IOReportSysBE/src/main/java/edu/ncst/ioreport/config/SecurityConfig.java
  4. 15
      IOReportSysBE/src/main/java/edu/ncst/ioreport/config/exception/NotBindUserException.java
  5. 109
      IOReportSysBE/src/main/java/edu/ncst/ioreport/config/security/DataBaseUrlVoter.java
  6. 104
      IOReportSysBE/src/main/java/edu/ncst/ioreport/config/security/filter/AuthCheckFilter.java
  7. 206
      IOReportSysBE/src/main/java/edu/ncst/ioreport/config/security/filter/LoginFilter.java
  8. 64
      IOReportSysBE/src/main/java/edu/ncst/ioreport/config/security/provider/WechatIdLoginProvider.java
  9. 40
      IOReportSysBE/src/main/java/edu/ncst/ioreport/config/security/token/JwtAuthenticationToken.java
  10. 39
      IOReportSysBE/src/main/java/edu/ncst/ioreport/config/security/token/MobileCaptchaAuthenticationToken.java
  11. 51
      IOReportSysBE/src/main/java/edu/ncst/ioreport/config/security/token/WechatIdAuthenticationToken.java
  12. 52
      IOReportSysBE/src/main/java/edu/ncst/ioreport/controller/IORecordsController.java
  13. 59
      IOReportSysBE/src/main/java/edu/ncst/ioreport/controller/ImageController.java
  14. 49
      IOReportSysBE/src/main/java/edu/ncst/ioreport/controller/MaterialUploadController.java
  15. 36
      IOReportSysBE/src/main/java/edu/ncst/ioreport/controller/UserController.java
  16. 34
      IOReportSysBE/src/main/java/edu/ncst/ioreport/mapper/BaseMapperPlus.java
  17. 19
      IOReportSysBE/src/main/java/edu/ncst/ioreport/mapper/IORecordsMapper.java
  18. 13
      IOReportSysBE/src/main/java/edu/ncst/ioreport/mapper/ImageMapper.java
  19. 19
      IOReportSysBE/src/main/java/edu/ncst/ioreport/mapper/MaterialUploadMapper.java
  20. 9
      IOReportSysBE/src/main/java/edu/ncst/ioreport/mapper/ResourceMapper.java
  21. 25
      IOReportSysBE/src/main/java/edu/ncst/ioreport/mapper/RoleMapper.java
  22. 26
      IOReportSysBE/src/main/java/edu/ncst/ioreport/mapper/UserMapper.java
  23. 18
      IOReportSysBE/src/main/java/edu/ncst/ioreport/model/Department.java
  24. 97
      IOReportSysBE/src/main/java/edu/ncst/ioreport/model/IORecords.java
  25. 41
      IOReportSysBE/src/main/java/edu/ncst/ioreport/model/Image.java
  26. 49
      IOReportSysBE/src/main/java/edu/ncst/ioreport/model/LoginLog.java
  27. 64
      IOReportSysBE/src/main/java/edu/ncst/ioreport/model/MaterialUploadRecord.java
  28. 55
      IOReportSysBE/src/main/java/edu/ncst/ioreport/model/Resource.java
  29. 58
      IOReportSysBE/src/main/java/edu/ncst/ioreport/model/Role.java
  30. 102
      IOReportSysBE/src/main/java/edu/ncst/ioreport/model/User.java
  31. 17
      IOReportSysBE/src/main/java/edu/ncst/ioreport/service/IIORecordService.java
  32. 18
      IOReportSysBE/src/main/java/edu/ncst/ioreport/service/IImageService.java
  33. 18
      IOReportSysBE/src/main/java/edu/ncst/ioreport/service/ILoginLogService.java
  34. 16
      IOReportSysBE/src/main/java/edu/ncst/ioreport/service/IMaterialUploadService.java
  35. 22
      IOReportSysBE/src/main/java/edu/ncst/ioreport/service/IResourceService.java
  36. 26
      IOReportSysBE/src/main/java/edu/ncst/ioreport/service/IRoleService.java
  37. 17
      IOReportSysBE/src/main/java/edu/ncst/ioreport/service/IUserService.java
  38. 132
      IOReportSysBE/src/main/java/edu/ncst/ioreport/service/impl/IORecordServiceImpl.java
  39. 66
      IOReportSysBE/src/main/java/edu/ncst/ioreport/service/impl/ImageServiceImpl.java
  40. 27
      IOReportSysBE/src/main/java/edu/ncst/ioreport/service/impl/LoginLogServiceImpl.java
  41. 77
      IOReportSysBE/src/main/java/edu/ncst/ioreport/service/impl/MaterialUploadServiceImpl.java
  42. 64
      IOReportSysBE/src/main/java/edu/ncst/ioreport/service/impl/ResourceServiceImpl.java
  43. 55
      IOReportSysBE/src/main/java/edu/ncst/ioreport/service/impl/RoleServiceImpl.java
  44. 111
      IOReportSysBE/src/main/java/edu/ncst/ioreport/service/impl/UserServiceImpl.java
  45. 79
      IOReportSysBE/src/main/java/edu/ncst/ioreport/utils/CaptchaUtil.java
  46. 29
      IOReportSysBE/src/main/java/edu/ncst/ioreport/utils/CookieUtils.java
  47. 130
      IOReportSysBE/src/main/java/edu/ncst/ioreport/utils/FileUtil.java
  48. 56
      IOReportSysBE/src/main/java/edu/ncst/ioreport/utils/SessionUtils.java
  49. 25
      IOReportSysBE/src/main/java/edu/ncst/ioreport/utils/SpringUtils.java
  50. 27
      IOReportSysBE/src/main/java/edu/ncst/ioreport/utils/URLUtils.java
  51. 30
      IOReportSysBE/src/main/java/edu/ncst/ioreport/vo/ListResultVO.java
  52. 21
      IOReportSysBE/src/main/java/edu/ncst/ioreport/vo/QRToken.java
  53. 61
      IOReportSysBE/src/main/java/edu/ncst/ioreport/vo/Query.java
  54. 20
      IOReportSysBE/src/main/java/edu/ncst/ioreport/vo/Sorter.java
  55. 41
      IOReportSysBE/src/main/java/edu/ncst/ioreport/vo/param/CurrentUserVO.java
  56. 29
      IOReportSysBE/src/main/java/edu/ncst/ioreport/vo/param/QLoginLog.java
  57. 31
      IOReportSysBE/src/main/java/edu/ncst/ioreport/vo/param/QRecord.java
  58. 14
      IOReportSysBE/src/main/java/edu/ncst/ioreport/vo/param/QUser.java
  59. 60
      IOReportSysBE/src/main/java/edu/ncst/ioreport/vo/result/RecordVO.java
  60. 29
      IOReportSysBE/src/main/java/edu/ncst/ioreport/vo/result/UserInfoVO.java
  61. 4
      IOReportSysBE/src/main/resources/application.yml
  62. 51
      IOReportSysBE/src/main/resources/mapping/IORecordMapper.xml
  63. 42
      IOReportSysBE/src/main/resources/mapping/MaterialUploadMapper.xml
  64. 52
      IOReportSysBE/src/main/resources/mapping/UserMapper.xml

@ -1,34 +0,0 @@
package edu.ncst.ioreport.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Service;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Service
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Autowired
private ObjectMapper objectMapper;
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
response.setContentType("application/json;charset=UTF-8");
Map map = new HashMap();
map.put("code",403);
map.put("msg", "无访问权限");
map.put("data","");
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().write(objectMapper.writeValueAsString(map));
}
}

@ -1,30 +0,0 @@
package edu.ncst.ioreport.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Component
@ConfigurationProperties(prefix = "file")
public class FileIOConfig implements WebMvcConfigurer {
private String fileDir;
public String getFileDir() {
return fileDir;
}
public void setFileDir(String fileDir) {
this.fileDir = fileDir;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/**
* 配置资源映射
* 意思是如果请求地址是以/upload/开头的
* 就给映射到本机的D:/profiles/这个文件夹内去找你要的资源
* 注意D:/profiles/ 后面的 /一定要带上
*/
registry.addResourceHandler("**/equipment/download/**")
.addResourceLocations("file:"+fileDir);
}
}

@ -1,13 +1,7 @@
package edu.ncst.ioreport.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.ncst.ioreport.config.security.DataBaseUrlVoter;
import edu.ncst.ioreport.config.security.filter.AuthCheckFilter;
import edu.ncst.ioreport.config.security.filter.LoginFilter;
import edu.ncst.ioreport.config.security.provider.WechatIdLoginProvider;
import edu.ncst.ioreport.exception.CodeMsg;
import edu.ncst.ioreport.service.ILoginLogService;
import edu.ncst.ioreport.service.impl.UserServiceImpl;
import edu.ncst.ioreport.utils.ResultUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@ -29,7 +23,6 @@ import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.expression.WebExpressionVoter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import java.io.PrintWriter;
import java.util.Arrays;
@ -43,37 +36,6 @@ import java.util.List;
@EnableGlobalMethodSecurity(securedEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserServiceImpl userService;
@Autowired
private ILoginLogService loginLogService;
@Autowired
private DataBaseUrlVoter dataBaseUrlVoter;
@Autowired
private RedisTemplate<String, String> redisCacheTemplate;
@Autowired
private WechatIdLoginProvider wechatIdLoginProvider;
/**
* 认证失败处理类
*/
@Autowired
CustomAccessDeniedHandler accessDeniedHandler;
//org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)
/**
* 解决 无法直接注入 AuthenticationManager
*
* @return
* @throws Exception
*/
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
{
return super.authenticationManagerBean();
}
/**
* 权限白名单
* 注意该名单下匹配的 URL 不会经过鉴权因此也无法获取当前用户的信息
@ -97,32 +59,10 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
"/api/user/login"
};
/**
* 密码加密器
*/
@Bean
public PasswordEncoder passwordEncoderBean() {
return new BCryptPasswordEncoder();
}
/**
* 权限投票访问决策管理器
*/
@Bean
public AccessDecisionManager accessDecisionManager() {
List<AccessDecisionVoter<? extends Object>> decisionVoters
= Arrays.asList(
new WebExpressionVoter(),
new RoleVoter(),//主要用来判断当前请求是否具备该接口所需要的角色
dataBaseUrlVoter,
new AuthenticatedVoter());
return new UnanimousBased(decisionVoters);//要求所有 AccessDecisionVoter 均返回肯定的结果时,才代表授予权限。
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService);
auth.authenticationProvider(wechatIdLoginProvider);
super.configure(auth);
}
@ -145,60 +85,15 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
// HttpSecurity 及WebSecurity 作用是不一样的:
// WebSecurity 主要针对的全局的忽略规则,
// HttpSecurity主要是权限控制规则。
@Override
protected void configure(HttpSecurity http) throws Exception {
//允许跨域
http.cors().and().anonymous().and()
// CRSF禁用,因为不使用session
.csrf().disable()
.formLogin().disable().httpBasic().disable()
.authorizeRequests()
.accessDecisionManager(accessDecisionManager())//访问决策管理器
.antMatchers("/api/login").permitAll()
.antMatchers("/system/init").permitAll()
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated()
.and().exceptionHandling().accessDeniedHandler(accessDeniedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterAfter(new AuthCheckFilter(redisCacheTemplate), UsernamePasswordAuthenticationFilter.class)
.addFilterAt(
new LoginFilter(authenticationManager(), loginLogService, redisCacheTemplate), UsernamePasswordAuthenticationFilter.class
)
.exceptionHandling()//登录认证失败
.authenticationEntryPoint(((request, response, authException) -> {
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
out.write(new ObjectMapper().writeValueAsString(ResultUtils.error(CodeMsg.USER_NEED_LOGIN)));
out.flush();
out.close();
}));
// 退出登录
http.logout()
.logoutUrl("/logout")
.deleteCookies("JSESSIONID")
.logoutSuccessHandler(((request, response, authentication) -> {
PrintWriter out = response.getWriter();
response.setContentType("application/json");
out.write(new ObjectMapper().writeValueAsString(ResultUtils.success("注销成功")));
out.flush();
out.close();
}));
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception{
//调试阶段
httpSecurity.csrf().disable().authorizeRequests();
httpSecurity.authorizeRequests().anyRequest()
.permitAll().and().logout().permitAll();
}
// @Override
// protected void configure(HttpSecurity httpSecurity) throws Exception{
// //调试阶段
// httpSecurity.csrf().disable().authorizeRequests();
// httpSecurity.authorizeRequests().anyRequest()
// .permitAll().and().logout().permitAll();
// }
//用于配置全局的某些通用事物,例如静态资源等
@Override
public void configure(WebSecurity web) throws Exception {

@ -1,15 +0,0 @@
package edu.ncst.ioreport.config.exception;
import org.springframework.security.core.AuthenticationException;
public class NotBindUserException extends AuthenticationException {
public NotBindUserException(String msg, Throwable t) {
super(msg, t);
}
public NotBindUserException(String msg) {
super(msg);
}
}

@ -1,109 +0,0 @@
package edu.ncst.ioreport.config.security;
import edu.ncst.ioreport.model.Role;
import edu.ncst.ioreport.service.IResourceService;
import edu.ncst.ioreport.utils.URLUtils;
import edu.ncst.ioreport.vo.result.UserInfoVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
/**
* URL 鉴权投票器
*/
@Component
public class DataBaseUrlVoter implements AccessDecisionVoter<FilterInvocation> {
@Autowired
private IResourceService resourceService;
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
@Override
public int vote(Authentication authentication, FilterInvocation fi, Collection<ConfigAttribute> attributes) {
if (authentication == null) {
return ACCESS_DENIED; // 反对票
}
String url = fi.getRequestUrl(); // 当前请求的URL
String urlWithoutQueryString = URLUtils.removeQueryString(url);
// Current User Info
Object details = authentication.getDetails();
if (details instanceof UserInfoVO) {
UserInfoVO userInfoVO = (UserInfoVO) details;
AntPathMatcher antPathMatcher = new AntPathMatcher();
//获取不限用户角色的资源
List<String> permitAllResourceURLs = resourceService.getPermitAllResourceURLs();
// Permit All Resource
for (String permitUrl : permitAllResourceURLs) {
boolean match = antPathMatcher.match(permitUrl, urlWithoutQueryString);
if (match) {
return ACCESS_GRANTED; // 赞同票
}
}
// 判断用户角色信息
// 反对票:1、没有角色信息 2、角色未绑定该资源
// 赞成票:用户是超级管理员
List<String> roles = userInfoVO.getRoles();
if (roles == null || roles.isEmpty()) {
return ACCESS_DENIED; // 反对票
}
List<String> roleNames = roles.stream().map(String::toString).collect(Collectors.toList());
// Super Admin User Always Pass
if (roleNames.contains("SUPER_ADMIN")) {
return ACCESS_GRANTED; // 赞同票
}
List<String> rolesResourceList = resourceService.getRolesResourceList(roleNames);//获取目标角色绑定的资源
// Role Resource
if (rolesResourceList == null) {
return ACCESS_DENIED; // 反对票
}
for (String allowUrl : rolesResourceList) {
boolean match = antPathMatcher.match(allowUrl, urlWithoutQueryString);
if (match) {
return ACCESS_GRANTED; // 赞同票
}
}
}
return ACCESS_DENIED;
}
Collection<? extends GrantedAuthority> extractAuthorities(
Authentication authentication) {
return authentication.getAuthorities();
}
}

@ -1,104 +0,0 @@
package edu.ncst.ioreport.config.security.filter;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.ncst.ioreport.config.security.token.JwtAuthenticationToken;
import edu.ncst.ioreport.exception.CodeMsg;
import edu.ncst.ioreport.model.Role;
import edu.ncst.ioreport.utils.ResponseUtils;
import edu.ncst.ioreport.utils.ResultUtils;
import edu.ncst.ioreport.vo.ResultVO;
import edu.ncst.ioreport.vo.result.UserInfoVO;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 用户凭证检查过滤器
* 并不是所有的container都像我们期望的只过滤一次servlet版本不同表现也不同
* OncePerRequestFilter可以保证一次请求只通过一次过滤器推荐自定义的授权过滤器继承OncePerRequestFilter
*/
@Slf4j
public class AuthCheckFilter extends OncePerRequestFilter {
private final RedisTemplate<String, String> stringRedisTemplate;
public AuthCheckFilter(RedisTemplate<String, String> stringRedisTemplate) {
super();
this.stringRedisTemplate = stringRedisTemplate;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String jwtToken = null;
String authorization = request.getHeader("Authorization");
log.info("开始鉴权====header Authorization====" +authorization);
if (authorization != null && authorization.startsWith("Bearer ")) {
jwtToken = authorization.replace("Bearer ", "");
log.info("获取到token====header====");
} else {
log.info("header中无token,进入过滤器链");
filterChain.doFilter(request, response);
return;
}
if (jwtToken == null || "".equals(jwtToken)) {
log.error("鉴权TOKEN:未获取,用户需要登录");
ResultVO<Object> resultVO = ResultUtils.error(CodeMsg.USER_NEED_LOGIN);
ResponseUtils.output(response, resultVO);
} else {
log.info("鉴权TOKEN:" +"Bearer " + jwtToken);
}
try {
// 解析TOKEN
Jws<Claims> jws = Jwts.parser().setSigningKey("ncst20221003")
.parseClaimsJws(jwtToken);
Claims claims = jws.getBody();
String userName = claims.getSubject();
//可以通过控制redis数据从服务端强制下线用户
if(!stringRedisTemplate.hasKey("jwt_token:"+userName)){
throw new ExpiredJwtException(null,jws.getBody(),"登录失效");
}
// 获取用户信息
String userInfoJSON = (String) claims.get("userInfo");
ObjectMapper objectMapper = new ObjectMapper();
UserInfoVO userInfoVO = objectMapper.readValue(userInfoJSON, UserInfoVO.class);
// 获取角色列表
List<String> roles = userInfoVO.getRoles();
List<GrantedAuthority> authorities = new ArrayList<>();
if (roles != null && !roles.isEmpty()) {
for (String role : roles) {
authorities.add(new SimpleGrantedAuthority("ROLE_" + role));
}
}
// 将 TOKEN 存到 CONTEXT 当中
JwtAuthenticationToken token = new JwtAuthenticationToken(userName, authorities, userInfoVO);
SecurityContextHolder.getContext().setAuthentication(token);
} catch (ExpiredJwtException e) {
ResultVO<Object> resultVO = ResultUtils.error(CodeMsg.USER_CREDENTIALS_EXPIRED);// 用户凭证过期
ResponseUtils.output(response, resultVO);
} finally {
filterChain.doFilter(request, response);
}
}
}

@ -1,206 +0,0 @@
package edu.ncst.ioreport.config.security.filter;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.ncst.ioreport.config.security.token.WechatIdAuthenticationToken;
import edu.ncst.ioreport.exception.BusinessException;
import edu.ncst.ioreport.exception.CodeMsg;
import edu.ncst.ioreport.model.Role;
import edu.ncst.ioreport.model.User;
import edu.ncst.ioreport.service.ILoginLogService;
import edu.ncst.ioreport.utils.ResultUtils;
import edu.ncst.ioreport.vo.ResultVO;
import edu.ncst.ioreport.vo.param.UserLoginVO;
import edu.ncst.ioreport.vo.result.UserInfoVO;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* 统一登录入口
*/
@Slf4j
public class LoginFilter extends AbstractAuthenticationProcessingFilter {//OncePerRequestFilter
private static final String loginUrl = "/api/login";
private final ILoginLogService loginLogService;
private final RedisTemplate<String, String> stringRedisTemplate;
private String tempToken="";
private final int MAX_ATTEMPT = 20;
public LoginFilter(AuthenticationManager authenticationManager, ILoginLogService loginLogService, RedisTemplate<String, String> stringRedisTemplate) {
super(new AntPathRequestMatcher(loginUrl, HttpMethod.POST.name()));
setAuthenticationManager(authenticationManager);
this.loginLogService = loginLogService;
this.stringRedisTemplate = stringRedisTemplate;
}
/**
* 尝试登录
* 根据登录表单的类型type将登录凭证分发给对应的 AuthenticationProvider
* 当前filter的认证逻辑
*/
@Override
public Authentication attemptAuthentication(
HttpServletRequest request, HttpServletResponse response
) throws AuthenticationException, IOException, ServletException {
UserLoginVO paramUserLoginVO = new ObjectMapper().readValue(request.getInputStream(), UserLoginVO.class);
AuthenticationManager authenticationManager = getAuthenticationManager();
request.setAttribute("userLoginVO", paramUserLoginVO);
log.info("尝试登录===="+ paramUserLoginVO);
// if(paramUserLoginVO!=null&&paramUserLoginVO.getWeChatCode()!=null&&paramUserLoginVO.getWeChatCode().trim().length()>0){
// AccessTokenDTO getAccessTokenDTO = WeChatUtils.code2session(paramUserLoginVO.getWeChatCode());
// String weChatId = getAccessTokenDTO.getWeChatId();
// if (weChatId != null && !"".equals(weChatId)) {
// stringRedisTemplate.opsForValue().set("wechat_id"+weChatId,getAccessTokenDTO.getSessionKey());
// }
// }
WechatIdAuthenticationToken token = new WechatIdAuthenticationToken(paramUserLoginVO.getWeChatCode());
request.setAttribute("token", token);
return authenticationManager.authenticate(token);
}
/**
* 登录成功
* 无论以何种方式登录登录成功后都向客户端返回 JWT前端将该 JWT 临时存储到 localStorage 当中以便后续的请求在请求头中携带 JWT
*/
@Override
protected void successfulAuthentication(
HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult
) throws IOException {
Object principal = authResult.getPrincipal();
UserInfoVO userInfoVO = new UserInfoVO();
if (principal instanceof User) {
User user = (User) principal;
BeanUtils.copyProperties(user, userInfoVO);
}
ObjectMapper objectMapper = new ObjectMapper();
String userInfoJSON = objectMapper.writeValueAsString(userInfoVO);
UUID uuid = UUID.randomUUID();
String jwtTokenId = uuid.toString();
// 生成 jwt
String jwt = Jwts.builder()
.claim("userInfo", userInfoJSON)
.setSubject(authResult.getName())
.setExpiration(new Date(System.currentTimeMillis() + 10 * 24 * 60 * 60 * 1000)) // 10天有效
.signWith(SignatureAlgorithm.HS512, "ncst20221003")
.setId(jwtTokenId)
.compact();
stringRedisTemplate.opsForValue().set("jwt_token:"+authResult.getName(),jwt,10, TimeUnit.DAYS);
// stringRedisTemplate.delete("user_attempts:"+request.getRemoteAddr());
// 记录登录日志
loginLogService.addLoginLog(userInfoVO.getUserID(), true);
// 返回结果
ResultVO<String> result = ResultUtils.success("登录成功", jwt);
response.setContentType("application/json;charset=utf-8");
Cookie cookieToken = new Cookie("SYS_TOKEN", jwt);
cookieToken.setHttpOnly(true);
response.addCookie(cookieToken);
log.info("登录成功");
PrintWriter out = response.getWriter();
out.print(new ObjectMapper().writeValueAsString(result));
out.flush();
out.close();
}
// 将权限列表转换成逗号分隔的字符串
private String convertRoleToString(List<Role> roleList) {
StringBuilder roleStrings = new StringBuilder();
if (roleList == null) {
return "";
}
for (Role role : roleList) {
roleStrings.append(role.getName()).append(",");
}
if (roleStrings.length() > 0) {
roleStrings.deleteCharAt(roleStrings.length() - 1);
}
return roleStrings.toString();
}
// 将权限列表转换成逗号分隔的字符串
private String convertAuthorityToString(Collection<? extends GrantedAuthority> authorities) {
StringBuilder authorityString = new StringBuilder();
for (GrantedAuthority authority : authorities) {
authorityString.append(authority.getAuthority()).append(",");
}
if (authorityString.length() > 0) {
authorityString.deleteCharAt(authorityString.length() - 1);
}
return authorityString.toString();
}
/**
* 登录失败
* 向前端返回登录失败的错误信息
*/
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
ResultVO<?> resultVO;
log.debug("登录失败:"+failed);
if (failed instanceof LockedException) {
resultVO = ResultUtils.error(CodeMsg.USER_IS_LOCKED);
} else if (failed instanceof CredentialsExpiredException) {
resultVO = ResultUtils.error(CodeMsg.USER_CREDENTIALS_EXPIRED);
} else if (failed instanceof DisabledException) {
resultVO = ResultUtils.error(CodeMsg.USER_IS_DISABLED);
} else if (failed instanceof AuthenticationException) {
Throwable cause = failed.getCause();
if (cause instanceof BusinessException) {
BusinessException businessException = (BusinessException) cause;
resultVO = ResultUtils.error(businessException.getError());
} else {
resultVO = ResultUtils.error(CodeMsg.USER_BAD_CREDENTIALS);
}
} else {
resultVO = ResultUtils.error(CodeMsg.LOGIN_FAIL);
}
// 拦截后直接将错误信息反馈给前端,不经过全局异常处理器(GlobalExceptionHandler)处理
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
out.write(new ObjectMapper().writeValueAsString(resultVO));
out.flush();
out.close();
}
}

@ -1,64 +0,0 @@
package edu.ncst.ioreport.config.security.provider;
import edu.ncst.ioreport.config.exception.NotBindUserException;
import edu.ncst.ioreport.config.security.token.WechatIdAuthenticationToken;
import edu.ncst.ioreport.service.IUserService;
import edu.ncst.ioreport.utils.WeChatUtils;
import edu.ncst.ioreport.vo.SessionKey;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class WechatIdLoginProvider implements AuthenticationProvider {
@Autowired
private IUserService userService;
@Autowired
private RedisTemplate<String, String> stringRedisTemplate;
@SneakyThrows
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
log.info("进入到微信登录接口");
// 获取 Code
if (!(authentication instanceof WechatIdAuthenticationToken)) {
return null;
}
WechatIdAuthenticationToken token = (WechatIdAuthenticationToken) authentication;
String code = token.getWechatCode();
SessionKey sessionKeyDTO = WeChatUtils.code2session(code,stringRedisTemplate);
if (sessionKeyDTO == null) {
return null;
}
String wechatId = sessionKeyDTO.getWeChatId();
String sessionKey = sessionKeyDTO.getSessionKey();
log.info("小程序登录成功:"+wechatId);
// 查找该 wechatID 已经绑定用户
UserDetails userDetails = userService.loadUserByWechatId(wechatId);
if (userDetails == null) {
throw new NotBindUserException("账号不存在");
} else {
return new WechatIdAuthenticationToken(userDetails);
}
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(WechatIdAuthenticationToken.class);
}
}

@ -1,40 +0,0 @@
package edu.ncst.ioreport.config.security.token;
import edu.ncst.ioreport.model.User;
import edu.ncst.ioreport.vo.result.UserInfoVO;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.List;
/**
* JWT认证凭证Security Context
*/
public class JwtAuthenticationToken extends AbstractAuthenticationToken {
private final Object principal;
private final Object details;
public JwtAuthenticationToken(Object principal, List<GrantedAuthority> authorities, UserInfoVO userInfoVO) {
super(authorities);
this.principal = principal;
this.details = userInfoVO;
this.setAuthenticated(true);
}
@Override
public Object getCredentials() {
return null;
}
@Override
public Object getPrincipal() {
return this.principal;
}
@Override
public Object getDetails() {
return this.details;
}
}

@ -1,39 +0,0 @@
package edu.ncst.ioreport.config.security.token;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;
/**
* 手机验证码方式登录凭证
*/
public class MobileCaptchaAuthenticationToken extends AbstractAuthenticationToken {
// 手机号码
private String phoneNumber;
// 验证码
private String captchaCode;
public MobileCaptchaAuthenticationToken(String phoneNumber, String captchaCode) {
super(null);
this.phoneNumber = phoneNumber;
this.captchaCode = captchaCode;
}
public MobileCaptchaAuthenticationToken(Collection<? extends GrantedAuthority> authorities) {
super(authorities);
}
@Override
public Object getCredentials() {
return this.phoneNumber;
}
@Override
public Object getPrincipal() {
return this.captchaCode;
}
}

@ -1,51 +0,0 @@
package edu.ncst.ioreport.config.security.token;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;
/**
* OpenId 登录
*/
public class WechatIdAuthenticationToken extends AbstractAuthenticationToken {
private String wechatCode;
private final Object principal;
public WechatIdAuthenticationToken(String wechatCode) {
super(null);
this.principal = wechatCode;
this.wechatCode = wechatCode;
}
public WechatIdAuthenticationToken(Object principal) {
super(null);
this.principal = principal;
super.setAuthenticated(true);
}
public WechatIdAuthenticationToken(Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = null;
}
@Override
public Object getCredentials() {
return this.wechatCode;
}
@Override
public Object getPrincipal() {
return this.principal;
}
public String getWechatCode() {
return wechatCode;
}
public void setWechatCode(String wechatCode) {
this.wechatCode = wechatCode;
}
}

@ -1,52 +0,0 @@
//package edu.ncst.ioreport.controller;
//
//import edu.ncst.ioreport.model.IORecords;
//import edu.ncst.ioreport.service.IIORecordService;
//import edu.ncst.ioreport.utils.ResultUtils;
//import edu.ncst.ioreport.vo.ResultVO;
//import edu.ncst.ioreport.vo.param.QRecord;
//import io.swagger.annotations.Api;
//import io.swagger.annotations.ApiOperation;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.web.bind.annotation.*;
//
//import java.util.List;
//
///**
// * 报备记录 控制器
// */
//@Api(description = "出入校报备记录控制器", tags = "IORecordsController")
//@Slf4j
//@RestController
//@RequestMapping("/api/iorecords")
//public class IORecordsController {
//
// @Autowired
// private IIORecordService iioRecordService;
// @ApiOperation("获取报备记录列表")
// @PostMapping("/list")
// public ResultVO<List<IORecords>> getIORecordsList(@RequestBody QRecord param){
// List<IORecords> ioRecordsList = iioRecordService.getIORecordsList(param);
// return ResultUtils.success(ioRecordsList);
// }
// @ApiOperation("获取报备记录列表")
// @PostMapping("/audit-list")
// public ResultVO<List<IORecords>> getIORecordsAuditList(@RequestBody QRecord param){
// List<IORecords> ioRecordsList = iioRecordService.getIORecordsAuditList(param);
// return ResultUtils.success(ioRecordsList);
// }
// @ApiOperation("根据记录ID获取记录详细信息")
// @GetMapping("/detail")
// public ResultVO<IORecords> getIORecordByID(@RequestParam(name = "ID") Integer ID){
// IORecords record = iioRecordService.getIORecordsDetail(ID);
// return ResultUtils.success(record);
// }
//
// @ApiOperation("新增一条报备记录")
// @PostMapping("/add")
// public ResultVO<Integer> addIORecord(@RequestBody IORecords param){
// int id = iioRecordService.addIORecord(param);
// return ResultUtils.success(Integer.valueOf(id));
// }
//}

@ -1,59 +0,0 @@
//package edu.ncst.ioreport.controller;
//
//import edu.ncst.ioreport.exception.BusinessException;
//import edu.ncst.ioreport.service.impl.ImageServiceImpl;
//import edu.ncst.ioreport.utils.FileUtil;
//import edu.ncst.ioreport.utils.SessionUtils;
//import edu.ncst.ioreport.vo.result.UserInfoVO;
//import io.swagger.annotations.Api;
//import io.swagger.annotations.ApiOperation;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.web.bind.annotation.*;
//import org.springframework.web.multipart.MultipartFile;
//
//import javax.servlet.http.HttpServletRequest;
//import java.io.FileNotFoundException;
//import java.io.IOException;
//
//@RestController
//@Slf4j
//@Api(description = "图片上传管理", tags = "ImageController")
//@RequestMapping("/api/image")
//public class ImageController {
//
// @Autowired
// ImageServiceImpl imageService;
//
// // 读取配置文件中上传路径
// @Value("${file.file-dir}")
// String imagePath;
//
//
//
// @ApiOperation("上传图片")
// @PostMapping("/upload")
// public void uploadImage(@RequestParam(value = "file",required = false) MultipartFile file) throws FileNotFoundException {
// UserInfoVO currentUser = SessionUtils.getCurrentUser();
// log.debug("上传图片的用户:" + currentUser.getUserID());
// try {
// imageService.uploadImage(file);
// } catch (IOException e) {
// log.error(e.getMessage());
// }
// }
//
// @ApiOperation("获取文件")
// @GetMapping("/get/{path}/{fileName}")
// public void getImage(@PathVariable String fileName,@PathVariable String path) {
// // UserInfoVO currentUser = SessionUtils.getCurrentUser();
// log.info(imagePath + fileName);
// try {
// FileUtil.downImage(path,fileName);
// }catch (Exception e){
// log.error("下载失败:",e);
// throw new BusinessException(fileName+"下载失败:"+e);
// }
// }
//}

@ -1,49 +0,0 @@
//package edu.ncst.ioreport.controller;
//
//import edu.ncst.ioreport.model.IORecords;
//import edu.ncst.ioreport.model.MaterialUploadRecord;
//import edu.ncst.ioreport.service.IIORecordService;
//import edu.ncst.ioreport.service.IMaterialUploadService;
//import edu.ncst.ioreport.utils.ResultUtils;
//import edu.ncst.ioreport.vo.ResultVO;
//import edu.ncst.ioreport.vo.param.QRecord;
//import io.swagger.annotations.Api;
//import io.swagger.annotations.ApiOperation;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.web.bind.annotation.*;
//
//import java.util.List;
//
///**
// * 报备记录 控制器
// */
//@Api(description = "资料上传记录控制器", tags = "MaterialUploadController")
//@Slf4j
//@RestController
//@RequestMapping("/api/records")
//public class MaterialUploadController {
//
// @Autowired
// private IMaterialUploadService recordService;
// @ApiOperation("获取报备记录列表")
// @PostMapping("/list")
// public ResultVO<List<MaterialUploadRecord>> getIORecordsList(@RequestBody QRecord param){
// List<MaterialUploadRecord> ioRecordsList = recordService.getRecordsList(param);
// return ResultUtils.success(ioRecordsList);
// }
//
// @ApiOperation("根据记录ID获取记录详细信息")
// @GetMapping("/detail")
// public ResultVO<MaterialUploadRecord> getIORecordByID(@RequestParam(name = "ID") Integer ID){
// MaterialUploadRecord record = recordService.getRecordsDetail(ID);
// return ResultUtils.success(record);
// }
//
// @ApiOperation("新增一条报备记录")
// @PostMapping("/add")
// public ResultVO<Integer> addIORecord(@RequestBody MaterialUploadRecord param){
// int id = recordService.addRecord(param);
// return ResultUtils.success(Integer.valueOf(id));
// }
//}

@ -2,18 +2,12 @@ package edu.ncst.ioreport.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.ncst.ioreport.config.security.token.WechatIdAuthenticationToken;
import edu.ncst.ioreport.exception.BusinessException;
import edu.ncst.ioreport.exception.CodeMsg;
import edu.ncst.ioreport.model.User;
import edu.ncst.ioreport.service.IRoleService;
import edu.ncst.ioreport.service.IUserService;
import edu.ncst.ioreport.utils.ResultUtils;
import edu.ncst.ioreport.utils.WeChatUtils;
import edu.ncst.ioreport.vo.ListResultVO;
import edu.ncst.ioreport.vo.ResultVO;
import edu.ncst.ioreport.vo.SessionKey;
import edu.ncst.ioreport.vo.param.QUser;
import edu.ncst.ioreport.vo.param.UserLoginVO;
import io.netty.util.internal.StringUtil;
import io.swagger.annotations.Api;
@ -21,14 +15,15 @@ import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
;import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;
;
/**
* 用户 控制器
@ -68,23 +63,4 @@ public class UserController {
}
//
// @ApiOperation("获取用户列表")
// @GetMapping("/list")
// public ResultVO<ListResultVO<User>> getUserList(QUser query) {
// ListResultVO<User> userList = userService.getUserList(query);
//
// return ResultUtils.success("ok", userList);
// }
//
//
// @ApiOperation("获取当前用户信息")
// @GetMapping("/current")
// public ResultVO<User> getCurrentUser() {
// User currentUserDTO = userService.getCurrentUser();
// // roleService.selectRoleAll();
// return ResultUtils.success(currentUserDTO);
// }
}

@ -1,34 +0,0 @@
package edu.ncst.ioreport.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import java.util.List;
/**
* 自定义 Mapper 接口, 实现 自定义扩展
*
* @param <M> mapper 泛型
* @param <T> table 泛型
* @param <V> vo 泛型
* @author Lion Li
* @since 2021-05-13
*/
@SuppressWarnings("unchecked")
public interface BaseMapperPlus<M, T, V> extends BaseMapper<T> {
Log log = LogFactory.getLog(BaseMapperPlus.class);
int DEFAULT_BATCH_SIZE = 1000;
default List<T> selectList() {
return this.selectList(new QueryWrapper<>());
}
}

@ -1,19 +0,0 @@
package edu.ncst.ioreport.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import edu.ncst.ioreport.model.IORecords;
import edu.ncst.ioreport.model.Resource;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface IORecordsMapper extends BaseMapper<IORecords> {
int insertAndGetId(IORecords record);
List<IORecords> selectAuditList(@Param(Constants.WRAPPER) QueryWrapper<IORecords> queryWrapper);
IORecords selectDetail(@Param(Constants.WRAPPER) QueryWrapper<IORecords> queryWrapper);
}

@ -1,13 +0,0 @@
package edu.ncst.ioreport.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import edu.ncst.ioreport.model.Image;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface ImageMapper extends BaseMapper<Image> {
int uploadImage(@Param("image")Image image);
}

@ -1,19 +0,0 @@
package edu.ncst.ioreport.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import edu.ncst.ioreport.model.IORecords;
import edu.ncst.ioreport.model.MaterialUploadRecord;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface MaterialUploadMapper extends BaseMapper<MaterialUploadRecord> {
int insertAndGetId(MaterialUploadRecord record);
List<MaterialUploadRecord> selectRecordList(@Param(Constants.WRAPPER) QueryWrapper<MaterialUploadRecord> queryWrapper);
MaterialUploadRecord selectDetail(@Param(Constants.WRAPPER) QueryWrapper<MaterialUploadRecord> queryWrapper);
}

@ -1,9 +0,0 @@
package edu.ncst.ioreport.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import edu.ncst.ioreport.model.Resource;
import org.springframework.stereotype.Repository;
@Repository
public interface ResourceMapper extends BaseMapper<Resource> {
}

@ -1,25 +0,0 @@
package edu.ncst.ioreport.mapper;
import edu.ncst.ioreport.model.Role;
import java.util.List;
/**
* 角色表 数据层
*
* @author Lion Li
*/
public interface RoleMapper extends BaseMapperPlus<RoleMapper, Role, Role> {
/**
* 根据条件分页查询角色数据
*
* @param role 角色信息
* @return 角色数据集合信息
*/
List<Role> selectRoleList(Role role);
}

@ -1,26 +0,0 @@
package edu.ncst.ioreport.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import edu.ncst.ioreport.model.User;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 用户 Mapper 接口
*/
@Repository
public interface UserMapper extends BaseMapper<User> {
List<User> getUserList( @Param(Constants.WRAPPER) QueryWrapper queryWrapper);
User getUserDetail(Integer userId);
User getByWechatId(String wechatId);
}

@ -1,18 +0,0 @@
package edu.ncst.ioreport.model;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ApiModel(value="Department", description="二级学院")
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("Department")
public class Department {
@ApiModelProperty(value = "部门编码")
private String departmentID;
@ApiModelProperty(value = "部门名称")
private String department;
}

@ -1,97 +0,0 @@
package edu.ncst.ioreport.model;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import edu.ncst.ioreport.vo.QRToken;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* 角色
*/
@ApiModel(value="IORecords", description="报备记录")
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("IORecords")
public class IORecords {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "报备记录ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "教师工号")
@NotNull(message = "教师信息不能为空")
private String teacherID;
@ApiModelProperty(value = "报备单类型:1-出;0-入")
@NotNull(message = "报备类型不能为空")
private String ioType;
@ApiModelProperty(value = "校外居住地")
@NotNull(message = "校外居住地不能为空")
private String outerResidence;
@ApiModelProperty(value = "校内居住地")
@NotNull(message = "校内居住地不能为空")
private String innerResidence;
@ApiModelProperty(value = "申请事由")
@NotNull(message = "申请事由不能为空")
private String reason;
@ApiModelProperty(value = "出入校时间")
@NotNull(message = "出入校时间不能为空")
@JSONField(format = "yyyy-MM-dd HH:mm")
private Date commitTime;
@ApiModelProperty(value = "院级审核人")
private Integer deptAuditorID;
@ApiModelProperty(value = "院级审核时间")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date deptAuditTime;
@ApiModelProperty(value = "校级审核人")
private Integer schoolAuditorID;
@ApiModelProperty(value = "校级审核时间")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date schoolAuditTime;
@ApiModelProperty(value = "核验人")
private Integer validatorID;
@ApiModelProperty(value = "核验时间")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date validateTime;
@ApiModelProperty(value = "单据状态:SUBMIT-提交待审核;DEPT_PASS-院级审核通过;SCHOOL_PASS-校级审核通过;VERIFY_PASS-核验通过;DEPT_DENY-院级审核不通过;SCHOOL_DENY-校级审核不通过;VERIFY_DENY-核验不通过;INVALID-无效")
private String status;
@ApiModelProperty(value = "教师")
@TableField(exist = false)
private User teacher;
@ApiModelProperty(value = "院级审核人")
@TableField(exist = false)
private User deptAuditor;
@ApiModelProperty(value = "校级审核人")
@TableField(exist = false)
private User schoolAuditor;
@ApiModelProperty(value = "核验人")
@TableField(exist = false)
private User validator;
@ApiModelProperty(value = "二维码token")
@TableField(exist = false)
private QRToken qrToken;
}

@ -1,41 +0,0 @@
package edu.ncst.ioreport.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
* 图片
*/
@ApiModel(value="MaterialUploadRecord", description="资料上传")
@Data
@TableName(value = "materialUploadRecord")
public class Image {
@ApiModelProperty(value = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty("图片的线上地址")
private String imagePath;
@ApiModelProperty("图片的线上地址")
private String materialType;
@ApiModelProperty("图片的base64编码")
private String base64Str;
@ApiModelProperty("图片名称")
private String imgName;
@ApiModelProperty("图片上传时间")
private Date uploadTime;
@ApiModelProperty("图片上传用户")
private String userId;
}

@ -1,49 +0,0 @@
package edu.ncst.ioreport.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
/**
* 登录日志
*/
@ApiModel(value="LoginLog", description="登录日志")
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("log_login_log")
public class LoginLog implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "登录方式")
private String type;
@ApiModelProperty(value = "用户ID")
private Integer userId;
@ApiModelProperty(value = "登錄用户")
@TableField(exist = false)
private User user;
@ApiModelProperty(value = "登录凭证", notes = "用户名、手机号、电子邮箱或微信登录凭证code")
private String principal;
@ApiModelProperty(value = "IP地址")
private String ipAddress;
@ApiModelProperty(value = "登录时间")
private Date loginTime;
}

@ -1,64 +0,0 @@
package edu.ncst.ioreport.model;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
* 图片
*/
@ApiModel(value="MaterialUploadRecord", description="资料上传")
@Data
@TableName(value = "materialUploadRecord")
public class MaterialUploadRecord {
@ApiModelProperty(value = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty("图片存储地址")
private String imagePath;
@ApiModelProperty("资料类型")
private String materialType;
@ApiModelProperty("资料上传时间")
@JSONField(format = "yyyy-MM-dd HH:mm")
private Date uploadTime;
@ApiModelProperty("核酸报告生成时间")
@JSONField(format = "yyyy-MM-dd HH:mm")
private Date genTime;
@ApiModelProperty("核酸检测时间")
@JSONField(format = "yyyy-MM-dd HH:mm")
private Date testResultTime;
@ApiModelProperty("健康码状态")
private String healthStatus;
@ApiModelProperty("行程码刷新时间")
@JSONField(format = "yyyy-MM-dd HH:mm")
private Date travelRefreshTime;
@ApiModelProperty("行程码状态")
private String travelStatus;
@ApiModelProperty("行程")
private String travelPlaces;
@ApiModelProperty("上传用户")
private String userId;
@ApiModelProperty("姓名")
private String name;
@ApiModelProperty("身份证号")
private String IDCode;
@ApiModelProperty("电话")
private String mobile;
@ApiModelProperty(value = "教师")
@TableField(exist = false)
private User teacher;
}

@ -1,55 +0,0 @@
package edu.ncst.ioreport.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.List;
@ApiModel(value="Resource", description="资源")
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("sys_resource")
public class Resource implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "资源ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "显示文本")
private String label;
@ApiModelProperty(value = "资源名称(方法签名)")
private String name;
@ApiModelProperty(value = "请求方法类型")
private String method;
@ApiModelProperty(value = "链接")
private String url;
@ApiModelProperty(value = "允许所有访问", notes = "不需要用户登录")
private Boolean permitAll = false;
@ApiModelProperty(value = "上级菜单ID")
private Integer parentId;
@ApiModelProperty(value = "上级菜单ID")
@TableField(exist = false)
private List<Resource> children;
@ApiModelProperty(value = "排序")
private Integer sort;
@ApiModelProperty(value = "是否對所有角色開放",notes = "需要用户登录")
private Boolean isForAll = true;
}

@ -1,58 +0,0 @@
package edu.ncst.ioreport.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import java.util.Objects;
/**
* 角色
*/
@ApiModel(value="Role", description="角色")
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("sys_role")
public class Role {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "角色ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "角色名称")
private String name;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Role role = (Role) o;
return Objects.equals(name, role.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
public static Role forName(String name) {
Role role = new Role();
role.setName(name);
return role;
}
}

@ -1,102 +0,0 @@
package edu.ncst.ioreport.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
@ApiModel(value="User", description="用户")
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("user")
public class User implements Serializable, UserDetails {
@ApiModelProperty(value = "用户id")
private String userID;
@ApiModelProperty(value = "用户名(微信名)")
private String userName;
@ApiModelProperty(value = "教师工号")
private String teacherID;
@ApiModelProperty(value = "用户姓名")
private String name;
@ApiModelProperty(value = "地址信息")
private String address;
@ApiModelProperty(value = "密码")
private String password;
@ApiModelProperty(value = "手机号")
private String mobile;
@ApiModelProperty(value = "所属单位")
private Integer departmentID;
@ApiModelProperty(value = "微信小程序id")
private Integer wechatID;
@ApiModelProperty(value = "角色列表")
@TableField(exist = false)
private List<String> roles;
@ApiModelProperty(value = "所属学院")
@TableField(exist = false)
private Department dept;
@ApiModelProperty(value = "是否在校 1:在校 0:未在")
private Boolean isInSchool;
@ApiModelProperty(value = "是否在校 1:在校 0:未在")
private Boolean enabled;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
if (this.roles != null && this.roles.size() > 0) {
List<GrantedAuthority> roleAuthority = roles.stream()
.map((role) -> new SimpleGrantedAuthority("ROLE_" + role))
.collect(Collectors.toList());
grantedAuthorities.addAll(roleAuthority);
}
return grantedAuthorities;
}
@Override
public String getPassword() {
return "";
}
@Override
public String getUsername() {
return teacherID;
}
@JsonIgnore
public boolean isAccountNonExpired() {
return true;
}//用户是否未过期
@JsonIgnore
@Override
public boolean isAccountNonLocked() {
return true;
}//用户是否未锁定
@JsonIgnore
@Override
public boolean isCredentialsNonExpired() {
return true;
}//凭证是否未过期
@Override
public boolean isEnabled() {
return true;
}//是否启用
}

@ -1,17 +0,0 @@
package edu.ncst.ioreport.service;
import edu.ncst.ioreport.model.IORecords;
import edu.ncst.ioreport.vo.param.QRecord;
import java.util.List;
public interface IIORecordService {
List<IORecords> getIORecordsList(QRecord query);
IORecords getIORecordsDetail(Integer ID);
int addIORecord(IORecords record);
List<IORecords> getIORecordsAuditList(QRecord param);
}

@ -1,18 +0,0 @@
package edu.ncst.ioreport.service;
import com.baomidou.mybatisplus.extension.service.IService;
import edu.ncst.ioreport.model.Image;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
/**
* 图片处理 服务类
* */
public interface IImageService extends IService<Image> {
void uploadImage(@RequestParam MultipartFile uploadFile) throws IOException;
}

@ -1,18 +0,0 @@
package edu.ncst.ioreport.service;
import edu.ncst.ioreport.model.LoginLog;
import edu.ncst.ioreport.vo.ListResultVO;
import edu.ncst.ioreport.vo.param.QLoginLog;
/**
* 登录日志 服务类
*/
public interface ILoginLogService {
// 查询登录日志列表
ListResultVO<LoginLog> getLoginLogList(QLoginLog query);
// 添加登录日志
void addLoginLog(String userId, Boolean success);
}

@ -1,16 +0,0 @@
package edu.ncst.ioreport.service;
import edu.ncst.ioreport.model.IORecords;
import edu.ncst.ioreport.model.MaterialUploadRecord;
import edu.ncst.ioreport.vo.param.QRecord;
import java.util.List;
public interface IMaterialUploadService {
MaterialUploadRecord getRecordsDetail(Integer ID);
int addRecord(MaterialUploadRecord record);
List<MaterialUploadRecord> getRecordsList(QRecord param);
}

@ -1,22 +0,0 @@
package edu.ncst.ioreport.service;
import edu.ncst.ioreport.model.Resource;
import edu.ncst.ioreport.vo.ListResultVO;
import edu.ncst.ioreport.vo.Query;
import java.util.List;
public interface IResourceService {
List<Resource> getResourceList(Query query);
List<Integer> getRoleResourceIds(Integer roleId);
List<String> getRolesResourceList(List<String> roleNames);
List<Resource> getPermitAllResourceList();
List<String> getPermitAllResourceURLs();
}

@ -1,26 +0,0 @@
package edu.ncst.ioreport.service;
import edu.ncst.ioreport.model.Role;
import java.util.List;
/**
* 角色业务层
*
*/
public interface IRoleService {
List<Role> insertRole() ;
List<Role> selectRoleList(Role role);
/**
* 查询所有角色
*
* @return 角色列表
*/
List<Role> selectRoleAll();
}

@ -1,17 +0,0 @@
package edu.ncst.ioreport.service;
import edu.ncst.ioreport.model.User;
import edu.ncst.ioreport.vo.ListResultVO;
import edu.ncst.ioreport.vo.param.QUser;
import org.springframework.security.core.userdetails.UserDetails;
public interface IUserService {
User getUserInfo(QUser query);
ListResultVO<User> getUserList(QUser query);
User getCurrentUser();
UserDetails loadUserByWechatId(String wechatId);
}

@ -1,132 +0,0 @@
package edu.ncst.ioreport.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.sun.org.apache.xpath.internal.operations.Bool;
import edu.ncst.ioreport.exception.BusinessException;
import edu.ncst.ioreport.exception.CodeMsg;
import edu.ncst.ioreport.mapper.IORecordsMapper;
import edu.ncst.ioreport.model.IORecords;
import edu.ncst.ioreport.model.User;
import edu.ncst.ioreport.service.IIORecordService;
import edu.ncst.ioreport.utils.SessionUtils;
import edu.ncst.ioreport.vo.QRToken;
import edu.ncst.ioreport.vo.param.QRecord;
import edu.ncst.ioreport.vo.result.UserInfoVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
@Service
public class IORecordServiceImpl implements IIORecordService {
@Autowired
private IORecordsMapper recordsMapper;
@Autowired
private RedisTemplate<String, String> stringRedisTemplate;
@Override
public List<IORecords> getIORecordsList(QRecord query) {
IORecords ioRecords = new IORecords();
ioRecords.setTeacherID(query.getTeacherID());
ioRecords.setStatus(query.getStatus());
ioRecords.setIoType(query.getType());
QueryWrapper<IORecords> queryWrapper = new QueryWrapper(ioRecords);
List<IORecords> list = recordsMapper.selectList(queryWrapper);
return list;
}
@Override
public List<IORecords> getIORecordsAuditList(QRecord query) {
IORecords ioRecords = new IORecords();
UserInfoVO user = SessionUtils.getCurrentUser();
if(user.getTeacherID().compareTo(query.getTeacherID()) !=0){
throw new BusinessException(CodeMsg.BUSINESS_ERROR.fillArgs("用户信息不匹配"));
}
Boolean canAccess = false;
Boolean schoolAudit = false;
for(String role:user.getRoles()){
if(role.contains("ADMIN")){
canAccess=true;
if(role.compareTo("S_ADMIN")==0){
schoolAudit = true;
}
}
}
if(!canAccess){
throw new BusinessException(CodeMsg.CAN_NOT_DATA_ACCESS);
}
QueryWrapper<IORecords> queryWrapper = new QueryWrapper(ioRecords);
queryWrapper.eq(query.getStatus()!=null,"status",query.getStatus());
queryWrapper.eq(query.getType()!=null,"ioType",query.getType());
if(schoolAudit){
queryWrapper.eq(query.getStatus()==null,"status","DEPT_PASS");
}else{
queryWrapper.eq("uu.departmentID",user.getDepartmentID());
queryWrapper.eq(query.getStatus()==null,"status","SUBMIT");
}
List<IORecords> list = recordsMapper.selectAuditList(queryWrapper);
return list;
}
@Override
public IORecords getIORecordsDetail(Integer ID) {
if(null==ID){
throw new BusinessException(CodeMsg.PARAM_ERROR.fillArgs("记录单ID为空"));
}
QueryWrapper<IORecords> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id",ID);
IORecords records = recordsMapper.selectDetail(queryWrapper);
if(records.getStatus().compareTo("SCHOOL_PASS")==0){
if(!stringRedisTemplate.hasKey("qrToken_"+ID)){
QRToken qrToken = new QRToken();
qrToken.setRecordID(ID);
stringRedisTemplate.opsForValue().set("qrToken_"+ID,JSON.toJSONString(qrToken),1, TimeUnit.MINUTES);
}
String qrTokenStr = stringRedisTemplate.opsForValue().get("qrToken_"+ID);
QRToken qrToken = JSON.parseObject(qrTokenStr,QRToken.class);
if(qrToken!=null){
Long seconds = stringRedisTemplate.getExpire("qrToken_"+ID);
qrToken.setExpireTime(seconds);
records.setQrToken(qrToken);
}
}
if(null==records){
throw new BusinessException("记录不存在");
}
return records;
}
public IORecords getIORecordsDetail(String states){
return null;
}
@Override
public int addIORecord(IORecords record) {
UserInfoVO user = SessionUtils.getCurrentUser();
List<String> roles = user.getRoles();
if(roles==null||(roles.size()==1&&user.getRoles().get(0).compareTo("DOORMEN")==0)){
throw new BusinessException(CodeMsg.CAN_NOT_DATA_ACCESS);
}
if(user.getTeacherID().compareTo(record.getTeacherID())!=0){
throw new BusinessException(CodeMsg.BUSINESS_ERROR.fillArgs("当前用户为"+user.getTeacherID()+",与单据中提交人不一致"));
}
record.setStatus("SUBMIT");
int id = recordsMapper.insertAndGetId(record);
if(id==1){
return record.getId();
}else{
throw new BusinessException(CodeMsg.ADD_ERROR);
}
}
}

@ -1,66 +0,0 @@
package edu.ncst.ioreport.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.ncst.ioreport.mapper.ImageMapper;
import edu.ncst.ioreport.model.Image;
import edu.ncst.ioreport.service.IImageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
/**
* 图片上传服务 实现类
* */
@Service
@Slf4j
public class ImageServiceImpl extends ServiceImpl<ImageMapper, Image>
implements IImageService {
// 读取配置文件中上传路径
@Value("${file.file-dir}")
public String uploadFilePath;
@Autowired
ImageMapper imageMapper;
@Override
public void uploadImage(@RequestParam MultipartFile newfile) throws IOException {
log.info("文件信息" + newfile);
// 获取存放文件的目录
File serverPath = new File(uploadFilePath);
if (!serverPath.exists()) {
serverPath.mkdirs();
}
//命名图片文件
String fileName = newfile.getOriginalFilename();
OutputStream outputStream = null; //存储图片文件
try {
File file = new File(serverPath, fileName); //在服务器上创建文件
log.info(file.getAbsolutePath());
if(file.exists()){
file.delete();
}
outputStream = new FileOutputStream(file);
InputStream is = newfile.getInputStream();
FileCopyUtils.copy(is, outputStream);//将文件写入到服务器文件
} catch (IOException e) {
log.error(e.getMessage());
}finally {
if(outputStream!=null){
outputStream.close();
}
}
}
}

@ -1,27 +0,0 @@
package edu.ncst.ioreport.service.impl;
import edu.ncst.ioreport.model.LoginLog;
import edu.ncst.ioreport.service.ILoginLogService;
import edu.ncst.ioreport.vo.ListResultVO;
import edu.ncst.ioreport.vo.param.QLoginLog;
import org.springframework.stereotype.Service;
/**
* 登录日志 服务实现类
*/
@Service
public class LoginLogServiceImpl implements ILoginLogService {
@Override
public ListResultVO<LoginLog> getLoginLogList(QLoginLog query) {
return null;
}
@Override
public void addLoginLog(String userId, Boolean success) {
}
//project/declarationAdd
}

@ -1,77 +0,0 @@
package edu.ncst.ioreport.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import edu.ncst.ioreport.exception.BusinessException;
import edu.ncst.ioreport.exception.CodeMsg;
import edu.ncst.ioreport.mapper.IORecordsMapper;
import edu.ncst.ioreport.mapper.MaterialUploadMapper;
import edu.ncst.ioreport.model.IORecords;
import edu.ncst.ioreport.model.MaterialUploadRecord;
import edu.ncst.ioreport.service.IIORecordService;
import edu.ncst.ioreport.service.IMaterialUploadService;
import edu.ncst.ioreport.utils.SessionUtils;
import edu.ncst.ioreport.vo.QRToken;
import edu.ncst.ioreport.vo.param.QRecord;
import edu.ncst.ioreport.vo.result.UserInfoVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Service
public class MaterialUploadServiceImpl implements IMaterialUploadService {
@Autowired
private MaterialUploadMapper recordsMapper;
@Autowired
private RedisTemplate<String, String> stringRedisTemplate;
@Override
public List<MaterialUploadRecord> getRecordsList(QRecord query) {
MaterialUploadRecord record = new MaterialUploadRecord();
record.setUserId(query.getUserID());
record.setMaterialType(query.getType());
QueryWrapper<MaterialUploadRecord> queryWrapper = new QueryWrapper(record);
queryWrapper.orderByDesc("UploadTime");
queryWrapper.last(query.getCount()!=null&&query.getCount()>0,"limit "+query.getCount());
List<MaterialUploadRecord> list = recordsMapper.selectList(queryWrapper);
return list;
}
@Override
public MaterialUploadRecord getRecordsDetail(Integer ID) {
if(null==ID){
throw new BusinessException(CodeMsg.PARAM_ERROR.fillArgs("记录单ID为空"));
}
QueryWrapper<MaterialUploadRecord> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id",ID);
MaterialUploadRecord record = recordsMapper.selectDetail(queryWrapper);
if(null==record){
throw new BusinessException("记录不存在");
}
return record;
}
@Override
public int addRecord(MaterialUploadRecord record) {
UserInfoVO user = SessionUtils.getCurrentUser();
List<String> roles = user.getRoles();
if(roles==null||(roles.size()==1&&user.getRoles().get(0).compareTo("DOORMEN")==0)){
throw new BusinessException(CodeMsg.CAN_NOT_DATA_ACCESS);
}
if(user.getUserID().compareTo(record.getUserId())!=0){
throw new BusinessException(CodeMsg.BUSINESS_ERROR.fillArgs("当前用户为"+user.getTeacherID()+",与单据中提交人不一致"));
}
int id = recordsMapper.insertAndGetId(record);
if(id==1){
return record.getId();
}else{
throw new BusinessException(CodeMsg.ADD_ERROR);
}
}
}

@ -1,64 +0,0 @@
package edu.ncst.ioreport.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import edu.ncst.ioreport.mapper.ResourceMapper;
import edu.ncst.ioreport.model.Resource;
import edu.ncst.ioreport.service.IResourceService;
import edu.ncst.ioreport.vo.ListResultVO;
import edu.ncst.ioreport.vo.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;
import java.lang.reflect.Method;
import java.util.*;
@Service
public class ResourceServiceImpl implements IResourceService {
@Autowired
private ResourceMapper resourceMapper;
// 欲扫描的包路径
private static final String SCAN_PACKAGE = "edu.ncst.ioreport.controller";
/**
* 获取资源列表
*/
@Override
public List<Resource> getResourceList(Query query) {
QueryWrapper<Resource> queryWrapper = new QueryWrapper<>();
List<Resource> resources = resourceMapper.selectList(queryWrapper);
return resources;
}
@Override
public List<Integer> getRoleResourceIds(Integer roleId) {
List<Integer> urls = new ArrayList<>();
urls.add(1);
return urls;
}
@Override
public List<String> getRolesResourceList(List<String> roleNames) {
return null;
}
@Override
public List<Resource> getPermitAllResourceList() {
return null;
}
//允许所有登录用户访问的接口列表
@Override
public List<String> getPermitAllResourceURLs() {
List<String> urls = new ArrayList<>();
urls.add("/api/user/current");
urls.add("/api/records/detail");
urls.add("/api/records/list");
urls.add("/api/records/add");
urls.add("/api/image/get/*");
return urls;
}
}

@ -1,55 +0,0 @@
package edu.ncst.ioreport.service.impl;
import edu.ncst.ioreport.mapper.RoleMapper;
import edu.ncst.ioreport.model.Role;
import edu.ncst.ioreport.service.IRoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
/**
* 角色 业务层处理
*
* @author Lion Li
*/
@RequiredArgsConstructor
@Service
public class RoleServiceImpl implements IRoleService {
private final RoleMapper baseMapper;
/**
* 根据条件分页查询角色数据
*
* @param role 角色信息
* @return 角色数据集合信息
*/
@Override
public List<Role> selectRoleList(Role role) {
return baseMapper.selectRoleList(role);
}
/**
* 查询所有角色
*
* @return 角色列表
*/
@Override
public List<Role> selectRoleAll() {
RoleServiceImpl x = (RoleServiceImpl) AopContext.currentProxy();
return x.selectRoleList(new Role());
}
@Override
@Transactional
public List<Role> insertRole() {
RoleServiceImpl x = (RoleServiceImpl) AopContext.currentProxy();
return x.selectRoleList(new Role());
}
}

@ -1,111 +0,0 @@
package edu.ncst.ioreport.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.ncst.ioreport.exception.BusinessException;
import edu.ncst.ioreport.exception.CodeMsg;
import edu.ncst.ioreport.mapper.UserMapper;
import edu.ncst.ioreport.model.Department;
import edu.ncst.ioreport.model.User;
import edu.ncst.ioreport.service.IUserService;
import edu.ncst.ioreport.utils.SessionUtils;
import edu.ncst.ioreport.vo.ListResultVO;
import edu.ncst.ioreport.vo.param.QUser;
import edu.ncst.ioreport.vo.result.UserInfoVO;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService, UserDetailsService {
private final UserMapper userMapper;
public UserServiceImpl(UserMapper userMapper) {
this.userMapper = userMapper;
}
@Override
public User getUserInfo(QUser query) {
User vo = new User();
vo.setTeacherID("1");
vo.setAddress("address 1111111");
vo.setUserName("zhangsan");
vo.setName("张三");
return vo;
}
@Override
public ListResultVO<User> getUserList(QUser query) {
User user = new User();
user.setAddress("address 1111111");
user.setTeacherID("1");
user.setName("张三");
user.setIsInSchool(true);
ListResultVO listResultVO = new ListResultVO();
List list = new ArrayList<>();
list.add(user);
listResultVO.setList(list);
return listResultVO;
}
@Override
public User getCurrentUser() {
UserInfoVO userinfo = SessionUtils.getCurrentUser();
if(userinfo==null){
throw new BusinessException(CodeMsg.USER_NEED_LOGIN);
}
User user = new User();
BeanUtils.copyProperties(userinfo,user);
Department dept =new Department();
dept.setDepartment("人工智能");
dept.setDepartmentID("1");
user.setDept(dept);
user.setMobile("123344444");
return user;
}
//根据wechatID获取用户信息
public UserDetails loadUserByWechatId2(String wechatId){
if(wechatId == null){
throw new BusinessException(CodeMsg.NOT_GET_CURRENT_USER_INFO);
}
User user = userMapper.getByWechatId(wechatId);
return user;
}
@Override
public UserDetails loadUserByWechatId(String wechatId) {
//用你的数据库信息来替换,查库获取用户信息'
User user = new User();
user.setAddress("address 1111111");
user.setTeacherID("1");
user.setUserID("1");
user.setName("张三");
List<String> roles = new ArrayList<>();
roles.add("S_ADMIN");//Teacher;DOORMEN;D_ADMIN;ADMIN
user.setRoles(roles);
user.setIsInSchool(true);
Department dept =new Department();
dept.setDepartment("人工智能");
dept.setDepartmentID("1");
user.setDept(dept);
return user;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = new User();
user.setAddress("address 1111111");
user.setTeacherID("1");
user.setName("张三");
List<String> roles = new ArrayList<>();
roles.add("S_ADMIN");
user.setIsInSchool(true);
return user;
}
}

@ -1,79 +0,0 @@
package edu.ncst.ioreport.utils;
import lombok.experimental.UtilityClass;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
@UtilityClass
public class CaptchaUtil {
private int width = 200;
private int height = 50;
public BufferedImage createImage() {
return new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
}
public String drawRandomText(BufferedImage verifyImg) {
Graphics2D graphics = (Graphics2D) verifyImg.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, width, height);
Font font = new Font("Bitmap", Font.PLAIN, 54);
graphics.setFont(font);
String baseNumLetter = "123456789abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
StringBuilder stringBuffer = new StringBuilder();
int x = 10;
String ch = "";
Random random = new Random();
for (int i = 0; i < 4; i++) {
graphics.setColor(getRandomColor());
// 设置字体旋转角度(控制小于30度)
int degree = random.nextInt() % 30;
int dot = random.nextInt(baseNumLetter.length());
ch = baseNumLetter.charAt(dot) + "";
stringBuffer.append(ch);
// 正向旋转
graphics.rotate(degree * Math.PI / 180, x, 45);
graphics.drawString(ch, x, 45);
// 反向旋转
graphics.rotate(-degree * Math.PI / 180, x, 45);
x += 48;
}
// 绘制干扰线
for (int i = 0; i < 6; i++) {
graphics.setColor(getRandomColor());
graphics.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));
}
// 绘制噪点
for (int i = 0; i < 30; i++) {
int x1 = random.nextInt(width);
int y1 = random.nextInt(height);
graphics.setColor(getRandomColor());
graphics.fillRect(x1, y1, 2, 1);
}
return stringBuffer.toString();
}
/***
* 取随机颜色
*/
private Color getRandomColor() {
Random random = new Random();
return new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
}
}

@ -1,29 +0,0 @@
package edu.ncst.ioreport.utils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
public class CookieUtils {
/**
* 获取指定的 Cookie
*/
public static Cookie getCookie(HttpServletRequest request, String name) {
if (name == null || "".equalsIgnoreCase(name)) {
return null;
}
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName() != null && name.equals(cookie.getName())) {
return cookie;
}
}
}
return null;
}
}

@ -1,130 +0,0 @@
package edu.ncst.ioreport.utils;
import edu.ncst.ioreport.config.FileIOConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
@Component
@Slf4j
public class FileUtil {
private static FileIOConfig fileIOConfig;
@Autowired
public void setFileIOConfig(FileIOConfig fileIOConfig) {
this.fileIOConfig = fileIOConfig;
}
public static File saveUpload(MultipartFile file,String filePath) throws IOException {
String fullPath=fileIOConfig.getFileDir();
if(filePath!=null){
fullPath=fullPath+ File.separator+filePath;
}
File parent = new File(fullPath);
if (!parent.exists()) {
parent.mkdirs();
}
String suffix = "";
String prefix = "";
String originalFilename = file.getOriginalFilename();
int beginIndex = originalFilename.lastIndexOf(".");
if (beginIndex != -1) {
suffix = originalFilename.substring(beginIndex);
prefix = originalFilename.substring(0,beginIndex);
}
// 执行保存文件
File dest = new File(parent, prefix+System.currentTimeMillis()+suffix);
file.transferTo(dest);
return dest;
}
public static String getFullPath(String filePath, String fileName){
String fullPath=fileIOConfig.getFileDir();
if(filePath!=null){
fullPath=fullPath+File.separator+ filePath;
}
File parent = new File(fullPath);
if (!parent.exists()) {
parent.mkdirs();
}
fullPath=fullPath+File.separator+fileName;
return fullPath;
}
public static void downFile(String filePath,String fileName){
downLoadFile("application/octet-stream",filePath,fileName);
}
public static void downImage(String filePath,String fileName){
downLoadFile("image/jpeg",filePath,fileName);
}
// 下载文件
private static void downLoadFile(String contentType,String filePath, String fileName){
String fullPath = fileIOConfig.getFileDir();
if(Strings.isEmpty(fileName)){
return;
}
if(filePath != null){
fullPath = fullPath + File.separator+ filePath + File.separator+fileName;
}else{
fullPath = fullPath + File.separator+ fileName;
}
File file = new File(fullPath);
HttpServletResponse response= SessionUtils.getResponse();
if (file.exists()) {
// 配置文件下载
response.setContentType(contentType);
response.setCharacterEncoding("utf-8");
// 下载文件能正常显示中文
response.setHeader("FileName", fileName);
response.setHeader("Cache-Control", "no-store, no-cache");
response.setContentType("application/octet-stream");
//配置https的下载
response.setHeader("Pragma", "public");
response.setHeader("Cache-Control", "public");
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") );
input = new BufferedInputStream(new FileInputStream(file));
output = new BufferedOutputStream(response.getOutputStream());
byte[] buffer = new byte[8192];
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
} catch (Exception e) {
log.info("Download the song failed!");
} finally {
if (output != null) try { output.close(); } catch (IOException ignore) {}
if (input != null) try { input.close(); } catch (IOException ignore) {}
}
} else {
try {
//设置响应的数据类型是html文本,并且告知浏览器,使用UTF-8 来编码。
response.setContentType("text/html;charset=UTF-8");
response.setHeader("Content-Type", "text/html;charset=UTF-8");
OutputStream os = response.getOutputStream();
os.write("对应文件不存在".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

@ -1,56 +0,0 @@
package edu.ncst.ioreport.utils;
import edu.ncst.ioreport.exception.BusinessException;
import edu.ncst.ioreport.exception.CodeMsg;
import edu.ncst.ioreport.model.User;
import edu.ncst.ioreport.service.IUserService;
import edu.ncst.ioreport.vo.result.UserInfoVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
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 javax.servlet.http.HttpServletResponse;
import java.util.Objects;
/**
* 会话工具类
*/
@Component
public class SessionUtils {
@Autowired
private IUserService userService;
// 获取当前用户
public static UserInfoVO getCurrentUser() {
SecurityContext context = SecurityContextHolder.getContext();
if (context == null || context.getAuthentication() == null || context.getAuthentication().getDetails() == null) {
throw new BusinessException(CodeMsg.NOT_GET_CURRENT_USER_INFO);
}
return (UserInfoVO) context.getAuthentication().getDetails();
}
// 获取当前用户标识
public static Object getCurrentPrincipal() {
SecurityContext context = SecurityContextHolder.getContext();
return context.getAuthentication().getPrincipal();
}
// 获取当前 Request
public static HttpServletRequest getRequest() {
return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
}
// 获取当前 Response
public static HttpServletResponse getResponse() {
return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getResponse();
}
}

@ -1,25 +0,0 @@
package edu.ncst.ioreport.utils;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Component;
/**
* spring工具类
*
* @author Lion Li
*/
@Component
public final class SpringUtils{
/**
* 获取aop代理对象
*
* @param invoker
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getAopProxy(T invoker) {
return (T) AopContext.currentProxy();
}
}

@ -1,27 +0,0 @@
package edu.ncst.ioreport.utils;
public class URLUtils {
public static String removeQueryString(String url) {
int a = url.indexOf("?");
int b = url.indexOf("#");
int deleteStart = 0;
if (a == -1 && b == -1) {
deleteStart = -1;
} else if (a != -1 && b != -1) {
deleteStart = Math.min(a, b);
} else if (a == -1) {
deleteStart = b;
} else {
deleteStart = a;
}
if (deleteStart != -1) {
return url.substring(0, deleteStart);
} else {
return url;
}
}
}

@ -1,30 +0,0 @@
package edu.ncst.ioreport.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.List;
@ApiModel(value = "ListResultVO", description = "分页列表数据")
@Data
@EqualsAndHashCode(callSuper = false)
public class ListResultVO<T> implements Serializable {
private static final long serialVersionUID = -8896090499552990782L;
@ApiModelProperty(value = "列表数据")
private List<T> list;
@ApiModelProperty(value = "记录总数")
private Long total;
@ApiModelProperty(value = "每页记录数")
private Long pageSize;
@ApiModelProperty(value = "当前页码")
private Long current;
}

@ -1,21 +0,0 @@
package edu.ncst.ioreport.vo;
import lombok.Data;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
@Data
public class QRToken {
private Integer recordID;
private Date expireTime;
public void setExpireTime(Long time){
Calendar calendar=Calendar.getInstance();
if(time!=null&&time>0){
calendar.add(Calendar.SECOND, time.intValue());
}
this.expireTime = calendar.getTime();
}
}

@ -1,61 +0,0 @@
package edu.ncst.ioreport.vo;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import java.io.Serializable;
@ApiModel(description = "查询参数")
@Data
public class Query implements Serializable {
private static final long serialVersionUID = 4617734867110140874L;
// 排序方式
private String sorter;
// 页码
private Integer current = 1;
// 每页记录数
private Integer pageSize = 10;
// 转换为 Pageable
public <T> Page<T> toPageRequest() {
return new Page<>(current, pageSize);
}
// 转换为 Sorter 对象
public Sorter toSorter() {
if (sorter == null) {
return null;
}
if (sorter.endsWith("_ascend")) {
String key = sorter.replace("_ascend", "");
String column = StringUtils.camelToUnderline(key);
Sorter _sorter = new Sorter();
_sorter.setColumn(column);
_sorter.setKey(key);
_sorter.setIsAsc(true);
return _sorter;
} else if (sorter.endsWith("_descend")){
String key = sorter.replace("_descend", "");
String column = StringUtils.camelToUnderline(key);
Sorter _sorter = new Sorter();
_sorter.setColumn(column);
_sorter.setKey(key);
_sorter.setIsAsc(false);
return _sorter;
}
return null;
}
}

@ -1,20 +0,0 @@
package edu.ncst.ioreport.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel(description = "排序器")
@Data
public class Sorter {
@ApiModelProperty(value = "排序关键字")
private String key;
@ApiModelProperty(value = "是否为升序")
private Boolean isAsc = true;
@ApiModelProperty(value = "排序列名", notes = "根据该列进行排序")
private String column;
}

@ -1,41 +0,0 @@
package edu.ncst.ioreport.vo.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel(description = "当前用户信息")
@Data
public class CurrentUserVO {
@ApiModelProperty("头像链接")
private String avatar;
@ApiModelProperty("姓名")
private String username;
@ApiModelProperty("昵称")
private String nickname;
@ApiModelProperty("全名")
private String fullname;
@ApiModelProperty("角色")
private String role;
@ApiModelProperty("头衔")
private String title;
@ApiModelProperty("用户组")
private String group;
@ApiModelProperty("用户ID")
private Integer userId;
@ApiModelProperty("所在单位ID")
private Integer unitId;
@ApiModelProperty("所在单位名称")
private Integer unitName;
}

@ -1,29 +0,0 @@
package edu.ncst.ioreport.vo.param;
import edu.ncst.ioreport.vo.Query;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@ApiModel(description = "登录日志查询对象")
@Data
public class QLoginLog extends Query {
@ApiModelProperty(value = "关键字", notes = "用于对用户名、用户ID、用户姓名进行模糊查询")
private String keyword;
@ApiModelProperty(value = "登录类型")
private String type;
@ApiModelProperty(value = "开始日期")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date startTime;
@ApiModelProperty(value = "结束日期")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date endTime;
}

@ -1,31 +0,0 @@
package edu.ncst.ioreport.vo.param;
import edu.ncst.ioreport.vo.Query;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@ApiModel(description = "出入报备记录查询对象")
@Data
public class QRecord extends Query {
@ApiModelProperty(value = "用户id")
private String userID;
@ApiModelProperty(value = "教师工号")
private String teacherID;
@ApiModelProperty(value = "记录类型")
private String type;
@ApiModelProperty(value = "记录状态")
private String status;
@ApiModelProperty(value = "记录条数")
private Integer count=10;
}

@ -1,14 +0,0 @@
package edu.ncst.ioreport.vo.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(description = "用户信息查询")
public class QUser {
@ApiModelProperty("手机号")
private String phone;
@ApiModelProperty("姓名")
private String name;
}

@ -1,60 +0,0 @@
package edu.ncst.ioreport.vo.result;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import edu.ncst.ioreport.model.User;
import edu.ncst.ioreport.vo.QRToken;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@ApiModel(description = "当前用户信息")
@Data
public class RecordVO {
@ApiModelProperty(value = "报备记录ID")
private Integer ID;
@ApiModelProperty(value = "教师工号")
private User Teacher;
@ApiModelProperty(value = "报备单类型:1-出;0-入")
private Integer IOType;
@ApiModelProperty(value = "校外居住地")
private String OuterResidence;
@ApiModelProperty(value = "校内居住地")
private String InnerResidence;
@ApiModelProperty(value = "申请事由")
private String Reason;
@ApiModelProperty(value = "出入校时间")
private Date CommitTime;
@ApiModelProperty(value = "院级审核人")
private User DeptAuditor;
@ApiModelProperty(value = "院级审核时间")
private Date DeptAuditTime;
@ApiModelProperty(value = "校级审核人")
private User SchoolAuditor;
@ApiModelProperty(value = "校级审核时间")
private Date SchoolAuditTime;
@ApiModelProperty(value = "核验人")
private User Validator;
@ApiModelProperty(value = "核验时间")
private Date ValidateTime;
@ApiModelProperty(value = "单据状态:0-保存;1-提交待审核;2-院级审核通过;3-校级审核通过;4-核验通过;9-院级审核不通过;8-校级审核不通过;7-核验不通过")
private String Status;
@ApiModelProperty(value = "二维码token")
private QRToken qrToken;
}

@ -1,29 +0,0 @@
package edu.ncst.ioreport.vo.result;
import com.baomidou.mybatisplus.annotation.TableField;
import edu.ncst.ioreport.model.Role;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
@ApiModel(description = "用户信息")
public class UserInfoVO {
@ApiModelProperty(value = "用户id")
private String userID;
@ApiModelProperty(value = "教师工号")
private String teacherID;
@ApiModelProperty(value = "用户姓名")
private String name;
@ApiModelProperty(value = "地址信息")
private String address;
@ApiModelProperty(value = "手机号")
private String mobile;
@ApiModelProperty(value = "所属单位")
private Integer departmentID;
@ApiModelProperty(value = "角色列表")
@TableField(exist = false)
private List<String> roles;
}

@ -81,7 +81,7 @@ server:
# configuration:
# map-underscore-to-camel-case: false
#
file:
file-dir: D:/uploads
#file:
# file-dir: D:/uploads
#file:
# file-dir: /root/Uploads

@ -1,51 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="edu.ncst.ioreport.mapper.IORecordsMapper">
<resultMap id="IORecord" type="edu.ncst.ioreport.model.IORecords" autoMapping="true">
<association property="teacher" columnPrefix="t_" autoMapping="true"/>
<association property="deptAuditor" columnPrefix="d_" autoMapping="true"/>
<association property="schoolAuditor" columnPrefix="s_" autoMapping="true"/>
<association property="validator" columnPrefix="v_" autoMapping="true"/>
</resultMap>
<insert id="insertAndGetId" useGeneratedKeys="true" keyProperty="id" parameterType="edu.ncst.ioreport.model.IORecords">
insert into iorecords (teacherid,iotype,outerResidence,innerResidence,reason,committime,status)
values(#{teacherID},#{ioType},#{outerResidence},#{innerResidence},#{reason},#{commitTime},#{status})
</insert>
<select id="selectAuditList" resultMap="IORecord">
select r.*,
uu.name as t_name,uu.userID as t_userID,uu.teacherID as t_teacherID,uu.mobile as t_mobile,
du.name as d_name,du.userID as d_userID,du.teacherID as d_teacherID,du.mobile as d_mobile,
su.name as s_name,su.userID as s_userID,su.teacherID as s_teacherID,su.mobile as s_mobile,
vu.name as v_name,vu.userID as v_userID,vu.teacherID as v_teacherID,vu.mobile as v_mobile
from iorecords r
LEFT JOIN user uu on r.teacherID = uu.teacherID
LEFT JOIN user du on r.DeptAuditorID = du.teacherID
LEFT JOIN user su on r.SchoolAuditorID = su.teacherID
LEFT JOIN user vu on r.ValidatorID = vu.teacherID
<where>
<if test="ew!= null and ew.emptyOfWhere == false">
${ew.sqlSegment}
</if>
</where>
</select>
<select id="selectDetail" resultMap="IORecord">
select r.*,
uu.name as t_name,uu.userID as t_userID,uu.teacherID as t_teacherID,uu.mobile as t_mobile,
du.name as d_name,du.userID as d_userID,du.teacherID as d_teacherID,du.mobile as d_mobile,
su.name as s_name,su.userID as s_userID,su.teacherID as s_teacherID,su.mobile as s_mobile,
vu.name as v_name,vu.userID as v_userID,vu.teacherID as v_teacherID,vu.mobile as v_mobile
from iorecords r
LEFT JOIN user uu on r.teacherID = uu.teacherID
LEFT JOIN user du on r.DeptAuditorID = du.teacherID
LEFT JOIN user su on r.SchoolAuditorID = su.teacherID
LEFT JOIN user vu on r.ValidatorID = vu.teacherID
<where>
<if test="ew!= null and ew.emptyOfWhere == false">
${ew.sqlSegment}
</if>
</where>
</select>
</mapper>

@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="edu.ncst.ioreport.mapper.MaterialUploadMapper">
<resultMap id="IORecord" type="edu.ncst.ioreport.model.MaterialUploadRecord" autoMapping="true">
<association property="teacher" columnPrefix="t_" autoMapping="true"/>
</resultMap>
<insert id="insertAndGetId" useGeneratedKeys="true" keyProperty="id" parameterType="edu.ncst.ioreport.model.MaterialUploadRecord">
insert into iorecords (teacherid,iotype,outerResidence,innerResidence,reason,committime,status)
values(#{teacherID},#{ioType},#{outerResidence},#{innerResidence},#{reason},#{commitTime},#{status})
</insert>
<select id="selectRecordList" resultMap="IORecord">
select r.*,
uu.name as t_name,uu.userID as t_userID,uu.teacherID as t_teacherID,uu.mobile as t_mobile
from material r
LEFT JOIN user uu on r.teacherID = uu.teacherID
<where>
<if test="ew!= null and ew.emptyOfWhere == false">
${ew.sqlSegment}
</if>
</where>
</select>
<select id="selectDetail" resultMap="IORecord">
select r.*,
uu.name as t_name,uu.userID as t_userID,uu.teacherID as t_teacherID,uu.mobile as t_mobile,
du.name as d_name,du.userID as d_userID,du.teacherID as d_teacherID,du.mobile as d_mobile,
su.name as s_name,su.userID as s_userID,su.teacherID as s_teacherID,su.mobile as s_mobile,
vu.name as v_name,vu.userID as v_userID,vu.teacherID as v_teacherID,vu.mobile as v_mobile
from iorecords r
LEFT JOIN user uu on r.teacherID = uu.teacherID
LEFT JOIN user du on r.DeptAuditorID = du.teacherID
LEFT JOIN user su on r.SchoolAuditorID = su.teacherID
LEFT JOIN user vu on r.ValidatorID = vu.teacherID
<where>
<if test="ew!= null and ew.emptyOfWhere == false">
${ew.sqlSegment}
</if>
</where>
</select>
</mapper>

@ -1,52 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="edu.ncst.ioreport.mapper.UserMapper">
<resultMap id="User" type="edu.ncst.ioreport.model.User" autoMapping="true">
<collection property="roles" column="RoleID" columnPrefix="sr_"
ofType="String" autoMapping="true">
</collection>
</resultMap>
<select id="getUserList" resultMap="User">
SELECT
Users.UserID,TeacherID,Name,Password,DepartmentID,WeChatID,Mobile,IsInSchool,
Role.RoleName as sr_name,
UsersInRoles.RoleID
FROM
dbo.Users
INNER JOIN
dbo.UsersInRoles
ON
Users.UserID = UsersInRoles.UserID
INNER JOIN
dbo.Role
ON
UsersInRoles.RoleID = Role.RoleID
</select>
<select id="getByWechatId" resultMap="User">
SELECT
su.UserID,
su.TeacherID,
su.Name,
su.Password,
su.DepartmentID,
su.WeChatID,
su.Mobile,
su.IsInSchool,
sr.RoleName AS sr_RoleName,
sur.RoleID AS sr_RoleID
FROM
dbo.Users AS su
INNER JOIN
dbo.UsersInRoles AS sur
ON
su.UserID = sur.UserID
INNER JOIN
dbo.Role AS sr
ON
sur.RoleID = sr.RoleID
WHERE
su.WeChatID = #{wechatId}
</select>
</mapper>
Loading…
Cancel
Save