Compare commits

..

No commits in common. 'develop' and 'soul2/mobile_api' have entirely different histories.

  1. 1
      .gitignore
  2. 18
      src/main/java/cn/soul2/jyjc/admin/annotation/SkinEncrypt.java
  3. 15
      src/main/java/cn/soul2/jyjc/admin/annotation/SkinLogin.java
  4. 99
      src/main/java/cn/soul2/jyjc/admin/bean/UserLoginStatusBean.java
  5. 65
      src/main/java/cn/soul2/jyjc/admin/config/CorsConfig.java
  6. 41
      src/main/java/cn/soul2/jyjc/admin/config/FilterConfig.java
  7. 67
      src/main/java/cn/soul2/jyjc/admin/config/WebMvcConfig.java
  8. 41
      src/main/java/cn/soul2/jyjc/admin/controller/AnswerController.java
  9. 22
      src/main/java/cn/soul2/jyjc/admin/controller/QrController.java
  10. 7
      src/main/java/cn/soul2/jyjc/admin/controller/QuestionnaireController.java
  11. 2
      src/main/java/cn/soul2/jyjc/admin/controller/SubjectController.java
  12. 47
      src/main/java/cn/soul2/jyjc/admin/controller/UserController.java
  13. 45
      src/main/java/cn/soul2/jyjc/admin/dto/AnswerDetailDTO.java
  14. 5
      src/main/java/cn/soul2/jyjc/admin/dto/AnswerPageQueryDTO.java
  15. 21
      src/main/java/cn/soul2/jyjc/admin/dto/AnswerSheetQueryDTO.java
  16. 37
      src/main/java/cn/soul2/jyjc/admin/dto/AnswerSubmitDTO.java
  17. 21
      src/main/java/cn/soul2/jyjc/admin/dto/QnOptionsDTO.java
  18. 30
      src/main/java/cn/soul2/jyjc/admin/dto/UserLoginDTO.java
  19. 21
      src/main/java/cn/soul2/jyjc/admin/dto/UserLoginOutPageDTO.java
  20. 25
      src/main/java/cn/soul2/jyjc/admin/dto/UserLogoutDTO.java
  21. 37
      src/main/java/cn/soul2/jyjc/admin/dto/UserPageDTO.java
  22. 45
      src/main/java/cn/soul2/jyjc/admin/dto/UserSaveDTO.java
  23. 8
      src/main/java/cn/soul2/jyjc/admin/entity/AnswerDetailsDO.java
  24. 16
      src/main/java/cn/soul2/jyjc/admin/entity/SubjectDO.java
  25. 2
      src/main/java/cn/soul2/jyjc/admin/entity/SubjectItemsDO.java
  26. 93
      src/main/java/cn/soul2/jyjc/admin/entity/UserDO.java
  27. 87
      src/main/java/cn/soul2/jyjc/admin/entity/UserLoginOutDO.java
  28. 60
      src/main/java/cn/soul2/jyjc/admin/filter/ReplaceStreamFilter.java
  29. 130
      src/main/java/cn/soul2/jyjc/admin/filter/ShaoduoRequestWrapper.java
  30. 120
      src/main/java/cn/soul2/jyjc/admin/filter/Soul2ResponseWrapper.java
  31. 137
      src/main/java/cn/soul2/jyjc/admin/interceptor/FinallyInterceptor.java
  32. 16
      src/main/java/cn/soul2/jyjc/admin/mapper/UserLoginOutMapper.java
  33. 16
      src/main/java/cn/soul2/jyjc/admin/mapper/UserMapper.java
  34. 10
      src/main/java/cn/soul2/jyjc/admin/repository/IQrRepository.java
  35. 11
      src/main/java/cn/soul2/jyjc/admin/repository/IQuestionnaireRepository.java
  36. 3
      src/main/java/cn/soul2/jyjc/admin/repository/ISubjectItemsRepository.java
  37. 3
      src/main/java/cn/soul2/jyjc/admin/repository/ISubjectRepository.java
  38. 71
      src/main/java/cn/soul2/jyjc/admin/repository/IUserLoginOutRepository.java
  39. 54
      src/main/java/cn/soul2/jyjc/admin/repository/IUserRepository.java
  40. 80
      src/main/java/cn/soul2/jyjc/admin/repository/impl/AnswerSheetRepositoryImpl.java
  41. 16
      src/main/java/cn/soul2/jyjc/admin/repository/impl/QrRepositoryImpl.java
  42. 21
      src/main/java/cn/soul2/jyjc/admin/repository/impl/QuestionnaireRepositoryImpl.java
  43. 1
      src/main/java/cn/soul2/jyjc/admin/repository/impl/RefSubjectItemsRepositoryImpl.java
  44. 7
      src/main/java/cn/soul2/jyjc/admin/repository/impl/SubjectItemsRepositoryImpl.java
  45. 5
      src/main/java/cn/soul2/jyjc/admin/repository/impl/SubjectRepositoryImpl.java
  46. 126
      src/main/java/cn/soul2/jyjc/admin/repository/impl/UserLoginOutRepositoryImpl.java
  47. 60
      src/main/java/cn/soul2/jyjc/admin/repository/impl/UserRepositoryImpl.java
  48. 31
      src/main/java/cn/soul2/jyjc/admin/service/IAnswerService.java
  49. 56
      src/main/java/cn/soul2/jyjc/admin/service/IUserService.java
  50. 66
      src/main/java/cn/soul2/jyjc/admin/service/impl/AnswerServiceImpl.java
  51. 4
      src/main/java/cn/soul2/jyjc/admin/service/impl/SubjectServiceImpl.java
  52. 95
      src/main/java/cn/soul2/jyjc/admin/service/impl/UserServiceImpl.java
  53. 48
      src/main/java/cn/soul2/jyjc/admin/utils/AesUtils.java
  54. 132
      src/main/java/cn/soul2/jyjc/admin/utils/EncryptUtils.java
  55. 33
      src/main/java/cn/soul2/jyjc/admin/utils/Md5Utils.java
  56. 10
      src/main/java/cn/soul2/jyjc/admin/utils/MybatisFastGenerator.java
  57. 35
      src/main/java/cn/soul2/jyjc/admin/utils/SaltUtils.java
  58. 2
      src/main/java/cn/soul2/jyjc/admin/vo/AnswerDetailsVO.java
  59. 32
      src/main/java/cn/soul2/jyjc/admin/vo/AnswerPageVO.java
  60. 8
      src/main/java/cn/soul2/jyjc/admin/vo/AnswerSheetVO.java
  61. 5
      src/main/java/cn/soul2/jyjc/admin/vo/QrVO.java
  62. 38
      src/main/java/cn/soul2/jyjc/admin/vo/UserVO.java
  63. 34
      src/main/java/cn/soul2/jyjc/admin/vo/base/OptionsVO.java
  64. 7
      src/main/resources/application-cors.yml
  65. 1
      src/main/resources/application.yml
  66. 127
      src/main/resources/logback-spring.xml

1
.gitignore vendored

@ -32,4 +32,3 @@ build/
### VS Code ### ### VS Code ###
.vscode/ .vscode/
/.mvn/ /.mvn/
/logs/

@ -1,18 +0,0 @@
package cn.soul2.jyjc.admin.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 跳过加解密
*
* @author Soul2
* @date 2024-04-08
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface SkinEncrypt {
}

@ -1,15 +0,0 @@
package cn.soul2.jyjc.admin.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Soul2
* @date 2024-04-02
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface SkinLogin {
}

@ -1,99 +0,0 @@
package cn.soul2.jyjc.admin.bean;
import cn.soul2.jyjc.admin.entity.UserLoginOutDO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
@Component
public class UserLoginStatusBean {
private ConcurrentHashMap<String, UserLoginOutDO> loginStatusMap = new ConcurrentHashMap<>();
public void loadUserLoginStatus(Collection<UserLoginOutDO> caches) {
for (UserLoginOutDO cache : caches) {
loginStatusMap.put(cache.getId(), cache);
}
}
/**
* 缓存登录信息
*
* @param token token
* @param loginOutStatus 登录信息
*/
public void login(String token, UserLoginOutDO loginOutStatus) {
loginStatusMap.put(token, loginOutStatus);
}
/**
* 从缓存读取登录信息
*
* @param token token
* @return {@link UserLoginOutDO}
*/
public UserLoginOutDO getStatus(String token) {
UserLoginOutDO loginStatus = loginStatusMap.getOrDefault(token, null);
if (loginStatus.getLapseTime() != null) {
LocalDateTime now = LocalDateTime.now();
if (now.isAfter(loginStatus.getLapseTime())) {
logout(token);
return null;
}
}
return loginStatus;
}
/**
* 为key设置登出
*
* @param token token
* @return {@link Boolean}
*/
public Boolean logout(String token) {
if (StringUtils.isNotBlank(token) && loginStatusMap.containsKey(token)) {
UserLoginOutDO removedUser = loginStatusMap.remove(token);
// 返回true表示成功登出,返回false表示未成功登出
return removedUser != null;
}
return Boolean.TRUE;
}
public Boolean logoutByUserId(String userId) {
final String[] targetKey = {null};
loginStatusMap.forEach((k, v) -> {
if (targetKey[0] == null && v.getUserId().equals(userId)) {
targetKey[0] = k;
}
});
return logout(targetKey[0]);
}
public String getTokenByUsername(String username) {
final String[] token = {null};
loginStatusMap.forEach((k, v) -> {
if (token[0] == null && v.getUserName().equals(username)) {
token[0] = k;
}
});
return token[0];
}
public Boolean containsToken(String token) {
if (StringUtils.isBlank(token)) {
return Boolean.FALSE;
}
UserLoginOutDO loginStatus = loginStatusMap.getOrDefault(token, null);
if (loginStatus != null && loginStatus.getLapseTime() != null) {
LocalDateTime now = LocalDateTime.now();
if (now.isAfter(loginStatus.getLapseTime())) {
logout(token);
}
}
return loginStatusMap.containsKey(token);
}
}

@ -0,0 +1,65 @@
package cn.soul2.jyjc.admin.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author Soul2
* @date 2024-03-25
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Value("${cors.allow-origins}")
private String[] allowOriginArray;
/**
* 将数组转换为List进行动态添加
*/
private final List<String> allowOriginList = new ArrayList<>();
// private static boolean isLocalV4Address(String ipAddress) {
// // todo 为进行手机测试而增加的读取内网IP,正式上线时须注释掉
// String[] parts = ipAddress.split("\\.");
// // 判断是否是有效的IPv4地址并且属于局域网
// return parts.length == 4 && parts[0].equals("192") && parts[1].equals("168");
// }
@Override
public void addCorsMappings(CorsRegistry registry) {
allowOriginList.addAll(Arrays.asList(allowOriginArray));
// // todo 为进行手机测试而增加的读取内网IP,正式上线时须注释掉
// try {
// Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
// while (networkInterfaces.hasMoreElements()) {
// NetworkInterface networkInterface = networkInterfaces.nextElement();
// Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
// while (inetAddresses.hasMoreElements()) {
// InetAddress inetAddress = inetAddresses.nextElement();
// if (isLocalV4Address(inetAddress.getHostAddress())) {
// System.out.println("Local IPv4 Address: " + inetAddress.getHostAddress());
// allowOriginList.add("http://" + inetAddress.getHostAddress() + ":7620");
// }
// }
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
// 打印 allowOriginList 到控制台
// System.out.println("allowOriginList: " + allowOriginList);
registry.addMapping("/**")
.allowedOrigins(allowOriginList.toArray(new String[0]))
.allowCredentials(true)
.allowedMethods("POST")
.maxAge(3600);
}
}

@ -1,41 +0,0 @@
package cn.soul2.jyjc.admin.config;
import cn.soul2.jyjc.admin.filter.ReplaceStreamFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
/**
* @author Soul2
* @description 过滤器配置类
* @date 2024-04-08
* <p>照抄自 <a href="https://blog.csdn.net/shaoduo/article/details/122322578">Shao duo</a></p>
*/
@Configuration
public class FilterConfig {
/**
* 注册过滤器
*
* @return FilterRegistrationBean
*/
@Bean
public FilterRegistrationBean someFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(replaceStreamFilter());
registration.addUrlPatterns("/*");
registration.setName("streamFilter");
return registration;
}
/**
* 实例化StreamFilter
*
* @return Filter
*/
@Bean(name = "replaceStreamFilter")
public Filter replaceStreamFilter() {
return new ReplaceStreamFilter();
}
}

@ -1,67 +0,0 @@
package cn.soul2.jyjc.admin.config;
import cn.soul2.jyjc.admin.interceptor.FinallyInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 注册拦截器
*
* @author Soul2
* @date 2024-04-02
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Value("${cors.allow-origin}")
private String[] allowOrigin;
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
// 设置允许跨域请求的域名
for (String url : allowOrigin) {
config.addAllowedOrigin(url);
}
// 是否允许证书 不再默认开启
// config.setAllowCredentials(true);
// 设置允许的方法
config.addAllowedMethod("*");
// 允许任何头
config.addAllowedHeader("*");
config.addExposedHeader("token");
config.setMaxAge(3600L);
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration("/**", config);
return new CorsFilter(configSource);
}
// @Override
// public void addCorsMappings(CorsRegistry registry) {
// registry.addMapping("/**")
// .allowedHeaders("*")
// .allowedOrigins(allowOrigin)
// .allowCredentials(true)
// .allowedMethods("POST")
// .maxAge(3600);
// }
@Bean
FinallyInterceptor createFinallyInterceptor() {
return new FinallyInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(createFinallyInterceptor())
// 拦截所有路径
.addPathPatterns("/**");
}
}

@ -1,41 +0,0 @@
package cn.soul2.jyjc.admin.controller;
import cn.soul2.jyjc.admin.dto.AnswerPageQueryDTO;
import cn.soul2.jyjc.admin.dto.AnswerSubmitDTO;
import cn.soul2.jyjc.admin.service.IAnswerService;
import cn.soul2.jyjc.admin.utils.base.BackUtils;
import cn.soul2.jyjc.admin.vo.AnswerSheetVO;
import cn.soul2.jyjc.admin.vo.base.Back;
import cn.soul2.jyjc.admin.vo.base.VPage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Soul2
* @date 2024-03-27 13:24
*/
@Slf4j
@RestController
@RequestMapping("/answer")
public class AnswerController {
@Autowired
private IAnswerService answerService;
@PostMapping("submit")
public Back<Boolean> submit(@RequestBody AnswerSubmitDTO dto) {
return BackUtils.success(answerService.handleSubmit(dto));
}
@PostMapping("page")
public Back<VPage<AnswerSheetVO>> page(@RequestBody AnswerPageQueryDTO dto) {
return BackUtils.success(answerService.page(dto));
}
}

@ -1,24 +1,22 @@
package cn.soul2.jyjc.admin.controller; package cn.soul2.jyjc.admin.controller;
import cn.soul2.jyjc.admin.annotation.SkinLogin;
import cn.soul2.jyjc.admin.dto.QrDTO; import cn.soul2.jyjc.admin.dto.QrDTO;
import cn.soul2.jyjc.admin.entity.QrDO; import cn.soul2.jyjc.admin.entity.QrDO;
import cn.soul2.jyjc.admin.entity.QuestionnaireDO;
import cn.soul2.jyjc.admin.repository.IQrRepository; import cn.soul2.jyjc.admin.repository.IQrRepository;
import cn.soul2.jyjc.admin.repository.IQuestionnaireRepository;
import cn.soul2.jyjc.admin.utils.base.BackUtils; import cn.soul2.jyjc.admin.utils.base.BackUtils;
import cn.soul2.jyjc.admin.utils.base.PageUtils; import cn.soul2.jyjc.admin.utils.base.PageUtils;
import cn.soul2.jyjc.admin.vo.QrVO; import cn.soul2.jyjc.admin.vo.QrVO;
import cn.soul2.jyjc.admin.vo.base.Back; import cn.soul2.jyjc.admin.vo.base.Back;
import cn.soul2.jyjc.admin.vo.base.VPage; import cn.soul2.jyjc.admin.vo.base.VPage;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -34,19 +32,12 @@ public class QrController {
@Autowired @Autowired
IQrRepository qrRepository; IQrRepository qrRepository;
@Autowired
private IQuestionnaireRepository questionnaireRepository;
@PostMapping("/page") @PostMapping("/page")
Back<VPage<QrVO>> page(@RequestBody QrDTO dto) { Back<VPage<QrVO>> page(@RequestBody QrDTO dto) {
VPage<QrDO> page = qrRepository.page(dto); VPage<QrDO> page = qrRepository.page(dto);
Map<String, QuestionnaireDO> map = questionnaireRepository.mapByIds(page.getRows().stream().map(QrDO::getQnId).collect(Collectors.toSet()));
VPage<QrVO> toPage = PageUtils.to(page, page.getRows().stream().map(e -> { VPage<QrVO> toPage = PageUtils.to(page, page.getRows().stream().map(e -> {
QrVO vo = new QrVO(); QrVO vo = new QrVO();
BeanUtils.copyProperties(e, vo); BeanUtils.copyProperties(e, vo);
if (StringUtils.isNotBlank(vo.getQnId())) {
vo.setQnName(map.getOrDefault(vo.getQnId(), null).getName());
}
return vo; return vo;
}).collect(Collectors.toList())); }).collect(Collectors.toList()));
return BackUtils.success(toPage); return BackUtils.success(toPage);
@ -67,10 +58,5 @@ public class QrController {
return BackUtils.success(qrRepository.status(dto)); return BackUtils.success(qrRepository.status(dto));
} }
@SkinLogin
@PostMapping("to/{query}")
public Back<String> qrQuery(@PathVariable String query) {
return BackUtils.success(qrRepository.getTo(query));
}
} }

@ -1,6 +1,5 @@
package cn.soul2.jyjc.admin.controller; package cn.soul2.jyjc.admin.controller;
import cn.soul2.jyjc.admin.dto.QnOptionsDTO;
import cn.soul2.jyjc.admin.dto.QnSubjectRefSaveDTO; import cn.soul2.jyjc.admin.dto.QnSubjectRefSaveDTO;
import cn.soul2.jyjc.admin.dto.QuestionnaireDTO; import cn.soul2.jyjc.admin.dto.QuestionnaireDTO;
import cn.soul2.jyjc.admin.dto.base.UpdateStatusDTO; import cn.soul2.jyjc.admin.dto.base.UpdateStatusDTO;
@ -9,7 +8,6 @@ import cn.soul2.jyjc.admin.repository.IRefQuestionnaireSubjectRepository;
import cn.soul2.jyjc.admin.utils.base.BackUtils; import cn.soul2.jyjc.admin.utils.base.BackUtils;
import cn.soul2.jyjc.admin.vo.QuestionnaireVO; import cn.soul2.jyjc.admin.vo.QuestionnaireVO;
import cn.soul2.jyjc.admin.vo.base.Back; import cn.soul2.jyjc.admin.vo.base.Back;
import cn.soul2.jyjc.admin.vo.base.OptionsVO;
import cn.soul2.jyjc.admin.vo.base.VPage; import cn.soul2.jyjc.admin.vo.base.VPage;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -61,9 +59,4 @@ public class QuestionnaireController {
return BackUtils.success(refQuestionnaireSubjectRepository.updateRefSubjects(dto)); return BackUtils.success(refQuestionnaireSubjectRepository.updateRefSubjects(dto));
} }
@PostMapping("options")
public Back<List<OptionsVO>> options(@RequestBody QnOptionsDTO dto) {
return BackUtils.success(questionnaireRepository.options(dto));
}
} }

@ -1,6 +1,5 @@
package cn.soul2.jyjc.admin.controller; package cn.soul2.jyjc.admin.controller;
import cn.soul2.jyjc.admin.annotation.SkinLogin;
import cn.soul2.jyjc.admin.dto.GetSubjectDTO; import cn.soul2.jyjc.admin.dto.GetSubjectDTO;
import cn.soul2.jyjc.admin.dto.QnSubjectRefItemDTO; import cn.soul2.jyjc.admin.dto.QnSubjectRefItemDTO;
import cn.soul2.jyjc.admin.dto.SubjectDTO; import cn.soul2.jyjc.admin.dto.SubjectDTO;
@ -91,7 +90,6 @@ public class SubjectController {
} }
@PostMapping("getSubject") @PostMapping("getSubject")
@SkinLogin
public Back<List<SubjectVO>> getSubject(@RequestBody GetSubjectDTO dto) { public Back<List<SubjectVO>> getSubject(@RequestBody GetSubjectDTO dto) {
if (StringUtils.isBlank(dto.getQnId())) { if (StringUtils.isBlank(dto.getQnId())) {
QuestionnaireDO qn = questionnaireRepository.getTheLatestOne(); QuestionnaireDO qn = questionnaireRepository.getTheLatestOne();

@ -1,47 +0,0 @@
package cn.soul2.jyjc.admin.controller;
import cn.soul2.jyjc.admin.annotation.SkinLogin;
import cn.soul2.jyjc.admin.dto.UserLoginDTO;
import cn.soul2.jyjc.admin.dto.UserLogoutDTO;
import cn.soul2.jyjc.admin.service.IUserService;
import cn.soul2.jyjc.admin.utils.base.BackUtils;
import cn.soul2.jyjc.admin.vo.UserVO;
import cn.soul2.jyjc.admin.vo.base.Back;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Soul2
* @date 2024-03-31 15:48
*/
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private IUserService userService;
@PostMapping("login")
@SkinLogin
public Back<UserVO> login(@RequestBody UserLoginDTO dto) {
return BackUtils.success(userService.login(dto));
}
@PostMapping("register")
@SkinLogin
public Back<UserVO> register(@RequestBody UserLoginDTO dto) {
return BackUtils.success(userService.register(dto));
}
@PostMapping("logout")
public Back<Boolean> logout(@RequestBody UserLogoutDTO dto) {
return BackUtils.success(userService.logout(dto));
}
}

@ -1,45 +0,0 @@
package cn.soul2.jyjc.admin.dto;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author Soul2
* @date 2024-03-27 13:31
*/
@Data
@Accessors(chain = true)
public class AnswerDetailDTO {
/**
* 回答内容(文字/选项id,多选时以,分隔)
*/
private String content;
/**
* 得分
*/
private Integer points;
/**
* 题目id
*/
private String subjectId;
/**
* 题目类型:0-单选;1-多选;2-文字
*/
private Integer subjectType;
/**
* 题目分值
*/
private Integer subjectPoints;
/**
* 权重
*/
private Double weights;
}

@ -23,9 +23,4 @@ public class AnswerPageQueryDTO extends PageParams {
*/ */
private String respondent; private String respondent;
/**
* qnId
*/
private String qnId;
} }

@ -1,21 +0,0 @@
package cn.soul2.jyjc.admin.dto;
import cn.soul2.jyjc.admin.dto.base.PageParams;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author Soul2
* @date 2024-05-10 11:48
*/
@Data
@Accessors(chain = true)
public class AnswerSheetQueryDTO extends PageParams {
/**
* sheet id
*/
private String sheetId;
}

@ -1,37 +0,0 @@
package cn.soul2.jyjc.admin.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
/**
* @author Soul2
* @date 2024-03-27 13:26
*/
@Data
@Accessors(chain = true)
public class AnswerSubmitDTO {
/**
* 二维码id
*/
private String qrId;
/**
* 问卷Id
*/
private String qnId;
/**
* openid, 即答卷人
*/
private String openid;
/**
* 答题内容
*/
private List<AnswerDetailDTO> details;
}

@ -1,21 +0,0 @@
package cn.soul2.jyjc.admin.dto;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author Soul2
* @date 2024-05-10 15:06
*/
@Data
@Accessors(chain = true)
public class QnOptionsDTO {
/**
* 查询状态 -1 or null: 所有
*/
private Integer status;
}

@ -1,30 +0,0 @@
package cn.soul2.jyjc.admin.dto;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author Soul2
* @date 2024-03-29 21:55
*/
@Data
@Accessors(chain = true)
public class UserLoginDTO {
/**
* userName
*/
private String username;
/**
* password
*/
private String password;
/**
* 密码错误次数(暂未使用)
*/
private Integer pswErrorCount;
}

@ -1,21 +0,0 @@
package cn.soul2.jyjc.admin.dto;
import cn.soul2.jyjc.admin.dto.base.PageParams;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author Soul2
* @date 2024-03-29 21:50
*/
@Data
@Accessors(chain = true)
public class UserLoginOutPageDTO extends PageParams {
/**
* userId
*/
private String userId;
}

@ -1,25 +0,0 @@
package cn.soul2.jyjc.admin.dto;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author Soul2
* @date 2024-03-29 21:56
*/
@Data
@Accessors(chain = true)
public class UserLogoutDTO {
/**
* userName
*/
private String username;
/**
* token
*/
private String token;
}

@ -1,37 +0,0 @@
package cn.soul2.jyjc.admin.dto;
import cn.soul2.jyjc.admin.dto.base.PageParams;
import lombok.Data;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
* @author Soul2
* @date 2024-03-29 20:50
*/
@Data
@Accessors(chain = true)
public class UserPageDTO extends PageParams {
/**
* id
*/
private String id;
/**
* 用户名
*/
private String username;
/**
* 状态;0(默认)正常4封号9异常
*/
private Integer status;
/**
* 注册时间
*/
private LocalDateTime startTime;
private LocalDateTime endTime;
}

@ -1,45 +0,0 @@
package cn.soul2.jyjc.admin.dto;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author Soul2
* @date 2024-03-29 20:50
*/
@Data
@Accessors(chain = true)
public class UserSaveDTO {
/**
* id
*/
private String id;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 状态;0(默认)正常4封号9异常
*/
private Integer status;
/**
* 权限等级,默认200
*/
private Integer authorityLevel;
/**
* 密码修改次数
*/
private Integer pswChange;
}

@ -15,7 +15,7 @@ import java.time.LocalDateTime;
* </p> * </p>
* *
* @author Soul2 * @author Soul2
* @since 2024-03-27 15:38:51 * @since 2024-03-12 10:10:24
*/ */
@Getter @Getter
@Setter @Setter
@ -32,10 +32,10 @@ public class AnswerDetailsDO extends Model<AnswerDetailsDO> {
private String id; private String id;
/** /**
* 题目类型:0-单选;1-多选;2-文字 * 状态0禁用1启用
*/ */
@TableField("subject_type") @TableField("status")
private Integer subjectType; private Short status;
/** /**
* 更新时间 * 更新时间

@ -15,7 +15,7 @@ import java.time.LocalDateTime;
* </p> * </p>
* *
* @author Soul2 * @author Soul2
* @since 2024-03-27 15:38:52 * @since 2024-03-12 10:10:24
*/ */
@Getter @Getter
@Setter @Setter
@ -80,20 +80,8 @@ public class SubjectDO extends Model<SubjectDO> {
@TableField("type") @TableField("type")
private Short type; private Short type;
/**
* 权重
*/
@TableField("weights")
private Double weights;
/**
* 分值
*/
@TableField("points")
private Integer points;
@Override @Override
public Serializable pkVal() { public Serializable pkVal() {
return this.id; return null;
} }
} }

@ -72,7 +72,7 @@ public class SubjectItemsDO extends Model<SubjectItemsDO> {
* 权重 * 权重
*/ */
@TableField("weights") @TableField("weights")
private Double weights; private Object weights;
/** /**
* 分值 * 分值

@ -1,93 +0,0 @@
package cn.soul2.jyjc.admin.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 用户表
* </p>
*
* @author Soul2
* @since 2024-03-30 14:34:13
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("tb_user")
public class UserDO extends Model<UserDO> {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id", type = IdType.ASSIGN_UUID)
private String id;
/**
* 用户名
*/
@TableField("username")
private String username;
/**
* 密码
*/
@TableField("password")
private String password;
/**
* 状态;0(默认)正常4封号9异常
*/
@TableField("status")
private Integer status;
/**
* 权限等级,默认200
*/
@TableField("authority_level")
private Integer authorityLevel;
/**
* 密码修改次数
*/
@TableField("psw_change")
private Integer pswChange;
/**
* 更新时间
*/
@TableField(value = "updated_time", fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updatedTime;
/**
* 创建时间
*/
@TableField(value = "created_time", fill = FieldFill.INSERT)
private LocalDateTime createdTime;
/**
* 删除标记
*/
@TableField("removed")
@TableLogic
private Integer removed;
/**
* ,用于密码加密,未启用
*/
@TableField("salt")
private String salt;
@Override
public Serializable pkVal() {
return this.id;
}
}

@ -1,87 +0,0 @@
package cn.soul2.jyjc.admin.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 用户登入登出表
* </p>
*
* @author Soul2
* @since 2024-03-30 13:57:00
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("tb_user_login_out")
public class UserLoginOutDO extends Model<UserLoginOutDO> {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id", type = IdType.ASSIGN_UUID)
private String id;
/**
* 用户id
*/
@TableField("user_id")
private String userId;
/**
* 用户名称
*/
@TableField("user_name")
private String userName;
/**
* 登录时间,登录成功才写入
*/
@TableField("login_time")
private LocalDateTime loginTime;
/**
* 登录失效时间
*/
@TableField("lapse_time")
private LocalDateTime lapseTime;
/**
* 用户操作登出时间
*/
@TableField("logout_time")
private LocalDateTime logoutTime;
/**
* 密码错误次数
*/
@TableField("psw_error_count")
private Integer pswErrorCount;
/**
* 创建时间
*/
@TableField(value = "created_time", fill = FieldFill.INSERT)
private LocalDateTime createdTime;
/**
* 1=删除;0=未删除
*/
@TableField("removed")
@TableLogic
private Integer removed;
@Override
public Serializable pkVal() {
return this.id;
}
}

@ -1,60 +0,0 @@
package cn.soul2.jyjc.admin.filter;
import cn.soul2.jyjc.admin.utils.EncryptUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author shaoduo
* @description 替换HttpServletRequest
* @since 1.0
**/
@Slf4j
public class ReplaceStreamFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("StreamFilter初始化...");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//如果是文件上传则会报错可以判断是否是文件上传不读取流即可
if (ServletFileUpload.isMultipartContent((HttpServletRequest) request)) {
chain.doFilter(request, response);
} else if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) request).getMethod())) {
chain.doFilter(request, response);
} else {
ServletRequest requestWrapper = new ShaoduoRequestWrapper((HttpServletRequest) request);
// System.out.printf("ReplaceStreamFilter触发, Method: %s, URI: %s%n", ((HttpServletRequest) request).getMethod(), ((HttpServletRequest) request).getRequestURI());
HttpServletResponse httpResponse = (HttpServletResponse) response;
Soul2ResponseWrapper soul2ResponseWrapper = new Soul2ResponseWrapper(httpResponse);
chain.doFilter(requestWrapper, soul2ResponseWrapper);
try {
byte[] data = soul2ResponseWrapper.getResponseData();
log.debug("原始返回 -> " + new String(data));
String encryptBody = EncryptUtils.encrypt(new String(data));
log.debug("加密返回 -> " + encryptBody);
soul2ResponseWrapper.setHeader("encrypt", "1");
soul2ResponseWrapper.setHeader("Access-Control-Expose-Headers", "encrypt");
PrintWriter out = response.getWriter();
out.print(encryptBody);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void destroy() {
log.info("StreamFilter销毁...");
}
}

@ -1,130 +0,0 @@
package cn.soul2.jyjc.admin.filter;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
/**
* @author shaoduo
* @description 包装HttpServletRequest目的是让其输入流可重复读
* @since <a href="https://blog.csdn.net/shaoduo/article/details/122322578">shaoduo</a>
**/
@Slf4j
public class ShaoduoRequestWrapper extends HttpServletRequestWrapper {
/**
* 存储body数据的容器
*/
private byte[] body;
public ShaoduoRequestWrapper(HttpServletRequest request) {
super(request);
// 将body数据存储起来
String bodyStr = getBodyString(request);
body = bodyStr.getBytes(Charset.defaultCharset());
}
/**
* 获取请求Body
*
* @param request request
* @return String
*/
public String getBodyString(final ServletRequest request) {
try {
return inputStream2String(request.getInputStream());
} catch (IOException e) {
log.error("", e);
throw new RuntimeException(e);
}
}
/**
* 获取请求Body
*
* @return String
*/
public String getBodyString() throws IOException {
InputStream inputStream = new ByteArrayInputStream(body);
return inputStream2String(inputStream);
}
/**
* 修改body 将json 重新设置成body
*
* @param val
*/
public void setBody(String val) {
body = val.getBytes(StandardCharsets.UTF_8);
}
/**
* 将inputStream里的数据读取出来并转换成字符串
*
* @param inputStream inputStream
* @return String
*/
private String inputStream2String(InputStream inputStream) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(inputStream, Charset.defaultCharset()));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
log.error("", e);
throw new RuntimeException(e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
log.error("", e);
}
}
}
return sb.toString();
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream inputStream = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public int read() {
return inputStream.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
}
}

@ -1,120 +0,0 @@
package cn.soul2.jyjc.admin.filter;
import lombok.SneakyThrows;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.*;
/**
* @author Soul2
* @description 包装ServletResponse, 照抄自 <a href="https://blog.csdn.net/temp_44/article/details/107762290">temp_44</a>
* @date 2024-04-15
*/
public class Soul2ResponseWrapper extends HttpServletResponseWrapper {
private ByteArrayOutputStream buffer = null;
private ServletOutputStream out = null;
private PrintWriter writer = null;
public Soul2ResponseWrapper(HttpServletResponse resp) throws IOException {
super(resp);
// 真正存储数据的流
buffer = new ByteArrayOutputStream();
out = new WapperedOutputStream(buffer);
writer = new PrintWriter(new OutputStreamWriter(buffer,
this.getCharacterEncoding()));
}
/**
* 重载父类获取outputstream的方法
*/
@Override
public ServletOutputStream getOutputStream() throws IOException {
return out;
}
/**
* 重载父类获取writer的方法
*/
@Override
public PrintWriter getWriter() throws UnsupportedEncodingException {
return writer;
}
/**
* The default behavior of this method is to call
* setCharacterEncoding(String charset) on the wrapped response object.
*
* @param charset
* @since 2.4
*/
@SneakyThrows
@Override
public void setCharacterEncoding(String charset) {
super.setCharacterEncoding(charset);
writer = new PrintWriter(new OutputStreamWriter(buffer,
this.getCharacterEncoding()));
}
/**
* 重载父类获取flushBuffer的方法
*/
@Override
public void flushBuffer() throws IOException {
if (out != null) {
out.flush();
}
if (writer != null) {
writer.flush();
}
}
@Override
public void reset() {
buffer.reset();
}
/**
* 将outwriter中的数据强制输出到WapperedResponse的buffer里面否则取不到数据
*/
public byte[] getResponseData() throws IOException {
flushBuffer();
return buffer.toByteArray();
}
/**
* 内部类对ServletOutputStream进行包装
*/
private class WapperedOutputStream extends ServletOutputStream {
private ByteArrayOutputStream bos = null;
public WapperedOutputStream(ByteArrayOutputStream stream)
throws IOException {
bos = stream;
}
@Override
public void write(int b) throws IOException {
bos.write(b);
}
@Override
public void write(byte[] b) throws IOException {
bos.write(b, 0, b.length);
}
@Override
public boolean isReady() {
// TODO Auto-generated method stub
return false;
}
@Override
public void setWriteListener(WriteListener writeListener) {
// TODO Auto-generated method stub
}
}
}

@ -1,137 +0,0 @@
package cn.soul2.jyjc.admin.interceptor;
import cn.soul2.jyjc.admin.annotation.SkinEncrypt;
import cn.soul2.jyjc.admin.annotation.SkinLogin;
import cn.soul2.jyjc.admin.bean.UserLoginStatusBean;
import cn.soul2.jyjc.admin.filter.ShaoduoRequestWrapper;
import cn.soul2.jyjc.admin.service.IUserService;
import cn.soul2.jyjc.admin.utils.EncryptUtils;
import cn.soul2.jyjc.admin.vo.base.Back;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.lang.reflect.Method;
/**
* Token拦截器
*
* @author Soul2
* @date 2024-04-02 15:31
*/
@Slf4j
public class FinallyInterceptor implements HandlerInterceptor {
@Resource
private UserLoginStatusBean userLoginStatusBean;
@Autowired
private IUserService userService;
private boolean load = true;
private void loadUserLoginStatus() {
userLoginStatusBean.loadUserLoginStatus(userService.getLoginedUser());
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (load) {
loadUserLoginStatus();
load = false;
}
boolean pass = false;
// 允许OPTIONS请求通过
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
return true;
}
// 如果不是映射到方法直接通过
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
String httpMethod = request.getMethod();
SkinEncrypt skinEncrypt = handlerMethod.getMethodAnnotation(SkinEncrypt.class);
// 检查方法上是否存在SkinLogin注解
boolean hasSkinLogin = handlerMethod.getMethodAnnotation(SkinLogin.class) != null;
// 从请求头中获取 token
String token = request.getHeader("jyjc-Token");
try {
/*
加解密
*/
// 不拦截get请求
if ("GET".equals(httpMethod)) {
pass = true;
// 如果是post请求且是json
} else if ("POST".equals(httpMethod)) {
// 如果类型为空就放行
if (request.getContentType() == null) {
pass = true;
}
}
// 跳过使用 @SkinEncrypt 的情况
if (skinEncrypt != null) {
pass = true;
}
if (!pass) {
ShaoduoRequestWrapper shaoduoRequestWrapper;
try {
shaoduoRequestWrapper = (ShaoduoRequestWrapper) request;
} catch (Exception e) {
System.out.printf("request.ClassTypeError: %s%n", request.getClass().getName());
return true;
}
String sourceParamBody = shaoduoRequestWrapper.getBodyString();
String afterBody = EncryptUtils.decrypt(sourceParamBody);
shaoduoRequestWrapper.setBody(afterBody);
log.debug(String.format("解密: %s -> %s", sourceParamBody, afterBody));
}
/* token验证 */
if (hasSkinLogin) {
// 跳过使用 @SkinLogin 的情况
pass = true;
} else {
// 验证token
// 检查 token 是否存在并且有效
if (token == null) {
// 没有Token,拒绝请求
response.setStatus(40401);
pass = false;
} else if (userLoginStatusBean != null) {
if (!userLoginStatusBean.containsToken(token)) {
// Token 无效,拒绝请求
response.setContentType("application/json");
Back<String> back = new Back<String>().setCode(40401).setMessage("Token invalid!");
// 转换为 JSON 字符串
ObjectMapper objectMapper = new ObjectMapper();
String responseBody = objectMapper.writeValueAsString(back);
// 输出错误信息到响应中
PrintWriter writer = response.getWriter();
writer.print(responseBody);
writer.flush();
pass = false;
} else {
// token存在, 通过拦截器
pass = true;
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return pass;
}
}

@ -1,16 +0,0 @@
package cn.soul2.jyjc.admin.mapper;
import cn.soul2.jyjc.admin.entity.UserLoginOutDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 用户登入登出表 Mapper 接口
* </p>
*
* @author Soul2
* @since 2024-03-29 20:46:42
*/
public interface UserLoginOutMapper extends BaseMapper<UserLoginOutDO> {
}

@ -1,16 +0,0 @@
package cn.soul2.jyjc.admin.mapper;
import cn.soul2.jyjc.admin.entity.UserDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 用户表 Mapper 接口
* </p>
*
* @author Soul2
* @since 2024-03-29 20:46:42
*/
public interface UserMapper extends BaseMapper<UserDO> {
}

@ -24,14 +24,6 @@ public interface IQrRepository extends IService<QrDO> {
Boolean remove(Collection<String> ids); Boolean remove(Collection<String> ids);
boolean status(QrDTO status);
/** boolean status(QrDTO status);
* 从二维码id读取跳转目标
* url的优先级大于问卷id
*
* @param id 二维码id
* @return {@link String}
*/
String getTo(String id);
} }

@ -1,18 +1,12 @@
package cn.soul2.jyjc.admin.repository; package cn.soul2.jyjc.admin.repository;
import cn.soul2.jyjc.admin.dto.QnOptionsDTO;
import cn.soul2.jyjc.admin.dto.QuestionnaireDTO; import cn.soul2.jyjc.admin.dto.QuestionnaireDTO;
import cn.soul2.jyjc.admin.dto.base.UpdateStatusDTO; import cn.soul2.jyjc.admin.dto.base.UpdateStatusDTO;
import cn.soul2.jyjc.admin.entity.QuestionnaireDO; import cn.soul2.jyjc.admin.entity.QuestionnaireDO;
import cn.soul2.jyjc.admin.vo.QuestionnaireVO; import cn.soul2.jyjc.admin.vo.QuestionnaireVO;
import cn.soul2.jyjc.admin.vo.base.OptionsVO;
import cn.soul2.jyjc.admin.vo.base.VPage; import cn.soul2.jyjc.admin.vo.base.VPage;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/** /**
* <p> * <p>
* 问卷表 服务类 * 问卷表 服务类
@ -55,9 +49,4 @@ public interface IQuestionnaireRepository extends IService<QuestionnaireDO> {
*/ */
QuestionnaireDO getTheLatestOne(); QuestionnaireDO getTheLatestOne();
List<OptionsVO> options(QnOptionsDTO dto);
Map<String, QuestionnaireDO> mapByIds(Collection<String> ids);
} }

@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* <p> * <p>
@ -33,8 +32,6 @@ public interface ISubjectItemsRepository extends IService<SubjectItemsDO> {
*/ */
List<SubjectItemsDO> listBySubjectIds(Collection<String> subjectIds); List<SubjectItemsDO> listBySubjectIds(Collection<String> subjectIds);
Map<String, SubjectItemsDO> mapByIds(Collection<String> ids);
/** /**
* 删除指定题目id下的所有选项 * 删除指定题目id下的所有选项
* *

@ -10,7 +10,6 @@ import cn.soul2.jyjc.admin.vo.base.VPage;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import java.util.Collection; import java.util.Collection;
import java.util.Map;
/** /**
* <p> * <p>
@ -63,6 +62,4 @@ public interface ISubjectRepository extends IService<SubjectDO> {
*/ */
VPage<SubjectChooseListDO> chooseList(QnSubjectRefItemDTO dto); VPage<SubjectChooseListDO> chooseList(QnSubjectRefItemDTO dto);
Map<String, SubjectDO> mapByIds(Collection<String> ids);
} }

@ -1,71 +0,0 @@
package cn.soul2.jyjc.admin.repository;
import cn.soul2.jyjc.admin.dto.UserLoginDTO;
import cn.soul2.jyjc.admin.dto.UserLoginOutPageDTO;
import cn.soul2.jyjc.admin.dto.UserLogoutDTO;
import cn.soul2.jyjc.admin.entity.UserDO;
import cn.soul2.jyjc.admin.entity.UserLoginOutDO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
* 用户登入登出表 服务类
* </p>
*
* @author Soul2
* @since 2024-03-29 20:46:42
*/
public interface IUserLoginOutRepository extends IService<UserLoginOutDO> {
/**
* 分页查询
*
* @param dto 查询条件
* @return {@link IPage}<{@link UserLoginOutDO}>
*/
IPage<UserLoginOutDO> page(UserLoginOutPageDTO dto);
/**
* 用户登录
*
* @param dto 用户信息
* @param user 用户
* @return {@link String}
*/
String login(UserLoginDTO dto, UserDO user);
/**
* 用户登出
*
* @param dto 用户信息
* @return {@link String}
*/
String logout(UserLogoutDTO dto);
/**
* 用户登出
*
* @param userId 用户id
* @return {@link String}
*/
Boolean logoutByUserId(String userId);
/**
* 删除目标用户的所有登录记录
*
* @param userId 用户id
* @return {@link Boolean}
*/
Boolean removeByUserId(String userId);
/**
* 重建当前登录的用户
*
* @return {@link List}<{@link UserLoginOutDO}>
*/
List<UserLoginOutDO> getLoginedUser();
}

@ -1,54 +0,0 @@
package cn.soul2.jyjc.admin.repository;
import cn.soul2.jyjc.admin.dto.UserPageDTO;
import cn.soul2.jyjc.admin.dto.UserSaveDTO;
import cn.soul2.jyjc.admin.dto.base.UpdateStatusDTO;
import cn.soul2.jyjc.admin.entity.UserDO;
import cn.soul2.jyjc.admin.vo.base.VPage;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 用户表 服务类
* </p>
*
* @author Soul2
* @since 2024-03-29 20:46:42
*/
public interface IUserRepository extends IService<UserDO> {
/**
* 分页查询
*
* @param dto 查询条件
* @return {@link VPage}<{@link UserDO}>
*/
IPage<UserDO> page(UserPageDTO dto);
/**
* 保存或更新
*
* @param dto /无id区分更新/新增
* @return {@link Boolean}
*/
Boolean saveOrUpdate(UserSaveDTO dto);
/**
* 更新状态
*
* @param dto 新状态
* @return {@link Boolean}
*/
Boolean updateStatus(UpdateStatusDTO dto);
/**
* 读取指定名字的用户
*
* @param username 用户名
* @return {@link UserDO}
*/
UserDO getOneByUsername(String username);
}

@ -1,16 +1,21 @@
package cn.soul2.jyjc.admin.repository.impl; package cn.soul2.jyjc.admin.repository.impl;
import cn.soul2.jyjc.admin.dto.AnswerPageQueryDTO; import cn.soul2.jyjc.admin.dto.AnswerPageQueryDTO;
import cn.soul2.jyjc.admin.entity.*; import cn.soul2.jyjc.admin.entity.AnswerDetailsDO;
import cn.soul2.jyjc.admin.entity.AnswerSheetDO;
import cn.soul2.jyjc.admin.entity.QrDO;
import cn.soul2.jyjc.admin.entity.QuestionnaireDO;
import cn.soul2.jyjc.admin.mapper.AnswerSheetMapper; import cn.soul2.jyjc.admin.mapper.AnswerSheetMapper;
import cn.soul2.jyjc.admin.repository.*; import cn.soul2.jyjc.admin.repository.IAnswerDetailsRepository;
import cn.soul2.jyjc.admin.repository.IAnswerSheetRepository;
import cn.soul2.jyjc.admin.repository.IQrRepository;
import cn.soul2.jyjc.admin.repository.IQuestionnaireRepository;
import cn.soul2.jyjc.admin.utils.base.PageUtils; import cn.soul2.jyjc.admin.utils.base.PageUtils;
import cn.soul2.jyjc.admin.vo.AnswerDetailsVO; import cn.soul2.jyjc.admin.vo.AnswerDetailsVO;
import cn.soul2.jyjc.admin.vo.AnswerSheetVO; import cn.soul2.jyjc.admin.vo.AnswerSheetVO;
import cn.soul2.jyjc.admin.vo.base.VPage; import cn.soul2.jyjc.admin.vo.base.VPage;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -20,7 +25,10 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport; import org.springframework.transaction.interceptor.TransactionAspectSupport;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import java.util.*; import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -43,86 +51,36 @@ public class AnswerSheetRepositoryImpl extends ServiceImpl<AnswerSheetMapper, An
@Autowired @Autowired
private IAnswerDetailsRepository detailsRepository; private IAnswerDetailsRepository detailsRepository;
@Autowired
private ISubjectItemsRepository subjectItemsRepository;
@Autowired
private ISubjectRepository subjectRepository;
@Override @Override
public VPage<AnswerSheetVO> page(AnswerPageQueryDTO dto) { public VPage<AnswerSheetVO> page(AnswerPageQueryDTO dto) {
LambdaQueryWrapper<AnswerSheetDO> query = Wrappers.lambdaQuery(); LambdaQueryWrapper<AnswerSheetDO> query = Wrappers.lambdaQuery();
query.eq(StringUtils.isNotBlank(dto.getRespondent()), AnswerSheetDO::getRespondent, dto.getRespondent()) query.eq(StringUtils.isNotBlank(dto.getRespondent()), AnswerSheetDO::getRespondent, dto.getRespondent())
.eq(dto.getStatus() != null, AnswerSheetDO::getStatus, dto.getStatus()) .eq(dto.getStatus() != null, AnswerSheetDO::getStatus, dto.getStatus())
.eq(StringUtils.isNotBlank(dto.getQnId()), AnswerSheetDO::getQnId, dto.getQnId())
.orderByDesc(AnswerSheetDO::getUpdatedTime).orderByDesc(AnswerSheetDO::getCreatedTime); .orderByDesc(AnswerSheetDO::getUpdatedTime).orderByDesc(AnswerSheetDO::getCreatedTime);
VPage<AnswerSheetDO> page = PageUtils.to(super.page(PageUtils.build(dto), query)); VPage<AnswerSheetDO> page = PageUtils.to(super.page(PageUtils.build(dto), query));
List<AnswerSheetDO> rows = page.getRows(); List<AnswerSheetDO> rows = page.getRows();
Set<String> qnSet = rows.stream().map(AnswerSheetDO::getQnId).collect(Collectors.toSet()); Set<String> qnSet = rows.stream().map(AnswerSheetDO::getQnId).collect(Collectors.toSet());
Set<String> qrSet = rows.stream().map(AnswerSheetDO::getQrId).collect(Collectors.toSet()); Set<String> qrSet = rows.stream().map(AnswerSheetDO::getQrId).collect(Collectors.toSet());
Map<String, QuestionnaireDO> qnMap; Map<String, QuestionnaireDO> qnMap = questionnaireRepository.listByIds(qnSet).stream().collect(Collectors.toMap(QuestionnaireDO::getId, o -> o, (o1, o2) -> o1));
if (CollectionUtils.isNotEmpty(qnSet)) { Map<String, QrDO> qrMap = qrRepository.listByIds(qrSet).stream().collect(Collectors.toMap(QrDO::getId, o -> o, (o1, o2) -> o1));
qnMap = questionnaireRepository.listByIds(qnSet).stream().collect(Collectors.toMap(QuestionnaireDO::getId, o -> o, (o1, o2) -> o1));
} else {
qnMap = new HashMap<>();
}
Map<String, QrDO> qrMap;
if (CollectionUtils.isNotEmpty(qrSet)) {
qrMap = qrRepository.listByIds(qrSet).stream().collect(Collectors.toMap(QrDO::getId, o -> o, (o1, o2) -> o1));
} else {
qrMap = new HashMap<>();
}
List<AnswerDetailsDO> detailsDOList = detailsRepository.listBySheetIds(rows.stream().map(AnswerSheetDO::getId).collect(Collectors.toList())); List<AnswerDetailsDO> detailsDOList = detailsRepository.listBySheetIds(rows.stream().map(AnswerSheetDO::getId).collect(Collectors.toList()));
// List<String> sids = detailsDOList.stream()
// .filter(e -> e.getSubjectType() == 0 || e.getSubjectType() == 1)
// .map(AnswerDetailsDO::getAnswerContent)
// .flatMap(ids -> Arrays.stream(ids.split(",")))
// .collect(Collectors.toList());
Map<String, SubjectDO> sMap = subjectRepository.mapByIds(detailsDOList.stream().map(AnswerDetailsDO::getSubjectId).collect(Collectors.toList()));
Map<Integer, List<String>> sidsMap = detailsDOList.stream()
.filter(e -> e.getSubjectType() == 0 || e.getSubjectType() == 1)
.collect(Collectors.groupingBy(AnswerDetailsDO::getSubjectType,
Collectors.mapping(AnswerDetailsDO::getAnswerContent, Collectors.toList())));
List<String> sids = new ArrayList<>(sidsMap.getOrDefault(0, Collections.emptyList()));
if (sidsMap.containsKey(1)) {
sids.addAll(sidsMap.get(1)
.stream().flatMap(ids -> Arrays.stream(ids.split(",")))
.collect(Collectors.toList()));
}
Map<String, SubjectItemsDO> siMap = subjectItemsRepository.mapByIds(sids);
return PageUtils.to(page, rows.stream().map(row -> { return PageUtils.to(page, rows.stream().map(row -> {
AnswerSheetVO vo = new AnswerSheetVO(); AnswerSheetVO vo = new AnswerSheetVO();
BeanUtils.copyProperties(row, vo); BeanUtils.copyProperties(row, vo);
vo.setSubmitTime(row.getUpdatedTime());
if (qnMap.containsKey(row.getQnId())) { if (qnMap.containsKey(row.getQnId())) {
vo.setQnName(qnMap.get(row.getQnId()).getName()); vo.setQnName(qnMap.get(row.getQnId()).getName());
} }
if (qrMap.containsKey(row.getQrId())) { if (qrMap.containsKey(row.getQrId())) {
vo.setQrTip(qrMap.get(row.getQrId()).getTip()); vo.setQnName(qrMap.get(row.getQrId()).getTip());
} }
vo.setDetails(detailsDOList.stream().filter(d -> d.getAnswerSheetId().equals(row.getId())).map(d -> { vo.setDetails(detailsDOList.stream().filter(d -> d.getAnswerSheetId().equals(row.getId())).map(d -> {
AnswerDetailsVO dv = new AnswerDetailsVO(); AnswerDetailsVO detailsVO = new AnswerDetailsVO();
BeanUtils.copyProperties(d, dv); BeanUtils.copyProperties(d, detailsVO);
dv.setType(d.getSubjectType()); return detailsVO;
if (d.getSubjectType() == 2) {
dv.setAnswerContent(d.getAnswerContent());
} else if (d.getSubjectType() == 1) {
dv.setAnswerContent(Arrays.stream(d.getAnswerContent().split(","))
.map(id -> (siMap.containsKey(id) ? siMap.get(id).getContent() : id))
.collect(Collectors.joining(",")));
} else if (d.getSubjectType() == 0) {
dv.setAnswerContent(siMap.containsKey(d.getAnswerContent()) ? siMap.get(d.getAnswerContent()).getContent() : d.getAnswerContent());
} else {
dv.setAnswerContent(d.getAnswerContent());
}
dv.setTitle(sMap.containsKey(d.getSubjectId()) ? sMap.get(d.getSubjectId()).getTitle() : "")
.setContent(sMap.containsKey(d.getSubjectId()) ? sMap.get(d.getSubjectId()).getContent() : "");
return dv;
}).collect(Collectors.toList())); }).collect(Collectors.toList()));
return vo; return vo;
}).collect(Collectors.toList())); }).collect(Collectors.toList()));
} }

@ -8,6 +8,7 @@ import cn.soul2.jyjc.admin.utils.base.PageUtils;
import cn.soul2.jyjc.admin.vo.QrVO; import cn.soul2.jyjc.admin.vo.QrVO;
import cn.soul2.jyjc.admin.vo.base.VPage; import cn.soul2.jyjc.admin.vo.base.VPage;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -29,6 +30,7 @@ import java.util.stream.Collectors;
@Service @Service
public class QrRepositoryImpl extends ServiceImpl<QrMapper, QrDO> implements IQrRepository { public class QrRepositoryImpl extends ServiceImpl<QrMapper, QrDO> implements IQrRepository {
@Override @Override
public VPage<QrDO> page(QrDTO dto) { public VPage<QrDO> page(QrDTO dto) {
LambdaQueryWrapper<QrDO> query = Wrappers.lambdaQuery(); LambdaQueryWrapper<QrDO> query = Wrappers.lambdaQuery();
@ -61,21 +63,9 @@ public class QrRepositoryImpl extends ServiceImpl<QrMapper, QrDO> implements IQr
@Override @Override
public boolean status(QrDTO status) { public boolean status(QrDTO status) {
LambdaUpdateWrapper<QrDO> update = Wrappers.lambdaUpdate();
QrDO qr = new QrDO(); QrDO qr = new QrDO();
BeanUtils.copyProperties(status, qr); BeanUtils.copyProperties(status, qr);
return updateById(qr); return updateById(qr);
} }
@Override
public String getTo(String id) {
QrDO qr = super.getById(id);
if (qr != null) {
if (StringUtils.isNotBlank(qr.getToUrl())) {
return qr.getToUrl();
}
return qr.getQnId();
} else {
return null;
}
}
} }

@ -1,6 +1,5 @@
package cn.soul2.jyjc.admin.repository.impl; package cn.soul2.jyjc.admin.repository.impl;
import cn.soul2.jyjc.admin.dto.QnOptionsDTO;
import cn.soul2.jyjc.admin.dto.QuestionnaireDTO; import cn.soul2.jyjc.admin.dto.QuestionnaireDTO;
import cn.soul2.jyjc.admin.dto.base.UpdateStatusDTO; import cn.soul2.jyjc.admin.dto.base.UpdateStatusDTO;
import cn.soul2.jyjc.admin.entity.QuestionnaireDO; import cn.soul2.jyjc.admin.entity.QuestionnaireDO;
@ -8,7 +7,6 @@ import cn.soul2.jyjc.admin.mapper.QuestionnaireMapper;
import cn.soul2.jyjc.admin.repository.IQuestionnaireRepository; import cn.soul2.jyjc.admin.repository.IQuestionnaireRepository;
import cn.soul2.jyjc.admin.utils.base.PageUtils; import cn.soul2.jyjc.admin.utils.base.PageUtils;
import cn.soul2.jyjc.admin.vo.QuestionnaireVO; import cn.soul2.jyjc.admin.vo.QuestionnaireVO;
import cn.soul2.jyjc.admin.vo.base.OptionsVO;
import cn.soul2.jyjc.admin.vo.base.VPage; import cn.soul2.jyjc.admin.vo.base.VPage;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@ -19,9 +17,6 @@ import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -79,20 +74,4 @@ public class QuestionnaireRepositoryImpl extends ServiceImpl<QuestionnaireMapper
query.orderByDesc(QuestionnaireDO::getUpdatedTime); query.orderByDesc(QuestionnaireDO::getUpdatedTime);
return super.getOne(query); return super.getOne(query);
} }
@Override
public List<OptionsVO> options(QnOptionsDTO dto) {
LambdaQueryWrapper<QuestionnaireDO> query = Wrappers.lambdaQuery();
query.select(QuestionnaireDO::getId, QuestionnaireDO::getName)
.eq(dto.getStatus() != null && dto.getStatus() > 0, QuestionnaireDO::getStatus, dto.getStatus())
.orderByDesc(QuestionnaireDO::getUpdatedTime)
.orderByDesc(QuestionnaireDO::getCreatedTime);
return super.list(query).stream().map(q -> new OptionsVO().setCode(q.getId()).setLabel(q.getName()).setTime(q.getUpdatedTime())).collect(Collectors.toList());
}
@Override
public Map<String, QuestionnaireDO> mapByIds(Collection<String> ids) {
List<QuestionnaireDO> list = listByIds(ids);
return list.stream().collect(Collectors.toMap(QuestionnaireDO::getId, o -> o, (o1, o2) -> o1));
}
} }

@ -100,7 +100,6 @@ public class RefSubjectItemsRepositoryImpl extends ServiceImpl<RefSubjectItemsMa
return removed; return removed;
} }
@Override @Override
public Integer updateRef(String subjectId, Collection<String> newItemIds) { public Integer updateRef(String subjectId, Collection<String> newItemIds) {
return null; return null;

@ -14,8 +14,6 @@ import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/** /**
* <p> * <p>
@ -48,11 +46,6 @@ public class SubjectItemsRepositoryImpl extends ServiceImpl<SubjectItemsMapper,
return super.list(query); return super.list(query);
} }
@Override
public Map<String, SubjectItemsDO> mapByIds(Collection<String> ids) {
return super.listByIds(ids).stream().collect(Collectors.toMap(SubjectItemsDO::getId, o -> o, (o1, o2) -> o1));
}
@Override @Override
public Boolean removeBySubjectId(Collection<String> subjectIds) { public Boolean removeBySubjectId(Collection<String> subjectIds) {
LambdaUpdateWrapper<SubjectItemsDO> update = Wrappers.lambdaUpdate(); LambdaUpdateWrapper<SubjectItemsDO> update = Wrappers.lambdaUpdate();

@ -154,8 +154,5 @@ public class SubjectRepositoryImpl extends ServiceImpl<SubjectMapper, SubjectDO>
return PageUtils.to(subjectMapper.useCounts(PageUtils.build(dto), query, dto.getQnId())); return PageUtils.to(subjectMapper.useCounts(PageUtils.build(dto), query, dto.getQnId()));
} }
@Override
public Map<String, SubjectDO> mapByIds(Collection<String> ids) {
return super.listByIds(ids).stream().collect(Collectors.toMap(SubjectDO::getId, o -> o, (o1, o2) -> o1));
}
} }

@ -1,126 +0,0 @@
package cn.soul2.jyjc.admin.repository.impl;
import cn.soul2.jyjc.admin.bean.UserLoginStatusBean;
import cn.soul2.jyjc.admin.dto.UserLoginDTO;
import cn.soul2.jyjc.admin.dto.UserLoginOutPageDTO;
import cn.soul2.jyjc.admin.dto.UserLogoutDTO;
import cn.soul2.jyjc.admin.entity.UserDO;
import cn.soul2.jyjc.admin.entity.UserLoginOutDO;
import cn.soul2.jyjc.admin.mapper.UserLoginOutMapper;
import cn.soul2.jyjc.admin.repository.IUserLoginOutRepository;
import cn.soul2.jyjc.admin.utils.base.PageUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* <p>
* 用户登入登出表 服务实现类
* </p>
*
* @author Soul2
* @since 2024-03-29 20:46:42
*/
@Service
public class UserLoginOutRepositoryImpl extends ServiceImpl<UserLoginOutMapper, UserLoginOutDO> implements IUserLoginOutRepository {
@Autowired
private UserLoginStatusBean userLoginStatusBean;
@Override
public IPage<UserLoginOutDO> page(UserLoginOutPageDTO dto) {
LambdaQueryWrapper<UserLoginOutDO> query = Wrappers.lambdaQuery();
query.eq(StringUtils.isNotBlank(dto.getUserId()), UserLoginOutDO::getUserId, dto.getUserId())
.orderByDesc(UserLoginOutDO::getCreatedTime);
return super.page(PageUtils.build(dto), query);
}
@Override
public String login(UserLoginDTO dto, UserDO user) {
UserLoginOutDO loginOutDO;
boolean saved;
LocalDateTime now = LocalDateTime.now();
// 判断是否登陆过,在缓存无法读取到目标用户名时即未登录,若登录过则令之前的登录记录失效
String token = userLoginStatusBean.getTokenByUsername(dto.getUsername());
if (token != null) {
userLoginStatusBean.logout(token);
UserLoginOutDO oldLoginOut = super.getById(token);
oldLoginOut.setLapseTime(now).setLogoutTime(now);
super.updateById(oldLoginOut);
}
loginOutDO = new UserLoginOutDO();
loginOutDO.setUserId(user.getId())
.setUserName(user.getUsername())
.setLoginTime(now)
.setLapseTime(now.plusHours(2))
;
saved = super.save(loginOutDO);
if (saved) {
userLoginStatusBean.login(loginOutDO.getId(), loginOutDO);
return loginOutDO.getId();
}
return null;
}
@Override
public String logout(UserLogoutDTO dto) {
// 清除缓存内的登录信息
Boolean logout = userLoginStatusBean.logout(dto.getToken());
// 保存退出登录的时间
LocalDateTime now = LocalDateTime.now();
UserLoginOutDO oldLoginOut = super.getById(dto.getToken());
oldLoginOut.setLogoutTime(now);
super.updateById(oldLoginOut);
return logout ? dto.getUsername() : null;
}
@Override
public Boolean logoutByUserId(String userId) {
return userLoginStatusBean.logoutByUserId(userId);
}
@Override
public Boolean removeByUserId(String userId) {
if (org.apache.commons.lang3.StringUtils.isBlank(userId)) {
return Boolean.TRUE;
}
LambdaUpdateWrapper<UserLoginOutDO> update = Wrappers.lambdaUpdate();
update.eq(UserLoginOutDO::getUserId, userId);
return super.remove(update);
}
@Override
public List<UserLoginOutDO> getLoginedUser() {
LocalDateTime now = LocalDateTime.now();
LambdaQueryWrapper<UserLoginOutDO> query = Wrappers.lambdaQuery();
query
.isNull(UserLoginOutDO::getLogoutTime)
.gt(UserLoginOutDO::getLapseTime, now);
List<UserLoginOutDO> list = super.list(query);
if (CollectionUtils.isEmpty(list)) {
return new ArrayList<>();
}
return new ArrayList<>(list
.stream()
.collect(Collectors.toMap(UserLoginOutDO::getUserId,
Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(UserLoginOutDO::getLoginTime))))
.values());
}
}

@ -1,60 +0,0 @@
package cn.soul2.jyjc.admin.repository.impl;
import cn.soul2.jyjc.admin.dto.UserPageDTO;
import cn.soul2.jyjc.admin.dto.UserSaveDTO;
import cn.soul2.jyjc.admin.dto.base.UpdateStatusDTO;
import cn.soul2.jyjc.admin.entity.UserDO;
import cn.soul2.jyjc.admin.mapper.UserMapper;
import cn.soul2.jyjc.admin.repository.IUserRepository;
import cn.soul2.jyjc.admin.utils.base.PageUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
/**
* <p>
* 用户表 服务实现类
* </p>
*
* @author Soul2
* @since 2024-03-29 20:46:42
*/
@Service
public class UserRepositoryImpl extends ServiceImpl<UserMapper, UserDO> implements IUserRepository {
@Override
public IPage<UserDO> page(UserPageDTO dto) {
LambdaQueryWrapper<UserDO> query = Wrappers.lambdaQuery();
query.eq(dto.getStatus() != null, UserDO::getStatus, dto.getStatus())
.like(StringUtils.isNotBlank(dto.getUsername()), UserDO::getUsername, dto.getUsername())
.orderByDesc(UserDO::getUpdatedTime);
return super.page(PageUtils.build(dto), query);
}
@Override
public Boolean saveOrUpdate(UserSaveDTO dto) {
UserDO user = new UserDO();
BeanUtils.copyProperties(dto, user);
return super.saveOrUpdate(user);
}
@Override
public Boolean updateStatus(UpdateStatusDTO dto) {
LambdaUpdateWrapper<UserDO> update = Wrappers.lambdaUpdate();
update.set(UserDO::getStatus, dto.getStatus())
.eq(UserDO::getId, dto.getId());
return super.update(update);
}
@Override
public UserDO getOneByUsername(String username) {
LambdaQueryWrapper<UserDO> query = Wrappers.lambdaQuery();
query.eq(UserDO::getUsername, username);
return super.getOne(query, false);
}
}

@ -1,31 +0,0 @@
package cn.soul2.jyjc.admin.service;
import cn.soul2.jyjc.admin.dto.AnswerPageQueryDTO;
import cn.soul2.jyjc.admin.dto.AnswerSubmitDTO;
import cn.soul2.jyjc.admin.vo.AnswerSheetVO;
import cn.soul2.jyjc.admin.vo.base.VPage;
/**
* @author Soul2
* @date 2024-03-27 14:43
*/
public interface IAnswerService {
/**
* 提交答卷
*
* @param dto 答卷内容
* @return {@link Boolean}
*/
Boolean handleSubmit(AnswerSubmitDTO dto);
/**
* 分页查询
*
* @param dto 查询条件
* @return {@link VPage}<{@link AnswerSheetVO}>
*/
VPage<AnswerSheetVO> page(AnswerPageQueryDTO dto);
}

@ -1,56 +0,0 @@
package cn.soul2.jyjc.admin.service;
import cn.soul2.jyjc.admin.dto.UserLoginDTO;
import cn.soul2.jyjc.admin.dto.UserLogoutDTO;
import cn.soul2.jyjc.admin.entity.UserLoginOutDO;
import cn.soul2.jyjc.admin.vo.UserVO;
import java.util.List;
/**
* @author Soul2
* @date 2024-03-29 20:47
*/
public interface IUserService {
/**
* 注册一个用户
*
* @param dto 用户名和密码
* @return {@link UserVO}
*/
UserVO register(UserLoginDTO dto);
/**
* 用户登录
*
* @param dto 用户名和密码
* @return {@link UserVO}
*/
UserVO login(UserLoginDTO dto);
/**
* 用户退出登录
*
* @param dto 登录key
* @return {@link Boolean}
*/
Boolean logout(UserLogoutDTO dto);
/**
* 删除用户并退出登录,同时将登录记录一并删除
*
* @param userId 用户id
* @return {@link Boolean}
*/
Boolean remove(String userId);
/**
* 重建当前登录的用户
*
* @return {@link List}<{@link UserLoginOutDO}>
*/
List<UserLoginOutDO> getLoginedUser();
}

@ -1,66 +0,0 @@
package cn.soul2.jyjc.admin.service.impl;
import cn.soul2.jyjc.admin.dto.AnswerPageQueryDTO;
import cn.soul2.jyjc.admin.dto.AnswerSubmitDTO;
import cn.soul2.jyjc.admin.entity.AnswerDetailsDO;
import cn.soul2.jyjc.admin.entity.AnswerSheetDO;
import cn.soul2.jyjc.admin.repository.IAnswerDetailsRepository;
import cn.soul2.jyjc.admin.repository.IAnswerSheetRepository;
import cn.soul2.jyjc.admin.service.IAnswerService;
import cn.soul2.jyjc.admin.vo.AnswerSheetVO;
import cn.soul2.jyjc.admin.vo.base.VPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author Soul2
* @date 2024-03-27 14:43
*/
@Service
public class AnswerServiceImpl implements IAnswerService {
@Autowired
private IAnswerSheetRepository sheetRepository;
@Autowired
private IAnswerDetailsRepository detailsRepository;
@Override
@Transactional
public Boolean handleSubmit(AnswerSubmitDTO dto) {
AnswerSheetDO sheet = new AnswerSheetDO();
sheet.setRespondent(dto.getOpenid())
.setQnId(dto.getQnId())
.setQrId(dto.getQrId());
boolean sheetSaved = sheetRepository.save(sheet);
if (sheetSaved) {
List<AnswerDetailsDO> details = dto.getDetails().stream().map(d -> {
AnswerDetailsDO detail = new AnswerDetailsDO();
detail.setAnswerContent(d.getContent())
.setAnswerSheetId(sheet.getId())
.setSubjectType(d.getSubjectType())
.setSubjectId(d.getSubjectId());
return detail;
}).collect(Collectors.toList());
boolean detailsSaved = detailsRepository.saveBatch(details);
if (!detailsSaved) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return Boolean.FALSE;
}
} else {
return Boolean.FALSE;
}
return Boolean.TRUE;
}
@Override
public VPage<AnswerSheetVO> page(AnswerPageQueryDTO dto) {
return sheetRepository.page(dto);
}
}

@ -11,7 +11,6 @@ import cn.soul2.jyjc.admin.service.ISubjectService;
import cn.soul2.jyjc.admin.vo.SubjectItemVO; import cn.soul2.jyjc.admin.vo.SubjectItemVO;
import cn.soul2.jyjc.admin.vo.SubjectVO; import cn.soul2.jyjc.admin.vo.SubjectVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
@ -50,9 +49,6 @@ public class SubjectServiceImpl implements ISubjectService {
List<RefQuestionnaireSubjectDO> refs = refQuestionnaireSubjectRepository.list(query); List<RefQuestionnaireSubjectDO> refs = refQuestionnaireSubjectRepository.list(query);
Set<String> idSet = refs.stream().map(RefQuestionnaireSubjectDO::getSubjectId).collect(Collectors.toSet()); Set<String> idSet = refs.stream().map(RefQuestionnaireSubjectDO::getSubjectId).collect(Collectors.toSet());
List<SubjectItemsDO> itemsDos = itemsRepository.listBySubjectIds(idSet); List<SubjectItemsDO> itemsDos = itemsRepository.listBySubjectIds(idSet);
if (CollectionUtils.isEmpty(idSet)) {
return new ArrayList<>();
}
List<SubjectDO> list = subjectRepository.listByIds(idSet); List<SubjectDO> list = subjectRepository.listByIds(idSet);
return list.stream().map(e -> { return list.stream().map(e -> {
SubjectVO vo = new SubjectVO(); SubjectVO vo = new SubjectVO();

@ -1,95 +0,0 @@
package cn.soul2.jyjc.admin.service.impl;
import cn.soul2.jyjc.admin.dto.UserLoginDTO;
import cn.soul2.jyjc.admin.dto.UserLogoutDTO;
import cn.soul2.jyjc.admin.entity.UserDO;
import cn.soul2.jyjc.admin.entity.UserLoginOutDO;
import cn.soul2.jyjc.admin.repository.IUserLoginOutRepository;
import cn.soul2.jyjc.admin.repository.IUserRepository;
import cn.soul2.jyjc.admin.service.IUserService;
import cn.soul2.jyjc.admin.utils.Md5Utils;
import cn.soul2.jyjc.admin.vo.UserVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author Soul2
* @date 2024-03-29 20:47
*/
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private IUserRepository userRepository;
@Autowired
private IUserLoginOutRepository loginOutRepository;
@Override
public UserVO register(UserLoginDTO dto) {
UserVO vo = new UserVO();
if (userRepository.getOneByUsername(dto.getUsername()) == null) {
UserDO user = new UserDO();
user.setUsername(dto.getUsername())
.setPassword(Md5Utils.md5(dto.getPassword()));
boolean saved = userRepository.save(user);
if (!saved) {
vo.setLoginFail("注册失败!");
} else {
String loginKey = loginOutRepository.login(dto, user);
if (loginKey != null) {
BeanUtils.copyProperties(user, vo);
vo.setToken(loginKey);
} else {
vo.setLoginFail("注册成功但登录失败!");
}
}
} else {
vo.setLoginFail("用户名已存在!");
}
return vo;
}
@Override
public UserVO login(UserLoginDTO dto) {
UserVO vo = new UserVO();
UserDO user = userRepository.getOneByUsername(dto.getUsername());
if (user != null) {
if (Md5Utils.verify(user.getPassword(), dto.getPassword())) {
String loginKey = loginOutRepository.login(dto, user);
if (loginKey != null) {
BeanUtils.copyProperties(user, vo);
vo.setToken(loginKey);
} else {
vo.setLoginFail("登录失败!");
}
} else {
vo.setLoginFail("密码错误!");
}
} else {
vo.setLoginFail("该用户尚未注册!");
}
return vo;
}
@Override
public Boolean logout(UserLogoutDTO dto) {
return loginOutRepository.logout(dto) != null;
}
@Override
public Boolean remove(String userId) {
loginOutRepository.logoutByUserId(userId);
loginOutRepository.removeByUserId(userId);
return userRepository.removeById(userId);
}
@Override
public List<UserLoginOutDO> getLoginedUser() {
return loginOutRepository.getLoginedUser();
}
}

@ -1,48 +0,0 @@
package cn.soul2.jyjc.admin.utils;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
/**
* @author Soul2
* @date 2024-03-30 14:02
*/
public class AesUtils {
private static final String AES_KEY = "98478f8a45887eda446501bcb44010520c3f53c7b45ff36215e86ce4f049b0f2";
private static final String AES_ALGORITHM = "AES";
private static SecretKeySpec generateKey(String key) {
return new SecretKeySpec(key.getBytes(), AES_ALGORITHM);
}
public static String encrypt(String source) throws Exception {
return encrypt(source, AES_KEY);
}
public static String decrypt(String encrypted) throws Exception {
return decrypt(encrypted, AES_KEY);
}
public static String encrypt(String source, String key) throws Exception {
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, generateKey(key));
byte[] encryptedBytes = cipher.doFinal(source.getBytes());
return Base64.getEncoder().encodeToString(encryptedBytes);
}
public static String decrypt(String encrypted, String key) throws Exception {
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, generateKey(key));
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encrypted));
return new String(decryptedBytes);
}
public static void main(String[] args) {
}
}

@ -1,132 +0,0 @@
package cn.soul2.jyjc.admin.utils;
import org.apache.tomcat.util.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
/**
* @author Soul2
* @date 2024-04-08 15:00
* <p>照抄自 <a href="https://blog.csdn.net/shaoduo/article/details/122322578">Shao duo</a></p>
*/
public class EncryptUtils {
private static final String KEY = "620b8d3c3be1e725";
//参数分别代表 算法名称/加密模式/数据填充方式
private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";
/**
* 加密
*
* @param content 加密的字符串
* @param encryptKey key值
* @return {@link String}
*/
public static String encrypt(String content, String encryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES"));
byte[] b = cipher.doFinal(content.getBytes("utf-8"));
// 采用base64算法进行转码,避免出现中文乱码
return Base64.encodeBase64String(b);
}
/**
* 解密
*
* @param encryptStr 解密的字符串
* @param decryptKey 解密的key值
* @return {@link String}
*/
public static String decrypt(String encryptStr, String decryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes("utf-8"), "AES"));
// 采用base64算法进行转码,避免出现中文乱码
//byte[] b = hex2Bytes(encryptStr) ;
byte[] encryptBytes = Base64.decodeBase64(encryptStr);
byte[] decryptBytes = cipher.doFinal(encryptBytes);
return new String(decryptBytes);
}
/**
* @param content 加密的字符串
* @return {@link String}
*/
public static String encrypt(String content) throws Exception {
return encrypt(content, KEY);
}
/**
* @param encryptStr 解密的字符串
* @return {@link String}
*/
public static String decrypt(String encryptStr) throws Exception {
return decrypt(encryptStr, KEY);
}
/* public static void main(String[] args) throws Exception {
Map map=new HashMap<String,String>();
map.put("key","value");
map.put("中文","汉字");
String content = JSONObject.toJSONString(map);
System.out.println("加密前:" + content);
String encrypt = encrypt(content, KEY);
System.out.println("加密后:" + encrypt);
String decrypt = decrypt(encrypt, KEY);
System.out.println("解密后:" + decrypt);
}*/
/**
* byte数组 转换成 16进制小写字符串
*/
public static String bytes2Hex(byte[] bytes) {
if (bytes == null || bytes.length == 0) {
return null;
}
StringBuilder hex = new StringBuilder();
for (byte b : bytes) {
hex.append(HEXES[(b >> 4) & 0x0F]);
hex.append(HEXES[b & 0x0F]);
}
return hex.toString();
}
/**
* 16进制字符串 转换为对应的 byte数组
*/
public static byte[] hex2Bytes(String hex) {
if (hex == null || hex.length() == 0) {
return null;
}
char[] hexChars = hex.toCharArray();
// 如果 hex 中的字符不是偶数个, 则忽略最后一个
byte[] bytes = new byte[hexChars.length / 2];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt("" + hexChars[i * 2] + hexChars[i * 2 + 1], 16);
}
return bytes;
}
private static final char[] HEXES = {
'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'a', 'b',
'c', 'd', 'e', 'f'
};
}

@ -1,33 +0,0 @@
package cn.soul2.jyjc.admin.utils;
import org.springframework.util.DigestUtils;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
/**
* @author fuzongyao
* @date 2021/10/14 11:19
* @since 1.0
*/
public class Md5Utils {
/**
* 加盐
*/
private static final String SALT = "4v6dKAOn+tEiVH58/XKeUw==";
public static String md5(String body) {
body += SALT;
return DigestUtils.md5DigestAsHex(body.getBytes(StandardCharsets.UTF_8)).toUpperCase();
}
public static boolean verify(String md5, String body) {
return Objects.equals(md5, md5(body));
}
public static void main(String[] args) {
System.out.println(md5("123456"));
}
}

@ -19,16 +19,16 @@ public class MybatisFastGenerator {
private static final DatasourceConfig DATASOURCE_CONFIG = new DatasourceConfig( private static final DatasourceConfig DATASOURCE_CONFIG = new DatasourceConfig(
"Soul2", "Soul2",
"jdbc:mysql://soul2.cn:3306/thli_upline?characterEncoding=utf8&serverTimezone=GMT%2B8", "jdbc:mysql://localhost:3306/pioneer?characterEncoding=utf8&serverTimezone=GMT%2B8",
"thli", "root",
"thli@20180913" "123456"
); );
/** /**
* 设置需要生成的表名 * 设置需要生成的表名
*/ */
private static final String[] TABLE_NAMES = { private static final String[] TABLE_NAMES = {
"tb_user", "tb_user",
// "tb_user_login_out", "tb_user_login_out",
}; };
/** /**
* 是否为表更新 * 是否为表更新
@ -37,7 +37,7 @@ public class MybatisFastGenerator {
/** /**
* 模块名称 * 模块名称
*/ */
private static final String MODULE_NAME = "jyjc.admin"; private static final String MODULE_NAME = "demo";
/** /**
* 设置过滤表前缀 * 设置过滤表前缀

@ -1,35 +0,0 @@
package cn.soul2.jyjc.admin.utils;
import java.security.SecureRandom;
import java.util.Base64;
/**
* 盐值生成
*
* @author Soul2
* @date 2024-03-30 14:30
*/
public class SaltUtils {
/**
* 生成指定长度的盐值
*
* @param length 盐值长度
* @return {@link String}
*/
public static String generateSalt(int length) {
SecureRandom random = new SecureRandom();
byte[] salt = new byte[length];
random.nextBytes(salt);
return Base64.getEncoder().encodeToString(salt);
}
public static void main(String[] args) {
// 设置盐值长度
int saltLength = 16;
String salt = generateSalt(saltLength);
System.out.println("Generated Salt: " + salt);
}
}

@ -30,7 +30,7 @@ public class AnswerDetailsVO {
/** /**
* 题目类型:0-单选;1-多选;2-文字 * 题目类型:0-单选;1-多选;2-文字
*/ */
private Integer type; private Short type;
/** /**
* 回答内容(文字/选项) * 回答内容(文字/选项)

@ -1,32 +0,0 @@
package cn.soul2.jyjc.admin.vo;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
/**
* @author Soul2
* @date 2024-05-10 12:46
*/
@Data
@Accessors(chain = true)
public class AnswerPageVO {
/**
* qnId
*/
private String qnId;
/**
* qnName
*/
private String qnName;
/**
* sheets
*/
private List<AnswerSheetVO> sheets;
}

@ -1,10 +1,8 @@
package cn.soul2.jyjc.admin.vo; package cn.soul2.jyjc.admin.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
/** /**
@ -46,12 +44,6 @@ public class AnswerSheetVO {
*/ */
private List<AnswerDetailsVO> details; private List<AnswerDetailsVO> details;
/**
* 提交时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime submitTime;
/** /**
* 答卷人 * 答卷人
*/ */

@ -50,9 +50,4 @@ public class QrVO {
* 二维码url * 二维码url
*/ */
private String qrUrl; private String qrUrl;
/**
* 指向名称
*/
private String qnName;
} }

@ -1,38 +0,0 @@
package cn.soul2.jyjc.admin.vo;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author Soul2
* @date 2024-03-30 14:40
*/
@Data
@Accessors(chain = true)
public class UserVO {
/**
* username
*/
private String username;
/**
* token
* 其实就是'UserLoginOut'表的id
*/
private String token;
/**
* 权限等级
*/
private String authorityLevel;
/**
* 状态;0(默认)正常4封号9异常
*/
private Integer status;
private String loginFail;
}

@ -1,34 +0,0 @@
package cn.soul2.jyjc.admin.vo.base;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
* @author Soul2
* @date 2024-05-10 15:07
*/
@Data
@Accessors(chain = true)
public class OptionsVO {
/**
* code
*/
private String code;
/**
* label
*/
private String label;
/**
* date time
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime time;
}

@ -1,7 +1,7 @@
# 允许跨域的地址 # 允许跨域的地址
cors: cors:
allow-origin: http://localhost:6100, http://localhost:7620 allow-origins: http://localhost
--- ---
spring: spring:
@ -9,12 +9,13 @@ spring:
activate: activate:
on-profile: dev on-profile: dev
cors: cors:
allow-origin: http://localhost:6100, http://localhost:7620, http://192.168.10.104:7620 allow-origins: http://localhost:6100, http://localhost:7620, http://192.168.10.104:7620
--- ---
spring: spring:
config: config:
activate: activate:
on-profile: prod on-profile: prod
cors: cors:
allow-origin: http://test.soul2.cn allow-origins: http://test.soul2.cn

@ -4,6 +4,7 @@ server:
#上下文 #上下文
servlet.context-path: /thli/jyjc/api servlet.context-path: /thli/jyjc/api
spring: spring:
application.name: jyjc-admin application.name: jyjc-admin
profiles.include: datasource,mybatis-plus,cors profiles.include: datasource,mybatis-plus,cors

@ -1,127 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds">
<!--<include resource="org/springframework/boot/logging/logback/base.xml" />-->
<contextName>logback</contextName>
<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
<!-- <property name="log.path" value=".logs/"/>-->
<springProperty scope="context" name="log.path" source="logging.path" defaultValue="./logs/"/>
<property name="log.pattern"
value="%cyan(%d{HH:mm:ss}) %green(%-5level) %blue(%logger{50}) - %boldMagenta(%msg) \t\t ---- %yellow([%thread] %d{yyyy-MM-dd HH:mm:ss.SSS}) %n"
/>
<property name="debug.path" value="${log.path}/%d{yyyyMM,aux}/%d{dd,aux}/debug-%d{yyyyMMdd}.%i.log.gz"/>
<property name="info.path" value="${log.path}/%d{yyyyMM,aux}/%d{dd,aux}/info-%d{yyyyMMdd}.%i.log.gz"/>
<property name="error.path" value="${log.path}/%d{yyyyMM,aux}/%d{dd,aux}/error-%d{yyyyMMdd}.%i.log.gz"/>
<!--输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!-- 控制台输出的日志级别是大于或等于此级别的日志信息 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<!--日志文件输出格式与字符集-->
<encoder>
<Pattern>${log.pattern}</Pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--输出到文件-->
<!-- 时间滚动输出 level为 DEBUG 日志 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/debug.log</file>
<!--日志文件输出格式与字符集-->
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志归档 -->
<fileNamePattern>${debug.path}</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>7</maxHistory>
</rollingPolicy>
<!-- 此日志文件记录debug级别以上的 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
</appender>
<!-- 时间滚动输出 level为 INFO 日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/info.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${info.path}</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>60</maxHistory>
</rollingPolicy>
<!-- 此日志文件记录info级别以上的 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
</appender>
<!-- 时间滚动输出 level为 ERROR 日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/error.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${error.path}</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>60</maxHistory>
</rollingPolicy>
<!-- 此日志文件记录error级别以上的 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<!--开发环境:打印控制台-->
<springProfile name="local,dev,test">
<logger level="DEBUG" additivity="false" name="cn.soul2">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="DEBUG_FILE"/>
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="ERROR_FILE"/>
</logger>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="ERROR_FILE"/>
</root>
</springProfile>
<!--生产环境:输出到文件-->
<springProfile name="pre,prod,prod-yun">
<root level="INFO">
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="ERROR_FILE"/>
</root>
</springProfile>
</configuration>
Loading…
Cancel
Save