图书馆,研究生

main
lensfrex 10 months ago
parent 1396a52945
commit 693e23f779
Signed by: lensfrex
GPG Key ID: 0F69A0A2FBEE98A0
  1. 4
      .gitignore
  2. 4
      README.md
  3. 4
      backend-main/backend-data/src/main/resources/mappers/StudentMapper.xml
  4. 4
      backend-main/backend-data/src/main/resources/mappers/UserBasicMapper.xml
  5. 19
      backend-main/backend-web/pom.xml
  6. 12
      backend-main/backend-web/src/main/java/wusthelper/web/annotation/RequireToken.java
  7. 4
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/TokenTool.java
  8. 486
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/code/V2ResponseCode.java
  9. 6
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/dto/response/CourseResponse.java
  10. 4
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/dto/response/graduate/GraduateScoreResponse.java
  11. 2
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/dto/response/graduate/GraduateStudentInfoResponse.java
  12. 94
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/dto/response/library/BookDetailResponse.java
  13. 78
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/dto/response/library/BookSearchResponseItem.java
  14. 31
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/dto/response/library/CurrentRentResponse.java
  15. 29
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/dto/response/library/RentHistoryResponse.java
  16. 3
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/dto/response/physics/PhysicsCourseResponse.java
  17. 4
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/dto/response/undergrad/CombineLoginResponse.java
  18. 2
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/dto/response/undergrad/StudentInfoResponse.java
  19. 25
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/handler/GlobalExceptionHandler.java
  20. 36
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/interceptor/NotFoundPathInterceptor.java
  21. 83
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/interceptor/TokenInterceptor.java
  22. 66
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/module/graduate/GraduateController.java
  23. 5
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/module/graduate/GraduateLoginController.java
  24. 28
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/module/library/LibraryLoginController.java
  25. 64
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/module/library/LibraryPersonalController.java
  26. 74
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/module/library/LibraryPublicController.java
  27. 17
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/module/linghang/LinghangController.java
  28. 10
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/module/physics/PhysicsController.java
  29. 5
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/module/physics/PhysicsLoginController.java
  30. 15
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/module/undergrade/UndergradController.java
  31. 11
      backend-main/backend-web/src/main/java/wusthelper/web/api/v2/module/undergrade/UndergradLoginController.java
  32. 8
      backend-main/backend-web/src/main/java/wusthelper/web/configure/PasswordCodecConfigure.java
  33. 31
      backend-main/backend-web/src/main/java/wusthelper/web/configure/WebMvcConfigure.java
  34. 14
      backend-main/backend-web/src/main/java/wusthelper/web/configure/WusthelperConfigureItems.java
  35. 2
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/graduate/GraduateCookieRemote.java
  36. 2
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/graduate/GraduateCourseTableRemote.java
  37. 2
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/graduate/GraduateScoreRemote.java
  38. 2
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/graduate/GraduateStudentInfoRemote.java
  39. 2
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/graduate/GraduateTrainingPlanRemote.java
  40. 27
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/library/LibraryBookCoverImageRemote.java
  41. 24
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/library/LibraryBookDetailRemote.java
  42. 23
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/library/LibraryBookHoldingRemote.java
  43. 20
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/library/LibraryCookieRemote.java
  44. 31
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/library/LibraryCurrentLoanRemote.java
  45. 31
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/library/LibraryLoanHistoryRemote.java
  46. 31
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/library/LibraryOverdueSoonRemote.java
  47. 31
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/library/LibrarySearchRemote.java
  48. 2
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/physics/PhysicsCookieRemote.java
  49. 2
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/physics/PhysicsCourseTableRemote.java
  50. 2
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/physics/PhysicsScoreRemote.java
  51. 2
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/undergrad/UndergradCookieRemote.java
  52. 2
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/undergrad/UndergradCourseTableRemote.java
  53. 2
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/undergrad/UndergradCreditStatusRemote.java
  54. 2
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/undergrad/UndergradExamDelayApplicationRemote.java
  55. 2
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/undergrad/UndergradScoreRemote.java
  56. 2
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/undergrad/UndergradStudentInfoRemote.java
  57. 2
      backend-main/backend-web/src/main/java/wusthelper/web/rpc/http/undergrad/UndergradTrainingPlanRemote.java
  58. 12
      backend-main/backend-web/src/main/java/wusthelper/web/service/campus/UserLoginService.java
  59. 11
      backend-main/backend-web/src/main/java/wusthelper/web/service/campus/library/LibraryCookieService.java
  60. 70
      backend-main/backend-web/src/main/java/wusthelper/web/service/campus/library/LibraryPersonalService.java
  61. 93
      backend-main/backend-web/src/main/java/wusthelper/web/service/campus/library/LibraryPublicService.java
  62. 2
      backend-main/backend-web/src/main/java/wusthelper/web/service/campus/undergrad/UndergradTrainingPlanService.java
  63. 33
      backend-main/backend-web/src/main/java/wusthelper/web/service/cookie/CookieManager.java
  64. 2
      backend-main/backend-web/src/main/java/wusthelper/web/service/student/StudentService.java
  65. 2
      backend-main/backend-web/src/main/java/wusthelper/web/util/GlobalLogger.java
  66. 41
      backend-main/backend-web/src/main/resources/application.yml
  67. 11
      common/src/main/java/wusthelper/code/ServiceCode.java
  68. 7
      common/src/main/java/wusthelper/web/response/Response.java
  69. 23
      common/src/main/java/wusthelper/web/util/PasswordCodec.java
  70. 2
      external-library/mywust
  71. 3
      external-library/rpc-frp-consul/src/main/java/wusthelper/internal/rpc/FrpConsulRegister.java
  72. 15
      external-library/rpc-frp-consul/src/main/java/wusthelper/internal/rpc/util/IPUtil.java
  73. 17
      pom.xml
  74. 1
      sub-services/graduate/pom.xml
  75. 10
      sub-services/graduate/src/main/java/wusthelper/internal/graduate/rpc/Register.java
  76. 5
      sub-services/graduate/src/main/java/wusthelper/internal/graduate/rpc/config/RpcConfig.java
  77. 2
      sub-services/graduate/src/main/resources/application.properties
  78. 18
      sub-services/library/src/main/java/wusthelper/internal/library/rpc/Register.java
  79. 5
      sub-services/library/src/main/java/wusthelper/internal/library/rpc/config/RpcConfig.java
  80. 2
      sub-services/library/src/main/resources/application.properties
  81. 18
      sub-services/physics/src/main/java/wusthelper/internal/physics/rpc/Register.java
  82. 5
      sub-services/physics/src/main/java/wusthelper/internal/physics/rpc/config/RpcConfig.java
  83. 2
      sub-services/physics/src/main/resources/application.properties
  84. 6
      sub-services/undergrad/pom.xml
  85. 1
      sub-services/undergrad/src/main/java/wusthelper/internal/undergrad/api/http/v1/interceptor/ResponseWrapperInterceptor.java
  86. 19
      sub-services/undergrad/src/main/java/wusthelper/internal/undergrad/rpc/Register.java
  87. 5
      sub-services/undergrad/src/main/java/wusthelper/internal/undergrad/rpc/config/RpcConfig.java
  88. 1
      sub-services/undergrad/src/main/java/wusthelper/internal/undergrad/services/LoginService.java
  89. 3
      sub-services/undergrad/src/main/java/wusthelper/internal/undergrad/services/ScoreService.java
  90. 4
      sub-services/undergrad/src/main/resources/application.properties

4
.gitignore vendored

@ -37,4 +37,6 @@ build/
### Mac OS ###
.DS_Store
.env
.env
.flattened-pom.xml

@ -1,5 +1,7 @@
# Wusthelper-backend
> ⚠ 未完成状态,半成品,部分接口未完全兼容实现
武科大助手后端项目
应该是第三代后端了吧。
@ -29,7 +31,7 @@ Maven 3.8.2+
- *后续可能会看情况转用Gradle*
Java版本:
Java 17+
Java 17+(应使用OpenJDK,OracleJDK(包括Graalvm)会出现 `SecurityException: JCE cannot authenticate the provider BC` 异常)
---

@ -0,0 +1,4 @@
<?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="wusthelper.data.dao.mapper.StudentMapper">
</mapper>

@ -0,0 +1,4 @@
<?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="wusthelper.data.dao.mapper.UserBasicMapper">
</mapper>

@ -36,11 +36,11 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
<version>${consul-discovery.version}</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-consul-discovery</artifactId>-->
<!-- <version>${consul-discovery.version}</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
@ -96,11 +96,20 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot.version}</version>
<configuration>
<systemPropertyVariables>
<file.encoding>UTF-8</file.encoding>
</systemPropertyVariables>
<mainClass>wusthelper.WebBackendMain</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

@ -0,0 +1,12 @@
package wusthelper.web.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface RequireToken {
boolean require() default true;
}

@ -13,7 +13,7 @@ public class TokenTool {
private final static String SECRET = "LingHangStudio.WustHelper";
private final static long EXPIRE_SCD = Duration.ofDays(3).toSeconds();
private final static long EXPIRE_MILLIS = Duration.ofDays(3).toMillis();
private static final Algorithm jwtAlgorithm = Algorithm.HMAC256(SECRET);
@ -25,7 +25,7 @@ public class TokenTool {
public static String signToken(Long uid, String studentNumber) {
try {
Date now = new Date();
Date expireAt = new Date(now.getTime() + EXPIRE_SCD);
Date expireAt = new Date(now.getTime() + EXPIRE_MILLIS);
return JWT.create()
.withClaim("StuId", uid.toString())

@ -0,0 +1,486 @@
package wusthelper.web.api.v2.code;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* <h>响应码枚举</h>
* <ul>
* <li>BASE_ 基本状态码: 10000-19999</li>
* <li>AUTH_ 用户身份验证C: 20000-29999</li>
* <li>JWC_ 教务处: 30000-39999</li>
* <li>LIB_ 图书馆: 40000-49999</li>
* <li>VOL_ 工时: 50000-59999</li>
* <li>YJS_ 研究生: 80000-89999</li>
* </ul>
* <p>状态码表示含义 <br>
* 12345: 1号模块23号接口45型状态
* </p>
*
* <p>
* <br>
* 关于状态码统一: <br>
* 由于安卓端表示成功状态码过于繁杂这里对成功的状态码进行了统一 <br>
* 所有成功状态 10000 <br>
* 所有因官方崩溃产生的失败但读取本地数据成功的状态 11000 <br>
* 修改: 2021/3/12
* </p>
* <br><br>
* <p>LingHang业务接口</p>
*
* @Author WSharkCoder
* @Date 2021/1/15 21:40
* @ClassName ResponseCode
*/
@AllArgsConstructor
@Getter
public enum V2ResponseCode {
//基本状态码 START (1)
/**
* 成功
*/
SUC(10000, "成功"),
/**
* 本地成功
*/
LOCAL_SUC(11000, "本地成功"),
/**
* 操作频繁
*/
LIMIT_REQUEST(99999, "操作频繁,请稍后再试"),
/**
* 失败
*/
ERR(11111, "失败"),
/**
* 参数缺失或参数类型错误
*/
BASE_PARAM_ERR(10001, "参数缺失或参数类型错误"),
/**
* 拒绝请求
*/
REQUEST_DENIED(10002, "请求错误"),
/**
* 接口调用错误:请求方式出错或者参数缺失
*/
REQUEST_CALLED_ERR(10003, "接口调用错误:请求出错,data中为错误信息,请检查并详细参照api文档使用该接口"),
/**
* 客户端连接中断
*/
CLIENT_ABORT_ERR(10004, "连接中断"),
//基本状态码 END
//身份验证状态码 START (2)
/**
* 用户身份验证模块异常
*/
AUTH_ERR(20001, "用户身份验证模块异常"),
/**
* 用户身份校验失败:请求缺失令牌TOKEN
*/
AUTH_ERR_TOKEN_MISS(21001, "用户身份校验失败:请求缺失令牌TOKEN"),
/**
* 用户身份校验失败:TOKEN无效或过期
*/
AUTH_ERR_TOKEN_INVALID(21002, "用户身份校验失败:TOKEN无效或过期"),
/**
* TOKEN解密成功
*/
AUTH_DECODE_FOR_STUNUM_SUC(10000, "TOKEN解密成功"),
/**
* TOKEN解密失败
*/
AUTH_DECODE_FOR_STUNUM_ERR(21101, "TOKEN解密失败"),
//身份验证状态码 END
//JWC模块状态码 START (3)
/**
* 教务处密码已修改,请重新登录!
*/
JWC_PWD_NED_UPD(30001, "教务处密码已修改,请重新登录"),
/**
* 教务处登录成功
*/
JWC_LOGIN_SUC(10000, "教务处登录成功"),
/**
* 教务登录失败:教务崩溃
*/
JWC_LOGIN_ERR_JWC_ERR(30104, "登录失败:教务系统异常,请重试"),
/**
* 教务处登录失败:账号或密码错误
*/
JWC_LOGIN_ERR_JWC_FIN_INFO_ERR(30101, "登陆失败:账号或密码错误"),
/**
* 教务处登录失败:需用户前往教务处修改默认密码
*/
JWC_LOGIN_ERR_JWC_MOD_DEF_PWD(30102, "登录失败:请前往教务官网修改默认密码"),
/**
* 教务登录失败:教务崩溃|本地登录失败:本地账号或密码错误
*/
JWC_LOGIN_ERR_JWC_ERR_INFO_ERR(30103, "登录失败:账号或密码错误,或教务异常,请重试"),
/**
* 教务处登录失败:重试次数过多
*/
JWC_LOGIN_ERR_JWC_RETRY_TOO_MANY_TIMES_ERR(30101, "登录失败:密码重试次数已达三次,继续重试可能会导致暂时封禁,请等待约三分钟后重试,请确保账号和密码为“统一认证平台”的账号和密码,如忘记可前往官网进行密码找回"),
/**
* 教务处登录失败:重试次数过多被封禁
*/
JWC_LOGIN_ERR_JWC_USER_WAS_BANNED_ERR(30101, "登录失败:密码总重试次数已达五次,已被暂时封禁,请等待约十分钟后重试,请确保账号和密码为“统一认证平台”的账号和密码,如忘记可前往官网进行密码找回"),
/**
* 教务登录失败:教务崩溃|本地登录成功
*/
JWC_LOGIN_SUC_JWC_ERR_LOC_SUC(11000, "教务异常:缓存登录成功"),
/**
* 教务处获取用户信息成功
*/
JWC_GETSTUINFO_SUC(10000, "教务处获取用户信息成功"),
/**
* 教务处获取用户信息失败:教务处崩溃|本地学生信息获取成功
*/
JWC_GETSTUINFO_SUC_JWC_ERR_LOC_SUC(11000, "教务异常:缓存学生信息获取成功"),
/**
* 教务处获取用户信息失败用户不存在
*/
JWC_GETSTUINFO_ERR_NO_SUCH_STU(30201, "教务处获取用户信息失败:用户不存在"),
/**
* 教务处获取课表信息成功
*/
JWC_GETCURRICULUM_SUC(10000, "教务处获取课表信息成功"),
/**
* 教务处获取课表信息失败:教务崩溃|本地课表信息获取成功
*/
JWC_GETCURRICULUM_SUC_JWC_ERR_LOC_SUC(11000, "教务异常:缓存课表信息获取成功"),
/**
* 教务异常:获取课表失败
*/
JWC_GETCURRICULUM_ERR_JWC_ERR(30301, "教务异常:获取课表失败"),
/**
* 教务公告列表获取成功
*/
JWC_GETJWCANNLIST_SUC(10000, "教务公告列表获取成功"),
/**
* 教务公告内容获取成功
*/
JWC_GETJWCANNCNT_SUC(10000, "教务公告内容获取成功"),
/**
* 教务处成绩获取成功
*/
JWC_GETGRADE_SUC(10000, "教务处成绩获取成功"),
/**
* 教务处成绩获取失败:需用户前往教务处评教|本地成绩获取成功
*/
JWC_GETGRADE_ERR_NEED_EVALUATE_TEACHING(30601, "教务处成绩获取失败:请前往教务官网评教"),
/**
* 教务处成绩获取失败:教务处崩溃|本地成绩获取成功
*/
JWC_GETGRADE_ERR_JWC_ERR_LOC_SUC(11000, "教务异常:缓存成绩获取成功"),
/**
* 教务处学分明细获取成功
*/
JWC_GETCREDIT_SUC(10000, "教务处学分明细获取成功"),
/**
* 教务处学分明细获取失败:教务处崩溃|本地学分明细获取成功
*/
JWC_GETCREDIT_SUC_JWC_ERR_LOC_SUC(11000, "教务异常:缓存学分明细获取成功"),
JWC_TRAINING_SCHEME_SUC(10000, "教务处培养方案获取成功"),
JWC_TRAINING_SCHEME_ERR(30701, "教务异常,培养方案获取失败"),
//JWC模块验证码 END
//LIB状态码 START (4)
/**
* 图书馆密码已经修改请重新登录!
*/
LIB_PWD_NED_UPD(40001, "图书馆密码已经修改,请重新登录!"),
/**
* 图书馆登录已过期请重新登录
*/
LIB_LOGIN_EXPIRE(40002, "图书馆登录已过期,请重新登录"),
/**
* 图书馆登录成功
*/
LIB_LOGIN_SUC(10000, "图书馆登录成功"),
/**
* 图书馆登录失败:账号或密码错误
*/
LIB_LOGIN_ERR_LIB_FIN_INFO_ERR(40101, "登录失败:账号或密码错误"),
/**
* 图书馆登录失败:验证码错误
*/
LIB_LOGIN_ERR_WRONG_AUTH_CODE(40103, "登录失败:验证码错误"),
/**
* 图书馆登录失败:登陆失败次数过多请稍后重试
*/
LIB_LOGIN_ERR_TOO_MUCH_TIME(40104, "登录失败:登陆失败次数过多,请稍后重试"),
/**
* 图书馆登录失败:图书馆崩溃|本地登录失败:账号或密码错误
*/
LIB_LOGIN_ERR_LIB_ERR_INFO_ERR(40102, "登录失败:账号或密码错误"),
/**
* 图书馆登录失败:图书管崩溃|本地登录成功
*/
LIB_LOGIN_ERR_LIB_ERR_LOC_SUC(11000, "图书管异常:缓存登录成功"),
/**
* 图书馆历史借阅记录获取成功
*/
LIB_GETRENTHISTORY_SUC(10000, "图书馆历史借阅记录获取成功"),
/**
* 图书馆崩溃|本地图书馆借阅历史缓存获取成功
*/
LIB_GETRENTHISTORY_SUC_LIB_ERR_LOC_SUC(11000, "图书馆异常:缓存图书馆借阅历史缓存获取成功"),
/**
* 图书馆当前借阅记录获取成功
*/
LIB_GETCURRENTRENT_SUC(10000, "图书馆当前借阅记录获取成功"),
/**
* 图书馆崩溃|本地当前借阅获取成功
*/
LIB_GETCURRENTRENT_SUC_LIB_ERR_LOC_SUC(11000, "图书馆异常:缓存当前借阅获取成功"),
/**
* 图书馆异常:缓存借阅记录获取成功
*/
LIB_GETRENT_SUC_LIB_ERR_LOC_SUC(11000, "图书馆异常:缓存借阅记录获取成功"),
/**
* 借阅记录获取成功
*/
LIB_GETRENT_SUC(10000, "借阅记录获取成功"),
/**
* 图书馆公告列表获取成功
*/
LIB_GETLIBANNLIST_SUC(10000, "图书馆公告列表获取成功"),
/**
* 图书馆公告内容获取成功
*/
LIB_GETLIBANNCNT_SUC(10000, "图书馆公告内容获取成功"),
/**
* 图书馆检索图书成功
*/
LIB_SEARCH_SUC(10000, "图书馆检索图书成功"),
/**
* 图书馆检索图书异常
*/
LIB_SEARCH_ERR(40601, "图书馆检索图书异常"),
/**
* 图书馆获取图书详情成功
*/
LIB_GETBOOKDETAIL_SUC(10000, "图书馆获取图书详情成功"),
/**
* 图书馆获取图书详情异常
*/
LIB_GETBOOKDETAIL_ERR(40701, "图书馆获取图书详情异常"),
/**
* 图书馆增添收藏成功
*/
LIB_ADDCOLLECTION_SUC(10000, "图书馆增添收藏成功"),
/**
* 图书馆添加收藏异常
*/
LIB_ADDCOLLECTION_ERR(40801, "图书馆添加收藏异常"),
/**
* 图书馆收藏列表查询成功
*/
LIB_LISTCOLLECTION_SUC(10000, "图书馆收藏列表查询成功"),
/**
* 图书馆收藏删除成功
*/
LIB_DELCOLLECTION_SUC(10000, "图书馆收藏删除成功"),
/**
* 图书馆获取验证码成功
*/
LIB_GETYZM_SUC(11111, "图书馆获取验证码成功"),
/**
* 图书馆获取借阅历史和当前借阅成功
*/
LIB_GETCRH_SUC(10101, "图书馆获取借阅历史和当前借阅成功"),
//LIB状态码 END
//YJS状态码 START ()
/**
* 研究生官网登录成功
*/
YJS_LOGIN_SUC(10000, "研究生官网登录成功"),
/**
* 研究生官网登录失败:账号或密码错误
*/
YJS_LOGIN_ERR_YJS_FIN_INFO_ERR(80002, "登录失败:账号或密码错误"),
YJS_LOGIN_ERROR(11111, "登录失败,研究生官网异常,请稍后再试"),
YJS_GETSTUINFO_SUC(10000, "研究生官网获取用户信息成功"),
YJS_GETSTUINFO_ERR(11111, "研究生官网异常,获取用户信息失败,请稍后再试"),
YJS_GETGRADE_SUC(10000, "研究生官网成绩获取成功"),
YJS_GETGRADE_ERR(11111, "研究生官网异常,获取成绩失败,请稍后再试"),
YJS_GETCOURSE_SUC(10000, "研究生官网课表获取成功"),
YJS_GETCOURSE_ERR(11111, "研究生官网异常,刷新课表失败,请稍后再试"),
YJS_GETTRAINPLAN_SUC(10000, "研究生官网培养管理获取成功"),
YJS_GETTRAINPLAN_ERR(11111, "研究生官网异常,获取培养管理失败,请稍后再试"),
YJS_PWD_NED_UPD(80001, "研究生官网密码已修改,请重新登录"),
//YJS状态码 END
//倒计时 START (5)
/**
* 倒计时:操作成功
*/
COUNTDOWN_OPERATION_SUC(10000, "倒计时:操作成功"),
//倒计时 END
//消息中心 START (6)
/**
* 发送邮件成功
*/
SEND_EMAIL_SUC(10000, "发送邮件成功"),
/**
* 无效的消息来源
*/
MSG_ORIGIN_INVALID(60003, "无效的消息来源"),
/**
* 发送邮件失败
*/
SEND_EMAIL_ERR(60001, "发送邮件失败"),
/**
* 发送邮件失败收件邮箱不存在
*/
SEND_EMAIL_ERR_INVALID_TAR_ERR(60002, "发送邮件失败,收件邮箱不存在或产生其他问题"),
/**
* 向飞书通知群发送消息成功
*/
SEND_MSG_TO_FEISHU_SUC(10000, "向飞书通知群发送消息成功"),
/**
* 向飞书通知群发送消息失败
*/
SEND_MSG_TO_FEISHU_ERR(60101, "向飞书通知群发送消息失败"),
/**
* 向安卓客户端发送消息成功
*/
SEND_MSG_TO_ANDROID_SUC(10000, "向安卓客户端发送消息成功"),
/**
* 向安卓客户端发送消息失败
*/
SEND_MSG_TO_ANDROID_ERR(60201, "向安卓客户端发送消息失败,用户可能不在线上,或是发生错误"),
/**
* 获取全部安卓端记录消息成功
*/
ANDROID_MSG_GET_SUC(10000, "获取全部安卓端记录消息成功"),
//消息中心 END
//物理实验 START (7)
/**
* 登陆失败:账号或密码错误或不在实验课不在本学期
*/
WLSY_LOGIN_ERR_WLSY_FIN_INFO_ERR(70001, "登陆失败:账号或密码错误,或不在实验课不在本学期"),
/**
* 登陆失败:实验系统官网异常请重试
*/
WLSY_LOGIN_ERR_WLSY_ERR(70002, "登陆失败:实验系统官网异常,请重试"),
/**
* 实验系统异常:缓存登陆成功
*/
WLSY_LOGIN_ERR_WLSY_ERR_LOC_SUC(11000, "实验系统异常:缓存登陆成功"),
/**
* 物理实验系统登陆成功
*/
WLSY_LOGIN_SUC(10000, "物理实验系统登陆成功"),
/**
* 获取已选实验课失败:实验系统官网异常
*/
WLSY_GETCOURSE_ERR_WLSY_ERR(70101, "获取已选实验课失败:实验系统官网异常"),
/**
* 获取已选实验课失败:登录过期
*/
WLSY_GETCOURSE_ERR_LOGIN_EXPIRED(70102, "获取已选实验课失败:登录过期"),
/**
* 实验系统异常:缓存获取已选实验课成功
*/
WLSY_GETCOURSE_ERR_WLSY_ERR_LOC_SUC(11000, "实验系统异常:缓存获取已选实验课成功"),
/**
* 获取已选实验课成功
*/
WLSY_GETCOURSE_SUC(10000, "获取已选实验课成功"),
//物理实验 END
//教室查询 START (8)
/**
* 查询空教室成功
*/
CLSR_SEARCH_EMPTY_CLASSROOM_SUC(10000, "查询空教室成功"),
/**
* 查询学院列表成功
*/
CLSR_GET_COLLEGE_LIST_SUC(10000, "查询学院列表成功"),
/**
* 查询课名列表成功
*/
CLSR_GET_COURSE_NAME_LIST_SUC(10000, "查询课名列表成功"),
/**
* 查询课程详情成功
*/
CLSR_GET_COURSE_DETAIL_LIST_SUC(10000, "查询课程详情成功"),
/**
* 查询结果为空
*/
CLSR_RESULT_EMPTY(80001, "查询结果为空"),
/**
* 已是最后一页
*/
CLSR_NO_MORE_PAGE(80002, "已是最后一页"),
//教室查询 END (8)
//助手信息查询 BEGIN (9)
/**
* 获取用户详情信息成功
*/
GET_USER_INFO_SUC(10000, "获取用户详情信息成功"),
/**
* 获取用户操作记录成功
*/
GET_USER_OPE_RECORD_SUC(10000, "获取用户操作记录成功"),
/**
* 获取学号列表成功
*/
GET_STU_NUM_LIST_SUC(10000, "获取学号列表成功"),
/**
* 获取用户信息失败用户不存在
*/
GET_USER_INFO_ERR_USER_NOT_EXIST(90001, "获取用户信息失败,用户不存在"),
/**
* 获取用户操作记录失败用户不存在
*/
GET_USER_OPE_RECORD_ERR_USER_NOT_EXIST(90101, "获取用户操作记录失败,用户不存在"),
/**
* 目标日志不存在或为空
*/
LOG_EMPTY_OR_NOT_EXIST(90201, "目标日志不存在或为空"),
/**
* 获取日志信息成功
*/
GET_LOG_INFO_SUC(10000, "获取日志信息成功"),
/**
* 获取时段请求信息成功
*/
GET_TIME_REPORT_SUC(10000, "获取时段请求信息成功"),
//助手信息查询 END (9)
;
private final int code;
private final String msg;
}

@ -1,9 +1,15 @@
package wusthelper.web.api.v2.dto.response;
import cn.wustlinghang.mywust.data.global.Course;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CourseResponse {
/**
* 课程名称

@ -1,4 +1,4 @@
package wusthelper.web.api.v2.dto.response;
package wusthelper.web.api.v2.dto.response.graduate;
import cn.wustlinghang.mywust.data.global.Score;
import lombok.Data;
@ -25,7 +25,7 @@ public class GraduateScoreResponse {
graduateScoreResponse.setName(score.getCourseName());
graduateScoreResponse.setCredit(Double.parseDouble(score.getCredit()));
graduateScoreResponse.setTerm(Integer.parseInt(score.getTerm()));
graduateScoreResponse.setPoint(score.getGradePoint());
graduateScoreResponse.setPoint(score.getScore());
return graduateScoreResponse;
}

@ -1,4 +1,4 @@
package wusthelper.web.api.v2.dto.response;
package wusthelper.web.api.v2.dto.response.graduate;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import com.fasterxml.jackson.annotation.JsonInclude;

@ -0,0 +1,94 @@
package wusthelper.web.api.v2.dto.response.library;
import cn.wustlinghang.mywust.data.library.origin.BookSearchResult;
import cn.wustlinghang.mywust.data.library.parsed.BookDetail;
import cn.wustlinghang.mywust.data.library.parsed.BookHolding;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.util.List;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class BookDetailResponse {
/**
* 题名/责任者
*/
private String bookNameAndAuth;
/**
* 出版发行项
*/
private String publisher;
/**
* ISBN及定价
*/
private String ISBN;
/**
* 内容简介
*/
private String introduction;
/**
* 图片URL
*/
private String imgUrl;
/**
* 是否已经收藏
*/
private Integer isCollection;
/**
* 租借信息
*/
private List<BookHoldingInfo> list;
public static BookDetailResponse from(BookDetail bookDetail) {
BookDetailResponse bookDetailResponse = new BookDetailResponse();
var extraInfo = bookDetail.getExtraInfoMap();
bookDetailResponse.setBookNameAndAuth(extraInfo.get("题名/责任者"));
bookDetailResponse.setPublisher(extraInfo.get("出版发行项"));
bookDetailResponse.setISBN(bookDetail.getIsbn());
bookDetailResponse.setIntroduction(bookDetail.getIntroduction());
bookDetailResponse.setIsCollection(0);
bookDetailResponse.setImgUrl(bookDetail.getCoverUrl());
// bookDetailResponse.setList();
return bookDetailResponse;
}
@Data
public static class BookHoldingInfo {
/**
* 索书号
*/
private String callNo;
/**
* 条号码
*/
private String barCode;
/**
* 馆藏地
*/
private String location;
/**
* 是否可借
*/
private String status;
public static BookHoldingInfo from(BookHolding bookHolding) {
BookHoldingInfo bookHoldingInfo = new BookHoldingInfo();
bookHoldingInfo.setCallNo(bookHolding.getCallNumber());
bookHoldingInfo.setBarCode(bookHolding.getBarCode());
bookHoldingInfo.setLocation(bookHolding.getLocation());
bookHoldingInfo.setStatus(bookHolding.getStatus());
return bookHoldingInfo;
}
}
}

@ -0,0 +1,78 @@
package wusthelper.web.api.v2.dto.response.library;
import cn.wustlinghang.mywust.data.library.origin.BookSearchResult;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.util.Arrays;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class BookSearchResponseItem {
/**
* 书名
*/
private String title;
/**
* 作者
*/
private String author;
/**
* 发布时间
*/
private String pubYear;
/**
* 出版方
*/
private String publisher;
/**
* 索书号
*/
private String callNo;
/**
* 书籍详情URL
*/
private String detailUrl;
/**
* 图片URL
*/
private String imgUrl;
/**
* 馆藏总数
*/
private String allNum;
/**
* 可借数目
*/
private String remainNum;
private String isbn;
@JsonInclude(JsonInclude.Include.NON_NULL)
public static BookSearchResponseItem from(BookSearchResult bookSearchResult) {
BookSearchResponseItem bookSearchResponseItem = new BookSearchResponseItem();
bookSearchResponseItem.setTitle(bookSearchResult.getTitle());
bookSearchResponseItem.setAuthor(bookSearchResult.getAuthor());
bookSearchResponseItem.setPubYear(bookSearchResult.getPubYear());
bookSearchResponseItem.setPublisher(bookSearchResult.getPublisher());
var callNumberString = Arrays.toString(bookSearchResult.getCallNumber().toArray(new String[0]));
bookSearchResponseItem.setCallNo(callNumberString);
bookSearchResponseItem.setIsbn(bookSearchResult.getIsbn());
// bookSearchResponseItem.setDetailUrl();
// bookSearchResponseItem.setImgUrl();
// bookSearchResponseItem.setAllNum();
// bookSearchResponseItem.setRemainNum();
return bookSearchResponseItem;
}
}

@ -0,0 +1,31 @@
package wusthelper.web.api.v2.dto.response.library;
import cn.wustlinghang.mywust.data.library.origin.CurrentLoanBook;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class CurrentRentResponse {
private String bookCode;
private String reRentNum = "";
private String bookPlace;
private String bookUrl;
private String rentTime;
private String bookName;
private String returnTime;
private static final String bookUrlFormat = "https://libsys.wust.edu.cn/meta-local/opac/bibs/%s/infos";
public static CurrentRentResponse from(CurrentLoanBook currentLoanBook) {
CurrentRentResponse currentRentResponse = new CurrentRentResponse();
currentRentResponse.setBookCode(currentLoanBook.getBarCode());
currentRentResponse.setBookPlace(currentLoanBook.getLocation());
currentRentResponse.setBookUrl(bookUrlFormat.formatted(currentLoanBook.getBibId()));
currentRentResponse.setRentTime(currentLoanBook.getLoanDate());
currentRentResponse.setBookName(currentLoanBook.getTitle());
currentRentResponse.setReturnTime(currentLoanBook.getDueDate());
return currentRentResponse;
}
}

@ -0,0 +1,29 @@
package wusthelper.web.api.v2.dto.response.library;
import cn.wustlinghang.mywust.data.library.origin.HistoryLoanBook;
import lombok.Data;
@Data
public class RentHistoryResponse {
private String bookCode;
private String bookPlace;
private String bookAuthor;
private String bookUrl;
private String rentTime;
private String bookName;
private String returnTime;
private static final String bookUrlFormat = "https://libsys.wust.edu.cn/meta-local/opac/bibs/%s/infos";
public static RentHistoryResponse from(HistoryLoanBook historyLoanBook) {
RentHistoryResponse currentRentResponse = new RentHistoryResponse();
currentRentResponse.setBookCode(historyLoanBook.getBarCode());
currentRentResponse.setBookPlace(historyLoanBook.getLocation());
currentRentResponse.setBookUrl(bookUrlFormat.formatted(historyLoanBook.getBibId()));
currentRentResponse.setRentTime(historyLoanBook.getLoanDate());
currentRentResponse.setBookName(historyLoanBook.getTitle());
currentRentResponse.setReturnTime(historyLoanBook.getReturnDate());
return currentRentResponse;
}
}

@ -1,8 +1,7 @@
package wusthelper.web.api.v2.dto.response;
package wusthelper.web.api.v2.dto.response.physics;
import cn.wustlinghang.mywust.data.physics.PhysicsCourse;
import lombok.Data;
import wusthelper.WebBackendMain;
import wusthelper.web.util.GlobalLogger;
import java.sql.Date;

@ -1,6 +1,6 @@
package wusthelper.web.api.v2.dto.response;
package wusthelper.web.api.v2.dto.response.undergrad;
import cn.wustlinghang.mywust.data.global.Course;
import wusthelper.web.api.v2.dto.response.CourseResponse;
import java.util.List;

@ -1,4 +1,4 @@
package wusthelper.web.api.v2.dto.response;
package wusthelper.web.api.v2.dto.response.undergrad;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import lombok.Data;

@ -2,8 +2,11 @@ package wusthelper.web.api.v2.handler;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.fasterxml.jackson.databind.JsonMappingException;
import feign.FeignException;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
@ -12,8 +15,12 @@ import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException;
import wusthelper.code.ServiceCode;
import wusthelper.web.api.v2.code.V2ResponseCode;
import wusthelper.web.exception.ServiceException;
import wusthelper.web.response.Response;
@ -47,6 +54,24 @@ public class GlobalExceptionHandler {
return Response.error(ServiceCode.ServerInternalError);
}
@ResponseBody
@ExceptionHandler(JWTVerificationException.class)
public Response<Object> baseException(JWTVerificationException e) {
return Response.error(V2ResponseCode.AUTH_ERR_TOKEN_INVALID.getCode());
}
/**
* 404
*
* @param e 异常
* @return 统一响应
*/
@ResponseBody
@ExceptionHandler(NoHandlerFoundException.class)
public Response<Object> baseException(NoHandlerFoundException e) {
return Response.error(ServiceCode.ApiNotImplement);
}
/**
* 处理参数不完整的请求异常
*

@ -0,0 +1,36 @@
package wusthelper.web.api.v2.interceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Nonnull;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import wusthelper.code.ServiceCode;
import wusthelper.web.response.Response;
@Component
public class NotFoundPathInterceptor implements HandlerInterceptor {
private final ObjectMapper objectMapper;
public NotFoundPathInterceptor(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override
public void postHandle(@Nonnull HttpServletRequest request,
@Nonnull HttpServletResponse servletResponse,
@Nonnull Object handler,
ModelAndView modelAndView) throws Exception {
if (servletResponse.getStatus() == HttpStatus.NOT_FOUND.value()) {
var response = Response.error(ServiceCode.ApiNotImplement);
var json = objectMapper.writeValueAsString(response);
servletResponse.setContentType("application/json");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.getWriter().write(json);
}
}
}

@ -0,0 +1,83 @@
package wusthelper.web.api.v2.interceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Nonnull;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import wusthelper.web.annotation.RequireToken;
import wusthelper.web.api.v2.TokenTool;
import wusthelper.web.api.v2.code.V2ResponseCode;
import wusthelper.web.response.Response;
import java.io.IOException;
@Slf4j
@Component
public class TokenInterceptor implements HandlerInterceptor {
private final ObjectMapper objectMapper;
public TokenInterceptor(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override
public boolean preHandle(@Nonnull HttpServletRequest request,
@Nonnull HttpServletResponse response,
@Nonnull Object handler) throws Exception {
if (!(handler instanceof HandlerMethod handlerMethod)) {
return true;
}
// 方法上的RequireToken
var methodAnnotation = handlerMethod.getMethodAnnotation(RequireToken.class);
if (methodAnnotation == null) {
// class上的RequireToken
var classAnnotation = handlerMethod.getMethod().getDeclaringClass().getAnnotation(RequireToken.class);
if (classAnnotation == null) {
return true;
} else {
if (!classAnnotation.require()) {
return true;
}
}
} else {
if (!methodAnnotation.require()) {
return true;
}
}
// 验证token
var token = request.getHeader("token");
if (token == null || "".equals(token)) {
this.rejectRequest(response);
return false;
}
var tokenValid = verifyToken(token);
if (!tokenValid) {
this.rejectRequest(response);
return false;
}
return true;
}
private boolean verifyToken(String token) {
return TokenTool.verify(token);
}
private void rejectRequest(HttpServletResponse servletResponse) throws IOException {
var response = Response.error(V2ResponseCode.AUTH_ERR_TOKEN_INVALID.getCode(), "token无效或已过期,请重新登录");
var json = objectMapper.writeValueAsString(response);
servletResponse.setContentType("application/json");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.getWriter().write(json);
}
}

@ -1,14 +1,15 @@
package wusthelper.web.api.v2.module.graduate;
import cn.wustlinghang.mywust.data.global.Course;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import wusthelper.web.annotation.RequireToken;
import wusthelper.web.api.v2.TokenTool;
import wusthelper.web.api.v2.code.V2ResponseCode;
import wusthelper.web.api.v2.dto.response.CourseResponse;
import wusthelper.web.api.v2.dto.response.GraduateScoreResponse;
import wusthelper.web.api.v2.dto.response.GraduateStudentInfoResponse;
import wusthelper.web.api.v2.dto.response.StudentInfoResponse;
import wusthelper.web.api.v2.dto.response.graduate.GraduateScoreResponse;
import wusthelper.web.api.v2.dto.response.graduate.GraduateStudentInfoResponse;
import wusthelper.web.response.Response;
import wusthelper.web.service.campus.graduate.GraduateCourseTableService;
import wusthelper.web.service.campus.graduate.GraduateScoreService;
@ -16,8 +17,11 @@ import wusthelper.web.service.campus.graduate.GraduateStudentInfoService;
import wusthelper.web.service.campus.graduate.GraduateTrainingPlanService;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
@RequireToken
@RestController
@RequestMapping("/v2/yjs")
public class GraduateController {
@ -44,19 +48,59 @@ public class GraduateController {
var studentInfo = studentInfoService.getStudentInfo(user);
var response = GraduateStudentInfoResponse.from(studentInfo);
return Response.success(response);
return Response.success(V2ResponseCode.YJS_GETSTUINFO_SUC.getCode(), response);
}
@RequestMapping("/get-course")
public Response<List<CourseResponse>> getCourses(@RequestHeader("Token") String token) {
var user = TokenTool.getStudentNumber(token);
var courses = courseTableService.getCourseTable(user);
var resultList = new ArrayList<CourseResponse>(courses.size());
for (var course : courses) {
resultList.add(CourseResponse.from(course));
LinkedHashSet<Course> filteredCourse = new LinkedHashSet<>(courses);
var resultList = convertCourseList(filteredCourse);
return Response.success(V2ResponseCode.YJS_GETCOURSE_SUC.getCode(), resultList);
}
/**
* 切课将连着的几节课切开来
*
* @param courses mywust类型的CourseList
* @return List<CourseResponse>
*/
private List<CourseResponse> convertCourseList(Collection<Course> courses) {
List<CourseResponse> courseResponses = new ArrayList<>(courses.size() * 2);
CourseResponse.CourseResponseBuilder builder = CourseResponse.builder();
for (Course course : courses) {
builder.className(course.getName());
builder.teachClass(course.getTeachClass());
builder.classroom(course.getClassroom().getRoom());
builder.startWeek(course.getStartWeek());
builder.endWeek(course.getEndWeek());
builder.weekDay(course.getWeekDay());
builder.teacher(course.getTeacher());
int startSection = course.getStartSection();
int endSection = course.getEndSection();
int courseSize = endSection - startSection + 1;
// 课程大小大于2的将课程按两节两节分割,只有一节的按两节处理
if (courseSize > 2) {
for (int i = 0; i < courseSize / 2; i++) {
int splitStartSection = startSection + i * 2;
int section = splitStartSection - (splitStartSection / 2);
builder.section(section);
courseResponses.add(builder.build());
}
} else {
builder.section(startSection - (startSection / 2));
courseResponses.add(builder.build());
}
}
return Response.success(resultList);
return courseResponses;
}
@RequestMapping("/get-grade")
@ -68,7 +112,7 @@ public class GraduateController {
resultList.add(GraduateScoreResponse.from(score));
}
return Response.success(resultList);
return Response.success(V2ResponseCode.YJS_GETGRADE_SUC.getCode(), resultList);
}
@RequestMapping("/get-scheme")
@ -76,6 +120,6 @@ public class GraduateController {
var user = TokenTool.getStudentNumber(token);
var page = trainingPlanService.getTrainingPlan(user);
return Response.success(page);
return Response.success(V2ResponseCode.YJS_GETTRAINPLAN_SUC.getCode(), page);
}
}

@ -2,6 +2,7 @@ package wusthelper.web.api.v2.module.graduate;
import org.springframework.web.bind.annotation.*;
import wusthelper.web.api.v2.TokenTool;
import wusthelper.web.api.v2.code.V2ResponseCode;
import wusthelper.web.response.Response;
import wusthelper.web.service.campus.UserLoginService;
@ -14,7 +15,7 @@ public class GraduateLoginController {
this.userLoginService = userLoginService;
}
@PostMapping("/login")
@RequestMapping("/login")
public Response<String> login(@RequestParam("stuNum") String username,
@RequestParam("jwcPwd") String password,
@RequestHeader(name = "Platform", required = false) String platform) {
@ -23,6 +24,6 @@ public class GraduateLoginController {
String token = TokenTool.signToken(user.getUid(), user.getStuNum());
return Response.success(token);
return Response.success(V2ResponseCode.YJS_LOGIN_SUC.getCode(), token);
}
}

@ -0,0 +1,28 @@
package wusthelper.web.api.v2.module.library;
import org.springframework.web.bind.annotation.*;
import wusthelper.web.annotation.RequireToken;
import wusthelper.web.api.v2.TokenTool;
import wusthelper.web.api.v2.code.V2ResponseCode;
import wusthelper.web.response.Response;
import wusthelper.web.service.campus.UserLoginService;
@RequireToken
@RestController
@RequestMapping("/v2/lib")
public class LibraryLoginController {
private final UserLoginService userLoginService;
public LibraryLoginController(UserLoginService userLoginService) {
this.userLoginService = userLoginService;
}
@PostMapping("/login")
public Response<Object> login(@RequestParam("libPwd") String password,
@RequestHeader("Token") String token) {
String username = TokenTool.getStudentNumber(token);
userLoginService.login(username, password, UserLoginService.LoginType.Library);
return Response.success(V2ResponseCode.LIB_LOGIN_SUC.getCode(), null);
}
}

@ -0,0 +1,64 @@
package wusthelper.web.api.v2.module.library;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import wusthelper.web.annotation.RequireToken;
import wusthelper.web.api.v2.TokenTool;
import wusthelper.web.api.v2.code.V2ResponseCode;
import wusthelper.web.api.v2.dto.response.library.CurrentRentResponse;
import wusthelper.web.api.v2.dto.response.library.RentHistoryResponse;
import wusthelper.web.response.Response;
import wusthelper.web.service.campus.library.LibraryPersonalService;
import java.util.ArrayList;
import java.util.List;
@RequireToken
@RestController
@RequestMapping("/v2/lib")
public class LibraryPersonalController {
private final LibraryPersonalService service;
public LibraryPersonalController(LibraryPersonalService service) {
this.service = service;
}
/**
* 获取当前借阅信息
*
* @param token
* @return
*/
@GetMapping(path = "/get-current-rent", produces = {"application/json"})
public Response<List<CurrentRentResponse>> getCurrentRent(@RequestHeader(value = "Token") String token) {
String stuNum = TokenTool.getStudentNumber(token);
var resultList = service.getCurrentLoan(stuNum, 0, 30).getData();
var responseData = new ArrayList<CurrentRentResponse>(resultList.size());
for (var result : resultList) {
responseData.add(CurrentRentResponse.from(result));
}
return Response.success(V2ResponseCode.LIB_GETCURRENTRENT_SUC.getCode(), responseData);
}
/**
* 获取历史借阅信息
*
* @param token
* @return
*/
@GetMapping(path = "/get-rent-history", produces = {"application/json"})
public Response<List<RentHistoryResponse>> getRentHistory(@RequestHeader(value = "Token") String token) {
String stuNum = TokenTool.getStudentNumber(token);
var resultList = service.getLoanHistory(stuNum, 0, 30).getData();
var responseData = new ArrayList<RentHistoryResponse>(resultList.size());
for (var result : resultList) {
responseData.add(RentHistoryResponse.from(result));
}
return Response.success(V2ResponseCode.LIB_GETRENTHISTORY_SUC.getCode(), responseData);
}
}

@ -0,0 +1,74 @@
package wusthelper.web.api.v2.module.library;
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 wusthelper.code.ServiceCode;
import wusthelper.web.api.v2.code.V2ResponseCode;
import wusthelper.web.api.v2.dto.response.library.BookDetailResponse;
import wusthelper.web.api.v2.dto.response.library.BookSearchResponseItem;
import wusthelper.web.response.Response;
import wusthelper.web.service.campus.library.LibraryPublicService;
import java.util.*;
import java.util.regex.Pattern;
@RestController
@RequestMapping("/v2/lib")
public class LibraryPublicController {
private final LibraryPublicService service;
public LibraryPublicController(LibraryPublicService service) {
this.service = service;
}
private static final Pattern BOOK_URL_PATTERN = Pattern.compile("https://libsys.wust.edu.cn/meta-local/opac/bibs/(.*?)/infos");
@RequestMapping(path = "/get-book-detail")
public Response<BookDetailResponse> getBookDetail(@RequestParam(value = "url") String url) {
var urlMatcher = BOOK_URL_PATTERN.matcher(url);
if (!urlMatcher.find()) {
return Response.error(ServiceCode.ParamWrong);
}
var id = urlMatcher.group(1);
var detail = service.getBookDetail(id);
var responseData = BookDetailResponse.from(detail);
var holdingInfoList = service.getBookHolding(id);
List<BookDetailResponse.BookHoldingInfo> bookHoldingInfoList = new ArrayList<>(holdingInfoList.size());
for (var holdingInfo : holdingInfoList) {
var bookHoldingInfo = BookDetailResponse.BookHoldingInfo.from(holdingInfo);
bookHoldingInfoList.add(bookHoldingInfo);
}
responseData.setList(bookHoldingInfoList);
return Response.success(V2ResponseCode.LIB_GETBOOKDETAIL_SUC.getCode(), responseData);
}
@RequestMapping(path = "/search")
public Response<List<BookSearchResponseItem>> search(
@RequestParam(value = "keyWord") String keyword,
@RequestParam(value = "pageNum", required = false, defaultValue = "1") int page,
@RequestParam(value = "pageSize", required = false, defaultValue = "20") int pageSize
) {
var upstreamResultList = service.searchBooks(keyword, page, pageSize).getData();
var responseData = new ArrayList<BookSearchResponseItem>(upstreamResultList.size());
var isbnList = new ArrayList<String>(upstreamResultList.size());
for (var result : upstreamResultList) {
var item = BookSearchResponseItem.from(result);
item.setAllNum("1");
item.setRemainNum("1");
responseData.add(item);
isbnList.add(result.getIsbn());
}
var coverUrls = service.getBookCoverImageBatch(isbnList);
for (var item : responseData) {
item.setImgUrl(coverUrls.get(item.getIsbn()).get(0));
}
return Response.success(V2ResponseCode.LIB_SEARCH_SUC.getCode(), responseData);
}
}

@ -0,0 +1,17 @@
package wusthelper.web.api.v2.module.linghang;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import wusthelper.web.annotation.RequireToken;
import wusthelper.web.api.v2.code.V2ResponseCode;
import wusthelper.web.response.Response;
@RestController
@RequestMapping("/v2/lh")
public class LinghangController {
@RequireToken
@RequestMapping("check-token")
public Response<Object> checkToken() {
return Response.success(V2ResponseCode.SUC.getCode(), null);
}
}

@ -3,9 +3,10 @@ package wusthelper.web.api.v2.module.physics;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import wusthelper.web.annotation.RequireToken;
import wusthelper.web.api.v2.TokenTool;
import wusthelper.web.api.v2.dto.response.CourseResponse;
import wusthelper.web.api.v2.dto.response.PhysicsCourseResponse;
import wusthelper.web.api.v2.code.V2ResponseCode;
import wusthelper.web.api.v2.dto.response.physics.PhysicsCourseResponse;
import wusthelper.web.api.v2.dto.response.ScoreResponse;
import wusthelper.web.response.Response;
import wusthelper.web.service.campus.physics.PhysicsCourseTableService;
@ -14,6 +15,7 @@ import wusthelper.web.service.campus.physics.PhysicsScoreService;
import java.util.ArrayList;
import java.util.List;
@RequireToken
@RestController
@RequestMapping("/v2/wlsy")
public class PhysicsController {
@ -28,7 +30,7 @@ public class PhysicsController {
this.scoreService = scoreService;
}
@RequestMapping("/get-course")
@RequestMapping("/get-courses")
public Response<List<PhysicsCourseResponse>> getCourses(@RequestHeader("Token") String token) {
var user = TokenTool.getStudentNumber(token);
var courses = courseTableService.getCourseTable(user);
@ -37,7 +39,7 @@ public class PhysicsController {
resultList.add(PhysicsCourseResponse.from(course));
}
return Response.success(resultList);
return Response.success(V2ResponseCode.WLSY_GETCOURSE_SUC.getCode(), resultList);
}
@RequestMapping("/get-grade")

@ -2,6 +2,7 @@ package wusthelper.web.api.v2.module.physics;
import org.springframework.web.bind.annotation.*;
import wusthelper.web.api.v2.TokenTool;
import wusthelper.web.api.v2.code.V2ResponseCode;
import wusthelper.web.response.Response;
import wusthelper.web.service.campus.UserLoginService;
@ -18,8 +19,8 @@ public class PhysicsLoginController {
public Response<Object> login(@RequestParam("wlsyPwd") String password,
@RequestHeader("Token") String token) {
String username = TokenTool.getStudentNumber(token);
userLoginService.login(username, password, UserLoginService.LoginType.Graduate);
userLoginService.login(username, password, UserLoginService.LoginType.Physics);
return Response.success();
return Response.success(V2ResponseCode.WLSY_LOGIN_SUC.getCode(), null);
}
}

@ -4,10 +4,12 @@ import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import wusthelper.web.annotation.RequireToken;
import wusthelper.web.api.v2.TokenTool;
import wusthelper.web.api.v2.code.V2ResponseCode;
import wusthelper.web.api.v2.dto.response.CourseResponse;
import wusthelper.web.api.v2.dto.response.ScoreResponse;
import wusthelper.web.api.v2.dto.response.StudentInfoResponse;
import wusthelper.web.api.v2.dto.response.undergrad.StudentInfoResponse;
import wusthelper.web.response.Response;
import wusthelper.web.service.campus.undergrad.*;
@ -16,6 +18,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
@RequireToken
@RestController
@RequestMapping("/v2/jwc")
public class UndergradController {
@ -44,7 +47,7 @@ public class UndergradController {
var user = TokenTool.getStudentNumber(token);
var studentInfo = studentInfoService.getStudentInfo(user);
return Response.success(StudentInfoResponse.from(studentInfo));
return Response.success(V2ResponseCode.JWC_GETSTUINFO_SUC.getCode(), StudentInfoResponse.from(studentInfo));
}
@RequestMapping("/get-curriculum")
@ -57,7 +60,7 @@ public class UndergradController {
resultList.add(CourseResponse.from(course));
}
return Response.success(resultList);
return Response.success(V2ResponseCode.JWC_GETCURRICULUM_SUC.getCode(), resultList);
}
@RequestMapping("/get-grade")
@ -93,7 +96,7 @@ public class UndergradController {
}
}
return Response.success(resultList);
return Response.success(V2ResponseCode.JWC_GETGRADE_SUC.getCode(), resultList);
}
@RequestMapping("/get-credit")
@ -101,7 +104,7 @@ public class UndergradController {
var user = TokenTool.getStudentNumber(token);
var page = creditStatusService.getCreditStatus(user);
return Response.success(page);
return Response.success(V2ResponseCode.JWC_GETCREDIT_SUC.getCode(), page);
}
@RequestMapping("/get-scheme")
@ -109,6 +112,6 @@ public class UndergradController {
var user = TokenTool.getStudentNumber(token);
var page = trainingPlanService.getTrainingPlan(user);
return Response.success(page);
return Response.success(V2ResponseCode.JWC_TRAINING_SCHEME_SUC.getCode(), page);
}
}

@ -2,9 +2,10 @@ package wusthelper.web.api.v2.module.undergrade;
import org.springframework.web.bind.annotation.*;
import wusthelper.web.api.v2.TokenTool;
import wusthelper.web.api.v2.dto.response.CombineLoginResponse;
import wusthelper.web.api.v2.code.V2ResponseCode;
import wusthelper.web.api.v2.dto.response.undergrad.CombineLoginResponse;
import wusthelper.web.api.v2.dto.response.CourseResponse;
import wusthelper.web.api.v2.dto.response.StudentInfoResponse;
import wusthelper.web.api.v2.dto.response.undergrad.StudentInfoResponse;
import wusthelper.web.response.Response;
import wusthelper.web.service.campus.UserLoginService;
import wusthelper.web.service.campus.undergrad.UndergradCourseTableService;
@ -29,7 +30,7 @@ public class UndergradLoginController {
this.courseTableService = courseTableService;
}
@PostMapping("/login")
@RequestMapping("/login")
public Response<String> login(@RequestParam(value = "stuNum") String username,
@RequestParam(value = "jwcPwd") String password,
@RequestHeader(name = "Platform", required = false) String platform) {
@ -38,7 +39,7 @@ public class UndergradLoginController {
String token = TokenTool.signToken(user.getUid(), user.getStuNum());
return Response.success(token);
return Response.success(V2ResponseCode.JWC_LOGIN_SUC.getCode(), token);
}
/**
@ -71,6 +72,6 @@ public class UndergradLoginController {
String token = TokenTool.signToken(user.getUid(), user.getStuNum());
var response = new CombineLoginResponse(token, courseResponses, studentResponse);
return Response.success(response);
return Response.success(V2ResponseCode.JWC_LOGIN_SUC.getCode(), response);
}
}

@ -6,15 +6,15 @@ import wusthelper.web.util.PasswordCodec;
@Configuration
public class PasswordCodecConfigure {
private final GlobalConfigureItems globalConfigureItems;
private final WusthelperConfigureItems wusthelperConfigureItems;
public PasswordCodecConfigure(GlobalConfigureItems globalConfigureItems) {
this.globalConfigureItems = globalConfigureItems;
public PasswordCodecConfigure(WusthelperConfigureItems wusthelperConfigureItems) {
this.wusthelperConfigureItems = wusthelperConfigureItems;
}
@Bean
public PasswordCodec passwordCodec() {
String key = globalConfigureItems.getPasswordEncodeKey();
String key = wusthelperConfigureItems.getPasswordEncodeKey();
return new PasswordCodec(key);
}

@ -0,0 +1,31 @@
package wusthelper.web.configure;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import wusthelper.web.api.v2.interceptor.NotFoundPathInterceptor;
import wusthelper.web.api.v2.interceptor.TokenInterceptor;
@Configuration
public class WebMvcConfigure implements WebMvcConfigurer {
private final TokenInterceptor tokenInterceptor;
private final NotFoundPathInterceptor notFoundPathInterceptor;
public WebMvcConfigure(TokenInterceptor tokenInterceptor,
NotFoundPathInterceptor notFoundPathInterceptor) {
this.tokenInterceptor = tokenInterceptor;
this.notFoundPathInterceptor = notFoundPathInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(this.tokenInterceptor)
.addPathPatterns("/**");
registry.addInterceptor(this.notFoundPathInterceptor)
.addPathPatterns("/**");
}
}

@ -4,9 +4,19 @@ import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
@Data
@Component
@ConfigurationProperties("wusthelper")
public class GlobalConfigureItems {
public class WusthelperConfigureItems {
private String passwordEncodeKey;
}
private List<RpcModule> rpc;
@Data
public static class RpcModule {
private String name;
private String address;
}
}

@ -5,7 +5,7 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import wusthelper.internal.rpc.response.RpcResponseDto;
@FeignClient(name = "wusthelper.graduate", contextId = "graduate-cookie")
@FeignClient(name = "wusthelper.graduate", contextId = "graduate-cookie", url = "http://127.0.0.1:22802")
public interface GraduateCookieRemote {
String COOKIE_ROOT_PATH = "/cookie";

@ -12,7 +12,7 @@ import wusthelper.internal.rpc.response.RpcResponseDto;
import java.util.List;
@Component
@FeignClient(name = "wusthelper.graduate", contextId = "graduate-courseTable")
@FeignClient(name = "wusthelper.graduate", contextId = "graduate-courseTable", url = "http://127.0.0.1:22802")
public interface GraduateCourseTableRemote {
String ROOT_PATH = "/course_table";

@ -12,7 +12,7 @@ import wusthelper.internal.rpc.response.RpcResponseDto;
import java.util.List;
@Component
@FeignClient(name = "wusthelper.graduate", contextId = "graduate-score")
@FeignClient(name = "wusthelper.graduate", contextId = "graduate-score", url = "http://127.0.0.1:22802")
public interface GraduateScoreRemote {
String ROOT_PATH = "/score";

@ -8,7 +8,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import wusthelper.internal.rpc.response.RpcResponseDto;
@FeignClient(name = "wusthelper.graduate", contextId = "graduate-studentInfo")
@FeignClient(name = "wusthelper.graduate", contextId = "graduate-studentInfo", url = "http://127.0.0.1:22802")
public interface GraduateStudentInfoRemote {
String ROOT_PATH = "/student_info";

@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import wusthelper.internal.rpc.response.RpcResponseDto;
@Component
@FeignClient(name = "wusthelper.graduate", contextId = "graduate-trainingPlan")
@FeignClient(name = "wusthelper.graduate", contextId = "graduate-trainingPlan", url = "http://127.0.0.1:22802")
public interface GraduateTrainingPlanRemote {
String ROOT_PATH = "/training_plan";

@ -0,0 +1,27 @@
package wusthelper.web.rpc.http.library;
import cn.wustlinghang.mywust.data.global.Course;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import wusthelper.internal.rpc.response.RpcResponseDto;
import java.util.List;
import java.util.Map;
@Component
@FeignClient(name = "wusthelper.library", contextId = "library-bookCoverImage", url = "http://127.0.0.1:22804")
public interface LibraryBookCoverImageRemote {
String ROOT_PATH = "/cover_image";
@GetMapping(ROOT_PATH)
RpcResponseDto<Object> get(@RequestParam("isbn") String isbn);
@GetMapping(ROOT_PATH + "/agent")
RpcResponseDto<String> agent(@RequestParam("isbn") String isbn);
@PostMapping(ROOT_PATH + "/batch")
RpcResponseDto<Map<String, List<String>>> batch(@RequestParam("isbn") String isbnList);
}

@ -0,0 +1,24 @@
package wusthelper.web.rpc.http.library;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.mywust.data.library.parsed.BookDetail;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import wusthelper.internal.rpc.response.RpcResponseDto;
import java.util.List;
@Component
@FeignClient(name = "wusthelper.library", contextId = "library-bookDetail", url = "http://127.0.0.1:22804")
public interface LibraryBookDetailRemote {
String ROOT_PATH = "/book_detail";
@GetMapping(ROOT_PATH)
RpcResponseDto<BookDetail> get(@RequestParam("id") String id);
@GetMapping(ROOT_PATH + "/agent")
RpcResponseDto<BookDetail> agent(@RequestParam("id") String id);
}

@ -0,0 +1,23 @@
package wusthelper.web.rpc.http.library;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.mywust.data.library.parsed.BookHolding;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import wusthelper.internal.rpc.response.RpcResponseDto;
import java.util.List;
@Component
@FeignClient(name = "wusthelper.library", contextId = "library-bookHoldings", url = "http://127.0.0.1:22804")
public interface LibraryBookHoldingRemote {
String ROOT_PATH = "/holdings";
@GetMapping(ROOT_PATH)
RpcResponseDto<List<BookHolding>> get(@RequestParam("id") String id);
@GetMapping(ROOT_PATH + "/agent")
RpcResponseDto<List<BookHolding>> agent(@RequestParam("id") String id);
}

@ -0,0 +1,20 @@
package wusthelper.web.rpc.http.library;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import wusthelper.internal.rpc.response.RpcResponseDto;
@Component
@FeignClient(name = "wusthelper.library", contextId = "library-cookie", url = "http://127.0.0.1:22804")
public interface LibraryCookieRemote {
String COOKIE_ROOT_PATH = "/cookie";
@GetMapping(COOKIE_ROOT_PATH)
RpcResponseDto<String> login(@RequestParam("username") String username,
@RequestParam("password") String password);
@GetMapping(COOKIE_ROOT_PATH + "/verify")
RpcResponseDto<Boolean> verify(@RequestParam("cookie") String cookie);
}

@ -0,0 +1,31 @@
package wusthelper.web.rpc.http.library;
import cn.wustlinghang.mywust.data.library.PagingResult;
import cn.wustlinghang.mywust.data.library.origin.CurrentLoanBook;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import wusthelper.internal.rpc.response.RpcResponseDto;
import java.util.List;
@Component
@FeignClient(name = "wusthelper.library", contextId = "library-currentLoan", url = "http://127.0.0.1:22804")
public interface LibraryCurrentLoanRemote {
String ROOT_PATH = "/current_loan";
@GetMapping(ROOT_PATH)
RpcResponseDto<PagingResult<List<CurrentLoanBook>>> get(
@RequestParam("cookie") String cookie,
@RequestParam("page") int page,
@RequestParam("page_ize") int pageSize
);
@GetMapping(ROOT_PATH + "/agent")
RpcResponseDto<PagingResult<List<CurrentLoanBook>>> agent(
@RequestParam("cookie") String cookie,
@RequestParam("page") int page,
@RequestParam("page_ize") int pageSize
);
}

@ -0,0 +1,31 @@
package wusthelper.web.rpc.http.library;
import cn.wustlinghang.mywust.data.library.PagingResult;
import cn.wustlinghang.mywust.data.library.origin.HistoryLoanBook;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import wusthelper.internal.rpc.response.RpcResponseDto;
import java.util.List;
@Component
@FeignClient(name = "wusthelper.library", contextId = "library-loanHistory", url = "http://127.0.0.1:22804")
public interface LibraryLoanHistoryRemote {
String ROOT_PATH = "/loan_history";
@GetMapping(ROOT_PATH)
RpcResponseDto<PagingResult<List<HistoryLoanBook>>> get(
@RequestParam("cookie") String cookie,
@RequestParam("page") int page,
@RequestParam("page_ize") int pageSize
);
@GetMapping(ROOT_PATH + "/agent")
RpcResponseDto<PagingResult<List<HistoryLoanBook>>> agent(
@RequestParam("cookie") String cookie,
@RequestParam("page") int page,
@RequestParam("page_ize") int pageSize
);
}

@ -0,0 +1,31 @@
package wusthelper.web.rpc.http.library;
import cn.wustlinghang.mywust.data.library.PagingResult;
import cn.wustlinghang.mywust.data.library.origin.BaseLoanBook;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import wusthelper.internal.rpc.response.RpcResponseDto;
import java.util.List;
@Component
@FeignClient(name = "wusthelper.library", contextId = "library-overdueSoon", url = "http://127.0.0.1:22804")
public interface LibraryOverdueSoonRemote {
String ROOT_PATH = "/overdue_soon";
@GetMapping(ROOT_PATH)
RpcResponseDto<PagingResult<List<BaseLoanBook>>> get(
@RequestParam("cookie") String cookie,
@RequestParam("page") int page,
@RequestParam("page_ize") int pageSize
);
@GetMapping(ROOT_PATH + "/agent")
RpcResponseDto<PagingResult<List<BaseLoanBook>>> agent(
@RequestParam("cookie") String cookie,
@RequestParam("page") int page,
@RequestParam("page_ize") int pageSize
);
}

@ -0,0 +1,31 @@
package wusthelper.web.rpc.http.library;
import cn.wustlinghang.mywust.data.library.PagingResult;
import cn.wustlinghang.mywust.data.library.origin.BookSearchResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import wusthelper.internal.rpc.response.RpcResponseDto;
import java.util.List;
@Component
@FeignClient(name = "wusthelper.library", contextId = "library-search", url = "http://127.0.0.1:22804")
public interface LibrarySearchRemote {
String ROOT_PATH = "/search";
@GetMapping(ROOT_PATH)
RpcResponseDto<PagingResult<List<BookSearchResult>>> get(
@RequestParam("keyword") String keyword,
@RequestParam("page") int page,
@RequestParam("page_ize") int pageSize
);
@GetMapping(ROOT_PATH + "/agent")
RpcResponseDto<PagingResult<List<BookSearchResult>>> agent(
@RequestParam("keyword") String keyword,
@RequestParam("page") int page,
@RequestParam("page_ize") int pageSize
);
}

@ -5,7 +5,7 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import wusthelper.internal.rpc.response.RpcResponseDto;
@FeignClient(name = "wusthelper.physics", contextId = "physics-cookie")
@FeignClient(name = "wusthelper.physics", contextId = "physics-cookie", url = "http://127.0.0.1:22806")
public interface PhysicsCookieRemote {
String COOKIE_ROOT_PATH = "/cookie";

@ -13,7 +13,7 @@ import wusthelper.internal.rpc.response.RpcResponseDto;
import java.util.List;
@Component
@FeignClient(name = "wusthelper.physics", contextId = "physics-courseTable")
@FeignClient(name = "wusthelper.physics", contextId = "physics-courseTable", url = "http://127.0.0.1:22806")
public interface PhysicsCourseTableRemote {
String ROOT_PATH = "/course_table";

@ -12,7 +12,7 @@ import wusthelper.internal.rpc.response.RpcResponseDto;
import java.util.List;
@Component
@FeignClient(name = "wusthelper.physics", contextId = "physics-score")
@FeignClient(name = "wusthelper.physics", contextId = "physics-score", url = "http://127.0.0.1:22806")
public interface PhysicsScoreRemote {
String ROOT_PATH = "/score";

@ -7,7 +7,7 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Component
@FeignClient(name = "wusthelper.undergrad", contextId = "undergrad-cookie")
@FeignClient(name = "wusthelper.undergrad", contextId = "undergrad-cookie", url = "http://127.0.0.1:22800")
public interface UndergradCookieRemote {
String COOKIE_ROOT_PATH = "/cookie";

@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@Component
@FeignClient(name = "wusthelper.undergrad", contextId = "undergrad-courseTable")
@FeignClient(name = "wusthelper.undergrad", contextId = "undergrad-courseTable", url = "http://127.0.0.1:22800")
public interface UndergradCourseTableRemote {
String ROOT_PATH = "/course_table";

@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Component
@FeignClient(name = "wusthelper.undergrad", contextId = "undergrad-creditStatus")
@FeignClient(name = "wusthelper.undergrad", contextId = "undergrad-creditStatus", url = "http://127.0.0.1:22800")
public interface UndergradCreditStatusRemote {
String ROOT_PATH = "/credit_status";

@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Component
@FeignClient(name = "wusthelper.undergrad", contextId = "undergrad-examDelayApplication")
@FeignClient(name = "wusthelper.undergrad", contextId = "undergrad-examDelayApplication", url = "http://127.0.0.1:22800")
public interface UndergradExamDelayApplicationRemote {
String ROOT_PATH = "/exam_delay_application";

@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@Component
@FeignClient(name = "wusthelper.undergrad", contextId = "undergrad-score")
@FeignClient(name = "wusthelper.undergrad", contextId = "undergrad-score", url = "http://127.0.0.1:22800")
public interface UndergradScoreRemote {
String ROOT_PATH = "/score";

@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Component
@FeignClient(name = "wusthelper.undergrad", contextId = "undergrad-studentInfo")
@FeignClient(name = "wusthelper.undergrad", contextId = "undergrad-studentInfo", url = "http://127.0.0.1:22800")
public interface UndergradStudentInfoRemote {
String ROOT_PATH = "/student_info";

@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Component
@FeignClient(name = "wusthelper.undergrad", contextId = "undergrad-trainingPlan")
@FeignClient(name = "wusthelper.undergrad", contextId = "undergrad-trainingPlan", url = "http://127.0.0.1:22800")
public interface UndergradTrainingPlanRemote {
String ROOT_PATH = "/training_plan";

@ -18,7 +18,7 @@ import wusthelper.web.util.PasswordCodec;
*/
@Service
public class UserLoginService {
private final UserBasicMapper studentMapper;
private final UserBasicMapper userBasicMapper;
private final PasswordCodec passwordCodec;
private final UndergradCookieService undergradCookieService;
@ -26,7 +26,7 @@ public class UserLoginService {
private final LibraryCookieService libraryCookieService;
private final PhysicsCookieService physicsCookieService;
public UserLoginService(UserBasicMapper studentMapper,
public UserLoginService(UserBasicMapper userBasicMapper,
PasswordCodec passwordCodec,
UndergradCookieService undergradCookieService,
@ -34,7 +34,7 @@ public class UserLoginService {
LibraryCookieService libraryCookieService,
PhysicsCookieService physicsCookieService) {
this.studentMapper = studentMapper;
this.userBasicMapper = userBasicMapper;
this.passwordCodec = passwordCodec;
this.undergradCookieService = undergradCookieService;
@ -74,7 +74,7 @@ public class UserLoginService {
}
private UserBasic saveOrUpdateUser(String username, String password, LoginType loginType) {
var user = studentMapper.selectOne(new QueryWrapper<UserBasic>()
var user = userBasicMapper.selectOne(new QueryWrapper<UserBasic>()
.eq("stu_num", username)
.eq("deleted", 0)
.last("limit 1")
@ -91,7 +91,7 @@ public class UserLoginService {
}
private void updateUser(String username, UserBasic user) {
studentMapper.update(user, new QueryWrapper<UserBasic>()
userBasicMapper.update(user, new QueryWrapper<UserBasic>()
.eq("stu_num", username)
.eq("deleted", 0)
.last("limit 1")
@ -107,7 +107,7 @@ public class UserLoginService {
this.fillPassword(password, user, loginType);
studentMapper.insert(user);
userBasicMapper.insert(user);
return user;
}

@ -4,17 +4,18 @@ import org.springframework.stereotype.Service;
import wusthelper.code.ServiceCode;
import wusthelper.web.exception.ServiceException;
import wusthelper.web.rpc.http.graduate.GraduateCookieRemote;
import wusthelper.web.rpc.http.library.LibraryCookieRemote;
@Service
public class LibraryCookieService {
private final GraduateCookieRemote graduateCookieRemote;
private final LibraryCookieRemote libraryCookieRemote;
public LibraryCookieService(GraduateCookieRemote graduateCookieRemote) {
this.graduateCookieRemote = graduateCookieRemote;
public LibraryCookieService(LibraryCookieRemote libraryCookieRemote) {
this.libraryCookieRemote = libraryCookieRemote;
}
public String getLoginCookie(String username, String password) throws ServiceException {
var rpcResp = graduateCookieRemote.login(username, password);
var rpcResp = libraryCookieRemote.login(username, password);
if (rpcResp.code() != ServiceCode.Ok) {
ServiceException.error(rpcResp.code());
}
@ -23,6 +24,6 @@ public class LibraryCookieService {
}
public Boolean checkCookie(String cookie) {
return graduateCookieRemote.verify(cookie).data();
return libraryCookieRemote.verify(cookie).data();
}
}

@ -0,0 +1,70 @@
package wusthelper.web.service.campus.library;
import cn.wustlinghang.mywust.data.library.PagingResult;
import cn.wustlinghang.mywust.data.library.origin.BaseLoanBook;
import cn.wustlinghang.mywust.data.library.origin.CurrentLoanBook;
import cn.wustlinghang.mywust.data.library.origin.HistoryLoanBook;
import org.springframework.stereotype.Service;
import wusthelper.code.ServiceCode;
import wusthelper.web.data.entity.CookieType;
import wusthelper.web.exception.ServiceException;
import wusthelper.web.rpc.http.library.LibraryCurrentLoanRemote;
import wusthelper.web.rpc.http.library.LibraryLoanHistoryRemote;
import wusthelper.web.rpc.http.library.LibraryOverdueSoonRemote;
import wusthelper.web.service.cookie.CookieManager;
import java.util.List;
@Service
public class LibraryPersonalService {
private final CookieManager cookieManager;
private final LibraryCurrentLoanRemote currentLoanRemote;
private final LibraryLoanHistoryRemote loanHistoryRemote;
private final LibraryOverdueSoonRemote overdueSoonRemote;
public LibraryPersonalService(CookieManager cookieManager,
LibraryCurrentLoanRemote currentLoanRemote,
LibraryLoanHistoryRemote loanHistoryRemote,
LibraryOverdueSoonRemote overdueSoonRemote) {
this.cookieManager = cookieManager;
this.currentLoanRemote = currentLoanRemote;
this.loanHistoryRemote = loanHistoryRemote;
this.overdueSoonRemote = overdueSoonRemote;
}
public PagingResult<List<CurrentLoanBook>> getCurrentLoan(String user, int page, int pageSize) {
String cookie = cookieManager.getCookie(user, CookieType.Library);
var rpcResp = currentLoanRemote.get(cookie, page, pageSize);
if (rpcResp.code() != ServiceCode.Ok) {
ServiceException.error(rpcResp.code());
}
// todo 异步存用户课表,异常判断等等
return rpcResp.data();
}
public PagingResult<List<HistoryLoanBook>> getLoanHistory(String user, int page, int pageSize) {
String cookie = cookieManager.getCookie(user, CookieType.Library);
var rpcResp = loanHistoryRemote.get(cookie, page, pageSize);
if (rpcResp.code() != ServiceCode.Ok) {
ServiceException.error(rpcResp.code());
}
// todo 异步存用户课表,异常判断等等
return rpcResp.data();
}
public PagingResult<List<BaseLoanBook>> getOverdueSoon(String user, int page, int pageSize) {
String cookie = cookieManager.getCookie(user, CookieType.Library);
var rpcResp = overdueSoonRemote.get(cookie, page, pageSize);
if (rpcResp.code() != ServiceCode.Ok) {
ServiceException.error(rpcResp.code());
}
// todo 异步存用户课表,异常判断等等
return rpcResp.data();
}
}

@ -0,0 +1,93 @@
package wusthelper.web.service.campus.library;
import cn.wustlinghang.mywust.data.library.PagingResult;
import cn.wustlinghang.mywust.data.library.origin.BookSearchResult;
import cn.wustlinghang.mywust.data.library.parsed.BookDetail;
import cn.wustlinghang.mywust.data.library.parsed.BookHolding;
import org.springframework.stereotype.Service;
import wusthelper.code.ServiceCode;
import wusthelper.web.exception.ServiceException;
import wusthelper.web.rpc.http.library.LibraryBookCoverImageRemote;
import wusthelper.web.rpc.http.library.LibraryBookDetailRemote;
import wusthelper.web.rpc.http.library.LibraryBookHoldingRemote;
import wusthelper.web.rpc.http.library.LibrarySearchRemote;
import java.util.*;
@Service
public class LibraryPublicService {
private final LibraryBookCoverImageRemote bookCoverImageRemote;
private final LibraryBookDetailRemote bookDetailRemote;
private final LibraryBookHoldingRemote bookHoldingRemote;
private final LibrarySearchRemote searchRemote;
public LibraryPublicService(LibraryBookCoverImageRemote bookCoverImageRemote,
LibraryBookDetailRemote bookDetailRemote,
LibraryBookHoldingRemote bookHoldingRemote,
LibrarySearchRemote searchRemote) {
this.bookCoverImageRemote = bookCoverImageRemote;
this.bookDetailRemote = bookDetailRemote;
this.bookHoldingRemote = bookHoldingRemote;
this.searchRemote = searchRemote;
}
public String getBookCoverImage(String isbn) {
var rpcResp = bookCoverImageRemote.agent(isbn);
if (rpcResp.code() != ServiceCode.Ok) {
ServiceException.error(rpcResp.code());
}
// todo 异步存用户课表,异常判断等等
return rpcResp.data();
}
public Map<String, List<String>> getBookCoverImageBatch(Collection<String> isbn) {
if (isbn.isEmpty()) {
return new HashMap<>();
}
StringJoiner stringJoiner = new StringJoiner(",");
for (var i : isbn) {
stringJoiner.add(i);
}
var rpcResp = bookCoverImageRemote.batch(stringJoiner.toString());
if (rpcResp.code() != ServiceCode.Ok) {
ServiceException.error(rpcResp.code());
}
// todo 异步存用户课表,异常判断等等
return rpcResp.data();
}
public BookDetail getBookDetail(String id) {
var rpcResp = bookDetailRemote.get(id);
if (rpcResp.code() != ServiceCode.Ok) {
ServiceException.error(rpcResp.code());
}
// todo 异步存用户课表,异常判断等等
return rpcResp.data();
}
public List<BookHolding> getBookHolding(String id) {
var rpcResp = bookHoldingRemote.get(id);
if (rpcResp.code() != ServiceCode.Ok) {
ServiceException.error(rpcResp.code());
}
// todo 异步存用户课表,异常判断等等
return rpcResp.data();
}
public PagingResult<List<BookSearchResult>> searchBooks(String keyword, int page, int pageSize) {
var rpcResp = searchRemote.get(keyword, page, pageSize);
if (rpcResp.code() != ServiceCode.Ok) {
ServiceException.error(rpcResp.code());
}
// todo 异步存用户课表,异常判断等等
return rpcResp.data();
}
}

@ -7,6 +7,8 @@ import wusthelper.web.data.entity.CookieType;
import wusthelper.web.service.cookie.CookieManager;
import org.springframework.stereotype.Service;
import java.util.function.Function;
@Service
public class UndergradTrainingPlanService {
private final UndergradTrainingPlanRemote trainingPlanRemote;

@ -2,17 +2,19 @@ package wusthelper.web.service.cookie;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import wusthelper.code.ServiceCode;
import wusthelper.data.dao.mapper.StudentMapper;
import wusthelper.data.entity.Student;
import wusthelper.data.dao.mapper.UserBasicMapper;
import wusthelper.data.entity.UserBasic;
import wusthelper.web.data.entity.CookieType;
import wusthelper.web.exception.ServiceException;
import wusthelper.web.service.campus.graduate.GraduateCookieService;
import wusthelper.web.service.campus.library.LibraryCookieService;
import wusthelper.web.service.campus.physics.PhysicsCookieService;
import wusthelper.web.service.campus.undergrad.UndergradCookieService;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import wusthelper.web.util.PasswordCodec;
import java.util.concurrent.TimeUnit;
@ -27,20 +29,27 @@ public class CookieManager {
private final UndergradCookieService undergradCookieService;
private final GraduateCookieService graduateCookieService;
private final LibraryCookieService libraryCookieService;
private final PhysicsCookieService physicsCookieService;
private final PasswordCodec passwordCodec;
private final StudentMapper studentMapper;
private final UserBasicMapper studentMapper;
public CookieManager(UndergradCookieService undergradCookieService,
GraduateCookieService graduateCookieService,
LibraryCookieService libraryCookieService,
PhysicsCookieService physicsCookieService,
StudentMapper studentMapper) {
PasswordCodec passwordCodec,
UserBasicMapper userBasicMapper) {
this.undergradCookieService = undergradCookieService;
this.graduateCookieService = graduateCookieService;
this.libraryCookieService = libraryCookieService;
this.physicsCookieService = physicsCookieService;
this.passwordCodec = passwordCodec;
this.studentMapper = studentMapper;
this.studentMapper = userBasicMapper;
}
public String getCookie(String username, CookieType cookieType) {
@ -71,14 +80,14 @@ public class CookieManager {
return switch (cookieType) {
case Undergrad -> undergradCookieService.checkCookie(cookie);
case Graduate -> graduateCookieService.checkCookie(cookie);
case Library -> libraryCookieService.checkCookie(cookie);
case Physics -> physicsCookieService.checkCookie(cookie);
default -> false;
};
}
public String refreshCookie(String username, CookieType cookieType) {
var student = studentMapper.selectOne(new QueryWrapper<Student>()
.eq("stuNum", username)
var student = studentMapper.selectOne(new QueryWrapper<UserBasic>()
.eq("stu_num", username)
.eq("deleted", 0)
);
@ -87,9 +96,9 @@ public class CookieManager {
}
String password = switch (cookieType) {
case Undergrad, Graduate -> student.getJwcPwd();
case Library -> student.getLibPwd();
case Physics -> student.getWlsyPwd();
case Undergrad, Graduate -> passwordCodec.decode(student.getOfficialPwd());
case Library -> passwordCodec.decode(student.getLibPwd());
case Physics -> passwordCodec.decode(student.getPhysicsPwd());
};
if (password == null) {
@ -99,8 +108,8 @@ public class CookieManager {
return switch (cookieType) {
case Undergrad -> undergradCookieService.getLoginCookie(username, password);
case Graduate -> graduateCookieService.getLoginCookie(username, password);
case Library -> libraryCookieService.getLoginCookie(username, password);
case Physics -> physicsCookieService.getLoginCookie(username, password);
default -> null;
};
}
}

@ -29,7 +29,7 @@ public class StudentService {
}
var query = new QueryWrapper<Student>()
.eq("stuNum", username)
.eq("stu_num", username)
.eq("deleted", 0);
// (按学号)检查用户信息是否已经存在数据库中,已存在则更新,否则新增信息

@ -5,6 +5,4 @@ import org.slf4j.LoggerFactory;
public class GlobalLogger {
public static final Logger log = LoggerFactory.getLogger("wusthelper");
}

@ -7,16 +7,24 @@ spring:
import: optional:file:.env[.properties]
application:
name: wusthelper-backend-main
# main:
# allow-bean-definition-overriding: true
# main.allow-bean-definition-overriding = true
cloud:
consul:
host: 127.0.0.1
port: 8500
discovery:
register: false
# consul:
# host: 121.43.32.5
# port: 8500
# discovery:
# register: false
# health-check-critical-timeout: 30s
openfeign:
client:
config:
wusthelper.undergrad:
url: "http://127.0.0.1:22800"
wusthelper.graduate:
url: "http://127.0.0.1:22802"
wusthelper.library:
url: "http://127.0.0.1:22804"
wusthelper.physics:
url: "http://127.0.0.1:22806"
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/wust_helper?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai
@ -35,8 +43,19 @@ spring:
max-idle: 16
max-active: 32
min-idle: 8
web:
resources:
add-mappings: false
mvc:
throw-exception-if-no-handler-found: true
server:
port: ${RUN_PORT}
port: ${WEB_RUN_PORT}
wusthelper:
password-encode-key: wusthelper
password-encode-key: ${WEB_PASSWORD_ENCODE_KEY}
mybatis:
configuration:
map-underscore-to-camel-case: false
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

@ -11,7 +11,7 @@ public class ServiceCode {
// 所有模块共用
public static final int Unknown = 10_000; // 未知错误
public static final int RequestInvalid = 10_001; // 请求无效
public static final int ParamWrong = 10_002; // 请求无效
public static final int ParamWrong = 10_002; // 参数错误
public static final int CookieInvalid = 10_003; // 提供的cookie无效
public static final int NetworkError = 10_004; // 网络错误
public static final int RpcError = 10_005; // 上游RPC错误
@ -28,6 +28,7 @@ public class ServiceCode {
public static final int UndergradPasswordNeedModify = 30_005; // 本科生:用户密码需要更改
public static final int UndergradBannedInExclusiveTime = 30_006; // 本科生:专属选课时间段账号被禁用(--> _ --)
public static final int UndergradNeedEvaluate = 30_007; // 本科生:需要评教
public static final int UndergradUserinfoNotExists = 30_008; // 本科生:用户名信息不存在(新生信息未录入或者老生删档)
// 研究生
public static final int GraduatePasswordWrong = 40_001; // 研究生:密码错误
@ -49,14 +50,15 @@ public class ServiceCode {
static {
text.put(Ok, "ok");
text.put(ServerInternalError, "服务器内部错误");
text.put(ApiNotImplement, "接口未实现");
text.put(ApiNotImplement, "api未实现");
// 主模块
text.put(UserNotExists, "用户不存在");
text.put(UserNotExists, "用户信息不存在,请重新登录");
// 所有模块共用
text.put(Unknown, "未知错误");
text.put(RequestInvalid, "请求无效");
text.put(ParamWrong, "参数错误");
text.put(CookieInvalid, "提供的cookie无效");
text.put(NetworkError, "网络错误");
text.put(RpcError, "上游RPC错误");
@ -70,6 +72,7 @@ public class ServiceCode {
text.put(UndergradPasswordNeedModify, "本科生:用户密码需要更改");
text.put(UndergradBannedInExclusiveTime, "本科生:专属选课时间段账号被禁用(--> _ --)");
text.put(UndergradNeedEvaluate, "本科生:需要评教");
text.put(UndergradUserinfoNotExists, "本科生登录:用户名信息不存在(登录的用户不是本科生,或者是新生信息未录入或者老生删档)");
// 研究生
text.put(GraduatePasswordWrong, "研究生:密码错误");
@ -82,7 +85,7 @@ public class ServiceCode {
text.put(LibraryPasswordNeedModify, "图书馆:用户密码需要更改");
// 物理实验
text.put(PhysicsPasswordWrong, "物理实验:用户不存在");
text.put(PhysicsPasswordWrong, "物理实验:用户不存在或密码错误");
text.put(PhysicsUserNotCurrentTerm, "物理实验:用户不在当前学期");
}

@ -15,7 +15,12 @@ import wusthelper.code.ServiceCode;
@JsonInclude(JsonInclude.Include.NON_NULL)
public record Response<T>(int code, String msg, T data) {
public static <T> Response<T> success(T data) {
return new Response<>(0, "ok", data);
return new Response<>(10000, "ok", data);
// return new Response<>(0, "ok", data);
}
public static <T> Response<T> success(int code, T data) {
return new Response<>(code, "ok", data);
}
public static <T> Response<T> success() {

@ -7,6 +7,7 @@ import cn.hutool.crypto.symmetric.AES;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.StringJoiner;
/**
@ -19,11 +20,12 @@ public class PasswordCodec {
private final SymmetricCrypto aes;
public PasswordCodec(String key) {
byte[] keyBytes = normalization(key);
byte[] keyBytes = this.paddingKeys(key.getBytes(StandardCharsets.UTF_8));
this.aes = new AES(Mode.ECB, Padding.PKCS5Padding, keyBytes);
}
public PasswordCodec(byte[] key) {
key = this.paddingKeys(key);
this.aes = new AES(Mode.ECB, Padding.PKCS5Padding, key);
}
@ -58,6 +60,25 @@ public class PasswordCodec {
byte[] data = aes.decrypt(HexUtil.decodeHex(encodedHex));
return new String(data);
}
private byte[] paddingKeys(byte[] bytes) {
// byte[] bytes = raw.getBytes(StandardCharsets.UTF_8);
if (bytes.length == 16 || bytes.length == 24 || bytes.length == 32) {
return bytes;
}
if (bytes.length < 16) {
byte[] result = Arrays.copyOf(bytes, 16);
Arrays.fill(result, bytes.length, 15, (byte) 0);
return result;
} else if (bytes.length < 24) {
byte[] result = Arrays.copyOf(bytes, 24);
Arrays.fill(result, bytes.length, 23, (byte) 0);
return result;
} else {
return Arrays.copyOf(bytes, 32);
}
}
//
// public static PasswordUtil getInstance(String key) {
// if (instance == null) {

@ -1 +1 @@
Subproject commit 5da31b26d1a8b7560f068d8bf507d01e34c1cdaf
Subproject commit 9dba2a9c374c28ee7ddd2c10beb28b99bc249f35

@ -11,6 +11,7 @@ import wusthelper.internal.rpc.entity.RegisterRequestBody;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import wusthelper.internal.rpc.util.IPUtil;
@Slf4j
public class FrpConsulRegister {
@ -28,7 +29,7 @@ public class FrpConsulRegister {
public FrpConsulRegister(RegisterConfig registerConfig, FrpConfig frpConfig,
Requester requester, ObjectMapper objectMapper) {
this.serviceId = RandomUtil.randomString(8);
this.serviceId = IPUtil.getHostName();
this.registerConfig = registerConfig;
this.frpcClientClient = new FrpcClient(frpConfig, requester, objectMapper);

@ -0,0 +1,15 @@
package wusthelper.internal.rpc.util;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class IPUtil {
public static String getHostName() {
try {
InetAddress addr = InetAddress.getLocalHost();
return addr.getHostName();
} catch (UnknownHostException e) {
return "unknown-host";
}
}
}

@ -27,6 +27,8 @@
<mywust.version>0.0.2-beta</mywust.version>
<lombok.version>1.18.26</lombok.version>
<hutool.version>5.8.20</hutool.version>
<okhttp.version>4.11.0</okhttp.version>
<junit.version>5.10.0</junit.version>
</properties>
<dependencies>
@ -53,7 +55,7 @@
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
@ -67,6 +69,19 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- okhttp版本强升,mywust-okhttp使用的版本(4.11.0)会被springboot覆盖(3.x) -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
</dependency>
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<version>3.2.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</dependencyManagement>

@ -3,6 +3,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.wustlinghang.wusthelper</groupId>
<artifactId>sub-services</artifactId>

@ -19,6 +19,12 @@ public class Register {
private final FrpConsulRegister register;
public Register(RpcConfig rpcConfig, Requester requester, ObjectMapper objectMapper) {
if (!rpcConfig.isEnable()) {
log.info("Rpc module is disabled.");
register = null;
return;
}
FrpConfig frpConfig = FrpConfig.builder()
.frpcAdminAddress(rpcConfig.getFrpcAdminAddress())
.frpcAdminUsername(rpcConfig.getFrpcAdminUsername())
@ -35,6 +41,8 @@ public class Register {
@PostConstruct
public void onStartup() {
register.register();
if (register != null) {
register.register();
}
}
}

@ -8,6 +8,10 @@ import org.eclipse.microprofile.config.inject.ConfigProperty;
@Data
@Singleton
public class RpcConfig {
@DefaultValue("false")
@ConfigProperty(name = "rpc.enable")
boolean enable;
@DefaultValue("default.service")
@ConfigProperty(name = "rpc.service.name")
String serviceName;
@ -31,3 +35,4 @@ public class RpcConfig {
@ConfigProperty(name = "quarkus.http.port")
String localServicePort;
}

@ -14,6 +14,8 @@ quarkus.package.type=uber-jar
# 现阶段使用jar运行,启动效率虽不如原生程序,但速度尚可
quarkus.native.additional-build-args=--initialize-at-run-time=cn.wustlinghang.mywust
rpc.enable=false
rpc.service.name=wusthelper.graduate
rpc.register.consul-api.address=http://127.0.0.1:8500

@ -1,15 +1,15 @@
package wusthelper.internal.library.rpc;
import cn.wustlinghang.mywust.network.Requester;
import wusthelper.internal.library.rpc.config.RpcConfig;
import wusthelper.internal.rpc.FrpConsulRegister;
import wusthelper.internal.rpc.config.FrpConfig;
import wusthelper.internal.rpc.config.RegisterConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.quarkus.runtime.Startup;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
import lombok.extern.slf4j.Slf4j;
import wusthelper.internal.library.rpc.config.RpcConfig;
import wusthelper.internal.rpc.FrpConsulRegister;
import wusthelper.internal.rpc.config.FrpConfig;
import wusthelper.internal.rpc.config.RegisterConfig;
@Slf4j
@Startup
@ -19,6 +19,12 @@ public class Register {
private final FrpConsulRegister register;
public Register(RpcConfig rpcConfig, Requester requester, ObjectMapper objectMapper) {
if (!rpcConfig.isEnable()) {
log.info("Rpc module is disabled.");
register = null;
return;
}
FrpConfig frpConfig = FrpConfig.builder()
.frpcAdminAddress(rpcConfig.getFrpcAdminAddress())
.frpcAdminUsername(rpcConfig.getFrpcAdminUsername())
@ -35,6 +41,8 @@ public class Register {
@PostConstruct
public void onStartup() {
register.register();
if (register != null) {
register.register();
}
}
}

@ -8,6 +8,10 @@ import org.eclipse.microprofile.config.inject.ConfigProperty;
@Data
@Singleton
public class RpcConfig {
@DefaultValue("false")
@ConfigProperty(name = "rpc.enable")
boolean enable;
@DefaultValue("default.service")
@ConfigProperty(name = "rpc.service.name")
String serviceName;
@ -31,3 +35,4 @@ public class RpcConfig {
@ConfigProperty(name = "quarkus.http.port")
String localServicePort;
}

@ -10,6 +10,8 @@ quarkus.package.type=uber-jar
# 现阶段使用jar运行,启动效率虽不如原生程序,但速度尚可
quarkus.native.additional-build-args="--initialize-at-run-time=cn.wustlinghang.mywust"
rpc.enable=false
rpc.service.name=wusthelper.library
rpc.register.consul-api.address=http://127.0.0.1:8500

@ -1,15 +1,15 @@
package wusthelper.internal.physics.rpc;
import cn.wustlinghang.mywust.network.Requester;
import wusthelper.internal.physics.rpc.config.RpcConfig;
import wusthelper.internal.rpc.FrpConsulRegister;
import wusthelper.internal.rpc.config.FrpConfig;
import wusthelper.internal.rpc.config.RegisterConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.quarkus.runtime.Startup;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
import lombok.extern.slf4j.Slf4j;
import wusthelper.internal.physics.rpc.config.RpcConfig;
import wusthelper.internal.rpc.FrpConsulRegister;
import wusthelper.internal.rpc.config.FrpConfig;
import wusthelper.internal.rpc.config.RegisterConfig;
@Slf4j
@Startup
@ -19,6 +19,12 @@ public class Register {
private final FrpConsulRegister register;
public Register(RpcConfig rpcConfig, Requester requester, ObjectMapper objectMapper) {
if (!rpcConfig.isEnable()) {
log.info("Rpc module is disabled.");
register = null;
return;
}
FrpConfig frpConfig = FrpConfig.builder()
.frpcAdminAddress(rpcConfig.getFrpcAdminAddress())
.frpcAdminUsername(rpcConfig.getFrpcAdminUsername())
@ -35,6 +41,8 @@ public class Register {
@PostConstruct
public void onStartup() {
register.register();
if (register != null) {
register.register();
}
}
}

@ -8,6 +8,10 @@ import org.eclipse.microprofile.config.inject.ConfigProperty;
@Data
@Singleton
public class RpcConfig {
@DefaultValue("false")
@ConfigProperty(name = "rpc.enable")
boolean enable;
@DefaultValue("default.service")
@ConfigProperty(name = "rpc.service.name")
String serviceName;
@ -31,3 +35,4 @@ public class RpcConfig {
@ConfigProperty(name = "quarkus.http.port")
String localServicePort;
}

@ -10,6 +10,8 @@ quarkus.package.type=uber-jar
# 现阶段使用jar运行,启动效率虽不如原生程序,但速度尚可
quarkus.native.additional-build-args="--initialize-at-run-time=cn.wustlinghang.mywust"
rpc.enable=false
rpc.service.name=wusthelper.physics
rpc.register.consul-api.address=http://127.0.0.1:8500

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>

@ -24,7 +24,6 @@ public class ResponseWrapperInterceptor implements WriterInterceptor {
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
System.out.println("ResponseWrapperInterceptor.aroundWriteTo");
boolean hasException = context.getHeaders().get(BaseExceptionHandler.EXCEPTION_HEADER_KEY) != null;
if (!hasException) {
Object data = context.getEntity();

@ -1,15 +1,15 @@
package wusthelper.internal.undergrad.rpc;
import cn.wustlinghang.mywust.network.Requester;
import wusthelper.internal.rpc.FrpConsulRegister;
import wusthelper.internal.rpc.config.FrpConfig;
import wusthelper.internal.rpc.config.RegisterConfig;
import wusthelper.internal.undergrad.rpc.config.RpcConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.quarkus.runtime.Startup;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
import lombok.extern.slf4j.Slf4j;
import wusthelper.internal.rpc.FrpConsulRegister;
import wusthelper.internal.rpc.config.FrpConfig;
import wusthelper.internal.rpc.config.RegisterConfig;
import wusthelper.internal.undergrad.rpc.config.RpcConfig;
@Slf4j
@Startup
@ -19,6 +19,12 @@ public class Register {
private final FrpConsulRegister register;
public Register(RpcConfig rpcConfig, Requester requester, ObjectMapper objectMapper) {
if (!rpcConfig.isEnable()) {
log.info("Rpc module is disabled.");
register = null;
return;
}
FrpConfig frpConfig = FrpConfig.builder()
.frpcAdminAddress(rpcConfig.getFrpcAdminAddress())
.frpcAdminUsername(rpcConfig.getFrpcAdminUsername())
@ -28,7 +34,6 @@ public class Register {
.consulAddress(rpcConfig.getConsulAddress())
.localServicePort(rpcConfig.getLocalServicePort())
.serviceName(rpcConfig.getServiceName())
.token("")
.build();
this.register = new FrpConsulRegister(registerConfig, frpConfig, requester, objectMapper);
@ -36,6 +41,8 @@ public class Register {
@PostConstruct
public void onStartup() {
register.register();
if (register != null) {
register.register();
}
}
}

@ -8,6 +8,10 @@ import org.eclipse.microprofile.config.inject.ConfigProperty;
@Data
@Singleton
public class RpcConfig {
@DefaultValue("false")
@ConfigProperty(name = "rpc.enable")
boolean enable;
@DefaultValue("default.service")
@ConfigProperty(name = "rpc.service.name")
String serviceName;
@ -31,3 +35,4 @@ public class RpcConfig {
@ConfigProperty(name = "quarkus.http.port")
String localServicePort;
}

@ -57,6 +57,7 @@ public class LoginService {
case UNDERGRAD_BANNED_IN_EXCLUSIVE_TIME -> ServiceCode.UndergradBannedInExclusiveTime;
case UNI_LOGIN_USER_NOT_ONLY, UNI_LOGIN_NO_REGISTER, UNI_LOGIN_NEED_TFA
-> ServiceCode.Unknown;
case UNDERGRAD_USERINFO_NOT_EXISTS -> ServiceCode.UndergradUserinfoNotExists;
default -> {
log.error("本科生:登录代理请求异常,异常未处理");
log.error("异常:", e);

@ -4,6 +4,7 @@ import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradScoreParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradScoreApiService;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import lombok.extern.slf4j.Slf4j;
import wusthelper.code.ServiceCode;
import wusthelper.internal.rpc.exception.RpcException;
@ -41,7 +42,7 @@ public class ScoreService extends BaseService {
}
return scoreParser.parse(data);
} catch (Exception e) {
} catch (ParseException e) {
log.error("解析错误:", e);
throw new RpcException(ServiceCode.ParseError);
}

@ -1,6 +1,6 @@
quarkus.http.port=22800
quarkus.http.enable-compression=true
quarkus.log.level=DEBUG
quarkus.log.level=INFO
quarkus.log.file.encoding=UTF-8
@ -12,6 +12,8 @@ quarkus.package.type=uber-jar
# 现阶段使用jar运行,启动效率虽不如原生程序,但速度尚可
quarkus.native.additional-build-args=--initialize-at-run-time=cn.wustlinghang.mywust,--initialize-at-run-time=cn.wustlinghang.wusthelper,--enable-url-protocols=https
rpc.enable=false
rpc.service.name=wusthelper.undergrad
rpc.register.consul-api.address=http://127.0.0.1:8500

Loading…
Cancel
Save