lensfrex 1 year ago
parent 7f1f8ba3e7
commit 76ed47c1b3
Signed by: lensfrex
GPG Key ID: 0F69A0A2FBEE98A0
  1. 20
      backend-main/backend-data/pom.xml
  2. 7
      backend-main/backend-data/src/main/java/cn/wustlinghang/main/data/Main.java
  3. 9
      backend-main/backend-data/src/main/java/cn/wustlinghang/wusthelper/data/dao/mapper/StudentMapper.java
  4. 96
      backend-main/backend-data/src/main/java/cn/wustlinghang/wusthelper/data/entity/Student.java
  5. 53
      backend-main/backend-web/pom.xml
  6. 17
      backend-main/backend-web/src/main/java/cn/wustlinghang/main/web/BackendMain.java
  7. 23
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/WebBackendMain.java
  8. 13
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/api/Health.java
  9. 6
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/api/v2/undergrade/UndergradController.java
  10. 34
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/configure/CaffeineCacheConfigure.java
  11. 35
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/entity/CookieType.java
  12. 18
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/rpc/undergrad/CookieRemote.java
  13. 27
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/rpc/undergrad/CourseTableRemote.java
  14. 22
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/rpc/undergrad/CreditStatusRemote.java
  15. 27
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/rpc/undergrad/ExamDelayApplicationRemote.java
  16. 25
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/rpc/undergrad/ScoreRemote.java
  17. 23
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/rpc/undergrad/StudentInfoRemote.java
  18. 22
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/rpc/undergrad/TrainingPlanRemote.java
  19. 33
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/service/campus/undergrad/CourseTableService.java
  20. 29
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/service/campus/undergrad/CreditStatusService.java
  21. 31
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/service/campus/undergrad/ExamDelayApplicationService.java
  22. 32
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/service/campus/undergrad/ScoreService.java
  23. 30
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/service/campus/undergrad/StudentInfoService.java
  24. 29
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/service/campus/undergrad/TrainingPlanService.java
  25. 21
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/service/campus/undergrad/UndergradCookieService.java
  26. 62
      backend-main/backend-web/src/main/java/cn/wustlinghang/wusthelper/web/service/cookie/CookieManager.java
  27. 5
      backend-main/backend-web/src/main/resources/application.yml
  28. 26
      backend-main/backend-web/src/test/java/cn/wustlinghang/wusthelper/StudentTest.java
  29. 29
      backend-main/backend-web/src/test/java/cn/wustlinghang/wusthelper/TestMain.java
  30. 24
      backend-main/backend-web/src/test/resources/application-test.yml
  31. 40
      backend-main/pom.xml
  32. 19
      common/src/main/java/cn/wustlinghang/wusthelper/internal/rpc/response/RpcResponse.java
  33. 19
      common/src/main/java/cn/wustlinghang/wusthelper/internal/rpc/response/RpcResponseDto.java
  34. 2
      common/src/main/java/cn/wustlinghang/wusthelper/web/response/Response.java
  35. 2
      common/src/main/java/cn/wustlinghang/wusthelper/web/response/ResponseCode.java
  36. 59
      external-library/rpc-frp-consul/.flattened-pom.xml
  37. 6
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/http/v1/handler/BaseExceptionHandler.java
  38. 4
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/http/v1/interceptor/ResponseWrapperInterceptor.java
  39. 40
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/rpc/Register.java
  40. 33
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/rpc/config/RpcConfig.java
  41. 14
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/rpc/health/HealthCheck.java
  42. 6
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/handler/BaseExceptionHandler.java
  43. 4
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/interceptor/ResponseWrapperInterceptor.java
  44. 40
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/rpc/Register.java
  45. 33
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/rpc/config/RpcConfig.java
  46. 14
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/rpc/health/HealthCheck.java
  47. 6
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/http/v1/handler/BaseExceptionHandler.java
  48. 4
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/http/v1/interceptor/ResponseWrapperInterceptor.java
  49. 40
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/rpc/Register.java
  50. 33
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/rpc/config/RpcConfig.java
  51. 14
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/rpc/health/HealthCheck.java
  52. 6
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/handler/BaseExceptionHandler.java
  53. 4
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/interceptor/ResponseWrapperInterceptor.java

@ -16,6 +16,26 @@
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
<mybatis.version>3.0.2</mybatis.version>
</properties>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>

@ -1,7 +0,0 @@
package cn.wustlinghang.main.data;
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

@ -0,0 +1,9 @@
package cn.wustlinghang.wusthelper.data.dao.mapper;
import cn.wustlinghang.wusthelper.data.entity.Student;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface StudentMapper extends BaseMapper<Student> {
}

@ -0,0 +1,96 @@
package cn.wustlinghang.wusthelper.data.entity;
import lombok.Data;
@Data
public class Student {
/**
* 本科生id
*/
private Long id;
/**
* 学号
*/
private String stuNum;
/**
* 姓名
*/
private String stuName;
/**
* 教务处密码
*/
private String jwcPwd;
/**
* 物理实验系统密码
*/
private String wlsyPwd;
/**
* 学院编号
*/
private Long collegeId;
/**
* 专业编号
*/
private Long majorId;
/**
* 班级编号
*/
private Long classId;
/**
* 生日
*/
private String birthday;
/**
* 性别
*/
private String sex;
/**
* 民族
*/
private String nation;
/**
* 籍贯
*/
private String nativePlace;
/**
* 昵称
*/
private String nickName;
/**
* 电话
*/
private String phone;
/**
* 电子邮箱
*/
private String email;
/**
* qq号
*/
private String qqNum;
/**
* 微信号码
*/
private String wechatNum;
/**
* 客户端平台
*/
private String platform;
}

@ -16,37 +16,12 @@
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<springboot.version>3.1.1</springboot.version>
<snakeyaml.version>2.0</snakeyaml.version>
<consul-discovery.version>4.0.2</consul-discovery.version>
<feign.version>4.0.3</feign.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${springboot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 清除springboot的依赖引入的漏洞警告,直接提升版本消除 -->
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>${snakeyaml.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@ -64,20 +39,9 @@
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<groupId>cn.wustlinghang.wusthelper</groupId>
<artifactId>backend-data</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
@ -91,12 +55,9 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
<systemPropertyVariables>
<file.encoding>UTF-8</file.encoding>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>

@ -1,17 +0,0 @@
package cn.wustlinghang.main.web;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableAsync
@EnableScheduling
@EnableFeignClients
@SpringBootApplication
public class BackendMain {
public static void main(String[] args) {
SpringApplication.run(BackendMain.class);
}
}

@ -0,0 +1,23 @@
package cn.wustlinghang.wusthelper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableAsync
@EnableScheduling
@EnableFeignClients(basePackages = {"cn.wustlinghang.wusthelper.web.rpc"})
@SpringBootApplication(scanBasePackages = {
// 指定springboot的bean扫描路径,有新增请及时更新
"cn.wustlinghang.wusthelper.data",
"cn.wustlinghang.wusthelper.web",
})
@MapperScan("cn.wustlinghang.wusthelper.data.dao.mapper")
public class WebBackendMain {
public static void main(String[] args) {
SpringApplication.run(WebBackendMain.class);
}
}

@ -0,0 +1,13 @@
package cn.wustlinghang.wusthelper.web.api;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/")
public class Health {
@RequestMapping("/health")
public String health() {
return "";
}
}

@ -1,7 +1,7 @@
package cn.wustlinghang.main.web.api.v2.undergrade;
package cn.wustlinghang.wusthelper.web.api.v2.undergrade;
import cn.wustlinghang.main.web.service.campus.undergrad.UndergradCookieService;
import cn.wustlinghang.wusthelper.main.response.Response;
import cn.wustlinghang.wusthelper.web.service.campus.undergrad.UndergradCookieService;
import cn.wustlinghang.wusthelper.web.response.Response;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@ -0,0 +1,34 @@
package cn.wustlinghang.wusthelper.web.configure;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
@Configuration
public class CaffeineCacheConfigure {
@Bean
public CacheManager cacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
cacheManager.setCaffeine(Caffeine.newBuilder()
.expireAfterAccess(1, TimeUnit.HOURS)
.initialCapacity(100)
.maximumSize(1024)
);
return cacheManager;
}
@Bean
public Cache<Object, Object> cache() {
return Caffeine.newBuilder()
.expireAfterWrite(1, TimeUnit.HOURS)
.initialCapacity(100)
.maximumSize(1024)
.build();
}
}

@ -0,0 +1,35 @@
package cn.wustlinghang.wusthelper.web.entity;
import java.util.StringJoiner;
public enum CookieType {
UNDERGRAD(0, "本科生"),
GRADUATE(1, "研究生"),
LIBRARY(2, "图书馆"),
PHYSICS(3, "物理实验"),;
private final int code;
private final String message;
CookieType(int id, String describe) {
this.code = id;
this.message = describe;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
@Override
public String toString() {
return new StringJoiner(", ", CookieType.class.getSimpleName() + "[", "]")
.add("code=" + code)
.add("message='" + message + "'")
.toString();
}
}

@ -0,0 +1,18 @@
package cn.wustlinghang.wusthelper.web.rpc.undergrad;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "wusthelper.undergrad", contextId = "cookie")
public interface CookieRemote {
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,27 @@
package cn.wustlinghang.wusthelper.web.rpc.undergrad;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto;
import jakarta.validation.constraints.NotNull;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@FeignClient(name = "wusthelper.undergrad", contextId = "courseTable")
public interface CourseTableRemote {
String ROOT_PATH = "/course_table";
@GetMapping(ROOT_PATH)
RpcResponseDto<List<Course>> get(@RequestParam("cookie") String cookie,
@RequestParam("term") String term);
@GetMapping(ROOT_PATH + "/agent")
RpcResponseDto<String> agent(@RequestParam("cookie") @NotNull String cookie,
@RequestParam("term") String term);
@PostMapping(ROOT_PATH + "/parse")
RpcResponseDto<List<Course>> parse(String html);
}

@ -0,0 +1,22 @@
package cn.wustlinghang.wusthelper.web.rpc.undergrad;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto;
import jakarta.validation.constraints.NotNull;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "wusthelper.undergrad", contextId = "creditStatus")
public interface CreditStatusRemote {
String ROOT_PATH = "/credit_status";
@GetMapping(ROOT_PATH)
RpcResponseDto<String> get(@RequestParam("cookie") String cookie);
@GetMapping(ROOT_PATH + "/agent")
RpcResponseDto<String> agent(@RequestParam("cookie") @NotNull String cookie);
@PostMapping(ROOT_PATH + "/parse")
RpcResponseDto<String> parse(String html);
}

@ -0,0 +1,27 @@
package cn.wustlinghang.wusthelper.web.rpc.undergrad;
import cn.wustlinghang.mywust.data.undergrad.ExamDelayApplication;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto;
import jakarta.validation.constraints.NotNull;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "wusthelper.undergrad", contextId = "examDelayApplication")
public interface ExamDelayApplicationRemote {
String ROOT_PATH = "/exam_delay_application";
@GetMapping(ROOT_PATH)
RpcResponseDto<ExamDelayApplication> get(@RequestParam("cookie") String cookie,
@RequestParam("term") String term,
@RequestParam("activity_id") String activityId);
@GetMapping(ROOT_PATH + "/agent")
RpcResponseDto<String> agent(@RequestParam("cookie") @NotNull String cookie,
@RequestParam("term") String term,
@RequestParam("activity_id") String activityId);
@PostMapping(ROOT_PATH + "/parse")
RpcResponseDto<ExamDelayApplication> parse(String html);
}

@ -0,0 +1,25 @@
package cn.wustlinghang.wusthelper.web.rpc.undergrad;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto;
import jakarta.validation.constraints.NotNull;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@FeignClient(name = "wusthelper.undergrad", contextId = "score")
public interface ScoreRemote {
String ROOT_PATH = "/score";
@GetMapping(ROOT_PATH)
RpcResponseDto<List<Score>> get(@RequestParam("cookie") String cookie);
@GetMapping(ROOT_PATH + "/agent")
RpcResponseDto<String> agent(@RequestParam("cookie") @NotNull String cookie);
@PostMapping(ROOT_PATH + "/parse")
RpcResponseDto<List<Score>> parse(String html);
}

@ -0,0 +1,23 @@
package cn.wustlinghang.wusthelper.web.rpc.undergrad;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto;
import jakarta.validation.constraints.NotNull;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "wusthelper.undergrad", contextId = "studentInfo")
public interface StudentInfoRemote {
String ROOT_PATH = "/student_info";
@GetMapping(ROOT_PATH)
RpcResponseDto<StudentInfo> get(@RequestParam("cookie") String cookie);
@GetMapping(ROOT_PATH + "/agent")
RpcResponseDto<String> agent(@RequestParam("cookie") @NotNull String cookie);
@PostMapping(ROOT_PATH + "/parse")
RpcResponseDto<StudentInfo> parse(String html);
}

@ -0,0 +1,22 @@
package cn.wustlinghang.wusthelper.web.rpc.undergrad;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto;
import jakarta.validation.constraints.NotNull;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "wusthelper.undergrad", contextId = "trainingPlan")
public interface TrainingPlanRemote {
String ROOT_PATH = "/training_plan";
@GetMapping(ROOT_PATH)
RpcResponseDto<String> get(@RequestParam("cookie") String cookie);
@GetMapping(ROOT_PATH + "/agent")
RpcResponseDto<String> agent(@RequestParam("cookie") @NotNull String cookie);
@PostMapping(ROOT_PATH + "/parse")
RpcResponseDto<String> parse(String html);
}

@ -0,0 +1,33 @@
package cn.wustlinghang.wusthelper.web.service.campus.undergrad;
import cn.wustlinghang.wusthelper.web.entity.CookieType;
import cn.wustlinghang.wusthelper.web.rpc.undergrad.CourseTableRemote;
import cn.wustlinghang.wusthelper.web.service.cookie.CookieManager;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CourseTableService {
private final CourseTableRemote courseTableRemote;
private final CookieManager cookieManager;
public CourseTableService(CourseTableRemote courseTableRemote, CookieManager cookieManager) {
this.courseTableRemote = courseTableRemote;
this.cookieManager = cookieManager;
}
public List<Course> getCourseTable(String user, String term) {
String cookie = cookieManager.getCookie(user, CookieType.UNDERGRAD);
var coursesResponse = courseTableRemote.get(cookie, term);
if (coursesResponse.code() != RpcCommonResponseCode.SUCCESS.getCode()) {
return null;
}
// todo 异步存用户课表,异常判断等等
return coursesResponse.data();
}
}

@ -0,0 +1,29 @@
package cn.wustlinghang.wusthelper.web.service.campus.undergrad;
import cn.wustlinghang.wusthelper.web.entity.CookieType;
import cn.wustlinghang.wusthelper.web.rpc.undergrad.CreditStatusRemote;
import cn.wustlinghang.wusthelper.web.service.cookie.CookieManager;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import org.springframework.stereotype.Service;
@Service
public class CreditStatusService {
private final CreditStatusRemote creditStatusRemote;
private final CookieManager cookieManager;
public CreditStatusService(CreditStatusRemote creditStatusRemote, CookieManager cookieManager) {
this.creditStatusRemote = creditStatusRemote;
this.cookieManager = cookieManager;
}
public String getCreditStatus(String user) {
String cookie = cookieManager.getCookie(user, CookieType.UNDERGRAD);
var response = creditStatusRemote.get(cookie);
if (response.code() != RpcCommonResponseCode.SUCCESS.getCode()) {
return null;
}
// todo 异步存用户课表,异常判断等等
return response.data();
}
}

@ -0,0 +1,31 @@
package cn.wustlinghang.wusthelper.web.service.campus.undergrad;
import cn.wustlinghang.wusthelper.web.rpc.undergrad.ExamDelayApplicationRemote;
import cn.wustlinghang.wusthelper.web.entity.CookieType;
import cn.wustlinghang.wusthelper.web.service.cookie.CookieManager;
import cn.wustlinghang.mywust.data.undergrad.ExamDelayApplication;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import org.springframework.stereotype.Service;
@Service
public class ExamDelayApplicationService {
private final ExamDelayApplicationRemote examDelayApplicationRemote;
private final CookieManager cookieManager;
public ExamDelayApplicationService(ExamDelayApplicationRemote examDelayApplicationRemote,
CookieManager cookieManager) {
this.examDelayApplicationRemote = examDelayApplicationRemote;
this.cookieManager = cookieManager;
}
public ExamDelayApplication getExamDelayApplication(String user, String term, String activityId) {
String cookie = cookieManager.getCookie(user, CookieType.UNDERGRAD);
var response = examDelayApplicationRemote.get(cookie, term, activityId);
if (response.code() != RpcCommonResponseCode.SUCCESS.getCode()) {
return null;
}
// todo 异步存用户课表,异常判断等等
return response.data();
}
}

@ -0,0 +1,32 @@
package cn.wustlinghang.wusthelper.web.service.campus.undergrad;
import cn.wustlinghang.wusthelper.web.entity.CookieType;
import cn.wustlinghang.wusthelper.web.rpc.undergrad.ScoreRemote;
import cn.wustlinghang.wusthelper.web.service.cookie.CookieManager;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ScoreService {
private final ScoreRemote scoreRemote;
private final CookieManager cookieManager;
public ScoreService(ScoreRemote scoreRemote, CookieManager cookieManager) {
this.scoreRemote = scoreRemote;
this.cookieManager = cookieManager;
}
public List<Score> getScore(String user) {
String cookie = cookieManager.getCookie(user, CookieType.UNDERGRAD);
var response = scoreRemote.get(cookie);
if (response.code() != RpcCommonResponseCode.SUCCESS.getCode()) {
return null;
}
// todo 异步存用户课表,异常判断等等
return response.data();
}
}

@ -0,0 +1,30 @@
package cn.wustlinghang.wusthelper.web.service.campus.undergrad;
import cn.wustlinghang.wusthelper.web.rpc.undergrad.StudentInfoRemote;
import cn.wustlinghang.wusthelper.web.entity.CookieType;
import cn.wustlinghang.wusthelper.web.service.cookie.CookieManager;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import org.springframework.stereotype.Service;
@Service
public class StudentInfoService {
private final StudentInfoRemote studentInfoRemote;
private final CookieManager cookieManager;
public StudentInfoService(StudentInfoRemote studentInfoRemote, CookieManager cookieManager) {
this.studentInfoRemote = studentInfoRemote;
this.cookieManager = cookieManager;
}
public StudentInfo getStudentInfo(String user) {
String cookie = cookieManager.getCookie(user, CookieType.UNDERGRAD);
var response = studentInfoRemote.get(cookie);
if (response.code() != RpcCommonResponseCode.SUCCESS.getCode()) {
return null;
}
// todo 异步存用户课表,异常判断等等
return response.data();
}
}

@ -0,0 +1,29 @@
package cn.wustlinghang.wusthelper.web.service.campus.undergrad;
import cn.wustlinghang.wusthelper.web.rpc.undergrad.TrainingPlanRemote;
import cn.wustlinghang.wusthelper.web.entity.CookieType;
import cn.wustlinghang.wusthelper.web.service.cookie.CookieManager;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import org.springframework.stereotype.Service;
@Service
public class TrainingPlanService {
private final TrainingPlanRemote trainingPlanRemote;
private final CookieManager cookieManager;
public TrainingPlanService(TrainingPlanRemote trainingPlanRemote, CookieManager cookieManager) {
this.trainingPlanRemote = trainingPlanRemote;
this.cookieManager = cookieManager;
}
public String getTrainingPlan(String user) {
String cookie = cookieManager.getCookie(user, CookieType.UNDERGRAD);
var response = trainingPlanRemote.get(cookie);
if (response.code() != RpcCommonResponseCode.SUCCESS.getCode()) {
return null;
}
// todo 异步存用户课表,异常判断等等
return response.data();
}
}

@ -0,0 +1,21 @@
package cn.wustlinghang.wusthelper.web.service.campus.undergrad;
import cn.wustlinghang.wusthelper.web.rpc.undergrad.CookieRemote;
import org.springframework.stereotype.Service;
@Service
public class UndergradCookieService {
private final CookieRemote cookieRemote;
public UndergradCookieService(CookieRemote cookieRemote) {
this.cookieRemote = cookieRemote;
}
public String getLoginCookie(String username, String password) {
return cookieRemote.login(username, password).data();
}
public Boolean checkCookie(String cookie) {
return cookieRemote.verify(cookie).data();
}
}

@ -0,0 +1,62 @@
package cn.wustlinghang.wusthelper.web.service.cookie;
import cn.wustlinghang.wusthelper.web.entity.CookieType;
import cn.wustlinghang.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 java.util.concurrent.TimeUnit;
@Service
@Scope("singleton")
public class CookieManager {
private static final Cache<String, String> cookiePool = Caffeine.newBuilder()
.expireAfterWrite(2, TimeUnit.HOURS)
.initialCapacity(256)
.maximumSize(2048)
.build();
private final UndergradCookieService undergradCookieService;
public CookieManager(UndergradCookieService undergradCookieService) {
this.undergradCookieService = undergradCookieService;
}
public String getCookie(String username, CookieType cookieType) {
return getCookie(username, cookieType, false);
}
public String getCookie(String username, CookieType cookieType, boolean forceRefresh) {
String cacheKey = String.format("%s:%d", username, cookieType.getCode());
String cookie = cookiePool.getIfPresent(cacheKey);
boolean valid = cookie != null && checkCookie(cookie, cookieType) && !forceRefresh;
if (valid) {
return cookie;
}
cookie = this.refreshCookie(username, cookieType);
cookiePool.put(cacheKey, cookie);
return cookie;
}
public boolean checkCookie(String cookie, CookieType cookieType) {
return switch (cookieType) {
case UNDERGRAD -> undergradCookieService.checkCookie(cookie);
case GRADUATE -> undergradCookieService.checkCookie(cookie);
default -> false;
};
}
public String refreshCookie(String username, CookieType cookieType) {
String password = "";
return switch (cookieType) {
case UNDERGRAD -> undergradCookieService.getLoginCookie(username, password);
case GRADUATE -> undergradCookieService.getLoginCookie(username, password);
default -> null;
};
}
}

@ -14,6 +14,11 @@ spring:
port: 8500
discovery:
register: false
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
username: root
password: Test2333!
server:
port: ${RUN_PORT}

@ -0,0 +1,26 @@
package cn.wustlinghang.wusthelper;
import cn.wustlinghang.wusthelper.data.dao.mapper.StudentMapper;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@Configuration
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = TestMain.class)
@TestPropertySource(properties = {
"spring.config.location=classpath:application-test.yml"
})
public class StudentTest {
@Autowired
private StudentMapper studentMapper;
@Test
public void testStudent() {
System.out.println(studentMapper.selectById(38));
}
}

@ -0,0 +1,29 @@
package cn.wustlinghang.wusthelper;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@EnableAsync
@Configuration
@EnableScheduling
@ExtendWith(SpringExtension.class)
@EnableFeignClients(basePackages = {"cn.wustlinghang.wusthelper.web.rpc"})
@TestPropertySource(properties = {
"spring.config.location=classpath:application-test.yml"
})
@SpringBootApplication(scanBasePackages = {
// 指定springboot的bean扫描路径,有新增请及时更新
"cn.wustlinghang.wusthelper.data",
"cn.wustlinghang.wusthelper.web",
})
@MapperScan("cn.wustlinghang.wusthelper.data.dao.mapper")
public class TestMain {
}

@ -0,0 +1,24 @@
# 服务端配置
# 密码/密钥/内部地址『禁止』写在此处或其他git能检测到的地方
# 具体数值由运维填写在.env文件中,不能添加到git仓库中
spring:
config:
import: optional:file:.env[.properties]
application:
name: wusthelper-backend-main
cloud:
consul:
host: 127.0.0.1
port: 8500
discovery:
register: false
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
username: root
password: Test2333!
server:
port: 10000

@ -23,6 +23,10 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<caffeine.version>3.1.6</caffeine.version>
<springboot.version>3.1.1</springboot.version>
<snakeyaml.version>2.0</snakeyaml.version>
<junit.version>5.10.0-RC1</junit.version>
</properties>
<dependencies>
@ -43,5 +47,41 @@
<artifactId>mywust-common</artifactId>
<version>${mywust.version}</version>
</dependency>
<!-- 清除springboot的依赖引入的漏洞警告,直接提升版本消除 -->
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>${snakeyaml.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.junit.jupiter</groupId>-->
<!-- <artifactId>junit-jupiter-api</artifactId>-->
<!-- <version>${junit.version}</version>-->
<!-- <scope>test</scope>-->
<!-- </dependency>-->
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${springboot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>

@ -1,19 +0,0 @@
package cn.wustlinghang.wusthelper.internal.rpc.response;
public record RpcResponse<T>(int code, String msg, T data) {
public static <T> RpcResponse<T> success(T data) {
return new RpcResponse<>(RpcCommonResponseCode.SUCCESS.getCode(), "ok", data);
}
public static <T> RpcResponse<T> success() {
return success(null);
}
public static <T> RpcResponse<T> error(int code, String message) {
return new RpcResponse<>(code, message, null);
}
public static <T> RpcResponse<T> error(RpcCommonResponseCode code) {
return error(code.getCode(), code.getMessage());
}
}

@ -0,0 +1,19 @@
package cn.wustlinghang.wusthelper.internal.rpc.response;
public record RpcResponseDto<T>(int code, String msg, T data) {
public static <T> RpcResponseDto<T> success(T data) {
return new RpcResponseDto<>(RpcCommonResponseCode.SUCCESS.getCode(), "ok", data);
}
public static <T> RpcResponseDto<T> success() {
return success(null);
}
public static <T> RpcResponseDto<T> error(int code, String message) {
return new RpcResponseDto<>(code, message, null);
}
public static <T> RpcResponseDto<T> error(RpcCommonResponseCode code) {
return error(code.getCode(), code.getMessage());
}
}

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.main.response;
package cn.wustlinghang.wusthelper.web.response;
/**

@ -2,7 +2,7 @@
* Class created by lensfrex.
*/
package cn.wustlinghang.wusthelper.main.response;
package cn.wustlinghang.wusthelper.web.response;
public enum ResponseCode {
SUCCESS(0, "成功"),

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.wustlinghang.wusthelper</groupId>
<artifactId>rpc-frp-consul</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.wustlinghang.mywust</groupId>
<artifactId>mywust-network-okhttp</artifactId>
<version>0.0.2-beta</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.ini4j</groupId>
<artifactId>ini4j</artifactId>
<version>0.5.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
<scope>provided</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2</url>
</repository>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>github</id>
<url>https://maven.pkg.github.com/LingHangStudio/mywust</url>
</repository>
</repositories>
</project>

@ -1,7 +1,7 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponse;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.core.MediaType;
@ -27,9 +27,9 @@ public abstract class BaseExceptionHandler {
public Response toResponse(Response.Status status, int code, String msg, String handlerName) {
Object response;
try {
response = objectMapper.writeValueAsString(RpcResponse.error(code, msg));
response = objectMapper.writeValueAsString(RpcResponseDto.error(code, msg));
} catch (JsonProcessingException e) {
response = RpcResponse.error(RpcCommonResponseCode.SERVER_INTERNAL_ERROR);
response = RpcResponseDto.error(RpcCommonResponseCode.SERVER_INTERNAL_ERROR);
}
return Response.status(status)

@ -1,7 +1,7 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1.interceptor;
import cn.wustlinghang.wusthelper.internal.graduate.api.http.v1.handler.BaseExceptionHandler;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponse;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.HttpHeaders;
@ -25,7 +25,7 @@ public class ResponseWrapperInterceptor implements WriterInterceptor {
boolean hasException = context.getHeaders().get(BaseExceptionHandler.EXCEPTION_HEADER_KEY) != null;
if (!hasException) {
Object data = context.getEntity();
RpcResponse<Object> wrappedResponse = RpcResponse.success(data);
RpcResponseDto<Object> wrappedResponse = RpcResponseDto.success(data);
String json = objectMapper.writeValueAsString(wrappedResponse);
context.getHeaders().putSingle(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
context.setEntity(json);

@ -0,0 +1,40 @@
package cn.wustlinghang.wusthelper.internal.graduate.rpc;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.wusthelper.internal.graduate.rpc.config.RpcConfig;
import cn.wustlinghang.wusthelper.internal.rpc.FrpConsulRegister;
import cn.wustlinghang.wusthelper.internal.rpc.config.FrpConfig;
import cn.wustlinghang.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;
@Slf4j
@Startup
@ApplicationScoped
public class Register {
private final FrpConsulRegister register;
public Register(RpcConfig rpcConfig, Requester requester, ObjectMapper objectMapper) {
FrpConfig frpConfig = FrpConfig.builder()
.frpcAdminAddress(rpcConfig.getFrpcAdminAddress())
.frpcAdminUsername(rpcConfig.getFrpcAdminUsername())
.frpcAdminPassword(rpcConfig.getFrpcAdminPassword())
.build();
RegisterConfig registerConfig = RegisterConfig.builder()
.consulAddress(rpcConfig.getConsulAddress())
.localServicePort(rpcConfig.getLocalServicePort())
.serviceName(rpcConfig.getServiceName())
.build();
this.register = new FrpConsulRegister(registerConfig, frpConfig, requester, objectMapper);
}
@PostConstruct
public void onStartup() {
register.register();
}
}

@ -0,0 +1,33 @@
package cn.wustlinghang.wusthelper.internal.graduate.rpc.config;
import jakarta.inject.Singleton;
import jakarta.ws.rs.DefaultValue;
import lombok.Data;
import org.eclipse.microprofile.config.inject.ConfigProperty;
@Data
@Singleton
public class RpcConfig {
@DefaultValue("default.service")
@ConfigProperty(name = "rpc.service.name")
String serviceName;
@DefaultValue("http://127.0.0.1:8500")
@ConfigProperty(name = "rpc.register.consul-api.address")
String consulAddress;
@DefaultValue("http://127.0.0.1:7400")
@ConfigProperty(name = "rpc.frpc.admin-api.address")
String frpcAdminAddress;
@DefaultValue("")
@ConfigProperty(name = "rpc.frpc.admin.username")
String frpcAdminUsername;
@DefaultValue("")
@ConfigProperty(name = "rpc.frpc.admin.password")
String frpcAdminPassword;
@ConfigProperty(name = "quarkus.http.port")
String localServicePort;
}

@ -0,0 +1,14 @@
package cn.wustlinghang.wusthelper.internal.graduate.rpc.health;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.Response;
@Path("/health")
public class HealthCheck {
private static final Response successResponse = Response.accepted().status(200).build();
@GET
@Path("/")
public Response response() {return successResponse;}
}

@ -1,7 +1,7 @@
package cn.wustlinghang.wusthelper.internal.library.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponse;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.core.MediaType;
@ -27,9 +27,9 @@ public abstract class BaseExceptionHandler {
public Response toResponse(Response.Status status, int code, String msg, String handlerName) {
Object response;
try {
response = objectMapper.writeValueAsString(RpcResponse.error(code, msg));
response = objectMapper.writeValueAsString(RpcResponseDto.error(code, msg));
} catch (JsonProcessingException e) {
response = RpcResponse.error(RpcCommonResponseCode.SERVER_INTERNAL_ERROR);
response = RpcResponseDto.error(RpcCommonResponseCode.SERVER_INTERNAL_ERROR);
}
return Response.status(status)

@ -1,7 +1,7 @@
package cn.wustlinghang.wusthelper.internal.library.api.http.v1.interceptor;
import cn.wustlinghang.wusthelper.internal.library.api.http.v1.handler.BaseExceptionHandler;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponse;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.HttpHeaders;
@ -25,7 +25,7 @@ public class ResponseWrapperInterceptor implements WriterInterceptor {
boolean hasException = context.getHeaders().get(BaseExceptionHandler.EXCEPTION_HEADER_KEY) != null;
if (!hasException) {
Object data = context.getEntity();
RpcResponse<Object> wrappedResponse = RpcResponse.success(data);
RpcResponseDto<Object> wrappedResponse = RpcResponseDto.success(data);
String json = objectMapper.writeValueAsString(wrappedResponse);
context.getHeaders().putSingle(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
context.setEntity(json);

@ -0,0 +1,40 @@
package cn.wustlinghang.wusthelper.internal.library.rpc;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.wusthelper.internal.library.rpc.config.RpcConfig;
import cn.wustlinghang.wusthelper.internal.rpc.FrpConsulRegister;
import cn.wustlinghang.wusthelper.internal.rpc.config.FrpConfig;
import cn.wustlinghang.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;
@Slf4j
@Startup
@ApplicationScoped
public class Register {
private final FrpConsulRegister register;
public Register(RpcConfig rpcConfig, Requester requester, ObjectMapper objectMapper) {
FrpConfig frpConfig = FrpConfig.builder()
.frpcAdminAddress(rpcConfig.getFrpcAdminAddress())
.frpcAdminUsername(rpcConfig.getFrpcAdminUsername())
.frpcAdminPassword(rpcConfig.getFrpcAdminPassword())
.build();
RegisterConfig registerConfig = RegisterConfig.builder()
.consulAddress(rpcConfig.getConsulAddress())
.localServicePort(rpcConfig.getLocalServicePort())
.serviceName(rpcConfig.getServiceName())
.build();
this.register = new FrpConsulRegister(registerConfig, frpConfig, requester, objectMapper);
}
@PostConstruct
public void onStartup() {
register.register();
}
}

@ -0,0 +1,33 @@
package cn.wustlinghang.wusthelper.internal.library.rpc.config;
import jakarta.inject.Singleton;
import jakarta.ws.rs.DefaultValue;
import lombok.Data;
import org.eclipse.microprofile.config.inject.ConfigProperty;
@Data
@Singleton
public class RpcConfig {
@DefaultValue("default.service")
@ConfigProperty(name = "rpc.service.name")
String serviceName;
@DefaultValue("http://127.0.0.1:8500")
@ConfigProperty(name = "rpc.register.consul-api.address")
String consulAddress;
@DefaultValue("http://127.0.0.1:7400")
@ConfigProperty(name = "rpc.frpc.admin-api.address")
String frpcAdminAddress;
@DefaultValue("")
@ConfigProperty(name = "rpc.frpc.admin.username")
String frpcAdminUsername;
@DefaultValue("")
@ConfigProperty(name = "rpc.frpc.admin.password")
String frpcAdminPassword;
@ConfigProperty(name = "quarkus.http.port")
String localServicePort;
}

@ -0,0 +1,14 @@
package cn.wustlinghang.wusthelper.internal.library.rpc.health;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.Response;
@Path("/health")
public class HealthCheck {
private static final Response successResponse = Response.accepted().status(200).build();
@GET
@Path("/")
public Response response() {return successResponse;}
}

@ -1,7 +1,7 @@
package cn.wustlinghang.wusthelper.internal.physics.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponse;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.core.MediaType;
@ -27,9 +27,9 @@ public abstract class BaseExceptionHandler {
public Response toResponse(Response.Status status, int code, String msg, String handlerName) {
Object response;
try {
response = objectMapper.writeValueAsString(RpcResponse.error(code, msg));
response = objectMapper.writeValueAsString(RpcResponseDto.error(code, msg));
} catch (JsonProcessingException e) {
response = RpcResponse.error(RpcCommonResponseCode.SERVER_INTERNAL_ERROR);
response = RpcResponseDto.error(RpcCommonResponseCode.SERVER_INTERNAL_ERROR);
}
return Response.status(status)

@ -1,7 +1,7 @@
package cn.wustlinghang.wusthelper.internal.physics.api.http.v1.interceptor;
import cn.wustlinghang.wusthelper.internal.physics.api.http.v1.handler.BaseExceptionHandler;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponse;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.HttpHeaders;
@ -25,7 +25,7 @@ public class ResponseWrapperInterceptor implements WriterInterceptor {
boolean hasException = context.getHeaders().get(BaseExceptionHandler.EXCEPTION_HEADER_KEY) != null;
if (!hasException) {
Object data = context.getEntity();
RpcResponse<Object> wrappedResponse = RpcResponse.success(data);
RpcResponseDto<Object> wrappedResponse = RpcResponseDto.success(data);
String json = objectMapper.writeValueAsString(wrappedResponse);
context.getHeaders().putSingle(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
context.setEntity(json);

@ -0,0 +1,40 @@
package cn.wustlinghang.wusthelper.internal.physics.rpc;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.wusthelper.internal.physics.rpc.config.RpcConfig;
import cn.wustlinghang.wusthelper.internal.rpc.FrpConsulRegister;
import cn.wustlinghang.wusthelper.internal.rpc.config.FrpConfig;
import cn.wustlinghang.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;
@Slf4j
@Startup
@ApplicationScoped
public class Register {
private final FrpConsulRegister register;
public Register(RpcConfig rpcConfig, Requester requester, ObjectMapper objectMapper) {
FrpConfig frpConfig = FrpConfig.builder()
.frpcAdminAddress(rpcConfig.getFrpcAdminAddress())
.frpcAdminUsername(rpcConfig.getFrpcAdminUsername())
.frpcAdminPassword(rpcConfig.getFrpcAdminPassword())
.build();
RegisterConfig registerConfig = RegisterConfig.builder()
.consulAddress(rpcConfig.getConsulAddress())
.localServicePort(rpcConfig.getLocalServicePort())
.serviceName(rpcConfig.getServiceName())
.build();
this.register = new FrpConsulRegister(registerConfig, frpConfig, requester, objectMapper);
}
@PostConstruct
public void onStartup() {
register.register();
}
}

@ -0,0 +1,33 @@
package cn.wustlinghang.wusthelper.internal.physics.rpc.config;
import jakarta.inject.Singleton;
import jakarta.ws.rs.DefaultValue;
import lombok.Data;
import org.eclipse.microprofile.config.inject.ConfigProperty;
@Data
@Singleton
public class RpcConfig {
@DefaultValue("default.service")
@ConfigProperty(name = "rpc.service.name")
String serviceName;
@DefaultValue("http://127.0.0.1:8500")
@ConfigProperty(name = "rpc.register.consul-api.address")
String consulAddress;
@DefaultValue("http://127.0.0.1:7400")
@ConfigProperty(name = "rpc.frpc.admin-api.address")
String frpcAdminAddress;
@DefaultValue("")
@ConfigProperty(name = "rpc.frpc.admin.username")
String frpcAdminUsername;
@DefaultValue("")
@ConfigProperty(name = "rpc.frpc.admin.password")
String frpcAdminPassword;
@ConfigProperty(name = "quarkus.http.port")
String localServicePort;
}

@ -0,0 +1,14 @@
package cn.wustlinghang.wusthelper.internal.physics.rpc.health;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.Response;
@Path("/health")
public class HealthCheck {
private static final Response successResponse = Response.accepted().status(200).build();
@GET
@Path("/")
public Response response() {return successResponse;}
}

@ -1,7 +1,7 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponse;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.core.MediaType;
@ -27,9 +27,9 @@ public abstract class BaseExceptionHandler {
public Response toResponse(Response.Status status, int code, String msg, String handlerName) {
Object response;
try {
response = objectMapper.writeValueAsString(RpcResponse.error(code, msg));
response = objectMapper.writeValueAsString(RpcResponseDto.error(code, msg));
} catch (JsonProcessingException e) {
response = RpcResponse.error(RpcCommonResponseCode.SERVER_INTERNAL_ERROR);
response = RpcResponseDto.error(RpcCommonResponseCode.SERVER_INTERNAL_ERROR);
}
return Response.status(status)

@ -1,7 +1,7 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1.interceptor;
import cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1.handler.BaseExceptionHandler;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponse;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.HttpHeaders;
@ -25,7 +25,7 @@ public class ResponseWrapperInterceptor implements WriterInterceptor {
boolean hasException = context.getHeaders().get(BaseExceptionHandler.EXCEPTION_HEADER_KEY) != null;
if (!hasException) {
Object data = context.getEntity();
RpcResponse<Object> wrappedResponse = RpcResponse.success(data);
RpcResponseDto<Object> wrappedResponse = RpcResponseDto.success(data);
String json = objectMapper.writeValueAsString(wrappedResponse);
context.getHeaders().putSingle(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
context.setEntity(json);

Loading…
Cancel
Save