robert 3 years ago
parent 34c884f9fb
commit 040f9480ec

@ -0,0 +1,36 @@
*.classpath
# Package Files
*.jar
*.war
*.ear
*.log
*.iml
.DS_Store
node_modules
dist/
target/
out/
.idea/
.classpath
.project
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

@ -0,0 +1,208 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>hoj-springboot</artifactId>
<groupId>top.hcode</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>DataBackup</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 指定该Main Class为全局的唯一入口 -->
<mainClass>top.hcode.hoj.DataBackupApplication</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中-->
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
<dependencies>
<dependency>
<groupId>top.hcode</groupId>
<artifactId>api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<!--分布式配置中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<!-- 默认导入的1.1.4版本不支持鉴权-->
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.7</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- hutool工具类-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.22</version>
</dependency>
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>5.6.1</version>
</dependency>
<dependency>
<groupId>com.vdurmont</groupId>
<artifactId>emoji-java</artifactId>
<version>5.1.1</version>
</dependency>
<!--redis整合-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- jwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!--实体类 web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>net.sourceforge.htmlunit</groupId>-->
<!-- <artifactId>htmlunit</artifactId>-->
<!-- <version>2.50.0</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--生成验证码-->
<dependency>
<groupId>com.github.whvcse</groupId>
<artifactId>easy-captcha</artifactId>
<version>1.6.2</version>
</dependency>
<!--单元测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- jsoup 爬虫库 @ https://jsoup.org/ -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.13.1</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,26 @@
package top.hcode.hoj;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @Author: Himit_ZH
* @Date: 2020/10/22 23:25
* @Description:
*/
@EnableRetry
@EnableScheduling // 开启定时任务
@EnableDiscoveryClient // 开启注册发现
@SpringBootApplication
@EnableAsync(proxyTargetClass=true) //开启异步注解
@EnableTransactionManagement
public class DataBackupApplication {
public static void main(String[] args) {
SpringApplication.run(DataBackupApplication.class,args);
}
}

@ -0,0 +1,299 @@
package top.hcode.hoj.advice;
import com.google.protobuf.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.shiro.ShiroException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthenticatedException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import top.hcode.hoj.common.exception.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.common.result.ResultStatus;
import top.hcode.hoj.exception.AccessException;
import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.SQLException;
import java.util.Set;
/**
*
*/
@Slf4j(topic = "hoj")
@RestControllerAdvice
public class GlobalExceptionAdvice {
/**
* 400 - Internal Server Error
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(value = {StatusForbiddenException.class,
StatusAccessDeniedException.class,
StatusFailException.class,
StatusNotFoundException.class,
StatusSystemErrorException.class})
public CommonResult<Void> handleCustomException(Exception e) {
return CommonResult.errorResponse(e.getMessage(), ResultStatus.FAIL);
}
/**
* 401 -UnAuthorized AuthenticationException,token
*/
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler(value = AuthenticationException.class)
public CommonResult<Void> handleAuthenticationException(AuthenticationException e,
HttpServletRequest httpRequest,
HttpServletResponse httpResponse) {
httpResponse.setHeader("Url-Type", httpRequest.getHeader("Url-Type")); // 为了前端能区别请求来源
return CommonResult.errorResponse(e.getMessage(), ResultStatus.ACCESS_DENIED);
}
/**
* 401 -UnAuthorized UnauthenticatedException,token
* token访@RequiresAuthentication
*/
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler(value = UnauthenticatedException.class)
public CommonResult<Void> handleUnauthenticatedException(UnauthenticatedException e,
HttpServletRequest httpRequest,
HttpServletResponse httpResponse) {
httpResponse.setHeader("Url-Type", httpRequest.getHeader("Url-Type")); // 为了前端能区别请求来源
return CommonResult.errorResponse("请您先登录!", ResultStatus.ACCESS_DENIED);
}
/**
* 403 -FORBIDDEN AuthorizationException
*/
@ResponseStatus(HttpStatus.FORBIDDEN)
@ExceptionHandler(value = AuthorizationException.class)
public CommonResult<Void> handleAuthenticationException(AuthorizationException e,
HttpServletRequest httpRequest,
HttpServletResponse httpResponse) {
httpResponse.setHeader("Url-Type", httpRequest.getHeader("Url-Type")); // 为了前端能区别请求来源
return CommonResult.errorResponse("对不起,您无权限进行此操作!", ResultStatus.FORBIDDEN);
}
/**
* 403 -FORBIDDEN shiro controller
*/
@ResponseStatus(HttpStatus.FORBIDDEN)
@ExceptionHandler(value = ShiroException.class)
public CommonResult<Void> handleShiroException(ShiroException e,
HttpServletRequest httpRequest,
HttpServletResponse httpResponse) {
httpResponse.setHeader("Url-Type", httpRequest.getHeader("Url-Type")); // 为了前端能区别请求来源
return CommonResult.errorResponse("对不起,您无权限进行此操作,请先登录进行授权认证", ResultStatus.FORBIDDEN);
}
/**
* 403 -FORBIDDEN 访api
*/
@ResponseStatus(HttpStatus.FORBIDDEN)
@ExceptionHandler(value = AccessException.class)
public CommonResult<Void> handleAccessException(AccessException e) {
return CommonResult.errorResponse(e.getMessage(), ResultStatus.FORBIDDEN);
}
/**
* 400 - Bad Request Assert
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(value = IllegalArgumentException.class)
public CommonResult<Void> handler(IllegalArgumentException e) {
return CommonResult.errorResponse(e.getMessage(), ResultStatus.FAIL);
}
/**
* 400 - Bad Request @Validated
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public CommonResult<Void> handlerMethodArgumentNotValidException(MethodArgumentNotValidException e) throws IOException {
BindingResult bindingResult = e.getBindingResult();
ObjectError objectError = bindingResult.getAllErrors().stream().findFirst().get();
return CommonResult.errorResponse(objectError.getDefaultMessage(), ResultStatus.FAIL);
}
/**
* 400 - Bad Request
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MissingServletRequestParameterException.class)
public CommonResult<Void> handleMissingServletRequestParameterException(
MissingServletRequestParameterException e) {
return CommonResult.errorResponse("The required request parameters are missing" + e.getMessage(), ResultStatus.FAIL);
}
/**
* 400 - Bad Request
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMessageNotReadableException.class)
public CommonResult<Void> handleHttpMessageNotReadableException(
HttpMessageNotReadableException e) {
return CommonResult.errorResponse("Failed to parse parameter format!", ResultStatus.FAIL);
}
/**
* 400 - Bad Request
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(BindException.class)
public CommonResult<Void> handleBindException(BindException e) {
BindingResult result = e.getBindingResult();
FieldError error = result.getFieldError();
String field = error.getField();
String code = error.getDefaultMessage();
String message = String.format("%s:%s", field, code);
return CommonResult.errorResponse(message, ResultStatus.FAIL);
}
/**
* 400 - Bad Request
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(ConstraintViolationException.class)
public CommonResult<Void> handleServiceException(ConstraintViolationException e) {
Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
ConstraintViolation<?> violation = violations.iterator().next();
String message = violation.getMessage();
return CommonResult.errorResponse("[参数验证失败]parameter:" + message, ResultStatus.FAIL);
}
/**
* 400 - Bad Request
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(ValidationException.class)
public CommonResult<Void> handleValidationException(ValidationException e) {
return CommonResult.errorResponse("Entity verification failed. The request parameters are incorrect!", ResultStatus.FAIL);
}
/**
* 405 - Method Not Allowed
*/
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public CommonResult<Void> handleHttpRequestMethodNotSupportedException(
HttpRequestMethodNotSupportedException e) {
return CommonResult.errorResponse("The request method is not supported!", ResultStatus.FAIL);
}
/**
* 415 - Unsupported Media Type
*/
@ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
public CommonResult<Void> handleHttpMediaTypeNotSupportedException(Exception e) {
return CommonResult.errorResponse("The media type is not supported!", ResultStatus.FAIL);
}
/**
* 500 - Internal Server Error
*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(value = MessagingException.class)
public CommonResult<Void> handler(MessagingException e) {
log.error("邮箱系统异常-------------->{}", getMessage(e));
return CommonResult.errorResponse("Server Error! Please try Again later!", ResultStatus.SYSTEM_ERROR);
}
/**
* 500 - Internal Server Error
*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(ServiceException.class)
public CommonResult<Void> handleServiceException(ServiceException e) {
log.error("业务逻辑异常-------------->{}", getMessage(e));
return CommonResult.errorResponse("Server Error! Please try Again later!", ResultStatus.SYSTEM_ERROR);
}
/**
* 500 - Internal Server Error :
*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(DataIntegrityViolationException.class)
public CommonResult<Void> handleDataIntegrityViolationException(DataIntegrityViolationException e) {
log.error("操作数据库出现异常-------------->{}", getMessage(e));
return CommonResult.errorResponse("Server Error! Please try Again later!", ResultStatus.SYSTEM_ERROR);
}
/**
* 500 - Internal Server Error
*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(SQLException.class)
public CommonResult<Void> handleSQLException(SQLException e) {
log.error("操作数据库出现异常-------------->{}", getMessage(e));
return CommonResult.errorResponse("Operation failed! Error message: " + e.getMessage(), ResultStatus.SYSTEM_ERROR);
}
/**
* 500 - Internal Server Error :
*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(PersistenceException.class)
public CommonResult<Void> handleBatchUpdateException(PersistenceException e) {
log.error("操作数据库出现异常-------------->{}", getMessage(e));
return CommonResult.errorResponse("请检查数据是否准确!可能原因:数据库中已有相同的数据导致重复冲突!", ResultStatus.SYSTEM_ERROR);
}
/**
* 500 - Internal Server Error
*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Exception.class)
public CommonResult<Void> handleException(Exception e) {
log.error("系统通用异常-------------->{}", getMessage(e));
return CommonResult.errorResponse("Server Error!", ResultStatus.SYSTEM_ERROR);
}
/**
*
*/
public static String getMessage(Exception e) {
String swStr = null;
try (StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw)) {
e.printStackTrace(pw);
pw.flush();
sw.flush();
swStr = sw.toString();
} catch (IOException ex) {
ex.printStackTrace();
log.error(ex.getMessage());
}
return swStr;
}
}

@ -0,0 +1,16 @@
package top.hcode.hoj.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Author Himit_ZH
* @Date 2022/5/9
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface HOJAccess {
HOJAccessEnum[] value() default {};
}

@ -0,0 +1,42 @@
package top.hcode.hoj.annotation;
/**
* @Author Himit_ZH
* @Date 2022/5/9
*/
public enum HOJAccessEnum {
/**
*
*/
PUBLIC_DISCUSSION,
/**
*
*/
GROUP_DISCUSSION,
/**
*
*/
CONTEST_COMMENT,
/**
*
*/
PUBLIC_JUDGE,
/**
*
*/
GROUP_JUDGE,
/**
*
*/
CONTEST_JUDGE,
/**
*
*/
HIDE_NON_CONTEST_SUBMISSION_CODE
}

@ -0,0 +1,28 @@
package top.hcode.hoj.common.exception;
/**
* @Author: Himit_ZH
* @Date: 2022/3/9 10:30
* @Description:
*/
public class StatusAccessDeniedException extends Exception {
public StatusAccessDeniedException() {
}
public StatusAccessDeniedException(String message) {
super(message);
}
public StatusAccessDeniedException(String message, Throwable cause) {
super(message, cause);
}
public StatusAccessDeniedException(Throwable cause) {
super(cause);
}
public StatusAccessDeniedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

@ -0,0 +1,27 @@
package top.hcode.hoj.common.exception;
/**
* @Author: Himit_ZH
* @Date: 2022/3/9 10:27
* @Description:
*/
public class StatusFailException extends Exception{
public StatusFailException() {
}
public StatusFailException(String message) {
super(message);
}
public StatusFailException(String message, Throwable cause) {
super(message, cause);
}
public StatusFailException(Throwable cause) {
super(cause);
}
public StatusFailException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

@ -0,0 +1,28 @@
package top.hcode.hoj.common.exception;
/**
* @Author: Himit_ZH
* @Date: 2022/3/9 10:29
* @Description:
*/
public class StatusForbiddenException extends Exception{
public StatusForbiddenException() {
}
public StatusForbiddenException(String message) {
super(message);
}
public StatusForbiddenException(String message, Throwable cause) {
super(message, cause);
}
public StatusForbiddenException(Throwable cause) {
super(cause);
}
public StatusForbiddenException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

@ -0,0 +1,28 @@
package top.hcode.hoj.common.exception;
/**
* @Author: Himit_ZH
* @Date: 2022/3/9 10:30
* @Description:
*/
public class StatusNotFoundException extends Exception{
public StatusNotFoundException() {
}
public StatusNotFoundException(String message) {
super(message);
}
public StatusNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public StatusNotFoundException(Throwable cause) {
super(cause);
}
public StatusNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

@ -0,0 +1,28 @@
package top.hcode.hoj.common.exception;
/**
* @Author: Himit_ZH
* @Date: 2022/3/10 14:33
* @Description:
*/
public class StatusSystemErrorException extends Exception {
public StatusSystemErrorException() {
}
public StatusSystemErrorException(String message) {
super(message);
}
public StatusSystemErrorException(String message, Throwable cause) {
super(message, cause);
}
public StatusSystemErrorException(Throwable cause) {
super(cause);
}
public StatusSystemErrorException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

@ -0,0 +1,73 @@
package top.hcode.hoj.common.result;
import lombok.Data;
@Data
public class CommonResult<T>{
private final Integer status; // 状态码
private final T data; // 返回的数据
private final String msg; // 自定义信息
/**
*
*
* @param data
* @param msg
*/
public static <T> CommonResult<T> successResponse(T data, String msg) {
return new CommonResult<>(ResultStatus.SUCCESS.getStatus(), data, msg);
}
/**
*
*
* @param data
*/
public static <T> CommonResult<T> successResponse(T data) {
return new CommonResult<T>(ResultStatus.SUCCESS.getStatus(), data, "success");
}
/**
*
*
* @param msg
*/
public static <T> CommonResult<T> successResponse(String msg) {
return new CommonResult<T>(ResultStatus.SUCCESS.getStatus(), null, msg);
}
/**
*
*/
public static <T> CommonResult<T> successResponse() {
return new CommonResult<T>(ResultStatus.SUCCESS.getStatus(), null, "success");
}
/**
*
*
* @param msg
*/
public static <T> CommonResult<T> errorResponse(String msg) {
return new CommonResult<T>(ResultStatus.FAIL.getStatus(), null, msg);
}
public static <T> CommonResult<T> errorResponse(ResultStatus resultStatus) {
return new CommonResult<T>(resultStatus.getStatus(), null, resultStatus.getDescription());
}
public static <T> CommonResult<T> errorResponse(String msg, ResultStatus resultStatus) {
return new CommonResult<T>(resultStatus.getStatus(), null, msg);
}
public static <T> CommonResult<T> errorResponse(String msg, Integer status) {
return new CommonResult<T>(status, null, msg);
}
}

@ -0,0 +1,31 @@
package top.hcode.hoj.common.result;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Author: Himit_ZH
* @Date: 2022/3/9 15:17
* @Description:
*/
@Getter
@AllArgsConstructor
public enum ResultStatus {
SUCCESS(200,"成功"),
FAIL(400,"失败"),
ACCESS_DENIED(401,"访问受限"),
FORBIDDEN(403,"拒绝访问"),
NOT_FOUND(404,"数据不存在"),
SYSTEM_ERROR(500,"系统错误");
private int status;
private String description;
}

@ -0,0 +1,62 @@
package top.hcode.hoj.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.lang.reflect.Method;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @Author: Himit_ZH
* @Date: 2020/11/6 23:36
* @Description: 线
*/
@Configuration
@Slf4j(topic = "hoj")
public class AsyncTaskConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
// 线程池维护线程的最少数量
taskExecutor.setCorePoolSize(10);
// 线程池维护线程的最大数量
taskExecutor.setMaxPoolSize(20);
// 缓存队列
taskExecutor.setQueueCapacity(200);
//活跃时间
taskExecutor.setKeepAliveSeconds(3);
// 对拒绝task的处理策略
//(1) 默认的ThreadPoolExecutor.AbortPolicy 处理程序遭到拒绝将抛出运行时RejectedExecutionException;
//(2) ThreadPoolExecutor.CallerRunsPolicy 线程调用运行该任务的 execute 本身。此策略提供简单的反馈控制机制,能够减缓新任务的提交速度
//(3) ThreadPoolExecutor.DiscardPolicy 不能执行的任务将被删除;
//(4) ThreadPoolExecutor.DiscardOldestPolicy 如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行程序(如果再次失败,则重复此过程)
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 线程名前缀,方便排查问题
taskExecutor.setThreadNamePrefix("CommonThread-");
// 注意一定要初始化
taskExecutor.initialize();
return taskExecutor;
}
/**
*
* @return
*/
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncUncaughtExceptionHandler() {
@Override
public void handleUncaughtException(Throwable arg0, Method arg1, Object... arg2) {
log.error("==========================" + arg0.getMessage() + "=======================", arg0);
log.error("exception method:" + arg1.getName());
}
};
}
}

@ -0,0 +1,27 @@
package top.hcode.hoj.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
/**
* @Author Himit_ZH
* @Date 2022/6/15
*/
@Component
@RefreshScope
@ConfigurationProperties(prefix = "hoj.db")
@Data
public class DataSourceConfigure {
private String username;
private String password;
private String host;
private Integer port;
private String name;
}

@ -0,0 +1,130 @@
package top.hcode.hoj.config;
import com.alibaba.druid.pool.DruidDataSource;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Optional;
/**
* @Author: Himit_ZH
* @Date: 2021/5/21 17:57
* @Description:
*/
@Configuration
@RefreshScope
@Data
@Slf4j(topic = "hoj")
public class DruidConfigure {
@Value("${mysql-username}")
private String username;
@Value("${mysql-password}")
private String password;
@Value("${mysql-host}")
private String host;
@Value("${mysql-port}")
private Integer port;
@Value("${mysql-name}")
private String name;
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Value("${spring.datasource.type}")
private String type;
@Value("${spring.datasource.initial-size}")
private Integer initialSize;
@Value("${spring.datasource.poolPreparedStatements:true}")
private Boolean poolPreparedStatements;
@Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize:20}")
private Integer maxPoolPreparedStatementPerConnectionSize;
@Value("${spring.datasource.timeBetweenEvictionRunsMillis:60000}")
private Integer timeBetweenEvictionRunsMillis;
@Value("${spring.datasource.minEvictableIdleTimeMillis:300000}")
private Integer minEvictableIdleTimeMillis;
@Value("${spring.datasource.validationQuery}")
private String validationQuery;
@Value("${spring.datasource.testWhileIdle:true}")
private Boolean testWhileIdle;
@Value("${spring.datasource.testOnBorrow:false}")
private Boolean testOnBorrow;
@Value("${spring.datasource.testOnReturn:false}")
private Boolean testOnReturn;
@Value("${spring.datasource.connectionErrorRetryAttempts:3}")
private Integer connectionErrorRetryAttempts;
@Value("${spring.datasource.breakAfterAcquireFailure:true}")
private Boolean breakAfterAcquireFailure;
@Value("${spring.datasource.timeBetweenConnectErrorMillis:300000}")
private Integer timeBetweenConnectErrorMillis;
@Value("${spring.datasource.min-idle}")
private Integer minIdle;
@Value("${spring.datasource.maxActive}")
private Integer maxActive;
@Value("${spring.datasource.maxWait}")
private Integer maxWait;
@Autowired
private DataSourceConfigure dataSourceConfigure;
@Bean(name = "datasource")
@RefreshScope
public DruidDataSource dataSource(){
String mysqlHost = Optional.ofNullable(dataSourceConfigure.getHost()).orElseGet(() -> host);
Integer mysqlPort = Optional.ofNullable(dataSourceConfigure.getPort()).orElseGet(() -> port);
String mysqlName = Optional.ofNullable(dataSourceConfigure.getName()).orElseGet(() -> name);
String mysqlUsername = Optional.ofNullable(dataSourceConfigure.getUsername()).orElseGet(() -> username);
String mysqlUserPassword = Optional.ofNullable(dataSourceConfigure.getPassword()).orElseGet(() -> password);
log.warn("[MySQL] [Config Change] name:[{}], host:[{}], port:[{}], username:[{}], password:[{}]", mysqlName, mysqlHost, mysqlPort, mysqlUsername, mysqlUserPassword);
DruidDataSource datasource = new DruidDataSource();
String url = "jdbc:mysql://" + mysqlHost + ":" + mysqlPort + "/" + mysqlName + "?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true";
datasource.setUrl(url);
datasource.setUsername(mysqlUsername);
datasource.setPassword(mysqlUserPassword);
datasource.setDriverClassName(driverClassName);
datasource.setDbType(type);
datasource.setMaxActive(maxActive);
datasource.setInitialSize(initialSize);
datasource.setMinIdle(minIdle);
datasource.setMaxWait(maxWait);
datasource.setPoolPreparedStatements(poolPreparedStatements);
datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setValidationQuery(validationQuery);
datasource.setTestWhileIdle(testWhileIdle);
datasource.setTestOnReturn(testOnReturn);
datasource.setTestOnBorrow(testOnBorrow);
datasource.setConnectionErrorRetryAttempts(connectionErrorRetryAttempts);
datasource.setBreakAfterAcquireFailure(breakAfterAcquireFailure);
datasource.setTimeBetweenConnectErrorMillis(timeBetweenConnectErrorMillis);
return datasource;
}
}

@ -0,0 +1,22 @@
package top.hcode.hoj.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
/**
* @Author Himit_ZH
* @Date 2022/6/15
*/
@Component
@RefreshScope
@ConfigurationProperties(prefix = "hoj.redis")
@Data
public class JedisPoolConfigure {
private String host;
private Integer port;
private String password;
}

@ -0,0 +1,39 @@
package top.hcode.hoj.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @Author: Himit_ZH
* @Date: 2021/5/24 16:54
* @Description: 线
*/
@Configuration
@EnableAsync
public class JudgeAsyncTaskConfig {
@Bean
public Executor judgeTaskAsyncPool() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核心线程池大小
executor.setCorePoolSize(2);
//最大线程数
executor.setMaxPoolSize(10);
//队列容量
executor.setQueueCapacity(500);
//活跃时间
executor.setKeepAliveSeconds(3);
//线程名字前缀
executor.setThreadNamePrefix("JudgeExecutor-");
// setRejectedExecutionHandler当pool已经达到max size的时候如何处理新任务
// CallerRunsPolicy不在新线程中执行任务而是由调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}

@ -0,0 +1,26 @@
package top.hcode.hoj.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* @Author: Himit_ZH
* @Date: 2020/12/4 14:14
* @Description: mybatis-plus
*/
@Component
public class MyMetaObjectConfig implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("gmtCreate",new Date(),metaObject);
this.setFieldValByName("gmtModified",new Date(),metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("gmtModified", new Date(), metaObject);
}
}

@ -0,0 +1,31 @@
package top.hcode.hoj.config;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @Author: Himit_ZH
* @Date: 2020/7/19 21:04
* @Description:
*/
@Configuration
@EnableTransactionManagement
@MapperScan("top.hcode.hoj.mapper")
public class MybatisPlusConfig {
// 注册乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
// 分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}

@ -0,0 +1,72 @@
package top.hcode.hoj.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import redis.clients.jedis.JedisPoolConfig;
import java.util.Optional;
/**
* @Author: Himit_ZH
* @Date: 2021/5/21 15:53
* @Description:
*/
@Configuration
public class RedisAutoConfig {
@Value("${spring.redis.jedis.pool.max-active:200}")
private Integer maxActive;
@Value("${spring.redis.jedis.pool.max-idle:50}")
private Integer maxIdle;
@Value("${spring.redis.jedis.pool.max-wait:-1}")
private Long maxWait;
@Value("${spring.redis.jedis.pool.min-idle:10}")
private Integer minIdle;
@Value("${redis-host}")
private String redisHost;
@Value("${redis-port}")
private Integer redisPort;
@Value("${redis-password}")
private String redisPassword;
@Autowired
private JedisPoolConfigure jedisPoolConfigure;
@Bean
public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPool,
RedisStandaloneConfiguration jedisConfig) {
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(jedisConfig);
connectionFactory.setPoolConfig(jedisPool);
return connectionFactory;
}
@Bean
public JedisPoolConfig jedisPool() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMaxWaitMillis(maxWait);
jedisPoolConfig.setMaxTotal(maxActive);
jedisPoolConfig.setMinIdle(minIdle);
return jedisPoolConfig;
}
@Bean
@RefreshScope
public RedisStandaloneConfiguration jedisConfig() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
config.setHostName(Optional.ofNullable(jedisPoolConfigure.getHost()).orElseGet(() -> redisHost));
config.setPort(Optional.ofNullable(jedisPoolConfigure.getPort()).orElseGet(() -> redisPort));
config.setPassword(RedisPassword.of(Optional.ofNullable(jedisPoolConfigure.getPassword()).orElseGet(() -> redisPassword)));
return config;
}
}

@ -0,0 +1,50 @@
package top.hcode.hoj.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @Author: Himit_ZH
* @Date: 2020/10/23 23:47
* @Description:
*/
@Configuration
public class RedisConfig {
// 自己定义了一个 RedisTemplate
@Bean(name = "redisTemplate")
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
// 我们为了自己开发方便,一般直接使用 <String, Object>
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
// Json序列化配置
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// String 的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}

@ -0,0 +1,30 @@
package top.hcode.hoj.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
/**
* @Author: Himit_ZH
* @Date: 2020/5/19 22:47
* @Description:
*/
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory)
{
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(600000);//单位为ms
factory.setConnectTimeout(50000);//单位为ms
return factory;
}
}

@ -0,0 +1,101 @@
package top.hcode.hoj.config;
/**
* @Author: Himit_ZH
* @Date: 2020/7/19 22:53
* @Description:
*/
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import top.hcode.hoj.shiro.AccountRealm;
import top.hcode.hoj.shiro.JwtFilter;
import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* shiro
*/
@Configuration
public class ShiroConfig {
@Autowired
JwtFilter jwtFilter;
@Bean
public SessionManager sessionManager(RedisSessionDAO redisSessionDAO) {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setSessionDAO(redisSessionDAO);
return sessionManager;
}
@Bean
public DefaultWebSecurityManager securityManager(AccountRealm accountRealm,
SessionManager sessionManager,
RedisCacheManager redisCacheManager) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(accountRealm);
securityManager.setSessionManager(sessionManager);
securityManager.setCacheManager(redisCacheManager);
/*
* shirosession
*/
DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
securityManager.setSubjectDAO(subjectDAO);
return securityManager;
}
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/**", "jwt"); // 主要通过注解方式校验权限
chainDefinition.addPathDefinitions(filterMap);
return chainDefinition;
}
@Bean("shiroFilterFactoryBean")
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager,
ShiroFilterChainDefinition shiroFilterChainDefinition) {
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
shiroFilter.setSecurityManager(securityManager);
Map<String, Filter> filters = new HashMap<>();
filters.put("jwt", jwtFilter);
shiroFilter.setFilters(filters);
Map<String, String> filterMap = shiroFilterChainDefinition.getFilterChainMap();
shiroFilter.setFilterChainDefinitionMap(filterMap);
return shiroFilter;
}
//开启注解代理(默认好像已经开启,可以不要)
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean
public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
creator.setProxyTargetClass(true);
return creator;
}
}

@ -0,0 +1,448 @@
package top.hcode.hoj.config;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import top.hcode.hoj.crawler.language.LanguageContext;
import top.hcode.hoj.dao.judge.RemoteJudgeAccountEntityService;
import top.hcode.hoj.dao.problem.LanguageEntityService;
import top.hcode.hoj.manager.admin.system.ConfigManager;
import top.hcode.hoj.pojo.entity.judge.RemoteJudgeAccount;
import top.hcode.hoj.pojo.entity.problem.Language;
import top.hcode.hoj.pojo.vo.ConfigVo;
import top.hcode.hoj.utils.Constants;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/**
* @Author: Himit_ZH
* @Date: 2021/2/19 22:11
* @Description:run
*/
@Component
@Slf4j(topic = "hoj")
public class StartupRunner implements CommandLineRunner {
@Autowired
private ConfigVo configVo;
@Autowired
private ConfigManager configManager;
@Autowired
private RemoteJudgeAccountEntityService remoteJudgeAccountEntityService;
@Autowired
private LanguageEntityService languageEntityService;
@Value("${open-remote-judge}")
private String openRemoteJudge;
// jwt配置
@Value("${jwt-token-secret}")
private String tokenSecret;
@Value("${jwt-token-expire}")
private String tokenExpire;
@Value("${jwt-token-fresh-expire}")
private String checkRefreshExpire;
// 数据库配置
@Value("${mysql-username}")
private String mysqlUsername;
@Value("${mysql-password}")
private String mysqlPassword;
@Value("${mysql-name}")
private String mysqlDBName;
@Value("${mysql-host}")
private String mysqlHost;
@Value("${mysql-public-host}")
private String mysqlPublicHost;
@Value("${mysql-port}")
private Integer mysqlPort;
@Value("${mysql-public-port}")
private Integer mysqlPublicPort;
// 缓存配置
@Value("${redis-host}")
private String redisHost;
@Value("${redis-port}")
private Integer redisPort;
@Value("${redis-password}")
private String redisPassword;
// 判题服务token
@Value("${judge-token}")
private String judgeToken;
// 邮箱配置
@Value("${email-username}")
private String emailUsername;
@Value("${email-password}")
private String emailPassword;
@Value("${email-host}")
private String emailHost;
@Value("${email-port}")
private Integer emailPort;
@Value("${hdu-username-list}")
private List<String> hduUsernameList;
@Value("${hdu-password-list}")
private List<String> hduPasswordList;
@Value("${cf-username-list}")
private List<String> cfUsernameList;
@Value("${cf-password-list}")
private List<String> cfPasswordList;
@Value("${poj-username-list}")
private List<String> pojUsernameList;
@Value("${poj-password-list}")
private List<String> pojPasswordList;
@Value("${atcoder-username-list}")
private List<String> atcoderUsernameList;
@Value("${atcoder-password-list}")
private List<String> atcoderPasswordList;
@Value("${spoj-username-list}")
private List<String> spojUsernameList;
@Value("${spoj-password-list}")
private List<String> spojPasswordList;
@Value("${forced-update-remote-judge-account}")
private Boolean forcedUpdateRemoteJudgeAccount;
@Override
public void run(String... args) throws Exception {
// 动态修改nacos上的配置文件
if (judgeToken.equals("default")) {
configVo.setJudgeToken(IdUtil.fastSimpleUUID());
} else {
configVo.setJudgeToken(judgeToken);
}
if (tokenSecret.equals("default")) {
configVo.setTokenSecret(IdUtil.fastSimpleUUID());
} else {
configVo.setTokenSecret(tokenSecret);
}
configVo.setTokenExpire(tokenExpire);
configVo.setCheckRefreshExpire(checkRefreshExpire);
configVo.setMysqlUsername(mysqlUsername);
configVo.setMysqlPassword(mysqlPassword);
configVo.setMysqlHost(mysqlHost);
configVo.setMysqlPublicHost(mysqlPublicHost);
configVo.setMysqlPort(mysqlPort);
configVo.setMysqlPublicPort(mysqlPublicPort);
configVo.setMysqlDBName(mysqlDBName);
configVo.setRedisHost(redisHost);
configVo.setRedisPort(redisPort);
configVo.setRedisPassword(redisPassword);
if (configVo.getEmailHost() == null || !"your_email_host".equals(emailHost)) {
configVo.setEmailHost(emailHost);
}
if (configVo.getEmailPort() == null || emailPort != 456) {
configVo.setEmailPort(emailPort);
}
if (configVo.getEmailUsername() == null || !"your_email_username".equals(emailUsername)) {
configVo.setEmailUsername(emailUsername);
}
if (configVo.getEmailPassword() == null || !"your_email_password".equals(emailPassword)) {
configVo.setEmailPassword(emailPassword);
}
if (CollectionUtils.isEmpty(configVo.getHduUsernameList()) || forcedUpdateRemoteJudgeAccount) {
configVo.setHduUsernameList(hduUsernameList);
}else {
hduUsernameList = configVo.getHduUsernameList();
}
if (CollectionUtils.isEmpty(configVo.getHduPasswordList()) || forcedUpdateRemoteJudgeAccount) {
configVo.setHduPasswordList(hduPasswordList);
}else {
hduPasswordList = configVo.getHduPasswordList();
}
if (CollectionUtils.isEmpty(configVo.getCfUsernameList()) || forcedUpdateRemoteJudgeAccount) {
configVo.setCfUsernameList(cfUsernameList);
}else {
cfUsernameList = configVo.getCfUsernameList();
}
if (CollectionUtils.isEmpty(configVo.getCfPasswordList()) || forcedUpdateRemoteJudgeAccount) {
configVo.setCfPasswordList(cfPasswordList);
}else {
cfPasswordList = configVo.getCfPasswordList();
}
if (CollectionUtils.isEmpty(configVo.getPojUsernameList()) || forcedUpdateRemoteJudgeAccount) {
configVo.setPojUsernameList(pojUsernameList);
}else {
pojUsernameList = configVo.getPojUsernameList();
}
if (CollectionUtils.isEmpty(configVo.getPojPasswordList()) || forcedUpdateRemoteJudgeAccount) {
configVo.setPojPasswordList(pojPasswordList);
}else {
pojPasswordList = configVo.getPojPasswordList();
}
if (CollectionUtils.isEmpty(configVo.getAtcoderUsernameList()) || forcedUpdateRemoteJudgeAccount) {
configVo.setAtcoderUsernameList(atcoderUsernameList);
}else {
atcoderUsernameList = configVo.getAtcoderUsernameList();
}
if (CollectionUtils.isEmpty(configVo.getAtcoderPasswordList()) || forcedUpdateRemoteJudgeAccount) {
configVo.setAtcoderPasswordList(atcoderPasswordList);
}else {
atcoderPasswordList = configVo.getAtcoderPasswordList();
}
if (CollectionUtils.isEmpty(configVo.getSpojUsernameList()) || forcedUpdateRemoteJudgeAccount) {
configVo.setSpojUsernameList(spojUsernameList);
}else {
spojUsernameList = configVo.getSpojUsernameList();
}
if (CollectionUtils.isEmpty(configVo.getSpojPasswordList()) || forcedUpdateRemoteJudgeAccount) {
configVo.setSpojPasswordList(spojPasswordList);
}else {
spojPasswordList = configVo.getSpojPasswordList();
}
configManager.sendNewConfigToNacos();
upsertHOJLanguage("PHP", "PyPy2", "PyPy3", "JavaScript Node", "JavaScript V8");
checkAllLanguageUpdate();
if (openRemoteJudge.equals("true")) {
// 初始化清空表
remoteJudgeAccountEntityService.remove(new QueryWrapper<>());
addRemoteJudgeAccountToMySQL(Constants.RemoteOJ.HDU.getName(), hduUsernameList, hduPasswordList);
addRemoteJudgeAccountToMySQL(Constants.RemoteOJ.POJ.getName(), pojUsernameList, pojPasswordList);
addRemoteJudgeAccountToMySQL(Constants.RemoteOJ.CODEFORCES.getName(), cfUsernameList, cfPasswordList);
addRemoteJudgeAccountToMySQL(Constants.RemoteOJ.SPOJ.getName(), spojUsernameList, spojPasswordList);
addRemoteJudgeAccountToMySQL(Constants.RemoteOJ.ATCODER.getName(), atcoderUsernameList, atcoderPasswordList);
checkRemoteOJLanguage(Constants.RemoteOJ.SPOJ, Constants.RemoteOJ.ATCODER);
}
}
/**
* @param oj
* @param usernameList
* @param passwordList
* @MethodName addRemoteJudgeAccountToRedis
* @Description ojmysql
* @Return
* @Since 2021/5/18
*/
private void addRemoteJudgeAccountToMySQL(String oj, List<String> usernameList, List<String> passwordList) {
if (CollectionUtils.isEmpty(usernameList) || CollectionUtils.isEmpty(passwordList) || usernameList.size() != passwordList.size()) {
log.error("[Init System Config] [{}]: There is no account or password configured for remote judge, " +
"username list:{}, password list:{}", oj, Arrays.toString(usernameList.toArray()),
Arrays.toString(passwordList.toArray()));
}
List<RemoteJudgeAccount> remoteAccountList = new LinkedList<>();
for (int i = 0; i < usernameList.size(); i++) {
remoteAccountList.add(new RemoteJudgeAccount()
.setUsername(usernameList.get(i))
.setPassword(passwordList.get(i))
.setStatus(true)
.setVersion(0L)
.setOj(oj));
}
if (remoteAccountList.size() > 0) {
boolean addOk = remoteJudgeAccountEntityService.saveOrUpdateBatch(remoteAccountList);
if (!addOk) {
log.error("[Init System Config] Remote judge initialization failed. Failed to add account for: [{}]. Please check the configuration file and restart!", oj);
}
}
}
private void upsertHOJLanguage(String... languageList) {
/**
* 2022.02.25 jspypyphp
*/
for (String language : languageList) {
QueryWrapper<Language> languageQueryWrapper = new QueryWrapper<>();
languageQueryWrapper.eq("oj", "ME")
.eq("name", language);
int count = languageEntityService.count(languageQueryWrapper);
if (count == 0) {
Language newLanguage = buildHOJLanguage(language);
boolean isOk = languageEntityService.save(newLanguage);
if (!isOk) {
log.error("[Init System Config] [HOJ] Failed to add new language [{}]! Please check whether the language table corresponding to the database has the language!", language);
}
}
}
}
private void checkAllLanguageUpdate() {
/**
* 2022.02.25 python3.6.9python3.7.5
*/
UpdateWrapper<Language> languageUpdateWrapper = new UpdateWrapper<>();
languageUpdateWrapper.eq("oj", "ME")
.eq("name", "Python3")
.set("description", "Python 3.7.5");
languageEntityService.update(languageUpdateWrapper);
/**
* 2022.02.25 cfMicrosoft Visual C++ 2010
*/
UpdateWrapper<Language> deleteWrapper = new UpdateWrapper<>();
deleteWrapper.eq("name", "Microsoft Visual C++ 2010")
.eq("oj", "CF");
languageEntityService.remove(deleteWrapper);
}
private void checkRemoteOJLanguage(Constants.RemoteOJ... remoteOJList) {
for (Constants.RemoteOJ remoteOJ : remoteOJList) {
QueryWrapper<Language> languageQueryWrapper = new QueryWrapper<>();
languageQueryWrapper.eq("oj", remoteOJ.getName());
int count = languageEntityService.count(languageQueryWrapper);
if (count == 0) {
List<Language> languageList = new LanguageContext(remoteOJ).buildLanguageList();
boolean isOk = languageEntityService.saveBatch(languageList);
if (!isOk) {
log.error("[Init System Config] [{}] Failed to initialize language list! Please check whether the language table corresponding to the database has the OJ language!", remoteOJ.getName());
}
}
}
}
private Language buildHOJLanguage(String lang) {
Language language = new Language();
switch (lang) {
case "PHP":
language.setName("PHP")
.setCompileCommand("/usr/bin/php {src_path}")
.setContentType("text/x-php")
.setDescription("PHP 7.3.33")
.setTemplate("<?=array_sum(fscanf(STDIN, \"%d %d\"));")
.setIsSpj(false)
.setOj("ME");
return language;
case "JavaScript Node":
language.setName("JavaScript Node")
.setCompileCommand("/usr/bin/node {src_path}")
.setContentType("text/javascript")
.setDescription("Node.js 14.19.0")
.setTemplate("var readline = require('readline');\n" +
"const rl = readline.createInterface({\n" +
" input: process.stdin,\n" +
" output: process.stdout\n" +
"});\n" +
"rl.on('line', function(line){\n" +
" var tokens = line.split(' ');\n" +
" console.log(parseInt(tokens[0]) + parseInt(tokens[1]));\n" +
"});")
.setIsSpj(false)
.setOj("ME");
return language;
case "JavaScript V8":
language.setName("JavaScript V8")
.setCompileCommand("/usr/bin/jsv8/d8 {src_path}")
.setContentType("text/javascript")
.setDescription("JavaScript V8 8.4.109")
.setTemplate("const [a, b] = readline().split(' ').map(n => parseInt(n, 10));\n" +
"print((a + b).toString());")
.setIsSpj(false)
.setOj("ME");
return language;
case "PyPy2":
language.setName("PyPy2")
.setContentType("text/x-python")
.setCompileCommand("/usr/bin/pypy -m py_compile {src_path}")
.setDescription("PyPy 2.7.18 (7.3.8)")
.setTemplate("print sum(int(x) for x in raw_input().split(' '))")
.setCodeTemplate("//PREPEND BEGIN\n" +
"//PREPEND END\n" +
"\n" +
"//TEMPLATE BEGIN\n" +
"def add(a, b):\n" +
" return a + b\n" +
"//TEMPLATE END\n" +
"\n" +
"\n" +
"if __name__ == '__main__': \n" +
" //APPEND BEGIN\n" +
" a, b = 1, 1\n" +
" print add(a, b)\n" +
" //APPEND END")
.setIsSpj(false)
.setOj("ME");
return language;
case "PyPy3":
language.setName("PyPy3")
.setContentType("text/x-python")
.setDescription("PyPy 3.8.12 (7.3.8)")
.setCompileCommand("/usr/bin/pypy3 -m py_compile {src_path}")
.setTemplate("print(sum(int(x) for x in input().split(' ')))")
.setCodeTemplate("//PREPEND BEGIN\n" +
"//PREPEND END\n" +
"\n" +
"//TEMPLATE BEGIN\n" +
"def add(a, b):\n" +
" return a + b\n" +
"//TEMPLATE END\n" +
"\n" +
"\n" +
"if __name__ == '__main__': \n" +
" //APPEND BEGIN\n" +
" a, b = 1, 1\n" +
" print(add(a, b))\n" +
" //APPEND END")
.setIsSpj(false)
.setOj("ME");
return language;
}
return null;
}
}

@ -0,0 +1,56 @@
package top.hcode.hoj.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
/**
* @Author: Himit_ZH
* @Date: 2020/5/29 22:28
* @Description:
*/
//@Configuration
//@EnableSwagger2 //开启swagger2
public class SwaggerConfig {
@Bean //配置swagger的docket的bean势力
public Docket docket(Environment environment){
//设置要显示的swagger环境
Profiles profiles = Profiles.of("dev","test"); //线下环境
//通过环境判断是否在自己所设定的环境当中
boolean flag = environment.acceptsProfiles(profiles);
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.groupName("Himit_ZH") //分组
.enable(flag) //开启
.select()
//RequestHandlerSelectors扫描方式
//any()全部
//none 都不扫描
//path 过滤什么路径
.apis(RequestHandlerSelectors.basePackage("top.hcode"))
.build();
}
//配置swagger信息
private ApiInfo apiInfo(){
//作者信息
Contact contact = new Contact("Himit_ZH", "https://blog.csdn.net/weixin_43853097", "372347736@qq.com");
return new ApiInfo(
"Himit_ZH的swaggerAPI文档",
"网站作者是个大帅哥!",
"v1.0",
"https://blog.csdn.net/weixin_43853097",
contact,
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList());
}
}

@ -0,0 +1,30 @@
package top.hcode.hoj.config;
import org.apache.catalina.connector.Connector;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author Himit_ZH
* @Date 2022/6/11
* [] \
*/
@Configuration
public class TomcatConfig {
@Bean
public TomcatServletWebServerFactory webServerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
@Override
public void customize(Connector connector) {
connector.setProperty("relaxedPathChars", "\"<>[\\]^`{|}");
connector.setProperty("relaxedQueryChars", "\"<>[\\]^`{|}");
connector.setProperty("rejectIllegalHeader", "false");
}
});
return factory;
}
}

@ -0,0 +1,56 @@
package top.hcode.hoj.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import top.hcode.hoj.interceptor.AccessInterceptor;
import top.hcode.hoj.utils.Constants;
import java.io.File;
/**
*
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
private static final String[] EXCLUDE_PATH_PATTERNS = new String[]{
"/api/admin/**", "/api/file/**", "/api/msg/**", "/api/public/**"
};
@Autowired
private AccessInterceptor accessInterceptor;
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
.allowCredentials(true)
.maxAge(3600)
.allowedHeaders("*");
}
// 前端直接通过/public/img/图片名称即可拿到
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// /api/public/img/** /api/public/file/**
registry.addResourceHandler(Constants.File.IMG_API.getPath() + "**", Constants.File.FILE_API.getPath() + "**")
.addResourceLocations("file:" + Constants.File.USER_AVATAR_FOLDER.getPath() + File.separator,
"file:" + Constants.File.GROUP_AVATAR_FOLDER.getPath() + File.separator,
"file:" + Constants.File.MARKDOWN_FILE_FOLDER.getPath() + File.separator,
"file:" + Constants.File.HOME_CAROUSEL_FOLDER.getPath() + File.separator,
"file:" + Constants.File.PROBLEM_FILE_FOLDER.getPath() + File.separator);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(accessInterceptor)
.addPathPatterns("/api/**")
.excludePathPatterns(EXCLUDE_PATH_PATTERNS);
}
}

@ -0,0 +1,42 @@
package top.hcode.hoj.controller.admin;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.LoginDto;
import top.hcode.hoj.pojo.vo.UserInfoVo;
import top.hcode.hoj.service.admin.account.AdminAccountService;
/**
* @Author: Himit_ZH
* @Date: 2020/12/2 21:23
* @Description:
*/
@RestController
@RequestMapping("/api/admin")
public class AdminAccountController {
@Autowired
private AdminAccountService adminAccountService;
@PostMapping("/login")
public CommonResult<UserInfoVo> login(@Validated @RequestBody LoginDto loginDto){
return adminAccountService.login(loginDto);
}
@GetMapping("/logout")
@RequiresAuthentication
@RequiresRoles(value = {"root","admin","problem_admin"},logical = Logical.OR)
public CommonResult<Void> logout() {
return adminAccountService.logout();
}
}

@ -0,0 +1,236 @@
package top.hcode.hoj.controller.admin;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.AnnouncementDto;
import top.hcode.hoj.pojo.dto.ContestProblemDto;
import top.hcode.hoj.pojo.dto.ProblemDto;
import top.hcode.hoj.pojo.entity.contest.Contest;
import top.hcode.hoj.pojo.entity.contest.ContestProblem;
import top.hcode.hoj.pojo.entity.problem.Problem;
import top.hcode.hoj.pojo.vo.AdminContestVo;
import top.hcode.hoj.pojo.vo.AnnouncementVo;
import top.hcode.hoj.service.admin.contest.AdminContestAnnouncementService;
import top.hcode.hoj.service.admin.contest.AdminContestProblemService;
import top.hcode.hoj.service.admin.contest.AdminContestService;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
/**
* @Author: Himit_ZH
* @Date: 2020/12/19 22:28
* @Description:
*/
@RestController
@RequestMapping("/api/admin/contest")
public class AdminContestController {
@Autowired
private AdminContestService adminContestService;
@Autowired
private AdminContestProblemService adminContestProblemService;
@Autowired
private AdminContestAnnouncementService adminContestAnnouncementService;
@GetMapping("/get-contest-list")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<IPage<Contest>> getContestList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "keyword", required = false) String keyword) {
return adminContestService.getContestList(limit, currentPage, keyword);
}
@GetMapping("")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<AdminContestVo> getContest(@RequestParam("cid") Long cid) {
return adminContestService.getContest(cid);
}
@DeleteMapping("")
@RequiresAuthentication
@RequiresRoles(value = "root") // 只有超级管理员能删除比赛
public CommonResult<Void> deleteContest(@RequestParam("cid") Long cid) {
return adminContestService.deleteContest(cid);
}
@PostMapping("")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> addContest(@RequestBody AdminContestVo adminContestVo) {
return adminContestService.addContest(adminContestVo);
}
@GetMapping("/clone")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> cloneContest(@RequestParam("cid") Long cid) {
return adminContestService.cloneContest(cid);
}
@PutMapping("")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
@Transactional(rollbackFor = Exception.class)
public CommonResult<Void> updateContest(@RequestBody AdminContestVo adminContestVo) {
return adminContestService.updateContest(adminContestVo);
}
@PutMapping("/change-contest-visible")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> changeContestVisible(@RequestParam(value = "cid", required = true) Long cid,
@RequestParam(value = "uid", required = true) String uid,
@RequestParam(value = "visible", required = true) Boolean visible) {
return adminContestService.changeContestVisible(cid, uid, visible);
}
/**
*
*/
@GetMapping("/get-problem-list")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
@Transactional(rollbackFor = Exception.class)
public CommonResult<HashMap<String, Object>> getProblemList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "cid", required = true) Long cid,
@RequestParam(value = "problemType", required = false) Integer problemType,
@RequestParam(value = "oj", required = false) String oj) {
return adminContestProblemService.getProblemList(limit, currentPage, keyword, cid, problemType, oj);
}
@GetMapping("/problem")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<Problem> getProblem(@RequestParam("pid") Long pid, HttpServletRequest request) {
return adminContestProblemService.getProblem(pid);
}
@DeleteMapping("/problem")
@RequiresAuthentication
@RequiresRoles(value = {"root", "problem_admin"}, logical = Logical.OR)
@Transactional(rollbackFor = Exception.class)
public CommonResult<Void> deleteProblem(@RequestParam("pid") Long pid,
@RequestParam(value = "cid", required = false) Long cid) {
return adminContestProblemService.deleteProblem(pid, cid);
}
@PostMapping("/problem")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
@Transactional(rollbackFor = Exception.class)
public CommonResult<Map<Object, Object>> addProblem(@RequestBody ProblemDto problemDto) {
return adminContestProblemService.addProblem(problemDto);
}
@PutMapping("/problem")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
@Transactional(rollbackFor = Exception.class)
public CommonResult<Void> updateProblem(@RequestBody ProblemDto problemDto) {
return adminContestProblemService.updateProblem(problemDto);
}
@GetMapping("/contest-problem")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<ContestProblem> getContestProblem(@RequestParam(value = "cid", required = true) Long cid,
@RequestParam(value = "pid", required = true) Long pid) {
return adminContestProblemService.getContestProblem(cid, pid);
}
@PutMapping("/contest-problem")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<ContestProblem> setContestProblem(@RequestBody ContestProblem contestProblem) {
return adminContestProblemService.setContestProblem(contestProblem);
}
@PostMapping("/add-problem-from-public")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> addProblemFromPublic(@RequestBody ContestProblemDto contestProblemDto) {
return adminContestProblemService.addProblemFromPublic(contestProblemDto);
}
@GetMapping("/import-remote-oj-problem")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
@Transactional(rollbackFor = Exception.class)
public CommonResult<Void> importContestRemoteOJProblem(@RequestParam("name") String name,
@RequestParam("problemId") String problemId,
@RequestParam("cid") Long cid,
@RequestParam("displayId") String displayId) {
return adminContestProblemService.importContestRemoteOJProblem(name, problemId, cid, displayId);
}
/**
*
*/
@GetMapping("/announcement")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<IPage<AnnouncementVo>> getAnnouncementList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "cid", required = true) Long cid) {
return adminContestAnnouncementService.getAnnouncementList(limit, currentPage, cid);
}
@DeleteMapping("/announcement")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> deleteAnnouncement(@RequestParam("aid") Long aid) {
return adminContestAnnouncementService.deleteAnnouncement(aid);
}
@PostMapping("/announcement")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> addAnnouncement(@RequestBody AnnouncementDto announcementDto) {
return adminContestAnnouncementService.addAnnouncement(announcementDto);
}
@PutMapping("/announcement")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> updateAnnouncement(@RequestBody AnnouncementDto announcementDto) {
return adminContestAnnouncementService.updateAnnouncement(announcementDto);
}
}

@ -0,0 +1,60 @@
package top.hcode.hoj.controller.admin;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.entity.discussion.Discussion;
import top.hcode.hoj.pojo.entity.discussion.DiscussionReport;
import top.hcode.hoj.pojo.vo.DiscussionReportVo;
import top.hcode.hoj.service.admin.discussion.AdminDiscussionService;
import java.util.List;
/**
* @Author: Himit_ZH
* @Date: 2021/5/15 20:35
* @Description:
*/
@RestController
@RequestMapping("/api/admin")
public class AdminDiscussionController {
@Autowired
private AdminDiscussionService adminDiscussionService;
@PutMapping("/discussion")
@RequiresRoles(value = {"root", "admin","problem_admin"}, logical = Logical.OR)
@RequiresAuthentication
public CommonResult<Void> updateDiscussion(@RequestBody Discussion discussion) {
return adminDiscussionService.updateDiscussion(discussion);
}
@DeleteMapping("/discussion")
@RequiresRoles(value = {"root", "admin","problem_admin"}, logical = Logical.OR)
@RequiresAuthentication
public CommonResult<Void> removeDiscussion(@RequestBody List<Integer> didList) {
return adminDiscussionService.removeDiscussion(didList);
}
@GetMapping("/discussion-report")
@RequiresRoles(value = {"root", "admin","problem_admin"}, logical = Logical.OR)
@RequiresAuthentication
public CommonResult<IPage<DiscussionReportVo>> getDiscussionReport(@RequestParam(value = "limit", defaultValue = "10") Integer limit,
@RequestParam(value = "currentPage", defaultValue = "1") Integer currentPage) {
return adminDiscussionService.getDiscussionReport(limit, currentPage);
}
@PutMapping("/discussion-report")
@RequiresRoles(value = {"root", "admin","problem_admin"}, logical = Logical.OR)
@RequiresAuthentication
public CommonResult<Void> updateDiscussionReport(@RequestBody DiscussionReport discussionReport) {
return adminDiscussionService.updateDiscussionReport(discussionReport);
}
}

@ -0,0 +1,40 @@
package top.hcode.hoj.controller.admin;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.ChangeGroupProblemProgressDto;
import top.hcode.hoj.pojo.entity.problem.Problem;
import top.hcode.hoj.service.admin.problem.AdminGroupProblemService;
import javax.annotation.Resource;
/**
* @Author Himit_ZH
* @Date 2022/4/13
*/
@RestController
@RequestMapping("/api/admin/group-problem")
@RequiresAuthentication
@RequiresRoles(value = {"root", "problem_admin"}, logical = Logical.OR)
public class AdminGroupProblemController {
@Resource
private AdminGroupProblemService adminGroupProblemService;
@GetMapping("/list")
public CommonResult<IPage<Problem>> getProblemList(@RequestParam(value = "currentPage", defaultValue = "1") Integer currentPage,
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "gid", required = false) Long gid) {
return adminGroupProblemService.getProblemList(currentPage, limit, keyword, gid);
}
@PutMapping("/change-progress")
public CommonResult<Void> changeProgress(@RequestBody ChangeGroupProblemProgressDto changeGroupProblemProgressDto) {
return adminGroupProblemService.changeProgress(changeGroupProblemProgressDto);
}
}

@ -0,0 +1,64 @@
package top.hcode.hoj.controller.admin;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.entity.judge.Judge;
import top.hcode.hoj.service.admin.rejudge.RejudgeService;
import javax.annotation.Resource;
/**
* @Author: Himit_ZH
* @Date: 2021/1/3 14:09
* @Description:
*/
@RestController
@RequestMapping("/api/admin/judge")
public class AdminJudgeController {
@Resource
private RejudgeService rejudgeService;
@GetMapping("/rejudge")
@RequiresAuthentication
@RequiresRoles("root") // 只有超级管理员能操作
@RequiresPermissions("rejudge")
public CommonResult<Judge> rejudge(@RequestParam("submitId") Long submitId) {
return rejudgeService.rejudge(submitId);
}
@GetMapping("/rejudge-contest-problem")
@RequiresAuthentication
@RequiresRoles("root") // 只有超级管理员能操作
@RequiresPermissions("rejudge")
public CommonResult<Void> rejudgeContestProblem(@RequestParam("cid") Long cid, @RequestParam("pid") Long pid) {
return rejudgeService.rejudgeContestProblem(cid, pid);
}
@GetMapping("/manual-judge")
@RequiresAuthentication
@RequiresRoles("root") // 只有超级管理员能操作
@RequiresPermissions("rejudge")
public CommonResult<Judge> manualJudge(@RequestParam("submitId") Long submitId,
@RequestParam("status") Integer status,
@RequestParam(value = "score", required = false) Integer score) {
return rejudgeService.manualJudge(submitId, status, score);
}
@GetMapping("/cancel-judge")
@RequiresAuthentication
@RequiresRoles("root") // 只有超级管理员能操作
@RequiresPermissions("rejudge")
public CommonResult<Judge> cancelJudge(@RequestParam("submitId") Long submitId) {
return rejudgeService.cancelJudge(submitId);
}
}

@ -0,0 +1,108 @@
package top.hcode.hoj.controller.admin;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.ProblemDto;
import top.hcode.hoj.pojo.dto.CompileDTO;
import top.hcode.hoj.pojo.entity.problem.Problem;
import top.hcode.hoj.pojo.entity.problem.ProblemCase;
import top.hcode.hoj.service.admin.problem.AdminProblemService;
import java.util.*;
/**
* @Author: Himit_ZH
* @Date: 2020/12/11 21:45
* @Description:
*/
@RestController
@RequestMapping("/api/admin/problem")
public class AdminProblemController {
@Autowired
private AdminProblemService adminProblemService;
@GetMapping("/get-problem-list")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<IPage<Problem>> getProblemList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "auth", required = false) Integer auth,
@RequestParam(value = "oj", required = false) String oj) {
return adminProblemService.getProblemList(limit, currentPage, keyword, auth, oj);
}
@GetMapping("")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<Problem> getProblem(@RequestParam("pid") Long pid) {
return adminProblemService.getProblem(pid);
}
@DeleteMapping("")
@RequiresAuthentication
@RequiresRoles(value = {"root", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> deleteProblem(@RequestParam("pid") Long pid) {
return adminProblemService.deleteProblem(pid);
}
@PostMapping("")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> addProblem(@RequestBody ProblemDto problemDto) {
return adminProblemService.addProblem(problemDto);
}
@PutMapping("")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> updateProblem(@RequestBody ProblemDto problemDto) {
return adminProblemService.updateProblem(problemDto);
}
@GetMapping("/get-problem-cases")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<List<ProblemCase>> getProblemCases(@RequestParam("pid") Long pid,
@RequestParam(value = "isUpload", defaultValue = "true") Boolean isUpload) {
return adminProblemService.getProblemCases(pid, isUpload);
}
@PostMapping("/compile-spj")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult compileSpj(@RequestBody CompileDTO compileDTO) {
return adminProblemService.compileSpj(compileDTO);
}
@PostMapping("/compile-interactive")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult compileInteractive(@RequestBody CompileDTO compileDTO) {
return adminProblemService.compileInteractive(compileDTO);
}
@GetMapping("/import-remote-oj-problem")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> importRemoteOJProblem(@RequestParam("name") String name,
@RequestParam("problemId") String problemId) {
return adminProblemService.importRemoteOJProblem(name, problemId);
}
@PutMapping("/change-problem-auth")
@RequiresAuthentication
@RequiresRoles(value = {"root", "problem_admin", "admin"}, logical = Logical.OR)
public CommonResult<Void> changeProblemAuth(@RequestBody Problem problem) {
return adminProblemService.changeProblemAuth(problem);
}
}

@ -0,0 +1,78 @@
package top.hcode.hoj.controller.admin;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.entity.problem.Tag;
import top.hcode.hoj.pojo.entity.problem.TagClassification;
import top.hcode.hoj.service.admin.tag.AdminTagService;
import javax.annotation.Resource;
import java.util.List;
/**
* @Author: Himit_ZH
* @Date: 2021/11/2 23:24
* @Description: tag
*/
@RestController
@RequestMapping("/api/admin/tag")
public class AdminTagController {
@Resource
private AdminTagService adminTagService;
@PostMapping("")
@RequiresAuthentication
@RequiresRoles(value = {"root", "problem_admin"}, logical = Logical.OR)
public CommonResult<Tag> addTag(@RequestBody Tag tag) {
return adminTagService.addTag(tag);
}
@PutMapping("")
@RequiresAuthentication
@RequiresRoles(value = {"root", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> updateTag(@RequestBody Tag tag) {
return adminTagService.updateTag(tag);
}
@DeleteMapping("")
@RequiresAuthentication
@RequiresRoles(value = {"root", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> deleteTag(@RequestParam("tid") Long tid) {
return adminTagService.deleteTag(tid);
}
@GetMapping("/classification")
@RequiresAuthentication
@RequiresRoles(value = {"root", "problem_admin"}, logical = Logical.OR)
public CommonResult<List<TagClassification>> getTagClassification(@RequestParam(value = "oj", defaultValue = "ME") String oj) {
return adminTagService.getTagClassification(oj);
}
@PostMapping("/classification")
@RequiresAuthentication
@RequiresRoles(value = {"root", "problem_admin"}, logical = Logical.OR)
public CommonResult<TagClassification> addTagClassification(@RequestBody TagClassification tagClassification) {
return adminTagService.addTagClassification(tagClassification);
}
@PutMapping("/classification")
@RequiresAuthentication
@RequiresRoles(value = {"root", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> updateTagClassification(@RequestBody TagClassification tagClassification) {
return adminTagService.updateTagClassification(tagClassification);
}
@DeleteMapping("/classification")
@RequiresAuthentication
@RequiresRoles(value = {"root", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> deleteTagClassification(@RequestParam("tcid") Long tcid) {
return adminTagService.deleteTagClassification(tcid);
}
}

@ -0,0 +1,48 @@
package top.hcode.hoj.controller.admin;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.entity.training.TrainingCategory;
import top.hcode.hoj.service.admin.training.AdminTrainingCategoryService;
import javax.annotation.Resource;
/**
* @Author: Himit_ZH
* @Date: 2021/11/27 15:11
* @Description:
*/
@RestController
@RequestMapping("/api/admin/training/category")
public class AdminTrainingCategoryController {
@Resource
private AdminTrainingCategoryService adminTrainingCategoryService;
@PostMapping("")
@RequiresAuthentication
@RequiresRoles(value = {"root", "problem_admin"}, logical = Logical.OR)
public CommonResult<TrainingCategory> addTrainingCategory(@RequestBody TrainingCategory trainingCategory) {
return adminTrainingCategoryService.addTrainingCategory(trainingCategory);
}
@PutMapping("")
@RequiresAuthentication
@RequiresRoles(value = {"root", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> updateTrainingCategory(@RequestBody TrainingCategory trainingCategory) {
return adminTrainingCategoryService.updateTrainingCategory(trainingCategory);
}
@DeleteMapping("")
@RequiresAuthentication
@RequiresRoles(value = {"root", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> deleteTrainingCategory(@RequestParam("cid") Long cid) {
return adminTrainingCategoryService.deleteTrainingCategory(cid);
}
}

@ -0,0 +1,128 @@
package top.hcode.hoj.controller.admin;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.TrainingDto;
import top.hcode.hoj.pojo.dto.TrainingProblemDto;
import top.hcode.hoj.pojo.entity.training.Training;
import top.hcode.hoj.pojo.entity.training.TrainingProblem;
import top.hcode.hoj.service.admin.training.AdminTrainingProblemService;
import top.hcode.hoj.service.admin.training.AdminTrainingService;
import javax.annotation.Resource;
import java.util.HashMap;
/**
* @Author Himit_ZH
* @Since 2022/01/23 20:22
* @Description
*/
@RestController
@RequestMapping("/api/admin/training")
public class AdminTrainingController {
@Resource
private AdminTrainingService adminTrainingService;
@Resource
private AdminTrainingProblemService adminTrainingProblemService;
@GetMapping("/get-training-list")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<IPage<Training>> getTrainingList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "keyword", required = false) String keyword) {
return adminTrainingService.getTrainingList(limit, currentPage, keyword);
}
@GetMapping("")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<TrainingDto> getTraining(@RequestParam("tid") Long tid) {
return adminTrainingService.getTraining(tid);
}
@DeleteMapping("")
@RequiresAuthentication
@RequiresRoles(value = "root") // 只有超级管理员能删除训练
public CommonResult<Void> deleteTraining(@RequestParam("tid") Long tid) {
return adminTrainingService.deleteTraining(tid);
}
@PostMapping("")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> addTraining(@RequestBody TrainingDto trainingDto) {
return adminTrainingService.addTraining(trainingDto);
}
@PutMapping("")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> updateTraining(@RequestBody TrainingDto trainingDto) {
return adminTrainingService.updateTraining(trainingDto);
}
@PutMapping("/change-training-status")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> changeTrainingStatus(@RequestParam(value = "tid", required = true) Long tid,
@RequestParam(value = "author", required = true) String author,
@RequestParam(value = "status", required = true) Boolean status) {
return adminTrainingService.changeTrainingStatus(tid, author, status);
}
@GetMapping("/get-problem-list")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<HashMap<String, Object>> getProblemList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "queryExisted", defaultValue = "false") Boolean queryExisted,
@RequestParam(value = "tid", required = true) Long tid) {
return adminTrainingProblemService.getProblemList(limit, currentPage, keyword, queryExisted, tid);
}
@PutMapping("/problem")
@RequiresAuthentication
@RequiresRoles(value = {"root", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> updateProblem(@RequestBody TrainingProblem trainingProblem) {
return adminTrainingProblemService.updateProblem(trainingProblem);
}
@DeleteMapping("/problem")
@RequiresAuthentication
@RequiresRoles(value = {"root", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> deleteProblem(@RequestParam("pid") Long pid,
@RequestParam(value = "tid", required = false) Long tid) {
return adminTrainingProblemService.deleteProblem(pid, tid);
}
@PostMapping("/add-problem-from-public")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult<Void> addProblemFromPublic(@RequestBody TrainingProblemDto trainingProblemDto) {
return adminTrainingProblemService.addProblemFromPublic(trainingProblemDto);
}
@GetMapping("/import-remote-oj-problem")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
@Transactional(rollbackFor = Exception.class)
public CommonResult<Void> importTrainingRemoteOJProblem(@RequestParam("name") String name,
@RequestParam("problemId") String problemId,
@RequestParam("tid") Long tid) {
return adminTrainingProblemService.importTrainingRemoteOJProblem(name, problemId, tid);
}
}

@ -0,0 +1,69 @@
package top.hcode.hoj.controller.admin;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.AdminEditUserDto;
import top.hcode.hoj.pojo.vo.UserRolesVo;
import top.hcode.hoj.service.admin.user.AdminUserService;
import java.util.List;
import java.util.Map;
/**
* @Author: Himit_ZH
* @Date: 2020/12/6 15:18
* @Description:
*/
@RestController
@RequestMapping("/api/admin/user")
public class AdminUserController {
@Autowired
private AdminUserService adminUserService;
@GetMapping("/get-user-list")
@RequiresAuthentication
@RequiresPermissions("user_admin")
public CommonResult<IPage<UserRolesVo>> getUserList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "onlyAdmin", defaultValue = "false") Boolean onlyAdmin,
@RequestParam(value = "keyword", required = false) String keyword) {
return adminUserService.getUserList(limit, currentPage, onlyAdmin, keyword);
}
@PutMapping("/edit-user")
@RequiresPermissions("user_admin")
@RequiresAuthentication
public CommonResult<Void> editUser(@RequestBody AdminEditUserDto adminEditUserDto) {
return adminUserService.editUser(adminEditUserDto);
}
@DeleteMapping("/delete-user")
@RequiresPermissions("user_admin")
@RequiresAuthentication
public CommonResult<Void> deleteUser(@RequestBody Map<String, Object> params) {
return adminUserService.deleteUser((List<String>) params.get("ids"));
}
@PostMapping("/insert-batch-user")
@RequiresPermissions("user_admin")
@RequiresAuthentication
public CommonResult<Void> insertBatchUser(@RequestBody Map<String, Object> params) {
return adminUserService.insertBatchUser((List<List<String>>) params.get("users"));
}
@PostMapping("/generate-user")
@RequiresPermissions("user_admin")
@RequiresAuthentication
public CommonResult<Map<Object, Object>> generateUser(@RequestBody Map<String, Object> params) {
return adminUserService.generateUser(params);
}
}

@ -0,0 +1,53 @@
package top.hcode.hoj.controller.admin;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.entity.common.Announcement;
import top.hcode.hoj.pojo.vo.AnnouncementVo;
import top.hcode.hoj.service.admin.announcement.AdminAnnouncementService;
/**
* @Author: Himit_ZH
* @Date: 2020/12/10 19:53
* @Description:
*/
@RestController
@RequiresAuthentication
@RequestMapping("/api/admin")
public class AnnouncementController {
@Autowired
private AdminAnnouncementService adminAnnouncementService;
@GetMapping("/announcement")
@RequiresPermissions("announcement_admin")
public CommonResult<IPage<AnnouncementVo>> getAnnouncementList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage) {
return adminAnnouncementService.getAnnouncementList(limit, currentPage);
}
@DeleteMapping("/announcement")
@RequiresPermissions("announcement_admin")
public CommonResult<Void> deleteAnnouncement(@RequestParam("aid") Long aid) {
return adminAnnouncementService.deleteAnnouncement(aid);
}
@PostMapping("/announcement")
@RequiresRoles("root") // 只有超级管理员能操作
@RequiresPermissions("announcement_admin")
public CommonResult<Void> addAnnouncement(@RequestBody Announcement announcement) {
return adminAnnouncementService.addAnnouncement(announcement);
}
@PutMapping("/announcement")
@RequiresPermissions("announcement_admin")
public CommonResult<Void> updateAnnouncement(@RequestBody Announcement announcement) {
return adminAnnouncementService.updateAnnouncement(announcement);
}
}

@ -0,0 +1,105 @@
package top.hcode.hoj.controller.admin;
import cn.hutool.json.JSONObject;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.DBAndRedisConfigDto;
import top.hcode.hoj.pojo.dto.EmailConfigDto;
import top.hcode.hoj.pojo.dto.TestEmailDto;
import top.hcode.hoj.pojo.dto.WebConfigDto;
import top.hcode.hoj.service.admin.system.ConfigService;
import javax.mail.MessagingException;
import java.util.List;
import java.util.Map;
/**
* @Author: Himit_ZH
* @Date: 2020/12/2 21:42
* @Description:
*/
@RestController
@RequestMapping("/api/admin/config")
public class ConfigController {
@Autowired
private ConfigService configService;
/**
* @MethodName getServiceInfo
* @Params * @param null
* @Description cpu使
* @Return CommonResult
* @Since 2020/12/3
*/
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
@RequestMapping("/get-service-info")
public CommonResult<JSONObject> getServiceInfo() {
return configService.getServiceInfo();
}
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
@RequestMapping("/get-judge-service-info")
public CommonResult<List<JSONObject>> getJudgeServiceInfo() {
return configService.getJudgeServiceInfo();
}
@RequiresPermissions("system_info_admin")
@RequestMapping("/get-web-config")
public CommonResult<WebConfigDto> getWebConfig() {
return configService.getWebConfig();
}
@RequiresPermissions("system_info_admin")
@DeleteMapping("/home-carousel")
public CommonResult<Void> deleteHomeCarousel(@RequestParam("id") Long id) {
return configService.deleteHomeCarousel(id);
}
@RequiresPermissions("system_info_admin")
@RequestMapping(value = "/set-web-config", method = RequestMethod.PUT)
public CommonResult<Void> setWebConfig(@RequestBody WebConfigDto config) {
return configService.setWebConfig(config);
}
@RequiresPermissions("system_info_admin")
@RequestMapping("/get-email-config")
public CommonResult<EmailConfigDto> getEmailConfig() {
return configService.getEmailConfig();
}
@RequiresPermissions("system_info_admin")
@PutMapping("/set-email-config")
public CommonResult<Void> setEmailConfig(@RequestBody EmailConfigDto config) {
return configService.setEmailConfig(config);
}
@RequiresPermissions("system_info_admin")
@PostMapping("/test-email")
public CommonResult<Void> testEmail(@RequestBody TestEmailDto testEmailDto) {
return configService.testEmail(testEmailDto);
}
@RequiresPermissions("system_info_admin")
@RequestMapping("/get-db-and-redis-config")
public CommonResult<DBAndRedisConfigDto> getDBAndRedisConfig() {
return configService.getDBAndRedisConfig();
}
@RequiresPermissions("system_info_admin")
@PutMapping("/set-db-and-redis-config")
public CommonResult<Void> setDBAndRedisConfig(@RequestBody DBAndRedisConfigDto config) {
return configService.setDBAndRedisConfig(config);
}
}

@ -0,0 +1,46 @@
package top.hcode.hoj.controller.admin;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.entity.user.Session;
import top.hcode.hoj.service.admin.system.DashboardService;
import java.util.Map;
/**
* @Author: Himit_ZH
* @Date: 2020/12/6 15:10
* @Description:
*/
@RestController
@RequestMapping("/api/admin/dashboard")
public class DashboardController {
@Autowired
private DashboardService dashboardService;
@PostMapping("/get-sessions")
@RequiresAuthentication
@RequiresRoles(value = {"root","admin","problem_admin"},logical = Logical.OR)
public CommonResult<Session> getRecentSession(){
return dashboardService.getRecentSession();
}
@GetMapping("/get-dashboard-info")
@RequiresAuthentication
@RequiresRoles(value = {"root","admin","problem_admin"},logical = Logical.OR)
public CommonResult<Map<Object,Object>> getDashboardInfo(){
return dashboardService.getDashboardInfo();
}
}

@ -0,0 +1,37 @@
package top.hcode.hoj.controller.admin;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.SwitchConfigDto;
import top.hcode.hoj.service.admin.system.ConfigService;
import javax.annotation.Resource;
/**
* @Author Himit_ZH
* @Date 2022/5/9
*/
@RestController
@RequestMapping("/api/admin/switch")
public class SwitchController {
@Resource
private ConfigService configService;
@RequiresPermissions("system_info_admin")
@RequestMapping("/info")
public CommonResult<SwitchConfigDto> getSwitchConfig() {
return configService.getSwitchConfig();
}
@RequiresPermissions("system_info_admin")
@PutMapping("/update")
public CommonResult<Void> setSwitchConfig(@RequestBody SwitchConfigDto config) {
return configService.setSwitchConfig(config);
}
}

@ -0,0 +1,57 @@
package top.hcode.hoj.controller.file;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import top.hcode.hoj.common.exception.StatusFailException;
import top.hcode.hoj.common.exception.StatusForbiddenException;
import top.hcode.hoj.service.file.ContestFileService;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
/**
* @Author: Himit_ZH
* @Date: 2021/10/5 19:55
* @Description:
*/
@Controller
@RequestMapping("/api/file")
public class ContestFileController {
@Autowired
private ContestFileService contestFileService;
@GetMapping("/download-contest-rank")
@RequiresAuthentication
public void downloadContestRank(@RequestParam("cid") Long cid,
@RequestParam("forceRefresh") Boolean forceRefresh,
@RequestParam(value = "removeStar", defaultValue = "false") Boolean removeStar,
HttpServletResponse response) throws StatusFailException, IOException, StatusForbiddenException {
contestFileService.downloadContestRank(cid, forceRefresh, removeStar, response);
}
@GetMapping("/download-contest-ac-submission")
@RequiresAuthentication
public void downloadContestACSubmission(@RequestParam("cid") Long cid,
@RequestParam(value = "excludeAdmin", defaultValue = "false") Boolean excludeAdmin,
@RequestParam(value = "splitType", defaultValue = "user") String splitType,
HttpServletResponse response) throws StatusFailException, StatusForbiddenException {
contestFileService.downloadContestACSubmission(cid, excludeAdmin, splitType, response);
}
@GetMapping("/download-contest-print-text")
@RequiresAuthentication
public void downloadContestPrintText(@RequestParam("id") Long id, HttpServletResponse response) throws StatusForbiddenException{
contestFileService.downloadContestPrintText(id, response);
}
}

@ -0,0 +1,55 @@
package top.hcode.hoj.controller.file;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.entity.group.Group;
import top.hcode.hoj.service.file.ImageService;
import java.util.Map;
/**
* @Author: Himit_ZH
* @Date: 2021/10/5 19:46
* @Description:
*/
@Controller
@RequestMapping("/api/file")
public class ImageController {
@Autowired
private ImageService imageService;
@RequestMapping(value = "/upload-avatar", method = RequestMethod.POST)
@RequiresAuthentication
@ResponseBody
public CommonResult<Map<Object, Object>> uploadAvatar(@RequestParam("image") MultipartFile image) {
return imageService.uploadAvatar(image);
}
@RequestMapping(value = "/upload-group-avatar", method = RequestMethod.POST)
@RequiresAuthentication
@ResponseBody
public CommonResult<Group> uploadGroupAvatar(@RequestParam(value = "image", required = true) MultipartFile image,
@RequestParam(value = "gid", required = true) Long gid) {
return imageService.uploadGroupAvatar(image, gid);
}
@RequestMapping(value = "/upload-carouse-img", method = RequestMethod.POST)
@RequiresAuthentication
@ResponseBody
@RequiresRoles("root")
public CommonResult<Map<Object, Object>> uploadCarouselImg(@RequestParam("file") MultipartFile image) {
return imageService.uploadCarouselImg(image);
}
}

@ -0,0 +1,46 @@
package top.hcode.hoj.controller.file;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.service.file.ImportFpsProblemService;
import javax.annotation.Resource;
/**
* @Author: Himit_ZH
* @Date: 2021/10/5 19:45
* @Description:
*/
@Controller
@RequestMapping("/api/file")
public class ImportFpsProblemController {
@Resource
private ImportFpsProblemService importFpsProblemService;
/**
* @param file
* @MethodName importFpsProblem
* @Description zip
* @Return
* @Since 2021/10/06
*/
@RequiresRoles("root")
@RequiresAuthentication
@ResponseBody
@PostMapping("/import-fps-problem")
public CommonResult<Void> importFPSProblem(@RequestParam("file") MultipartFile file) {
return importFpsProblemService.importFPSProblem(file);
}
}

@ -0,0 +1,45 @@
package top.hcode.hoj.controller.file;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.service.file.ImportQDUOJProblemService;
/**
* @Author: Himit_ZH
* @Date: 2021/10/5 19:44
* @Description:
*/
@Controller
@RequestMapping("/api/file")
public class ImportQDUOJProblemController {
@Autowired
private ImportQDUOJProblemService importQDUOJProblemService;
/**
* @param file
* @MethodName importQDOJProblem
* @Description zip
* @Return
* @Since 2021/5/27
*/
@RequiresRoles("root")
@RequiresAuthentication
@ResponseBody
@PostMapping("/import-qdoj-problem")
public CommonResult<Void> importQDOJProblem(@RequestParam("file") MultipartFile file) {
return importQDUOJProblemService.importQDOJProblem(file);
}
}

@ -0,0 +1,54 @@
package top.hcode.hoj.controller.file;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.service.file.MarkDownFileService;
import javax.annotation.Resource;
import java.util.Map;
/**
* @Author: Himit_ZH
* @Date: 2021/10/5 20:01
* @Description:
*/
@Controller
@RequestMapping("/api/file")
public class MarkDownFileController {
@Resource
private MarkDownFileService markDownFileService;
@RequestMapping(value = "/upload-md-img", method = RequestMethod.POST)
@RequiresAuthentication
@ResponseBody
public CommonResult<Map<Object, Object>> uploadMDImg(@RequestParam("image") MultipartFile image,
@RequestParam(value = "gid", required = false) Long gid) {
return markDownFileService.uploadMDImg(image, gid);
}
@RequestMapping(value = "/delete-md-img", method = RequestMethod.GET)
@RequiresAuthentication
@ResponseBody
public CommonResult<Void> deleteMDImg(@RequestParam("fileId") Long fileId) {
return markDownFileService.deleteMDImg(fileId);
}
@RequestMapping(value = "/upload-md-file", method = RequestMethod.POST)
@RequiresAuthentication
@ResponseBody
public CommonResult<Map<Object, Object>> uploadMd(@RequestParam("file") MultipartFile file,
@RequestParam(value = "gid", required = false) Long gid) {
return markDownFileService.uploadMd(file, gid);
}
}

@ -0,0 +1,59 @@
package top.hcode.hoj.controller.file;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.service.file.ProblemFileService;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
/**
* @Author: Himit_ZH
* @Date: 2021/10/5 20:05
* @Description:
*/
@Controller
@RequestMapping("/api/file")
public class ProblemFileController {
@Autowired
private ProblemFileService problemFileService;
/**
* @param file
* @MethodName importProblem
* @Description zip
* @Return
* @Since 2021/5/27
*/
@RequiresRoles("root")
@RequiresAuthentication
@ResponseBody
@PostMapping("/import-problem")
public CommonResult<Void> importProblem(@RequestParam("file") MultipartFile file) {
return problemFileService.importProblem(file);
}
/**
* @param pidList
* @param response
* @MethodName exportProblem
* @Description zip
* @Return
* @Since 2021/5/28
*/
@GetMapping("/export-problem")
@RequiresAuthentication
@RequiresRoles("root")
public void exportProblem(@RequestParam("pid") List<Long> pidList, HttpServletResponse response) {
problemFileService.exportProblem(pidList, response);
}
}

@ -0,0 +1,42 @@
package top.hcode.hoj.controller.file;
import top.hcode.hoj.common.exception.StatusForbiddenException;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import top.hcode.hoj.common.exception.StatusFailException;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.service.file.TestCaseService;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
/**
* @Author: Himit_ZH
* @Date: 2021/10/5 19:51
* @Description:
*/
@Controller
@RequestMapping("/api/file")
public class TestCaseController {
@Autowired
private TestCaseService testCaseService;
@PostMapping("/upload-testcase-zip")
@ResponseBody
public CommonResult<Map<Object, Object>> uploadTestcaseZip(@RequestParam("file") MultipartFile file,
@RequestParam(value = "gid", required = false) Long gid) {
return testCaseService.uploadTestcaseZip(file, gid);
}
@GetMapping("/download-testcase")
@RequiresAuthentication
public void downloadTestcase(@RequestParam("pid") Long pid, HttpServletResponse response) throws StatusFailException, StatusForbiddenException {
testCaseService.downloadTestcase(pid, response);
}
}

@ -0,0 +1,34 @@
package top.hcode.hoj.controller.file;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import top.hcode.hoj.service.file.UserFileService;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @Author: Himit_ZH
* @Date: 2021/10/5 19:48
* @Description:
*/
@Controller
@RequestMapping("/api/file")
public class UserFileController {
@Autowired
private UserFileService userFileService;
@RequestMapping("/generate-user-excel")
@RequiresAuthentication
@RequiresRoles("root")
public void generateUserExcel(@RequestParam("key") String key, HttpServletResponse response) throws IOException {
userFileService.generateUserExcel(key, response);
}
}

@ -0,0 +1,54 @@
package top.hcode.hoj.controller.group;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.entity.common.Announcement;
import top.hcode.hoj.pojo.vo.AnnouncementVo;
import top.hcode.hoj.service.group.announcement.GroupAnnouncementService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @Author: LengYun
* @Date: 2022/3/11 13:36
* @Description:
*/
@RestController
@RequiresAuthentication
@RequestMapping("/api/group")
public class GroupAnnouncementController {
@Autowired
private GroupAnnouncementService groupAnnouncementService;
@GetMapping("/get-announcement-list")
public CommonResult<IPage<AnnouncementVo>> getAnnouncementList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "gid", required = true) Long gid) {
return groupAnnouncementService.getAnnouncementList(limit, currentPage, gid);
}
@GetMapping("/get-admin-announcement-list")
public CommonResult<IPage<AnnouncementVo>> getAdminAnnouncementList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "gid", required = true) Long gid) {
return groupAnnouncementService.getAdminAnnouncementList(limit, currentPage, gid);
}
@PostMapping("/announcement")
public CommonResult<Void> addAnnouncement(@RequestBody Announcement announcement) {
return groupAnnouncementService.addAnnouncement(announcement);
}
@PutMapping("/announcement")
public CommonResult<Void> updateAnnouncement(@RequestBody Announcement announcement) {
return groupAnnouncementService.updateAnnouncement(announcement);
}
@DeleteMapping("/announcement")
public CommonResult<Void> deleteAnnouncement(@RequestParam(value = "aid", required = true) Long aid) {
return groupAnnouncementService.deleteAnnouncement(aid);
}
}

@ -0,0 +1,151 @@
package top.hcode.hoj.controller.group;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.AnnouncementDto;
import top.hcode.hoj.pojo.dto.ContestProblemDto;
import top.hcode.hoj.pojo.dto.ProblemDto;
import top.hcode.hoj.pojo.entity.contest.Contest;
import top.hcode.hoj.pojo.entity.contest.ContestProblem;
import top.hcode.hoj.pojo.vo.AdminContestVo;
import top.hcode.hoj.pojo.vo.AnnouncementVo;
import top.hcode.hoj.pojo.vo.ContestVo;
import top.hcode.hoj.service.group.contest.GroupContestAnnouncementService;
import top.hcode.hoj.service.group.contest.GroupContestProblemService;
import top.hcode.hoj.service.group.contest.GroupContestService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
/**
* @Author: LengYun
* @Date: 2022/3/11 13:36
* @Description:
*/
@RestController
@RequiresAuthentication
@RequestMapping("/api/group")
public class GroupContestController {
@Autowired
private GroupContestService groupContestService;
@Autowired
private GroupContestProblemService groupContestProblemService;
@Autowired
private GroupContestAnnouncementService groupContestAnnouncementService;
@GetMapping("/get-contest-list")
public CommonResult<IPage<ContestVo>> getContestList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "gid", required = true) Long gid) {
return groupContestService.getContestList(limit, currentPage, gid);
}
@GetMapping("/get-admin-contest-list")
public CommonResult<IPage<Contest>> getAdminContestList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "gid", required = true) Long gid) {
return groupContestService.getAdminContestList(limit, currentPage, gid);
}
@GetMapping("/contest")
public CommonResult<AdminContestVo> getContest(@RequestParam("cid") Long cid) {
return groupContestService.getContest(cid);
}
@PostMapping("/contest")
public CommonResult<Void> addContest(@RequestBody AdminContestVo adminContestVo) {
return groupContestService.addContest(adminContestVo);
}
@PutMapping("/contest")
public CommonResult<Void> updateContest(@RequestBody AdminContestVo adminContestVo) {
return groupContestService.updateContest(adminContestVo);
}
@DeleteMapping("/contest")
public CommonResult<Void> deleteContest(@RequestParam(value = "cid", required = true) Long cid) {
return groupContestService.deleteContest(cid);
}
@PutMapping("/change-contest-visible")
public CommonResult<Void> changeContestVisible(@RequestParam(value = "cid", required = true) Long cid,
@RequestParam(value = "visible", required = true) Boolean visible) {
return groupContestService.changeContestVisible(cid, visible);
}
@GetMapping("/get-contest-problem-list")
public CommonResult<HashMap<String, Object>> getContestProblemList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "cid", required = true) Long cid,
@RequestParam(value = "problemType", required = false) Integer problemType,
@RequestParam(value = "oj", required = false) String oj) {
return groupContestProblemService.getContestProblemList(limit, currentPage, keyword, cid, problemType, oj);
}
@PostMapping("/contest-problem")
public CommonResult<Map<Object, Object>> addProblem(@RequestBody ProblemDto problemDto) {
return groupContestProblemService.addProblem(problemDto);
}
@GetMapping("/contest-problem")
public CommonResult<ContestProblem> getContestProblem(@RequestParam(value = "pid", required = true) Long pid,
@RequestParam(value = "cid", required = true) Long cid) {
return groupContestProblemService.getContestProblem(pid, cid);
}
@PutMapping("/contest-problem")
public CommonResult<Void> updateContestProblem(@RequestBody ContestProblem contestProblem) {
return groupContestProblemService.updateContestProblem(contestProblem);
}
@DeleteMapping("/contest-problem")
public CommonResult<Void> deleteContestProblem(@RequestParam(value = "pid", required = true) Long pid,
@RequestParam(value = "cid", required = true) Long cid) {
return groupContestProblemService.deleteContestProblem(pid, cid);
}
@PostMapping("/add-contest-problem-from-public")
public CommonResult<Void> addProblemFromPublic(@RequestBody ContestProblemDto contestProblemDto) {
return groupContestProblemService.addProblemFromPublic(contestProblemDto);
}
@PostMapping("/add-contest-problem-from-group")
public CommonResult<Void> addProblemFromGroup(@RequestParam(value = "problemId", required = true) String problemId,
@RequestParam(value = "cid", required = true) Long cid,
@RequestParam(value = "displayId", required = true) String displayId) {
return groupContestProblemService.addProblemFromGroup(problemId, cid, displayId);
}
@GetMapping("/get-contest-announcement-list")
public CommonResult<IPage<AnnouncementVo>> getContestAnnouncementList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "cid", required = true) Long cid) {
return groupContestAnnouncementService.getContestAnnouncementList(limit, currentPage, cid);
}
@PostMapping("/contest-announcement")
public CommonResult<Void> addContestAnnouncement(@RequestBody AnnouncementDto announcementDto) {
return groupContestAnnouncementService.addContestAnnouncement(announcementDto);
}
@PutMapping("/contest-announcement")
public CommonResult<Void> updateContestAnnouncement(@RequestBody AnnouncementDto announcementDto) {
return groupContestAnnouncementService.updateContestAnnouncement(announcementDto);
}
@DeleteMapping("/contest-announcement")
public CommonResult<Void> deleteContestAnnouncement(@RequestParam(value = "aid", required = true) Long aid,
@RequestParam(value = "cid", required = true) Long cid) {
return groupContestAnnouncementService.deleteContestAnnouncement(aid, cid);
}
}

@ -0,0 +1,71 @@
package top.hcode.hoj.controller.group;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.entity.group.Group;
import top.hcode.hoj.pojo.vo.AccessVo;
import top.hcode.hoj.pojo.vo.GroupVo;
import top.hcode.hoj.service.group.GroupService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @Author: LengYun
* @Date: 2022/3/11 13:36
* @Description:
*/
@RestController
@RequestMapping("/api")
public class GroupController {
@Autowired
private GroupService groupService;
@GetMapping("/get-group-list")
public CommonResult<IPage<GroupVo>> getGroupList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "auth", required = false) Integer auth,
@RequestParam(value = "onlyMine", required = false) Boolean onlyMine) {
return groupService.getGroupList(limit, currentPage, keyword, auth, onlyMine);
}
@GetMapping("/get-group-detail")
public CommonResult<Group> getGroup(@RequestParam(value = "gid", required = true) Long gid) {
return groupService.getGroup(gid);
}
@RequiresAuthentication
@GetMapping("/get-group-access")
public CommonResult<AccessVo> getGroupAccess(@RequestParam(value = "gid", required = true) Long gid) {
return groupService.getGroupAccess(gid);
}
@RequiresAuthentication
@GetMapping("/get-group-auth")
public CommonResult<Integer> getGroupAuth(@RequestParam(value = "gid", required = true) Long gid) {
return groupService.getGroupAuth(gid);
}
@PostMapping("/group")
@RequiresAuthentication
@RequiresPermissions("group_add")
public CommonResult<Void> addGroup(@RequestBody Group group) {
return groupService.addGroup(group);
}
@PutMapping("/group")
@RequiresAuthentication
public CommonResult<Void> updateGroup(@RequestBody Group group) {
return groupService.updateGroup(group);
}
@DeleteMapping("/group")
@RequiresAuthentication
@RequiresPermissions("group_del")
public CommonResult<Void> deleteGroup(@RequestParam(value = "gid", required = true) Long gid) {
return groupService.deleteGroup(gid);
}
}

@ -0,0 +1,57 @@
package top.hcode.hoj.controller.group;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.annotation.HOJAccess;
import top.hcode.hoj.annotation.HOJAccessEnum;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.entity.discussion.Discussion;
import top.hcode.hoj.service.group.discussion.GroupDiscussionService;
/**
* @Author: LengYun
* @Date: 2022/3/11 13:36
* @Description:
*/
@RestController
@RequiresAuthentication
@RequestMapping("/api/group")
@HOJAccess({HOJAccessEnum.GROUP_DISCUSSION})
public class GroupDiscussionController {
@Autowired
private GroupDiscussionService groupDiscussionService;
@GetMapping("/get-discussion-list")
public CommonResult<IPage<Discussion>> getDiscussionList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "gid", required = true) Long gid,
@RequestParam(value = "pid", required = false) String pid) {
return groupDiscussionService.getDiscussionList(limit, currentPage, gid, pid);
}
@GetMapping("/get-admin-discussion-list")
public CommonResult<IPage<Discussion>> getAdminDiscussionList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "gid", required = true) Long gid) {
return groupDiscussionService.getAdminDiscussionList(limit, currentPage, gid);
}
@PostMapping("/discussion")
public CommonResult<Void> addDiscussion(@RequestBody Discussion discussion) {
return groupDiscussionService.addDiscussion(discussion);
}
@PutMapping("/discussion")
public CommonResult<Void> updateDiscussion(@RequestBody Discussion discussion) {
return groupDiscussionService.updateDiscussion(discussion);
}
@DeleteMapping("/discussion")
public CommonResult<Void> deleteDiscussion(@RequestParam(value = "did", required = true) Long did) {
return groupDiscussionService.deleteDiscussion(did);
}
}

@ -0,0 +1,71 @@
package top.hcode.hoj.controller.group;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.entity.group.GroupMember;
import top.hcode.hoj.pojo.vo.GroupMemberVo;
import top.hcode.hoj.service.group.member.GroupMemberService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @Author: LengYun
* @Date: 2022/3/11 13:36
* @Description:
*/
@RestController
@RequiresAuthentication
@RequestMapping("/api/group")
public class GroupMemberController {
@Autowired
private GroupMemberService groupMemberService;
@GetMapping("/get-member-list")
public CommonResult<IPage<GroupMemberVo>> getMemberList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "auth", required = false) Integer auth,
@RequestParam(value = "gid", required = true) Long gid) {
return groupMemberService.getMemberList(limit, currentPage, keyword, auth, gid);
}
@GetMapping("/get-apply-list")
public CommonResult<IPage<GroupMemberVo>> getApplyList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "auth", required = false) Integer auth,
@RequestParam(value = "gid", required = true) Long gid) {
return groupMemberService.getApplyList(limit, currentPage, keyword, auth, gid);
}
@PostMapping("/member")
@RequiresAuthentication
public CommonResult<Void> addGroupMember(@RequestParam(value = "gid", required = true) Long gid,
@RequestParam(value = "code", required = false) String code,
@RequestParam(value = "reason", required = false) String reason) {
return groupMemberService.addMember(gid, code, reason);
}
@PutMapping("/member")
@RequiresAuthentication
public CommonResult<Void> updateMember(@RequestBody GroupMember groupMember) {
return groupMemberService.updateMember(groupMember);
}
@DeleteMapping("/member")
@RequiresAuthentication
public CommonResult<Void> deleteMember(@RequestParam(value = "uid", required = true) String uid,
@RequestParam(value = "gid", required = true) Long gid) {
return groupMemberService.deleteMember(uid, gid);
}
@DeleteMapping("/member/exit")
@RequiresAuthentication
public CommonResult<Void> exitGroup(@RequestParam(value = "gid", required = true) Long gid) {
return groupMemberService.exitGroup(gid);
}
}

@ -0,0 +1,100 @@
package top.hcode.hoj.controller.group;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.ProblemDto;
import top.hcode.hoj.pojo.dto.CompileDTO;
import top.hcode.hoj.pojo.entity.problem.Problem;
import top.hcode.hoj.pojo.entity.problem.ProblemCase;
import top.hcode.hoj.pojo.entity.problem.Tag;
import top.hcode.hoj.pojo.vo.ProblemVo;
import top.hcode.hoj.service.group.problem.GroupProblemService;
import java.util.List;
/**
* @Author: LengYun
* @Date: 2022/3/11 13:36
* @Description:
*/
@RestController
@RequiresAuthentication
@RequestMapping("/api/group")
public class GroupProblemController {
@Autowired
private GroupProblemService groupProblemService;
@GetMapping("/get-problem-list")
public CommonResult<IPage<ProblemVo>> getProblemList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "gid", required = true) Long gid) {
return groupProblemService.getProblemList(limit, currentPage, gid);
}
@GetMapping("/get-admin-problem-list")
public CommonResult<IPage<Problem>> getAdminProblemList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "gid", required = true) Long gid) {
return groupProblemService.getAdminProblemList(limit, currentPage, gid);
}
@GetMapping("/problem")
public CommonResult<Problem> getProblem(@RequestParam("pid") Long pid) {
return groupProblemService.getProblem(pid);
}
@PostMapping("/problem")
public CommonResult<Void> addProblem(@RequestBody ProblemDto problemDto) {
return groupProblemService.addProblem(problemDto);
}
@PutMapping("/problem")
public CommonResult<Void> updateProblem(@RequestBody ProblemDto problemDto) {
return groupProblemService.updateProblem(problemDto);
}
@DeleteMapping("/problem")
public CommonResult<Void> deleteProblem(@RequestParam(value = "pid", required = true) Long pid) {
return groupProblemService.deleteProblem(pid);
}
@GetMapping("/get-problem-cases")
public CommonResult<List<ProblemCase>> getProblemCases(@RequestParam("pid") Long pid,
@RequestParam(value = "isUpload", defaultValue = "true") Boolean isUpload) {
return groupProblemService.getProblemCases(pid, isUpload);
}
@GetMapping("/get-all-problem-tags")
public CommonResult<List<Tag>> getAllProblemTagsList(@RequestParam("gid") Long gid) {
return groupProblemService.getAllProblemTagsList(gid);
}
@PostMapping("/compile-spj")
public CommonResult<Void> compileSpj(@RequestBody CompileDTO compileDTO,
@RequestParam("gid") Long gid) {
return groupProblemService.compileSpj(compileDTO, gid);
}
@PostMapping("/compile-interactive")
public CommonResult<Void> compileInteractive(@RequestBody CompileDTO compileDTO,
@RequestParam("gid") Long gid) {
return groupProblemService.compileInteractive(compileDTO, gid);
}
@PutMapping("/change-problem-auth")
public CommonResult<Void> changeProblemAuth(@RequestParam(value = "pid", required = true) Long pid,
@RequestParam(value = "auth", required = true) Integer auth) {
return groupProblemService.changeProblemAuth(pid, auth);
}
@PutMapping("/apply-public")
public CommonResult<Void> applyPublic(@RequestParam(value = "pid", required = true) Long pid,
@RequestParam(value = "isApplied", required = true) Boolean isApplied) {
return groupProblemService.applyPublic(pid, isApplied);
}
}

@ -0,0 +1,32 @@
package top.hcode.hoj.controller.group;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.vo.OIRankVo;
import top.hcode.hoj.service.group.GroupRankService;
/**
* @Author Himit_ZH
* @Date 2022/4/22
*/
@RestController
@RequestMapping("/api")
public class GroupRankController {
@Autowired
private GroupRankService groupRankService;
@GetMapping("/get-group-rank-list")
public CommonResult<IPage<OIRankVo>> getRankList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "searchUser", required = false) String searchUser,
@RequestParam(value = "gid", required = true) Long gid,
@RequestParam(value = "type", required = true) Integer type) {
return groupRankService.getGroupRankList(limit, currentPage, searchUser, type, gid);
}
}

@ -0,0 +1,104 @@
package top.hcode.hoj.controller.group;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.TrainingDto;
import top.hcode.hoj.pojo.dto.TrainingProblemDto;
import top.hcode.hoj.pojo.entity.training.Training;
import top.hcode.hoj.pojo.entity.training.TrainingProblem;
import top.hcode.hoj.pojo.vo.TrainingVo;
import top.hcode.hoj.service.group.training.GroupTrainingProblemService;
import top.hcode.hoj.service.group.training.GroupTrainingService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
/**
* @Author: LengYun
* @Date: 2022/3/11 13:36
* @Description:
*/
@RestController
@RequiresAuthentication
@RequestMapping("/api/group")
public class GroupTrainingController {
@Autowired
private GroupTrainingService groupTrainingService;
@Autowired
private GroupTrainingProblemService groupTrainingProblemService;
@GetMapping("/get-training-list")
public CommonResult<IPage<TrainingVo>> getTrainingList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "gid", required = true) Long gid) {
return groupTrainingService.getTrainingList(limit, currentPage, gid);
}
@GetMapping("/get-admin-training-list")
public CommonResult<IPage<Training>> getAdminTrainingList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "gid", required = true) Long gid) {
return groupTrainingService.getAdminTrainingList(limit, currentPage, gid);
}
@GetMapping("/training")
public CommonResult<TrainingDto> getTraining(@RequestParam("tid") Long tid) {
return groupTrainingService.getTraining(tid);
}
@PostMapping("/training")
public CommonResult<Void> addTraining(@RequestBody TrainingDto trainingDto) {
return groupTrainingService.addTraining(trainingDto);
}
@PutMapping("/training")
public CommonResult<Void> updateTraining(@RequestBody TrainingDto trainingDto) {
return groupTrainingService.updateTraining(trainingDto);
}
@DeleteMapping("/training")
public CommonResult<Void> deleteTraining(@RequestParam(value = "tid", required = true) Long tid) {
return groupTrainingService.deleteTraining(tid);
}
@PutMapping("/change-training-status")
public CommonResult<Void> changeTrainingStatus(@RequestParam(value = "tid", required = true) Long tid,
@RequestParam(value = "status", required = true) Boolean status) {
return groupTrainingService.changeTrainingStatus(tid, status);
}
@GetMapping("/get-training-problem-list")
public CommonResult<HashMap<String, Object>> getTrainingProblemList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "queryExisted", required = false, defaultValue = "true") Boolean queryExisted,
@RequestParam(value = "tid", required = true) Long tid) {
return groupTrainingProblemService.getTrainingProblemList(limit, currentPage, keyword, queryExisted, tid);
}
@PutMapping("/training-problem")
public CommonResult<Void> updateTrainingProblem(@RequestBody TrainingProblem trainingProblem) {
return groupTrainingProblemService.updateTrainingProblem(trainingProblem);
}
@DeleteMapping("/training-problem")
public CommonResult<Void> deleteTrainingProblem(@RequestParam(value = "pid", required = true) Long pid,
@RequestParam(value = "tid", required = true) Long tid) {
return groupTrainingProblemService.deleteTrainingProblem(pid, tid);
}
@PostMapping("/add-training-problem-from-public")
public CommonResult<Void> addProblemFromPublic(@RequestBody TrainingProblemDto trainingProblemDto) {
return groupTrainingProblemService.addProblemFromPublic(trainingProblemDto);
}
@PostMapping("/add-training-problem-from-group")
public CommonResult<Void> addProblemFromGroup(@RequestParam(value = "problemId", required = true) String problemId,
@RequestParam(value = "tid", required = true) Long tid) {
return groupTrainingProblemService.addProblemFromGroup(problemId, tid);
}
}

@ -0,0 +1,61 @@
package top.hcode.hoj.controller.msg;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.entity.msg.AdminSysNotice;
import top.hcode.hoj.pojo.vo.AdminSysNoticeVo;
import top.hcode.hoj.service.msg.AdminNoticeService;
import javax.annotation.Resource;
/**
* @Author: Himit_ZH
* @Date: 2021/10/1 20:38
* @Description:
*/
@RestController
@RequestMapping("/api/admin/msg")
public class AdminNoticeController {
@Resource
private AdminNoticeService adminNoticeService;
@GetMapping("/notice")
@RequiresAuthentication
@RequiresRoles("root")
public CommonResult<IPage<AdminSysNoticeVo>> getSysNotice(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "type", required = false) String type) {
return adminNoticeService.getSysNotice(limit, currentPage, type);
}
@PostMapping("/notice")
@RequiresAuthentication
@RequiresRoles("root")
public CommonResult<Void> addSysNotice(@RequestBody AdminSysNotice adminSysNotice) {
return adminNoticeService.addSysNotice(adminSysNotice);
}
@DeleteMapping("/notice")
@RequiresAuthentication
@RequiresRoles("root")
public CommonResult<Void> deleteSysNotice(@RequestParam("id") Long id) {
return adminNoticeService.deleteSysNotice(id);
}
@PutMapping("/notice")
@RequiresAuthentication
@RequiresRoles("root")
public CommonResult<Void> updateSysNotice(@RequestBody AdminSysNotice adminSysNotice) {
return adminNoticeService.updateSysNotice(adminSysNotice);
}
}

@ -0,0 +1,43 @@
package top.hcode.hoj.controller.msg;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.vo.SysMsgVo;
import top.hcode.hoj.service.msg.NoticeService;
import javax.annotation.Resource;
/**
* @Author: Himit_ZH
* @Date: 2021/10/1 20:42
* @Description:
*/
@RestController
@RequestMapping("/api/msg")
public class NoticeController {
@Resource
private NoticeService noticeService;
@RequestMapping(value = "/sys", method = RequestMethod.GET)
@RequiresAuthentication
public CommonResult<IPage<SysMsgVo>> getSysNotice(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage) {
return noticeService.getSysNotice(limit, currentPage);
}
@RequestMapping(value = "/mine", method = RequestMethod.GET)
@RequiresAuthentication
public CommonResult<IPage<SysMsgVo>> getMineNotice(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage) {
return noticeService.getMineNotice(limit, currentPage);
}
}

@ -0,0 +1,103 @@
package top.hcode.hoj.controller.msg;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.vo.UserMsgVo;
import top.hcode.hoj.pojo.vo.UserUnreadMsgCountVo;
import top.hcode.hoj.service.msg.UserMessageService;
import javax.annotation.Resource;
/**
* @Author: Himit_ZH
* @Date: 2021/10/1 20:40
* @Description:
*/
@RestController
@RequestMapping("/api/msg")
public class UserMessageController {
@Resource
private UserMessageService userMessageService;
/**
* @MethodName getUnreadMsgCount
* @Description
* @Return
* @Since 2021/10/1
*/
@RequestMapping(value = "/unread", method = RequestMethod.GET)
@RequiresAuthentication
public CommonResult<UserUnreadMsgCountVo> getUnreadMsgCount() {
return userMessageService.getUnreadMsgCount();
}
/**
* @param type Discuss Reply Like Sys Mine
* @MethodName cleanMsg
* @Description type
* @Return
* @Since 2021/10/3
*/
@RequestMapping(value = "/clean", method = RequestMethod.DELETE)
@RequiresAuthentication
public CommonResult<Void> cleanMsg(@RequestParam("type") String type,
@RequestParam(value = "id", required = false) Long id) {
return userMessageService.cleanMsg(type, id);
}
/**
* @param limit
* @param currentPage
* @MethodName getCommentMsg
* @Description
* @Return
* @Since 2021/10/1
*/
@RequestMapping(value = "/comment", method = RequestMethod.GET)
@RequiresAuthentication
public CommonResult<IPage<UserMsgVo>> getCommentMsg(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage) {
return userMessageService.getCommentMsg(limit, currentPage);
}
/**
* @param limit
* @param currentPage
* @MethodName getReplyMsg
* @Description
* @Return
* @Since 2021/10/1
*/
@RequestMapping(value = "/reply", method = RequestMethod.GET)
@RequiresAuthentication
public CommonResult<IPage<UserMsgVo>> getReplyMsg(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage) {
return userMessageService.getReplyMsg(limit, currentPage);
}
/**
* @param limit
* @param currentPage
* @MethodName getLikeMsg
* @Description
* @Return
* @Since 2021/10/1
*/
@RequestMapping(value = "/like", method = RequestMethod.GET)
@RequiresAuthentication
public CommonResult<IPage<UserMsgVo>> getLikeMsg(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage) {
return userMessageService.getLikeMsg(limit, currentPage);
}
}

@ -0,0 +1,95 @@
package top.hcode.hoj.controller.oj;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.pojo.dto.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.vo.*;
import top.hcode.hoj.service.oj.AccountService;
/**
* @Author: Himit_ZH
* @Date: 2020/10/23 12:00
* @Description:
*/
@RestController
@RequestMapping("/api")
public class AccountController {
@Autowired
private AccountService accountService;
/**
* @MethodName checkUsernameOrEmail
* @Description
* @Return
* @Since 2020/11/5
*/
@RequestMapping(value = "/check-username-or-email", method = RequestMethod.POST)
public CommonResult<CheckUsernameOrEmailVo> checkUsernameOrEmail(@RequestBody CheckUsernameOrEmailDto checkUsernameOrEmailDto) {
return accountService.checkUsernameOrEmail(checkUsernameOrEmailDto);
}
/**
* @param uid
* @MethodName getUserHomeInfo
* @Description userHomeACACRating
* @Return CommonResult
* @Since 2021/01/07
*/
@GetMapping("/get-user-home-info")
public CommonResult<UserHomeVo> getUserHomeInfo(@RequestParam(value = "uid", required = false) String uid,
@RequestParam(value = "username", required = false) String username) {
return accountService.getUserHomeInfo(uid, username);
}
/**
* @param uid
* @param username
* @return
* @Description
*/
@GetMapping("/get-user-calendar-heatmap")
public CommonResult<UserCalendarHeatmapVo> getUserCalendarHeatmap(@RequestParam(value = "uid", required = false) String uid,
@RequestParam(value = "username", required = false) String username) {
return accountService.getUserCalendarHeatmap(uid, username);
}
/**
* @MethodName changePassword
* @Params * @param null
* @Description 5
* @Return
* @Since 2021/1/8
*/
@PostMapping("/change-password")
@RequiresAuthentication
public CommonResult<ChangeAccountVo> changePassword(@RequestBody ChangePasswordDto changePasswordDto) {
return accountService.changePassword(changePasswordDto);
}
/**
* @MethodName changeEmail
* @Params * @param null
* @Description 5
* @Return
* @Since 2021/1/9
*/
@PostMapping("/change-email")
@RequiresAuthentication
public CommonResult<ChangeAccountVo> changeEmail(@RequestBody ChangeEmailDto changeEmailDto) {
return accountService.changeEmail(changeEmailDto);
}
@PostMapping("/change-userInfo")
@RequiresAuthentication
public CommonResult<UserInfoVo> changeUserInfo(@RequestBody UserInfoVo userInfoVo) {
return accountService.changeUserInfo(userInfoVo);
}
}

@ -0,0 +1,81 @@
package top.hcode.hoj.controller.oj;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.ReplyDto;
import top.hcode.hoj.pojo.entity.discussion.Comment;
import top.hcode.hoj.pojo.entity.discussion.Reply;
import top.hcode.hoj.pojo.vo.CommentListVo;
import top.hcode.hoj.pojo.vo.CommentVo;
import top.hcode.hoj.pojo.vo.ReplyVo;
import top.hcode.hoj.service.oj.CommentService;
import java.util.List;
/**
* @Author: Himit_ZH
* @Date: 2021/5/5 15:41
* @Description:
*/
@RestController
@RequestMapping("/api")
public class CommentController {
@Autowired
private CommentService commentService;
@GetMapping("/comments")
public CommonResult<CommentListVo> getComments(@RequestParam(value = "cid", required = false) Long cid,
@RequestParam(value = "did", required = false) Integer did,
@RequestParam(value = "limit", required = false, defaultValue = "20") Integer limit,
@RequestParam(value = "currentPage", required = false, defaultValue = "1") Integer currentPage) {
return commentService.getComments(cid, did, limit, currentPage);
}
@PostMapping("/comment")
@RequiresPermissions("comment_add")
@RequiresAuthentication
public CommonResult<CommentVo> addComment(@RequestBody Comment comment) {
return commentService.addComment(comment);
}
@DeleteMapping("/comment")
@RequiresAuthentication
public CommonResult<Void> deleteComment(@RequestBody Comment comment) {
return commentService.deleteComment(comment);
}
@GetMapping("/comment-like")
@RequiresAuthentication
public CommonResult<Void> addCommentLike(@RequestParam("cid") Integer cid,
@RequestParam("toLike") Boolean toLike,
@RequestParam("sourceId") Integer sourceId,
@RequestParam("sourceType") String sourceType) {
return commentService.addCommentLike(cid, toLike, sourceId, sourceType);
}
@GetMapping("/reply")
public CommonResult<List<ReplyVo>> getAllReply(@RequestParam("commentId") Integer commentId,
@RequestParam(value = "cid", required = false) Long cid) {
return commentService.getAllReply(commentId, cid);
}
@PostMapping("/reply")
@RequiresPermissions("reply_add")
@RequiresAuthentication
public CommonResult<ReplyVo> addReply(@RequestBody ReplyDto replyDto) {
return commentService.addReply(replyDto);
}
@DeleteMapping("/reply")
@RequiresAuthentication
public CommonResult<Void> deleteReply(@RequestBody ReplyDto replyDto) {
return commentService.deleteReply(replyDto);
}
}

@ -0,0 +1,77 @@
package top.hcode.hoj.controller.oj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.entity.problem.CodeTemplate;
import top.hcode.hoj.pojo.entity.problem.Language;
import top.hcode.hoj.pojo.entity.problem.Tag;
import top.hcode.hoj.pojo.entity.training.TrainingCategory;
import top.hcode.hoj.pojo.vo.CaptchaVo;
import top.hcode.hoj.pojo.vo.ProblemTagVo;
import top.hcode.hoj.service.oj.CommonService;
import java.util.Collection;
import java.util.List;
/**
* @Author: Himit_ZH
* @Date: 2020/12/12 23:25
* @Description:
*/
@RestController
@RequestMapping("/api")
public class CommonController {
@Autowired
private CommonService commonService;
@GetMapping("/captcha")
public CommonResult<CaptchaVo> getCaptcha() {
return commonService.getCaptcha();
}
@GetMapping("/get-training-category")
public CommonResult<List<TrainingCategory>> getTrainingCategory() {
return commonService.getTrainingCategory();
}
@GetMapping("/get-all-problem-tags")
public CommonResult<List<Tag>> getAllProblemTagsList(@RequestParam(value = "oj", defaultValue = "ME") String oj) {
return commonService.getAllProblemTagsList(oj);
}
@GetMapping("/get-problem-tags-and-classification")
public CommonResult<List<ProblemTagVo>> getProblemTagsAndClassification(@RequestParam(value = "oj", defaultValue = "ME") String oj) {
return commonService.getProblemTagsAndClassification(oj);
}
@GetMapping("/get-problem-tags")
public CommonResult<Collection<Tag>> getProblemTags(Long pid) {
return commonService.getProblemTags(pid);
}
@GetMapping("/languages")
public CommonResult<List<Language>> getLanguages(@RequestParam(value = "pid", required = false) Long pid,
@RequestParam(value = "all", required = false) Boolean all) {
return commonService.getLanguages(pid, all);
}
@GetMapping("/get-problem-languages")
public CommonResult<Collection<Language>> getProblemLanguages(@RequestParam("pid") Long pid) {
return commonService.getProblemLanguages(pid);
}
@GetMapping("/get-problem-code-template")
public CommonResult<List<CodeTemplate>> getProblemCodeTemplate(@RequestParam("pid") Long pid) {
return commonService.getProblemCodeTemplate(pid);
}
}

@ -0,0 +1,83 @@
package top.hcode.hoj.controller.oj;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.CheckACDto;
import top.hcode.hoj.pojo.entity.contest.ContestPrint;
import top.hcode.hoj.pojo.entity.contest.ContestRecord;
import top.hcode.hoj.service.oj.ContestAdminService;
/**
* @Author: Himit_ZH
* @Date: 2021/9/20 13:15
* @Description:
*/
@RestController
@RequestMapping("/api")
public class ContestAdminController {
@Autowired
private ContestAdminService contestAdminService;
/**
* @MethodName getContestACInfo
* @Params * @param null
* @Description ac
* @Return
* @Since 2021/1/17
*/
@GetMapping("/get-contest-ac-info")
@RequiresAuthentication
public CommonResult<IPage<ContestRecord>> getContestACInfo(@RequestParam("cid") Long cid,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "limit", required = false) Integer limit) {
return contestAdminService.getContestACInfo(cid, currentPage, limit);
}
/**
* @MethodName checkContestACInfo
* @Params * @param null
* @Description ac
* @Return
* @Since 2021/1/17
*/
@PutMapping("/check-contest-ac-info")
@RequiresAuthentication
public CommonResult<Void> checkContestACInfo(@RequestBody CheckACDto checkACDto) {
return contestAdminService.checkContestACInfo(checkACDto);
}
@GetMapping("/get-contest-print")
@RequiresAuthentication
public CommonResult<IPage<ContestPrint>> getContestPrint(@RequestParam("cid") Long cid,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "limit", required = false) Integer limit) {
return contestAdminService.getContestPrint(cid, currentPage, limit);
}
/**
* @param id
* @param cid
* @MethodName checkContestStatus
* @Description
* @Return
* @Since 2021/9/20
*/
@PutMapping("/check-contest-print-status")
@RequiresAuthentication
public CommonResult<Void> checkContestPrintStatus(@RequestParam("id") Long id,
@RequestParam("cid") Long cid) {
return contestAdminService.checkContestPrintStatus(id, cid);
}
}

@ -0,0 +1,193 @@
package top.hcode.hoj.controller.oj;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.ContestPrintDto;
import top.hcode.hoj.pojo.dto.ContestRankDto;
import top.hcode.hoj.pojo.dto.RegisterContestDto;
import top.hcode.hoj.pojo.dto.UserReadContestAnnouncementDto;
import top.hcode.hoj.pojo.entity.common.Announcement;
import top.hcode.hoj.pojo.vo.*;
import top.hcode.hoj.service.oj.ContestService;
import java.util.*;
/**
* @Author: Himit_ZH
* @Date: 2020/10/27 21:40
* @Description:
*/
@RestController
@RequestMapping("/api")
public class ContestController {
@Autowired
private ContestService contestService;
/**
* @MethodName getContestList
* @Params * @param null
* @Description
* @Return CommonResult
* @Since 2020/10/27
*/
@GetMapping("/get-contest-list")
public CommonResult<IPage<ContestVo>> getContestList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "status", required = false) Integer status,
@RequestParam(value = "type", required = false) Integer type,
@RequestParam(value = "keyword", required = false) String keyword) {
return contestService.getContestList(limit, currentPage, status, type, keyword);
}
/**
* @MethodName getContestInfo
* @Description
* @Return
* @Since 2020/10/28
*/
@GetMapping("/get-contest-info")
@RequiresAuthentication
public CommonResult<ContestVo> getContestInfo(@RequestParam(value = "cid", required = true) Long cid) {
return contestService.getContestInfo(cid);
}
/**
* @MethodName toRegisterContest
* @Description
* @Return
* @Since 2020/10/28
*/
@PostMapping("/register-contest")
@RequiresAuthentication
public CommonResult<Void> toRegisterContest(@RequestBody RegisterContestDto registerContestDto) {
return contestService.toRegisterContest(registerContestDto);
}
/**
* @MethodName getContestAccess
* @Description 访
* @Return
* @Since 2020/10/28
*/
@RequiresAuthentication
@GetMapping("/get-contest-access")
public CommonResult<AccessVo> getContestAccess(@RequestParam(value = "cid") Long cid) {
return contestService.getContestAccess(cid);
}
/**
* @MethodName getContestProblem
* @Description
* @Return
* @Since 2020/10/28
*/
@GetMapping("/get-contest-problem")
@RequiresAuthentication
public CommonResult<List<ContestProblemVo>> getContestProblem(@RequestParam(value = "cid", required = true) Long cid) {
return contestService.getContestProblem(cid);
}
@GetMapping("/get-contest-problem-details")
@RequiresAuthentication
public CommonResult<ProblemInfoVo> getContestProblemDetails(@RequestParam(value = "cid", required = true) Long cid,
@RequestParam(value = "displayId", required = true) String displayId) {
return contestService.getContestProblemDetails(cid, displayId);
}
@GetMapping("/contest-submissions")
@RequiresAuthentication
public CommonResult<IPage<JudgeVo>> getContestSubmissionList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "onlyMine", required = false) Boolean onlyMine,
@RequestParam(value = "problemID", required = false) String displayId,
@RequestParam(value = "status", required = false) Integer searchStatus,
@RequestParam(value = "username", required = false) String searchUsername,
@RequestParam(value = "contestID", required = true) Long searchCid,
@RequestParam(value = "beforeContestSubmit", required = true) Boolean beforeContestSubmit,
@RequestParam(value = "completeProblemID", defaultValue = "false") Boolean completeProblemID) {
return contestService.getContestSubmissionList(limit,
currentPage,
onlyMine,
displayId,
searchStatus,
searchUsername,
searchCid,
beforeContestSubmit,
completeProblemID);
}
/**
* @MethodName getContestRank
* @Description
* @Return
* @Since 2020/10/28
*/
@PostMapping("/get-contest-rank")
@RequiresAuthentication
public CommonResult<IPage> getContestRank(@RequestBody ContestRankDto contestRankDto) {
return contestService.getContestRank(contestRankDto);
}
/**
* @MethodName getContestAnnouncement
* @Description
* @Return CommonResult
* @Since 2020/10/28
*/
@GetMapping("/get-contest-announcement")
@RequiresAuthentication
public CommonResult<IPage<AnnouncementVo>> getContestAnnouncement(@RequestParam(value = "cid", required = true) Long cid,
@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage) {
return contestService.getContestAnnouncement(cid, limit, currentPage);
}
/**
* @param userReadContestAnnouncementDto
* @MethodName getContestUserNotReadAnnouncement
* @Description idid
* @Return
* @Since 2021/7/17
*/
@PostMapping("/get-contest-not-read-announcement")
@RequiresAuthentication
public CommonResult<List<Announcement>> getContestUserNotReadAnnouncement(@RequestBody UserReadContestAnnouncementDto userReadContestAnnouncementDto) {
return contestService.getContestUserNotReadAnnouncement(userReadContestAnnouncementDto);
}
/**
* @param contestPrintDto
* @MethodName submitPrintText
* @Description
* @Return
* @Since 2021/9/20
*/
@PostMapping("/submit-print-text")
@RequiresAuthentication
public CommonResult<Void> submitPrintText(@RequestBody ContestPrintDto contestPrintDto) {
return contestService.submitPrintText(contestPrintDto);
}
}

@ -0,0 +1,47 @@
package top.hcode.hoj.controller.oj;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.ContestRankDto;
import top.hcode.hoj.pojo.vo.*;
import top.hcode.hoj.service.oj.ContestScoreboardService;
import javax.annotation.Resource;
import java.util.List;
/**
* @Author: Himit_ZH
* @Date: 2022/3/11 22:11
* @Description:
*/
@RestController
@RequestMapping("/api")
public class ContestScoreboardController {
@Resource
private ContestScoreboardService contestScoreboardService;
/**
* @param cid id
* @MethodName getContestOutsideInfo
* @Description
* @Return
* @Since 2021/12/8
*/
@GetMapping("/get-contest-outsize-info")
public CommonResult<ContestOutsideInfo> getContestOutsideInfo(@RequestParam(value = "cid", required = true) Long cid) {
return contestScoreboardService.getContestOutsideInfo(cid);
}
/**
* @MethodName getContestScoreBoard
* @Description
* @Return
* @Since 2021/12/07
*/
@PostMapping("/get-contest-outside-scoreboard")
public CommonResult<List> getContestOutsideScoreboard(@RequestBody ContestRankDto contestRankDto) {
return contestScoreboardService.getContestOutsideScoreboard(contestRankDto);
}
}

@ -0,0 +1,93 @@
package top.hcode.hoj.controller.oj;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.annotation.HOJAccess;
import top.hcode.hoj.annotation.HOJAccessEnum;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.entity.problem.Category;
import top.hcode.hoj.pojo.entity.discussion.Discussion;
import top.hcode.hoj.pojo.entity.discussion.DiscussionReport;
import top.hcode.hoj.pojo.vo.DiscussionVo;
import top.hcode.hoj.service.oj.DiscussionService;
import java.util.List;
/**
* @Author: Himit_ZH
* @Date: 2021/05/04 10:14
* @Description:
*/
@RestController
@RequestMapping("/api")
public class DiscussionController {
@Autowired
private DiscussionService discussionService;
@GetMapping("/get-discussion-list")
@HOJAccess({HOJAccessEnum.PUBLIC_DISCUSSION})
public CommonResult<IPage<Discussion>> getDiscussionList(@RequestParam(value = "limit", required = false, defaultValue = "10") Integer limit,
@RequestParam(value = "currentPage", required = false, defaultValue = "1") Integer currentPage,
@RequestParam(value = "cid", required = false) Integer categoryId,
@RequestParam(value = "pid", required = false) String pid,
@RequestParam(value = "onlyMine", required = false, defaultValue = "false") Boolean onlyMine,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "admin", defaultValue = "false") Boolean admin) {
return discussionService.getDiscussionList(limit, currentPage, categoryId, pid, onlyMine, keyword, admin);
}
@GetMapping("/get-discussion-detail")
public CommonResult<DiscussionVo> getDiscussion(@RequestParam(value = "did", required = true) Integer did) {
return discussionService.getDiscussion(did);
}
@PostMapping("/discussion")
@RequiresPermissions("discussion_add")
@RequiresAuthentication
@HOJAccess({HOJAccessEnum.PUBLIC_DISCUSSION})
public CommonResult<Void> addDiscussion(@RequestBody Discussion discussion) {
return discussionService.addDiscussion(discussion);
}
@PutMapping("/discussion")
@RequiresPermissions("discussion_edit")
@RequiresAuthentication
@HOJAccess({HOJAccessEnum.PUBLIC_DISCUSSION})
public CommonResult<Void> updateDiscussion(@RequestBody Discussion discussion) {
return discussionService.updateDiscussion(discussion);
}
@DeleteMapping("/discussion")
@RequiresPermissions("discussion_del")
@RequiresAuthentication
@HOJAccess({HOJAccessEnum.PUBLIC_DISCUSSION})
public CommonResult<Void> removeDiscussion(@RequestParam("did") Integer did) {
return discussionService.removeDiscussion(did);
}
@GetMapping("/discussion-like")
@RequiresAuthentication
public CommonResult<Void> addDiscussionLike(@RequestParam("did") Integer did,
@RequestParam("toLike") Boolean toLike) {
return discussionService.addDiscussionLike(did, toLike);
}
@GetMapping("/discussion-category")
public CommonResult<List<Category>> getDiscussionCategory() {
return discussionService.getDiscussionCategory();
}
@PostMapping("/discussion-report")
@RequiresAuthentication
public CommonResult<Void> addDiscussionReport(@RequestBody DiscussionReport discussionReport) {
return discussionService.addDiscussionReport(discussionReport);
}
}

@ -0,0 +1,113 @@
package top.hcode.hoj.controller.oj;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.vo.ACMRankVo;
import top.hcode.hoj.pojo.vo.AnnouncementVo;;
import top.hcode.hoj.pojo.vo.ContestVo;
import top.hcode.hoj.service.oj.HomeService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author: Himit_ZH
* @Date: 2020/12/26 14:12
* @Description:
*/
@RestController
@RequestMapping("/api")
public class HomeController {
@Autowired
private HomeService homeService;
/**
* @MethodName getRecentContest
* @Params * @param null
* @Description 14
* @Return CommonResult
* @Since 2020/12/29
*/
@GetMapping("/get-recent-contest")
public CommonResult<List<ContestVo>> getRecentContest() {
return homeService.getRecentContest();
}
/**
* @MethodName getHomeCarousel
* @Params
* @Description
* @Return
* @Since 2021/9/4
*/
@GetMapping("/home-carousel")
public CommonResult<List<HashMap<String, Object>>> getHomeCarousel() {
return homeService.getHomeCarousel();
}
/**
* @MethodName getRecentSevenACRank
* @Params * @param null
* @Description 7
* @Return
* @Since 2021/1/15
*/
@GetMapping("/get-recent-seven-ac-rank")
public CommonResult<List<ACMRankVo>> getRecentSevenACRank() {
return homeService.getRecentSevenACRank();
}
/**
* @MethodName getRecentOtherContest
* @Params * @param null
* @Description OJ
* @Return CommonResult
* @Since 2020/1/15
*/
@GetMapping("/get-recent-other-contest")
public CommonResult<List<HashMap<String, Object>>> getRecentOtherContest() {
return homeService.getRecentOtherContest();
}
/**
* @MethodName getCommonAnnouncement
* @Params * @param null
* @Description
* @Return CommonResult
* @Since 2020/12/29
*/
@GetMapping("/get-common-announcement")
public CommonResult<IPage<AnnouncementVo>> getCommonAnnouncement(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage) {
return homeService.getCommonAnnouncement(limit, currentPage);
}
/**
* @MethodName getWebConfig
* @Params * @param null
* @Description
* @Return CommonResult
* @Since 2020/12/29
*/
@GetMapping("/get-website-config")
public CommonResult<Map<Object, Object>> getWebConfig() {
return homeService.getWebConfig();
}
}

@ -0,0 +1,160 @@
package top.hcode.hoj.controller.oj;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.SubmitIdListDto;
import top.hcode.hoj.pojo.dto.TestJudgeDto;
import top.hcode.hoj.pojo.dto.SubmitJudgeDto;
import top.hcode.hoj.pojo.entity.judge.Judge;
import top.hcode.hoj.pojo.entity.judge.JudgeCase;
import top.hcode.hoj.pojo.vo.JudgeVo;
import top.hcode.hoj.pojo.vo.SubmissionInfoVo;
import top.hcode.hoj.pojo.vo.TestJudgeVo;
import top.hcode.hoj.service.oj.JudgeService;
import java.util.HashMap;
import java.util.List;
/**
* @Author: Himit_ZH
* @Date: 2020/10/27 20:52
* @Description:
*/
@RestController
@RequestMapping("/api")
public class JudgeController {
@Autowired
private JudgeService judgeService;
/**
* @param limit
* @param currentPage
* @param onlyMine
* @param searchPid
* @param searchStatus
* @param searchUsername
* @param completeProblemID
* @MethodName getJudgeList
* @Description
* @Return CommonResult
* @Since 2020/10/29
*/
@GetMapping("/get-submission-list")
public CommonResult<IPage<JudgeVo>> getJudgeList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "onlyMine", required = false) Boolean onlyMine,
@RequestParam(value = "problemID", required = false) String searchPid,
@RequestParam(value = "status", required = false) Integer searchStatus,
@RequestParam(value = "username", required = false) String searchUsername,
@RequestParam(value = "completeProblemID", defaultValue = "false") Boolean completeProblemID,
@RequestParam(value = "gid", required = false) Long gid) {
return judgeService.getJudgeList(limit, currentPage, onlyMine, searchPid, searchStatus, searchUsername, completeProblemID, gid);
}
/**
* @MethodName getSubmission
* @Description
* @Return CommonResult
* @Since 2021/1/2
*/
@GetMapping("/get-submission-detail")
public CommonResult<SubmissionInfoVo> getSubmission(@RequestParam(value = "submitId", required = true) Long submitId) {
return judgeService.getSubmission(submitId);
}
/**
* @MethodName submitProblemJudge
* @Description
* @Return CommonResult
* @Since 2020/10/30
*/
@RequiresAuthentication
@RequiresPermissions("submit")
@RequestMapping(value = "/submit-problem-judge", method = RequestMethod.POST)
public CommonResult<Judge> submitProblemJudge(@RequestBody SubmitJudgeDto judgeDto) {
return judgeService.submitProblemJudge(judgeDto);
}
@RequiresAuthentication
@RequiresPermissions("submit")
@RequestMapping(value = "/submit-problem-test-judge", method = RequestMethod.POST)
public CommonResult<String> submitProblemTestJudge(@RequestBody TestJudgeDto testJudgeDto) {
return judgeService.submitProblemTestJudge(testJudgeDto);
}
@RequiresAuthentication
@GetMapping("/get-test-judge-result")
public CommonResult<TestJudgeVo> getTestJudgeResult(@RequestParam("testJudgeKey") String testJudgeKey) {
return judgeService.getTestJudgeResult(testJudgeKey);
}
/**
* @MethodName resubmit
* @Description 60s
* @Return
* @Since 2021/2/12
*/
@RequiresAuthentication
@GetMapping(value = "/resubmit")
public CommonResult<Judge> resubmit(@RequestParam("submitId") Long submitId) {
return judgeService.resubmit(submitId);
}
/**
* @MethodName updateSubmission
* @Description
* @Return CommonResult
* @Since 2021/1/2
*/
@PutMapping("/submission")
@RequiresAuthentication
public CommonResult<Void> updateSubmission(@RequestBody Judge judge) {
return judgeService.updateSubmission(judge);
}
/**
* @MethodName checkJudgeResult
* @Description PendingJudging
* @Return
* @Since 2021/1/3
*/
@RequestMapping(value = "/check-submissions-status", method = RequestMethod.POST)
public CommonResult<HashMap<Long, Object>> checkCommonJudgeResult(@RequestBody SubmitIdListDto submitIdListDto) {
return judgeService.checkCommonJudgeResult(submitIdListDto);
}
/**
* @param submitIdListDto
* @MethodName checkContestJudgeResult
* @Description
* @Return
* @Since 2021/6/11
*/
@RequestMapping(value = "/check-contest-submissions-status", method = RequestMethod.POST)
@RequiresAuthentication
public CommonResult<HashMap<Long, Object>> checkContestJudgeResult(@RequestBody SubmitIdListDto submitIdListDto) {
return judgeService.checkContestJudgeResult(submitIdListDto);
}
/**
* @param submitId
* @MethodName getJudgeCase
* @Description idIO
* @Return
* @Since 2020/10/29
*/
@GetMapping("/get-all-case-result")
public CommonResult<List<JudgeCase>> getALLCaseResult(@RequestParam(value = "submitId", required = true) Long submitId) {
return judgeService.getALLCaseResult(submitId);
}
}

@ -0,0 +1,109 @@
package top.hcode.hoj.controller.oj;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.LoginDto;
import top.hcode.hoj.pojo.dto.RegisterDto;
import top.hcode.hoj.pojo.dto.ApplyResetPasswordDto;
import top.hcode.hoj.pojo.dto.ResetPasswordDto;
import top.hcode.hoj.pojo.vo.RegisterCodeVo;
import top.hcode.hoj.pojo.vo.UserInfoVo;
import top.hcode.hoj.service.oj.PassportService;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @Author: Himit_ZH
* @Date: 2022/3/11 17:00
* @Description:
*/
@RestController
@RequestMapping("/api")
public class PassportController {
@Autowired
private PassportService passportService;
/**
* @param loginDto
* @MethodName login
* @Description
* @Return CommonResult
* @Since 2020/10/24
*/
@PostMapping("/login")
public CommonResult<UserInfoVo> login(@Validated @RequestBody LoginDto loginDto, HttpServletResponse response, HttpServletRequest request) {
return passportService.login(loginDto, response, request);
}
/**
* @MethodName getRegisterCode
* @Description 6
* @Return
* @Since 2020/10/26
*/
@RequestMapping(value = "/get-register-code", method = RequestMethod.GET)
public CommonResult<RegisterCodeVo> getRegisterCode(@RequestParam(value = "email", required = true) String email) {
return passportService.getRegisterCode(email);
}
/**
* @param registerDto
* @MethodName register
* @Description RegisterDto
* @Return
* @Since 2020/10/24
*/
@PostMapping("/register")
public CommonResult<Void> register(@Validated @RequestBody RegisterDto registerDto) {
return passportService.register(registerDto);
}
/**
* @param applyResetPasswordDto
* @MethodName applyResetPassword
* @Description
* @Return
* @Since 2020/11/6
*/
@PostMapping("/apply-reset-password")
public CommonResult<Void> applyResetPassword(@RequestBody ApplyResetPasswordDto applyResetPasswordDto) {
return passportService.applyResetPassword(applyResetPasswordDto);
}
/**
* @param resetPasswordDto
* @MethodName resetPassword
* @Description
* @Return
* @Since 2020/11/6
*/
@PostMapping("/reset-password")
public CommonResult<Void> resetPassword(@RequestBody ResetPasswordDto resetPasswordDto) {
return passportService.resetPassword(resetPasswordDto);
}
/**
* @MethodName logout
* @Description 退jwtredis
* @Return CommonResult
* @Since 2020/10/24
*/
@GetMapping("/logout")
@RequiresAuthentication
public CommonResult<Void> logout() {
SecurityUtils.getSubject().logout();
return CommonResult.successResponse("登出成功!");
}
}

@ -0,0 +1,88 @@
package top.hcode.hoj.controller.oj;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.PidListDto;
import top.hcode.hoj.pojo.vo.*;
import top.hcode.hoj.service.oj.ProblemService;
import java.util.*;
/**
* @Author: Himit_ZH
* @Date: 2020/10/27 13:24
* @Description:
*/
@RestController
@RequestMapping("/api")
public class ProblemController {
@Autowired
private ProblemService problemService;
/**
* @param currentPage
* @param keyword
* @param tagId
* @param difficulty
* @param oj
* @MethodName getProblemList
* @Description
* @Return CommonResult
* @Since 2020/10/27
*/
@RequestMapping(value = "/get-problem-list", method = RequestMethod.GET)
public CommonResult<Page<ProblemVo>> getProblemList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "tagId", required = false) List<Long> tagId,
@RequestParam(value = "difficulty", required = false) Integer difficulty,
@RequestParam(value = "oj", required = false) String oj) {
return problemService.getProblemList(limit, currentPage, keyword, tagId, difficulty, oj);
}
/**
* @MethodName getRandomProblem
* @Description
* @Return CommonResult
* @Since 2020/10/27
*/
@GetMapping("/get-random-problem")
public CommonResult<RandomProblemVo> getRandomProblem() {
return problemService.getRandomProblem();
}
/**
* @param pidListDto
* @MethodName getUserProblemStatus
* @Description
* @Return CommonResult
* @Since 2020/12/29
*/
@RequiresAuthentication
@PostMapping("/get-user-problem-status")
public CommonResult<HashMap<Long, Object>> getUserProblemStatus(@Validated @RequestBody PidListDto pidListDto) {
return problemService.getUserProblemStatus(pidListDto);
}
/**
* @param problemId
* @MethodName getProblemInfo
* @Description auth1
* @Return CommonResult
* @Since 2020/10/27
*/
@RequestMapping(value = "/get-problem-detail", method = RequestMethod.GET)
public CommonResult<ProblemInfoVo> getProblemInfo(@RequestParam(value = "problemId", required = true) String problemId,
@RequestParam(value = "gid", required = false) Long gid) {
return problemService.getProblemInfo(problemId,gid);
}
}

@ -0,0 +1,38 @@
package top.hcode.hoj.controller.oj;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.service.oj.RankService;
/**
* @Author: Himit_ZH
* @Date: 2020/10/27 20:53
* @Description:
*/
@RestController
@RequestMapping("/api")
public class RankController {
@Autowired
private RankService rankService;
/**
* @MethodName get-rank-list
* @Params * @param null
* @Description
* @Return CommonResult
* @Since 2020/10/27
*/
@GetMapping("/get-rank-list")
public CommonResult<IPage> getRankList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "searchUser", required = false) String searchUser,
@RequestParam(value = "type", required = true) Integer type) {
return rankService.getRankList(limit, currentPage, searchUser, type);
}
}

@ -0,0 +1,121 @@
package top.hcode.hoj.controller.oj;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.RegisterTrainingDto;
import top.hcode.hoj.pojo.vo.*;
import top.hcode.hoj.service.oj.TrainingService;
import javax.annotation.Resource;
import java.util.List;
/**
* @Author: Himit_ZH
* @Date: 2021/11/19 21:42
* @Description:
*/
@RestController
@RequestMapping("/api")
public class TrainingController {
@Resource
private TrainingService trainingService;
/**
* @param limit
* @param currentPage
* @param keyword
* @param categoryId
* @param auth
* @MethodName getTrainingList
* @Description
* @Return
* @Since 2021/11/20
*/
@GetMapping("/get-training-list")
public CommonResult<IPage<TrainingVo>> getTrainingList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "categoryId", required = false) Long categoryId,
@RequestParam(value = "auth", required = false) String auth) {
return trainingService.getTrainingList(limit, currentPage, keyword, categoryId, auth);
}
/**
* @param tid
* @MethodName getTraining
* @Description tid
* @Return
* @Since 2021/11/20
*/
@GetMapping("/get-training-detail")
@RequiresAuthentication
public CommonResult<TrainingVo> getTraining(@RequestParam(value = "tid") Long tid) {
return trainingService.getTraining(tid);
}
/**
* @param tid
* @MethodName getTrainingProblemList
* @Description tid
* @Return
* @Since 2021/11/20
*/
@GetMapping("/get-training-problem-list")
@RequiresAuthentication
public CommonResult<List<ProblemVo>> getTrainingProblemList(@RequestParam(value = "tid") Long tid) {
return trainingService.getTrainingProblemList(tid);
}
/**
* @param registerTrainingDto
* @MethodName toRegisterTraining
* @Description
* @Return
* @Since 2021/11/20
*/
@PostMapping("/register-training")
@RequiresAuthentication
public CommonResult<Void> toRegisterTraining(@RequestBody RegisterTrainingDto registerTrainingDto) {
return trainingService.toRegisterTraining(registerTrainingDto);
}
/**
* @param tid
* @MethodName getTrainingAccess
* @Description
* @Return
* @Since 2021/11/20
*/
@RequiresAuthentication
@GetMapping("/get-training-access")
public CommonResult<AccessVo> getTrainingAccess(@RequestParam(value = "tid") Long tid) {
return trainingService.getTrainingAccess(tid);
}
/**
* @param tid
* @param limit
* @param currentPage
* @MethodName getTrainingRank
* @Description
* @Return
* @Since 2021/11/22
*/
@GetMapping("/get-training-rank")
@RequiresAuthentication
public CommonResult<IPage<TrainingRankVo>> getTrainingRank(@RequestParam(value = "tid", required = true) Long tid,
@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage) {
return trainingService.getTrainingRank(tid, limit, currentPage);
}
}

@ -0,0 +1,326 @@
package top.hcode.hoj.crawler.language;
import cn.hutool.core.util.ReUtil;
import top.hcode.hoj.pojo.entity.problem.Language;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;
/**
* @Author: Himit_ZH
* @Date: 2022/1/28 21:48
* @Description:
*/
public class AtCoderLanguageStrategy extends LanguageStrategy {
@Override
public String getLanguageNameById(String id) {
return null;
}
@Override
public List<Language> buildLanguageListByIds(List<Language> allLanguageList, List<String> langIdList) {
return null;
}
@Override
public Collection<String> getLangList() {
HashMap<String, String> languageMap = new HashMap<>();
languageMap.put("C (GCC 9.2.1)", "4001");
languageMap.put("C (Clang 10.0.0)", "4002");
languageMap.put("C++ (GCC 9.2.1)", "4003");
languageMap.put("C++ (Clang 10.0.0)", "4004");
languageMap.put("Java (OpenJDK 11.0.6)", "4005");
languageMap.put("Python (3.8.2)", "4006");
languageMap.put("Bash (5.0.11)", "4007");
languageMap.put("bc (1.07.1)", "4008");
languageMap.put("Awk (GNU Awk 4.1.4)", "4009");
languageMap.put("C# (.NET Core 3.1.201)", "4010");
languageMap.put("C# (Mono-mcs 6.8.0.105)", "4011");
languageMap.put("C# (Mono-csc 3.5.0)", "4012");
languageMap.put("Clojure (1.10.1.536)", "4013");
languageMap.put("Crystal (0.33.0)", "4014");
languageMap.put("D (DMD 2.091.0)", "4015");
languageMap.put("D (GDC 9.2.1)", "4016");
languageMap.put("D (LDC 1.20.1)", "4017");
languageMap.put("Dart (2.7.2)", "4018");
languageMap.put("dc (1.4.1)", "4019");
languageMap.put("Erlang (22.3)", "4020");
languageMap.put("Elixir (1.10.2)", "4021");
languageMap.put("F# (.NET Core 3.1.201)", "4022");
languageMap.put("F# (Mono 10.2.3)", "4023");
languageMap.put("Forth (gforth 0.7.3)", "4024");
languageMap.put("Fortran (GNU Fortran 9.2.1)", "4025");
languageMap.put("Go (1.14.1)", "4026");
languageMap.put("Haskell (GHC 8.8.3)", "4027");
languageMap.put("Haxe (4.0.3); js", "4028");
languageMap.put("Haxe (4.0.3); Java", "4029");
languageMap.put("JavaScript (Node.js 12.16.1)", "4030");
languageMap.put("Julia (1.4.0)", "4031");
languageMap.put("Kotlin (1.3.71)", "4032");
languageMap.put("Lua (Lua 5.3.5)", "4033");
languageMap.put("Lua (LuaJIT 2.1.0)", "4034");
languageMap.put("Dash (0.5.8)", "4035");
languageMap.put("Nim (1.0.6)", "4036");
languageMap.put("Objective-C (Clang 10.0.0)", "4037");
languageMap.put("Common Lisp (SBCL 2.0.3)", "4038");
languageMap.put("OCaml (4.10.0)", "4039");
languageMap.put("Octave (5.2.0)", "4040");
languageMap.put("Pascal (FPC 3.0.4)", "4041");
languageMap.put("Perl (5.26.1)", "4042");
languageMap.put("Raku (Rakudo 2020.02.1)", "4043");
languageMap.put("PHP (7.4.4)", "4044");
languageMap.put("Prolog (SWI-Prolog 8.0.3)", "4045");
languageMap.put("PyPy2 (7.3.0)", "4046");
languageMap.put("PyPy3 (7.3.0)", "4047");
languageMap.put("Racket (7.6)", "4048");
languageMap.put("Ruby (2.7.1)", "4049");
languageMap.put("Rust (1.42.0)", "4050");
languageMap.put("Scala (2.13.1)", "4051");
languageMap.put("Java (OpenJDK 1.8.0)", "4052");
languageMap.put("Scheme (Gauche 0.9.9)", "4053");
languageMap.put("Standard ML (MLton 20130715)", "4054");
languageMap.put("Swift (5.2.1)", "4055");
languageMap.put("Text (cat 8.28)", "4056");
languageMap.put("TypeScript (3.8)", "4057");
languageMap.put("Visual Basic (.NET Core 3.1.101)", "4058");
languageMap.put("Zsh (5.4.2)", "4059");
languageMap.put("COBOL - Fixed (OpenCOBOL 1.1.0)", "4060");
languageMap.put("COBOL - Free (OpenCOBOL 1.1.0)", "4061");
languageMap.put("Brainfuck (bf 20041219)", "4062");
languageMap.put("Ada2012 (GNAT 9.2.1)", "4063");
languageMap.put("Unlambda (2.0.0)", "4064");
languageMap.put("Cython (0.29.16)", "4065");
languageMap.put("Sed (4.4)", "4066");
languageMap.put("Vim (8.2.0460)", "4067");
return languageMap.keySet();
}
@Override
public String getOJName() {
return "AC";
}
@Override
protected String getLangContentType(String name) {
HashMap<String, String> nameMapContestType = new HashMap<>();
nameMapContestType.put("C (GCC 9.2.1)", "text/x-csrc");
nameMapContestType.put("C (Clang 10.0.0)", "text/x-csrc");
nameMapContestType.put("C++ (GCC 9.2.1)", "text/x-c++src");
nameMapContestType.put("C++ (Clang 10.0.0)", "text/x-c++src");
nameMapContestType.put("Java (OpenJDK 11.0.6)", "text/x-java");
nameMapContestType.put("Python (3.8.2)", "text/x-python");
nameMapContestType.put("Bash (5.0.11)", "text/x-sh");
nameMapContestType.put("bc (1.07.1)", "text/x-bc");
nameMapContestType.put("Awk (GNU Awk 4.1.4)", "text/x-sh");
nameMapContestType.put("C# (.NET Core 3.1.201)", "text/x-csharp");
nameMapContestType.put("C# (Mono-mcs 6.8.0.105)", "text/x-csharp");
nameMapContestType.put("C# (Mono-csc 3.5.0)", "text/x-csharp");
nameMapContestType.put("Clojure (1.10.1.536)", "text/x-clojure");
nameMapContestType.put("Crystal (0.33.0)", "text/x-crystal");
nameMapContestType.put("D (DMD 2.091.0)", "text/x-d");
nameMapContestType.put("D (GDC 9.2.1)", "text/x-d");
nameMapContestType.put("D (LDC 1.20.1)", "text/x-d");
nameMapContestType.put("Dart (2.7.2)", "application/dart");
nameMapContestType.put("dc (1.4.1)", "text/x-dc");
nameMapContestType.put("Erlang (22.3)", "text/x-erlang");
nameMapContestType.put("Elixir (1.10.2)", "elixir");
nameMapContestType.put("F# (.NET Core 3.1.201)", "text/x-fsharp");
nameMapContestType.put("F# (Mono 10.2.3)", "text/x-fsharp");
nameMapContestType.put("Forth (gforth 0.7.3)", "text/x-forth");
nameMapContestType.put("Fortran (GNU Fortran 9.2.1)", "text/x-fortran");
nameMapContestType.put("Go (1.14.1)", "text/x-go");
nameMapContestType.put("Haskell (GHC 8.8.3)", "text/x-haskell");
nameMapContestType.put("Haxe (4.0.3); js", "text/x-haxe");
nameMapContestType.put("Haxe (4.0.3); Java", "text/x-haxe");
nameMapContestType.put("JavaScript (Node.js 12.16.1)", "text/javascript");
nameMapContestType.put("Julia (1.4.0)", "text/x-julia");
nameMapContestType.put("Kotlin (1.3.71)", "text/x-kotlin");
nameMapContestType.put("Lua (Lua 5.3.5)", "text/x-lua");
nameMapContestType.put("Lua (LuaJIT 2.1.0)", "text/x-lua");
nameMapContestType.put("Dash (0.5.8)", "text/x-sh");
nameMapContestType.put("Nim (1.0.6)", "text/x-nim");
nameMapContestType.put("Objective-C (Clang 10.0.0)", "text/x-objectivec");
nameMapContestType.put("Common Lisp (SBCL 2.0.3)", "text/x-common-lisp");
nameMapContestType.put("OCaml (4.10.0)", "text/x-ocaml");
nameMapContestType.put("Octave (5.2.0)", "text/x-octave");
nameMapContestType.put("Pascal (FPC 3.0.4)", "text/x-pascal");
nameMapContestType.put("Perl (5.26.1)", "text/x-perl");
nameMapContestType.put("Raku (Rakudo 2020.02.1)", "text/x-perl");
nameMapContestType.put("PHP (7.4.4)", "text/x-php");
nameMapContestType.put("Prolog (SWI-Prolog 8.0.3)", "text/x-prolog");
nameMapContestType.put("PyPy2 (7.3.0)", "text/x-python");
nameMapContestType.put("PyPy3 (7.3.0)", "text/x-python");
nameMapContestType.put("Racket (7.6)", "text/x-racket");
nameMapContestType.put("Ruby (2.7.1)", "text/x-ruby");
nameMapContestType.put("Rust (1.42.0)", "text/x-rustsrc");
nameMapContestType.put("Scala (2.13.1)", "text/x-scala");
nameMapContestType.put("Java (OpenJDK 1.8.0)", "text/x-java");
nameMapContestType.put("Scheme (Gauche 0.9.9)", "text/x-scheme");
nameMapContestType.put("Standard ML (MLton 20130715)", "text/x-sml");
nameMapContestType.put("Swift (5.2.1)", "text/x-swift");
nameMapContestType.put("Text (cat 8.28)", "text/plain");
nameMapContestType.put("TypeScript (3.8)", "text/typescript");
nameMapContestType.put("Visual Basic (.NET Core 3.1.101)", "text/x-vb");
nameMapContestType.put("Zsh (5.4.2)", "text/x-sh");
nameMapContestType.put("COBOL - Fixed (OpenCOBOL 1.1.0)", "text/x-cobol");
nameMapContestType.put("COBOL - Free (OpenCOBOL 1.1.0)", "text/x-cobol");
nameMapContestType.put("Brainfuck (bf 20041219)", "text/x-brainfuck");
nameMapContestType.put("Ada2012 (GNAT 9.2.1)", "text/x-ada");
nameMapContestType.put("Unlambda (2.0.0)", "text/x-unlambda");
nameMapContestType.put("Cython (0.29.16)", "text/x-python");
nameMapContestType.put("Sed (4.4)", "text/x-sh");
nameMapContestType.put("Vim (8.2.0460)", "text/x-vim");
return nameMapContestType.get(name);
}
public static void main(String[] args) {
String body = "<option value=\"4001\" data-mime=\"text/x-csrc\">C (GCC 9.2.1)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4002\" data-mime=\"text/x-csrc\">C (Clang 10.0.0)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4003\" data-mime=\"text/x-c++src\">C++ (GCC 9.2.1)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4004\" data-mime=\"text/x-c++src\">C++ (Clang 10.0.0)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4005\" data-mime=\"text/x-java\">Java (OpenJDK 11.0.6)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4006\" data-mime=\"text/x-python\">Python (3.8.2)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4007\" data-mime=\"text/x-sh\">Bash (5.0.11)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4008\" data-mime=\"text/x-bc\">bc (1.07.1)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4009\" data-mime=\"text/x-sh\">Awk (GNU Awk 4.1.4)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4010\" data-mime=\"text/x-csharp\">C# (.NET Core 3.1.201)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4011\" data-mime=\"text/x-csharp\">C# (Mono-mcs 6.8.0.105)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4012\" data-mime=\"text/x-csharp\">C# (Mono-csc 3.5.0)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4013\" data-mime=\"text/x-clojure\">Clojure (1.10.1.536)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4014\" data-mime=\"text/x-crystal\">Crystal (0.33.0)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4015\" data-mime=\"text/x-d\">D (DMD 2.091.0)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4016\" data-mime=\"text/x-d\">D (GDC 9.2.1)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4017\" data-mime=\"text/x-d\">D (LDC 1.20.1)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4018\" data-mime=\"application/dart\">Dart (2.7.2)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4019\" data-mime=\"text/x-dc\">dc (1.4.1)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4020\" data-mime=\"text/x-erlang\">Erlang (22.3)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4021\" data-mime=\"elixir\">Elixir (1.10.2)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4022\" data-mime=\"text/x-fsharp\">F# (.NET Core 3.1.201)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4023\" data-mime=\"text/x-fsharp\">F# (Mono 10.2.3)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4024\" data-mime=\"text/x-forth\">Forth (gforth 0.7.3)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4025\" data-mime=\"text/x-fortran\">Fortran (GNU Fortran 9.2.1)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4026\" data-mime=\"text/x-go\">Go (1.14.1)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4027\" data-mime=\"text/x-haskell\">Haskell (GHC 8.8.3)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4028\" data-mime=\"text/x-haxe\">Haxe (4.0.3); js</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4029\" data-mime=\"text/x-haxe\">Haxe (4.0.3); Java</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4030\" data-mime=\"text/javascript\">JavaScript (Node.js 12.16.1)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4031\" data-mime=\"text/x-julia\">Julia (1.4.0)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4032\" data-mime=\"text/x-kotlin\">Kotlin (1.3.71)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4033\" data-mime=\"text/x-lua\">Lua (Lua 5.3.5)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4034\" data-mime=\"text/x-lua\">Lua (LuaJIT 2.1.0)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4035\" data-mime=\"text/x-sh\">Dash (0.5.8)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4036\" data-mime=\"text/x-nim\">Nim (1.0.6)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4037\" data-mime=\"text/x-objectivec\">Objective-C (Clang 10.0.0)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4038\" data-mime=\"text/x-common-lisp\">Common Lisp (SBCL 2.0.3)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4039\" data-mime=\"text/x-ocaml\">OCaml (4.10.0)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4040\" data-mime=\"text/x-octave\">Octave (5.2.0)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4041\" data-mime=\"text/x-pascal\">Pascal (FPC 3.0.4)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4042\" data-mime=\"text/x-perl\">Perl (5.26.1)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4043\" data-mime=\"text/x-perl\">Raku (Rakudo 2020.02.1)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4044\" data-mime=\"text/x-php\">PHP (7.4.4)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4045\" data-mime=\"text/x-prolog\">Prolog (SWI-Prolog 8.0.3)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4046\" data-mime=\"text/x-python\">PyPy2 (7.3.0)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4047\" data-mime=\"text/x-python\">PyPy3 (7.3.0)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4048\" data-mime=\"text/x-racket\">Racket (7.6)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4049\" data-mime=\"text/x-ruby\">Ruby (2.7.1)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4050\" data-mime=\"text/x-rustsrc\">Rust (1.42.0)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4051\" data-mime=\"text/x-scala\">Scala (2.13.1)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4052\" data-mime=\"text/x-java\">Java (OpenJDK 1.8.0)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4053\" data-mime=\"text/x-scheme\">Scheme (Gauche 0.9.9)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4054\" data-mime=\"text/x-sml\">Standard ML (MLton 20130715)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4055\" data-mime=\"text/x-swift\">Swift (5.2.1)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4056\" data-mime=\"text/plain\">Text (cat 8.28)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4057\" data-mime=\"text/typescript\">TypeScript (3.8)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4058\" data-mime=\"text/x-vb\">Visual Basic (.NET Core 3.1.101)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4059\" data-mime=\"text/x-sh\">Zsh (5.4.2)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4060\" data-mime=\"text/x-cobol\">COBOL - Fixed (OpenCOBOL 1.1.0)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4061\" data-mime=\"text/x-cobol\">COBOL - Free (OpenCOBOL 1.1.0)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4062\" data-mime=\"text/x-brainfuck\">Brainfuck (bf 20041219)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4063\" data-mime=\"text/x-ada\">Ada2012 (GNAT 9.2.1)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4064\" data-mime=\"text/x-unlambda\">Unlambda (2.0.0)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4065\" data-mime=\"text/x-python\">Cython (0.29.16)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4066\" data-mime=\"text/x-sh\">Sed (4.4)</option>\n" +
"\t\t\t\t\t\t\n" +
"\t\t\t\t\t\t\t<option value=\"4067\" data-mime=\"text/x-vim\">Vim (8.2.0460)</option>";
Pattern pattern1 = Pattern.compile("<option value=\"([\\s\\S]*?)\" data-mime=\"[\\s\\S]*?\">[\\s\\S]*?</option>");
Pattern pattern2 = Pattern.compile("<option value=\"[\\s\\S]*?\" data-mime=\"[\\s\\S]*?\">([\\s\\S]*?)</option>");
Pattern pattern3 = Pattern.compile("<option value=\"[\\s\\S]*?\" data-mime=\"([\\s\\S]*?)\">[\\s\\S]*?</option>");
List<String> allGroups1 = ReUtil.findAll(pattern1, body, 1);
List<String> allGroups2 = ReUtil.findAll(pattern2, body, 1);
List<String> allGroups3 = ReUtil.findAll(pattern3, body, 1);
for (int i = 0; i < allGroups1.size(); i++) {
System.out.println("nameMapContestType.put(\"" + allGroups2.get(i) + "\", \"" + allGroups3.get(i) + "\");");
}
for (int i = 0; i < allGroups1.size(); i++) {
System.out.println("languageMap.put(\"" + allGroups2.get(i) + "\", \"" + allGroups1.get(i) + "\");");
}
}
}

@ -0,0 +1,45 @@
package top.hcode.hoj.crawler.language;
import top.hcode.hoj.pojo.entity.problem.Language;
import top.hcode.hoj.utils.Constants;
;import java.util.List;
/**
* @Author: Himit_ZH
* @Date: 2022/1/27 21:15
* @Description:
*/
public class LanguageContext {
private LanguageStrategy languageStrategy;
public LanguageContext(LanguageStrategy languageStrategy) {
this.languageStrategy = languageStrategy;
}
public LanguageContext(Constants.RemoteOJ remoteOJ) {
switch (remoteOJ) {
case SPOJ:
languageStrategy = new SPOJLanguageStrategy();
break;
case ATCODER:
languageStrategy = new AtCoderLanguageStrategy();
break;
default:
throw new RuntimeException("未知的OJ的名字暂时不支持");
}
}
public List<Language> buildLanguageList(){
return languageStrategy.buildLanguageList();
}
public String getLanguageNameById(String id) {
return languageStrategy.getLanguageNameById(id);
}
public List<Language> buildLanguageListByIds(List<Language> allLanguageList, List<String> langIdList) {
return languageStrategy.buildLanguageListByIds(allLanguageList, langIdList);
}
}

@ -0,0 +1,119 @@
package top.hcode.hoj.crawler.language;
import top.hcode.hoj.pojo.entity.problem.Language;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* @Author: Himit_ZH
* @Date: 2022/1/27 21:14
* @Description:
*/
public abstract class LanguageStrategy {
public abstract String getLanguageNameById(String id);
public abstract List<Language> buildLanguageListByIds(List<Language> allLanguageList, List<String> langIdList);
public abstract Collection<String> getLangList();
public abstract String getOJName();
public List<Language> buildLanguageList() {
List<Language> languageList = new ArrayList<>();
for (String lang : getLangList()) {
languageList.add(new Language()
.setName(lang)
.setDescription(lang)
.setOj(getOJName())
.setContentType(getLangContentType(lang)));
}
return languageList;
}
private final static List<String> CLang = Arrays.asList("c", "gcc", "clang");
private final static List<String> CPPLang = Arrays.asList("c++", "g++", "clang++");
private final static List<String> PythonLang = Arrays.asList("python", "pypy");
private final static List<String> JSLang = Arrays.asList("node", "javascript");
protected String getLangContentType(String name) {
String lowerName = name.toLowerCase();
for (String lang : CPPLang) {
if (lowerName.contains(lang)) {
return "text/x-c++src";
}
}
if (lowerName.contains("c#")) {
return "text/x-csharp";
}
for (String lang : CLang) {
if (lowerName.contains(lang)) {
return "text/x-csrc";
}
}
for (String lang : PythonLang) {
if (lowerName.contains(lang)) {
return "text/x-python";
}
}
for (String lang : JSLang) {
if (lowerName.contains(lang)) {
return "text/javascript";
}
}
if (lowerName.contains("scala")) {
return "text/x-scala";
}
if (lowerName.contains("java")) {
return "text/x-java";
}
if (lowerName.contains("pascal")) {
return "text/x-pascal";
}
if (lowerName.contains("go")) {
return "text/x-go";
}
if (lowerName.contains("ruby")) {
return "text/x-ruby";
}
if (lowerName.contains("rust")) {
return "text/x-rustsrc";
}
if (lowerName.contains("php")) {
return "text/x-php";
}
if (lowerName.contains("perl")) {
return "text/x-perl";
}
if (lowerName.contains("fortran")) {
return "text/x-fortran";
}
if (lowerName.contains("haskell")) {
return "text/x-haskell";
}
if (lowerName.contains("ocaml")) {
return "text/x-ocaml";
}
return null;
}
}

@ -0,0 +1,143 @@
package top.hcode.hoj.crawler.language;
import cn.hutool.core.util.ReUtil;
import cn.hutool.http.HttpUtil;
import top.hcode.hoj.pojo.entity.problem.Language;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* @Author: Himit_ZH
* @Date: 2022/1/27 21:21
* @Description:
*/
public class SPOJLanguageStrategy extends LanguageStrategy {
private static final HashMap<String, String> languageMap = new HashMap<>();
static {
languageMap.put("7", "Ada95 (gnat 8.3)");
languageMap.put("45", "Assembler 32 (gcc 8.3)");
languageMap.put("13", "Assembler 32 (nasm 2.14)");
languageMap.put("42", "Assembler 64 (nasm 2.14)");
languageMap.put("104", "AWK (gawk 4.2.1)");
languageMap.put("105", "AWK (mawk 1.3.3)");
languageMap.put("28", "Bash (bash 5.0.3)");
languageMap.put("110", "BC (bc 1.07.1)");
languageMap.put("12", "Brainf**k (bff 1.0.6)");
languageMap.put("81", "C (clang 8.0)");
languageMap.put("11", "C (gcc 8.3)");
languageMap.put("27", "C# (gmcs 5.20.1)");
languageMap.put("41", "C++ (g++ 4.3.2)");
languageMap.put("1", "C++ (gcc 8.3)");
languageMap.put("44", "C++14 (gcc 8.3)");
languageMap.put("82", "C++14 (clang 8.0)");
languageMap.put("34", "C99 (gcc 8.3)");
languageMap.put("14", "Clips (clips 6.30)");
languageMap.put("111", "Clojure (clojure 1.10.0)");
languageMap.put("118", "Cobol (gnucobol 2.2.0)");
languageMap.put("91", "CoffeeScript (coffee 2.4.1)");
languageMap.put("31", "Common Lisp (sbcl 1.4.16)");
languageMap.put("32", "Common Lisp (clisp 2.49.92)");
languageMap.put("102", "D (dmd 2.085.0)");
languageMap.put("84", "D (ldc 1.12.0)");
languageMap.put("20", "D (gdc 8.3)");
languageMap.put("48", "Dart (dart 2.3.0)");
languageMap.put("96", "Elixir (elixir 1.8.2)");
languageMap.put("36", "Erlang (erl 21.3.8)");
languageMap.put("124", "F# (mono 4.1)");
languageMap.put("92", "Fantom (fantom 1.0.72)");
languageMap.put("107", "Forth (gforth 0.7.3)");
languageMap.put("5", "Fortran (gfortran 8.3)");
languageMap.put("114", "Go (go 1.12.1)");
languageMap.put("98", "Gosu (gosu 1.14.9)");
languageMap.put("121", "Groovy (groovy 2.5.6)");
languageMap.put("21", "Haskell (ghc 8.4.4)");
languageMap.put("16", "Icon (iconc 9.5.1)");
languageMap.put("9", "Intercal (ick 0.3)");
languageMap.put("24", "JAR (JavaSE 6)");
languageMap.put("10", "Java (HotSpot 12)");
languageMap.put("35", "JavaScript (rhino 1.7.9)");
languageMap.put("112", "JavaScript (SMonkey 60.2.3)");
languageMap.put("47", "Kotlin (kotlin 1.3.21)");
languageMap.put("26", "Lua (luac 5.3.3)");
languageMap.put("30", "Nemerle (ncc 1.2.547)");
languageMap.put("25", "Nice (nicec 0.9.13)");
languageMap.put("122", "Nim (nim 0.19.4)");
languageMap.put("56", "Node.js (node 11.12.0)");
languageMap.put("43", "Objective-C (gcc 8.3)");
languageMap.put("83", "Objective-C (clang 8.0)");
languageMap.put("8", "Ocaml (ocamlopt 4.05.0)");
languageMap.put("127", "Octave (octave 4.4.1)");
languageMap.put("2", "Pascal (gpc 20070904)");
languageMap.put("22", "Pascal (fpc 3.0.4)");
languageMap.put("54", "Perl (perl 2018.12)");
languageMap.put("3", "Perl (perl 5.28.1)");
languageMap.put("29", "PHP (php 7.3.5)");
languageMap.put("94", "Pico Lisp (pico 18.12.27)");
languageMap.put("19", "Pike (pike 8.0)");
languageMap.put("15", "Prolog (swi 7.6.4)");
languageMap.put("108", "Prolog (gprolog 1.4.5)");
languageMap.put("4", "Python (cpython 2.7.16)");
languageMap.put("99", "Python (PyPy 2.7.13)");
languageMap.put("116", "Python 3 (python 3.7.3)");
languageMap.put("126", "Python 3 nbc (python 3.7.3)");
languageMap.put("117", "R (R 3.5.2)");
languageMap.put("95", "Racket (racket 7.0)");
languageMap.put("17", "Ruby (ruby 2.5.5)");
languageMap.put("93", "Rust (rust 1.33.0)");
languageMap.put("39", "Scala (scala 2.12.8)");
languageMap.put("18", "Scheme (stalin 0.11)");
languageMap.put("33", "Scheme (guile 2.2.4)");
languageMap.put("97", "Scheme (chicken 4.13)");
languageMap.put("46", "Sed (sed 4.7)");
languageMap.put("23", "Smalltalk (gst 3.2.5)");
languageMap.put("40", "SQLite (sqlite 3.27.2)");
languageMap.put("85", "Swift (swift 4.2.2)");
languageMap.put("38", "TCL (tcl 8.6)");
languageMap.put("62", "Text (plain text)");
languageMap.put("115", "Unlambda (unlambda 0.1.4.2)");
languageMap.put("50", "VB.net (mono 4.7)");
languageMap.put("6", "Whitespace (wspace 0.3)");
}
@Override
public String getLanguageNameById(String id) {
return languageMap.get(id);
}
@Override
public List<Language> buildLanguageListByIds(List<Language> allLanguageList, List<String> langIdList) {
List<String> langNameList = langIdList.stream().map(this::getLanguageNameById).collect(Collectors.toList());
return allLanguageList.stream().filter(language -> langNameList.contains(language.getName())).collect(Collectors.toList());
}
@Override
public Collection<String> getLangList() {
return languageMap.values();
}
@Override
public String getOJName() {
return "SPOJ";
}
public static void main(String[] args) {
String url = "https://www.spoj.com/submit/HOTLINE/";
String body = HttpUtil.get(url);
Pattern pattern1 = Pattern.compile("<option value=\"([\\s\\S]*?)\" >[\\s\\S]*?</option>");
Pattern pattern2 = Pattern.compile("<option value=\"[\\s\\S]*?\" >([\\s\\S]*?)</option>");
List<String> allGroups1 = ReUtil.findAll(pattern1, body, 1);
List<String> allGroups2 = ReUtil.findAll(pattern2, body, 1);
for (int i = 0; i < allGroups1.size(); i++) {
System.out.println("languageMap.put(\"" + allGroups2.get(i) + "\", \"" + allGroups1.get(i) + "\");");
}
}
}

@ -0,0 +1,128 @@
package top.hcode.hoj.crawler.problem;
import cn.hutool.core.util.ReUtil;
import cn.hutool.http.HttpUtil;
import org.apache.commons.lang.Validate;
import org.jsoup.Jsoup;
import top.hcode.hoj.pojo.entity.problem.Problem;
import top.hcode.hoj.utils.Constants;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @Author: Himit_ZH
* @Date: 2022/1/28 21:23
* @Description:
*/
public class AtCoderProblemStrategy extends ProblemStrategy {
public static final String JUDGE_NAME = "AC";
public static final String HOST = "https://atcoder.jp";
public static final String PROBLEM_URL = "/contests/%s/tasks/%s";
public String getJudgeName() {
return JUDGE_NAME;
}
public String getProblemUrl(String problemId, String contestId) {
return HOST + String.format(PROBLEM_URL, contestId, problemId);
}
public String getProblemSource(String problemId, String contestId) {
return String.format("<a style='color:#1A5CC8' href='" + getProblemUrl(problemId, contestId) + "'>%s</a>", "AtCoder-" + problemId);
}
@Override
public RemoteProblemInfo getProblemInfo(String problemId, String author) throws Exception {
problemId = problemId.toLowerCase();
boolean isMatch = ReUtil.isMatch("[a-z]+[0-9]+_[a-z]*[0-9]*", problemId);
if (!isMatch){
throw new IllegalArgumentException("AtCoder: Incorrect problem id format! Must be like `abc110_a`");
}
String contestId = problemId.split("_")[0];
String body = HttpUtil.get(getProblemUrl(problemId, contestId));
Pattern pattern = Pattern.compile("Time Limit: (\\d+) sec / Memory Limit: (\\d+) MB");
Matcher matcher = pattern.matcher(body);
Validate.isTrue(matcher.find());
String timeLimit = matcher.group(1).trim();
String memoryLimit = matcher.group(2).trim();
String title = ReUtil.get("<title>[\\s\\S]*? - ([\\s\\S]*?)</title>", body, 1);
Problem problem = new Problem();
problem.setProblemId(getJudgeName() + "-" + problemId)
.setAuthor(author)
.setTitle(title)
.setType(0)
.setTimeLimit(Integer.parseInt(timeLimit) * 1000)
.setMemoryLimit(Integer.parseInt(memoryLimit))
.setIsRemote(true)
.setSource(getProblemSource(problemId, contestId))
.setAuth(1)
.setOpenCaseResult(false)
.setIsRemoveEndBlank(false)
.setIsGroup(false)
.setDifficulty(1); // 默认为中等
if (body.contains("Problem Statement")) {
String desc = ReUtil.get("<h3>Problem Statement</h3>([\\s\\S]*?)</section>[\\s\\S]*?</div>", body, 1);
desc = desc.replaceAll("<var>", "\\$").replaceAll("</var>", "\\$");
desc = desc.replaceAll("<pre>", "<pre style=\"padding:9px!important;background-color: #f5f5f5!important\">");
desc = desc.replaceAll("src=\"/img", "src=\"" + HOST + "/img");
StringBuilder sb = new StringBuilder();
String rawInput = ReUtil.get("<h3>Input</h3>([\\s\\S]*?)</section>[\\s\\S]*?</div>", body, 1);
sb.append(rawInput);
String constrains = ReUtil.get("<h3>Constraints</h3>([\\s\\S]*?)</section>[\\s\\S]*?</div>", body, 1);
sb.append(constrains);
String input = sb.toString().replaceAll("<var>", "\\$").replaceAll("</var>", "\\$");
input = input.replaceAll("<pre>", "<pre style=\"padding:9px!important;background-color: #f5f5f5!important\">");
String rawOutput = ReUtil.get("<h3>Output</h3>([\\s\\S]*?)</section>[\\s\\S]*?</div>", body, 1);
String output = rawOutput.replaceAll("<var>", "\\$").replaceAll("</var>", "\\$");
output = output.replaceAll("<pre>", "<pre style=\"padding:9px!important;background-color: #f5f5f5!important\">");
List<String> sampleInput = ReUtil.findAll("<h3>Sample Input \\d+</h3><pre>([\\s\\S]*?)</pre>[\\s\\S]*?</section>[\\s\\S]*?</div>", body, 1);
List<String> sampleOutput = ReUtil.findAll("<h3>Sample Output \\d+</h3><pre>([\\s\\S]*?)</pre>[\\s\\S]*?</section>[\\s\\S]*?</div>", body, 1);
StringBuilder examples = new StringBuilder();
for (int i = 0; i < sampleInput.size() && i < sampleOutput.size(); i++) {
examples.append("<input>");
String exampleInput = sampleInput.get(i).trim();
examples.append(exampleInput).append("</input>");
examples.append("<output>");
String exampleOutput = sampleOutput.get(i).trim();
examples.append(exampleOutput).append("</output>");
}
problem.setInput(input.trim())
.setOutput(output.trim())
.setDescription(desc.trim())
.setExamples(examples.toString());
} else {
org.jsoup.nodes.Element element = Jsoup.parse(body).getElementById("task-statement");
String desc = element.html();
desc = desc.replaceAll("src=\"/img", "src=\"https://atcoder.jp/img");
desc = desc.replaceAll("<pre>", "<pre style=\"padding:9px!important;background-color: #f5f5f5!important\">");
desc = desc.replaceAll("<var>", "\\$").replaceAll("</var>", "\\$");
desc = desc.replaceAll("<hr>", "");
problem.setDescription(desc);
}
return new RemoteProblemInfo()
.setProblem(problem)
.setTagList(null)
.setLangIdList(null)
.setRemoteOJ(Constants.RemoteOJ.ATCODER);
}
}

@ -0,0 +1,197 @@
package top.hcode.hoj.crawler.problem;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.http.HtmlUtil;
import cn.hutool.http.HttpRequest;
import org.springframework.util.StringUtils;
import top.hcode.hoj.pojo.entity.problem.Problem;
import top.hcode.hoj.pojo.entity.problem.Tag;
import top.hcode.hoj.utils.CodeForcesUtils;
import top.hcode.hoj.utils.Constants;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
/**
* @Author: Himit_ZH
* @Date: 2021/3/3 15:00
* @Description:
*/
public class CFProblemStrategy extends ProblemStrategy {
public static final String JUDGE_NAME = "CF";
public static final String HOST = "https://codeforces.com";
public static final String PROBLEM_URL = "/problemset/problem/%s/%s";
public String getJudgeName() {
return JUDGE_NAME;
}
public String getProblemUrl(String contestId, String problemNum) {
return HOST + String.format(PROBLEM_URL, contestId, problemNum);
}
public String getProblemSource(String html, String problemId, String contestId, String problemNum) {
return String.format("<p>Problem<a style='color:#1A5CC8' href='https://codeforces.com/problemset/problem/%s/%s'>%s</a></p><p>" +
"Contest" + ReUtil.get("(<a[^<>]+/contest/\\d+\">.+?</a>)", html, 1)
.replace("/contest", HOST + "/contest")
.replace("color: black", "color: #009688;") + "</p>",
contestId, problemNum, getJudgeName() + "-" + problemId);
}
@Override
public RemoteProblemInfo getProblemInfo(String problemId, String author) throws Exception {
String contestId;
String problemNum;
if (NumberUtil.isInteger(problemId)) {
contestId = ReUtil.get("([0-9]+)[0-9]{2}", problemId, 1);
problemNum = ReUtil.get("[0-9]+([0-9]{2})", problemId, 1);
} else {
contestId = ReUtil.get("([0-9]+)[A-Z]{1}[0-9]{0,1}", problemId, 1);
problemNum = ReUtil.get("[0-9]+([A-Z]{1}[0-9]{0,1})", problemId, 1);
}
if (contestId == null || problemNum == null) {
throw new IllegalArgumentException("Codeforces: Incorrect problem id format!");
}
String html = HttpRequest.get(getProblemUrl(contestId, problemNum))
.header("cookie", "RCPC=" + CodeForcesUtils.getRCPC())
.timeout(20000)
.execute()
.body();
// 重定向失效更新RCPC
if (html.contains("Redirecting... Please, wait.")) {
List<String> list = ReUtil.findAll("[a-z0-9]+[a-z0-9]{31}", html, 0, new ArrayList<>());
CodeForcesUtils.updateRCPC(list);
html = HttpRequest.get(getProblemUrl(contestId, problemNum))
.header("cookie", "RCPC=" + CodeForcesUtils.getRCPC())
.timeout(20000)
.execute()
.body();
}
Problem info = new Problem();
info.setProblemId(getJudgeName() + "-" + problemId);
info.setTitle(ReUtil.get("<div class=\"title\">\\s*" + problemNum + "\\. ([\\s\\S]*?)</div>", html, 1).trim());
String timeLimitStr = ReUtil.get("</div>\\s*([\\d\\.]+) (seconds?|s)\\s*</div>", html, 1);
if (StringUtils.isEmpty(timeLimitStr)) {
timeLimitStr = ReUtil.get("</div>\\s*<span .*?>(\\d+) (seconds?|s)\\s*</span>\\s*</div>", html, 1);
}
double timeLimit = 1000 * Double.parseDouble(timeLimitStr);
info.setTimeLimit((int) timeLimit);
String memoryLimitStr = ReUtil.get("</div>\\s*(\\d+) (megabytes|MB)\\s*</div>", html, 1);
if (StringUtils.isEmpty(memoryLimitStr)) {
memoryLimitStr = ReUtil.get("</div>\\s*<span .*?>(\\d+) (megabytes|MB)\\s*</span>\\s*</div>", html, 1);
}
info.setMemoryLimit(Integer.parseInt(memoryLimitStr));
String tmpDesc = ReUtil.get("standard output\\s*</div>\\s*</div>\\s*<div>([\\s\\S]*?)</div>\\s*<div class=\"input-specification",
html, 1);
if (StringUtils.isEmpty(tmpDesc)) {
tmpDesc = ReUtil.get("<div class=\"input-file\">([\\s\\S]*?)</div><div class=\"input-specification", html, 1);
}
if (StringUtils.isEmpty(tmpDesc)) {
// 交互题
tmpDesc = ReUtil.get("standard output\\s*</div>\\s*</div>\\s*<div>([\\s\\S]*?)</div>\\s*<div>\\s*<div class=\"section-title", html, 1);
}
if (StringUtils.isEmpty(tmpDesc)) {
// 单单只有题面描述
tmpDesc = ReUtil.get("standard output\\s*</div>\\s*</div>\\s*<div>([\\s\\S]*?)</div>",
html, 1);
}
if (!StringUtils.isEmpty(tmpDesc)) {
tmpDesc = tmpDesc.replaceAll("\\$\\$\\$", "\\$")
.replaceAll("src=\"../../", "src=\"" + HOST + "/")
.trim();
}
info.setDescription(tmpDesc);
String inputDesc = ReUtil.get("<div class=\"section-title\">\\s*Input\\s*</div>([\\s\\S]*?)</div>\\s*<div class=\"output-specification\">", html, 1);
if (StringUtils.isEmpty(inputDesc)) {
inputDesc = ReUtil.get("<div class=\"section-title\">\\s*Interaction\\s*</div>([\\s\\S]*?)</div>\\s*<div class=\"sample-tests\">", html, 1);
}
if (StringUtils.isEmpty(inputDesc)) {
inputDesc = ReUtil.get("<div class=\"input-specification\">\\s*<div class=\"section-title\">\\s*Input\\s*</div>([\\s\\S]*?)</div>", html, 1);
}
if (!StringUtils.isEmpty(inputDesc)) {
inputDesc = inputDesc.replaceAll("\\$\\$\\$", "\\$").trim();
}
info.setInput(inputDesc);
String outputDesc = ReUtil.get("<div class=\"section-title\">\\s*Output\\s*</div>([\\s\\S]*?)</div>\\s*<div class=\"sample-tests\">", html, 1);
if (!StringUtils.isEmpty(outputDesc)) {
outputDesc = outputDesc.replaceAll("\\$\\$\\$", "\\$").trim();
}
info.setOutput(outputDesc);
List<String> inputExampleList = ReUtil.findAll(Pattern.compile("<div class=\"input\">\\s*<div class=\"title\">\\s*Input\\s*</div>\\s*<pre>([\\s\\S]*?)</pre>\\s*</div>"), html, 1);
List<String> outputExampleList = ReUtil.findAll(Pattern.compile("<div class=\"output\">\\s*<div class=\"title\">\\s*Output\\s*</div>\\s*<pre>([\\s\\S]*?)</pre>\\s*</div>"), html, 1);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < inputExampleList.size() && i < outputExampleList.size(); i++) {
sb.append("<input>");
String input = inputExampleList.get(i)
.replaceAll("<br>", "\n")
.replaceAll("<br />", "\n")
.trim();
sb.append(HtmlUtil.unescape(input)).append("</input>");
sb.append("<output>");
String output = outputExampleList.get(i)
.replaceAll("<br>", "\n")
.replaceAll("<br />", "\n")
.trim();
sb.append(HtmlUtil.unescape(output)).append("</output>");
}
info.setExamples(sb.toString());
String tmpHint = ReUtil.get("<div class=\"section-title\">\\s*Note\\s*</div>([\\s\\S]*?)</div>\\s*</div>", html, 1);
if (tmpHint != null) {
info.setHint(tmpHint.replaceAll("\\$\\$\\$", "\\$").trim());
}
info.setIsRemote(true);
info.setSource(getProblemSource(html, problemId, contestId, problemNum));
info.setType(0)
.setAuth(1)
.setAuthor(author)
.setOpenCaseResult(true)
.setIsRemoveEndBlank(false)
.setIsGroup(false)
.setDifficulty(1); // 默认为中等
List<String> allTags = ReUtil.findAll(Pattern.compile("<span class=\"tag-box\" style=\"font-size:1\\.2rem;\" title=\"[\\s\\S]*?\">([\\s\\S]*?)</span>"), html, 1);
List<Tag> tagList = new LinkedList<>();
for (String tmp : allTags) {
tagList.add(new Tag().setName(tmp.trim()));
}
return new RemoteProblemInfo()
.setProblem(info)
.setTagList(tagList)
.setRemoteOJ(Constants.RemoteOJ.CODEFORCES);
}
}

@ -0,0 +1,134 @@
package top.hcode.hoj.crawler.problem;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import top.hcode.hoj.pojo.entity.problem.Problem;
import top.hcode.hoj.utils.CodeForcesUtils;
import top.hcode.hoj.utils.Constants;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @Author: Himit_ZH
* @Date: 2021/11/6 11:35
* @Description:
*/
public class GYMProblemStrategy extends CFProblemStrategy {
public static final String IMAGE_HOST = "https://codeforces.com";
@Override
public String getJudgeName() {
return "GYM";
}
@Override
public String getProblemUrl(String contestId, String problemNum) {
String problemUrl = "/gym/%s/problem/%s";
return HOST + String.format(problemUrl, contestId, problemNum);
}
@Override
public String getProblemSource(String html, String problemId, String contestNum, String problemNum) {
return String.format("<p>Problem<a style='color:#1A5CC8' href='https://codeforces.com/gym/%s/problem/%s'>%s</a></p><p>" +
"Contest" + ReUtil.get("(<a[^<>]+/gym/\\d+\">.+?</a>)", html, 1)
.replace("/gym", HOST + "/gym")
.replace("color: black", "color: #009688;") + "</p>",
contestNum, problemNum, getJudgeName() + "-" + problemId);
}
@Override
public RemoteProblemInfo getProblemInfo(String problemId, String author) {
try {
return super.getProblemInfo(problemId, author);
} catch (Exception ignored) {
String contestNum = ReUtil.get("([0-9]+)[A-Z]{1}[0-9]{0,1}", problemId, 1);
String problemNum = ReUtil.get("[0-9]+([A-Z]{1}[0-9]{0,1})", problemId, 1);
return getPDFHtml(problemId, contestNum, problemNum, author);
}
}
private RemoteProblemInfo getPDFHtml(String problemId, String contestNum, String problemNum, String author) {
Problem problem = new Problem();
String url = HOST + "/gym/" + contestNum;
String html = HttpRequest.get(url)
.header("cookie", "RCPC=" + CodeForcesUtils.getRCPC())
.timeout(20000)
.execute()
.body();
// 重定向失效更新RCPC
if (html.contains("Redirecting... Please, wait.")) {
List<String> list = ReUtil.findAll("[a-z0-9]+[a-z0-9]{31}", html, 0, new ArrayList<>());
CodeForcesUtils.updateRCPC(list);
html = HttpRequest.get(url)
.header("cookie", "RCPC=" + CodeForcesUtils.getRCPC())
.timeout(20000)
.execute()
.body();
}
String regex = "<a href=\"\\/gym\\/" + contestNum + "\\/problem\\/" + problemNum
+ "\"><!--\\s*-->([^<]+)(?:(?:.|\\s)*?<div){2}[^>]*>\\s*([^<]+)<\\/div>\\s*([\\d.]+)\\D*(\\d+)";
Matcher matcher = Pattern.compile(regex).matcher(html);
matcher.find();
problem.setProblemId(getJudgeName() + "-" + problemId);
problem.setTitle(matcher.group(1));
problem.setTimeLimit((int) (Double.parseDouble(matcher.group(3)) * 1000));
problem.setMemoryLimit(Integer.parseInt(matcher.group(4)));
problem.setSource(String.format("<p>Problem<a style='color:#1A5CC8' href='https://codeforces.com/gym/%s/attachments'>%s</a></p><p>" +
"Contest" + ReUtil.get("(<a[^<>]+/gym/\\d+\">.+?</a>)", html, 1)
.replace("/gym", HOST + "/gym")
.replace("color: black", "color: #009688;") + "</p>",
contestNum, getJudgeName() + "-" + problemId));
regex = "\\/gym\\/" + contestNum + "\\/attachments\\/download\\S*?\\.pdf";
matcher = Pattern.compile(regex).matcher(html);
matcher.find();
String pdfURI;
try {
String fileName = IdUtil.fastSimpleUUID() + ".pdf";
String filePath = Constants.File.PROBLEM_FILE_FOLDER.getPath() + File.separator + fileName;
HttpUtil.downloadFile(IMAGE_HOST + matcher.group(0), filePath);
pdfURI = Constants.File.FILE_API.getPath() + fileName;
} catch (Exception e1) {
try {
pdfURI = HOST + matcher.group(0);
} catch (Exception e2) {
String fileName = IdUtil.fastSimpleUUID() + ".pdf";
String filePath = Constants.File.PROBLEM_FILE_FOLDER.getPath() + File.separator + fileName;
CodeForcesUtils.downloadPDF(HOST + "/gym/" + contestNum + "/problem/" + problemNum, filePath);
pdfURI = Constants.File.FILE_API.getPath() + fileName;
}
}
String description = "<p><a style='color:#3091f2' href=\"" + pdfURI + "\">Click here to download the PDF file.</a></p>";
problem.setDescription(description);
problem.setType(0)
.setIsRemote(true)
.setAuth(1)
.setAuthor(author)
.setOpenCaseResult(true)
.setIsRemoveEndBlank(false)
.setIsGroup(false)
.setDifficulty(1); // 默认为中等
return new RemoteProblemInfo()
.setProblem(problem)
.setTagList(null)
.setRemoteOJ(Constants.RemoteOJ.GYM);
}
}

@ -0,0 +1,66 @@
package top.hcode.hoj.crawler.problem;
import cn.hutool.core.util.ReUtil;
import com.baomidou.mybatisplus.extension.api.R;
import org.jsoup.Connection;
import org.jsoup.nodes.Document;
import org.springframework.util.Assert;
import top.hcode.hoj.pojo.entity.problem.Problem;
import top.hcode.hoj.utils.Constants;
import top.hcode.hoj.utils.JsoupUtils;
/**
* @Author: Himit_ZH
* @Date: 2021/2/17 22:42
* @Description:
*/
public class HDUProblemStrategy extends ProblemStrategy {
public static final String JUDGE_NAME = "HDU";
public static final String HOST = "http://acm.hdu.edu.cn";
public static final String PROBLEM_URL = "/showproblem.php?pid=%s";
/**
* @param problemId String
* @param author
* @return Problem
* @throws Exception
*/
@Override
public RemoteProblemInfo getProblemInfo(String problemId, String author) throws Exception {
// 验证题号是否符合规范
Assert.isTrue(problemId.matches("[1-9]\\d*"), "HDU题号格式错误");
Problem info = new Problem();
String url = HOST + String.format(PROBLEM_URL, problemId);
Connection connection = JsoupUtils.getConnectionFromUrl(url, null, null);
Document document = JsoupUtils.getDocument(connection, null);
String html = document.html();
info.setProblemId(JUDGE_NAME + "-" + problemId);
info.setTitle(ReUtil.get("color:#1A5CC8\">([\\s\\S]*?)</h1>", html, 1).trim());
info.setTimeLimit(Integer.parseInt(ReUtil.get("(\\d*) MS", html, 1)));
info.setMemoryLimit(Integer.parseInt(ReUtil.get("/(\\d*) K", html, 1)) / 1024);
info.setDescription(ReUtil.get(">Problem Description</div> <div class=.*?>([\\s\\S]*?)</div>", html, 1)
.replaceAll("src=\"[../]*", "src=\"" + HOST + "/"));
info.setInput(ReUtil.get(">Input</div> <div class=.*?>([\\s\\S]*?)</div>", html, 1));
info.setOutput(ReUtil.get(">Output</div> <div class=.*?>([\\s\\S]*?)</div>", html, 1));
StringBuilder sb = new StringBuilder("<input>");
sb.append(ReUtil.get(">Sample Input</div><div .*?,monospace;\">([\\s\\S]*?)</div></pre>", html, 1));
sb.append("</input><output>");
sb.append(ReUtil.get(">Sample Output</div><div .*?monospace;\">([\\s\\S]*?)(<div style=.*?</div><i style=.*?</i>)*?</div></pre>", html, 1)).append("</output>");
info.setExamples(sb.toString());
info.setHint(ReUtil.get("<i>Hint</i></div>([\\s\\S]*?)</div><i .*?<br><[^<>]*?panel_title[^<>]*?>", html, 1));
info.setIsRemote(true);
info.setSource(String.format("<a style='color:#1A5CC8' href='https://acm.hdu.edu.cn/showproblem.php?pid=%s'>%s</a>", problemId, JUDGE_NAME + "-" + problemId));
info.setType(0)
.setAuth(1)
.setAuthor(author)
.setOpenCaseResult(false)
.setIsRemoveEndBlank(false)
.setIsGroup(false)
.setDifficulty(1); // 默认为简单
return new RemoteProblemInfo()
.setProblem(info)
.setTagList(null)
.setRemoteOJ(Constants.RemoteOJ.HDU);
}
}

@ -0,0 +1,63 @@
package top.hcode.hoj.crawler.problem;
import cn.hutool.core.util.ReUtil;
import org.jsoup.Connection;
import org.jsoup.nodes.Document;
import org.springframework.util.Assert;
import top.hcode.hoj.pojo.entity.problem.Problem;
import top.hcode.hoj.utils.Constants;
import top.hcode.hoj.utils.JsoupUtils;
/**
* @Author: Himit_ZH
* @Date: 2021/6/24 23:27
* @Description:
*/
public class POJProblemStrategy extends ProblemStrategy {
public static final String JUDGE_NAME = "POJ";
public static final String HOST = "http://poj.org";
public static final String PROBLEM_URL = "/problem?id=%s";
@Override
public RemoteProblemInfo getProblemInfo(String problemId, String author) throws Exception {
// 验证题号是否符合规范
Assert.isTrue(problemId.matches("[1-9]\\d*"), "POJ题号格式错误");
Problem info = new Problem();
String url = HOST + String.format(PROBLEM_URL, problemId);
Connection connection = JsoupUtils.getConnectionFromUrl(url, null, null);
Document document = JsoupUtils.getDocument(connection, null);
String html = document.html();
html = html.replaceAll("<br>", "\n");
info.setProblemId(JUDGE_NAME + "-" + problemId);
info.setTitle(ReUtil.get("<title>\\d{3,} -- ([\\s\\S]*?)</title>", html, 1).trim());
info.setTimeLimit(Integer.parseInt(ReUtil.get("<b>Time Limit:</b> (\\d{3,})MS</td>", html, 1)));
info.setMemoryLimit(Integer.parseInt(ReUtil.get("<b>Memory Limit:</b> (\\d{2,})K</td>", html, 1)) / 1024);
info.setDescription(ReUtil.get("<p class=\"pst\">Description</p><div class=.*?>([\\s\\S]*?)</div><p class=\"pst\">", html, 1)
.replaceAll("src=\"[../]*", "src=\"" + HOST + "/"));
info.setInput(ReUtil.get("<p class=\"pst\">Input</p><div class=.*?>([\\s\\S]*?)</div><p class=\"pst\">", html, 1));
info.setOutput(ReUtil.get("<p class=\"pst\">Output</p><div class=.*?>([\\s\\S]*?)</div><p class=\"pst\">", html, 1));
StringBuilder sb = new StringBuilder("<input>");
sb.append(ReUtil.get("<p class=\"pst\">Sample Input</p><pre class=.*?>([\\s\\S]*?)</pre><p class=\"pst\">", html, 1));
sb.append("</input><output>");
sb.append(ReUtil.get("<p class=\"pst\">Sample Output</p><pre class=.*?>([\\s\\S]*?)</pre><p class=\"pst\">", html, 1))
.append("</output>");
info.setExamples(sb.toString());
info.setHint(ReUtil.get("<p class=.*?>Hint</p><div class=.*?>([\\s\\S]*?)</div><p class=\"pst\">", html, 1));
info.setIsRemote(true);
info.setSource(String.format("<a style='color:#1A5CC8' href='http://poj.org/problem?id=%s'>%s</a>", problemId, JUDGE_NAME + "-" + problemId));
info.setType(0)
.setAuth(1)
.setAuthor(author)
.setOpenCaseResult(false)
.setIsRemoveEndBlank(false)
.setIsGroup(false)
.setDifficulty(1); // 默认为简单
return new RemoteProblemInfo()
.setProblem(info)
.setTagList(null)
.setRemoteOJ(Constants.RemoteOJ.POJ);
}
}

@ -0,0 +1,31 @@
package top.hcode.hoj.crawler.problem;
import lombok.extern.slf4j.Slf4j;
/**
* @Author: Himit_ZH
* @Date: 2021/2/17 22:40
* @Description:
*/
@Slf4j(topic = "hoj")
public class ProblemContext {
ProblemStrategy problemStrategy;
public ProblemContext(ProblemStrategy problemStrategy) {
this.problemStrategy = problemStrategy;
}
//上下文接口
public ProblemStrategy.RemoteProblemInfo getProblemInfo(String problemId, String author) throws Exception {
try {
return problemStrategy.getProblemInfo(problemId, author);
}catch (IllegalArgumentException e){
throw e;
} catch (Exception e) {
log.error("获取题目详情失败---------------->{}", e);
}
return null;
}
}

@ -0,0 +1,24 @@
package top.hcode.hoj.crawler.problem;
import lombok.Data;
import lombok.experimental.Accessors;
import top.hcode.hoj.pojo.entity.problem.Problem;
import top.hcode.hoj.pojo.entity.problem.Tag;
import top.hcode.hoj.utils.Constants;
import java.util.List;
public abstract class ProblemStrategy {
public abstract RemoteProblemInfo getProblemInfo(String problemId,String author) throws Exception;
@Data
@Accessors(chain = true)
public static
class RemoteProblemInfo {
private Problem problem;
private List<Tag> tagList;
private List<String> langIdList;
private Constants.RemoteOJ remoteOJ;
}
}

@ -0,0 +1,89 @@
package top.hcode.hoj.crawler.problem;
import cn.hutool.core.util.ReUtil;
import cn.hutool.http.HttpUtil;
import top.hcode.hoj.pojo.entity.problem.Problem;
import top.hcode.hoj.pojo.entity.problem.Tag;
import top.hcode.hoj.utils.Constants;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
/**
* @Author: Himit_ZH
* @Date: 2022/1/25 14:11
* @Description:
*/
public class SPOJProblemStrategy extends ProblemStrategy {
public static final String JUDGE_NAME = "SPOJ";
public static final String HOST = "https://www.spoj.com";
public static final String PROBLEM_URL = "/problems/%s/";
public static final String SUBMIT_URL = "/submit/%s/";
public String getJudgeName() {
return JUDGE_NAME;
}
public String getProblemUrl(String problemId) {
return HOST + String.format(PROBLEM_URL, problemId);
}
public String getSubmitUrl(String problemId) {
return HOST + String.format(SUBMIT_URL, problemId);
}
public String getProblemSource(String problemId) {
return String.format("<a style='color:#1A5CC8' href='" + getProblemUrl(problemId) + "'>%s</a>", getJudgeName() + "-" + problemId);
}
@Override
public RemoteProblemInfo getProblemInfo(String problemId, String author) throws Exception {
problemId = problemId.toUpperCase();
String body = HttpUtil.get(getProblemUrl(problemId));
String title = ReUtil.get("<h2 id=\"problem-name\" class=\"text-center\">[\\s\\S]*? - ([\\s\\S]*?)</h2>", body, 1);
String timeLimit = ReUtil.get("Time limit:</td><td>([\\s\\S]*?)s", body, 1);
String memoryLimit = ReUtil.get("Memory limit:</td><td>([\\s\\S]*?)MB", body, 1);
String desc = ReUtil.get("<div id=\"problem-body\">([\\s\\S]*?)</div>", body, 1);
desc = desc.replaceAll("src=\"/", "src=\"" + HOST + "/")
.replaceAll("<pre>", "<pre style=\"padding:9px!important;background-color: #f5f5f5!important\">");
desc = desc.replaceAll("<!-- here starts your code -->", "");
Pattern tagPattern = Pattern.compile("<a href=\".*?\"><span class=\".*?\" data-tagid=\".*?\">([\\s\\S]*?)<span class=\".*?\" style=\"display: none\"></span></span></a>");
List<String> allTags = ReUtil.findAll(tagPattern, body, 1);
Problem problem = new Problem();
problem.setProblemId(getJudgeName() + "-" + problemId)
.setAuthor(author)
.setTitle(title)
.setType(0)
.setTimeLimit((int) (Double.parseDouble(timeLimit) * 1000))
.setMemoryLimit(Integer.parseInt(memoryLimit))
.setDescription(desc.trim())
.setIsRemote(true)
.setSource(getProblemSource(problemId))
.setAuth(1)
.setOpenCaseResult(false)
.setIsGroup(false)
.setIsRemoveEndBlank(false)
.setDifficulty(1); // 默认为中等
List<Tag> tagList = new ArrayList<>();
for (String tmp : allTags) {
tagList.add(new Tag().setName(tmp.trim()));
}
String submitPageBody = HttpUtil.get(getSubmitUrl(problemId));
Pattern pattern = Pattern.compile("<option value=\"([\\s\\S]*?)\" >[\\s\\S]*?</option>");
List<String> langIdList = ReUtil.findAll(pattern, submitPageBody, 1);
return new RemoteProblemInfo()
.setProblem(problem)
.setTagList(tagList)
.setLangIdList(langIdList)
.setRemoteOJ(Constants.RemoteOJ.SPOJ);
}
}

@ -0,0 +1,21 @@
package top.hcode.hoj.dao.common;
import com.baomidou.mybatisplus.core.metadata.IPage;
import top.hcode.hoj.pojo.entity.common.Announcement;
import com.baomidou.mybatisplus.extension.service.IService;
import top.hcode.hoj.pojo.vo.AnnouncementVo;
/**
* <p>
*
* </p>
*
* @author Himit_ZH
* @since 2020-10-23
*/
public interface AnnouncementEntityService extends IService<Announcement> {
IPage<AnnouncementVo> getAnnouncementList(int limit, int currentPage, Boolean notAdmin);
IPage<AnnouncementVo> getContestAnnouncement(Long cid,Boolean notAdmin,int limit, int currentPage);
}

@ -0,0 +1,28 @@
package top.hcode.hoj.dao.common;
import com.baomidou.mybatisplus.extension.service.IService;
import top.hcode.hoj.pojo.entity.common.File;
import top.hcode.hoj.pojo.vo.ACMContestRankVo;
import top.hcode.hoj.pojo.vo.OIContestRankVo;
import java.util.List;
public interface FileEntityService extends IService<File> {
int updateFileToDeleteByUidAndType(String uid, String type);
int updateFileToDeleteByGidAndType(Long gid, String type);
List<File> queryDeleteAvatarList();
List<File> queryCarouselFileList();
List<List<String>> getContestRankExcelHead(List<String> contestProblemDisplayIDList, Boolean isACM);
List<List<Object>> changeACMContestRankToExcelRowList(List<ACMContestRankVo> acmContestRankVoList,
List<String> contestProblemDisplayIDList,
String rankShowName);
List<List<Object>> changOIContestRankToExcelRowList(List<OIContestRankVo> oiContestRankVoList,
List<String> contestProblemDisplayIDList,
String rankShowName);
}

@ -0,0 +1,39 @@
package top.hcode.hoj.dao.common.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import top.hcode.hoj.pojo.entity.common.Announcement;
import top.hcode.hoj.mapper.AnnouncementMapper;
import top.hcode.hoj.pojo.vo.AnnouncementVo;
import top.hcode.hoj.dao.common.AnnouncementEntityService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
*
* </p>
*
* @author Himit_ZH
* @since 2020-10-23
*/
@Service
public class AnnouncementEntityServiceImpl extends ServiceImpl<AnnouncementMapper, Announcement> implements AnnouncementEntityService {
@Autowired
private AnnouncementMapper announcementMapper;
@Override
public IPage<AnnouncementVo> getAnnouncementList(int limit, int currentPage,Boolean notAdmin) {
//新建分页
Page<AnnouncementVo> page = new Page<>(currentPage, limit);
return announcementMapper.getAnnouncementList(page,notAdmin);
}
@Override
public IPage<AnnouncementVo> getContestAnnouncement(Long cid,Boolean notAdmin,int limit, int currentPage) {
Page<AnnouncementVo> page = new Page<>(currentPage, limit);
return announcementMapper.getContestAnnouncement(page,cid,notAdmin);
}
}

@ -0,0 +1,184 @@
package top.hcode.hoj.dao.common.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.hcode.hoj.mapper.FileMapper;
import top.hcode.hoj.pojo.entity.common.File;
import top.hcode.hoj.pojo.vo.ACMContestRankVo;
import top.hcode.hoj.pojo.vo.OIContestRankVo;
import top.hcode.hoj.dao.common.FileEntityService;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
/**
* @Author: Himit_ZH
* @Date: 2021/1/11 14:05
* @Description:
*/
@Service
public class FileEntityEntityServiceImpl extends ServiceImpl<FileMapper, File> implements FileEntityService {
@Autowired
private FileMapper fileMapper;
@Override
public int updateFileToDeleteByUidAndType(String uid, String type) {
return fileMapper.updateFileToDeleteByUidAndType(uid, type);
}
@Override
public int updateFileToDeleteByGidAndType(Long gid, String type) {
return fileMapper.updateFileToDeleteByGidAndType(gid, type);
}
@Override
public List<File> queryDeleteAvatarList() {
return fileMapper.queryDeleteAvatarList();
}
@Override
public List<File> queryCarouselFileList() {
return fileMapper.queryCarouselFileList();
}
@Override
public List<List<String>> getContestRankExcelHead(List<String> contestProblemDisplayIDList, Boolean isACM) {
List<List<String>> headList = new LinkedList<>();
List<String> head0 = new LinkedList<>();
head0.add("Rank");
List<String> head1 = new LinkedList<>();
head1.add("Username");
List<String> head2 = new LinkedList<>();
head2.add("ShowName");
List<String> head3 = new LinkedList<>();
head3.add("Real Name");
List<String> head4 = new LinkedList<>();
head4.add("School");
headList.add(head0);
headList.add(head1);
headList.add(head2);
headList.add(head3);
headList.add(head4);
List<String> head5 = new LinkedList<>();
if (isACM) {
head5.add("AC");
List<String> head6 = new LinkedList<>();
head6.add("Total Submission");
List<String> head7 = new LinkedList<>();
head7.add("Total Penalty Time");
headList.add(head5);
headList.add(head6);
headList.add(head7);
} else {
head5.add("Total Score");
headList.add(head5);
}
// 添加题目头
for (String displayID : contestProblemDisplayIDList) {
List<String> tmp = new LinkedList<>();
tmp.add(displayID);
headList.add(tmp);
}
return headList;
}
@Override
public List<List<Object>> changeACMContestRankToExcelRowList(List<ACMContestRankVo> acmContestRankVoList,
List<String> contestProblemDisplayIDList,
String rankShowName) {
List<List<Object>> allRowDataList = new LinkedList<>();
for (ACMContestRankVo acmContestRankVo : acmContestRankVoList) {
List<Object> rowData = new LinkedList<>();
rowData.add(acmContestRankVo.getRank() == -1 ? "*" : acmContestRankVo.getRank().toString());
rowData.add(acmContestRankVo.getUsername());
if ("username".equals(rankShowName)) {
rowData.add(acmContestRankVo.getUsername());
} else if ("realname".equals(rankShowName)) {
rowData.add(acmContestRankVo.getRealname());
} else if ("nickname".equals(rankShowName)) {
rowData.add(acmContestRankVo.getNickname());
} else {
rowData.add("");
}
rowData.add(acmContestRankVo.getRealname());
rowData.add(acmContestRankVo.getSchool());
rowData.add(acmContestRankVo.getAc());
rowData.add(acmContestRankVo.getTotal());
rowData.add(acmContestRankVo.getTotalTime());
HashMap<String, HashMap<String, Object>> submissionInfo = acmContestRankVo.getSubmissionInfo();
for (String displayID : contestProblemDisplayIDList) {
HashMap<String, Object> problemInfo = submissionInfo.getOrDefault(displayID, null);
if (problemInfo != null) { // 如果是有提交记录的
boolean isAC = (boolean) problemInfo.getOrDefault("isAC", false);
String info = "";
int errorNum = (int) problemInfo.getOrDefault("errorNum", 0);
int tryNum = (int) problemInfo.getOrDefault("tryNum", 0);
if (isAC) {
if (errorNum == 0) {
info = "+(1)";
} else {
info = "-(" + (errorNum + 1) + ")";
}
} else {
if (tryNum != 0 && errorNum != 0) {
info = "-(" + errorNum + "+" + tryNum + ")";
} else if (errorNum != 0) {
info = "-(" + errorNum + ")";
} else if (tryNum != 0) {
info = "?(" + tryNum + ")";
}
}
rowData.add(info);
} else {
rowData.add("");
}
}
allRowDataList.add(rowData);
}
return allRowDataList;
}
@Override
public List<List<Object>> changOIContestRankToExcelRowList(List<OIContestRankVo> oiContestRankVoList,
List<String> contestProblemDisplayIDList,
String rankShowName) {
List<List<Object>> allRowDataList = new LinkedList<>();
for (OIContestRankVo oiContestRankVo : oiContestRankVoList) {
List<Object> rowData = new LinkedList<>();
rowData.add(oiContestRankVo.getRank() == -1 ? "*" : oiContestRankVo.getRank().toString());
rowData.add(oiContestRankVo.getUsername());
if ("username".equals(rankShowName)) {
rowData.add(oiContestRankVo.getUsername());
} else if ("realname".equals(rankShowName)) {
rowData.add(oiContestRankVo.getRealname());
} else if ("nickname".equals(rankShowName)) {
rowData.add(oiContestRankVo.getNickname());
} else {
rowData.add("");
}
rowData.add(oiContestRankVo.getRealname());
rowData.add(oiContestRankVo.getSchool());
rowData.add(oiContestRankVo.getTotalScore());
HashMap<String, Integer> submissionInfo = oiContestRankVo.getSubmissionInfo();
for (String displayID : contestProblemDisplayIDList) {
Integer score = submissionInfo.getOrDefault(displayID, null);
if (score != null) { // 如果是有提交记录的就写最后一次提交的分数,没有的就写空
rowData.add(score);
} else {
rowData.add("");
}
}
allRowDataList.add(rowData);
}
return allRowDataList;
}
}

@ -0,0 +1,8 @@
package top.hcode.hoj.dao.contest;
import com.baomidou.mybatisplus.extension.service.IService;
import top.hcode.hoj.pojo.entity.contest.ContestAnnouncement;
public interface ContestAnnouncementEntityService extends IService<ContestAnnouncement> {
}

@ -0,0 +1,25 @@
package top.hcode.hoj.dao.contest;
import com.baomidou.mybatisplus.core.metadata.IPage;
import top.hcode.hoj.pojo.vo.ContestVo;
import top.hcode.hoj.pojo.entity.contest.Contest;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author Himit_ZH
* @since 2020-10-23
*/
public interface ContestEntityService extends IService<Contest> {
List<ContestVo> getWithinNext14DaysContests();
IPage<ContestVo> getContestList(Integer limit, Integer currentPage, Integer type, Integer status, String keyword);
ContestVo getContestInfoById(long cid);
}

@ -0,0 +1,16 @@
package top.hcode.hoj.dao.contest;
import top.hcode.hoj.pojo.entity.contest.ContestExplanation;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
*
* </p>
*
* @author Himit_ZH
* @since 2020-10-23
*/
public interface ContestExplanationEntityService extends IService<ContestExplanation> {
}

@ -0,0 +1,12 @@
package top.hcode.hoj.dao.contest;
import com.baomidou.mybatisplus.extension.service.IService;
import top.hcode.hoj.pojo.entity.contest.ContestPrint;
/**
* @Author: Himit_ZH
* @Date: 2021/9/19 21:05
* @Description:
*/
public interface ContestPrintEntityService extends IService<ContestPrint> {
}

@ -0,0 +1,28 @@
package top.hcode.hoj.dao.contest;
import top.hcode.hoj.pojo.entity.contest.ContestProblem;
import com.baomidou.mybatisplus.extension.service.IService;
import top.hcode.hoj.pojo.vo.ContestProblemVo;
import java.util.Date;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author Himit_ZH
* @since 2020-10-23
*/
public interface ContestProblemEntityService extends IService<ContestProblem> {
List<ContestProblemVo> getContestProblemList(Long cid,
Date startTime,
Date endTime,
Date sealTime,
Boolean isAdmin,
String contestAuthorUid,
List<String> groupRootUidList);
void syncContestRecord(Long pid, Long cid, String displayId);
}

@ -0,0 +1,32 @@
package top.hcode.hoj.dao.contest;
import com.baomidou.mybatisplus.core.metadata.IPage;
import top.hcode.hoj.pojo.entity.contest.Contest;
import top.hcode.hoj.pojo.entity.contest.ContestRecord;
import com.baomidou.mybatisplus.extension.service.IService;
import top.hcode.hoj.pojo.vo.ContestRecordVo;
import java.util.Date;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author Himit_ZH
* @since 2020-10-23
*/
public interface ContestRecordEntityService extends IService<ContestRecord> {
IPage<ContestRecord> getACInfo(Integer currentPage,
Integer limit,
Integer status,
Long cid,
String contestCreatorId);
List<ContestRecordVo> getOIContestRecord(Contest contest,List<Integer> externalCidList, Boolean isOpenSealRank);
List<ContestRecordVo> getACMContestRecord(String contestCreatorUid, Long cid, List<Integer> externalCidList, Date startTime);
}

@ -0,0 +1,16 @@
package top.hcode.hoj.dao.contest;
import top.hcode.hoj.pojo.entity.contest.ContestRegister;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
*
* </p>
*
* @author Himit_ZH
* @since 2020-10-23
*/
public interface ContestRegisterEntityService extends IService<ContestRegister> {
}

@ -0,0 +1,16 @@
package top.hcode.hoj.dao.contest;
import top.hcode.hoj.pojo.entity.contest.ContestScore;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
*
* </p>
*
* @author Himit_ZH
* @since 2020-10-23
*/
public interface ContestScoreEntityService extends IService<ContestScore> {
}

@ -0,0 +1,16 @@
package top.hcode.hoj.dao.contest.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import top.hcode.hoj.mapper.ContestAnnouncementMapper;
import top.hcode.hoj.pojo.entity.contest.ContestAnnouncement;
import top.hcode.hoj.dao.contest.ContestAnnouncementEntityService;
/**
* @Author: Himit_ZH
* @Date: 2020/12/21 22:59
* @Description:
*/
@Service
public class ContestAnnouncementEntityServiceImpl extends ServiceImpl<ContestAnnouncementMapper, ContestAnnouncement> implements ContestAnnouncementEntityService {
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save