main
parent
76ed47c1b3
commit
7f8fabd46e
@ -1,6 +1,6 @@ |
||||
package cn.wustlinghang.wusthelper.data.dao.mapper; |
||||
package wusthelper.data.dao.mapper; |
||||
|
||||
import cn.wustlinghang.wusthelper.data.entity.Student; |
||||
import wusthelper.data.entity.Student; |
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
import org.apache.ibatis.annotations.Mapper; |
||||
|
@ -1,23 +0,0 @@ |
||||
package cn.wustlinghang.wusthelper.web.api.v2.undergrade; |
||||
|
||||
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; |
||||
|
||||
@RestController |
||||
@RequestMapping("/jwc") |
||||
public class UndergradController { |
||||
private final UndergradCookieService undergradCookieService; |
||||
|
||||
public UndergradController(UndergradCookieService undergradCookieService) { |
||||
this.undergradCookieService = undergradCookieService; |
||||
} |
||||
|
||||
@PostMapping("/login") |
||||
public Response<String> login() { |
||||
String cookie = undergradCookieService.getLoginCookie("202118194039", "-96387ee"); |
||||
return Response.success(cookie); |
||||
} |
||||
} |
@ -1,30 +0,0 @@ |
||||
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(); |
||||
} |
||||
} |
@ -1,21 +0,0 @@ |
||||
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(); |
||||
} |
||||
} |
@ -1,62 +0,0 @@ |
||||
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; |
||||
}; |
||||
} |
||||
} |
@ -1,4 +1,4 @@ |
||||
package cn.wustlinghang.wusthelper; |
||||
package wusthelper; |
||||
|
||||
import org.mybatis.spring.annotation.MapperScan; |
||||
import org.springframework.boot.SpringApplication; |
@ -1,4 +1,4 @@ |
||||
package cn.wustlinghang.wusthelper.web.api; |
||||
package wusthelper.web.api; |
||||
|
||||
import org.springframework.stereotype.Controller; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
@ -0,0 +1,81 @@ |
||||
package wusthelper.web.api.v2; |
||||
|
||||
import com.auth0.jwt.JWT; |
||||
import com.auth0.jwt.algorithms.Algorithm; |
||||
import com.auth0.jwt.exceptions.JWTVerificationException; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
|
||||
import java.time.Duration; |
||||
import java.util.Date; |
||||
|
||||
@Slf4j |
||||
public class Token { |
||||
|
||||
private final static String SECRET = "LingHangStudio.WustHelper"; |
||||
|
||||
private final static long EXPIRE_SCD = Duration.ofDays(3).toSeconds(); |
||||
|
||||
private static final Algorithm jwtAlgorithm = Algorithm.HMAC256(SECRET); |
||||
|
||||
/** |
||||
* 签发Token |
||||
* |
||||
* @return |
||||
*/ |
||||
public static String signToken(Long uid, String studentNumber) { |
||||
try { |
||||
Date now = new Date(); |
||||
Date expireAt = new Date(now.getTime() + EXPIRE_SCD); |
||||
|
||||
return JWT.create() |
||||
.withClaim("StuId", uid.toString()) |
||||
.withClaim("StuNum", studentNumber) |
||||
.withIssuedAt(now) |
||||
.withExpiresAt(expireAt) |
||||
.sign(jwtAlgorithm); |
||||
} catch (Exception e) { |
||||
log.error("[{}]:Token签发工具类>签发Token异常, 空指针异常: uid={},studentNumber={}", |
||||
Thread.currentThread().getStackTrace()[1].getMethodName(), |
||||
uid, studentNumber); |
||||
throw new RuntimeException("[JwtUtil.signToken()]"); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 校验Token |
||||
* |
||||
* @param token |
||||
* @return |
||||
*/ |
||||
public static boolean verifyToken(String token) { |
||||
try { |
||||
JWT.require(jwtAlgorithm) |
||||
.build() |
||||
.verify(token); |
||||
} catch (JWTVerificationException e) { |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* Token 负载StuId |
||||
* |
||||
* @param token |
||||
* @return |
||||
*/ |
||||
public static String getUid(String token) { |
||||
return JWT.decode(token).getClaim("StuId").asString(); |
||||
} |
||||
|
||||
/** |
||||
* Token 负载StuNum |
||||
* |
||||
* @param token |
||||
* @return |
||||
*/ |
||||
public static String getStudentNumber(String token) { |
||||
return JWT.decode(token).getClaim("StuNum").asString(); |
||||
} |
||||
} |
@ -0,0 +1,5 @@ |
||||
package wusthelper.web.api.v2.undergrade; |
||||
|
||||
public class UndergradController { |
||||
|
||||
} |
@ -0,0 +1,30 @@ |
||||
package wusthelper.web.api.v2.undergrade; |
||||
|
||||
import org.springframework.web.bind.annotation.*; |
||||
import wusthelper.internal.rpc.response.RpcCommonResponseCode; |
||||
import wusthelper.web.api.v2.Token; |
||||
import wusthelper.web.response.Response; |
||||
import wusthelper.web.service.campus.GeneralUserService; |
||||
import wusthelper.web.service.campus.undergrad.UndergradCookieService; |
||||
|
||||
@RestController |
||||
@RequestMapping("/jwc") |
||||
public class UndergradLoginController { |
||||
private final GeneralUserService generalUserService; |
||||
|
||||
public UndergradLoginController(GeneralUserService generalUserService) { |
||||
this.generalUserService = generalUserService; |
||||
} |
||||
|
||||
@PostMapping("/login") |
||||
public Response<String> login(@RequestParam(value = "username") String username, |
||||
@RequestParam(value = "jwcPwd") String password, |
||||
@RequestHeader(name = "Platform", required = false) String platform) { |
||||
|
||||
var user = generalUserService.login(username, password, GeneralUserService.UserType.Undergrad); |
||||
|
||||
String token = Token.signToken(user.getId(), user.getStuNum()); |
||||
|
||||
return Response.success(token); |
||||
} |
||||
} |
@ -1,4 +1,4 @@ |
||||
package cn.wustlinghang.wusthelper.web.configure; |
||||
package wusthelper.web.configure; |
||||
|
||||
import com.github.benmanes.caffeine.cache.Cache; |
||||
import com.github.benmanes.caffeine.cache.Caffeine; |
@ -0,0 +1,12 @@ |
||||
package wusthelper.web.configure; |
||||
|
||||
import lombok.Data; |
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Data |
||||
@Component |
||||
@ConfigurationProperties("wusthelper") |
||||
public class GlobalConfigureItems { |
||||
private String passwordEncodeKey; |
||||
} |
@ -0,0 +1,21 @@ |
||||
package wusthelper.web.configure; |
||||
|
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import wusthelper.web.util.PasswordCodec; |
||||
|
||||
@Configuration |
||||
public class PasswordCodecConfigure { |
||||
private final GlobalConfigureItems globalConfigureItems; |
||||
|
||||
public PasswordCodecConfigure(GlobalConfigureItems globalConfigureItems) { |
||||
this.globalConfigureItems = globalConfigureItems; |
||||
} |
||||
|
||||
@Bean |
||||
public PasswordCodec passwordCodec() { |
||||
String key = globalConfigureItems.getPasswordEncodeKey(); |
||||
|
||||
return new PasswordCodec(key); |
||||
} |
||||
} |
@ -1,12 +1,12 @@ |
||||
package cn.wustlinghang.wusthelper.web.entity; |
||||
package wusthelper.web.data.entity; |
||||
|
||||
import java.util.StringJoiner; |
||||
|
||||
public enum CookieType { |
||||
UNDERGRAD(0, "本科生"), |
||||
GRADUATE(1, "研究生"), |
||||
LIBRARY(2, "图书馆"), |
||||
PHYSICS(3, "物理实验"),; |
||||
Undergrad(0, "本科生"), |
||||
Graduate(1, "研究生"), |
||||
Library(2, "图书馆"), |
||||
Physics(3, "物理实验"),; |
||||
|
||||
private final int code; |
||||
|
@ -0,0 +1,18 @@ |
||||
package wusthelper.web.rpc.graduate; |
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient; |
||||
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 = "cookie") |
||||
public interface GraduateCookieRemote { |
||||
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,23 @@ |
||||
package wusthelper.web.rpc.graduate; |
||||
|
||||
import cn.wustlinghang.mywust.data.global.StudentInfo; |
||||
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 wusthelper.internal.rpc.response.RpcResponseDto; |
||||
|
||||
@FeignClient(name = "wusthelper.graduate", contextId = "studentInfo") |
||||
public interface GraduateStudentInfoRemote { |
||||
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); |
||||
} |
@ -1,7 +1,7 @@ |
||||
package cn.wustlinghang.wusthelper.web.rpc.undergrad; |
||||
package wusthelper.web.rpc.undergrad; |
||||
|
||||
import cn.wustlinghang.mywust.data.global.Course; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto; |
||||
import wusthelper.internal.rpc.response.RpcResponseDto; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import org.springframework.cloud.openfeign.FeignClient; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
@ -1,6 +1,6 @@ |
||||
package cn.wustlinghang.wusthelper.web.rpc.undergrad; |
||||
package wusthelper.web.rpc.undergrad; |
||||
|
||||
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto; |
||||
import wusthelper.internal.rpc.response.RpcResponseDto; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import org.springframework.cloud.openfeign.FeignClient; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
@ -1,7 +1,7 @@ |
||||
package cn.wustlinghang.wusthelper.web.rpc.undergrad; |
||||
package wusthelper.web.rpc.undergrad; |
||||
|
||||
import cn.wustlinghang.mywust.data.undergrad.ExamDelayApplication; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto; |
||||
import wusthelper.internal.rpc.response.RpcResponseDto; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import org.springframework.cloud.openfeign.FeignClient; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
@ -1,7 +1,7 @@ |
||||
package cn.wustlinghang.wusthelper.web.rpc.undergrad; |
||||
package wusthelper.web.rpc.undergrad; |
||||
|
||||
import cn.wustlinghang.mywust.data.global.Score; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto; |
||||
import wusthelper.internal.rpc.response.RpcResponseDto; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import org.springframework.cloud.openfeign.FeignClient; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
@ -1,6 +1,6 @@ |
||||
package cn.wustlinghang.wusthelper.web.rpc.undergrad; |
||||
package wusthelper.web.rpc.undergrad; |
||||
|
||||
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto; |
||||
import wusthelper.internal.rpc.response.RpcResponseDto; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import org.springframework.cloud.openfeign.FeignClient; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
@ -1,12 +1,12 @@ |
||||
package cn.wustlinghang.wusthelper.web.rpc.undergrad; |
||||
package wusthelper.web.rpc.undergrad; |
||||
|
||||
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto; |
||||
import 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 { |
||||
public interface UndergradCookieRemote { |
||||
String COOKIE_ROOT_PATH = "/cookie"; |
||||
|
||||
@GetMapping(COOKIE_ROOT_PATH) |
@ -0,0 +1,116 @@ |
||||
package wusthelper.web.service.campus; |
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
||||
import com.github.yitter.idgen.YitIdHelper; |
||||
import org.springframework.stereotype.Service; |
||||
import wusthelper.code.ServiceCode; |
||||
import wusthelper.data.dao.mapper.StudentMapper; |
||||
import wusthelper.data.entity.Student; |
||||
import wusthelper.web.data.entity.CookieType; |
||||
import wusthelper.web.exception.ServiceException; |
||||
import wusthelper.web.rpc.graduate.GraduateStudentInfoRemote; |
||||
import wusthelper.web.rpc.undergrad.UndergradStudentInfoRemote; |
||||
import wusthelper.web.service.campus.graduate.GraduateCookieService; |
||||
import wusthelper.web.service.campus.undergrad.UndergradCookieService; |
||||
import wusthelper.web.service.cookie.CookieManager; |
||||
import wusthelper.web.util.Converter; |
||||
import wusthelper.web.util.PasswordCodec; |
||||
|
||||
/** |
||||
* 通用的用户信息服务,包括登录和(已存储的)用户信息获取等,同时自动存入新用户信息 |
||||
*/ |
||||
@Service |
||||
public class GeneralUserService { |
||||
private final StudentMapper studentMapper; |
||||
private final PasswordCodec passwordCodec; |
||||
|
||||
private final UndergradCookieService undergradCookieService; |
||||
private final GraduateCookieService graduateCookieService; |
||||
|
||||
private final GraduateStudentInfoRemote graduateStudentInfoRemote; |
||||
private final UndergradStudentInfoRemote undergradStudentInfoRemote; |
||||
|
||||
|
||||
public GeneralUserService(StudentMapper studentMapper, |
||||
PasswordCodec passwordCodec, |
||||
|
||||
UndergradCookieService undergradCookieService, |
||||
GraduateCookieService graduateCookieService, |
||||
|
||||
GraduateStudentInfoRemote graduateStudentInfoRemote, |
||||
UndergradStudentInfoRemote undergradStudentInfoRemote) { |
||||
|
||||
this.studentMapper = studentMapper; |
||||
this.passwordCodec = passwordCodec; |
||||
|
||||
this.undergradCookieService = undergradCookieService; |
||||
this.graduateCookieService = graduateCookieService; |
||||
|
||||
this.graduateStudentInfoRemote = graduateStudentInfoRemote; |
||||
this.undergradStudentInfoRemote = undergradStudentInfoRemote; |
||||
} |
||||
|
||||
public enum UserType {Undergrad, Graduate} |
||||
|
||||
/** |
||||
* 登录验证并获取用户信息,同时自动存库 |
||||
* |
||||
* @param username 用户名(即学号) |
||||
* @param password 密码(明文原文) |
||||
* @param userType 用户类型,现在有本科生和研究生 |
||||
* @return 用户信息 |
||||
*/ |
||||
public Student login(String username, String password, UserType userType) { |
||||
var cookie = switch (userType) { |
||||
case Undergrad -> undergradCookieService.getLoginCookie(username, password); |
||||
case Graduate -> graduateCookieService.getLoginCookie(username, password); |
||||
}; |
||||
|
||||
var cookieType = switch (userType) { |
||||
case Undergrad -> CookieType.Undergrad; |
||||
case Graduate -> CookieType.Graduate; |
||||
}; |
||||
|
||||
// 保存cookie,并获取用户信息并存库(基本的操作,非异步,信息获取失败意味登陆失败)
|
||||
CookieManager.store(username, cookie, cookieType); |
||||
return this.saveOrUpdateUser(username, cookie, password, userType); |
||||
} |
||||
|
||||
private Student saveOrUpdateUser(String username, String cookie, String password, UserType userType) { |
||||
var rpcResp = switch (userType) { |
||||
case Undergrad -> undergradStudentInfoRemote.get(cookie); |
||||
case Graduate -> graduateStudentInfoRemote.get(cookie); |
||||
}; |
||||
|
||||
if (rpcResp.code() != ServiceCode.Ok) { |
||||
ServiceException.of(rpcResp.code()); |
||||
} |
||||
|
||||
var studentInfo = rpcResp.data(); |
||||
var student = Converter.convert(studentInfo); |
||||
if (student.getStuNum() == null) { |
||||
student.setStuNum(username); |
||||
} |
||||
|
||||
var query = new QueryWrapper<Student>() |
||||
.eq("stu_num", username) |
||||
.eq("deleted", 0); |
||||
|
||||
// (按学号)检查用户信息是否已经存在数据库中,已存在则更新,否则新增信息
|
||||
var studentExists = studentMapper.exists(query); |
||||
if (studentExists) { |
||||
studentMapper.update(student, query); |
||||
} else { |
||||
student.setId(YitIdHelper.nextId()); |
||||
var encrypted = passwordCodec.encode(password); |
||||
student.setJwcPwd(encrypted); |
||||
if (userType == UserType.Undergrad) { |
||||
student.setLibPwd(encrypted); |
||||
} |
||||
|
||||
studentMapper.insert(student); |
||||
} |
||||
|
||||
return student; |
||||
} |
||||
} |
@ -0,0 +1,28 @@ |
||||
package wusthelper.web.service.campus.graduate; |
||||
|
||||
import org.springframework.stereotype.Service; |
||||
import wusthelper.code.ServiceCode; |
||||
import wusthelper.web.exception.ServiceException; |
||||
import wusthelper.web.rpc.graduate.GraduateCookieRemote; |
||||
|
||||
@Service |
||||
public class GraduateCookieService { |
||||
private final GraduateCookieRemote graduateCookieRemote; |
||||
|
||||
public GraduateCookieService(GraduateCookieRemote graduateCookieRemote) { |
||||
this.graduateCookieRemote = graduateCookieRemote; |
||||
} |
||||
|
||||
public String getLoginCookie(String username, String password) throws ServiceException { |
||||
var rpcResp = graduateCookieRemote.login(username, password); |
||||
if (rpcResp.code() != ServiceCode.Ok) { |
||||
ServiceException.of(rpcResp.code()); |
||||
} |
||||
|
||||
return rpcResp.data(); |
||||
} |
||||
|
||||
public Boolean checkCookie(String cookie) { |
||||
return graduateCookieRemote.verify(cookie).data(); |
||||
} |
||||
} |
@ -0,0 +1,46 @@ |
||||
package wusthelper.web.service.campus.graduate; |
||||
|
||||
import cn.wustlinghang.mywust.data.global.StudentInfo; |
||||
import org.springframework.stereotype.Service; |
||||
import wusthelper.code.ServiceCode; |
||||
import wusthelper.web.data.entity.CookieType; |
||||
import wusthelper.web.exception.ServiceException; |
||||
import wusthelper.web.rpc.graduate.GraduateStudentInfoRemote; |
||||
import wusthelper.web.service.cookie.CookieManager; |
||||
import wusthelper.web.service.student.StudentService; |
||||
|
||||
@Service |
||||
public class GraduateStudentInfoService { |
||||
private final GraduateStudentInfoRemote graduateStudentInfoRemote; |
||||
|
||||
private final CookieManager cookieManager; |
||||
|
||||
private final StudentService studentService; |
||||
|
||||
public GraduateStudentInfoService(GraduateStudentInfoRemote graduateStudentInfoRemote, |
||||
CookieManager cookieManager, |
||||
StudentService studentService) { |
||||
|
||||
this.graduateStudentInfoRemote = graduateStudentInfoRemote; |
||||
this.cookieManager = cookieManager; |
||||
this.studentService = studentService; |
||||
} |
||||
|
||||
public StudentInfo getStudentInfo(String user) { |
||||
String cookie = cookieManager.getCookie(user, CookieType.Graduate); |
||||
|
||||
return getStudentInfo(user, cookie); |
||||
} |
||||
|
||||
public StudentInfo getStudentInfo(String user, String cookie) { |
||||
var response = graduateStudentInfoRemote.get(cookie); |
||||
if (response.code() != ServiceCode.Ok) { |
||||
ServiceException.of(response.code()); |
||||
} |
||||
|
||||
var studentInfo = response.data(); |
||||
|
||||
studentService.saveOrUpdateUserAsync(user, studentInfo); |
||||
return studentInfo; |
||||
} |
||||
} |
@ -0,0 +1,29 @@ |
||||
package wusthelper.web.service.campus.undergrad; |
||||
|
||||
import org.springframework.stereotype.Service; |
||||
import wusthelper.code.ServiceCode; |
||||
import wusthelper.web.exception.ServiceException; |
||||
import wusthelper.web.rpc.undergrad.UndergradCookieRemote; |
||||
|
||||
@Service |
||||
public class UndergradCookieService { |
||||
|
||||
private final UndergradCookieRemote undergradCookieRemote; |
||||
|
||||
public UndergradCookieService(UndergradCookieRemote undergradCookieRemote) { |
||||
this.undergradCookieRemote = undergradCookieRemote; |
||||
} |
||||
|
||||
public String getLoginCookie(String username, String password) throws ServiceException { |
||||
var rpcResp = undergradCookieRemote.login(username, password); |
||||
if (rpcResp.code() != ServiceCode.Ok) { |
||||
ServiceException.of(rpcResp.code()); |
||||
} |
||||
|
||||
return rpcResp.data(); |
||||
} |
||||
|
||||
public Boolean checkCookie(String cookie) { |
||||
return undergradCookieRemote.verify(cookie).data(); |
||||
} |
||||
} |
@ -0,0 +1,48 @@ |
||||
package wusthelper.web.service.campus.undergrad; |
||||
|
||||
import cn.wustlinghang.mywust.data.global.StudentInfo; |
||||
import org.springframework.stereotype.Service; |
||||
import wusthelper.code.ServiceCode; |
||||
import wusthelper.web.data.entity.CookieType; |
||||
import wusthelper.web.exception.ServiceException; |
||||
import wusthelper.web.rpc.undergrad.UndergradStudentInfoRemote; |
||||
import wusthelper.web.service.cookie.CookieManager; |
||||
import wusthelper.web.service.student.StudentService; |
||||
import wusthelper.web.util.PasswordCodec; |
||||
|
||||
@Service |
||||
public class UndergradStudentInfoService { |
||||
|
||||
private final UndergradStudentInfoRemote undergradStudentInfoRemote; |
||||
|
||||
private final CookieManager cookieManager; |
||||
|
||||
private final StudentService studentService; |
||||
|
||||
public UndergradStudentInfoService(UndergradStudentInfoRemote undergradStudentInfoRemote, |
||||
CookieManager cookieManager, |
||||
StudentService studentService) { |
||||
|
||||
this.undergradStudentInfoRemote = undergradStudentInfoRemote; |
||||
this.cookieManager = cookieManager; |
||||
this.studentService = studentService; |
||||
} |
||||
|
||||
public StudentInfo getStudentInfo(String user) { |
||||
String cookie = cookieManager.getCookie(user, CookieType.Undergrad); |
||||
|
||||
return getStudentInfo(user, cookie); |
||||
} |
||||
|
||||
public StudentInfo getStudentInfo(String user, String cookie) { |
||||
var rpcResp = undergradStudentInfoRemote.get(cookie); |
||||
if (rpcResp.code() != ServiceCode.Ok) { |
||||
ServiceException.of(rpcResp.code()); |
||||
} |
||||
|
||||
var studentInfo = rpcResp.data(); |
||||
|
||||
studentService.saveOrUpdateUserAsync(user, studentInfo); |
||||
return studentInfo; |
||||
} |
||||
} |
@ -0,0 +1,100 @@ |
||||
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.web.data.entity.CookieType; |
||||
import wusthelper.web.exception.ServiceException; |
||||
import wusthelper.web.service.campus.graduate.GraduateCookieService; |
||||
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 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; |
||||
private final GraduateCookieService graduateCookieService; |
||||
|
||||
private final StudentMapper studentMapper; |
||||
|
||||
public CookieManager(UndergradCookieService undergradCookieService, |
||||
GraduateCookieService graduateCookieService, |
||||
StudentMapper studentMapper) { |
||||
|
||||
this.undergradCookieService = undergradCookieService; |
||||
this.graduateCookieService = graduateCookieService; |
||||
|
||||
this.studentMapper = studentMapper; |
||||
} |
||||
|
||||
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 static void store(String username, String cookie, CookieType cookieType) { |
||||
String cacheKey = String.format("%s:%d", username, cookieType.getCode()); |
||||
cookiePool.put(cacheKey, cookie); |
||||
} |
||||
|
||||
public boolean checkCookie(String cookie, CookieType cookieType) { |
||||
return switch (cookieType) { |
||||
case Undergrad -> undergradCookieService.checkCookie(cookie); |
||||
case Graduate -> graduateCookieService.checkCookie(cookie); |
||||
default -> false; |
||||
}; |
||||
} |
||||
|
||||
public String refreshCookie(String username, CookieType cookieType) { |
||||
var student = studentMapper.selectOne(new QueryWrapper<Student>() |
||||
.eq("stuNum", username) |
||||
.eq("deleted", 0) |
||||
); |
||||
|
||||
if (student == null) { |
||||
ServiceException.of(ServiceCode.UserNotExists); |
||||
} |
||||
|
||||
String password = switch (cookieType) { |
||||
case Undergrad, Graduate -> student.getJwcPwd(); |
||||
case Library -> student.getLibPwd(); |
||||
case Physics -> student.getWlsyPwd(); |
||||
}; |
||||
|
||||
if (password == null) { |
||||
ServiceException.of(ServiceCode.ParamWrong); |
||||
} |
||||
|
||||
return switch (cookieType) { |
||||
case Undergrad -> undergradCookieService.getLoginCookie(username, password); |
||||
case Graduate -> graduateCookieService.getLoginCookie(username, password); |
||||
default -> null; |
||||
}; |
||||
} |
||||
} |
@ -0,0 +1,46 @@ |
||||
package wusthelper.web.service.student; |
||||
|
||||
import cn.wustlinghang.mywust.data.global.StudentInfo; |
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
||||
import com.github.yitter.idgen.YitIdHelper; |
||||
import org.springframework.scheduling.annotation.Async; |
||||
import org.springframework.scheduling.annotation.EnableAsync; |
||||
import org.springframework.stereotype.Service; |
||||
import wusthelper.data.dao.mapper.StudentMapper; |
||||
import wusthelper.data.entity.Student; |
||||
import wusthelper.web.util.Converter; |
||||
|
||||
import java.util.concurrent.CompletableFuture; |
||||
|
||||
@Service |
||||
@EnableAsync |
||||
public class StudentService { |
||||
private final StudentMapper studentMapper; |
||||
|
||||
public StudentService(StudentMapper studentMapper) { |
||||
this.studentMapper = studentMapper; |
||||
} |
||||
|
||||
@Async |
||||
public CompletableFuture<Student> saveOrUpdateUserAsync(String username, StudentInfo studentInfo) { |
||||
var student = Converter.convert(studentInfo); |
||||
if (student.getStuNum() == null) { |
||||
student.setStuNum(username); |
||||
} |
||||
|
||||
var query = new QueryWrapper<Student>() |
||||
.eq("stuNum", username) |
||||
.eq("deleted", 0); |
||||
|
||||
// (按学号)检查用户信息是否已经存在数据库中,已存在则更新,否则新增信息
|
||||
var studentExists = studentMapper.exists(query); |
||||
if (studentExists) { |
||||
studentMapper.update(student, query); |
||||
} else { |
||||
student.setId(YitIdHelper.nextId()); |
||||
studentMapper.insert(student); |
||||
} |
||||
|
||||
return CompletableFuture.completedFuture(student); |
||||
} |
||||
} |
@ -0,0 +1,29 @@ |
||||
package wusthelper.web.util; |
||||
|
||||
import cn.wustlinghang.mywust.data.global.StudentInfo; |
||||
import wusthelper.data.entity.Student; |
||||
|
||||
public class Converter { |
||||
public static Student convert(StudentInfo studentInfo) { |
||||
Student student = new Student(); |
||||
// student.setId();
|
||||
student.setStuNum(studentInfo.getStudentNumber()); |
||||
student.setStuName(studentInfo.getName()); |
||||
// student.setJwcPwd();
|
||||
// student.setWlsyPwd();
|
||||
// student.setCollegeId();
|
||||
// student.setMajorId();
|
||||
// student.setClassId();
|
||||
student.setBirthday(studentInfo.getBirthday()); |
||||
student.setSex(studentInfo.getSex()); |
||||
student.setNation(studentInfo.getNationality()); |
||||
student.setNativePlace(studentInfo.getHometown()); |
||||
// student.setNickName();
|
||||
// student.setPhone();
|
||||
// student.setEmail();
|
||||
// student.setQqNum();
|
||||
// student.setWechatNum();
|
||||
// student.setPlatform();
|
||||
return student; |
||||
} |
||||
} |
@ -1,6 +1,6 @@ |
||||
package cn.wustlinghang.wusthelper; |
||||
package wusthelper; |
||||
|
||||
import cn.wustlinghang.wusthelper.data.dao.mapper.StudentMapper; |
||||
import 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; |
@ -1,29 +1,48 @@ |
||||
package cn.wustlinghang.wusthelper; |
||||
package wusthelper; |
||||
|
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.junit.jupiter.api.Test; |
||||
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; |
||||
import wusthelper.web.api.v2.Token; |
||||
|
||||
@Slf4j |
||||
@EnableAsync |
||||
@Configuration |
||||
@EnableScheduling |
||||
@ExtendWith(SpringExtension.class) |
||||
@EnableFeignClients(basePackages = {"cn.wustlinghang.wusthelper.web.rpc"}) |
||||
@EnableFeignClients(basePackages = {"wusthelper.web.rpc"}) |
||||
@TestPropertySource(properties = { |
||||
"spring.config.location=classpath:application-test.yml" |
||||
}) |
||||
@SpringBootApplication(scanBasePackages = { |
||||
// 指定springboot的bean扫描路径,有新增请及时更新
|
||||
"cn.wustlinghang.wusthelper.data", |
||||
"cn.wustlinghang.wusthelper.web", |
||||
"wusthelper.data", |
||||
"wusthelper.web", |
||||
}) |
||||
@MapperScan("cn.wustlinghang.wusthelper.data.dao.mapper") |
||||
public class TestMain { |
||||
@Test |
||||
public void jwtTest() { |
||||
String token = Token.signToken(1233487L, "202118194039"); |
||||
log.info(token); |
||||
} |
||||
|
||||
public static void main(String[] args) { |
||||
String token = Token.signToken(1233487L, "202118194039"); |
||||
boolean valid = Token.verifyToken(token); |
||||
var uid = Token.getUid(token); |
||||
var studentNumber = Token.getStudentNumber(token); |
||||
log.info(token); |
||||
log.info("{}", valid); |
||||
log.info(uid); |
||||
log.info(studentNumber); |
||||
} |
||||
} |
@ -1,34 +0,0 @@ |
||||
/* |
||||
* Class created by lensfrex. |
||||
*/ |
||||
|
||||
package cn.wustlinghang.wusthelper.internal.rpc.response; |
||||
|
||||
public enum RpcCommonResponseCode { |
||||
SUCCESS(20000, "成功"), |
||||
REQUEST_TOO_FAST(20001, "技能冷却中..."), |
||||
INVALID_REQUEST(30000, "非法请求"), |
||||
PARAM_WRONG(30001, "参数错误"), |
||||
PERMISSION_DENIED(40000, "权限不足"), |
||||
TOKEN_EXPIRED(40001, "token过期"), |
||||
TOKEN_INVALID(40002, "token无效"), |
||||
SERVER_INTERNAL_ERROR(50000, "服务器内部错误"), |
||||
API_NOT_IMPLEMENT(0, "接口未实现"),; |
||||
|
||||
private final int code; |
||||
|
||||
private final String message; |
||||
|
||||
RpcCommonResponseCode(int code, String message) { |
||||
this.code = code; |
||||
this.message = message; |
||||
} |
||||
|
||||
public int getCode() { |
||||
return code; |
||||
} |
||||
|
||||
public String getMessage() { |
||||
return message; |
||||
} |
||||
} |
@ -1,28 +0,0 @@ |
||||
/* |
||||
* Class created by lensfrex. |
||||
*/ |
||||
|
||||
package cn.wustlinghang.wusthelper.web.response; |
||||
|
||||
public enum ResponseCode { |
||||
SUCCESS(0, "成功"), |
||||
SERVER_INTERNAL_ERROR(-2, "服务器内部错误"), |
||||
API_NOT_IMPLEMENT(-1, "接口未实现"); |
||||
|
||||
private final int code; |
||||
|
||||
private final String message; |
||||
|
||||
ResponseCode(int code, String message) { |
||||
this.code = code; |
||||
this.message = message; |
||||
} |
||||
|
||||
public int getCode() { |
||||
return code; |
||||
} |
||||
|
||||
public String getMessage() { |
||||
return message; |
||||
} |
||||
} |
@ -0,0 +1,147 @@ |
||||
package wusthelper.code; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
public class ServiceCode { |
||||
public static final int Ok = 0; // ok
|
||||
public static final int ServerInternalError = -2; // 服务器内部错误
|
||||
public static final int ApiNotImplement = -1; // 接口未实现
|
||||
|
||||
// 所有模块共用
|
||||
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 CookieInvalid = 10_003; // 提供的cookie无效
|
||||
public static final int NetworkError = 10_004; // 网络错误
|
||||
public static final int RpcError = 10_005; // 上游RPC错误
|
||||
public static final int ParseError = 10_006; // 解析错误
|
||||
|
||||
// 主模块
|
||||
public static final int UserNotExists = 20_001; // 用户不存在
|
||||
|
||||
// 本科生
|
||||
public static final int UndergradUserNotExists = 30_001; // 本科生:用户不存在
|
||||
public static final int UndergradUserBanned = 30_002; // 本科生:封号
|
||||
public static final int UndergradUserDisabled = 30_003; // 本科生:用户账号禁用
|
||||
public static final int UndergradPasswordNeedModify = 30_004; // 本科生:用户密码需要更改
|
||||
public static final int UndergradBannedInExclusiveTime = 30_005; // 本科生:专属选课时间段账号被禁用(--> _ --)
|
||||
public static final int UndergradNeedEvaluate = 30_006; // 本科生:需要评教
|
||||
|
||||
// 研究生
|
||||
public static final int GraduatePasswordWrong = 40_001; // 研究生:密码错误
|
||||
public static final int GraduateCaptchaWrong = 40_002; // 研究生:验证码错误
|
||||
|
||||
// 图书馆
|
||||
public static final int LibraryUserNotExists = 50_001; // 图书馆:用户不存在
|
||||
public static final int LibraryUserBanned = 50_002; // 图书馆:封号
|
||||
public static final int LibraryUserDisabled = 50_003; // 图书馆:用户账号禁用
|
||||
public static final int LibraryPasswordNeedModify = 50_004; // 图书馆:用户密码需要更改
|
||||
|
||||
// 物理实验
|
||||
public static final int PhysicsPasswordWrong = 60_001; // 物理实验:用户不存在
|
||||
public static final int PhysicsUserNotCurrentTerm = 60_002; // 物理实验:用户不在当前学期
|
||||
|
||||
private static final Map<Integer, String> text = new HashMap<>(128); |
||||
|
||||
// 错误码文案
|
||||
static { |
||||
text.put(Ok, "ok"); |
||||
text.put(ServerInternalError, "服务器内部错误"); |
||||
text.put(ApiNotImplement, "接口未实现"); |
||||
|
||||
// 主模块
|
||||
text.put(UserNotExists, "用户不存在"); |
||||
|
||||
// 所有模块共用
|
||||
text.put(Unknown, "未知错误"); |
||||
text.put(RequestInvalid, "请求无效"); |
||||
text.put(CookieInvalid, "提供的cookie无效"); |
||||
text.put(NetworkError, "网络错误"); |
||||
text.put(RpcError, "上游RPC错误"); |
||||
text.put(ParseError, "解析错误"); |
||||
|
||||
// 本科生
|
||||
text.put(UndergradUserNotExists, "本科生:用户不存在"); |
||||
text.put(UndergradUserBanned, "本科生:封号"); |
||||
text.put(UndergradUserDisabled, "本科生:用户账号禁用"); |
||||
text.put(UndergradPasswordNeedModify, "本科生:用户密码需要更改"); |
||||
text.put(UndergradBannedInExclusiveTime, "本科生:专属选课时间段账号被禁用(--> _ --)"); |
||||
text.put(UndergradNeedEvaluate, "本科生:需要评教"); |
||||
|
||||
// 研究生
|
||||
text.put(GraduatePasswordWrong, "研究生:密码错误"); |
||||
text.put(GraduateCaptchaWrong, "研究生:验证码错误"); |
||||
|
||||
// 图书馆
|
||||
text.put(LibraryUserNotExists, "图书馆:用户不存在"); |
||||
text.put(LibraryUserBanned, "图书馆:封号"); |
||||
text.put(LibraryUserDisabled, "图书馆:用户账号禁用"); |
||||
text.put(LibraryPasswordNeedModify, "图书馆:用户密码需要更改"); |
||||
|
||||
// 物理实验
|
||||
text.put(PhysicsPasswordWrong, "物理实验:用户不存在"); |
||||
text.put(PhysicsUserNotCurrentTerm, "物理实验:用户不在当前学期"); |
||||
} |
||||
|
||||
private final int code; |
||||
|
||||
private final String description; |
||||
|
||||
ServiceCode(int code, String description) { |
||||
this.code = code; |
||||
this.description = description; |
||||
} |
||||
|
||||
ServiceCode(int code) { |
||||
this(code, getDescribe(code)); |
||||
} |
||||
|
||||
public int getCode() { |
||||
return code; |
||||
} |
||||
|
||||
public String getDescription() { |
||||
return description; |
||||
} |
||||
|
||||
public static String getDescribe(int code) { |
||||
return text.get(code); |
||||
} |
||||
|
||||
public static ServiceCode of(int code) { |
||||
return new ServiceCode(code); |
||||
} |
||||
//
|
||||
// public static class Code {
|
||||
// // 所有模块共用
|
||||
// public static final ErrorCode Unknown = ErrorCode.of(10_000); // 未知错误
|
||||
// public static final ErrorCode RequestInvalid = ErrorCode.of(10_001); // 请求无效
|
||||
// public static final ErrorCode CookieInvalid = ErrorCode.of(10_002); // 提供的cookie无效
|
||||
// public static final ErrorCode NetworkError = ErrorCode.of(10_003); // 网络错误
|
||||
// public static final ErrorCode RpcError = ErrorCode.of(10_004); // 上游RPC错误
|
||||
// public static final ErrorCode ParseError = ErrorCode.of(10_005); // 解析错误
|
||||
//
|
||||
// // 本科生
|
||||
// public static final ErrorCode UndergradUserNotExists = ErrorCode.of(20_001); // 本科生:用户不存在
|
||||
// public static final ErrorCode UndergradUserBanned = ErrorCode.of(20_002); // 本科生:封号
|
||||
// public static final ErrorCode UndergradUserDisabled = ErrorCode.of(20_003); // 本科生:用户账号禁用
|
||||
// public static final ErrorCode UndergradPasswordNeedModify = ErrorCode.of(20_004); // 本科生:用户密码需要更改
|
||||
// public static final ErrorCode UndergradBannedInExclusiveTime = ErrorCode.of(20_005); // 本科生:专属选课时间段账号被禁用(--> _ --)
|
||||
// public static final ErrorCode UndergradNeedEvaluate = ErrorCode.of(20_006); // 本科生:需要评教
|
||||
//
|
||||
// // 研究生
|
||||
// public static final ErrorCode GraduatePasswordWrong = ErrorCode.of(30_001); // 研究生:密码错误
|
||||
// public static final ErrorCode GraduateCaptchaWrong = ErrorCode.of(30_002); // 研究生:验证码错误
|
||||
//
|
||||
// // 图书馆
|
||||
// public static final ErrorCode LibraryUserNotExists = ErrorCode.of(40_001); // 图书馆:用户不存在
|
||||
// public static final ErrorCode LibraryUserBanned = ErrorCode.of(40_002); // 图书馆:封号
|
||||
// public static final ErrorCode LibraryUserDisabled = ErrorCode.of(40_003); // 图书馆:用户账号禁用
|
||||
// public static final ErrorCode LibraryPasswordNeedModify = ErrorCode.of(40_004); // 图书馆:用户密码需要更改
|
||||
//
|
||||
// // 物理实验
|
||||
// public static final ErrorCode PhysicsPasswordWrong = ErrorCode.of(50_001); // 物理实验:用户不存在
|
||||
// public static final ErrorCode PhysicsUserNotCurrentTerm = ErrorCode.of(50_002); // 物理实验:用户不在当前学期
|
||||
// }
|
||||
} |
@ -1,14 +1,13 @@ |
||||
package cn.wustlinghang.wusthelper.internal.rpc.exception; |
||||
package wusthelper.internal.rpc.exception; |
||||
|
||||
import java.util.StringJoiner; |
||||
|
||||
public class GraduateRpcException extends RpcException { |
||||
public static final int UNDERGRAD_MODULE = 1; |
||||
|
||||
public GraduateRpcException(TypeCode typeCode, |
||||
SubModuleCode subModuleCode, |
||||
ErrorCode errorCode) { |
||||
super(UNDERGRAD_MODULE, |
||||
super(GRADUATE_MODULE, |
||||
typeCode.ordinal(), |
||||
subModuleCode.ordinal() * 100 + errorCode.ordinal(), |
||||
new StringJoiner("/") |
@ -1,9 +1,8 @@ |
||||
package cn.wustlinghang.wusthelper.internal.rpc.exception; |
||||
package wusthelper.internal.rpc.exception; |
||||
|
||||
import java.util.StringJoiner; |
||||
|
||||
public class LibraryRpcException extends RpcException { |
||||
public static final int LIBRARY_MODULE = 3; |
||||
|
||||
public LibraryRpcException(TypeCode typeCode, |
||||
SubModuleCode subModuleCode, |
@ -1,10 +1,8 @@ |
||||
package cn.wustlinghang.wusthelper.internal.rpc.exception; |
||||
package wusthelper.internal.rpc.exception; |
||||
|
||||
import java.util.StringJoiner; |
||||
|
||||
public class PhysicsRpcException extends RpcException { |
||||
public static final int PHYSICS_MODULE = 4; |
||||
|
||||
public PhysicsRpcException(TypeCode typeCode, |
||||
SubModuleCode subModuleCode, |
||||
ErrorCode errorCode) { |
@ -0,0 +1,31 @@ |
||||
/* |
||||
* Class created by lensfrex. |
||||
*/ |
||||
|
||||
package wusthelper.internal.rpc.response; |
||||
|
||||
public enum RpcCommonResponseCode { |
||||
Success(20000, "成功"), |
||||
ParamWrong(30001, "参数错误"), |
||||
ServerInternalError(50000, "服务器内部错误"), |
||||
ApiNotImplement(0, "接口未实现"), |
||||
|
||||
; |
||||
|
||||
private final int code; |
||||
|
||||
private final String message; |
||||
|
||||
RpcCommonResponseCode(int code, String message) { |
||||
this.code = code; |
||||
this.message = message; |
||||
} |
||||
|
||||
public int getCode() { |
||||
return code; |
||||
} |
||||
|
||||
public String getMessage() { |
||||
return message; |
||||
} |
||||
} |
@ -1,4 +1,4 @@ |
||||
package cn.wustlinghang.wusthelper.internal.rpc.util; |
||||
package wusthelper.internal.rpc.util; |
||||
|
||||
public class EnumUtil { |
||||
public static <E extends Enum<E>> boolean equal(int value, Enum<E> e) { |
@ -0,0 +1,43 @@ |
||||
package wusthelper.web.exception; |
||||
|
||||
import wusthelper.code.ServiceCode; |
||||
|
||||
public class ServiceException extends RuntimeException { |
||||
private final int code; |
||||
|
||||
public ServiceException(ServiceCode code) { |
||||
this(code, code.getDescription()); |
||||
} |
||||
|
||||
public ServiceException(ServiceCode code, String message) { |
||||
super(message); |
||||
this.code = code.getCode(); |
||||
} |
||||
|
||||
public ServiceException(int code) { |
||||
this(code, ServiceCode.getDescribe(code)); |
||||
} |
||||
|
||||
public ServiceException(int code, String message) { |
||||
super(message); |
||||
this.code = code; |
||||
} |
||||
|
||||
public ServiceCode getCode() { |
||||
return ServiceCode.of(code); |
||||
} |
||||
|
||||
public int getCodeValue() { |
||||
return code; |
||||
} |
||||
|
||||
/** |
||||
* 直接按错误码抛出异常 |
||||
* |
||||
* @param code 错误码 |
||||
* @throws ServiceException . |
||||
*/ |
||||
public static void of(int code) throws ServiceException { |
||||
throw new ServiceException(code); |
||||
} |
||||
} |
@ -0,0 +1,4 @@ |
||||
package wusthelper.web.response; |
||||
|
||||
public class V2ErrorCodeConverter { |
||||
} |
@ -0,0 +1,73 @@ |
||||
package wusthelper.web.util; |
||||
|
||||
import cn.hutool.core.util.HexUtil; |
||||
import cn.hutool.crypto.Mode; |
||||
import cn.hutool.crypto.Padding; |
||||
import cn.hutool.crypto.symmetric.AES; |
||||
import cn.hutool.crypto.symmetric.SymmetricCrypto; |
||||
|
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.StringJoiner; |
||||
|
||||
/** |
||||
* 密码编解码器, |
||||
* 用aes加密而不是常规密码存储使用的hash摘要,是因为有获取明文密码的需求,毕竟登录进系统还是要明文密码的, |
||||
* 日后如果将数据获取转到客户端上进行,可以改为bcrypt存储 |
||||
*/ |
||||
public class PasswordCodec { |
||||
|
||||
private final SymmetricCrypto aes; |
||||
|
||||
public PasswordCodec(String key) { |
||||
byte[] keyBytes = normalization(key); |
||||
this.aes = new AES(Mode.ECB, Padding.PKCS5Padding, keyBytes); |
||||
} |
||||
|
||||
public PasswordCodec(byte[] key) { |
||||
this.aes = new AES(Mode.ECB, Padding.PKCS5Padding, key); |
||||
} |
||||
|
||||
private static byte[] normalization(String key) { |
||||
if (key.length() < 16) { |
||||
StringJoiner sj = new StringJoiner(key); |
||||
for (int i = 0; i < 16 - key.length(); i++) { |
||||
sj.add("a"); |
||||
} |
||||
key = sj.toString(); |
||||
} else if (key.length() > 16) { |
||||
key = key.substring(15); |
||||
} |
||||
|
||||
return key.getBytes(StandardCharsets.UTF_8); |
||||
} |
||||
|
||||
public String encode(String raw) { |
||||
if (raw == null) { |
||||
return null; |
||||
} |
||||
|
||||
byte[] data = aes.encrypt(raw.getBytes(StandardCharsets.UTF_8)); |
||||
return HexUtil.encodeHexStr(data); |
||||
} |
||||
|
||||
public String decode(String encodedHex) { |
||||
if (encodedHex == null) { |
||||
return null; |
||||
} |
||||
|
||||
byte[] data = aes.decrypt(HexUtil.decodeHex(encodedHex)); |
||||
return new String(data); |
||||
} |
||||
//
|
||||
// public static PasswordUtil getInstance(String key) {
|
||||
// if (instance == null) {
|
||||
// synchronized (PasswordUtil.class) {
|
||||
// if (instance == null) {
|
||||
// instance = new PasswordUtil(key);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return instance;
|
||||
// }
|
||||
} |
@ -1 +1 @@ |
||||
Subproject commit 736dc78d1b9e64124474cee98c5db6e8212fa096 |
||||
Subproject commit 367ddbb930b50cadbb56bd97acee05d721b9427b |
@ -1,13 +1,13 @@ |
||||
package cn.wustlinghang.wusthelper.internal.rpc; |
||||
package wusthelper.internal.rpc; |
||||
|
||||
import cn.hutool.core.thread.ThreadUtil; |
||||
import cn.hutool.core.util.RandomUtil; |
||||
import cn.wustlinghang.mywust.network.Requester; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.client.ConsulClient; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.client.FrpcClient; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.config.FrpConfig; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.config.RegisterConfig; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.entity.RegisterRequestBody; |
||||
import wusthelper.internal.rpc.client.ConsulClient; |
||||
import wusthelper.internal.rpc.client.FrpcClient; |
||||
import wusthelper.internal.rpc.config.FrpConfig; |
||||
import wusthelper.internal.rpc.config.RegisterConfig; |
||||
import wusthelper.internal.rpc.entity.RegisterRequestBody; |
||||
import com.fasterxml.jackson.databind.JsonNode; |
||||
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
import lombok.extern.slf4j.Slf4j; |
@ -1,10 +1,10 @@ |
||||
package cn.wustlinghang.wusthelper.internal.rpc.client; |
||||
package wusthelper.internal.rpc.client; |
||||
|
||||
import cn.wustlinghang.mywust.network.Requester; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpResponse; |
||||
import cn.wustlinghang.mywust.network.request.RequestFactory; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.config.RegisterConfig; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.entity.RegisterRequestBody; |
||||
import wusthelper.internal.rpc.config.RegisterConfig; |
||||
import wusthelper.internal.rpc.entity.RegisterRequestBody; |
||||
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
import com.google.common.collect.Lists; |
||||
import lombok.extern.slf4j.Slf4j; |
@ -1,10 +1,10 @@ |
||||
package cn.wustlinghang.wusthelper.internal.rpc.client; |
||||
package wusthelper.internal.rpc.client; |
||||
|
||||
import cn.hutool.core.codec.Base64; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpResponse; |
||||
import cn.wustlinghang.mywust.network.request.RequestFactory; |
||||
import cn.wustlinghang.mywust.network.Requester; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.config.FrpConfig; |
||||
import wusthelper.internal.rpc.config.FrpConfig; |
||||
import com.fasterxml.jackson.databind.JsonNode; |
||||
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
import com.fasterxml.jackson.databind.node.MissingNode; |
@ -1,4 +1,4 @@ |
||||
package cn.wustlinghang.wusthelper.internal.rpc.config; |
||||
package wusthelper.internal.rpc.config; |
||||
|
||||
import lombok.Builder; |
||||
import lombok.Data; |
@ -1,4 +1,4 @@ |
||||
package cn.wustlinghang.wusthelper.internal.rpc.config; |
||||
package wusthelper.internal.rpc.config; |
||||
|
||||
import lombok.Builder; |
||||
import lombok.Data; |
@ -1,4 +1,4 @@ |
||||
package cn.wustlinghang.wusthelper.internal.rpc.entity; |
||||
package wusthelper.internal.rpc.entity; |
||||
|
||||
import lombok.Builder; |
||||
|
@ -1,10 +1,9 @@ |
||||
package cn.wustlinghang.wusthelper.internal.graduate; |
||||
package wusthelper.internal.graduate; |
||||
|
||||
import io.quarkus.runtime.Startup; |
||||
import jakarta.annotation.PostConstruct; |
||||
import jakarta.inject.Singleton; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.eclipse.microprofile.config.inject.ConfigProperties; |
||||
import org.eclipse.microprofile.config.inject.ConfigProperty; |
||||
|
||||
@Slf4j |
@ -1,7 +1,7 @@ |
||||
package cn.wustlinghang.wusthelper.internal.physics.api.http.v1; |
||||
package wusthelper.internal.graduate.api.http.v1; |
||||
|
||||
import cn.wustlinghang.wusthelper.internal.physics.services.LoginService; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.graduate.services.LoginService; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import jakarta.ws.rs.GET; |
||||
import jakarta.ws.rs.Path; |
@ -1,8 +1,8 @@ |
||||
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1; |
||||
package wusthelper.internal.graduate.api.http.v1; |
||||
|
||||
import cn.wustlinghang.mywust.data.global.Course; |
||||
import cn.wustlinghang.wusthelper.internal.graduate.services.CourseTableService; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.graduate.services.CourseTableService; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.enterprise.context.ApplicationScoped; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import jakarta.ws.rs.GET; |
@ -1,8 +1,8 @@ |
||||
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1; |
||||
package wusthelper.internal.graduate.api.http.v1; |
||||
|
||||
import cn.wustlinghang.mywust.data.global.Score; |
||||
import cn.wustlinghang.wusthelper.internal.graduate.services.ScoreService; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.graduate.services.ScoreService; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.enterprise.context.ApplicationScoped; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import jakarta.ws.rs.GET; |
@ -1,8 +1,8 @@ |
||||
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1; |
||||
package wusthelper.internal.graduate.api.http.v1; |
||||
|
||||
import cn.wustlinghang.mywust.data.global.StudentInfo; |
||||
import cn.wustlinghang.wusthelper.internal.undergrad.services.StudentInfoService; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.graduate.services.StudentInfoService; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.enterprise.context.ApplicationScoped; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import jakarta.ws.rs.GET; |
@ -1,7 +1,7 @@ |
||||
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1; |
||||
package wusthelper.internal.graduate.api.http.v1; |
||||
|
||||
import cn.wustlinghang.wusthelper.internal.graduate.services.TrainingPlanService; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.graduate.services.TrainingPlanService; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.enterprise.context.ApplicationScoped; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import jakarta.ws.rs.GET; |
@ -1,6 +1,6 @@ |
||||
package cn.wustlinghang.wusthelper.internal.physics.api.http.v1.handler; |
||||
package wusthelper.internal.graduate.api.http.v1.handler; |
||||
|
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.ws.rs.core.Response; |
||||
import jakarta.ws.rs.ext.ExceptionMapper; |
||||
import jakarta.ws.rs.ext.Provider; |
@ -1,7 +1,7 @@ |
||||
package cn.wustlinghang.wusthelper.internal.physics.api.http.v1.interceptor; |
||||
package wusthelper.internal.graduate.api.http.v1.interceptor; |
||||
|
||||
import cn.wustlinghang.wusthelper.internal.physics.api.http.v1.handler.BaseExceptionHandler; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponseDto; |
||||
import wusthelper.internal.graduate.api.http.v1.handler.BaseExceptionHandler; |
||||
import wusthelper.internal.rpc.response.RpcResponseDto; |
||||
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
import jakarta.ws.rs.WebApplicationException; |
||||
import jakarta.ws.rs.core.HttpHeaders; |
@ -1,8 +1,7 @@ |
||||
package cn.wustlinghang.wusthelper.internal.physics.bean; |
||||
package wusthelper.internal.graduate.bean; |
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
import jakarta.enterprise.context.ApplicationScoped; |
||||
import jakarta.inject.Singleton; |
||||
|
||||
public class JacksonBean { |
||||
@ApplicationScoped |
@ -1,4 +1,4 @@ |
||||
package cn.wustlinghang.wusthelper.internal.graduate.bean; |
||||
package wusthelper.internal.graduate.bean; |
||||
|
||||
import cn.wustlinghang.mywust.core.parser.graduate.GraduateCourseTableParser; |
||||
import cn.wustlinghang.mywust.core.parser.graduate.GraduateScoreParser; |
@ -1,4 +1,4 @@ |
||||
package cn.wustlinghang.wusthelper.internal.graduate.bean; |
||||
package wusthelper.internal.graduate.bean; |
||||
|
||||
import cn.wustlinghang.mywust.core.request.service.auth.GraduateLogin; |
||||
import cn.wustlinghang.mywust.core.request.service.captcha.solver.DdddOcrCaptchaSolver; |
@ -1,10 +1,10 @@ |
||||
package cn.wustlinghang.wusthelper.internal.physics.rpc; |
||||
package wusthelper.internal.graduate.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 wusthelper.internal.graduate.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; |
@ -1,4 +1,4 @@ |
||||
package cn.wustlinghang.wusthelper.internal.physics.rpc.config; |
||||
package wusthelper.internal.graduate.rpc.config; |
||||
|
||||
import jakarta.inject.Singleton; |
||||
import jakarta.ws.rs.DefaultValue; |
@ -1,4 +1,4 @@ |
||||
package cn.wustlinghang.wusthelper.internal.physics.rpc.health; |
||||
package wusthelper.internal.graduate.rpc.health; |
||||
|
||||
import jakarta.ws.rs.GET; |
||||
import jakarta.ws.rs.Path; |
@ -1,7 +1,7 @@ |
||||
package cn.wustlinghang.wusthelper.internal.graduate.services; |
||||
package wusthelper.internal.graduate.services; |
||||
|
||||
import cn.wustlinghang.mywust.exception.ApiException; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.GraduateRpcException; |
||||
import wusthelper.internal.rpc.exception.GraduateRpcException; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
|
||||
@Slf4j |
@ -1,12 +1,12 @@ |
||||
package cn.wustlinghang.wusthelper.internal.graduate.services; |
||||
package wusthelper.internal.graduate.services; |
||||
|
||||
import cn.wustlinghang.mywust.core.parser.graduate.GraduateCourseTableParser; |
||||
import cn.wustlinghang.mywust.core.request.service.graduate.GraduateCourseTableApiService; |
||||
import cn.wustlinghang.mywust.data.global.Course; |
||||
import cn.wustlinghang.mywust.exception.ApiException; |
||||
import cn.wustlinghang.mywust.network.RequestClientOption; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.GraduateRpcException; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.rpc.exception.GraduateRpcException; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.enterprise.context.ApplicationScoped; |
||||
|
||||
import java.io.IOException; |
@ -1,9 +1,9 @@ |
||||
package cn.wustlinghang.wusthelper.internal.graduate.services; |
||||
package wusthelper.internal.graduate.services; |
||||
|
||||
import cn.wustlinghang.mywust.core.request.service.auth.GraduateLogin; |
||||
import cn.wustlinghang.mywust.exception.ApiException; |
||||
import cn.wustlinghang.mywust.network.RequestClientOption; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.GraduateRpcException; |
||||
import wusthelper.internal.rpc.exception.GraduateRpcException; |
||||
import jakarta.enterprise.context.ApplicationScoped; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.eclipse.microprofile.config.inject.ConfigProperty; |
@ -1,12 +1,12 @@ |
||||
package cn.wustlinghang.wusthelper.internal.graduate.services; |
||||
package wusthelper.internal.graduate.services; |
||||
|
||||
import cn.wustlinghang.mywust.core.parser.graduate.GraduateScoreParser; |
||||
import cn.wustlinghang.mywust.core.request.service.graduate.GraduateScoreApiService; |
||||
import cn.wustlinghang.mywust.data.global.Score; |
||||
import cn.wustlinghang.mywust.exception.ApiException; |
||||
import cn.wustlinghang.mywust.network.RequestClientOption; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.GraduateRpcException; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.rpc.exception.GraduateRpcException; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.enterprise.context.ApplicationScoped; |
||||
|
||||
import java.io.IOException; |
@ -1,12 +1,12 @@ |
||||
package cn.wustlinghang.wusthelper.internal.graduate.services; |
||||
package wusthelper.internal.graduate.services; |
||||
|
||||
import cn.wustlinghang.mywust.core.parser.graduate.GraduateStudentInfoPageParser; |
||||
import cn.wustlinghang.mywust.core.request.service.graduate.GraduateStudentInfoApiService; |
||||
import cn.wustlinghang.mywust.data.global.StudentInfo; |
||||
import cn.wustlinghang.mywust.exception.ApiException; |
||||
import cn.wustlinghang.mywust.network.RequestClientOption; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.GraduateRpcException; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.rpc.exception.GraduateRpcException; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.enterprise.context.ApplicationScoped; |
||||
|
||||
import java.io.IOException; |
@ -1,11 +1,11 @@ |
||||
package cn.wustlinghang.wusthelper.internal.graduate.services; |
||||
package wusthelper.internal.graduate.services; |
||||
|
||||
import cn.wustlinghang.mywust.core.parser.graduate.GraduateTrainingPlanPageParser; |
||||
import cn.wustlinghang.mywust.core.request.service.graduate.GraduateTrainingPlanApiService; |
||||
import cn.wustlinghang.mywust.exception.ApiException; |
||||
import cn.wustlinghang.mywust.network.RequestClientOption; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.GraduateRpcException; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.rpc.exception.GraduateRpcException; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.enterprise.context.ApplicationScoped; |
||||
|
||||
import java.io.IOException; |
@ -1,4 +1,4 @@ |
||||
package cn.wustlinghang.wusthelper.internal.library; |
||||
package wusthelper.internal.library; |
||||
|
||||
import io.quarkus.runtime.Startup; |
||||
import jakarta.annotation.PostConstruct; |
@ -1,7 +1,7 @@ |
||||
package cn.wustlinghang.wusthelper.internal.library.api.http.v1; |
||||
package wusthelper.internal.library.api.http.v1; |
||||
|
||||
import cn.wustlinghang.wusthelper.internal.library.services.BookCoverImageUrlService; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.library.services.BookCoverImageUrlService; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.enterprise.context.ApplicationScoped; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import jakarta.ws.rs.GET; |
@ -1,8 +1,8 @@ |
||||
package cn.wustlinghang.wusthelper.internal.library.api.http.v1; |
||||
package wusthelper.internal.library.api.http.v1; |
||||
|
||||
import cn.wustlinghang.mywust.data.library.parsed.BookDetail; |
||||
import cn.wustlinghang.wusthelper.internal.library.services.BookDetailService; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.library.services.BookDetailService; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.enterprise.context.ApplicationScoped; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import jakarta.ws.rs.GET; |
@ -1,8 +1,8 @@ |
||||
package cn.wustlinghang.wusthelper.internal.library.api.http.v1; |
||||
package wusthelper.internal.library.api.http.v1; |
||||
|
||||
import cn.wustlinghang.mywust.data.library.parsed.BookHolding; |
||||
import cn.wustlinghang.wusthelper.internal.library.services.BookHoldingService; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.library.services.BookHoldingService; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.enterprise.context.ApplicationScoped; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import jakarta.ws.rs.GET; |
@ -1,7 +1,7 @@ |
||||
package cn.wustlinghang.wusthelper.internal.library.api.http.v1; |
||||
package wusthelper.internal.library.api.http.v1; |
||||
|
||||
import cn.wustlinghang.wusthelper.internal.library.services.LoginService; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.library.services.LoginService; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import jakarta.ws.rs.GET; |
||||
import jakarta.ws.rs.Path; |
@ -1,9 +1,9 @@ |
||||
package cn.wustlinghang.wusthelper.internal.library.api.http.v1; |
||||
package wusthelper.internal.library.api.http.v1; |
||||
|
||||
import cn.wustlinghang.mywust.data.library.PagingResult; |
||||
import cn.wustlinghang.mywust.data.library.origin.CurrentLoanBook; |
||||
import cn.wustlinghang.wusthelper.internal.library.services.CurrentLoanService; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.library.services.CurrentLoanService; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.enterprise.context.ApplicationScoped; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import jakarta.ws.rs.DefaultValue; |
@ -1,9 +1,9 @@ |
||||
package cn.wustlinghang.wusthelper.internal.library.api.http.v1; |
||||
package wusthelper.internal.library.api.http.v1; |
||||
|
||||
import cn.wustlinghang.mywust.data.library.PagingResult; |
||||
import cn.wustlinghang.mywust.data.library.origin.HistoryLoanBook; |
||||
import cn.wustlinghang.wusthelper.internal.library.services.LoanHistoryService; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.library.services.LoanHistoryService; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.enterprise.context.ApplicationScoped; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import jakarta.ws.rs.DefaultValue; |
@ -1,9 +1,9 @@ |
||||
package cn.wustlinghang.wusthelper.internal.library.api.http.v1; |
||||
package wusthelper.internal.library.api.http.v1; |
||||
|
||||
import cn.wustlinghang.mywust.data.library.PagingResult; |
||||
import cn.wustlinghang.mywust.data.library.origin.BaseLoanBook; |
||||
import cn.wustlinghang.wusthelper.internal.library.services.OverdueSoonService; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.library.services.OverdueSoonService; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.enterprise.context.ApplicationScoped; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import jakarta.ws.rs.DefaultValue; |
@ -1,9 +1,9 @@ |
||||
package cn.wustlinghang.wusthelper.internal.library.api.http.v1; |
||||
package wusthelper.internal.library.api.http.v1; |
||||
|
||||
import cn.wustlinghang.mywust.data.library.PagingResult; |
||||
import cn.wustlinghang.mywust.data.library.origin.BookSearchResult; |
||||
import cn.wustlinghang.wusthelper.internal.library.services.SearchService; |
||||
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException; |
||||
import wusthelper.internal.library.services.SearchService; |
||||
import wusthelper.internal.rpc.exception.RpcException; |
||||
import jakarta.enterprise.context.ApplicationScoped; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import jakarta.ws.rs.DefaultValue; |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue