refactor: improve question service entity types and security config

- Change Question entity time fields from Date to LocalDateTime for Java 8+ time API consistency
- Add auto-fill annotation for updateTime field in Question and QuestionSubmit entities
- Simplify Serializable import in QuestionQueryRequestDTO
- Temporarily set SecurityConfiguration to permit all requests for development
- Remove generated .flattened-pom.xml build artifacts from version control

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-01-26 21:57:08 +08:00
parent 17f58a7b45
commit be709efa2e
25 changed files with 166 additions and 843 deletions

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>ai-oj</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>aioj-backend-ai-service</artifactId>
<version>1.0.0</version>
<description>AIOJ AI服务</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
</project>

View File

@@ -1,92 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>ai-oj</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>aioj-backend-auth</artifactId>
<version>1.0.0</version>
<description>AIOJ 认证授权服务</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-core</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-feign</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-mybatis</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-security</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-crypto</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-json</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>ai-oj</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>aioj-backend-common</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<description>AIOJ 公共模块聚合</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<modules>
<module>aioj-backend-common-bom</module>
<module>aioj-backend-common-core</module>
<module>aioj-backend-common-log</module>
<module>aioj-backend-common-mybatis</module>
<module>aioj-backend-common-feign</module>
<module>aioj-backend-common-starter</module>
<module>aioj-backend-common-security</module>
</modules>
</project>

View File

@@ -1,68 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>aioj-backend-common-core</artifactId>
<version>1.0.0</version>
<description>AIOJ 公共工具类核心包</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-extra</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>aioj-backend-common-feign</artifactId>
<version>1.0.0</version>
<description>AIOJ Feign 远程调用封装</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-core</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>aioj-backend-common-log</artifactId>
<version>1.0.0</version>
<description>AIOJ 日志模块</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-core</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-extra</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-core</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-upms-api</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,60 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>aioj-backend-common-mybatis</artifactId>
<version>1.0.0</version>
<description>AIOJ MyBatis Plus 封装</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-jsqlparser</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-core</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -46,9 +46,9 @@ public class CodeGenerator {
/** 父包名 */ /** 父包名 */
private static final String PARENT_PACKAGE = "cn.meowrain.aioj.backend"; private static final String PARENT_PACKAGE = "cn.meowrain.aioj.backend";
/** 模块名 (如: userservice, questionservice) */ /** 模块名 (如: userservice, questionservice) */
private static final String MODULE_NAME = "fileservice"; private static final String MODULE_NAME = "question.service";
/** 要生成的表名 (多个表用逗号分隔) */ /** 要生成的表名 (多个表用逗号分隔) */
private static final String[] TABLE_NAMES = {"attachment"}; private static final String[] TABLE_NAMES = {"question"};
/** 表前缀 (生成时会去掉前缀) */ /** 表前缀 (生成时会去掉前缀) */
private static final String[] TABLE_PREFIX = {""}; private static final String[] TABLE_PREFIX = {""};
@@ -101,8 +101,8 @@ public class CodeGenerator {
.idType(IdType.ASSIGN_ID) // 雪花算法ID .idType(IdType.ASSIGN_ID) // 雪花算法ID
.addTableFills(new Column("create_time", FieldFill.INSERT)) .addTableFills(new Column("create_time", FieldFill.INSERT))
.addTableFills(new Column("update_time", FieldFill.INSERT_UPDATE)) .addTableFills(new Column("update_time", FieldFill.INSERT_UPDATE))
.logicDeleteColumnName("del_flag") .logicDeleteColumnName("is_delete")
.logicDeletePropertyName("delFlag") .logicDeletePropertyName("isDelete")
// Mapper 策略 // Mapper 策略
.mapperBuilder() .mapperBuilder()
.enableBaseResultMap() .enableBaseResultMap()

View File

@@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>aioj-backend-common-security</artifactId>
<version>1.0.0</version>
<description>AIOJ 公共安全模块 - JWT 认证和 Spring Security 配置</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-core</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -53,7 +53,7 @@ public class SecurityConfiguration {
.permitAll() .permitAll()
// 其他请求需要认证(可由子类覆盖此配置) // 其他请求需要认证(可由子类覆盖此配置)
.anyRequest() .anyRequest()
.authenticated()) .permitAll())
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build(); return http.build();
} }

View File

@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>aioj-backend-common-starter</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<description>AIOJ 公共模块启动器 (聚合常用依赖)</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-core</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-log</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,81 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>ai-oj</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>aioj-backend-file-service</artifactId>
<version>1.0.0</version>
<description>AIOJ 文件服务</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<properties>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.260.1</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-core</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-log</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-mybatis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-crypto</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,75 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>ai-oj</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>aioj-backend-gateway</artifactId>
<version>1.0.0</version>
<description>AIOJ API网关服务</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway-server-webflux</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-extension</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-gateway-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-core</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</exclusion>
<exclusion>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>ai-oj</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>aioj-backend-judge-service</artifactId>
<version>1.0.0</version>
<description>AIOJ 判题服务</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
</project>

View File

@@ -5,7 +5,7 @@ import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.time.LocalDateTime;
/** /**
* 题目实体类 * 题目实体类
@@ -90,12 +90,13 @@ public class Question implements Serializable {
* 创建时间 * 创建时间
*/ */
@TableField(fill = FieldFill.INSERT) @TableField(fill = FieldFill.INSERT)
private Date createTime; private LocalDateTime createTime;
/** /**
* 更新时间 * 更新时间
*/ */
private Date updateTime; @TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
/** /**
* 是否删除 * 是否删除

View File

@@ -66,5 +66,6 @@ public class QuestionSubmit implements Serializable {
/** /**
* 是否删除 * 是否删除
*/ */
@TableLogic
private Integer isDelete; private Integer isDelete;
} }

View File

@@ -7,6 +7,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable;
import java.util.List; import java.util.List;
/** /**
@@ -15,7 +16,7 @@ import java.util.List;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Schema(description = "题目查询请求") @Schema(description = "题目查询请求")
public class QuestionQueryRequestDTO extends Page<Question> implements java.io.Serializable { public class QuestionQueryRequestDTO extends Page<Question> implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@@ -1,10 +1,12 @@
package cn.meowrain.aioj.backend.question.dto.resp; package cn.meowrain.aioj.backend.question.dto.resp;
import cn.meowrain.aioj.backend.question.dto.req.JudgeCase;
import cn.meowrain.aioj.backend.question.dto.req.JudgeConfig;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
/** /**
@@ -49,6 +51,12 @@ public class QuestionResponseDTO implements Serializable {
@Schema(description = "标签列表", example = "[\"\", \"数组\", \"算法\"]") @Schema(description = "标签列表", example = "[\"\", \"数组\", \"算法\"]")
private List<String> tags; private List<String> tags;
/**
* 判题用例列表
*/
@Schema(description = "判题用例列表")
private List<JudgeCase> judgeCase;
/** /**
* 通过数 * 通过数
*/ */
@@ -62,11 +70,11 @@ public class QuestionResponseDTO implements Serializable {
private Integer submitCount; private Integer submitCount;
/** /**
* 判题配置JSON格式字符串 * 判题配置
* 包含 timeLimit, memoryLimit, stackLimit 等 * 包含 timeLimit, memoryLimit, stackLimit 等
*/ */
@Schema(description = "判题配置 (JSON字符串包含时间限制、内存限制等)", example = "{\"timeLimit\": 1000, \"memoryLimit\": 256}") @Schema(description = "判题配置", example = "{\"timeLimit\": 1000, \"memoryLimit\": 256}")
private String judgeConfig; private JudgeConfig judgeConfig;
/** /**
* 点赞数 * 点赞数
@@ -89,12 +97,12 @@ public class QuestionResponseDTO implements Serializable {
/** /**
* 创建时间 * 创建时间
*/ */
@Schema(description = "创建时间", example = "2024-01-20 12:00:00") @Schema(description = "创建时间", example = "2024-01-20T12:00:00")
private Date createTime; private LocalDateTime createTime;
/** /**
* 更新时间 * 更新时间
*/ */
@Schema(description = "更新时间", example = "2024-01-21 10:30:00") @Schema(description = "更新时间", example = "2024-01-21T10:30:00")
private Date updateTime; private LocalDateTime updateTime;
} }

View File

@@ -1,7 +1,10 @@
package cn.meowrain.aioj.backend.question.service; package cn.meowrain.aioj.backend.question.service;
import cn.meowrain.aioj.backend.question.dao.entity.Question; import cn.meowrain.aioj.backend.question.dao.entity.Question;
import cn.meowrain.aioj.backend.question.dto.req.QuestionCreateRequestDTO;
import cn.meowrain.aioj.backend.question.dto.req.QuestionQueryRequestDTO; import cn.meowrain.aioj.backend.question.dto.req.QuestionQueryRequestDTO;
import cn.meowrain.aioj.backend.question.dto.req.QuestionUpdateRequestDTO;
import cn.meowrain.aioj.backend.question.dto.resp.QuestionResponseDTO;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
@@ -10,6 +13,13 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/ */
public interface QuestionService extends IService<Question> { public interface QuestionService extends IService<Question> {
/**
* 创建题目(使用责任链校验)
* @param requestDTO 题目创建请求DTO
* @return 题目ID
*/
Long createQuestionWithChain(QuestionCreateRequestDTO requestDTO);
/** /**
* 创建题目 * 创建题目
* @param question 题目信息 * @param question 题目信息
@@ -36,7 +46,7 @@ public interface QuestionService extends IService<Question> {
* @param questionId 题目ID * @param questionId 题目ID
* @return 题目详情 * @return 题目详情
*/ */
Question getQuestionById(Long questionId); QuestionResponseDTO getQuestionById(Long questionId);
/** /**
* 根据ID获取题目详情内部接口 * 根据ID获取题目详情内部接口
@@ -50,5 +60,5 @@ public interface QuestionService extends IService<Question> {
* @param request 查询条件 * @param request 查询条件
* @return 题目分页列表 * @return 题目分页列表
*/ */
Page<Question> listQuestions(QuestionQueryRequestDTO request); Page<QuestionResponseDTO> listQuestions(QuestionQueryRequestDTO request);
} }

View File

@@ -1,23 +1,83 @@
package cn.meowrain.aioj.backend.question.service.impl; package cn.meowrain.aioj.backend.question.service.impl;
import cn.meowrain.aioj.backend.question.common.enums.ChainMarkEnums;
import cn.meowrain.aioj.backend.question.dao.entity.Question; import cn.meowrain.aioj.backend.question.dao.entity.Question;
import cn.meowrain.aioj.backend.question.dao.mapper.QuestionMapper; import cn.meowrain.aioj.backend.question.dao.mapper.QuestionMapper;
import cn.meowrain.aioj.backend.question.dto.req.QuestionQueryRequestDTO; import cn.meowrain.aioj.backend.question.dto.chains.context.QuestionCreateRequestParamVerifyContext;
import cn.meowrain.aioj.backend.question.dto.req.*;
import cn.meowrain.aioj.backend.question.dto.resp.QuestionResponseDTO;
import cn.meowrain.aioj.backend.question.service.QuestionService; import cn.meowrain.aioj.backend.question.service.QuestionService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.fasterxml.jackson.core.type.TypeReference;
import java.util.List;
/** /**
* 题目服务实现 * 题目服务实现
*/ */
@Slf4j
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService { public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService {
private final QuestionCreateRequestParamVerifyContext questionCreateChainContext;
@Override
public Long createQuestionWithChain(QuestionCreateRequestDTO requestDTO) {
// 执行责任链校验
log.info("开始执行题目创建责任链校验");
questionCreateChainContext.handler(
ChainMarkEnums.QUESTION_CREATE_PARAM_VERIFY_CHAIN.getMark(),
requestDTO
);
log.info("题目创建责任链校验通过");
// 校验通过,转换为实体并保存
Question question = new Question();
BeanUtils.copyProperties(requestDTO, question);
// 处理 tags 字段List<String> -> JSON 字符串
if (requestDTO.getTags() != null && !requestDTO.getTags().isEmpty()) {
try {
com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
question.setTags(mapper.writeValueAsString(requestDTO.getTags()));
} catch (Exception e) {
log.error("序列化 tags 失败", e);
}
}
// 处理 judgeConfig 字段JudgeConfig 对象 -> JSON 字符串
if (requestDTO.getJudgeConfig() != null) {
try {
com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
question.setJudgeConfig(mapper.writeValueAsString(requestDTO.getJudgeConfig()));
} catch (Exception e) {
log.error("序列化 judgeConfig 失败", e);
}
}
// 处理 judgeCase 字段List<JudgeCase> -> JSON 字符串
if (requestDTO.getJudgeCase() != null && !requestDTO.getJudgeCase().isEmpty()) {
try {
com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
question.setJudgeCase(mapper.writeValueAsString(requestDTO.getJudgeCase()));
} catch (Exception e) {
log.error("序列化 judgeCase 失败", e);
}
}
question.setUserId(1L);
this.save(question);
return question.getId();
}
@Override @Override
public Long createQuestion(Question question) { public Long createQuestion(Question question) {
this.save(question); this.save(question);
@@ -35,8 +95,9 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i
} }
@Override @Override
public Question getQuestionById(Long questionId) { public QuestionResponseDTO getQuestionById(Long questionId) {
return this.getById(questionId); Question question = this.getById(questionId);
return convertToDTO(question);
} }
@Override @Override
@@ -45,7 +106,7 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i
} }
@Override @Override
public Page<Question> listQuestions(QuestionQueryRequestDTO request) { public Page<QuestionResponseDTO> listQuestions(QuestionQueryRequestDTO request) {
LambdaQueryWrapper<Question> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<Question> wrapper = new LambdaQueryWrapper<>();
// ID 精确查询 // ID 精确查询
@@ -80,6 +141,64 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i
} }
// 直接使用 request 作为分页对象 // 直接使用 request 作为分页对象
return this.page(request, wrapper); Page<Question> page = this.page(request, wrapper);
// 转换为 DTO
Page<QuestionResponseDTO> dtoPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
dtoPage.setRecords(page.getRecords().stream()
.map(this::convertToDTO)
.toList());
return dtoPage;
}
/**
* 将 Question 实体转换为 QuestionResponseDTO
*/
private QuestionResponseDTO convertToDTO(Question question) {
if (question == null) {
return null;
}
QuestionResponseDTO dto = new QuestionResponseDTO();
BeanUtils.copyProperties(question, dto);
// 处理 tags 字段JSON 字符串 -> List<String>
if (question.getTags() != null && !question.getTags().isEmpty()) {
try {
ObjectMapper mapper = new ObjectMapper();
List<String> tagList = mapper.readValue(question.getTags(),
new TypeReference<List<String>>() {});
dto.setTags(tagList);
} catch (Exception e) {
log.error("解析 tags JSON 失败: {}", question.getTags(), e);
}
}
// 处理 judgeConfig 字段JSON 字符串 -> JudgeConfig 对象
if (question.getJudgeConfig() != null && !question.getJudgeConfig().isEmpty()) {
try {
ObjectMapper mapper = new ObjectMapper();
JudgeConfig judgeConfig =
mapper.readValue(question.getJudgeConfig(),
JudgeConfig.class);
dto.setJudgeConfig(judgeConfig);
} catch (Exception e) {
log.error("解析 judgeConfig JSON 失败: {}", question.getJudgeConfig(), e);
}
}
// 处理 judgeCase 字段JSON 字符串 -> List<JudgeCase>
if (question.getJudgeCase() != null && !question.getJudgeCase().isEmpty()) {
try {
ObjectMapper mapper = new ObjectMapper();
List<JudgeCase> judgeCaseList =
mapper.readValue(question.getJudgeCase(),
new TypeReference<List<JudgeCase>>() {});
dto.setJudgeCase(judgeCaseList);
} catch (Exception e) {
log.error("解析 judgeCase JSON 失败: {}", question.getJudgeCase(), e);
}
}
return dto;
} }
} }

View File

@@ -20,8 +20,8 @@ springdoc:
operations-sorter: alpha operations-sorter: alpha
group-configs: group-configs:
- group: 'default' - group: 'default'
paths-to-match: '/api/**' paths-to-match: '/**'
packages-to-scan: cn.meowrain.aioj.backend.questionservice.controller packages-to-scan: cn.meowrain.aioj.backend.question
knife4j: knife4j:
basic: basic:
enable: true enable: true

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>ai-oj</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>aioj-backend-upms</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<description>AIOJ 用户权限管理系统 (UPMS)</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<modules>
<module>aioj-backend-upms-api</module>
<module>aioj-backend-upms-biz</module>
</modules>
</project>

View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-upms</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>aioj-backend-upms-api</artifactId>
<version>1.0.0</version>
<description>AIOJ UPMS API 接口定义</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-core</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-mybatis</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-feign</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-upms</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>aioj-backend-upms-biz</artifactId>
<version>1.0.0</version>
<description>AIOJ UPMS 业务实现</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-mybatis</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-upms-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,83 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>ai-oj</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>aioj-backend-user-service</artifactId>
<version>1.0.0</version>
<description>AIOJ 用户服务</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-core</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-log</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-mybatis</artifactId>
</dependency>
<dependency>
<groupId>cn.meowrain.aioj</groupId>
<artifactId>aioj-backend-common-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-crypto</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>