Compare commits
197 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e14420a4a3 | |||
| 5ea2d62f7f | |||
| a76e5306cf | |||
| b077443687 | |||
| 821be43cfd | |||
| 1bd0490dd9 | |||
| 1887802f52 | |||
| 1e0fb9883b | |||
| 989d1db754 | |||
| 4d9812466a | |||
|
|
925817bb1e | ||
|
|
71c82fa332 | ||
|
|
2b18350e5a | ||
|
|
46f258dd97 | ||
|
|
718f84b8a4 | ||
|
|
237a4f10a8 | ||
|
|
3f56528979 | ||
|
|
92d85b3e44 | ||
|
|
61d70bb379 | ||
|
|
035794f916 | ||
|
|
10c03265d8 | ||
|
|
d7944a0c64 | ||
| af808a80b7 | |||
| 4526e237a6 | |||
| 1963b6df29 | |||
|
|
ab75199f17 | ||
|
|
1ea941a4d1 | ||
| 319f57419f | |||
| 181c267219 | |||
|
|
341dab35d0 | ||
|
|
b13795a3b7 | ||
| 53f6de63ce | |||
| 7505a27317 | |||
|
|
61e35598b3 | ||
|
|
7837fca784 | ||
| 3c21fc3500 | |||
| bd4ca454a3 | |||
|
|
59cd0049e2 | ||
|
|
c7a66f623f | ||
|
|
5529646506 | ||
|
|
16abb964a5 | ||
| 894e9d38b4 | |||
|
|
40aa49a5ba | ||
|
|
b8e649c13c | ||
|
|
5da9d2135a | ||
|
|
9dca80de0e | ||
| 65e8179e14 | |||
| 678b9eeb6e | |||
|
|
e0aa844162 | ||
|
|
93a5b7e3b2 | ||
|
|
a73cc74342 | ||
|
|
e92e6ffeca | ||
| 06063b975a | |||
| 65e68d3c8b | |||
|
|
a9e3e9146a | ||
|
|
87fbf7c686 | ||
|
|
7dda8cae1c | ||
|
|
8b45b63bbe | ||
| a57ab82151 | |||
| 4f5ee086a4 | |||
|
|
7fca0228fd | ||
|
|
ea534f1a90 | ||
| a793020c5e | |||
| 16bac95dee | |||
|
|
01e9b12eaf | ||
|
|
d925089869 | ||
|
|
b4c0be4051 | ||
|
|
44b025f686 | ||
|
|
132b020763 | ||
|
|
8f1fec0169 | ||
|
|
a4fe5c17e6 | ||
|
|
8e484ad8de | ||
|
|
625d8b1383 | ||
|
|
561eed3147 | ||
|
|
10218685cc | ||
|
|
f8515a5bb0 | ||
| 877f6b6046 | |||
| a07f29f9b2 | |||
|
|
2824d20fc1 | ||
| af1102a1b9 | |||
|
|
461bbaec56 | ||
|
|
4ccef54e7e | ||
|
|
bb5a154768 | ||
|
|
ce9c3099c0 | ||
| d9c60a21db | |||
| 978ba1ecd9 | |||
| 0a043be325 | |||
| 00615712f8 | |||
| 918514a6ec | |||
|
|
a3a1ef430e | ||
|
|
b376d406d7 | ||
|
|
e6d382c7cf | ||
| 27dabcce7a | |||
| d294bfc606 | |||
| c4a6307b9a | |||
| b41598f7f8 | |||
|
|
ce36c26dff | ||
|
|
6cc473fead | ||
|
|
d1373a5524 | ||
| 48935314bf | |||
| 5a5557d479 | |||
|
|
a9ae28e3e1 | ||
|
|
35fb15e2e3 | ||
|
|
40bfe138f0 | ||
|
|
f020747b1f | ||
|
|
c0a2047544 | ||
|
|
cff6d963a0 | ||
|
|
1ca17d6b92 | ||
| 44ee564b5f | |||
|
|
e70ed44bfb | ||
|
|
a1054006e6 | ||
|
|
3f199d375b | ||
|
|
3429e6ac7b | ||
|
|
ac7864f34b | ||
|
|
1596e6fc33 | ||
|
|
67068a03b6 | ||
|
|
337ba0f42a | ||
|
|
42eb767979 | ||
| 326e764f29 | |||
| 3896f6df85 | |||
| 6cf1b91b85 | |||
| 61665d749d | |||
|
|
bf470b1c79 | ||
| 58ea4b3071 | |||
| 69d2a464cb | |||
| 97419396f6 | |||
|
|
5861ce2655 | ||
|
|
a51f6c6e2e | ||
|
|
9d490fbbda | ||
| 9dc9b50b1d | |||
| e06a4b9f89 | |||
|
|
5b0e087dcd | ||
| 796f1502b6 | |||
|
|
a9a2a16618 | ||
|
|
c48769872d | ||
|
|
9830e0d3b3 | ||
| 52798ce478 | |||
| 35ed6f0b1b | |||
|
|
50e127c505 | ||
|
|
f2cf55e293 | ||
|
|
520fbcf177 | ||
| d9c50d4750 | |||
|
|
3f2c7877ed | ||
|
|
78de817ca9 | ||
|
|
6b2ae0f50d | ||
| b3fda1650b | |||
| d7b8733123 | |||
| 81a6f0ee43 | |||
| 7f9bd444dd | |||
|
|
049ee30611 | ||
|
|
0d83336140 | ||
| bf96853b68 | |||
|
|
4080fa4ce5 | ||
|
|
d069086ea4 | ||
|
|
b4bbcb4d7d | ||
|
|
23ad7f14f9 | ||
|
|
4619edaad8 | ||
|
|
593224a478 | ||
|
|
8717b32306 | ||
|
|
7188b7a500 | ||
|
|
3d9fda6230 | ||
|
|
4c160a7bb3 | ||
|
|
d2b61c6d95 | ||
|
|
de06ae4b92 | ||
|
|
595bd526d4 | ||
|
|
960aee1b68 | ||
|
|
ec89859f60 | ||
|
|
64b7eded58 | ||
|
|
a4754cb513 | ||
|
|
00df9d643b | ||
|
|
d9ef0b8fa6 | ||
|
|
02d0d55a9d | ||
|
|
801e48b660 | ||
|
|
c08fc2bb79 | ||
|
|
2334fae638 | ||
|
|
880626acfc | ||
|
|
8f9e974aad | ||
| 962101f37a | |||
|
|
9738eec256 | ||
|
|
7caffa67cc | ||
|
|
5bfea2b020 | ||
|
|
a496d61524 | ||
|
|
0427eebee7 | ||
|
|
60c7ff577d | ||
|
|
025be43257 | ||
|
|
e5e0823e7a | ||
|
|
865d3f8f22 | ||
|
|
b992471374 | ||
|
|
bc369ad2dc | ||
| a6f8b2cd25 | |||
| 97e23b2ad1 | |||
| 83b06b7648 | |||
|
|
64262ad748 | ||
|
|
6b2ab8eed7 | ||
|
|
4ddb774b32 | ||
|
|
09a8f99ab8 | ||
|
|
0922190012 |
4
.vscode/settings.json
vendored
Normal file
4
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"java.configuration.updateBuildConfiguration": "automatic",
|
||||||
|
"java.compile.nullAnalysis.mode": "automatic"
|
||||||
|
}
|
||||||
@ -18,14 +18,17 @@ services:
|
|||||||
--max_allowed_packet=128M
|
--max_allowed_packet=128M
|
||||||
--default-authentication-plugin=caching_sha2_password
|
--default-authentication-plugin=caching_sha2_password
|
||||||
ports:
|
ports:
|
||||||
- 13306:3306
|
- 25523:3306
|
||||||
|
# 添加数据卷挂载,将MySQL数据持久化到宿主机目录
|
||||||
|
volumes:
|
||||||
|
- /home/visionx/AIOL/mysql-jeecg:/var/lib/mysql
|
||||||
networks:
|
networks:
|
||||||
- jeecg-boot
|
- jeecg-boot
|
||||||
|
|
||||||
jeecg-boot-redis:
|
jeecg-boot-redis:
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/jeecgdocker/redis:5.0
|
image: registry.cn-hangzhou.aliyuncs.com/jeecgdocker/redis:5.0
|
||||||
# ports:
|
ports:
|
||||||
# - 3792:6379
|
- 25524:6379
|
||||||
restart: always
|
restart: always
|
||||||
hostname: jeecg-boot-redis
|
hostname: jeecg-boot-redis
|
||||||
container_name: jeecg-boot-redis
|
container_name: jeecg-boot-redis
|
||||||
@ -39,8 +42,8 @@ services:
|
|||||||
POSTGRES_USER: postgres
|
POSTGRES_USER: postgres
|
||||||
POSTGRES_PASSWORD: postgres
|
POSTGRES_PASSWORD: postgres
|
||||||
POSTGRES_DB: vector_db
|
POSTGRES_DB: vector_db
|
||||||
ports:
|
# ports:
|
||||||
- 5432:5432
|
# - 25524:5432
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
- jeecg-boot
|
- jeecg-boot
|
||||||
@ -56,7 +59,7 @@ services:
|
|||||||
image: jeecg-boot-system
|
image: jeecg-boot-system
|
||||||
hostname: jeecg-boot-system
|
hostname: jeecg-boot-system
|
||||||
ports:
|
ports:
|
||||||
- 8080:8080
|
- 25525:8080
|
||||||
networks:
|
networks:
|
||||||
- jeecg-boot
|
- jeecg-boot
|
||||||
jeecg-vue:
|
jeecg-vue:
|
||||||
@ -69,8 +72,9 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- jeecg-boot
|
- jeecg-boot
|
||||||
ports:
|
ports:
|
||||||
- 80:80
|
- 25526:80
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
jeecg-boot:
|
jeecg-boot:
|
||||||
name: jeecg_boot
|
name: jeecg_boot
|
||||||
|
|
||||||
|
|||||||
@ -165,7 +165,7 @@ public class JeecgBootExceptionHandler {
|
|||||||
public Result<?> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
|
public Result<?> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
addSysLog(e);
|
addSysLog(e);
|
||||||
return Result.error("文件大小超出10MB限制, 请压缩或降低文件质量! ");
|
return Result.error("文件大小超出限制, 请压缩或降低文件质量! ");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -56,6 +56,7 @@ public class MybatisInterceptor implements Interceptor {
|
|||||||
if (sysUser != null) {
|
if (sysUser != null) {
|
||||||
// 登录人账号
|
// 登录人账号
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
|
// field.set(parameter, sysUser.getId());
|
||||||
field.set(parameter, sysUser.getUsername());
|
field.set(parameter, sysUser.getUsername());
|
||||||
field.setAccessible(false);
|
field.setAccessible(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,7 +61,7 @@ public class ShiroRealm extends AuthorizingRealm {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
||||||
log.debug("===============Shiro权限认证开始============ [ roles、permissions]==========");
|
log.info("===============Shiro权限认证开始============ [ roles、permissions]==========");
|
||||||
String username = null;
|
String username = null;
|
||||||
String userId = null;
|
String userId = null;
|
||||||
if (principals != null) {
|
if (principals != null) {
|
||||||
@ -73,13 +73,12 @@ public class ShiroRealm extends AuthorizingRealm {
|
|||||||
|
|
||||||
// 设置用户拥有的角色集合,比如“admin,test”
|
// 设置用户拥有的角色集合,比如“admin,test”
|
||||||
Set<String> roleSet = commonApi.queryUserRolesById(userId);
|
Set<String> roleSet = commonApi.queryUserRolesById(userId);
|
||||||
//System.out.println(roleSet.toString());
|
// System.out.println(roleSet.toString());
|
||||||
info.setRoles(roleSet);
|
info.setRoles(roleSet);
|
||||||
|
|
||||||
// 设置用户拥有的权限集合,比如“sys:role:add,sys:user:add”
|
// 设置用户拥有的权限集合,比如“sys:role:add,sys:user:add”
|
||||||
Set<String> permissionSet = commonApi.queryUserAuths(userId);
|
Set<String> permissionSet = commonApi.queryUserAuths(userId);
|
||||||
info.addStringPermissions(permissionSet);
|
info.addStringPermissions(permissionSet);
|
||||||
//System.out.println(permissionSet);
|
|
||||||
log.info("===============Shiro权限认证成功==============");
|
log.info("===============Shiro权限认证成功==============");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|||||||
43
jeecg-boot/jeecg-boot-module/jeecg-module-aiol/pom.xml
Normal file
43
jeecg-boot/jeecg-boot-module/jeecg-module-aiol/pom.xml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<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">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
|
<artifactId>jeecg-boot-module</artifactId>
|
||||||
|
<version>3.8.2</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>jeecg-module-aiol</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>jeecg-module-aiol</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
|
<artifactId>jeecg-boot-base-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
|
<artifactId>jeecg-system-local-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
|
<artifactId>jeecg-system-biz</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/ws.schild/jave-all-deps -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>ws.schild</groupId>
|
||||||
|
<artifactId>jave-all-deps</artifactId>
|
||||||
|
<version>3.5.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package org.jeecg.modules.aiol.constant;
|
||||||
|
|
||||||
|
public class CourseSectionTypeConst {
|
||||||
|
public static final int VIDEO = 0;
|
||||||
|
public static final int DOCUMENT = 1;
|
||||||
|
public static final int EXAM = 2;
|
||||||
|
public static final int HOMEWORK = 3;
|
||||||
|
public static final int EXERCISE = 4;
|
||||||
|
public static final int DISCUSSION = 5;
|
||||||
|
}
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
package org.jeecg.modules.aiol.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* entity_link 表类型常量定义
|
||||||
|
* source_type:主体类型
|
||||||
|
* target_type:内容类型
|
||||||
|
*/
|
||||||
|
public final class EntityLinkConst {
|
||||||
|
|
||||||
|
private EntityLinkConst() {}
|
||||||
|
|
||||||
|
/** 主体类型 */
|
||||||
|
public static final class SourceType {
|
||||||
|
private SourceType() {}
|
||||||
|
// 课程
|
||||||
|
public static final String COURSE = "course";
|
||||||
|
// 课程分类
|
||||||
|
public static final String COURSE_CATEGORY = "course_category";
|
||||||
|
// 课程章节
|
||||||
|
public static final String COURSE_SECTION = "course_section";
|
||||||
|
// 专题(字典/专题)
|
||||||
|
public static final String SUBJECT = "subject";
|
||||||
|
// 活动
|
||||||
|
public static final String ACTIVITY = "activity";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 内容类型 */
|
||||||
|
public static final class TargetType {
|
||||||
|
private TargetType() {}
|
||||||
|
// 资源(对应资源表),包括视频和文档
|
||||||
|
public static final String RESOURCE = "resource";
|
||||||
|
// 作业(对应作业表)
|
||||||
|
public static final String HOMEWORK = "homework";
|
||||||
|
// 考试(对应考试表),包括考试和练习
|
||||||
|
public static final String EXAM = "exam";
|
||||||
|
// 课程
|
||||||
|
public static final String COURSE = "course";
|
||||||
|
// 题库
|
||||||
|
public static final String REPO = "repo";
|
||||||
|
// 班级
|
||||||
|
public static final String CLASS = "class";
|
||||||
|
// 讨论
|
||||||
|
public static final String DISCUSSION = "discussion";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 资源类型 0:视频,1:图片,2:文档 */
|
||||||
|
public static final class ResourceType {
|
||||||
|
private ResourceType() {}
|
||||||
|
public static final int VIDEO = 0;
|
||||||
|
public static final int IMAGE = 1;
|
||||||
|
public static final int DOCUMENT = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package org.jeecg.modules.aiol.constant;
|
||||||
|
|
||||||
|
public class EntityPermissionConst {
|
||||||
|
|
||||||
|
public static final class EntityType {
|
||||||
|
private EntityType() {}
|
||||||
|
public static final String COURSE = "course";
|
||||||
|
public static final String CLASS = "class";
|
||||||
|
public static final String ACTIVITY = "activity";
|
||||||
|
public static final String HOMEWORK = "homework";
|
||||||
|
public static final String EXAM = "exam";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Mode {
|
||||||
|
private Mode() {}
|
||||||
|
public static final String READ = "read";
|
||||||
|
public static final String WRITE = "write";
|
||||||
|
public static final String MANAGE = "manage";
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package org.jeecg.modules.aiol.constant;
|
||||||
|
|
||||||
|
public class RedisConst {
|
||||||
|
// 视频资源信息
|
||||||
|
public static final String VIDEO_RESOURCE_CACHE_KEY_PREFIX = "aiol:video_resource:";
|
||||||
|
public static final int VIDEO_RESOURCE_CACHE_EXPIRE = 30 * 24 * 60 * 60; // 30天过期
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package org.jeecg.modules.aiol.constant;
|
||||||
|
|
||||||
|
public final class ResourceTypeConst {
|
||||||
|
public static final int VIDEO = 0;
|
||||||
|
public static final int IMAGE = 1;
|
||||||
|
public static final int DOCUMENT = 2;
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
package org.jeecg.modules.aiol.constant;
|
||||||
|
|
||||||
|
public class RoleConst {
|
||||||
|
public static final String TEACHER_ROLE_ID = "1955367301787348993";
|
||||||
|
public static final String STUDENT_ROLE_ID = "1955367267343724546";
|
||||||
|
}
|
||||||
@ -0,0 +1,221 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.config.shiro.IgnoreAuth;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolActivity;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolTag;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolTagMapper;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolActivityService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 活动
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name = "活动")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolActivity")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolActivityController extends JeecgController<AiolActivity, IAiolActivityService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolActivityService aiolActivityService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolActivity
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "活动-分页列表查询")
|
||||||
|
@Operation(summary = "活动-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<IPage<AiolActivity>> queryPageList(AiolActivity aiolActivity,
|
||||||
|
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
|
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolActivity> queryWrapper = QueryGenerator.initQueryWrapper(aiolActivity, req.getParameterMap());
|
||||||
|
Page<AiolActivity> page = new Page<AiolActivity>(pageNo, pageSize);
|
||||||
|
IPage<AiolActivity> pageList = aiolActivityService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolActivity
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "活动-添加")
|
||||||
|
@Operation(summary = "活动-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_activity:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolActivity aiolActivity) {
|
||||||
|
aiolActivityService.save(aiolActivity);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolActivity
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "活动-编辑")
|
||||||
|
@Operation(summary = "活动-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_activity:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolActivity aiolActivity) {
|
||||||
|
aiolActivityService.updateById(aiolActivity);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "活动-通过id删除")
|
||||||
|
@Operation(summary = "活动-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_activity:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
aiolActivityService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "活动-批量删除")
|
||||||
|
@Operation(summary = "活动-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_activity:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||||
|
this.aiolActivityService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "活动-通过id查询")
|
||||||
|
@Operation(summary = "活动-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolActivity> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
AiolActivity aiolActivity = aiolActivityService.getById(id);
|
||||||
|
if (aiolActivity == null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolActivity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolActivity
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_activity:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolActivity aiolActivity) {
|
||||||
|
return super.exportXls(request, aiolActivity, AiolActivity.class, "活动");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_activity:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolActivity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AiolTagMapper aiolTagMapper;
|
||||||
|
|
||||||
|
@GetMapping("/selected")
|
||||||
|
@Operation(summary = "查询精选活动")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<AiolActivity>> getSelectedActivities() {
|
||||||
|
// 1. 从 aiol_tag 表查询 target_type='activity' 的 target_id 列表
|
||||||
|
QueryWrapper<AiolTag> tagWrapper = new QueryWrapper<>();
|
||||||
|
tagWrapper.eq("target_type", "activity");
|
||||||
|
List<AiolTag> tags = aiolTagMapper.selectList(tagWrapper);
|
||||||
|
|
||||||
|
if (tags == null || tags.isEmpty()) {
|
||||||
|
return Result.OK(List.of());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 提取 target_id 列表
|
||||||
|
List<String> activityIds = tags.stream()
|
||||||
|
.map(AiolTag::getTargetId)
|
||||||
|
.filter(id -> id != null && !id.trim().isEmpty())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (activityIds.isEmpty()) {
|
||||||
|
return Result.OK(List.of());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 根据 target_id 列表查询活动数据
|
||||||
|
QueryWrapper<AiolActivity> activityWrapper = new QueryWrapper<>();
|
||||||
|
activityWrapper.in("id", activityIds);
|
||||||
|
List<AiolActivity> activities = aiolActivityService.list(activityWrapper);
|
||||||
|
|
||||||
|
return Result.OK(activities);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,221 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolActivity;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolActivitySignup;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolActivityService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolActivitySignupService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
|
import org.jeecg.modules.system.service.impl.SysUserServiceImpl;
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 活动报名
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="活动报名")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolActivitySignup")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolActivitySignupController extends JeecgController<AiolActivitySignup, IAiolActivitySignupService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolActivitySignupService aiolActivitySignupService;
|
||||||
|
@Autowired
|
||||||
|
private SysUserServiceImpl sysUserService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolActivityService aiolActivityService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolActivitySignup
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "活动报名-分页列表查询")
|
||||||
|
@Operation(summary="活动报名-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolActivitySignup>> queryPageList(AiolActivitySignup aiolActivitySignup,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolActivitySignup> queryWrapper = QueryGenerator.initQueryWrapper(aiolActivitySignup, req.getParameterMap());
|
||||||
|
Page<AiolActivitySignup> page = new Page<AiolActivitySignup>(pageNo, pageSize);
|
||||||
|
IPage<AiolActivitySignup> pageList = aiolActivitySignupService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolActivitySignup
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "活动报名-添加")
|
||||||
|
@Operation(summary="活动报名-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_activity_signup:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolActivitySignup aiolActivitySignup) {
|
||||||
|
aiolActivitySignupService.save(aiolActivitySignup);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolActivitySignup
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "活动报名-编辑")
|
||||||
|
@Operation(summary="活动报名-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_activity_signup:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolActivitySignup aiolActivitySignup) {
|
||||||
|
aiolActivitySignupService.updateById(aiolActivitySignup);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "活动报名-通过id删除")
|
||||||
|
@Operation(summary="活动报名-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_activity_signup:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolActivitySignupService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "活动报名-批量删除")
|
||||||
|
@Operation(summary="活动报名-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_activity_signup:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolActivitySignupService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "活动报名-通过id查询")
|
||||||
|
@Operation(summary="活动报名-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolActivitySignup> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolActivitySignup aiolActivitySignup = aiolActivitySignupService.getById(id);
|
||||||
|
if(aiolActivitySignup==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolActivitySignup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolActivitySignup
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_activity_signup:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolActivitySignup aiolActivitySignup) {
|
||||||
|
return super.exportXls(request, aiolActivitySignup, AiolActivitySignup.class, "活动报名");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_activity_signup:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolActivitySignup.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
//查看我报名的活动
|
||||||
|
@GetMapping(value = "/queryMyActivity")
|
||||||
|
@Operation(summary="我的活动查询")
|
||||||
|
public Result<List<AiolActivity>> queryMyActivit(HttpServletRequest req) {
|
||||||
|
try {
|
||||||
|
// 1. 从JWT中获取当前用户信息
|
||||||
|
String username = JwtUtil.getUserNameByToken(req);
|
||||||
|
if (username == null || username.trim().isEmpty()) {
|
||||||
|
return Result.error(401, "用户未登录或token无效");
|
||||||
|
}
|
||||||
|
SysUser currentUser = sysUserService.getUserByName(username);
|
||||||
|
if (currentUser == null) {
|
||||||
|
return Result.error(404, "用户不存在");
|
||||||
|
}
|
||||||
|
// 2. 根据当前用户ID查询报名信息
|
||||||
|
QueryWrapper<AiolActivitySignup> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("user_id", currentUser.getId());
|
||||||
|
List<AiolActivitySignup> list = aiolActivitySignupService.list(queryWrapper);
|
||||||
|
// 3. 根据报名信息中的活动ID查询活动信息
|
||||||
|
List<AiolActivity> activityList = new ArrayList<>();
|
||||||
|
List<String> activityIds = list.stream()
|
||||||
|
.map(AiolActivitySignup::getActivityId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (!activityIds.isEmpty()) {
|
||||||
|
activityList = aiolActivityService.listByIds(activityIds);
|
||||||
|
}
|
||||||
|
return Result.OK(activityList);
|
||||||
|
}catch (Exception e){
|
||||||
|
log.error("查询失败: {}", e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return Result.OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,989 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.config.shiro.IgnoreAuth;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolChat;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolChatMember;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolChatMessage;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolClass;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolClassStudent;
|
||||||
|
import org.jeecg.modules.aiol.dto.ChatWithUnreadCountDTO;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolChatMemberMapper;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolChatMessageMapper;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolClassMapper;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolClassStudentMapper;
|
||||||
|
import org.jeecg.modules.system.mapper.SysUserRoleMapper;
|
||||||
|
import org.jeecg.modules.aiol.constant.RoleConst;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolChatService;
|
||||||
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
|
import org.jeecg.modules.system.entity.SysUserRole;
|
||||||
|
import org.jeecg.modules.system.mapper.SysUserMapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 会话
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-11
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name = "会话")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolChat")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolChatController extends JeecgController<AiolChat, IAiolChatService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolChatService aiolChatService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AiolChatMemberMapper aiolChatMemberMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISysBaseAPI sysBaseApi;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysUserMapper sysUserMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AiolChatMessageMapper aiolChatMessageMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AiolClassMapper aiolClassMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AiolClassStudentMapper aiolClassStudentMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysUserRoleMapper sysUserRoleMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolChat
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
// @AutoLog(value = "会话-分页列表查询")
|
||||||
|
@Operation(summary = "会话-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolChat>> queryPageList(AiolChat aiolChat,
|
||||||
|
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
|
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
QueryWrapper<AiolChat> queryWrapper = QueryGenerator.initQueryWrapper(aiolChat, req.getParameterMap());
|
||||||
|
Page<AiolChat> page = new Page<AiolChat>(pageNo, pageSize);
|
||||||
|
IPage<AiolChat> pageList = aiolChatService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolChat
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话-添加")
|
||||||
|
@Operation(summary = "会话-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_chat:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolChat aiolChat) {
|
||||||
|
aiolChatService.save(aiolChat);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolChat
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话-编辑")
|
||||||
|
@Operation(summary = "会话-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_chat:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = { RequestMethod.PUT, RequestMethod.POST })
|
||||||
|
public Result<String> edit(@RequestBody AiolChat aiolChat) {
|
||||||
|
aiolChatService.updateById(aiolChat);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话-通过id删除")
|
||||||
|
@Operation(summary = "会话-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_chat:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
aiolChatService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话-批量删除")
|
||||||
|
@Operation(summary = "会话-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_chat:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||||
|
this.aiolChatService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
// @AutoLog(value = "会话-通过id查询")
|
||||||
|
@Operation(summary = "会话-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolChat> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
AiolChat aiolChat = aiolChatService.getById(id);
|
||||||
|
if (aiolChat == null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolChat);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolChat
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_chat:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolChat aiolChat) {
|
||||||
|
return super.exportXls(request, aiolChat, AiolChat.class, "会话");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_chat:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolChat.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询当前用户会话列表
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Operation(summary = "查询当前用户会话列表", description = "根据当前登录用户ID查询其参与的会话列表,包含未读消息数")
|
||||||
|
@GetMapping(value = "/my_chats")
|
||||||
|
public Result<List<ChatWithUnreadCountDTO>> queryMyChatList(HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
// 1. 从token获取当前用户信息
|
||||||
|
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
if (token == null || token.trim().isEmpty()) {
|
||||||
|
return Result.error("用户未登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error("用户信息不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 根据用户ID查询会话成员表,获取chat_id列表和last_read_msg_id
|
||||||
|
QueryWrapper<AiolChatMember> memberWrapper = new QueryWrapper<>();
|
||||||
|
memberWrapper.eq("user_id", sysUser.getId());
|
||||||
|
List<AiolChatMember> chatMembers = aiolChatMemberMapper.selectList(memberWrapper);
|
||||||
|
|
||||||
|
if (chatMembers.isEmpty()) {
|
||||||
|
return Result.OK(new java.util.ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 提取chat_id列表
|
||||||
|
List<String> chatIds = chatMembers.stream()
|
||||||
|
.map(AiolChatMember::getChatId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 4. 根据chat_id列表查询会话详情
|
||||||
|
QueryWrapper<AiolChat> chatWrapper = new QueryWrapper<>();
|
||||||
|
chatWrapper.in("id", chatIds);
|
||||||
|
chatWrapper.orderByDesc("create_time");
|
||||||
|
|
||||||
|
List<AiolChat> chatList = aiolChatService.list(chatWrapper);
|
||||||
|
|
||||||
|
// 5. 转换为包含未读消息数的DTO列表
|
||||||
|
List<ChatWithUnreadCountDTO> resultList = new java.util.ArrayList<>();
|
||||||
|
|
||||||
|
for (AiolChat chat : chatList) {
|
||||||
|
ChatWithUnreadCountDTO chatDTO = convertToChatWithUnreadCount(chat, chatMembers, sysUser.getId());
|
||||||
|
resultList.add(chatDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("用户 {} 查询到 {} 个会话", username, resultList.size());
|
||||||
|
return Result.OK(resultList);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询用户会话列表失败: {}", e.getMessage(), e);
|
||||||
|
return Result.error("查询会话列表失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询群聊会话成员列表
|
||||||
|
*
|
||||||
|
* @param chatId 会话ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Operation(summary = "查询群聊会话成员列表", description = "根据会话ID查询该会话的所有成员信息,包括用户ID、真实姓名、头像和教师身份")
|
||||||
|
@GetMapping(value = "/{chatId}/members")
|
||||||
|
public Result<List<Map<String, Object>>> queryChatMembers(@PathVariable(value = "chatId") String chatId) {
|
||||||
|
try {
|
||||||
|
// 1. 根据会话ID查询会话成员
|
||||||
|
QueryWrapper<AiolChatMember> memberWrapper = new QueryWrapper<>();
|
||||||
|
memberWrapper.eq("chat_id", chatId);
|
||||||
|
List<AiolChatMember> chatMembers = aiolChatMemberMapper.selectList(memberWrapper);
|
||||||
|
|
||||||
|
if (chatMembers.isEmpty()) {
|
||||||
|
return Result.OK(new java.util.ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将成员列表按userId建立映射,便于取出member相关字段
|
||||||
|
Map<String, AiolChatMember> userIdToMemberMap = chatMembers.stream()
|
||||||
|
.collect(Collectors.toMap(AiolChatMember::getUserId, m -> m, (a, b) -> a));
|
||||||
|
|
||||||
|
// 2. 提取用户ID列表
|
||||||
|
List<String> userIds = chatMembers.stream()
|
||||||
|
.map(AiolChatMember::getUserId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 3. 查询用户信息
|
||||||
|
List<SysUser> userList = sysUserMapper.selectByIds(userIds);
|
||||||
|
|
||||||
|
// 4. 查询所有用户的教师角色身份
|
||||||
|
Map<String, Boolean> teacherStatusMap = new HashMap<>();
|
||||||
|
if (!userIds.isEmpty()) {
|
||||||
|
try {
|
||||||
|
QueryWrapper<SysUserRole> roleWrapper = new QueryWrapper<>();
|
||||||
|
roleWrapper.eq("role_id", RoleConst.TEACHER_ROLE_ID)
|
||||||
|
.in("user_id", userIds);
|
||||||
|
|
||||||
|
List<SysUserRole> teacherRoleList = sysUserRoleMapper.selectList(roleWrapper);
|
||||||
|
|
||||||
|
// 构建教师身份映射
|
||||||
|
for (SysUserRole userRole : teacherRoleList) {
|
||||||
|
teacherStatusMap.put(userRole.getUserId(), true);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("查询教师角色身份失败: error={}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 构建返回结果
|
||||||
|
List<Map<String, Object>> result = new ArrayList<>();
|
||||||
|
for (SysUser user : userList) {
|
||||||
|
Map<String, Object> memberInfo = new HashMap<>();
|
||||||
|
memberInfo.put("id", user.getId());
|
||||||
|
memberInfo.put("realname", user.getRealname());
|
||||||
|
memberInfo.put("avatar", user.getAvatar());
|
||||||
|
|
||||||
|
// 添加教师身份标记
|
||||||
|
boolean isTeacher = teacherStatusMap.getOrDefault(user.getId(), false);
|
||||||
|
memberInfo.put("isTeacher", isTeacher);
|
||||||
|
|
||||||
|
// 可选:添加更多用户信息
|
||||||
|
memberInfo.put("username", user.getUsername());
|
||||||
|
memberInfo.put("phone", user.getPhone());
|
||||||
|
memberInfo.put("email", user.getEmail());
|
||||||
|
memberInfo.put("sex", user.getSex());
|
||||||
|
|
||||||
|
// 新增:返回aiol_chat_member表中的角色与设置字段
|
||||||
|
AiolChatMember member = userIdToMemberMap.get(user.getId());
|
||||||
|
if (member != null) {
|
||||||
|
memberInfo.put("role", member.getRole());
|
||||||
|
memberInfo.put("izMuted", member.getIzMuted());
|
||||||
|
memberInfo.put("izNotDisturb", member.getIzNotDisturb());
|
||||||
|
memberInfo.put("lastReadMsgId", member.getLastReadMsgId());
|
||||||
|
}
|
||||||
|
|
||||||
|
result.add(memberInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("查询会话 {} 的成员列表,共 {} 个成员", chatId, result.size());
|
||||||
|
return Result.OK(result);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询会话成员列表失败: chatId={}, error={}", chatId, e.getMessage(), e);
|
||||||
|
return Result.error("查询会话成员列表失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询会话消息列表
|
||||||
|
*
|
||||||
|
* @param chatId 会话ID
|
||||||
|
* @param pageNo 页码
|
||||||
|
* @param pageSize 每页大小
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Operation(summary = "查询会话消息列表", description = "根据会话ID查询该会话的消息列表,包含发送者信息")
|
||||||
|
@GetMapping(value = "/{chatId}/messages")
|
||||||
|
public Result<List<Map<String, Object>>> queryChatMessages(
|
||||||
|
@PathVariable(value = "chatId") String chatId) {
|
||||||
|
try {
|
||||||
|
// 1. 构建查询条件
|
||||||
|
QueryWrapper<AiolChatMessage> messageWrapper = new QueryWrapper<>();
|
||||||
|
messageWrapper.eq("chat_id", chatId);
|
||||||
|
messageWrapper.orderByDesc("create_time");
|
||||||
|
|
||||||
|
List<AiolChatMessage> messageList = aiolChatMessageMapper.selectList(messageWrapper);
|
||||||
|
|
||||||
|
if (messageList.isEmpty()) {
|
||||||
|
return Result.OK(new java.util.ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 提取发送者ID列表
|
||||||
|
List<String> senderIds = messageList.stream()
|
||||||
|
.map(AiolChatMessage::getSenderId)
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 3. 查询发送者信息
|
||||||
|
List<SysUser> senderList = sysUserMapper.selectByIds(senderIds);
|
||||||
|
Map<String, SysUser> senderMap = senderList.stream()
|
||||||
|
.collect(Collectors.toMap(SysUser::getId, user -> user));
|
||||||
|
|
||||||
|
// 4. 构建返回结果,包含发送者信息
|
||||||
|
List<Map<String, Object>> result = new java.util.ArrayList<>();
|
||||||
|
for (AiolChatMessage message : messageList) {
|
||||||
|
Map<String, Object> messageInfo = new java.util.HashMap<>();
|
||||||
|
|
||||||
|
// 添加消息基本信息
|
||||||
|
messageInfo.put("id", message.getId());
|
||||||
|
messageInfo.put("chatId", message.getChatId());
|
||||||
|
messageInfo.put("senderId", message.getSenderId());
|
||||||
|
messageInfo.put("content", message.getContent());
|
||||||
|
messageInfo.put("messageType", message.getMessageType());
|
||||||
|
messageInfo.put("status", message.getStatus());
|
||||||
|
messageInfo.put("fileUrl", message.getFileUrl());
|
||||||
|
messageInfo.put("fileName", message.getFileName());
|
||||||
|
messageInfo.put("fileSize", message.getFileSize());
|
||||||
|
messageInfo.put("createTime", message.getCreateTime());
|
||||||
|
|
||||||
|
// 添加发送者信息
|
||||||
|
SysUser sender = senderMap.get(message.getSenderId());
|
||||||
|
if (sender != null) {
|
||||||
|
messageInfo.put("senderInfo", new java.util.HashMap<String, Object>() {
|
||||||
|
{
|
||||||
|
put("id", sender.getId());
|
||||||
|
put("realname", sender.getRealname());
|
||||||
|
put("avatar", sender.getAvatar());
|
||||||
|
put("username", sender.getUsername());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 如果找不到发送者信息,设置默认值
|
||||||
|
messageInfo.put("senderInfo", new java.util.HashMap<String, Object>() {
|
||||||
|
{
|
||||||
|
put("id", message.getSenderId());
|
||||||
|
put("realname", "未知用户");
|
||||||
|
put("avatar", "");
|
||||||
|
put("username", "");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
result.add(messageInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("查询会话 {} 的消息列表,共 {} 条消息", chatId, result.size());
|
||||||
|
return Result.OK(result);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询会话消息列表失败: chatId={}, error={}", chatId, e.getMessage(), e);
|
||||||
|
return Result.error("查询会话消息列表失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询会话详情
|
||||||
|
*
|
||||||
|
* @param chatId 会话ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Operation(summary = "查询会话详情", description = "根据会话ID查询会话详情,群聊类型会包含班级信息")
|
||||||
|
@GetMapping(value = "/{chatId}/detail")
|
||||||
|
public Result<Map<String, Object>> queryChatDetail(@PathVariable(value = "chatId") String chatId) {
|
||||||
|
try {
|
||||||
|
// 1. 查询会话基本信息
|
||||||
|
AiolChat chat = aiolChatService.getById(chatId);
|
||||||
|
if (chat == null) {
|
||||||
|
return Result.error("会话不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 构建返回结果
|
||||||
|
Map<String, Object> result = new java.util.HashMap<>();
|
||||||
|
result.put("id", chat.getId());
|
||||||
|
result.put("type", chat.getType());
|
||||||
|
result.put("name", chat.getName());
|
||||||
|
result.put("avatar", chat.getAvatar());
|
||||||
|
result.put("refId", chat.getRefId());
|
||||||
|
result.put("izAllMuted", chat.getIzAllMuted());
|
||||||
|
result.put("showLabel", chat.getShowLabel());
|
||||||
|
result.put("createBy", chat.getCreateBy());
|
||||||
|
result.put("createTime", chat.getCreateTime());
|
||||||
|
result.put("updateBy", chat.getUpdateBy());
|
||||||
|
result.put("updateTime", chat.getUpdateTime());
|
||||||
|
|
||||||
|
// 3. 如果是群聊类型(type==1),查询班级信息
|
||||||
|
if (chat.getType() != null && chat.getType() == 1 && chat.getRefId() != null) {
|
||||||
|
try {
|
||||||
|
// 查询班级信息
|
||||||
|
AiolClass aiolClass = aiolClassMapper.selectById(chat.getRefId());
|
||||||
|
if (aiolClass != null) {
|
||||||
|
Map<String, Object> classInfo = new java.util.HashMap<>();
|
||||||
|
classInfo.put("id", aiolClass.getId());
|
||||||
|
classInfo.put("name", aiolClass.getName());
|
||||||
|
classInfo.put("courseId", aiolClass.getCourseId());
|
||||||
|
classInfo.put("inviteCode", aiolClass.getInviteCode());
|
||||||
|
classInfo.put("createBy", aiolClass.getCreateBy());
|
||||||
|
classInfo.put("createTime", aiolClass.getCreateTime());
|
||||||
|
|
||||||
|
// 查询班级人数
|
||||||
|
QueryWrapper<AiolClassStudent> studentWrapper = new QueryWrapper<>();
|
||||||
|
studentWrapper.eq("class_id", aiolClass.getId());
|
||||||
|
long studentCount = aiolClassStudentMapper.selectCount(studentWrapper);
|
||||||
|
classInfo.put("studentCount", studentCount);
|
||||||
|
|
||||||
|
result.put("classInfo", classInfo);
|
||||||
|
} else {
|
||||||
|
log.warn("群聊会话 {} 关联的班级 {} 不存在", chatId, chat.getRefId());
|
||||||
|
result.put("classInfo", null);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询群聊班级信息失败: chatId={}, refId={}, error={}",
|
||||||
|
chatId, chat.getRefId(), e.getMessage(), e);
|
||||||
|
result.put("classInfo", null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.put("classInfo", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("查询会话详情成功: chatId={}, type={}", chatId, chat.getType());
|
||||||
|
return Result.OK(result);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询会话详情失败: chatId={}, error={}", chatId, e.getMessage(), e);
|
||||||
|
return Result.error("查询会话详情失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开启全员禁言
|
||||||
|
*
|
||||||
|
* @param chatId 会话ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话-开启全员禁言")
|
||||||
|
@Operation(summary = "开启全员禁言", description = "开启群聊的全员禁言功能,设置iz_all_muted字段为1")
|
||||||
|
@PostMapping(value = "/{chatId}/mute_all")
|
||||||
|
public Result<String> muteAll(@PathVariable(value = "chatId") String chatId) {
|
||||||
|
try {
|
||||||
|
return updateChatSetting(chatId, "iz_all_muted", 1, "开启全员禁言");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("开启全员禁言失败: chatId={}, error={}", chatId, e.getMessage(), e);
|
||||||
|
return Result.error("开启全员禁言失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭全员禁言
|
||||||
|
*
|
||||||
|
* @param chatId 会话ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话-关闭全员禁言")
|
||||||
|
@Operation(summary = "关闭全员禁言", description = "关闭群聊的全员禁言功能,设置iz_all_muted字段为0")
|
||||||
|
@PostMapping(value = "/{chatId}/unmute_all")
|
||||||
|
public Result<String> unmuteAll(@PathVariable(value = "chatId") String chatId) {
|
||||||
|
try {
|
||||||
|
return updateChatSetting(chatId, "iz_all_muted", 0, "关闭全员禁言");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("关闭全员禁言失败: chatId={}, error={}", chatId, e.getMessage(), e);
|
||||||
|
return Result.error("关闭全员禁言失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开启显示教师标签
|
||||||
|
*
|
||||||
|
* @param chatId 会话ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话-开启显示教师标签")
|
||||||
|
@Operation(summary = "开启显示教师标签", description = "开启群聊中显示教师标签功能,设置show_label字段为1")
|
||||||
|
@PostMapping(value = "/{chatId}/show_label")
|
||||||
|
public Result<String> showLabel(@PathVariable(value = "chatId") String chatId) {
|
||||||
|
try {
|
||||||
|
return updateChatSetting(chatId, "show_label", 1, "开启显示教师标签");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("开启显示教师标签失败: chatId={}, error={}", chatId, e.getMessage(), e);
|
||||||
|
return Result.error("开启显示教师标签失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭显示教师标签
|
||||||
|
*
|
||||||
|
* @param chatId 会话ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话-关闭显示教师标签")
|
||||||
|
@Operation(summary = "关闭显示教师标签", description = "关闭群聊中显示教师标签功能,设置show_label字段为0")
|
||||||
|
@PostMapping(value = "/{chatId}/hide_label")
|
||||||
|
public Result<String> hideLabel(@PathVariable(value = "chatId") String chatId) {
|
||||||
|
try {
|
||||||
|
return updateChatSetting(chatId, "show_label", 0, "关闭显示教师标签");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("关闭显示教师标签失败: chatId={}, error={}", chatId, e.getMessage(), e);
|
||||||
|
return Result.error("关闭显示教师标签失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用更新会话设置的方法
|
||||||
|
*
|
||||||
|
* @param chatId 会话ID
|
||||||
|
* @param fieldName 字段名
|
||||||
|
* @param value 字段值
|
||||||
|
* @param operationName 操作名称
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Result<String> updateChatSetting(String chatId, String fieldName, Integer value, String operationName) {
|
||||||
|
// 1. 查询会话是否存在
|
||||||
|
AiolChat chat = aiolChatService.getById(chatId);
|
||||||
|
if (chat == null) {
|
||||||
|
return Result.error("会话不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 根据字段名设置相应的值
|
||||||
|
if ("iz_all_muted".equals(fieldName)) {
|
||||||
|
chat.setIzAllMuted(value);
|
||||||
|
} else if ("show_label".equals(fieldName)) {
|
||||||
|
chat.setShowLabel(value);
|
||||||
|
} else {
|
||||||
|
return Result.error("无效的字段名");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 更新数据库
|
||||||
|
boolean updated = aiolChatService.updateById(chat);
|
||||||
|
if (!updated) {
|
||||||
|
return Result.error(operationName + "失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("{}成功: chatId={}, {}={}", operationName, chatId, fieldName, value);
|
||||||
|
return Result.OK(operationName + "成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 禁言群聊成员
|
||||||
|
*
|
||||||
|
* @param chatId 会话ID
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话-禁言群聊成员")
|
||||||
|
@Operation(summary = "禁言群聊成员", description = "禁言指定群聊成员,设置iz_muted字段为1")
|
||||||
|
@PostMapping(value = "/{chatId}/mute_member/{userId}")
|
||||||
|
public Result<String> muteMember(@PathVariable(value = "chatId") String chatId,
|
||||||
|
@PathVariable(value = "userId") String userId) {
|
||||||
|
try {
|
||||||
|
return updateMemberSetting(chatId, userId, "iz_muted", 1, "禁言群聊成员");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("禁言群聊成员失败: chatId={}, userId={}, error={}", chatId, userId, e.getMessage(), e);
|
||||||
|
return Result.error("禁言群聊成员失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解除禁言群聊成员
|
||||||
|
*
|
||||||
|
* @param chatId 会话ID
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话-解除禁言群聊成员")
|
||||||
|
@Operation(summary = "解除禁言群聊成员", description = "解除指定群聊成员的禁言状态,设置iz_muted字段为0")
|
||||||
|
@PostMapping(value = "/{chatId}/unmute_member/{userId}")
|
||||||
|
public Result<String> unmuteMember(@PathVariable(value = "chatId") String chatId,
|
||||||
|
@PathVariable(value = "userId") String userId) {
|
||||||
|
try {
|
||||||
|
return updateMemberSetting(chatId, userId, "iz_muted", 0, "解除禁言群聊成员");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("解除禁言群聊成员失败: chatId={}, userId={}, error={}", chatId, userId, e.getMessage(), e);
|
||||||
|
return Result.error("解除禁言群聊成员失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开启免打扰
|
||||||
|
*
|
||||||
|
* @param chatId 会话ID
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话-开启免打扰")
|
||||||
|
@Operation(summary = "开启免打扰", description = "为指定用户开启群聊免打扰功能,设置iz_not_disturb字段为1")
|
||||||
|
@PostMapping(value = "/{chatId}/enable_not_disturb/{userId}")
|
||||||
|
public Result<String> enableNotDisturb(@PathVariable(value = "chatId") String chatId,
|
||||||
|
@PathVariable(value = "userId") String userId) {
|
||||||
|
try {
|
||||||
|
return updateMemberSetting(chatId, userId, "iz_not_disturb", 1, "开启免打扰");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("开启免打扰失败: chatId={}, userId={}, error={}", chatId, userId, e.getMessage(), e);
|
||||||
|
return Result.error("开启免打扰失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭免打扰
|
||||||
|
*
|
||||||
|
* @param chatId 会话ID
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话-关闭免打扰")
|
||||||
|
@Operation(summary = "关闭免打扰", description = "为指定用户关闭群聊免打扰功能,设置iz_not_disturb字段为0")
|
||||||
|
@PostMapping(value = "/{chatId}/disable_not_disturb/{userId}")
|
||||||
|
public Result<String> disableNotDisturb(@PathVariable(value = "chatId") String chatId,
|
||||||
|
@PathVariable(value = "userId") String userId) {
|
||||||
|
try {
|
||||||
|
return updateMemberSetting(chatId, userId, "iz_not_disturb", 0, "关闭免打扰");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("关闭免打扰失败: chatId={}, userId={}, error={}", chatId, userId, e.getMessage(), e);
|
||||||
|
return Result.error("关闭免打扰失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用更新群聊成员设置的方法
|
||||||
|
*
|
||||||
|
* @param chatId 会话ID
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @param fieldName 字段名
|
||||||
|
* @param value 字段值
|
||||||
|
* @param operationName 操作名称
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Result<String> updateMemberSetting(String chatId, String userId, String fieldName, Integer value,
|
||||||
|
String operationName) {
|
||||||
|
// 1. 查询群聊成员是否存在
|
||||||
|
QueryWrapper<AiolChatMember> memberWrapper = new QueryWrapper<>();
|
||||||
|
memberWrapper.eq("chat_id", chatId).eq("user_id", userId);
|
||||||
|
AiolChatMember chatMember = aiolChatMemberMapper.selectOne(memberWrapper);
|
||||||
|
|
||||||
|
if (chatMember == null) {
|
||||||
|
return Result.error("该用户不是群聊成员或会话不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 根据字段名设置相应的值
|
||||||
|
if ("iz_muted".equals(fieldName)) {
|
||||||
|
chatMember.setIzMuted(value);
|
||||||
|
} else if ("iz_not_disturb".equals(fieldName)) {
|
||||||
|
chatMember.setIzNotDisturb(value);
|
||||||
|
} else {
|
||||||
|
return Result.error("无效的字段名");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 更新数据库
|
||||||
|
boolean updated = aiolChatMemberMapper.updateById(chatMember) > 0;
|
||||||
|
if (!updated) {
|
||||||
|
return Result.error(operationName + "失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("{}成功: chatId={}, userId={}, {}={}", operationName, chatId, userId, fieldName, value);
|
||||||
|
return Result.OK(operationName + "成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将AiolChat转换为包含未读消息数的DTO
|
||||||
|
*
|
||||||
|
* @param chat 会话实体
|
||||||
|
* @param chatMembers 会话成员列表
|
||||||
|
* @param userId 当前用户ID
|
||||||
|
* @return 包含未读消息数的DTO
|
||||||
|
*/
|
||||||
|
private ChatWithUnreadCountDTO convertToChatWithUnreadCount(AiolChat chat, List<AiolChatMember> chatMembers,
|
||||||
|
String userId) {
|
||||||
|
ChatWithUnreadCountDTO chatDTO = new ChatWithUnreadCountDTO();
|
||||||
|
|
||||||
|
// 复制基本属性
|
||||||
|
chatDTO.setId(chat.getId());
|
||||||
|
chatDTO.setType(chat.getType());
|
||||||
|
chatDTO.setName(chat.getName());
|
||||||
|
chatDTO.setAvatar(chat.getAvatar());
|
||||||
|
chatDTO.setRefId(chat.getRefId());
|
||||||
|
chatDTO.setIzAllMuted(chat.getIzAllMuted());
|
||||||
|
chatDTO.setShowLabel(chat.getShowLabel());
|
||||||
|
chatDTO.setCreateBy(chat.getCreateBy());
|
||||||
|
chatDTO.setCreateTime(chat.getCreateTime());
|
||||||
|
chatDTO.setUpdateBy(chat.getUpdateBy());
|
||||||
|
chatDTO.setUpdateTime(chat.getUpdateTime());
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 计算未读消息数
|
||||||
|
AiolChatMember currentUserMember = chatMembers.stream()
|
||||||
|
.filter(member -> member.getChatId().equals(chat.getId()) && member.getUserId().equals(userId))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
int unreadCount = 0;
|
||||||
|
if (currentUserMember != null) {
|
||||||
|
String lastReadMsgId = currentUserMember.getLastReadMsgId();
|
||||||
|
|
||||||
|
// 查询该会话中last_read_msg_id之后的消息数量
|
||||||
|
QueryWrapper<AiolChatMessage> messageWrapper = new QueryWrapper<>();
|
||||||
|
messageWrapper.eq("chat_id", chat.getId());
|
||||||
|
|
||||||
|
if (lastReadMsgId != null && !lastReadMsgId.trim().isEmpty()) {
|
||||||
|
// 如果有最后读取的消息ID,查询该消息之后的消息
|
||||||
|
QueryWrapper<AiolChatMessage> lastReadMsgWrapper = new QueryWrapper<>();
|
||||||
|
lastReadMsgWrapper.eq("chat_id", chat.getId()).eq("id", lastReadMsgId);
|
||||||
|
AiolChatMessage lastReadMsg = aiolChatMessageMapper.selectOne(lastReadMsgWrapper);
|
||||||
|
|
||||||
|
if (lastReadMsg != null) {
|
||||||
|
// 查询创建时间晚于最后读取消息的消息数量
|
||||||
|
messageWrapper.gt("create_time", lastReadMsg.getCreateTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Long count = aiolChatMessageMapper.selectCount(messageWrapper);
|
||||||
|
unreadCount = count != null ? count.intValue() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
chatDTO.setUnreadCount(unreadCount);
|
||||||
|
|
||||||
|
// 2. 处理私聊类型的会话,获取对方用户信息
|
||||||
|
if (chat.getType() != null && chat.getType() == 0) {
|
||||||
|
// 私聊类型,需要获取对方用户信息
|
||||||
|
try {
|
||||||
|
// 查询该会话的成员,排除当前用户
|
||||||
|
QueryWrapper<AiolChatMember> otherMemberWrapper = new QueryWrapper<>();
|
||||||
|
otherMemberWrapper.eq("chat_id", chat.getId())
|
||||||
|
.ne("user_id", userId);
|
||||||
|
List<AiolChatMember> otherMembers = aiolChatMemberMapper.selectList(otherMemberWrapper);
|
||||||
|
|
||||||
|
if (!otherMembers.isEmpty()) {
|
||||||
|
// 获取对方用户ID
|
||||||
|
String otherUserId = otherMembers.get(0).getUserId();
|
||||||
|
|
||||||
|
// 查询对方用户信息
|
||||||
|
SysUser otherUser = sysUserMapper.selectById(otherUserId);
|
||||||
|
if (otherUser != null) {
|
||||||
|
// 替换会话的name和avatar为对方用户信息
|
||||||
|
chatDTO.setName(otherUser.getRealname());
|
||||||
|
chatDTO.setAvatar(otherUser.getAvatar());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("获取私聊对方用户信息失败: chatId={}, error={}", chat.getId(), e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("转换会话信息失败: chatId={}, error={}", chat.getId(), e.getMessage(), e);
|
||||||
|
// 即使转换失败,也返回基本的会话信息
|
||||||
|
chatDTO.setUnreadCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return chatDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户最后读取的消息ID
|
||||||
|
*
|
||||||
|
* @param chatId 会话ID
|
||||||
|
* @param messageId 消息ID
|
||||||
|
* @param request HTTP请求对象
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话-更新最后读取消息ID")
|
||||||
|
@Operation(summary = "更新最后读取消息ID", description = "更新当前用户在指定会话中的最后读取消息ID")
|
||||||
|
@PostMapping(value = "/{chatId}/update_last_read/{messageId}")
|
||||||
|
public Result<String> updateLastReadMsgId(@PathVariable(value = "chatId") String chatId,
|
||||||
|
@PathVariable(value = "messageId") String messageId,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
// 1. 从token获取当前用户信息
|
||||||
|
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
if (token == null || token.trim().isEmpty()) {
|
||||||
|
return Result.error("用户未登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error("用户信息不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 查询群聊成员是否存在
|
||||||
|
QueryWrapper<AiolChatMember> memberWrapper = new QueryWrapper<>();
|
||||||
|
memberWrapper.eq("chat_id", chatId).eq("user_id", sysUser.getId());
|
||||||
|
AiolChatMember chatMember = aiolChatMemberMapper.selectOne(memberWrapper);
|
||||||
|
|
||||||
|
if (chatMember == null) {
|
||||||
|
return Result.error("该用户不是群聊成员或会话不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 验证消息是否存在
|
||||||
|
AiolChatMessage message = aiolChatMessageMapper.selectById(messageId);
|
||||||
|
if (message == null || !message.getChatId().equals(chatId)) {
|
||||||
|
return Result.error("消息不存在或不属于该会话");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 更新最后读取的消息ID
|
||||||
|
chatMember.setLastReadMsgId(messageId);
|
||||||
|
boolean updated = aiolChatMemberMapper.updateById(chatMember) > 0;
|
||||||
|
|
||||||
|
if (!updated) {
|
||||||
|
return Result.error("更新失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("用户 {} 更新会话 {} 的最后读取消息ID为 {}", username, chatId, messageId);
|
||||||
|
return Result.OK("更新成功!");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("更新最后读取消息ID失败: chatId={}, messageId={}, error={}", chatId, messageId, e.getMessage(), e);
|
||||||
|
return Result.error("更新失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出群聊
|
||||||
|
*
|
||||||
|
* @param chatId 会话ID
|
||||||
|
* @param request HTTP请求对象
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话-退出群聊")
|
||||||
|
@Operation(summary = "退出群聊", description = "当前用户退出指定的群聊会话,从aiol_chat_member表中删除用户记录")
|
||||||
|
@DeleteMapping(value = "/{chatId}/exit")
|
||||||
|
public Result<String> exitChat(@PathVariable(value = "chatId") String chatId,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
// 1. 从token获取当前用户信息
|
||||||
|
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
if (token == null || token.trim().isEmpty()) {
|
||||||
|
return Result.error("用户未登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error("用户信息不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 验证会话是否存在
|
||||||
|
AiolChat chat = aiolChatService.getById(chatId);
|
||||||
|
if (chat == null) {
|
||||||
|
return Result.error("会话不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 查询用户是否为该会话的成员
|
||||||
|
QueryWrapper<AiolChatMember> memberWrapper = new QueryWrapper<>();
|
||||||
|
memberWrapper.eq("chat_id", chatId).eq("user_id", sysUser.getId());
|
||||||
|
AiolChatMember chatMember = aiolChatMemberMapper.selectOne(memberWrapper);
|
||||||
|
|
||||||
|
if (chatMember == null) {
|
||||||
|
return Result.error("您不是该会话的成员");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 检查是否为会话创建者(可选:不允许创建者退出)
|
||||||
|
if (chat.getCreateBy() != null && chat.getCreateBy().equals(sysUser.getId())) {
|
||||||
|
// 可选:如果创建者退出,需要转移创建者权限或不允许退出
|
||||||
|
log.warn("会话创建者尝试退出群聊: chatId={}, userId={}", chatId, sysUser.getId());
|
||||||
|
// 这里可以选择是否允许创建者退出,或者需要先转移权限
|
||||||
|
// return Result.error("群聊创建者不能直接退出,请先转移群主权限");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 从会话成员表中删除该用户
|
||||||
|
boolean deleted = aiolChatMemberMapper.deleteById(chatMember.getId()) > 0;
|
||||||
|
|
||||||
|
if (!deleted) {
|
||||||
|
return Result.error("退出群聊失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 检查会话是否还有其他成员,如果没有则删除会话(可选)
|
||||||
|
QueryWrapper<AiolChatMember> remainingMemberWrapper = new QueryWrapper<>();
|
||||||
|
remainingMemberWrapper.eq("chat_id", chatId);
|
||||||
|
long remainingMemberCount = aiolChatMemberMapper.selectCount(remainingMemberWrapper);
|
||||||
|
|
||||||
|
if (remainingMemberCount == 0) {
|
||||||
|
// 如果没有其他成员了,删除会话
|
||||||
|
aiolChatService.removeById(chatId);
|
||||||
|
log.info("会话 {} 无成员,已自动删除", chatId);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("用户 {} 成功退出群聊 {}", username, chatId);
|
||||||
|
return Result.OK("退出群聊成功!");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("退出群聊失败: chatId={}, error={}", chatId, e.getMessage(), e);
|
||||||
|
return Result.error("退出群聊失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,188 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolChatMember;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolChatMessage;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolChatMemberService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolChatMessageService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 会话用户
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-11
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="会话用户")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolChatMember")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolChatMemberController extends JeecgController<AiolChatMember, IAiolChatMemberService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolChatMemberService aiolChatMemberService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolChatMember
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "会话用户-分页列表查询")
|
||||||
|
@Operation(summary="会话用户-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolChatMember>> queryPageList(AiolChatMember aiolChatMember,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolChatMember> queryWrapper = QueryGenerator.initQueryWrapper(aiolChatMember, req.getParameterMap());
|
||||||
|
Page<AiolChatMember> page = new Page<AiolChatMember>(pageNo, pageSize);
|
||||||
|
IPage<AiolChatMember> pageList = aiolChatMemberService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolChatMember
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话用户-添加")
|
||||||
|
@Operation(summary="会话用户-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_chat_member:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolChatMember aiolChatMember) {
|
||||||
|
aiolChatMemberService.save(aiolChatMember);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolChatMember
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话用户-编辑")
|
||||||
|
@Operation(summary="会话用户-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_chat_member:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolChatMember aiolChatMember) {
|
||||||
|
aiolChatMemberService.updateById(aiolChatMember);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话用户-通过id删除")
|
||||||
|
@Operation(summary="会话用户-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_chat_member:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolChatMemberService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话用户-批量删除")
|
||||||
|
@Operation(summary="会话用户-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_chat_member:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolChatMemberService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "会话用户-通过id查询")
|
||||||
|
@Operation(summary="会话用户-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolChatMember> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolChatMember aiolChatMember = aiolChatMemberService.getById(id);
|
||||||
|
if(aiolChatMember==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolChatMember);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolChatMember
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_chat_member:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolChatMember aiolChatMember) {
|
||||||
|
return super.exportXls(request, aiolChatMember, AiolChatMember.class, "会话用户");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_chat_member:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolChatMember.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,251 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolChatMember;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolChatMessage;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolChatMemberService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolChatMessageService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 会话消息
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-11
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name = "会话消息")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolChatMessage")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolChatMessageController extends JeecgController<AiolChatMessage, IAiolChatMessageService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolChatMessageService aiolChatMessageService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISysBaseAPI sysBaseApi;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolChatMemberService aiolChatMemberService;
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolChatMessage
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
// @AutoLog(value = "会话消息-分页列表查询")
|
||||||
|
@Operation(summary = "会话消息-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolChatMessage>> queryPageList(AiolChatMessage aiolChatMessage,
|
||||||
|
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
|
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
QueryWrapper<AiolChatMessage> queryWrapper = QueryGenerator.initQueryWrapper(aiolChatMessage,
|
||||||
|
req.getParameterMap());
|
||||||
|
Page<AiolChatMessage> page = new Page<AiolChatMessage>(pageNo, pageSize);
|
||||||
|
IPage<AiolChatMessage> pageList = aiolChatMessageService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolChatMessage
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话消息-添加")
|
||||||
|
@Operation(summary = "会话消息-添加")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolChatMessage aiolChatMessage) {
|
||||||
|
aiolChatMessageService.save(aiolChatMessage);
|
||||||
|
|
||||||
|
return Result.OK(aiolChatMessage.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolChatMessage
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话消息-编辑")
|
||||||
|
@Operation(summary = "会话消息-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_chat_message:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = { RequestMethod.PUT, RequestMethod.POST })
|
||||||
|
public Result<String> edit(@RequestBody AiolChatMessage aiolChatMessage) {
|
||||||
|
aiolChatMessageService.updateById(aiolChatMessage);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话消息-通过id删除")
|
||||||
|
@Operation(summary = "会话消息-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_chat_message:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
aiolChatMessageService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话消息-批量删除")
|
||||||
|
@Operation(summary = "会话消息-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_chat_message:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||||
|
this.aiolChatMessageService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
// @AutoLog(value = "会话消息-通过id查询")
|
||||||
|
@Operation(summary = "会话消息-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolChatMessage> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
AiolChatMessage aiolChatMessage = aiolChatMessageService.getById(id);
|
||||||
|
if (aiolChatMessage == null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolChatMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolChatMessage
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_chat_message:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolChatMessage aiolChatMessage) {
|
||||||
|
return super.exportXls(request, aiolChatMessage, AiolChatMessage.class, "会话消息");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_chat_message:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolChatMessage.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送消息
|
||||||
|
* 前端传递 chat_id、content、message_type、file_url,sender_id 从token获取
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "会话用户-发送消息")
|
||||||
|
@Operation(summary = "会话用户-发送消息", description = "发送会话消息,sender_id从token获取")
|
||||||
|
@PostMapping(value = "/send")
|
||||||
|
public Result<String> sendMessage(@RequestBody Map<String, Object> body, HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
// 1. 从token获取当前用户
|
||||||
|
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
if (token == null || token.trim().isEmpty()) {
|
||||||
|
return Result.error("用户未登录");
|
||||||
|
}
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error("用户信息不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 解析参数
|
||||||
|
String chatId = body.get("chat_id") != null ? String.valueOf(body.get("chat_id")) : null;
|
||||||
|
String content = body.get("content") != null ? String.valueOf(body.get("content")) : null;
|
||||||
|
Integer messageType = body.get("message_type") != null
|
||||||
|
? Integer.parseInt(String.valueOf(body.get("message_type")))
|
||||||
|
: 0;
|
||||||
|
String fileUrl = body.get("file_url") != null ? String.valueOf(body.get("file_url")) : null;
|
||||||
|
|
||||||
|
if (chatId == null || chatId.trim().isEmpty()) {
|
||||||
|
return Result.error("chat_id不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 校验用户是否在该会话中
|
||||||
|
QueryWrapper<AiolChatMember> memberWrapper = new QueryWrapper<>();
|
||||||
|
memberWrapper.eq("chat_id", chatId).eq("user_id", sysUser.getId());
|
||||||
|
AiolChatMember chatMember = aiolChatMemberService.getOne(memberWrapper);
|
||||||
|
if (chatMember == null) {
|
||||||
|
return Result.error("您不是该会话的成员");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 组装消息并保存
|
||||||
|
AiolChatMessage message = new AiolChatMessage();
|
||||||
|
message.setChatId(chatId);
|
||||||
|
message.setSenderId(sysUser.getId());
|
||||||
|
message.setContent(content);
|
||||||
|
message.setMessageType(messageType);
|
||||||
|
message.setStatus(0);
|
||||||
|
message.setFileUrl(fileUrl);
|
||||||
|
|
||||||
|
aiolChatMessageService.save(message);
|
||||||
|
|
||||||
|
log.info("用户 {} 在会话 {} 发送消息成功, messageId={}", username, chatId, message.getId());
|
||||||
|
return Result.OK(message.getId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("发送消息失败: error={}", e.getMessage(), e);
|
||||||
|
return Result.error("发送消息失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,663 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolClass;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolClassStudent;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolUserInfo;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolClassService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolClassStudentService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolUserInfoService;
|
||||||
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
|
import org.jeecg.modules.system.mapper.SysUserMapper;
|
||||||
|
import org.jeecg.modules.system.service.ISysUserService;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolUserInfoMapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import java.util.Random;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 班级
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-04
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="班级")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolClass")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolClassController extends JeecgController<AiolClass, IAiolClassService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolClassService aiolClassService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolClassStudentService aiolClassStudentService;
|
||||||
|
@Autowired
|
||||||
|
private ISysBaseAPI sysBaseApi;
|
||||||
|
@Autowired
|
||||||
|
private SysUserMapper sysUserMapper;
|
||||||
|
@Autowired
|
||||||
|
private ISysUserService sysUserService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolUserInfoService aiolUserInfoService;
|
||||||
|
@Autowired
|
||||||
|
private AiolUserInfoMapper aiolUserInfoMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成8位不重复的邀请码
|
||||||
|
* @return 邀请码
|
||||||
|
*/
|
||||||
|
private String generateUniqueInviteCode() {
|
||||||
|
String inviteCode;
|
||||||
|
int maxAttempts = 100; // 最大尝试次数,防止无限循环
|
||||||
|
int attempts = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
inviteCode = generateRandomInviteCode();
|
||||||
|
attempts++;
|
||||||
|
|
||||||
|
if (attempts > maxAttempts) {
|
||||||
|
log.error("生成邀请码失败,已达到最大尝试次数: {}", maxAttempts);
|
||||||
|
throw new RuntimeException("生成邀请码失败,请稍后重试");
|
||||||
|
}
|
||||||
|
} while (isInviteCodeExists(inviteCode));
|
||||||
|
|
||||||
|
log.info("成功生成邀请码: {}, 尝试次数: {}", inviteCode, attempts);
|
||||||
|
return inviteCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成8位随机邀请码(数字+大写字母)
|
||||||
|
* @return 8位邀请码
|
||||||
|
*/
|
||||||
|
private String generateRandomInviteCode() {
|
||||||
|
String characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
Random random = new Random();
|
||||||
|
StringBuilder inviteCode = new StringBuilder(8);
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
inviteCode.append(characters.charAt(random.nextInt(characters.length())));
|
||||||
|
}
|
||||||
|
|
||||||
|
return inviteCode.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查邀请码是否已存在
|
||||||
|
* @param inviteCode 邀请码
|
||||||
|
* @return true-已存在,false-不存在
|
||||||
|
*/
|
||||||
|
private boolean isInviteCodeExists(String inviteCode) {
|
||||||
|
QueryWrapper<AiolClass> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("invite_code", inviteCode);
|
||||||
|
return aiolClassService.count(queryWrapper) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolClass
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "班级-分页列表查询")
|
||||||
|
@Operation(summary="班级-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolClass>> queryPageList(AiolClass aiolClass,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolClass> queryWrapper = QueryGenerator.initQueryWrapper(aiolClass, req.getParameterMap());
|
||||||
|
Page<AiolClass> page = new Page<AiolClass>(pageNo, pageSize);
|
||||||
|
IPage<AiolClass> pageList = aiolClassService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolClass
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "班级-添加")
|
||||||
|
@Operation(summary="班级-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_class:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolClass aiolClass) {
|
||||||
|
try {
|
||||||
|
// 自动生成8位不重复的邀请码
|
||||||
|
String inviteCode = generateUniqueInviteCode();
|
||||||
|
aiolClass.setInviteCode(inviteCode);
|
||||||
|
|
||||||
|
aiolClassService.save(aiolClass);
|
||||||
|
|
||||||
|
log.info("班级添加成功,班级名: {}, 邀请码: {}", aiolClass.getName(), inviteCode);
|
||||||
|
return Result.OK(aiolClass.getId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("添加班级失败: {}", e.getMessage(), e);
|
||||||
|
return Result.error("添加班级失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolClass
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "班级-编辑")
|
||||||
|
@Operation(summary="班级-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_class:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolClass aiolClass) {
|
||||||
|
aiolClassService.updateById(aiolClass);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "班级-通过id删除")
|
||||||
|
@Operation(summary="班级-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_class:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolClassService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "班级-批量删除")
|
||||||
|
@Operation(summary="班级-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_class:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolClassService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "班级-通过id查询")
|
||||||
|
@Operation(summary="班级-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolClass> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolClass aiolClass = aiolClassService.getById(id);
|
||||||
|
if(aiolClass==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolClass
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_class:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolClass aiolClass) {
|
||||||
|
return super.exportXls(request, aiolClass, AiolClass.class, "班级");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_class:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolClass.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量导入学生到班级
|
||||||
|
*
|
||||||
|
* @param classId 班级ID
|
||||||
|
* @param requestBody 请求体,包含ids字段
|
||||||
|
* @param request HTTP请求对象
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "班级学生-批量导入学生")
|
||||||
|
@Operation(summary = "批量导入学生到班级", description = "请求体为JSON格式,包含ids字段,ids为逗号分隔的学生ID字符串")
|
||||||
|
@PostMapping(value = "/{classId}/import_students")
|
||||||
|
public Result<Map<String, Object>> importStudentsToClass(
|
||||||
|
@PathVariable(value = "classId") String classId,
|
||||||
|
@RequestBody Map<String, Object> requestBody,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 获取当前登录用户信息
|
||||||
|
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error("用户未登录或登录已过期");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 从请求体中获取学生ID列表
|
||||||
|
String ids = (String) requestBody.get("ids");
|
||||||
|
if (ids == null || ids.trim().isEmpty()) {
|
||||||
|
return Result.error("ids字段不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 调用Service层处理批量导入逻辑
|
||||||
|
Map<String, Object> result = aiolClassService.importStudentsToClass(classId, ids, sysUser);
|
||||||
|
|
||||||
|
log.info("用户 {} 成功导入学生到班级,班级ID: {}, 导入结果: {}",
|
||||||
|
username, classId, result);
|
||||||
|
|
||||||
|
return Result.OK(result);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("批量导入学生到班级失败: classId={}, error={}", classId, e.getMessage(), e);
|
||||||
|
return Result.error("批量导入学生失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询班级学生列表
|
||||||
|
*
|
||||||
|
* @param classId 班级ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Operation(summary = "查询班级学生列表", description = "根据班级ID查询该班级下的所有学生")
|
||||||
|
@GetMapping(value = "/{classId}/student_list")
|
||||||
|
public Result<List<Map<String, Object>>> queryClassStudentList(@PathVariable("classId") String classId) {
|
||||||
|
try {
|
||||||
|
// 1. 查询班级学生关联记录
|
||||||
|
QueryWrapper<AiolClassStudent> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("class_id", classId);
|
||||||
|
|
||||||
|
List<AiolClassStudent> classStudents = aiolClassStudentService.list(queryWrapper);
|
||||||
|
|
||||||
|
// 2. 联查用户信息,构建包含学生信息的列表
|
||||||
|
List<Map<String, Object>> result = new ArrayList<>();
|
||||||
|
for (AiolClassStudent classStudent : classStudents) {
|
||||||
|
Map<String, Object> studentInfo = new HashMap<>();
|
||||||
|
// 复制班级学生关联信息
|
||||||
|
studentInfo.put("id", classStudent.getId());
|
||||||
|
studentInfo.put("classId", classStudent.getClassId());
|
||||||
|
studentInfo.put("studentId", classStudent.getStudentId());
|
||||||
|
studentInfo.put("createTime", classStudent.getCreateTime());
|
||||||
|
studentInfo.put("createBy", classStudent.getCreateBy());
|
||||||
|
studentInfo.put("updateTime", classStudent.getUpdateTime());
|
||||||
|
studentInfo.put("updateBy", classStudent.getUpdateBy());
|
||||||
|
|
||||||
|
// 查询学生用户信息
|
||||||
|
SysUser sysUser = sysUserMapper.selectById(classStudent.getStudentId());
|
||||||
|
if (sysUser != null) {
|
||||||
|
studentInfo.put("realname", sysUser.getRealname());
|
||||||
|
studentInfo.put("userAvatar", sysUser.getAvatar());
|
||||||
|
studentInfo.put("username", sysUser.getUsername());
|
||||||
|
studentInfo.put("phone", sysUser.getPhone());
|
||||||
|
studentInfo.put("email", sysUser.getEmail());
|
||||||
|
studentInfo.put("status", sysUser.getStatus());
|
||||||
|
studentInfo.put("sex", sysUser.getSex());
|
||||||
|
studentInfo.put("birthday", sysUser.getBirthday());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询学生扩展信息(aiol_user_info)
|
||||||
|
QueryWrapper<AiolUserInfo> userInfoWrapper = new QueryWrapper<>();
|
||||||
|
userInfoWrapper.eq("user_id", classStudent.getStudentId());
|
||||||
|
AiolUserInfo userInfo = aiolUserInfoMapper.selectOne(userInfoWrapper);
|
||||||
|
if (userInfo != null) {
|
||||||
|
studentInfo.put("major", userInfo.getMajor());
|
||||||
|
studentInfo.put("college", userInfo.getCollege());
|
||||||
|
studentInfo.put("education", userInfo.getEducation());
|
||||||
|
studentInfo.put("title", userInfo.getTitle());
|
||||||
|
} else {
|
||||||
|
// 如果没有扩展信息,设置默认值
|
||||||
|
studentInfo.put("major", "");
|
||||||
|
studentInfo.put("college", "");
|
||||||
|
studentInfo.put("education", "");
|
||||||
|
studentInfo.put("title", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
result.add(studentInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.OK(result);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询班级学生列表失败: classId={}, error={}", classId, e.getMessage(), e);
|
||||||
|
return Result.error("查询班级学生列表失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从班级中移除学生
|
||||||
|
*
|
||||||
|
* @param classId 班级ID
|
||||||
|
* @param studentId 学生ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "班级学生-移除学生")
|
||||||
|
@Operation(summary = "从班级中移除学生", description = "将指定学生从班级中移除")
|
||||||
|
@DeleteMapping(value = "/{classId}/remove_student/{studentId}")
|
||||||
|
public Result<String> removeStudentFromClass(
|
||||||
|
@PathVariable("classId") String classId,
|
||||||
|
@PathVariable("studentId") String studentId) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
QueryWrapper<AiolClassStudent> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("class_id", classId)
|
||||||
|
.eq("student_id", studentId);
|
||||||
|
|
||||||
|
boolean removed = aiolClassStudentService.remove(queryWrapper);
|
||||||
|
|
||||||
|
if (removed) {
|
||||||
|
log.info("成功从班级移除学生,班级ID: {}, 学生ID: {}", classId, studentId);
|
||||||
|
return Result.OK("学生移除成功!");
|
||||||
|
} else {
|
||||||
|
return Result.error("未找到该学生在班级中的记录");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("从班级移除学生失败: classId={}, studentId={}, error={}",
|
||||||
|
classId, studentId, e.getMessage(), e);
|
||||||
|
return Result.error("移除学生失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入学生到班级(通过Excel)
|
||||||
|
*
|
||||||
|
* @param classId 班级ID
|
||||||
|
* @param request HTTP请求对象
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "班级学生-导入学生")
|
||||||
|
@Operation(summary = "导入学生到班级", description = "通过Excel文件导入学生到指定班级,如果学生不存在则自动创建")
|
||||||
|
@PostMapping(value = "/{classId}/import_students_excel")
|
||||||
|
public Result<Map<String, Object>> importStudentsToClassByExcel(
|
||||||
|
@PathVariable("classId") String classId,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 获取当前登录用户信息
|
||||||
|
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error("用户未登录或登录已过期");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 模拟Excel数据(暂时不实现Excel解析,直接使用模拟数据)
|
||||||
|
List<Map<String, String>> studentDataList = new ArrayList<>();
|
||||||
|
|
||||||
|
// 模拟数据示例
|
||||||
|
Map<String, String> student1 = new HashMap<>();
|
||||||
|
student1.put("studentNumber", "2024001");
|
||||||
|
student1.put("realName", "张三");
|
||||||
|
studentDataList.add(student1);
|
||||||
|
|
||||||
|
Map<String, String> student2 = new HashMap<>();
|
||||||
|
student2.put("studentNumber", "2024002");
|
||||||
|
student2.put("realName", "李四");
|
||||||
|
studentDataList.add(student2);
|
||||||
|
|
||||||
|
// 3. 处理学生数据
|
||||||
|
int successCount = 0;
|
||||||
|
int failCount = 0;
|
||||||
|
List<String> errorMessages = new ArrayList<>();
|
||||||
|
List<String> createdStudentIds = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Map<String, String> studentData : studentDataList) {
|
||||||
|
try {
|
||||||
|
String studentNumber = studentData.get("studentNumber");
|
||||||
|
String realName = studentData.get("realName");
|
||||||
|
|
||||||
|
// 检查学生是否已存在
|
||||||
|
SysUser existingStudent = sysUserService.getUserByName(studentNumber);
|
||||||
|
String studentId;
|
||||||
|
|
||||||
|
if (existingStudent != null) {
|
||||||
|
// 学生已存在,直接使用现有学生ID
|
||||||
|
studentId = existingStudent.getId();
|
||||||
|
log.info("学生已存在,使用现有学生: 学号={}, 姓名={}", studentNumber, realName);
|
||||||
|
} else {
|
||||||
|
// 学生不存在,创建新学生
|
||||||
|
SysUser newStudent = sysUserService.createStudentUser(studentNumber, realName, null);
|
||||||
|
studentId = newStudent.getId();
|
||||||
|
createdStudentIds.add(studentId);
|
||||||
|
log.info("创建新学生: 学号={}, 姓名={}, ID={}", studentNumber, realName, studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查学生是否已在班级中
|
||||||
|
QueryWrapper<AiolClassStudent> checkWrapper = new QueryWrapper<>();
|
||||||
|
checkWrapper.eq("class_id", classId)
|
||||||
|
.eq("student_id", studentId);
|
||||||
|
|
||||||
|
AiolClassStudent existingRelation = aiolClassStudentService.getOne(checkWrapper);
|
||||||
|
if (existingRelation != null) {
|
||||||
|
log.info("学生已在班级中: 学号={}, 班级ID={}", studentNumber, classId);
|
||||||
|
continue; // 跳过已存在的学生
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建班级学生关联
|
||||||
|
AiolClassStudent classStudent = new AiolClassStudent();
|
||||||
|
classStudent.setClassId(classId);
|
||||||
|
classStudent.setStudentId(studentId);
|
||||||
|
classStudent.setCreateBy(sysUser.getUsername());
|
||||||
|
classStudent.setCreateTime(new Date());
|
||||||
|
|
||||||
|
boolean saved = aiolClassStudentService.save(classStudent);
|
||||||
|
if (saved) {
|
||||||
|
successCount++;
|
||||||
|
log.info("成功将学生添加到班级: 学号={}, 班级ID={}", studentNumber, classId);
|
||||||
|
} else {
|
||||||
|
failCount++;
|
||||||
|
errorMessages.add("保存学生 " + studentNumber + " 到班级失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
failCount++;
|
||||||
|
String errorMsg = "处理学生 " + studentData.get("studentNumber") + " 失败: " + e.getMessage();
|
||||||
|
errorMessages.add(errorMsg);
|
||||||
|
log.error(errorMsg, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 构建返回结果
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
result.put("totalCount", studentDataList.size());
|
||||||
|
result.put("successCount", successCount);
|
||||||
|
result.put("failCount", failCount);
|
||||||
|
result.put("createdStudentCount", createdStudentIds.size());
|
||||||
|
result.put("errorMessages", errorMessages);
|
||||||
|
result.put("createdStudentIds", createdStudentIds);
|
||||||
|
|
||||||
|
log.info("导入学生完成: 班级ID={}, 总数={}, 成功={}, 失败={}, 新创建学生={}",
|
||||||
|
classId, studentDataList.size(), successCount, failCount, createdStudentIds.size());
|
||||||
|
|
||||||
|
return Result.OK(result);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("导入学生到班级失败: classId={}, error={}", classId, e.getMessage(), e);
|
||||||
|
return Result.error("导入学生失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询班级列表
|
||||||
|
*
|
||||||
|
* @param courseId 可选课程ID;不传时查询当前登录用户创建的全部班级
|
||||||
|
* @param request HTTP请求对象,用于获取登录态
|
||||||
|
* @return 班级列表
|
||||||
|
*/
|
||||||
|
@Operation(summary = "查询班级列表", description = "参数courseId可选;不传则查当前登录用户创建的全部班级,传则查对应课程id的班级")
|
||||||
|
@GetMapping(value = "/query_list")
|
||||||
|
public Result<List<AiolClass>> queryClassList(
|
||||||
|
@RequestParam(name = "courseId", required = false) String courseId,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
QueryWrapper<AiolClass> queryWrapper = new QueryWrapper<>();
|
||||||
|
|
||||||
|
if (courseId == null || courseId.trim().isEmpty()) {
|
||||||
|
// 未传courseId,查询当前登录用户创建的班级
|
||||||
|
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error("用户未登录或登录已过期");
|
||||||
|
}
|
||||||
|
queryWrapper.eq("create_by", sysUser.getUsername());
|
||||||
|
} else {
|
||||||
|
// 传了courseId,按课程查询
|
||||||
|
queryWrapper.eq("course_id", courseId);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<AiolClass> list = aiolClassService.list(queryWrapper);
|
||||||
|
return Result.OK(list);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询班级列表失败: courseId={}, error={}", courseId, e.getMessage(), e);
|
||||||
|
return Result.error("查询班级列表失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新建学生并添加至班级
|
||||||
|
*
|
||||||
|
* 前端传参:realName(姓名)、studentNumber(学号)、password(登录密码,可选)、school(所属学校)、classId(所属班级ID,支持多个,用逗号分割)
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "班级学生-新建学生并添加至班级")
|
||||||
|
@Operation(summary = "新建学生并添加至班级", description = "创建sysUser,保存aiol_user_info的学校信息,并写入aiol_class_student。支持多个班级ID,用逗号分割")
|
||||||
|
@PostMapping(value = "/create_and_add_student")
|
||||||
|
public Result<Map<String, Object>> createStudentAndAddToClass(@RequestBody Map<String, Object> body,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
String realName = (String) body.get("realName");
|
||||||
|
String studentNumber = (String) body.get("studentNumber");
|
||||||
|
String password = (String) body.get("password");
|
||||||
|
String school = (String) body.get("school");
|
||||||
|
String classId = (String) body.get("classId");
|
||||||
|
|
||||||
|
if (realName == null || realName.trim().isEmpty()) {
|
||||||
|
return Result.error("姓名不能为空");
|
||||||
|
}
|
||||||
|
if (studentNumber == null || studentNumber.trim().isEmpty()) {
|
||||||
|
return Result.error("学号不能为空");
|
||||||
|
}
|
||||||
|
if (classId == null || classId.trim().isEmpty()) {
|
||||||
|
return Result.error("班级ID不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前登录用户
|
||||||
|
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error("用户未登录或登录已过期");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1) 创建学生用户(sys_user)
|
||||||
|
SysUser created = sysUserService.createStudentUser(studentNumber, realName, password);
|
||||||
|
|
||||||
|
// 2) 保存学校至 aiol_user_info(使用 college 字段存储学校)
|
||||||
|
AiolUserInfo userInfo = new AiolUserInfo();
|
||||||
|
userInfo.setUserId(created.getId());
|
||||||
|
userInfo.setCollege(school);
|
||||||
|
userInfo.setCreateBy(sysUser.getUsername());
|
||||||
|
userInfo.setCreateTime(new Date());
|
||||||
|
aiolUserInfoService.save(userInfo);
|
||||||
|
|
||||||
|
// 3) 写入班级关系 aiol_class_student
|
||||||
|
// 支持多个班级ID,用逗号分割
|
||||||
|
String[] classIds = classId.split(",");
|
||||||
|
int successCount = 0;
|
||||||
|
int skipCount = 0;
|
||||||
|
|
||||||
|
for (String singleClassId : classIds) {
|
||||||
|
if (singleClassId == null || singleClassId.trim().isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
singleClassId = singleClassId.trim();
|
||||||
|
|
||||||
|
// 检查是否已存在关系,避免重复
|
||||||
|
QueryWrapper<AiolClassStudent> checkWrapper = new QueryWrapper<>();
|
||||||
|
checkWrapper.eq("class_id", singleClassId).eq("student_id", created.getId());
|
||||||
|
AiolClassStudent exist = aiolClassStudentService.getOne(checkWrapper);
|
||||||
|
|
||||||
|
if (exist == null) {
|
||||||
|
AiolClassStudent relation = new AiolClassStudent();
|
||||||
|
relation.setClassId(singleClassId);
|
||||||
|
relation.setStudentId(created.getId());
|
||||||
|
relation.setCreateBy(sysUser.getUsername());
|
||||||
|
relation.setCreateTime(new Date());
|
||||||
|
boolean saved = aiolClassStudentService.save(relation);
|
||||||
|
if (saved) {
|
||||||
|
successCount++;
|
||||||
|
log.info("成功将学生 {} 添加到班级 {}", created.getUsername(), singleClassId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
skipCount++;
|
||||||
|
log.info("学生 {} 已在班级 {} 中,跳过", created.getUsername(), singleClassId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> resp = new HashMap<>();
|
||||||
|
resp.put("userId", created.getId());
|
||||||
|
resp.put("username", created.getUsername());
|
||||||
|
resp.put("classId", classId);
|
||||||
|
resp.put("school", school);
|
||||||
|
resp.put("totalClassCount", classIds.length);
|
||||||
|
resp.put("successCount", successCount);
|
||||||
|
resp.put("skipCount", skipCount);
|
||||||
|
|
||||||
|
return Result.OK(resp);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("新建学生并添加至班级失败: body={}, error={}", body, e.getMessage(), e);
|
||||||
|
return Result.error("新建学生并添加至班级失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,321 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolClassStudent;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolClassStudentService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 班级学生
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-04
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="班级学生")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolClassStudent")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolClassStudentController extends JeecgController<AiolClassStudent, IAiolClassStudentService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolClassStudentService aiolClassStudentService;
|
||||||
|
@Autowired
|
||||||
|
private ISysBaseAPI sysBaseApi;
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolClassStudent
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "班级学生-分页列表查询")
|
||||||
|
@Operation(summary="班级学生-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolClassStudent>> queryPageList(AiolClassStudent aiolClassStudent,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolClassStudent> queryWrapper = QueryGenerator.initQueryWrapper(aiolClassStudent, req.getParameterMap());
|
||||||
|
Page<AiolClassStudent> page = new Page<AiolClassStudent>(pageNo, pageSize);
|
||||||
|
IPage<AiolClassStudent> pageList = aiolClassStudentService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolClassStudent
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "班级学生-添加")
|
||||||
|
@Operation(summary="班级学生-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_class_student:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolClassStudent aiolClassStudent) {
|
||||||
|
aiolClassStudentService.save(aiolClassStudent);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolClassStudent
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "班级学生-编辑")
|
||||||
|
@Operation(summary="班级学生-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_class_student:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolClassStudent aiolClassStudent) {
|
||||||
|
aiolClassStudentService.updateById(aiolClassStudent);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "班级学生-通过id删除")
|
||||||
|
@Operation(summary="班级学生-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_class_student:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolClassStudentService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "班级学生-批量删除")
|
||||||
|
@Operation(summary="班级学生-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_class_student:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolClassStudentService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "班级学生-通过id查询")
|
||||||
|
@Operation(summary="班级学生-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolClassStudent> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolClassStudent aiolClassStudent = aiolClassStudentService.getById(id);
|
||||||
|
if(aiolClassStudent==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolClassStudent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolClassStudent
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_class_student:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolClassStudent aiolClassStudent) {
|
||||||
|
return super.exportXls(request, aiolClassStudent, AiolClassStudent.class, "班级学生");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_class_student:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolClassStudent.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量调班
|
||||||
|
*
|
||||||
|
* @param requestBody 包含学生ID列表、原班级ID和新班级ID
|
||||||
|
* @param request HTTP请求对象
|
||||||
|
* @return 调班结果
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "班级学生-批量调班")
|
||||||
|
@Operation(summary = "批量调班", description = "将指定学生从原班级调转到新班级")
|
||||||
|
@PostMapping(value = "/batchTransfer")
|
||||||
|
public Result<Map<String, Object>> batchTransfer(@RequestBody Map<String, Object> requestBody,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
// 1. 获取当前登录用户信息
|
||||||
|
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error("用户未登录或登录已过期");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 从请求体中获取参数
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<String> studentIds = (List<String>) requestBody.get("studentIds");
|
||||||
|
String originalClassId = (String) requestBody.get("originalClassId");
|
||||||
|
String newClassId = (String) requestBody.get("newClassId");
|
||||||
|
|
||||||
|
// 3. 参数验证
|
||||||
|
if (studentIds == null || studentIds.isEmpty()) {
|
||||||
|
return Result.error("学生ID列表不能为空");
|
||||||
|
}
|
||||||
|
if (originalClassId == null || originalClassId.trim().isEmpty()) {
|
||||||
|
return Result.error("原班级ID不能为空");
|
||||||
|
}
|
||||||
|
if (newClassId == null || newClassId.trim().isEmpty()) {
|
||||||
|
return Result.error("新班级ID不能为空");
|
||||||
|
}
|
||||||
|
if (originalClassId.equals(newClassId)) {
|
||||||
|
return Result.error("原班级和新班级不能相同");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 执行批量调班操作
|
||||||
|
Map<String, Object> result = performBatchTransfer(studentIds, originalClassId, newClassId, sysUser);
|
||||||
|
|
||||||
|
log.info("用户 {} 执行批量调班操作完成,结果: {}", username, result);
|
||||||
|
return Result.OK(result);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("批量调班失败: {}", e.getMessage(), e);
|
||||||
|
return Result.error("批量调班失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行批量调班操作
|
||||||
|
*
|
||||||
|
* @param studentIds 学生ID列表
|
||||||
|
* @param originalClassId 原班级ID
|
||||||
|
* @param newClassId 新班级ID
|
||||||
|
* @param sysUser 当前登录用户
|
||||||
|
* @return 调班结果统计
|
||||||
|
*/
|
||||||
|
private Map<String, Object> performBatchTransfer(List<String> studentIds, String originalClassId,
|
||||||
|
String newClassId, LoginUser sysUser) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
int successCount = 0;
|
||||||
|
int failCount = 0;
|
||||||
|
int notFoundCount = 0;
|
||||||
|
int alreadyInNewClassCount = 0;
|
||||||
|
List<String> successStudentIds = new ArrayList<>();
|
||||||
|
List<String> failStudentIds = new ArrayList<>();
|
||||||
|
List<String> notFoundStudentIds = new ArrayList<>();
|
||||||
|
List<String> alreadyInNewClassStudentIds = new ArrayList<>();
|
||||||
|
|
||||||
|
for (String studentId : studentIds) {
|
||||||
|
try {
|
||||||
|
// 1. 查找原班级中的学生记录
|
||||||
|
QueryWrapper<AiolClassStudent> originalQuery = new QueryWrapper<>();
|
||||||
|
originalQuery.eq("class_id", originalClassId)
|
||||||
|
.eq("student_id", studentId);
|
||||||
|
|
||||||
|
AiolClassStudent originalRecord = aiolClassStudentService.getOne(originalQuery);
|
||||||
|
|
||||||
|
if (originalRecord == null) {
|
||||||
|
notFoundCount++;
|
||||||
|
notFoundStudentIds.add(studentId);
|
||||||
|
log.warn("学生 {} 在原班级 {} 中不存在", studentId, originalClassId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 检查学生是否已在新班级中
|
||||||
|
QueryWrapper<AiolClassStudent> newClassQuery = new QueryWrapper<>();
|
||||||
|
newClassQuery.eq("class_id", newClassId)
|
||||||
|
.eq("student_id", studentId);
|
||||||
|
|
||||||
|
AiolClassStudent existingInNewClass = aiolClassStudentService.getOne(newClassQuery);
|
||||||
|
if (existingInNewClass != null) {
|
||||||
|
alreadyInNewClassCount++;
|
||||||
|
alreadyInNewClassStudentIds.add(studentId);
|
||||||
|
log.warn("学生 {} 已在新班级 {} 中", studentId, newClassId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 执行调班操作:更新原记录的班级ID
|
||||||
|
originalRecord.setClassId(newClassId);
|
||||||
|
originalRecord.setUpdateBy(sysUser.getUsername());
|
||||||
|
originalRecord.setUpdateTime(new Date());
|
||||||
|
|
||||||
|
boolean updateResult = aiolClassStudentService.updateById(originalRecord);
|
||||||
|
|
||||||
|
if (updateResult) {
|
||||||
|
successCount++;
|
||||||
|
successStudentIds.add(studentId);
|
||||||
|
log.info("成功将学生 {} 从班级 {} 调转到班级 {}", studentId, originalClassId, newClassId);
|
||||||
|
} else {
|
||||||
|
failCount++;
|
||||||
|
failStudentIds.add(studentId);
|
||||||
|
log.error("更新学生 {} 的班级信息失败", studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
failCount++;
|
||||||
|
failStudentIds.add(studentId);
|
||||||
|
log.error("处理学生 {} 调班时发生异常: {}", studentId, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 构建返回结果
|
||||||
|
result.put("totalCount", studentIds.size());
|
||||||
|
result.put("successCount", successCount);
|
||||||
|
result.put("failCount", failCount);
|
||||||
|
result.put("notFoundCount", notFoundCount);
|
||||||
|
result.put("alreadyInNewClassCount", alreadyInNewClassCount);
|
||||||
|
result.put("originalClassId", originalClassId);
|
||||||
|
result.put("newClassId", newClassId);
|
||||||
|
result.put("successStudentIds", successStudentIds);
|
||||||
|
result.put("failStudentIds", failStudentIds);
|
||||||
|
result.put("notFoundStudentIds", notFoundStudentIds);
|
||||||
|
result.put("alreadyInNewClassStudentIds", alreadyInNewClassStudentIds);
|
||||||
|
|
||||||
|
log.info("批量调班操作完成 - 总数: {}, 成功: {}, 失败: {}, 未找到: {}, 已在新班级: {}",
|
||||||
|
studentIds.size(), successCount, failCount, notFoundCount, alreadyInNewClassCount);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,564 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
|
import org.jeecg.config.shiro.IgnoreAuth;
|
||||||
|
import org.jeecg.modules.aiol.dto.CommentWithUserInfo;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolComment;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolCommentService;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolCourse;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolDiscussion;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolCourseService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolDiscussionService;
|
||||||
|
import org.jeecg.modules.aiol.utils.MessageNotificationUtil;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 评论
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name = "评论")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolComment")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolCommentController extends JeecgController<AiolComment, IAiolCommentService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolCommentService aiolCommentService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MessageNotificationUtil messageNotificationUtil;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolCourseService aiolCourseService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolDiscussionService aiolDiscussionService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolComment
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
// @AutoLog(value = "评论-分页列表查询")
|
||||||
|
@Operation(summary = "评论-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolComment>> queryPageList(AiolComment aiolComment,
|
||||||
|
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
|
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
QueryWrapper<AiolComment> queryWrapper = QueryGenerator.initQueryWrapper(aiolComment, req.getParameterMap());
|
||||||
|
Page<AiolComment> page = new Page<AiolComment>(pageNo, pageSize);
|
||||||
|
IPage<AiolComment> pageList = aiolCommentService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolComment
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "评论-添加")
|
||||||
|
@Operation(summary = "评论-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_comment:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolComment aiolComment, HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
// 1. 获取当前登录用户信息
|
||||||
|
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error("用户未登录或登录已过期");
|
||||||
|
}
|
||||||
|
|
||||||
|
aiolComment.setUserId(sysUser.getId()); // 用户ID
|
||||||
|
aiolComment.setLikeCount(0);
|
||||||
|
|
||||||
|
// 2. 保存评论
|
||||||
|
aiolCommentService.save(aiolComment);
|
||||||
|
|
||||||
|
// 3. 发送评论通知
|
||||||
|
sendCommentNotification(aiolComment, sysUser);
|
||||||
|
|
||||||
|
log.info("用户 {} 成功添加评论,评论ID: {}, 目标类型: {}, 目标ID: {}",
|
||||||
|
username, aiolComment.getId(), aiolComment.getTargetType(), aiolComment.getTargetId());
|
||||||
|
|
||||||
|
return Result.OK(aiolComment.getId());
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("添加评论失败: targetType={}, targetId={}, error={}",
|
||||||
|
aiolComment.getTargetType(), aiolComment.getTargetId(), e.getMessage(), e);
|
||||||
|
return Result.error("添加评论失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolComment
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "评论-编辑")
|
||||||
|
@Operation(summary = "评论-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_comment:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = { RequestMethod.PUT, RequestMethod.POST })
|
||||||
|
public Result<String> edit(@RequestBody AiolComment aiolComment) {
|
||||||
|
aiolCommentService.updateById(aiolComment);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "评论-通过id删除")
|
||||||
|
@Operation(summary = "评论-通过id删除")
|
||||||
|
// @RequiresPermissions("aiol:aiol_comment:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
aiolCommentService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "评论-批量删除")
|
||||||
|
@Operation(summary = "评论-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_comment:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||||
|
this.aiolCommentService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
// @AutoLog(value = "评论-通过id查询")
|
||||||
|
@Operation(summary = "评论-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<AiolComment> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
AiolComment aiolComment = aiolCommentService.getById(id);
|
||||||
|
if (aiolComment == null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolComment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolComment
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_comment:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolComment aiolComment) {
|
||||||
|
return super.exportXls(request, aiolComment, AiolComment.class, "评论");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_comment:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolComment.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/course/{courseId}/list")
|
||||||
|
@Operation(summary = "查询课程评论列表", description = "根据课程ID查询课程评论列表,包含用户信息和所有子评论(支持多层嵌套,所有子评论都放在顶级评论的replies中)")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<CommentWithUserInfo>> queryCourseCommentList(@PathVariable("courseId") String courseId) {
|
||||||
|
try {
|
||||||
|
// 1. 查询课程的一级评论(target_type=course, target_id=courseId)
|
||||||
|
List<CommentWithUserInfo> parentComments = aiolCommentService.getCommentList("course", courseId);
|
||||||
|
|
||||||
|
// 2. 为每个一级评论查询其所有子评论(递归查询所有层级)
|
||||||
|
for (CommentWithUserInfo parentComment : parentComments) {
|
||||||
|
List<CommentWithUserInfo> allReplies = getAllRepliesRecursively(parentComment.getId());
|
||||||
|
parentComment.setReplies(allReplies);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("查询课程评论列表成功: courseId={}, 一级评论数量={}", courseId, parentComments.size());
|
||||||
|
return Result.OK(parentComments);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询课程评论列表失败: courseId={}, error={}", courseId, e.getMessage(), e);
|
||||||
|
return Result.error("查询课程评论列表失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/discussion/{discussionId}/list")
|
||||||
|
@Operation(summary = "查询讨论评论列表", description = "根据讨论ID查询讨论评论列表,包含用户信息和所有子评论(支持多层嵌套,所有子评论都放在顶级评论的replies中)")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<CommentWithUserInfo>> queryDiscussionCommentList(@PathVariable("discussionId") String discussionId) {
|
||||||
|
try {
|
||||||
|
// 1. 查询讨论的一级评论(target_type=discussion, target_id=discussionId)
|
||||||
|
List<CommentWithUserInfo> parentComments = aiolCommentService.getCommentList("discussion", discussionId);
|
||||||
|
|
||||||
|
// 2. 为每个一级评论查询其所有子评论(递归查询所有层级)
|
||||||
|
for (CommentWithUserInfo parentComment : parentComments) {
|
||||||
|
List<CommentWithUserInfo> allReplies = getAllRepliesRecursively(parentComment.getId());
|
||||||
|
parentComment.setReplies(allReplies);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("查询讨论评论列表成功: discussionId={}, 一级评论数量={}", discussionId, parentComments.size());
|
||||||
|
return Result.OK(parentComments);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询讨论评论列表失败: discussionId={}, error={}", discussionId, e.getMessage(), e);
|
||||||
|
return Result.error("查询讨论评论列表失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归查询评论的所有子评论
|
||||||
|
* @param commentId 评论ID
|
||||||
|
* @return 所有子评论列表
|
||||||
|
*/
|
||||||
|
private List<CommentWithUserInfo> getAllRepliesRecursively(String commentId) {
|
||||||
|
List<CommentWithUserInfo> allReplies = new ArrayList<>();
|
||||||
|
|
||||||
|
// 查询直接子评论(target_type=comment, target_id=commentId)
|
||||||
|
List<CommentWithUserInfo> directReplies = aiolCommentService.getCommentList("comment", commentId);
|
||||||
|
|
||||||
|
for (CommentWithUserInfo reply : directReplies) {
|
||||||
|
// 将当前回复添加到总列表中
|
||||||
|
allReplies.add(reply);
|
||||||
|
|
||||||
|
// 递归查询当前回复的子评论
|
||||||
|
List<CommentWithUserInfo> subReplies = getAllRepliesRecursively(reply.getId());
|
||||||
|
allReplies.addAll(subReplies);
|
||||||
|
}
|
||||||
|
|
||||||
|
return allReplies;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @GetMapping("/activity/{activityId}/list")
|
||||||
|
// @Operation(summary = "查询活动评论列表", description = "根据活动ID查询活动评论列表,包含用户信息")
|
||||||
|
// public Result<List<CommentWithUserInfo>>
|
||||||
|
// queryActivityCommentList(@PathVariable("activityId") String activityId) {
|
||||||
|
// List<CommentWithUserInfo> list = commentBizService.getCommentList("activity",
|
||||||
|
// activityId);
|
||||||
|
// return Result.OK(list);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @GetMapping("/{targetType}/{targetId}/list")
|
||||||
|
// @Operation(summary = "查询通用评论列表", description = "根据目标类型和目标ID查询评论列表,包含用户信息")
|
||||||
|
// public Result<List<CommentWithUserInfo>> queryCommentList(
|
||||||
|
// @PathVariable("targetType") String targetType,
|
||||||
|
// @PathVariable("targetId") String targetId) {
|
||||||
|
// List<CommentWithUserInfo> list = commentBizService.getCommentList(targetType,
|
||||||
|
// targetId);
|
||||||
|
// return Result.OK(list);
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISysBaseAPI sysBaseApi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增课程评论
|
||||||
|
*
|
||||||
|
* @param courseId 课程ID
|
||||||
|
* @param aiolComment 评论信息
|
||||||
|
* @param request HTTP请求对象
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
// @AutoLog(value = "评论-新增课程评论")
|
||||||
|
// @Operation(summary = "新增课程评论", description = "新增课程评论,target_type默认为course,user_id通过token自动获取")
|
||||||
|
// @PostMapping(value = "/course/{courseId}/add")
|
||||||
|
// public Result<String> addCourseComment(
|
||||||
|
// @PathVariable("courseId") String courseId,
|
||||||
|
// @RequestBody AiolComment aiolComment,
|
||||||
|
// HttpServletRequest request) {
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// // 1. 获取当前登录用户信息
|
||||||
|
// String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
// String username = JwtUtil.getUsername(token);
|
||||||
|
// LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
|
||||||
|
// if (sysUser == null) {
|
||||||
|
// return Result.error("用户未登录或登录已过期");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 2. 设置评论基本信息
|
||||||
|
// aiolComment.setTargetType("course");
|
||||||
|
// aiolComment.setTargetId(courseId); // 课程ID
|
||||||
|
// aiolComment.setUserId(sysUser.getId()); // 用户ID
|
||||||
|
|
||||||
|
// // 3. 保存评论
|
||||||
|
// aiolCommentService.save(aiolComment);
|
||||||
|
|
||||||
|
// log.info("用户 {} 成功添加课程评论,课程ID: {}, 评论ID: {}",
|
||||||
|
// username, courseId, aiolComment.getId());
|
||||||
|
|
||||||
|
// return Result.OK("评论添加成功!");
|
||||||
|
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// log.error("添加课程评论失败: courseId={}, error={}", courseId, e.getMessage(), e);
|
||||||
|
// return Result.error("评论添加失败: " + e.getMessage());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
@AutoLog(value = "评论-点赞")
|
||||||
|
@Operation(summary = "点赞评论", description = "为指定评论点赞,增加like_count字段值并发送通知")
|
||||||
|
@GetMapping(value = "/like/{commentId}")
|
||||||
|
public Result<String> likeComment(@PathVariable("commentId") String commentId, HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
// 1. 获取当前登录用户信息
|
||||||
|
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error("用户未登录或登录已过期");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 查询评论是否存在
|
||||||
|
AiolComment comment = aiolCommentService.getById(commentId);
|
||||||
|
if (comment == null) {
|
||||||
|
return Result.error("评论不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 更新点赞数
|
||||||
|
Integer currentLikeCount = comment.getLikeCount() != null ? comment.getLikeCount() : 0;
|
||||||
|
comment.setLikeCount(currentLikeCount + 1);
|
||||||
|
|
||||||
|
boolean updated = aiolCommentService.updateById(comment);
|
||||||
|
if (!updated) {
|
||||||
|
return Result.error("点赞失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 发送点赞通知
|
||||||
|
sendLikeNotification(comment, sysUser);
|
||||||
|
|
||||||
|
log.info("用户 {} 评论点赞成功: commentId={}, 当前点赞数={}", username, commentId, comment.getLikeCount());
|
||||||
|
return Result.OK("点赞成功!");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("评论点赞失败: commentId={}, error={}", commentId, e.getMessage(), e);
|
||||||
|
return Result.error("点赞失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AutoLog(value = "评论-置顶")
|
||||||
|
@Operation(summary = "置顶评论", description = "将指定评论置顶,设置iz_top字段为1")
|
||||||
|
@RequiresPermissions("aiol:aiol_comment:edit")
|
||||||
|
@GetMapping(value = "/top/{commentId}")
|
||||||
|
public Result<String> topComment(@PathVariable("commentId") String commentId) {
|
||||||
|
try {
|
||||||
|
// 1. 查询评论是否存在
|
||||||
|
AiolComment comment = aiolCommentService.getById(commentId);
|
||||||
|
if (comment == null) {
|
||||||
|
return Result.error("评论不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 设置置顶状态
|
||||||
|
comment.setIzTop(1);
|
||||||
|
|
||||||
|
boolean updated = aiolCommentService.updateById(comment);
|
||||||
|
if (!updated) {
|
||||||
|
return Result.error("置顶失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("评论置顶成功: commentId={}", commentId);
|
||||||
|
return Result.OK("置顶成功!");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("评论置顶失败: commentId={}, error={}", commentId, e.getMessage(), e);
|
||||||
|
return Result.error("置顶失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AutoLog(value = "评论-取消置顶")
|
||||||
|
@Operation(summary = "取消置顶评论", description = "将指定评论取消置顶,设置iz_top字段为0")
|
||||||
|
@RequiresPermissions("aiol:aiol_comment:edit")
|
||||||
|
@GetMapping(value = "/untop/{commentId}")
|
||||||
|
public Result<String> untopComment(@PathVariable("commentId") String commentId) {
|
||||||
|
try {
|
||||||
|
// 1. 查询评论是否存在
|
||||||
|
AiolComment comment = aiolCommentService.getById(commentId);
|
||||||
|
if (comment == null) {
|
||||||
|
return Result.error("评论不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 取消置顶状态
|
||||||
|
comment.setIzTop(0);
|
||||||
|
boolean updated = aiolCommentService.updateById(comment);
|
||||||
|
if (!updated) {
|
||||||
|
return Result.error("取消置顶失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("评论取消置顶成功: commentId={}", commentId);
|
||||||
|
return Result.OK("取消置顶成功!");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("评论取消置顶失败: commentId={}, error={}", commentId, e.getMessage(), e);
|
||||||
|
return Result.error("取消置顶失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送评论通知
|
||||||
|
*
|
||||||
|
* @param aiolComment 评论对象
|
||||||
|
* @param sysUser 当前用户
|
||||||
|
*/
|
||||||
|
private void sendCommentNotification(AiolComment aiolComment, LoginUser sysUser) {
|
||||||
|
try {
|
||||||
|
String targetType = aiolComment.getTargetType();
|
||||||
|
String targetId = aiolComment.getTargetId();
|
||||||
|
|
||||||
|
// 确定接收通知的用户和实体标题
|
||||||
|
String toUserId = null;
|
||||||
|
String entityTitle = "未知实体";
|
||||||
|
|
||||||
|
if ("course".equals(targetType)) {
|
||||||
|
// 课程评论:通知课程创建者
|
||||||
|
AiolCourse course = aiolCourseService.getById(targetId);
|
||||||
|
if (course != null) {
|
||||||
|
toUserId = course.getCreateBy(); // 课程创建者
|
||||||
|
entityTitle = course.getName(); // 课程名称
|
||||||
|
}
|
||||||
|
} else if ("discussion".equals(targetType)) {
|
||||||
|
// 讨论评论:通知讨论创建者
|
||||||
|
AiolDiscussion discussion = aiolDiscussionService.getById(targetId);
|
||||||
|
if (discussion != null) {
|
||||||
|
toUserId = discussion.getCreateBy(); // 讨论创建者
|
||||||
|
entityTitle = discussion.getTitle(); // 讨论标题
|
||||||
|
}
|
||||||
|
} else if ("comment".equals(targetType)) {
|
||||||
|
// 回复评论:通知被回复的评论作者
|
||||||
|
AiolComment parentComment = aiolCommentService.getById(targetId);
|
||||||
|
if (parentComment != null) {
|
||||||
|
toUserId = parentComment.getUserId(); // 被回复评论的作者
|
||||||
|
entityTitle = "评论回复"; // 回复类型
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不给自己发通知
|
||||||
|
if (toUserId != null && !toUserId.equals(sysUser.getId()) && !toUserId.equals(sysUser.getUsername())) {
|
||||||
|
// 生成当前时间(格式:yyyy-MM-dd HH:mm:ss)
|
||||||
|
String actionTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||||
|
|
||||||
|
// 调用消息通知工具类发送评论通知
|
||||||
|
messageNotificationUtil.sendCommentNotification(
|
||||||
|
toUserId, // 接收用户ID
|
||||||
|
sysUser.getId(), // 发送用户ID
|
||||||
|
sysUser.getId(), // 发送者ID
|
||||||
|
sysUser.getUsername(), // 发送者用户名
|
||||||
|
Long.valueOf(aiolComment.getId()), // 评论ID
|
||||||
|
aiolComment.getContent(), // 评论内容
|
||||||
|
targetType, // 实体类型
|
||||||
|
targetId, // 实体ID
|
||||||
|
entityTitle, // 实体标题
|
||||||
|
actionTime // 操作时间
|
||||||
|
);
|
||||||
|
|
||||||
|
log.info("评论通知发送成功: 评论者={}, 接收者={}, 目标类型={}, 实体标题={}",
|
||||||
|
sysUser.getUsername(), toUserId, targetType, entityTitle);
|
||||||
|
} else {
|
||||||
|
log.debug("跳过通知发送: 自己评论自己的内容或未找到接收者, 评论者={}, 接收者={}",
|
||||||
|
sysUser.getId(), toUserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 通知发送失败不影响评论的正常添加,只记录错误日志
|
||||||
|
log.error("发送评论通知失败: commentId={}, targetType={}, targetId={}, error={}",
|
||||||
|
aiolComment.getId(), aiolComment.getTargetType(), aiolComment.getTargetId(), e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送点赞通知
|
||||||
|
*
|
||||||
|
* @param comment 被点赞的评论对象
|
||||||
|
* @param sysUser 点赞用户
|
||||||
|
*/
|
||||||
|
private void sendLikeNotification(AiolComment comment, LoginUser sysUser) {
|
||||||
|
try {
|
||||||
|
// 获取评论作者ID
|
||||||
|
String toUserId = comment.getUserId();
|
||||||
|
String entityTitle = "评论";
|
||||||
|
|
||||||
|
// 不给自己发通知
|
||||||
|
if (toUserId != null && !toUserId.equals(sysUser.getId()) && !toUserId.equals(sysUser.getUsername())) {
|
||||||
|
// 生成当前时间(格式:yyyy-MM-dd HH:mm:ss)
|
||||||
|
String actionTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||||
|
|
||||||
|
// 调用消息通知工具类发送点赞通知
|
||||||
|
messageNotificationUtil.sendLikeNotification(
|
||||||
|
toUserId, // 接收用户ID(评论作者)
|
||||||
|
sysUser.getId(), // 发送用户ID(点赞者)
|
||||||
|
sysUser.getId(), // 发送者ID
|
||||||
|
sysUser.getUsername(), // 发送者用户名
|
||||||
|
"comment", // 实体类型
|
||||||
|
comment.getId(), // 实体ID(评论ID)
|
||||||
|
entityTitle, // 实体标题
|
||||||
|
"like", // 操作类型
|
||||||
|
actionTime // 操作时间
|
||||||
|
);
|
||||||
|
|
||||||
|
log.info("点赞通知发送成功: 点赞者={}, 接收者={}, 评论ID={}",
|
||||||
|
sysUser.getUsername(), toUserId, comment.getId());
|
||||||
|
} else {
|
||||||
|
log.debug("跳过点赞通知发送: 自己点赞自己的评论, 点赞者={}, 接收者={}",
|
||||||
|
sysUser.getId(), toUserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 通知发送失败不影响点赞的正常操作,只记录错误日志
|
||||||
|
log.error("发送点赞通知失败: commentId={}, error={}",
|
||||||
|
comment.getId(), e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,182 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolContentConfig;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolContentConfigService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 内容配置
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="内容配置")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolContentConfig")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolContentConfigController extends JeecgController<AiolContentConfig, IAiolContentConfigService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolContentConfigService aiolContentConfigService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolContentConfig
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "内容配置-分页列表查询")
|
||||||
|
@Operation(summary="内容配置-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolContentConfig>> queryPageList(AiolContentConfig aiolContentConfig,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolContentConfig> queryWrapper = QueryGenerator.initQueryWrapper(aiolContentConfig, req.getParameterMap());
|
||||||
|
Page<AiolContentConfig> page = new Page<AiolContentConfig>(pageNo, pageSize);
|
||||||
|
IPage<AiolContentConfig> pageList = aiolContentConfigService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolContentConfig
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "内容配置-添加")
|
||||||
|
@Operation(summary="内容配置-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_content_config:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolContentConfig aiolContentConfig) {
|
||||||
|
aiolContentConfigService.save(aiolContentConfig);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolContentConfig
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "内容配置-编辑")
|
||||||
|
@Operation(summary="内容配置-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_content_config:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolContentConfig aiolContentConfig) {
|
||||||
|
aiolContentConfigService.updateById(aiolContentConfig);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "内容配置-通过id删除")
|
||||||
|
@Operation(summary="内容配置-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_content_config:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolContentConfigService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "内容配置-批量删除")
|
||||||
|
@Operation(summary="内容配置-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_content_config:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolContentConfigService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "内容配置-通过id查询")
|
||||||
|
@Operation(summary="内容配置-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolContentConfig> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolContentConfig aiolContentConfig = aiolContentConfigService.getById(id);
|
||||||
|
if(aiolContentConfig==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolContentConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolContentConfig
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_content_config:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolContentConfig aiolContentConfig) {
|
||||||
|
return super.exportXls(request, aiolContentConfig, AiolContentConfig.class, "内容配置");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_content_config:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolContentConfig.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,182 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolCourseCategory;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolCourseCategoryService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 课程分类
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="课程分类")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolCourseCategory")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolCourseCategoryController extends JeecgController<AiolCourseCategory, IAiolCourseCategoryService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolCourseCategoryService aiolCourseCategoryService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolCourseCategory
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "课程分类-分页列表查询")
|
||||||
|
@Operation(summary="课程分类-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolCourseCategory>> queryPageList(AiolCourseCategory aiolCourseCategory,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolCourseCategory> queryWrapper = QueryGenerator.initQueryWrapper(aiolCourseCategory, req.getParameterMap());
|
||||||
|
Page<AiolCourseCategory> page = new Page<AiolCourseCategory>(pageNo, pageSize);
|
||||||
|
IPage<AiolCourseCategory> pageList = aiolCourseCategoryService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolCourseCategory
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "课程分类-添加")
|
||||||
|
@Operation(summary="课程分类-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_course_category:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolCourseCategory aiolCourseCategory) {
|
||||||
|
aiolCourseCategoryService.save(aiolCourseCategory);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolCourseCategory
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "课程分类-编辑")
|
||||||
|
@Operation(summary="课程分类-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_course_category:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolCourseCategory aiolCourseCategory) {
|
||||||
|
aiolCourseCategoryService.updateById(aiolCourseCategory);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "课程分类-通过id删除")
|
||||||
|
@Operation(summary="课程分类-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_course_category:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolCourseCategoryService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "课程分类-批量删除")
|
||||||
|
@Operation(summary="课程分类-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_course_category:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolCourseCategoryService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "课程分类-通过id查询")
|
||||||
|
@Operation(summary="课程分类-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolCourseCategory> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolCourseCategory aiolCourseCategory = aiolCourseCategoryService.getById(id);
|
||||||
|
if(aiolCourseCategory==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolCourseCategory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolCourseCategory
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_course_category:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolCourseCategory aiolCourseCategory) {
|
||||||
|
return super.exportXls(request, aiolCourseCategory, AiolCourseCategory.class, "课程分类");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_course_category:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolCourseCategory.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,264 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolCourseSection;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolEntityLink;
|
||||||
|
import org.jeecg.modules.aiol.constant.EntityLinkConst;
|
||||||
|
import org.jeecg.modules.aiol.dto.AiolCourseSectionDTO;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolCourseSectionService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolEntityLinkService;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolEntityLinkMapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import java.util.Date;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 课程章节
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="课程章节")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolCourseSection")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolCourseSectionController extends JeecgController<AiolCourseSection, IAiolCourseSectionService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolCourseSectionService aiolCourseSectionService;
|
||||||
|
@Autowired
|
||||||
|
private AiolEntityLinkMapper aiolEntityLinkMapper;
|
||||||
|
@Autowired
|
||||||
|
private IAiolEntityLinkService aiolEntityLinkService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolCourseSection
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "课程章节-分页列表查询")
|
||||||
|
@Operation(summary="课程章节-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolCourseSection>> queryPageList(AiolCourseSection aiolCourseSection,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolCourseSection> queryWrapper = QueryGenerator.initQueryWrapper(aiolCourseSection, req.getParameterMap());
|
||||||
|
Page<AiolCourseSection> page = new Page<AiolCourseSection>(pageNo, pageSize);
|
||||||
|
IPage<AiolCourseSection> pageList = aiolCourseSectionService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param sectionDTO 课程章节DTO,包含章节信息和资源关联信息
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "课程章节-添加")
|
||||||
|
@Operation(summary="课程章节-添加", description = "添加课程章节并关联资源,支持resourceId和resourceType参数")
|
||||||
|
@RequiresPermissions("aiol:aiol_course_section:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Result<String> add(@RequestBody AiolCourseSectionDTO sectionDTO) {
|
||||||
|
try {
|
||||||
|
// 1. 保存章节信息
|
||||||
|
aiolCourseSectionService.save(sectionDTO);
|
||||||
|
|
||||||
|
// 2. 处理资源关联
|
||||||
|
if (sectionDTO.getTargetId() != null && !sectionDTO.getTargetId().trim().isEmpty() &&
|
||||||
|
sectionDTO.getType() != null) {
|
||||||
|
|
||||||
|
aiolEntityLinkService.save(
|
||||||
|
EntityLinkConst.SourceType.COURSE_SECTION,
|
||||||
|
sectionDTO.getId(),
|
||||||
|
getTargetType(sectionDTO.getType()),
|
||||||
|
sectionDTO.getTargetId()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.OK(sectionDTO.getId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("添加课程章节失败: {}", e.getMessage(), e);
|
||||||
|
return Result.error("添加课程章节失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getTargetType(Integer type) {
|
||||||
|
switch (type) {
|
||||||
|
case 0:
|
||||||
|
return EntityLinkConst.TargetType.RESOURCE;
|
||||||
|
case 1:
|
||||||
|
return EntityLinkConst.TargetType.RESOURCE;
|
||||||
|
case 2:
|
||||||
|
return EntityLinkConst.TargetType.EXAM;
|
||||||
|
case 3:
|
||||||
|
return EntityLinkConst.TargetType.HOMEWORK;
|
||||||
|
case 4:
|
||||||
|
return EntityLinkConst.TargetType.EXAM;
|
||||||
|
case 5:
|
||||||
|
return EntityLinkConst.TargetType.DISCUSSION;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param sectionDTO 课程章节DTO,包含章节信息和资源关联信息
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "课程章节-编辑")
|
||||||
|
@Operation(summary="课程章节-编辑", description = "编辑课程章节并更新资源关联,支持resourceId和resourceType参数")
|
||||||
|
@RequiresPermissions("aiol:aiol_course_section:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Result<String> edit(@RequestBody AiolCourseSectionDTO sectionDTO) {
|
||||||
|
try {
|
||||||
|
// 1. 更新章节信息
|
||||||
|
aiolCourseSectionService.updateById(sectionDTO);
|
||||||
|
|
||||||
|
// 2. 处理资源关联更新
|
||||||
|
if (sectionDTO.getTargetId() != null && !sectionDTO.getTargetId().trim().isEmpty() &&
|
||||||
|
sectionDTO.getType() != null) {
|
||||||
|
|
||||||
|
// 先删除旧的关联关系
|
||||||
|
QueryWrapper<AiolEntityLink> deleteWrapper = new QueryWrapper<>();
|
||||||
|
deleteWrapper.eq("source_type", EntityLinkConst.SourceType.COURSE_SECTION)
|
||||||
|
.eq("source_id", sectionDTO.getId());
|
||||||
|
aiolEntityLinkMapper.delete(deleteWrapper);
|
||||||
|
|
||||||
|
// 创建新的关联关系
|
||||||
|
aiolEntityLinkService.save(
|
||||||
|
EntityLinkConst.SourceType.COURSE_SECTION,
|
||||||
|
sectionDTO.getId(),
|
||||||
|
getTargetType(sectionDTO.getType()),
|
||||||
|
sectionDTO.getTargetId()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// 如果没有提供资源信息,删除所有关联关系
|
||||||
|
QueryWrapper<AiolEntityLink> deleteWrapper = new QueryWrapper<>();
|
||||||
|
deleteWrapper.eq("source_type", EntityLinkConst.SourceType.COURSE_SECTION)
|
||||||
|
.eq("source_id", sectionDTO.getId());
|
||||||
|
aiolEntityLinkMapper.delete(deleteWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("编辑课程章节失败: {}", e.getMessage(), e);
|
||||||
|
return Result.error("编辑课程章节失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "课程章节-通过id删除")
|
||||||
|
@Operation(summary="课程章节-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_course_section:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolCourseSectionService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "课程章节-批量删除")
|
||||||
|
@Operation(summary="课程章节-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_course_section:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolCourseSectionService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "课程章节-通过id查询")
|
||||||
|
@Operation(summary="课程章节-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolCourseSection> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolCourseSection aiolCourseSection = aiolCourseSectionService.getById(id);
|
||||||
|
if(aiolCourseSection==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolCourseSection);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolCourseSection
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_course_section:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolCourseSection aiolCourseSection) {
|
||||||
|
return super.exportXls(request, aiolCourseSection, AiolCourseSection.class, "课程章节");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_course_section:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolCourseSection.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,182 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolCourseSignup;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolCourseSignupService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 课程报名
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="课程报名")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolCourseSignup")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolCourseSignupController extends JeecgController<AiolCourseSignup, IAiolCourseSignupService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolCourseSignupService aiolCourseSignupService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolCourseSignup
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "课程报名-分页列表查询")
|
||||||
|
@Operation(summary="课程报名-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolCourseSignup>> queryPageList(AiolCourseSignup aiolCourseSignup,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolCourseSignup> queryWrapper = QueryGenerator.initQueryWrapper(aiolCourseSignup, req.getParameterMap());
|
||||||
|
Page<AiolCourseSignup> page = new Page<AiolCourseSignup>(pageNo, pageSize);
|
||||||
|
IPage<AiolCourseSignup> pageList = aiolCourseSignupService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolCourseSignup
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "课程报名-添加")
|
||||||
|
@Operation(summary="课程报名-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_course_signup:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolCourseSignup aiolCourseSignup) {
|
||||||
|
aiolCourseSignupService.save(aiolCourseSignup);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolCourseSignup
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "课程报名-编辑")
|
||||||
|
@Operation(summary="课程报名-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_course_signup:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolCourseSignup aiolCourseSignup) {
|
||||||
|
aiolCourseSignupService.updateById(aiolCourseSignup);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "课程报名-通过id删除")
|
||||||
|
@Operation(summary="课程报名-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_course_signup:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolCourseSignupService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "课程报名-批量删除")
|
||||||
|
@Operation(summary="课程报名-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_course_signup:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolCourseSignupService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "课程报名-通过id查询")
|
||||||
|
@Operation(summary="课程报名-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolCourseSignup> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolCourseSignup aiolCourseSignup = aiolCourseSignupService.getById(id);
|
||||||
|
if(aiolCourseSignup==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolCourseSignup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolCourseSignup
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_course_signup:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolCourseSignup aiolCourseSignup) {
|
||||||
|
return super.exportXls(request, aiolCourseSignup, AiolCourseSignup.class, "课程报名");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_course_signup:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolCourseSignup.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,182 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolCourseTeacher;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolCourseTeacherService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 授课教师
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="授课教师")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolCourseTeacher")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolCourseTeacherController extends JeecgController<AiolCourseTeacher, IAiolCourseTeacherService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolCourseTeacherService aiolCourseTeacherService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolCourseTeacher
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "授课教师-分页列表查询")
|
||||||
|
@Operation(summary="授课教师-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolCourseTeacher>> queryPageList(AiolCourseTeacher aiolCourseTeacher,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolCourseTeacher> queryWrapper = QueryGenerator.initQueryWrapper(aiolCourseTeacher, req.getParameterMap());
|
||||||
|
Page<AiolCourseTeacher> page = new Page<AiolCourseTeacher>(pageNo, pageSize);
|
||||||
|
IPage<AiolCourseTeacher> pageList = aiolCourseTeacherService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolCourseTeacher
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "授课教师-添加")
|
||||||
|
@Operation(summary="授课教师-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_course_teacher:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolCourseTeacher aiolCourseTeacher) {
|
||||||
|
aiolCourseTeacherService.save(aiolCourseTeacher);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolCourseTeacher
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "授课教师-编辑")
|
||||||
|
@Operation(summary="授课教师-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_course_teacher:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolCourseTeacher aiolCourseTeacher) {
|
||||||
|
aiolCourseTeacherService.updateById(aiolCourseTeacher);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "授课教师-通过id删除")
|
||||||
|
@Operation(summary="授课教师-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_course_teacher:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolCourseTeacherService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "授课教师-批量删除")
|
||||||
|
@Operation(summary="授课教师-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_course_teacher:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolCourseTeacherService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "授课教师-通过id查询")
|
||||||
|
@Operation(summary="授课教师-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolCourseTeacher> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolCourseTeacher aiolCourseTeacher = aiolCourseTeacherService.getById(id);
|
||||||
|
if(aiolCourseTeacher==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolCourseTeacher);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolCourseTeacher
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_course_teacher:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolCourseTeacher aiolCourseTeacher) {
|
||||||
|
return super.exportXls(request, aiolCourseTeacher, AiolCourseTeacher.class, "授课教师");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_course_teacher:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolCourseTeacher.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,292 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.config.shiro.IgnoreAuth;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolDiscussion;
|
||||||
|
import org.jeecg.modules.aiol.dto.DiscussionWithSectionDTO;
|
||||||
|
import org.jeecg.modules.aiol.dto.AiolDiscussionSaveDTO;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolDiscussionService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolEntityLinkService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolCourseSectionService;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolCourseSection;
|
||||||
|
import org.jeecg.modules.aiol.constant.EntityLinkConst;
|
||||||
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 讨论
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-19
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="讨论")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolDiscussion")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolDiscussionController extends JeecgController<AiolDiscussion, IAiolDiscussionService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolDiscussionService aiolDiscussionService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolEntityLinkService aiolEntityLinkService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolCourseSectionService aiolCourseSectionService;
|
||||||
|
@Autowired
|
||||||
|
private ISysBaseAPI sysBaseApi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolDiscussion
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "讨论-分页列表查询")
|
||||||
|
@Operation(summary="讨论-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolDiscussion>> queryPageList(AiolDiscussion aiolDiscussion,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolDiscussion> queryWrapper = QueryGenerator.initQueryWrapper(aiolDiscussion, req.getParameterMap());
|
||||||
|
Page<AiolDiscussion> page = new Page<AiolDiscussion>(pageNo, pageSize);
|
||||||
|
IPage<AiolDiscussion> pageList = aiolDiscussionService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolDiscussionSaveDTO 讨论保存DTO,包含章节ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "讨论-添加")
|
||||||
|
@Operation(summary="讨论-添加", description="添加讨论,可选择关联到指定章节")
|
||||||
|
@RequiresPermissions("aiol:aiol_discussion:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolDiscussionSaveDTO aiolDiscussionSaveDTO) {
|
||||||
|
try {
|
||||||
|
// 创建讨论实体
|
||||||
|
AiolDiscussion aiolDiscussion = new AiolDiscussion();
|
||||||
|
aiolDiscussion.setTitle(aiolDiscussionSaveDTO.getTitle());
|
||||||
|
aiolDiscussion.setDescription(aiolDiscussionSaveDTO.getDescription());
|
||||||
|
aiolDiscussion.setCourseId(aiolDiscussionSaveDTO.getCourseId());
|
||||||
|
|
||||||
|
// 保存讨论记录
|
||||||
|
aiolDiscussionService.save(aiolDiscussion);
|
||||||
|
|
||||||
|
// 如果传入了sectionId,创建与章节的关联关系
|
||||||
|
String sectionId = aiolDiscussionSaveDTO.getSectionId();
|
||||||
|
if (sectionId != null && !sectionId.trim().isEmpty()) {
|
||||||
|
aiolEntityLinkService.save(
|
||||||
|
EntityLinkConst.SourceType.COURSE_SECTION,
|
||||||
|
sectionId.trim(),
|
||||||
|
EntityLinkConst.TargetType.DISCUSSION,
|
||||||
|
aiolDiscussion.getId()
|
||||||
|
);
|
||||||
|
log.info("讨论 {} 成功关联到章节 {}", aiolDiscussion.getId(), sectionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.OK(aiolDiscussion.getId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("添加讨论失败: {}", e.getMessage(), e);
|
||||||
|
return Result.error("添加讨论失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolDiscussion
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "讨论-编辑")
|
||||||
|
@Operation(summary="讨论-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_discussion:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolDiscussion aiolDiscussion) {
|
||||||
|
aiolDiscussionService.updateById(aiolDiscussion);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "讨论-通过id删除")
|
||||||
|
@Operation(summary="讨论-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_discussion:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolDiscussionService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "讨论-批量删除")
|
||||||
|
@Operation(summary="讨论-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_discussion:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolDiscussionService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "讨论-通过id查询")
|
||||||
|
@Operation(summary="讨论-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<AiolDiscussion> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolDiscussion aiolDiscussion = aiolDiscussionService.getById(id);
|
||||||
|
if(aiolDiscussion==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolDiscussion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolDiscussion
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_discussion:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolDiscussion aiolDiscussion) {
|
||||||
|
return super.exportXls(request, aiolDiscussion, AiolDiscussion.class, "讨论");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_discussion:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolDiscussion.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AutoLog(value = "讨论-查询课程下的讨论列表")
|
||||||
|
@Operation(summary = "查询课程讨论列表", description = "查询课程讨论列表,包含关联的章节ID")
|
||||||
|
@GetMapping(value = "/teacher_list")
|
||||||
|
public Result<List<DiscussionWithSectionDTO>> queryCourseDiscussions(HttpServletRequest request, @RequestParam(value = "courseId") String courseId) {
|
||||||
|
try {
|
||||||
|
// 1. 查询课程下的讨论列表
|
||||||
|
QueryWrapper<AiolDiscussion> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("course_id", courseId)
|
||||||
|
.orderByDesc("create_time");
|
||||||
|
|
||||||
|
List<AiolDiscussion> discussionList = aiolDiscussionService.list(queryWrapper);
|
||||||
|
|
||||||
|
// 2. 转换为包含章节信息的DTO列表
|
||||||
|
List<DiscussionWithSectionDTO> resultList = discussionList.stream()
|
||||||
|
.map(this::convertToDiscussionWithSection)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return Result.OK(resultList);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询课程讨论列表失败: error={}", e.getMessage(), e);
|
||||||
|
return Result.error("查询课程讨论列表失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将AiolDiscussion转换为包含章节信息的DTO
|
||||||
|
* @param discussion 讨论实体
|
||||||
|
* @return 包含章节ID的DTO
|
||||||
|
*/
|
||||||
|
private DiscussionWithSectionDTO convertToDiscussionWithSection(AiolDiscussion discussion) {
|
||||||
|
DiscussionWithSectionDTO dto = new DiscussionWithSectionDTO();
|
||||||
|
|
||||||
|
// 复制基本属性
|
||||||
|
dto.setId(discussion.getId());
|
||||||
|
dto.setTitle(discussion.getTitle());
|
||||||
|
dto.setDescription(discussion.getDescription());
|
||||||
|
dto.setCourseId(discussion.getCourseId());
|
||||||
|
dto.setCreateBy(discussion.getCreateBy());
|
||||||
|
dto.setCreateTime(discussion.getCreateTime());
|
||||||
|
dto.setUpdateBy(discussion.getUpdateBy());
|
||||||
|
dto.setUpdateTime(discussion.getUpdateTime());
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 查询关联的章节ID
|
||||||
|
String sectionId = aiolEntityLinkService.listSourceId(
|
||||||
|
EntityLinkConst.TargetType.DISCUSSION,
|
||||||
|
discussion.getId(),
|
||||||
|
EntityLinkConst.SourceType.COURSE_SECTION
|
||||||
|
);
|
||||||
|
|
||||||
|
if (sectionId != null) {
|
||||||
|
dto.setSectionId(sectionId);
|
||||||
|
|
||||||
|
// 查询章节名称
|
||||||
|
AiolCourseSection section = aiolCourseSectionService.getById(sectionId);
|
||||||
|
if (section != null && section.getName() != null) {
|
||||||
|
dto.setSectionName(section.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询讨论关联章节失败: discussionId={}, error={}", discussion.getId(), e.getMessage(), e);
|
||||||
|
// 即使查询失败,也返回基本的讨论信息
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,182 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolEntityLink;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolEntityLinkService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 主体绑定
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="主体绑定")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolEntityLink")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolEntityLinkController extends JeecgController<AiolEntityLink, IAiolEntityLinkService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolEntityLinkService aiolEntityLinkService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolEntityLink
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "主体绑定-分页列表查询")
|
||||||
|
@Operation(summary="主体绑定-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolEntityLink>> queryPageList(AiolEntityLink aiolEntityLink,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolEntityLink> queryWrapper = QueryGenerator.initQueryWrapper(aiolEntityLink, req.getParameterMap());
|
||||||
|
Page<AiolEntityLink> page = new Page<AiolEntityLink>(pageNo, pageSize);
|
||||||
|
IPage<AiolEntityLink> pageList = aiolEntityLinkService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolEntityLink
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "主体绑定-添加")
|
||||||
|
@Operation(summary="主体绑定-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_entity_link:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolEntityLink aiolEntityLink) {
|
||||||
|
aiolEntityLinkService.save(aiolEntityLink);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolEntityLink
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "主体绑定-编辑")
|
||||||
|
@Operation(summary="主体绑定-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_entity_link:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolEntityLink aiolEntityLink) {
|
||||||
|
aiolEntityLinkService.updateById(aiolEntityLink);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "主体绑定-通过id删除")
|
||||||
|
@Operation(summary="主体绑定-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_entity_link:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolEntityLinkService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "主体绑定-批量删除")
|
||||||
|
@Operation(summary="主体绑定-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_entity_link:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolEntityLinkService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "主体绑定-通过id查询")
|
||||||
|
@Operation(summary="主体绑定-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolEntityLink> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolEntityLink aiolEntityLink = aiolEntityLinkService.getById(id);
|
||||||
|
if(aiolEntityLink==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolEntityLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolEntityLink
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_entity_link:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolEntityLink aiolEntityLink) {
|
||||||
|
return super.exportXls(request, aiolEntityLink, AiolEntityLink.class, "主体绑定");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_entity_link:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolEntityLink.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,182 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolEntityPermission;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolEntityPermissionService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 实体权限
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-05
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="实体权限")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolEntityPermission")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolEntityPermissionController extends JeecgController<AiolEntityPermission, IAiolEntityPermissionService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolEntityPermissionService aiolEntityPermissionService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolEntityPermission
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "实体权限-分页列表查询")
|
||||||
|
@Operation(summary="实体权限-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolEntityPermission>> queryPageList(AiolEntityPermission aiolEntityPermission,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolEntityPermission> queryWrapper = QueryGenerator.initQueryWrapper(aiolEntityPermission, req.getParameterMap());
|
||||||
|
Page<AiolEntityPermission> page = new Page<AiolEntityPermission>(pageNo, pageSize);
|
||||||
|
IPage<AiolEntityPermission> pageList = aiolEntityPermissionService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolEntityPermission
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "实体权限-添加")
|
||||||
|
@Operation(summary="实体权限-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_entity_permission:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolEntityPermission aiolEntityPermission) {
|
||||||
|
aiolEntityPermissionService.save(aiolEntityPermission);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolEntityPermission
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "实体权限-编辑")
|
||||||
|
@Operation(summary="实体权限-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_entity_permission:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolEntityPermission aiolEntityPermission) {
|
||||||
|
aiolEntityPermissionService.updateById(aiolEntityPermission);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "实体权限-通过id删除")
|
||||||
|
@Operation(summary="实体权限-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_entity_permission:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolEntityPermissionService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "实体权限-批量删除")
|
||||||
|
@Operation(summary="实体权限-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_entity_permission:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolEntityPermissionService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "实体权限-通过id查询")
|
||||||
|
@Operation(summary="实体权限-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolEntityPermission> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolEntityPermission aiolEntityPermission = aiolEntityPermissionService.getById(id);
|
||||||
|
if(aiolEntityPermission==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolEntityPermission);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolEntityPermission
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_entity_permission:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolEntityPermission aiolEntityPermission) {
|
||||||
|
return super.exportXls(request, aiolEntityPermission, AiolEntityPermission.class, "实体权限");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_entity_permission:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolEntityPermission.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,182 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolExamAnswer;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolExamAnswerService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 考试答题
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="考试答题")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolExamAnswer")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolExamAnswerController extends JeecgController<AiolExamAnswer, IAiolExamAnswerService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolExamAnswerService aiolExamAnswerService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolExamAnswer
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "考试答题-分页列表查询")
|
||||||
|
@Operation(summary="考试答题-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolExamAnswer>> queryPageList(AiolExamAnswer aiolExamAnswer,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolExamAnswer> queryWrapper = QueryGenerator.initQueryWrapper(aiolExamAnswer, req.getParameterMap());
|
||||||
|
Page<AiolExamAnswer> page = new Page<AiolExamAnswer>(pageNo, pageSize);
|
||||||
|
IPage<AiolExamAnswer> pageList = aiolExamAnswerService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolExamAnswer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "考试答题-添加")
|
||||||
|
@Operation(summary="考试答题-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_exam_answer:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolExamAnswer aiolExamAnswer) {
|
||||||
|
aiolExamAnswerService.save(aiolExamAnswer);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolExamAnswer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "考试答题-编辑")
|
||||||
|
@Operation(summary="考试答题-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_exam_answer:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolExamAnswer aiolExamAnswer) {
|
||||||
|
aiolExamAnswerService.updateById(aiolExamAnswer);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "考试答题-通过id删除")
|
||||||
|
@Operation(summary="考试答题-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_exam_answer:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolExamAnswerService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "考试答题-批量删除")
|
||||||
|
@Operation(summary="考试答题-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_exam_answer:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolExamAnswerService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "考试答题-通过id查询")
|
||||||
|
@Operation(summary="考试答题-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolExamAnswer> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolExamAnswer aiolExamAnswer = aiolExamAnswerService.getById(id);
|
||||||
|
if(aiolExamAnswer==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolExamAnswer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolExamAnswer
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_exam_answer:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolExamAnswer aiolExamAnswer) {
|
||||||
|
return super.exportXls(request, aiolExamAnswer, AiolExamAnswer.class, "考试答题");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_exam_answer:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolExamAnswer.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,199 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolExamAnswer;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolExamRecord;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolExamAnswerService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolExamRecordService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 考试记录
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="考试记录")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolExamRecord")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolExamRecordController extends JeecgController<AiolExamRecord, IAiolExamRecordService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolExamRecordService aiolExamRecordService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolExamAnswerService aiolExamAnswerService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolExamRecord
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "考试记录-分页列表查询")
|
||||||
|
@Operation(summary="考试记录-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolExamRecord>> queryPageList(AiolExamRecord aiolExamRecord,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolExamRecord> queryWrapper = QueryGenerator.initQueryWrapper(aiolExamRecord, req.getParameterMap());
|
||||||
|
Page<AiolExamRecord> page = new Page<AiolExamRecord>(pageNo, pageSize);
|
||||||
|
IPage<AiolExamRecord> pageList = aiolExamRecordService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolExamRecord
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "考试记录-添加")
|
||||||
|
@Operation(summary="考试记录-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_exam_record:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolExamRecord aiolExamRecord) {
|
||||||
|
aiolExamRecordService.save(aiolExamRecord);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolExamRecord
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "考试记录-编辑")
|
||||||
|
@Operation(summary="考试记录-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_exam_record:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolExamRecord aiolExamRecord) {
|
||||||
|
aiolExamRecordService.updateById(aiolExamRecord);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "考试记录-通过id删除")
|
||||||
|
@Operation(summary="考试记录-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_exam_record:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolExamRecordService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "考试记录-批量删除")
|
||||||
|
@Operation(summary="考试记录-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_exam_record:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolExamRecordService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@AutoLog(value = "考试记录-重新练习")
|
||||||
|
@Operation(summary="考试记录-重新练习")
|
||||||
|
@RequiresPermissions("aiol:aiol_exam_record:edit")
|
||||||
|
@Transactional
|
||||||
|
@RequestMapping(value = "/rePractice", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> rePractice(@RequestParam String userId,@RequestParam String examId) {
|
||||||
|
aiolExamRecordService.remove(new QueryWrapper<AiolExamRecord>().eq("user_id", userId).eq("exam_id", examId));
|
||||||
|
aiolExamAnswerService.remove(new QueryWrapper<AiolExamAnswer>().eq("user_id", userId).eq("exam_id", examId));
|
||||||
|
return Result.OK("请返回重新练习一次吧!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "考试记录-通过id查询")
|
||||||
|
@Operation(summary="考试记录-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolExamRecord> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolExamRecord aiolExamRecord = aiolExamRecordService.getById(id);
|
||||||
|
if(aiolExamRecord==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolExamRecord);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolExamRecord
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_exam_record:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolExamRecord aiolExamRecord) {
|
||||||
|
return super.exportXls(request, aiolExamRecord, AiolExamRecord.class, "考试记录");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_exam_record:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolExamRecord.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,718 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.dto.AiolHomeworkSaveDTO;
|
||||||
|
import org.jeecg.modules.aiol.dto.StudentSubmitHomework;
|
||||||
|
import org.jeecg.modules.aiol.dto.HomeworkWithDetailsDTO;
|
||||||
|
import org.jeecg.modules.aiol.entity.*;
|
||||||
|
import org.jeecg.modules.aiol.service.*;
|
||||||
|
import org.jeecg.modules.aiol.constant.EntityLinkConst;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolClassStudentMapper;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolCourseSignupMapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
|
import org.jeecg.modules.system.service.ISysUserService;
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 作业
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name = "作业")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolHomework")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolHomeworkController extends JeecgController<AiolHomework, IAiolHomeworkService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolHomeworkService aiolHomeworkService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolCourseSignupService aiolCourseSignupService;
|
||||||
|
@Autowired
|
||||||
|
private ISysUserService sysUserService;
|
||||||
|
@Autowired
|
||||||
|
private ISysBaseAPI sysBaseApi;
|
||||||
|
@Autowired
|
||||||
|
private IAiolEntityLinkService aiolEntityLinkService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolHomeworkSubmitService aiolHomeworkSubmitService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolHomework
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "作业-分页列表查询")
|
||||||
|
@Operation(summary = "作业-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolHomework>> queryPageList(AiolHomework aiolHomework,
|
||||||
|
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
|
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolHomework> queryWrapper = QueryGenerator.initQueryWrapper(aiolHomework, req.getParameterMap());
|
||||||
|
Page<AiolHomework> page = new Page<AiolHomework>(pageNo, pageSize);
|
||||||
|
IPage<AiolHomework> pageList = aiolHomeworkService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "我的作业-作业查询")
|
||||||
|
@GetMapping(value = "/myHomeworkList")
|
||||||
|
public Result<?> queryMyHomeworkList(HttpServletRequest request, @RequestParam(name = "type", defaultValue = "4", required = false) Integer type) {
|
||||||
|
// 尝试获取token,判断用户id
|
||||||
|
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
List<MyHomeworkDTO> homeworkDTOList = new ArrayList<>();
|
||||||
|
if (token != null && !token.trim().isEmpty()) {
|
||||||
|
try {
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
// 获取当前用户ID
|
||||||
|
String currentUserId = sysUser.getId();
|
||||||
|
if (sysUser != null) {
|
||||||
|
//获取课程id列表
|
||||||
|
List<AiolCourseSignup> courseSignupList = aiolCourseSignupMapper.selectList(
|
||||||
|
new QueryWrapper<AiolCourseSignup>()
|
||||||
|
.eq("user_id", sysUser.getId())
|
||||||
|
.select("course_id")
|
||||||
|
);
|
||||||
|
log.info("查询到课程数量: {}", courseSignupList.size());
|
||||||
|
// 获取课程章节id列表
|
||||||
|
List<AiolCourseSection> courseId = aiolCourseSectionService.list(
|
||||||
|
new QueryWrapper<AiolCourseSection>()
|
||||||
|
.in("course_id", courseSignupList.stream().map(AiolCourseSignup::getCourseId).collect(Collectors.toList()))
|
||||||
|
.select("id"));
|
||||||
|
List<String> courseIdList = courseId.stream()
|
||||||
|
.map(AiolCourseSection::getId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
log.info("查询到课程章节数量: {}", courseId.size());
|
||||||
|
//获取实体列表里的作业
|
||||||
|
List<String> list = new ArrayList<>();
|
||||||
|
if (!courseIdList.isEmpty()) {
|
||||||
|
list = aiolEntityLinkService.list(new QueryWrapper<AiolEntityLink>()
|
||||||
|
.eq("source_type", "course_section")
|
||||||
|
.in("source_id", courseIdList)
|
||||||
|
.eq("target_type", "homework")
|
||||||
|
.select("target_id")).stream().map(AiolEntityLink::getTargetId).collect(Collectors.toList());
|
||||||
|
} else return Result.ok();
|
||||||
|
log.info("查询到作业关联数量: {}", list.size());
|
||||||
|
|
||||||
|
// 查询作业
|
||||||
|
QueryWrapper<AiolHomework> queryWrapper = new QueryWrapper<>();
|
||||||
|
if (!list.isEmpty()) {
|
||||||
|
queryWrapper.in("id", list);
|
||||||
|
} else return Result.ok();
|
||||||
|
// 查询作业列表并去重
|
||||||
|
List<AiolHomework> homeworkList = aiolHomeworkService.list(queryWrapper)
|
||||||
|
.stream()
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
// 获取所有创建人ID
|
||||||
|
List<String> creatorIds = homeworkList.stream()
|
||||||
|
.map(AiolHomework::getCreateBy)
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (creatorIds.isEmpty()) return Result.ok();
|
||||||
|
// 查询所有作业的提交记录
|
||||||
|
List<AiolHomeworkSubmit> submitRecords = aiolHomeworkSubmitService.list(
|
||||||
|
new QueryWrapper<AiolHomeworkSubmit>()
|
||||||
|
.in("homework_id", homeworkList.stream().map(AiolHomework::getId).collect(Collectors.toList()))
|
||||||
|
);
|
||||||
|
// 按作业ID和学生ID分组存储提交记录
|
||||||
|
Map<String, Map<String, List<AiolHomeworkSubmit>>> userSubmitMap = submitRecords.stream()
|
||||||
|
.collect(Collectors.groupingBy(
|
||||||
|
AiolHomeworkSubmit::getHomeworkId,
|
||||||
|
Collectors.groupingBy(
|
||||||
|
AiolHomeworkSubmit::getStudentId
|
||||||
|
)
|
||||||
|
));
|
||||||
|
// 按作业ID分组统计提交人数
|
||||||
|
Map<String, Long> submitCountMap = submitRecords.stream()
|
||||||
|
.collect(Collectors.groupingBy(
|
||||||
|
AiolHomeworkSubmit::getHomeworkId,
|
||||||
|
Collectors.counting()
|
||||||
|
));
|
||||||
|
// 查询创建人信息
|
||||||
|
List<SysUser> userList = sysUserService.list(
|
||||||
|
new QueryWrapper<SysUser>()
|
||||||
|
.in("username", creatorIds)
|
||||||
|
);
|
||||||
|
// 创建ID到用户名的映射
|
||||||
|
Map<String, SysUser> userMap = userList.stream()
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
SysUser::getUsername,
|
||||||
|
SysUser -> SysUser
|
||||||
|
));
|
||||||
|
// 替换作业中的创建人ID为用户名
|
||||||
|
for (AiolHomework homework : homeworkList) {
|
||||||
|
MyHomeworkDTO myHomeworkDTO = new MyHomeworkDTO();
|
||||||
|
myHomeworkDTO.setAiolHomework(homework);
|
||||||
|
// 获取当前用户的提交记录,如果没有则返回空列表
|
||||||
|
List<AiolHomeworkSubmit> userSubmits = userSubmitMap.getOrDefault(homework.getId(), Collections.emptyMap())
|
||||||
|
.getOrDefault(currentUserId, Collections.emptyList());
|
||||||
|
if (type == 1 || type == 2) {
|
||||||
|
if (userSubmits.isEmpty() || !userSubmits.get(0).getStatus().equals(type)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (type == 0) {
|
||||||
|
if (!userSubmits.isEmpty() && !userSubmits.get(0).getStatus().equals(type)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
myHomeworkDTO.setAiolHomeworkSubmits(userSubmits);
|
||||||
|
myHomeworkDTO.setSubmitCount(submitCountMap.getOrDefault(homework.getId(), 0L));
|
||||||
|
String creatorId = homework.getCreateBy();
|
||||||
|
if (creatorId != null && userMap.containsKey(creatorId)) {
|
||||||
|
myHomeworkDTO.setRealName(userMap.get(creatorId).getRealname());
|
||||||
|
myHomeworkDTO.setAvatar(userMap.get(creatorId).getAvatar());
|
||||||
|
}
|
||||||
|
homeworkDTOList.add(myHomeworkDTO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.ok(homeworkDTOList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolHomework
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "作业-添加")
|
||||||
|
@Operation(summary = "作业-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_homework:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolHomework aiolHomework) {
|
||||||
|
aiolHomeworkService.save(aiolHomework);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolHomework
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "作业-编辑")
|
||||||
|
@Operation(summary = "作业-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_homework:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolHomework aiolHomework) {
|
||||||
|
aiolHomeworkService.updateById(aiolHomework);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "作业-通过id删除")
|
||||||
|
@Operation(summary = "作业-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_homework:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
aiolHomeworkService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "作业-批量删除")
|
||||||
|
@Operation(summary = "作业-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_homework:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||||
|
this.aiolHomeworkService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "作业-通过id查询")
|
||||||
|
@Operation(summary = "作业-通过id查询", description = "根据ID查询作业详情,包含班级名和章节信息")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<HomeworkWithDetailsDTO> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
AiolHomework aiolHomework = aiolHomeworkService.getById(id);
|
||||||
|
if (aiolHomework == null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换为包含详情的DTO
|
||||||
|
HomeworkWithDetailsDTO result = convertToHomeworkWithDetails(aiolHomework);
|
||||||
|
return Result.OK(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolHomework
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_homework:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolHomework aiolHomework) {
|
||||||
|
return super.exportXls(request, aiolHomework, AiolHomework.class, "作业");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_homework:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolHomework.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolHomeworkSubmitService homeworkSubmitService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolEntityLinkService entityLinkBizService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AiolClassStudentMapper aiolClassStudentMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AiolCourseSignupMapper aiolCourseSignupMapper;
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolClassService aiolClassService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolCourseSectionService aiolCourseSectionService;
|
||||||
|
|
||||||
|
@GetMapping("/course/{courseId}")
|
||||||
|
@Operation(summary = "查询课程作业")
|
||||||
|
public Result<List<AiolHomework>> list(@PathVariable String courseId) {
|
||||||
|
return Result.OK(aiolHomeworkService.listByCourseId(courseId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@AutoLog(value = "作业-教师端查询作业列表")
|
||||||
|
@Operation(summary = "查询课程作业列表", description = "查询当前登录教师创建的作业列表,包含班级名和章节信息")
|
||||||
|
@GetMapping(value = "/teacher_list")
|
||||||
|
public Result<List<HomeworkWithDetailsDTO>> teacherList(@RequestParam(value = "courseId") String courseId, HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
QueryWrapper<AiolHomework> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("course_id", courseId)
|
||||||
|
.orderByDesc("create_time");
|
||||||
|
|
||||||
|
List<AiolHomework> homeworkList = aiolHomeworkService.list(queryWrapper);
|
||||||
|
|
||||||
|
// 转换为包含详情的DTO列表
|
||||||
|
List<HomeworkWithDetailsDTO> resultList = homeworkList.stream()
|
||||||
|
.map(this::convertToHomeworkWithDetails)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return Result.OK(resultList);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询教师作业列表失败: error={}", e.getMessage(), e);
|
||||||
|
return Result.error("查询教师作业列表失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("submit")
|
||||||
|
@Operation(summary = "提交作业")
|
||||||
|
public Result<String> submit(@RequestBody StudentSubmitHomework studentSubmitHomework) {
|
||||||
|
return Result.OK(homeworkSubmitService.submit(studentSubmitHomework) ? "提交成功" : "提交失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("submitted/{studentId}")
|
||||||
|
@Operation(summary = "查询我已提交的作业")
|
||||||
|
public Result<List<AiolHomeworkSubmit>> submitted(@PathVariable String studentId) {
|
||||||
|
return Result.OK(homeworkSubmitService.submitted(studentId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("correct/{homeworkSubmitId}")
|
||||||
|
@Operation(summary = "教师批改作业")
|
||||||
|
public Result<Integer> correct(@PathVariable String homeworkSubmitId, @RequestParam Integer score,
|
||||||
|
@RequestParam String comment, @RequestParam String teacherId) {
|
||||||
|
return Result.OK(homeworkSubmitService.correct(homeworkSubmitId, score, comment, teacherId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@AutoLog(value = "作业-教师删除")
|
||||||
|
@Operation(summary = "作业-教师删除", description = "教师删除作业,同时删除相关的作业提交记录")
|
||||||
|
@RequiresPermissions("aiol:aiol_homework:delete")
|
||||||
|
@DeleteMapping(value = "/teacher_delete")
|
||||||
|
public Result<String> teacherDelete(@RequestParam(name = "id", required = true) String homeworkId) {
|
||||||
|
try {
|
||||||
|
// 1. 删除作业提交记录
|
||||||
|
QueryWrapper<AiolHomeworkSubmit> submitWrapper = new QueryWrapper<>();
|
||||||
|
submitWrapper.eq("homework_id", homeworkId);
|
||||||
|
List<AiolHomeworkSubmit> submitList = homeworkSubmitService.list(submitWrapper);
|
||||||
|
|
||||||
|
if (!submitList.isEmpty()) {
|
||||||
|
List<String> submitIds = submitList.stream()
|
||||||
|
.map(AiolHomeworkSubmit::getId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
homeworkSubmitService.removeByIds(submitIds);
|
||||||
|
log.info("删除作业提交记录成功: homeworkId={}, 删除数量={}", homeworkId, submitIds.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 删除作业记录
|
||||||
|
boolean deleted = aiolHomeworkService.removeById(homeworkId);
|
||||||
|
if (!deleted) {
|
||||||
|
return Result.error("删除作业失败,作业不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("教师删除作业成功: homeworkId={}", homeworkId);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("教师删除作业失败: homeworkId={}, error={}", homeworkId, e.getMessage(), e);
|
||||||
|
return Result.error("删除作业失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AutoLog(value = "作业-教师添加")
|
||||||
|
@Operation(summary = "作业-教师添加", description = "教师添加作业,支持指定班级、课程和章节,自动为学生创建作业提交记录")
|
||||||
|
@RequiresPermissions("aiol:aiol_homework:add")
|
||||||
|
@PostMapping(value = "/teacher_add")
|
||||||
|
public Result<String> teacherAdd(@RequestBody AiolHomeworkSaveDTO homeworkSaveDTO) {
|
||||||
|
try {
|
||||||
|
// 1. 保存作业记录
|
||||||
|
AiolHomework aiolHomework = new AiolHomework();
|
||||||
|
// 复制DTO中的作业字段到实体
|
||||||
|
BeanUtils.copyProperties(homeworkSaveDTO, aiolHomework);
|
||||||
|
aiolHomeworkService.save(aiolHomework);
|
||||||
|
|
||||||
|
String homeworkId = aiolHomework.getId();
|
||||||
|
String classId = homeworkSaveDTO.getClassId();
|
||||||
|
String courseId = homeworkSaveDTO.getCourseId();
|
||||||
|
String sectionId = homeworkSaveDTO.getSectionId();
|
||||||
|
|
||||||
|
// 2. 为学生创建作业提交记录
|
||||||
|
List<String> studentIds = new ArrayList<>();
|
||||||
|
|
||||||
|
if (classId != null && !classId.trim().isEmpty()) {
|
||||||
|
// 如果传递了班级ID,查询指定班级的学生
|
||||||
|
String[] classIds = classId.split(",");
|
||||||
|
for (String singleClassId : classIds) {
|
||||||
|
if (singleClassId != null && !singleClassId.trim().isEmpty()) {
|
||||||
|
singleClassId = singleClassId.trim();
|
||||||
|
QueryWrapper<AiolClassStudent> classStudentWrapper = new QueryWrapper<>();
|
||||||
|
classStudentWrapper.eq("class_id", singleClassId);
|
||||||
|
List<AiolClassStudent> classStudents = aiolClassStudentMapper.selectList(classStudentWrapper);
|
||||||
|
|
||||||
|
for (AiolClassStudent classStudent : classStudents) {
|
||||||
|
String studentId = classStudent.getStudentId();
|
||||||
|
if (!studentIds.contains(studentId)) {
|
||||||
|
studentIds.add(studentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (courseId != null && !courseId.trim().isEmpty()) {
|
||||||
|
// 如果没有传递班级ID,查询课程下的所有学生
|
||||||
|
QueryWrapper<AiolCourseSignup> courseSignupWrapper = new QueryWrapper<>();
|
||||||
|
courseSignupWrapper.eq("course_id", courseId);
|
||||||
|
List<AiolCourseSignup> courseSignups = aiolCourseSignupMapper.selectList(courseSignupWrapper);
|
||||||
|
|
||||||
|
for (AiolCourseSignup courseSignup : courseSignups) {
|
||||||
|
String studentId = courseSignup.getUserId();
|
||||||
|
if (!studentIds.contains(studentId)) {
|
||||||
|
studentIds.add(studentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 为每个学生创建空的作业提交记录
|
||||||
|
for (String studentId : studentIds) {
|
||||||
|
homeworkSubmitService.createEmptySubmit(homeworkId, studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 如果传递了章节ID,创建章节与作业的关联关系
|
||||||
|
if (sectionId != null && !sectionId.trim().isEmpty()) {
|
||||||
|
entityLinkBizService.save(
|
||||||
|
EntityLinkConst.SourceType.COURSE_SECTION,
|
||||||
|
sectionId.trim(),
|
||||||
|
EntityLinkConst.TargetType.HOMEWORK,
|
||||||
|
homeworkId
|
||||||
|
);
|
||||||
|
log.info("作业 {} 成功关联到章节 {}", homeworkId, sectionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("教师添加作业成功: homeworkId={}, courseId={}, classId={}, sectionId={}, 学生数量={}",
|
||||||
|
homeworkId, courseId, classId, sectionId, studentIds.size());
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("教师添加作业失败: homeworkSaveDTO={}, error={}", homeworkSaveDTO, e.getMessage(), e);
|
||||||
|
return Result.error("添加作业失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AutoLog(value = "作业-教师编辑")
|
||||||
|
@Operation(summary = "作业-教师编辑", description = "教师编辑作业,更新作业基础信息、章节关联,并为新范围内学生补齐提交记录")
|
||||||
|
@RequiresPermissions("aiol:aiol_homework:edit")
|
||||||
|
@PostMapping(value = "/teacher_edit")
|
||||||
|
public Result<String> teacherEdit(@RequestBody AiolHomeworkSaveDTO homeworkSaveDTO) {
|
||||||
|
try {
|
||||||
|
// 1. 校验ID并查询原记录
|
||||||
|
if (homeworkSaveDTO.getId() == null || homeworkSaveDTO.getId().trim().isEmpty()) {
|
||||||
|
return Result.error("作业ID不能为空");
|
||||||
|
}
|
||||||
|
AiolHomework origin = aiolHomeworkService.getById(homeworkSaveDTO.getId());
|
||||||
|
if (origin == null) {
|
||||||
|
return Result.error("作业不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 覆盖更新作业基础信息
|
||||||
|
AiolHomework toUpdate = new AiolHomework();
|
||||||
|
org.springframework.beans.BeanUtils.copyProperties(homeworkSaveDTO, toUpdate);
|
||||||
|
boolean updated = aiolHomeworkService.updateById(toUpdate);
|
||||||
|
if (!updated) {
|
||||||
|
return Result.error("更新作业失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
final String homeworkId = homeworkSaveDTO.getId();
|
||||||
|
final String classId = homeworkSaveDTO.getClassId();
|
||||||
|
final String courseId = homeworkSaveDTO.getCourseId();
|
||||||
|
final String sectionId = homeworkSaveDTO.getSectionId();
|
||||||
|
|
||||||
|
// 3. 处理章节关联:先清除旧关联,再新增(若提供)
|
||||||
|
try {
|
||||||
|
QueryWrapper<AiolEntityLink> delWrapper = new QueryWrapper<>();
|
||||||
|
delWrapper.eq("target_type", EntityLinkConst.TargetType.HOMEWORK)
|
||||||
|
.eq("target_id", homeworkId)
|
||||||
|
.eq("source_type", EntityLinkConst.SourceType.COURSE_SECTION);
|
||||||
|
entityLinkBizService.remove(delWrapper);
|
||||||
|
|
||||||
|
if (sectionId != null && !sectionId.trim().isEmpty()) {
|
||||||
|
entityLinkBizService.save(
|
||||||
|
EntityLinkConst.SourceType.COURSE_SECTION,
|
||||||
|
sectionId.trim(),
|
||||||
|
EntityLinkConst.TargetType.HOMEWORK,
|
||||||
|
homeworkId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("更新作业章节关联失败但不影响主体更新: homeworkId={}, error={}", homeworkId, e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 依据新的班级/课程范围为缺失的学生补齐提交记录(不删除已有)
|
||||||
|
try {
|
||||||
|
List<String> needStudentIds = new ArrayList<>();
|
||||||
|
if (classId != null && !classId.trim().isEmpty()) {
|
||||||
|
String[] classIds = classId.split(",");
|
||||||
|
for (String singleClassId : classIds) {
|
||||||
|
if (singleClassId == null || singleClassId.trim().isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
QueryWrapper<AiolClassStudent> csWrapper = new QueryWrapper<>();
|
||||||
|
csWrapper.eq("class_id", singleClassId.trim());
|
||||||
|
List<AiolClassStudent> classStudents = aiolClassStudentMapper.selectList(csWrapper);
|
||||||
|
for (AiolClassStudent cs : classStudents) {
|
||||||
|
String sid = cs.getStudentId();
|
||||||
|
if (sid != null && !sid.isEmpty() && !needStudentIds.contains(sid)) {
|
||||||
|
needStudentIds.add(sid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (courseId != null && !courseId.trim().isEmpty()) {
|
||||||
|
QueryWrapper<AiolCourseSignup> suWrapper = new QueryWrapper<>();
|
||||||
|
suWrapper.eq("course_id", courseId.trim());
|
||||||
|
List<AiolCourseSignup> signups = aiolCourseSignupMapper.selectList(suWrapper);
|
||||||
|
for (AiolCourseSignup su : signups) {
|
||||||
|
String sid = su.getUserId();
|
||||||
|
if (sid != null && !sid.isEmpty() && !needStudentIds.contains(sid)) {
|
||||||
|
needStudentIds.add(sid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 补齐缺失提交记录
|
||||||
|
if (!needStudentIds.isEmpty()) {
|
||||||
|
for (String sid : needStudentIds) {
|
||||||
|
QueryWrapper<AiolHomeworkSubmit> existWrapper = new QueryWrapper<>();
|
||||||
|
existWrapper.eq("homework_id", homeworkId).eq("student_id", sid);
|
||||||
|
long exist = homeworkSubmitService.count(existWrapper);
|
||||||
|
if (exist == 0) {
|
||||||
|
homeworkSubmitService.createEmptySubmit(homeworkId, sid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("补齐作业提交记录失败但不影响主体更新: homeworkId={}, error={}", homeworkId, e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("教师编辑作业成功: homeworkId={}", homeworkId);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("教师编辑作业失败: homeworkSaveDTO={}, error={}", homeworkSaveDTO, e.getMessage(), e);
|
||||||
|
return Result.error("编辑作业失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AutoLog(value = "作业-批阅")
|
||||||
|
@Operation(summary = "作业批阅", description = "教师批阅作业,更新作业提交记录的分数和状态")
|
||||||
|
@RequiresPermissions("aiol:aiol_homework:edit")
|
||||||
|
@PostMapping(value = "/review")
|
||||||
|
public Result<String> reviewHomework(@RequestBody Map<String, Object> reviewParams) {
|
||||||
|
try {
|
||||||
|
// 1. 从JSON参数中提取数据
|
||||||
|
String submitId = (String) reviewParams.get("submitId");
|
||||||
|
Integer score = (Integer) reviewParams.get("score");
|
||||||
|
String comment = (String) reviewParams.get("comment");
|
||||||
|
|
||||||
|
// 验证必填参数
|
||||||
|
if (submitId == null || submitId.trim().isEmpty()) {
|
||||||
|
return Result.error("submitId不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 查询作业提交记录
|
||||||
|
AiolHomeworkSubmit submit = homeworkSubmitService.getById(submitId);
|
||||||
|
if (submit == null) {
|
||||||
|
return Result.error("作业提交记录不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 更新作业提交记录
|
||||||
|
AiolHomeworkSubmit updateSubmit = new AiolHomeworkSubmit();
|
||||||
|
updateSubmit.setId(submitId);
|
||||||
|
|
||||||
|
// 设置分数(如果提供)
|
||||||
|
if (score != null) {
|
||||||
|
updateSubmit.setScore(score);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置评语(如果提供)
|
||||||
|
if (comment != null && !comment.trim().isEmpty()) {
|
||||||
|
updateSubmit.setComment(comment.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新状态为已批阅(3)
|
||||||
|
updateSubmit.setStatus(3);
|
||||||
|
|
||||||
|
// 4. 保存更新
|
||||||
|
boolean updated = homeworkSubmitService.updateById(updateSubmit);
|
||||||
|
if (!updated) {
|
||||||
|
return Result.error("批阅失败,更新作业提交记录失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("作业批阅成功: submitId={}, score={}, status=3", submitId, score);
|
||||||
|
return Result.OK("批阅成功!");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("作业批阅失败: reviewParams={}, error={}", reviewParams, e.getMessage(), e);
|
||||||
|
return Result.error("批阅失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将AiolHomework转换为包含详情的DTO
|
||||||
|
*
|
||||||
|
* @param homework 作业实体
|
||||||
|
* @return 包含班级名和章节信息的DTO
|
||||||
|
*/
|
||||||
|
private HomeworkWithDetailsDTO convertToHomeworkWithDetails(AiolHomework homework) {
|
||||||
|
HomeworkWithDetailsDTO dto = new HomeworkWithDetailsDTO();
|
||||||
|
BeanUtils.copyProperties(homework, dto);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 查询班级信息
|
||||||
|
List<String> classNames = new ArrayList<>();
|
||||||
|
String classId = homework.getClassId();
|
||||||
|
if (classId != null && !classId.trim().isEmpty()) {
|
||||||
|
String[] classIds = classId.split(",");
|
||||||
|
for (String singleClassId : classIds) {
|
||||||
|
if (singleClassId != null && !singleClassId.trim().isEmpty()) {
|
||||||
|
singleClassId = singleClassId.trim();
|
||||||
|
AiolClass aiolClass = aiolClassService.getById(singleClassId);
|
||||||
|
if (aiolClass != null && aiolClass.getName() != null) {
|
||||||
|
classNames.add(aiolClass.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dto.setClassNames(classNames);
|
||||||
|
|
||||||
|
// 2. 查询章节信息
|
||||||
|
List<String> sectionIds = entityLinkBizService.listSourceIds(
|
||||||
|
EntityLinkConst.TargetType.HOMEWORK,
|
||||||
|
homework.getId(),
|
||||||
|
EntityLinkConst.SourceType.COURSE_SECTION
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!sectionIds.isEmpty()) {
|
||||||
|
String sectionId = sectionIds.get(0); // 取第一个章节ID
|
||||||
|
dto.setSectionId(sectionId);
|
||||||
|
|
||||||
|
AiolCourseSection section = aiolCourseSectionService.getById(sectionId);
|
||||||
|
if (section != null && section.getName() != null) {
|
||||||
|
dto.setSectionTitle(section.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("转换作业详情失败: homeworkId={}, error={}", homework.getId(), e.getMessage(), e);
|
||||||
|
// 即使转换失败,也返回基本的作业信息
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,328 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolHomeworkSubmit;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolHomework;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolClass;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolClassStudent;
|
||||||
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolHomeworkSubmitService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolHomeworkService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolClassService;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolClassStudentMapper;
|
||||||
|
import org.jeecg.modules.system.service.ISysUserService;
|
||||||
|
import org.jeecg.modules.aiol.dto.HomeworkSubmitDetailDTO;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 作业提交
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="作业提交")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolHomeworkSubmit")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolHomeworkSubmitController extends JeecgController<AiolHomeworkSubmit, IAiolHomeworkSubmitService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolHomeworkSubmitService aiolHomeworkSubmitService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolHomeworkService aiolHomeworkService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolClassService aiolClassService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AiolClassStudentMapper aiolClassStudentMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISysUserService sysUserService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolHomeworkSubmit
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "作业提交-分页列表查询")
|
||||||
|
@Operation(summary="作业提交-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolHomeworkSubmit>> queryPageList(AiolHomeworkSubmit aiolHomeworkSubmit,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolHomeworkSubmit> queryWrapper = QueryGenerator.initQueryWrapper(aiolHomeworkSubmit, req.getParameterMap());
|
||||||
|
Page<AiolHomeworkSubmit> page = new Page<AiolHomeworkSubmit>(pageNo, pageSize);
|
||||||
|
IPage<AiolHomeworkSubmit> pageList = aiolHomeworkSubmitService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolHomeworkSubmit
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "作业提交-添加")
|
||||||
|
@Operation(summary="作业提交-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_homework_submit:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolHomeworkSubmit aiolHomeworkSubmit) {
|
||||||
|
aiolHomeworkSubmitService.save(aiolHomeworkSubmit);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolHomeworkSubmit
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "作业提交-编辑")
|
||||||
|
@Operation(summary="作业提交-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_homework_submit:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolHomeworkSubmit aiolHomeworkSubmit) {
|
||||||
|
aiolHomeworkSubmitService.updateById(aiolHomeworkSubmit);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "作业提交-通过id删除")
|
||||||
|
@Operation(summary="作业提交-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_homework_submit:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolHomeworkSubmitService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "作业提交-批量删除")
|
||||||
|
@Operation(summary="作业提交-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_homework_submit:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolHomeworkSubmitService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "作业提交-通过id查询")
|
||||||
|
@Operation(summary="作业提交-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolHomeworkSubmit> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolHomeworkSubmit aiolHomeworkSubmit = aiolHomeworkSubmitService.getById(id);
|
||||||
|
if(aiolHomeworkSubmit==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolHomeworkSubmit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolHomeworkSubmit
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_homework_submit:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolHomeworkSubmit aiolHomeworkSubmit) {
|
||||||
|
return super.exportXls(request, aiolHomeworkSubmit, AiolHomeworkSubmit.class, "作业提交");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_homework_submit:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolHomeworkSubmit.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AutoLog(value = "作业提交-查询作业提交情况")
|
||||||
|
@Operation(summary = "查询作业提交情况", description = "根据作业ID查询该作业的所有提交情况,包含作业信息、学生信息、班级信息")
|
||||||
|
@GetMapping(value = "/homework/{homeworkId}/submits")
|
||||||
|
public Result<List<HomeworkSubmitDetailDTO>> queryHomeworkSubmits(@PathVariable("homeworkId") String homeworkId) {
|
||||||
|
try {
|
||||||
|
// 1. 查询指定作业的所有提交记录
|
||||||
|
QueryWrapper<AiolHomeworkSubmit> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("homework_id", homeworkId)
|
||||||
|
.orderByDesc("create_time");
|
||||||
|
|
||||||
|
List<AiolHomeworkSubmit> submitList = aiolHomeworkSubmitService.list(queryWrapper);
|
||||||
|
|
||||||
|
if (submitList.isEmpty()) {
|
||||||
|
log.info("查询作业提交情况成功: homeworkId={}, 提交数量=0", homeworkId);
|
||||||
|
return Result.OK(new java.util.ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 查询作业信息
|
||||||
|
AiolHomework homework = aiolHomeworkService.getById(homeworkId);
|
||||||
|
if (homework == null) {
|
||||||
|
return Result.error("作业不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 提取所有学生ID
|
||||||
|
List<String> studentIds = submitList.stream()
|
||||||
|
.map(AiolHomeworkSubmit::getStudentId)
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 4. 批量查询学生信息
|
||||||
|
final Map<String, SysUser> studentMap;
|
||||||
|
if (!studentIds.isEmpty()) {
|
||||||
|
List<SysUser> students = sysUserService.listByIds(studentIds);
|
||||||
|
studentMap = students.stream()
|
||||||
|
.collect(Collectors.toMap(SysUser::getId, student -> student));
|
||||||
|
} else {
|
||||||
|
studentMap = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 查询学生班级关系
|
||||||
|
Map<String, AiolClass> studentClassMap = new HashMap<>();
|
||||||
|
if (!studentIds.isEmpty()) {
|
||||||
|
QueryWrapper<AiolClassStudent> classStudentWrapper = new QueryWrapper<>();
|
||||||
|
classStudentWrapper.in("student_id", studentIds);
|
||||||
|
List<AiolClassStudent> classStudents = aiolClassStudentMapper.selectList(classStudentWrapper);
|
||||||
|
|
||||||
|
if (!classStudents.isEmpty()) {
|
||||||
|
// 提取班级ID
|
||||||
|
List<String> classIds = classStudents.stream()
|
||||||
|
.map(AiolClassStudent::getClassId)
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 批量查询班级信息
|
||||||
|
List<AiolClass> classes = aiolClassService.listByIds(classIds);
|
||||||
|
Map<String, AiolClass> classMap = classes.stream()
|
||||||
|
.collect(Collectors.toMap(AiolClass::getId, cls -> cls));
|
||||||
|
|
||||||
|
// 建立学生到班级的映射
|
||||||
|
for (AiolClassStudent classStudent : classStudents) {
|
||||||
|
AiolClass cls = classMap.get(classStudent.getClassId());
|
||||||
|
if (cls != null) {
|
||||||
|
studentClassMap.put(classStudent.getStudentId(), cls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 组装结果
|
||||||
|
List<HomeworkSubmitDetailDTO> resultList = submitList.stream()
|
||||||
|
.map(submit -> {
|
||||||
|
HomeworkSubmitDetailDTO dto = new HomeworkSubmitDetailDTO();
|
||||||
|
|
||||||
|
// 复制提交信息
|
||||||
|
dto.setId(submit.getId());
|
||||||
|
dto.setHomeworkId(submit.getHomeworkId());
|
||||||
|
dto.setStudentId(submit.getStudentId());
|
||||||
|
dto.setContent(submit.getContent());
|
||||||
|
dto.setAttachment(submit.getAttachment());
|
||||||
|
dto.setScore(submit.getScore());
|
||||||
|
dto.setComment(submit.getComment());
|
||||||
|
dto.setStatus(submit.getStatus());
|
||||||
|
dto.setCreateTime(submit.getCreateTime());
|
||||||
|
dto.setUpdateTime(submit.getUpdateTime());
|
||||||
|
|
||||||
|
// 设置作业信息
|
||||||
|
dto.setHomeworkTitle(homework.getTitle());
|
||||||
|
dto.setHomeworkDescription(homework.getDescription());
|
||||||
|
dto.setHomeworkMaxScore(homework.getMaxScore());
|
||||||
|
dto.setHomeworkPassScore(homework.getPassScore());
|
||||||
|
dto.setHomeworkStartTime(homework.getStartTime());
|
||||||
|
dto.setHomeworkEndTime(homework.getEndTime());
|
||||||
|
dto.setHomeworkStatus(homework.getStatus());
|
||||||
|
dto.setHomeworkNotifyTime(homework.getNotifyTime());
|
||||||
|
dto.setHomeworkAllowMakeup(homework.getAllowMakeup());
|
||||||
|
dto.setHomeworkMakeupTime(homework.getMakeupTime());
|
||||||
|
|
||||||
|
// 设置学生信息
|
||||||
|
SysUser student = studentMap.get(submit.getStudentId());
|
||||||
|
if (student != null) {
|
||||||
|
dto.setStudentUsername(student.getUsername());
|
||||||
|
dto.setStudentRealname(student.getRealname());
|
||||||
|
dto.setStudentAvatar(student.getAvatar());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置班级信息
|
||||||
|
AiolClass cls = studentClassMap.get(submit.getStudentId());
|
||||||
|
if (cls != null) {
|
||||||
|
dto.setClassId(cls.getId());
|
||||||
|
dto.setClassName(cls.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
log.info("查询作业提交情况成功: homeworkId={}, 提交数量={}", homeworkId, resultList.size());
|
||||||
|
return Result.OK(resultList);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询作业提交情况失败: homeworkId={}, error={}", homeworkId, e.getMessage(), e);
|
||||||
|
return Result.error("查询作业提交情况失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,166 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.config.shiro.IgnoreAuth;
|
||||||
|
import org.jeecg.modules.aiol.dto.CommentWithUserInfo;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolContentConfig;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolCourse;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolContentConfigMapper;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolCourseMapper;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolCommentService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.data.redis.core.ZSetOperations;
|
||||||
|
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 java.util.*;
|
||||||
|
|
||||||
|
@Tag(name = "首页")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/index")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolIndexController {
|
||||||
|
@Autowired
|
||||||
|
private AiolContentConfigMapper contentConfigMapper;
|
||||||
|
@Autowired
|
||||||
|
private IAiolCommentService commentBizService;
|
||||||
|
@Autowired(required = false)
|
||||||
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
@Autowired
|
||||||
|
private AiolCourseMapper courseMapper;
|
||||||
|
|
||||||
|
private static final String HOT_SEARCH_ZSET_KEY = "hot:search";
|
||||||
|
|
||||||
|
@GetMapping("/content")
|
||||||
|
@Operation(summary = "查询首页内容")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<String> queryContent(@RequestParam String contentKey) {
|
||||||
|
AiolContentConfig contentConfig = contentConfigMapper.selectOne(new QueryWrapper<AiolContentConfig>().eq("content_key", contentKey));
|
||||||
|
if (contentConfig == null) {
|
||||||
|
return Result.error("内容配置不存在");
|
||||||
|
}
|
||||||
|
return Result.OK(contentConfig.getContentValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/statistics")
|
||||||
|
@Operation(summary = "查询首页数据统计")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<Map<String, Object>> queryStatistics() {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
|
||||||
|
// 定义统计项的配置键
|
||||||
|
String[] statisticsKeys = {"xxsp", "mszj", "pxjc", "zysc", "zxsy"};
|
||||||
|
|
||||||
|
// 从配置表查询每个统计项的值
|
||||||
|
for (String key : statisticsKeys) {
|
||||||
|
AiolContentConfig contentConfig = contentConfigMapper.selectOne(
|
||||||
|
new QueryWrapper<AiolContentConfig>().eq("content_key", key)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (contentConfig != null && contentConfig.getContentValue() != null) {
|
||||||
|
try {
|
||||||
|
// 尝试解析为数字,如果失败则使用默认值0
|
||||||
|
Integer value = Integer.parseInt(contentConfig.getContentValue());
|
||||||
|
map.put(key, value);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.warn("配置项 {} 的值 {} 不是有效数字,使用默认值0", key, contentConfig.getContentValue());
|
||||||
|
map.put(key, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("配置项 {} 不存在,使用默认值0", key);
|
||||||
|
map.put(key, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.OK(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/selected_comments")
|
||||||
|
@Operation(summary = "查询精选评论")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<CommentWithUserInfo>> querySelectedComments() {
|
||||||
|
// 查询精选评论(包含用户信息)
|
||||||
|
List<CommentWithUserInfo> comments = commentBizService.getAllSelectedComments();
|
||||||
|
return Result.OK(comments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/hot_search")
|
||||||
|
@Operation(summary = "查询热门搜索记录(关键词+搜索次数,Redis ZSet 排名)")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<Map<String, Object>>> queryHotSearch(@RequestParam(defaultValue = "10") Integer limit) {
|
||||||
|
if (limit == null || limit <= 0) {
|
||||||
|
limit = 10;
|
||||||
|
}
|
||||||
|
if (stringRedisTemplate == null) {
|
||||||
|
return Result.error("Redis 未配置,无法查询热门搜索");
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<ZSetOperations.TypedTuple<String>> tuples = stringRedisTemplate.opsForZSet()
|
||||||
|
.reverseRangeWithScores(HOT_SEARCH_ZSET_KEY, 0, limit - 1);
|
||||||
|
|
||||||
|
List<Map<String, Object>> result = new ArrayList<>();
|
||||||
|
if (tuples != null) {
|
||||||
|
for (ZSetOperations.TypedTuple<String> tuple : tuples) {
|
||||||
|
if (tuple == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Map<String, Object> item = new HashMap<>();
|
||||||
|
item.put("keyword", tuple.getValue());
|
||||||
|
item.put("count", tuple.getScore() == null ? 0 : tuple.getScore().longValue());
|
||||||
|
result.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.OK(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/search")
|
||||||
|
@Operation(summary = "全局搜索(课程:name/description/school)")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<AiolCourse>> globalSearch(
|
||||||
|
@RequestParam String keyword,
|
||||||
|
@RequestParam(required = false, defaultValue = "20") Integer limit
|
||||||
|
) {
|
||||||
|
if (limit == null || limit <= 0) {
|
||||||
|
limit = 20;
|
||||||
|
}
|
||||||
|
if (limit > 100) {
|
||||||
|
limit = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyword == null || keyword.trim().isEmpty()) {
|
||||||
|
return Result.OK(new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyword.trim().length() < 2) {
|
||||||
|
return Result.error("关键词长度至少为2个字符");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 记录关键词到 Redis 热搜
|
||||||
|
if (stringRedisTemplate != null) {
|
||||||
|
try {
|
||||||
|
stringRedisTemplate.opsForZSet().incrementScore(HOT_SEARCH_ZSET_KEY, keyword.trim(), 1D);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("记录热搜关键词到 Redis 失败: {}", keyword, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String kw = keyword.trim();
|
||||||
|
QueryWrapper<AiolCourse> wrapper = new QueryWrapper<>();
|
||||||
|
wrapper.lambda()
|
||||||
|
.like(AiolCourse::getName, kw)
|
||||||
|
.or()
|
||||||
|
.like(AiolCourse::getDescription, kw)
|
||||||
|
.or()
|
||||||
|
.like(AiolCourse::getSchool, kw);
|
||||||
|
|
||||||
|
List<AiolCourse> list = courseMapper.selectList(wrapper.last("limit " + limit));
|
||||||
|
return Result.OK(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,182 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolLearnProgress;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolLearnProgressService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 学习进度
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="学习进度")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolLearnProgress")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolLearnProgressController extends JeecgController<AiolLearnProgress, IAiolLearnProgressService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolLearnProgressService aiolLearnProgressService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolLearnProgress
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "学习进度-分页列表查询")
|
||||||
|
@Operation(summary="学习进度-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolLearnProgress>> queryPageList(AiolLearnProgress aiolLearnProgress,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolLearnProgress> queryWrapper = QueryGenerator.initQueryWrapper(aiolLearnProgress, req.getParameterMap());
|
||||||
|
Page<AiolLearnProgress> page = new Page<AiolLearnProgress>(pageNo, pageSize);
|
||||||
|
IPage<AiolLearnProgress> pageList = aiolLearnProgressService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolLearnProgress
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "学习进度-添加")
|
||||||
|
@Operation(summary="学习进度-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_learn_progress:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolLearnProgress aiolLearnProgress) {
|
||||||
|
aiolLearnProgressService.save(aiolLearnProgress);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolLearnProgress
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "学习进度-编辑")
|
||||||
|
@Operation(summary="学习进度-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_learn_progress:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolLearnProgress aiolLearnProgress) {
|
||||||
|
aiolLearnProgressService.updateById(aiolLearnProgress);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "学习进度-通过id删除")
|
||||||
|
@Operation(summary="学习进度-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_learn_progress:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolLearnProgressService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "学习进度-批量删除")
|
||||||
|
@Operation(summary="学习进度-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_learn_progress:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolLearnProgressService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "学习进度-通过id查询")
|
||||||
|
@Operation(summary="学习进度-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolLearnProgress> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolLearnProgress aiolLearnProgress = aiolLearnProgressService.getById(id);
|
||||||
|
if(aiolLearnProgress==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolLearnProgress);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolLearnProgress
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_learn_progress:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolLearnProgress aiolLearnProgress) {
|
||||||
|
return super.exportXls(request, aiolLearnProgress, AiolLearnProgress.class, "学习进度");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_learn_progress:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolLearnProgress.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,229 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.config.shiro.IgnoreAuth;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolMenu;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolMenuService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 前台菜单
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-29
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="前台菜单")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolMenu")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolMenuController extends JeecgController<AiolMenu, IAiolMenuService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolMenuService aiolMenuService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolMenu
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "前台菜单-分页列表查询")
|
||||||
|
@Operation(summary="前台菜单-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolMenu>> queryPageList(AiolMenu aiolMenu,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolMenu> queryWrapper = QueryGenerator.initQueryWrapper(aiolMenu, req.getParameterMap());
|
||||||
|
Page<AiolMenu> page = new Page<AiolMenu>(pageNo, pageSize);
|
||||||
|
IPage<AiolMenu> pageList = aiolMenuService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolMenu
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "前台菜单-添加")
|
||||||
|
@Operation(summary="前台菜单-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_menu:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolMenu aiolMenu) {
|
||||||
|
aiolMenuService.save(aiolMenu);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolMenu
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "前台菜单-编辑")
|
||||||
|
@Operation(summary="前台菜单-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_menu:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolMenu aiolMenu) {
|
||||||
|
aiolMenuService.updateById(aiolMenu);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "前台菜单-通过id删除")
|
||||||
|
@Operation(summary="前台菜单-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_menu:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolMenuService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "前台菜单-批量删除")
|
||||||
|
@Operation(summary="前台菜单-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_menu:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolMenuService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "前台菜单-通过id查询")
|
||||||
|
@Operation(summary="前台菜单-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolMenu> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolMenu aiolMenu = aiolMenuService.getById(id);
|
||||||
|
if(aiolMenu==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolMenu
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_menu:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolMenu aiolMenu) {
|
||||||
|
return super.exportXls(request, aiolMenu, AiolMenu.class, "前台菜单");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_menu:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolMenu.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取前台菜单
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Operation(summary="获取前台菜单")
|
||||||
|
@GetMapping(value = "/getIndexMenus")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<AiolMenu>> getIndexMenus() {
|
||||||
|
QueryWrapper<AiolMenu> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("type", "index")
|
||||||
|
.eq("iz_visible", 1)
|
||||||
|
.orderByDesc("sort_order");
|
||||||
|
List<AiolMenu> menuList = aiolMenuService.list(queryWrapper);
|
||||||
|
return Result.OK(menuList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary="获取学员端菜单")
|
||||||
|
@GetMapping(value = "/getStudentMenus")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<AiolMenu>> getStudentMenus() {
|
||||||
|
QueryWrapper<AiolMenu> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("type", "student")
|
||||||
|
.eq("iz_visible", 1)
|
||||||
|
.orderByDesc("sort_order");
|
||||||
|
List<AiolMenu> menuList = aiolMenuService.list(queryWrapper);
|
||||||
|
return Result.OK(menuList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取教师端菜单
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Operation(summary="获取教师端菜单")
|
||||||
|
@GetMapping(value = "/getTeacherMenus")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<AiolMenu>> getTeacherMenus() {
|
||||||
|
QueryWrapper<AiolMenu> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("type", "teacher")
|
||||||
|
.eq("iz_visible", 1)
|
||||||
|
.orderByDesc("sort_order");
|
||||||
|
List<AiolMenu> menuList = aiolMenuService.list(queryWrapper);
|
||||||
|
return Result.OK(menuList);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,262 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
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.RestController;
|
||||||
|
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.apache.shiro.SecurityUtils;
|
||||||
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||||
|
import org.jeecg.modules.system.model.AnnouncementSendModel;
|
||||||
|
import org.jeecg.modules.system.service.ISysAnnouncementSendService;
|
||||||
|
import org.jeecg.modules.system.service.ISysAnnouncementService;
|
||||||
|
import org.jeecg.modules.system.entity.SysAnnouncementSend;
|
||||||
|
import org.jeecg.modules.system.entity.SysAnnouncement;
|
||||||
|
import org.jeecg.modules.aiol.utils.MessageNotificationUtil;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Date;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/message")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolMessageController {
|
||||||
|
@Autowired
|
||||||
|
private ISysAnnouncementSendService sysAnnouncementSendService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISysAnnouncementService sysAnnouncementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MessageNotificationUtil messageNotificationUtil;
|
||||||
|
|
||||||
|
@GetMapping("/test")
|
||||||
|
public void test() {
|
||||||
|
// 测试评论通知
|
||||||
|
messageNotificationUtil.sendCommentNotification(
|
||||||
|
"202121200873", // 接收用户ID
|
||||||
|
"202121200874", // 发送用户ID
|
||||||
|
"1966804797404344321", // 发送者ID
|
||||||
|
"小明", // 发送者用户名
|
||||||
|
456L, // 评论ID
|
||||||
|
"老师讲得真棒![user:789:李四] 快来看这个课程!", // 评论内容
|
||||||
|
"course", // 实体类型
|
||||||
|
"1954463468539371522", // 实体ID
|
||||||
|
"python语言基础与应用", // 实体标题
|
||||||
|
"2025-09-16T15:30:00Z" // 操作时间
|
||||||
|
);
|
||||||
|
|
||||||
|
// 测试点赞通知
|
||||||
|
messageNotificationUtil.sendLikeNotification(
|
||||||
|
"202121200873", // 接收用户ID
|
||||||
|
"202121200874", // 发送用户ID
|
||||||
|
"202121200874", // 发送者ID
|
||||||
|
"202121200874", // 发送者用户名
|
||||||
|
"course", // 实体类型
|
||||||
|
"1954463468539371522", // 实体ID
|
||||||
|
"python语言基础与应用", // 实体标题
|
||||||
|
"like", // 操作类型
|
||||||
|
"2025-09-16T15:35:00Z" // 操作时间
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/comments_at")
|
||||||
|
public Result<IPage<AnnouncementSendModel>> queryCommentsAndAt(
|
||||||
|
AnnouncementSendModel model,
|
||||||
|
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
|
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||||
|
try {
|
||||||
|
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||||
|
String userId = sysUser.getId();
|
||||||
|
model.setUserId(userId);
|
||||||
|
model.setPageNo((pageNo - 1) * pageSize);
|
||||||
|
model.setPageSize(pageSize);
|
||||||
|
// 处理时间范围与SysAnnouncementSendController一致
|
||||||
|
if (StringUtils.isNotEmpty(model.getSendTimeBegin())) {
|
||||||
|
model.setSendTimeBegin(model.getSendTimeBegin() + " 00:00:00");
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(model.getSendTimeEnd())) {
|
||||||
|
model.setSendTimeEnd(model.getSendTimeEnd() + " 23:59:59");
|
||||||
|
}
|
||||||
|
// 评论和@ 消息类别 = 3
|
||||||
|
model.setMsgCategory("3");
|
||||||
|
|
||||||
|
Page<AnnouncementSendModel> page = new Page<>(pageNo, pageSize);
|
||||||
|
IPage<AnnouncementSendModel> pageList = sysAnnouncementSendService.getMyAnnouncementSendPage(page, model);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error("查询评论/@消息失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/likes")
|
||||||
|
public Result<IPage<AnnouncementSendModel>> queryLikes(
|
||||||
|
AnnouncementSendModel model,
|
||||||
|
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
|
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||||
|
try {
|
||||||
|
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||||
|
String userId = sysUser.getId();
|
||||||
|
model.setUserId(userId);
|
||||||
|
model.setPageNo((pageNo - 1) * pageSize);
|
||||||
|
model.setPageSize(pageSize);
|
||||||
|
if (StringUtils.isNotEmpty(model.getSendTimeBegin())) {
|
||||||
|
model.setSendTimeBegin(model.getSendTimeBegin() + " 00:00:00");
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(model.getSendTimeEnd())) {
|
||||||
|
model.setSendTimeEnd(model.getSendTimeEnd() + " 23:59:59");
|
||||||
|
}
|
||||||
|
// 点赞 消息类别 = 4
|
||||||
|
model.setMsgCategory("4");
|
||||||
|
|
||||||
|
Page<AnnouncementSendModel> page = new Page<>(pageNo, pageSize);
|
||||||
|
IPage<AnnouncementSendModel> pageList = sysAnnouncementSendService.getMyAnnouncementSendPage(page, model);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error("查询点赞消息失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/system")
|
||||||
|
public Result<IPage<AnnouncementSendModel>> querySystemMessages(
|
||||||
|
AnnouncementSendModel model,
|
||||||
|
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
|
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||||
|
try {
|
||||||
|
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||||
|
String userId = sysUser.getId();
|
||||||
|
model.setUserId(userId);
|
||||||
|
model.setPageNo((pageNo - 1) * pageSize);
|
||||||
|
model.setPageSize(pageSize);
|
||||||
|
// 处理时间范围与SysAnnouncementSendController一致
|
||||||
|
if (StringUtils.isNotEmpty(model.getSendTimeBegin())) {
|
||||||
|
model.setSendTimeBegin(model.getSendTimeBegin() + " 00:00:00");
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(model.getSendTimeEnd())) {
|
||||||
|
model.setSendTimeEnd(model.getSendTimeEnd() + " 23:59:59");
|
||||||
|
}
|
||||||
|
// 系统消息 消息类别 = 2
|
||||||
|
model.setMsgCategory("2");
|
||||||
|
|
||||||
|
Page<AnnouncementSendModel> page = new Page<>(pageNo, pageSize);
|
||||||
|
IPage<AnnouncementSendModel> pageList = sysAnnouncementSendService.getMyAnnouncementSendPage(page, model);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error("查询系统消息失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/unread_count")
|
||||||
|
public Result<Map<String, Object>> queryUnreadMessageCount() {
|
||||||
|
try {
|
||||||
|
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||||
|
String userId = sysUser.getId();
|
||||||
|
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
|
// 1. 先查询用户所有未读消息的annt_id
|
||||||
|
QueryWrapper<SysAnnouncementSend> unreadWrapper = new QueryWrapper<>();
|
||||||
|
unreadWrapper.eq("user_id", userId)
|
||||||
|
.or().eq("user_id", sysUser.getUsername())
|
||||||
|
.eq("read_flag", 0);
|
||||||
|
List<SysAnnouncementSend> unreadMessages = sysAnnouncementSendService.list(unreadWrapper);
|
||||||
|
|
||||||
|
if (unreadMessages.isEmpty()) {
|
||||||
|
// 如果没有未读消息,返回0
|
||||||
|
result.put("commentsUnreadCount", 0);
|
||||||
|
result.put("likesUnreadCount", 0);
|
||||||
|
result.put("systemUnreadCount", 0);
|
||||||
|
result.put("totalUnreadCount", 0);
|
||||||
|
return Result.OK(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 提取所有annt_id
|
||||||
|
List<String> anntIds = unreadMessages.stream()
|
||||||
|
.map(SysAnnouncementSend::getAnntId)
|
||||||
|
.collect(java.util.stream.Collectors.toList());
|
||||||
|
|
||||||
|
// 3. 根据annt_id查询对应的消息详情,获取msg_category
|
||||||
|
QueryWrapper<SysAnnouncement> announcementWrapper = new QueryWrapper<>();
|
||||||
|
announcementWrapper.in("id", anntIds);
|
||||||
|
List<SysAnnouncement> announcements = sysAnnouncementService.list(announcementWrapper);
|
||||||
|
|
||||||
|
// 4. 按msg_category分类统计
|
||||||
|
long commentsUnreadCount = 0; // msg_category=3
|
||||||
|
long likesUnreadCount = 0; // msg_category=4
|
||||||
|
long systemUnreadCount = 0; // msg_category=2
|
||||||
|
|
||||||
|
for (SysAnnouncement announcement : announcements) {
|
||||||
|
String msgCategory = announcement.getMsgCategory();
|
||||||
|
if ("3".equals(msgCategory)) {
|
||||||
|
commentsUnreadCount++;
|
||||||
|
} else if ("4".equals(msgCategory)) {
|
||||||
|
likesUnreadCount++;
|
||||||
|
} else if ("2".equals(msgCategory)) {
|
||||||
|
systemUnreadCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 计算总未读数量
|
||||||
|
long totalUnreadCount = commentsUnreadCount + likesUnreadCount + systemUnreadCount;
|
||||||
|
|
||||||
|
result.put("commentsUnreadCount", commentsUnreadCount);
|
||||||
|
result.put("likesUnreadCount", likesUnreadCount);
|
||||||
|
result.put("systemUnreadCount", systemUnreadCount);
|
||||||
|
result.put("totalUnreadCount", totalUnreadCount);
|
||||||
|
|
||||||
|
return Result.OK(result);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error("查询未读消息数量失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @功能:标记单条消息已读
|
||||||
|
* @param sendId 消息发送记录ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping(value = "/readOne")
|
||||||
|
public Result<SysAnnouncementSend> readOne(@RequestParam(name = "sendId", required = true) String sendId) {
|
||||||
|
Result<SysAnnouncementSend> result = new Result<SysAnnouncementSend>();
|
||||||
|
try {
|
||||||
|
if (StringUtils.isEmpty(sendId)) {
|
||||||
|
result.error500("消息ID不能为空");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建更新条件:根据sendId和userId更新单条消息
|
||||||
|
LambdaUpdateWrapper<SysAnnouncementSend> updateWrapper = new UpdateWrapper<SysAnnouncementSend>().lambda();
|
||||||
|
updateWrapper.set(SysAnnouncementSend::getReadFlag, CommonConstant.HAS_READ_FLAG);
|
||||||
|
updateWrapper.set(SysAnnouncementSend::getReadTime, new Date());
|
||||||
|
updateWrapper.eq(SysAnnouncementSend::getId, sendId);
|
||||||
|
|
||||||
|
SysAnnouncementSend announcementSend = new SysAnnouncementSend();
|
||||||
|
boolean updateResult = sysAnnouncementSendService.update(announcementSend, updateWrapper);
|
||||||
|
|
||||||
|
if (updateResult) {
|
||||||
|
result.setSuccess(true);
|
||||||
|
result.setMessage("消息已标记为已读");
|
||||||
|
} else {
|
||||||
|
result.error500("标记已读失败,可能消息不存在或已被标记");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("标记单条消息已读失败: " + e.getMessage(), e);
|
||||||
|
result.error500("标记已读失败: " + e.getMessage());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,184 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolPaper;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolPaperService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 试卷
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="试卷")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolPaper")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolPaperController extends JeecgController<AiolPaper, IAiolPaperService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolPaperService aiolPaperService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolPaper
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Operation(summary="试卷-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<Map<String, Object>>> queryPageList(AiolPaper aiolPaper,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
QueryWrapper<AiolPaper> queryWrapper = QueryGenerator.initQueryWrapper(aiolPaper, req.getParameterMap());
|
||||||
|
Page<Map<String, Object>> page = new Page<>(pageNo, pageSize);
|
||||||
|
|
||||||
|
queryWrapper.select("aiol_paper.*", "(SELECT realname FROM sys_user WHERE username = aiol_paper.create_by) as createByName");
|
||||||
|
|
||||||
|
IPage<Map<String, Object>> pageList = aiolPaperService.pageMaps(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolPaper
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "试卷-添加")
|
||||||
|
@Operation(summary="试卷-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_paper:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolPaper aiolPaper) {
|
||||||
|
aiolPaperService.save(aiolPaper);
|
||||||
|
|
||||||
|
return Result.OK(aiolPaper.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolPaper
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "试卷-编辑")
|
||||||
|
@Operation(summary="试卷-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_paper:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolPaper aiolPaper) {
|
||||||
|
aiolPaperService.updateById(aiolPaper);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "试卷-通过id删除")
|
||||||
|
@Operation(summary="试卷-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_paper:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolPaperService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "试卷-批量删除")
|
||||||
|
@Operation(summary="试卷-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_paper:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolPaperService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "试卷-通过id查询")
|
||||||
|
@Operation(summary="试卷-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolPaper> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolPaper aiolPaper = aiolPaperService.getById(id);
|
||||||
|
if(aiolPaper==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolPaper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolPaper
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_paper:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolPaper aiolPaper) {
|
||||||
|
return super.exportXls(request, aiolPaper, AiolPaper.class, "试卷");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_paper:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolPaper.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,328 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.modules.aiol.dto.QuestionAnswerDTO;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolPaperQuestion;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolQuestion;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolQuestionAnswer;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolQuestionOption;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolPaperQuestionService;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolQuestionAnswerService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolQuestionOptionService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolQuestionService;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 试卷试题
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="试卷试题")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolPaperQuestion")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolPaperQuestionController extends JeecgController<AiolPaperQuestion, IAiolPaperQuestionService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolPaperQuestionService aiolPaperQuestionService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolQuestionService aiolQuestionService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolQuestionAnswerService answerService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolQuestionOptionService optionService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolPaperQuestion
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "试卷试题-分页列表查询")
|
||||||
|
@Operation(summary="试卷试题-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolPaperQuestion>> queryPageList(AiolPaperQuestion aiolPaperQuestion,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolPaperQuestion> queryWrapper = QueryGenerator.initQueryWrapper(aiolPaperQuestion, req.getParameterMap());
|
||||||
|
Page<AiolPaperQuestion> page = new Page<AiolPaperQuestion>(pageNo, pageSize);
|
||||||
|
IPage<AiolPaperQuestion> pageList = aiolPaperQuestionService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolPaperQuestion
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "试卷试题-添加")
|
||||||
|
@Operation(summary="试卷试题-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_paper_question:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolPaperQuestion aiolPaperQuestion) {
|
||||||
|
boolean isScoreNaN = false;
|
||||||
|
//获取试题及其子题目,分数
|
||||||
|
List<AiolPaperQuestion> paperQuestions = new ArrayList<>();
|
||||||
|
AiolQuestion question = aiolQuestionService.getById(aiolPaperQuestion.getQuestionId());
|
||||||
|
if(aiolPaperQuestion.getScore().isNaN()){
|
||||||
|
isScoreNaN = true;
|
||||||
|
aiolPaperQuestion.setScore(Double.valueOf(question.getScore()));
|
||||||
|
}
|
||||||
|
paperQuestions.add(aiolPaperQuestion);
|
||||||
|
if( question.getType() == 5 ){
|
||||||
|
//如果试题类型为复合题,则获取其子题目
|
||||||
|
LambdaQueryWrapper<AiolQuestion> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(AiolQuestion::getParentId, question.getId());
|
||||||
|
List<AiolQuestion> questions = aiolQuestionService.list(queryWrapper);
|
||||||
|
for(AiolQuestion q : questions){
|
||||||
|
AiolPaperQuestion sonPaperQuestion = new AiolPaperQuestion();
|
||||||
|
sonPaperQuestion.setPaperId(aiolPaperQuestion.getPaperId());
|
||||||
|
sonPaperQuestion.setQuestionId(q.getId());
|
||||||
|
sonPaperQuestion.setOrderNo(aiolPaperQuestion.getOrderNo());
|
||||||
|
if(isScoreNaN){
|
||||||
|
sonPaperQuestion.setScore(Double.valueOf(q.getScore()));
|
||||||
|
}else{
|
||||||
|
// 计算原始分数
|
||||||
|
double rawScore = aiolPaperQuestion.getScore() * q.getScore() / question.getScore();
|
||||||
|
// 四舍五入保留两位小数
|
||||||
|
BigDecimal bd = new BigDecimal(rawScore);
|
||||||
|
bd = bd.setScale(2, RoundingMode.HALF_UP);
|
||||||
|
sonPaperQuestion.setScore(bd.doubleValue());
|
||||||
|
}
|
||||||
|
paperQuestions.add(sonPaperQuestion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aiolPaperQuestionService.saveBatch(paperQuestions);
|
||||||
|
|
||||||
|
return Result.OK(aiolPaperQuestion.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolPaperQuestion
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "试卷试题-编辑")
|
||||||
|
@Operation(summary="试卷试题-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_paper_question:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolPaperQuestion aiolPaperQuestion) {
|
||||||
|
aiolPaperQuestionService.updateById(aiolPaperQuestion);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "试卷试题-通过id删除")
|
||||||
|
@Operation(summary="试卷试题-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_paper_question:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
@Transactional
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolPaperQuestion byId = aiolPaperQuestionService.getById(id);
|
||||||
|
//如果试题类型为复合题,则删除其子题目
|
||||||
|
List<AiolQuestion> list = aiolQuestionService.list(
|
||||||
|
new LambdaQueryWrapper<AiolQuestion>().
|
||||||
|
eq(AiolQuestion::getParentId, byId.getQuestionId()));
|
||||||
|
if(!list.isEmpty()){
|
||||||
|
aiolPaperQuestionService.remove(
|
||||||
|
new LambdaQueryWrapper<AiolPaperQuestion>().
|
||||||
|
eq(AiolPaperQuestion::getPaperId, byId.getPaperId())
|
||||||
|
.in(AiolPaperQuestion::getQuestionId, list.stream().map(AiolQuestion::getId).collect(Collectors.toList()))
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
aiolPaperQuestionService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "试卷试题-批量删除")
|
||||||
|
@Operation(summary="试卷试题-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_paper_question:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolPaperQuestionService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "试卷试题-通过id查询")
|
||||||
|
@Operation(summary="试卷试题-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolPaperQuestion> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolPaperQuestion aiolPaperQuestion = aiolPaperQuestionService.getById(id);
|
||||||
|
if(aiolPaperQuestion==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolPaperQuestion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolPaperQuestion
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_paper_question:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolPaperQuestion aiolPaperQuestion) {
|
||||||
|
return super.exportXls(request, aiolPaperQuestion, AiolPaperQuestion.class, "试卷试题");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_paper_question:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolPaperQuestion.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/paperDetail/{paperId}")
|
||||||
|
@Operation(summary = "查询试卷所有题目详情")
|
||||||
|
public Result<?> paperDetail(@PathVariable String paperId) {
|
||||||
|
List<AiolPaperQuestion> list = aiolPaperQuestionService.list(new LambdaQueryWrapper<AiolPaperQuestion>().eq(AiolPaperQuestion::getPaperId, paperId));
|
||||||
|
// 收集所有需要的 questionId
|
||||||
|
List<String> questionIds = list.stream()
|
||||||
|
.map(AiolPaperQuestion::getQuestionId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if(questionIds.isEmpty()){
|
||||||
|
return Result.error("试卷没有题目");
|
||||||
|
}
|
||||||
|
return Result.OK(convertToQuestionAnswerDTO(questionIds,aiolQuestionService,optionService,answerService));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将题目列表转换为题目答案DTO映射
|
||||||
|
*
|
||||||
|
* @param questionIds 题目id列表
|
||||||
|
* @param aiolQuestionService 题目服务
|
||||||
|
* @param optionService 选项服务
|
||||||
|
* @param answerService 答案服务
|
||||||
|
* @return 题目答案DTO映射,key为题目ID
|
||||||
|
*/
|
||||||
|
public static Collection<QuestionAnswerDTO> convertToQuestionAnswerDTO(
|
||||||
|
List<String> questionIds,
|
||||||
|
IAiolQuestionService aiolQuestionService,
|
||||||
|
IAiolQuestionOptionService optionService,
|
||||||
|
IAiolQuestionAnswerService answerService) {
|
||||||
|
|
||||||
|
// 批量查询所有题目
|
||||||
|
List<AiolQuestion> questions = aiolQuestionService.listByIds(questionIds);
|
||||||
|
|
||||||
|
// 分离选项和答案的ID
|
||||||
|
List<String> optionIds = new ArrayList<>();
|
||||||
|
List<String> answerIds = new ArrayList<>();
|
||||||
|
for (AiolQuestion question : questions) {
|
||||||
|
if (question.getType() >= 0 && question.getType() <= 2) {
|
||||||
|
optionIds.add(question.getId());
|
||||||
|
} else if (question.getType() == 3 || question.getType() == 4) {
|
||||||
|
answerIds.add(question.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量查询选项和答案
|
||||||
|
List<AiolQuestionOption> questionOptions = Collections.emptyList();
|
||||||
|
List<AiolQuestionAnswer> questionAnswers = Collections.emptyList();
|
||||||
|
|
||||||
|
if (!optionIds.isEmpty()) {
|
||||||
|
questionOptions = optionService.list(new LambdaQueryWrapper<AiolQuestionOption>().in(AiolQuestionOption::getQuestionId, optionIds));
|
||||||
|
}
|
||||||
|
if (!answerIds.isEmpty()) {
|
||||||
|
questionAnswers = answerService.list(new LambdaQueryWrapper<AiolQuestionAnswer>().in(AiolQuestionAnswer::getQuestionId, answerIds));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建题目id的映射
|
||||||
|
Map<String, List<AiolQuestionOption>> optionMap = questionOptions.stream()
|
||||||
|
.collect(Collectors.groupingBy(AiolQuestionOption::getQuestionId));
|
||||||
|
Map<String, List<AiolQuestionAnswer>> answerMap = questionAnswers.stream()
|
||||||
|
.collect(Collectors.groupingBy(AiolQuestionAnswer::getQuestionId));
|
||||||
|
|
||||||
|
// 构建结果列表
|
||||||
|
Map<String, QuestionAnswerDTO> result = new HashMap<>();
|
||||||
|
Map<String, List<QuestionAnswerDTO>> children = new HashMap<>();
|
||||||
|
|
||||||
|
for (AiolQuestion question : questions) {
|
||||||
|
QuestionAnswerDTO questionAnswerDTO = new QuestionAnswerDTO();
|
||||||
|
questionAnswerDTO.setQuestion(question);
|
||||||
|
|
||||||
|
// 设置对应的选项或答案
|
||||||
|
if (question.getType() >= 0 && question.getType() <= 2) {
|
||||||
|
questionAnswerDTO.setAnswer(optionMap.get(question.getId()));
|
||||||
|
} else if (question.getType() == 3 || question.getType() == 4) {
|
||||||
|
questionAnswerDTO.setAnswer(answerMap.get(question.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理父子关系
|
||||||
|
if (question.getParentId() == null || question.getParentId().isEmpty()) {
|
||||||
|
result.put(question.getId(), questionAnswerDTO);
|
||||||
|
} else {
|
||||||
|
children.computeIfAbsent(question.getParentId(), k -> new ArrayList<>())
|
||||||
|
.add(questionAnswerDTO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将子问题列表添加到对应的父问题中
|
||||||
|
children.forEach((parentId, childList) -> {
|
||||||
|
if (result.containsKey(parentId)) {
|
||||||
|
result.get(parentId).setChildren(childList);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,182 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolQuestionAnswer;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolQuestionAnswerService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 题目答案
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="题目答案")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolQuestionAnswer")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolQuestionAnswerController extends JeecgController<AiolQuestionAnswer, IAiolQuestionAnswerService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolQuestionAnswerService aiolQuestionAnswerService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolQuestionAnswer
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "题目答案-分页列表查询")
|
||||||
|
@Operation(summary="题目答案-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolQuestionAnswer>> queryPageList(AiolQuestionAnswer aiolQuestionAnswer,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolQuestionAnswer> queryWrapper = QueryGenerator.initQueryWrapper(aiolQuestionAnswer, req.getParameterMap());
|
||||||
|
Page<AiolQuestionAnswer> page = new Page<AiolQuestionAnswer>(pageNo, pageSize);
|
||||||
|
IPage<AiolQuestionAnswer> pageList = aiolQuestionAnswerService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolQuestionAnswer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题目答案-添加")
|
||||||
|
@Operation(summary="题目答案-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_question_answer:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolQuestionAnswer aiolQuestionAnswer) {
|
||||||
|
aiolQuestionAnswerService.save(aiolQuestionAnswer);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolQuestionAnswer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题目答案-编辑")
|
||||||
|
@Operation(summary="题目答案-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_question_answer:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolQuestionAnswer aiolQuestionAnswer) {
|
||||||
|
aiolQuestionAnswerService.updateById(aiolQuestionAnswer);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题目答案-通过id删除")
|
||||||
|
@Operation(summary="题目答案-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_question_answer:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolQuestionAnswerService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题目答案-批量删除")
|
||||||
|
@Operation(summary="题目答案-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_question_answer:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolQuestionAnswerService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "题目答案-通过id查询")
|
||||||
|
@Operation(summary="题目答案-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolQuestionAnswer> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolQuestionAnswer aiolQuestionAnswer = aiolQuestionAnswerService.getById(id);
|
||||||
|
if(aiolQuestionAnswer==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolQuestionAnswer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolQuestionAnswer
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_question_answer:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolQuestionAnswer aiolQuestionAnswer) {
|
||||||
|
return super.exportXls(request, aiolQuestionAnswer, AiolQuestionAnswer.class, "题目答案");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_question_answer:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolQuestionAnswer.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,216 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolQuestion;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolQuestionRepo;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolQuestionRepoService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolQuestionService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 题目
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="题目")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolQuestion")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolQuestionController extends JeecgController<AiolQuestion, IAiolQuestionService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolQuestionService aiolQuestionService;
|
||||||
|
@Autowired
|
||||||
|
private AiolQuestionRepoController aiolQuestionRepoController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolQuestion
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "题目-分页列表查询")
|
||||||
|
@Operation(summary="题目-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolQuestion>> queryPageList(AiolQuestion aiolQuestion,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolQuestion> queryWrapper = QueryGenerator.initQueryWrapper(aiolQuestion, req.getParameterMap());
|
||||||
|
Page<AiolQuestion> page = new Page<AiolQuestion>(pageNo, pageSize);
|
||||||
|
IPage<AiolQuestion> pageList = aiolQuestionService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolQuestion
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题目-添加")
|
||||||
|
@Operation(summary="题目-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_question:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
@Transactional
|
||||||
|
public Result<String> add(@RequestBody AiolQuestion aiolQuestion,@RequestParam(name="repoId",required=false) String repoId) {
|
||||||
|
aiolQuestion.setStatus(1);
|
||||||
|
aiolQuestionService.save(aiolQuestion);
|
||||||
|
//题库题目添加
|
||||||
|
if(repoId!=null&& !repoId.isEmpty()){
|
||||||
|
AiolQuestionRepo aiolQuestionRepo = new AiolQuestionRepo();
|
||||||
|
aiolQuestionRepo.setRepoId(repoId);
|
||||||
|
aiolQuestionRepo.setQuestionId(aiolQuestion.getId());
|
||||||
|
|
||||||
|
aiolQuestionRepoController.add(aiolQuestionRepo);
|
||||||
|
}
|
||||||
|
return Result.OK(aiolQuestion.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@AutoLog(value = "题目-是否入库")
|
||||||
|
@Operation(summary="题目-是否入库")
|
||||||
|
@PostMapping(value = "/whetherPutStorage")
|
||||||
|
public Result<String> whetherPutStorage(@RequestBody List<String> ids){
|
||||||
|
try {
|
||||||
|
// 参数校验
|
||||||
|
if (ids == null || ids.isEmpty()) {
|
||||||
|
return Result.error("参数不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用服务层更新状态
|
||||||
|
aiolQuestionService.updateStatusByIds(ids);
|
||||||
|
|
||||||
|
return Result.OK("操作成功");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("更新题目状态失败", e);
|
||||||
|
return Result.error("操作失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolQuestion
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题目-编辑")
|
||||||
|
@Operation(summary="题目-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_question:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolQuestion aiolQuestion) {
|
||||||
|
aiolQuestionService.updateById(aiolQuestion);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题目-通过id删除")
|
||||||
|
@Operation(summary="题目-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_question:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolQuestionService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题目-批量删除")
|
||||||
|
@Operation(summary="题目-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_question:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolQuestionService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "题目-通过id查询")
|
||||||
|
@Operation(summary="题目-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolQuestion> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolQuestion aiolQuestion = aiolQuestionService.getById(id);
|
||||||
|
if(aiolQuestion==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolQuestion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolQuestion
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_question:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolQuestion aiolQuestion) {
|
||||||
|
return super.exportXls(request, aiolQuestion, AiolQuestion.class, "题目");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_question:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolQuestion.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,182 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolQuestionOption;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolQuestionOptionService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 题目选项
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="题目选项")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolQuestionOption")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolQuestionOptionController extends JeecgController<AiolQuestionOption, IAiolQuestionOptionService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolQuestionOptionService aiolQuestionOptionService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolQuestionOption
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "题目选项-分页列表查询")
|
||||||
|
@Operation(summary="题目选项-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolQuestionOption>> queryPageList(AiolQuestionOption aiolQuestionOption,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolQuestionOption> queryWrapper = QueryGenerator.initQueryWrapper(aiolQuestionOption, req.getParameterMap());
|
||||||
|
Page<AiolQuestionOption> page = new Page<AiolQuestionOption>(pageNo, pageSize);
|
||||||
|
IPage<AiolQuestionOption> pageList = aiolQuestionOptionService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolQuestionOption
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题目选项-添加")
|
||||||
|
@Operation(summary="题目选项-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_question_option:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolQuestionOption aiolQuestionOption) {
|
||||||
|
aiolQuestionOptionService.save(aiolQuestionOption);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolQuestionOption
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题目选项-编辑")
|
||||||
|
@Operation(summary="题目选项-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_question_option:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolQuestionOption aiolQuestionOption) {
|
||||||
|
aiolQuestionOptionService.updateById(aiolQuestionOption);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题目选项-通过id删除")
|
||||||
|
@Operation(summary="题目选项-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_question_option:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolQuestionOptionService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题目选项-批量删除")
|
||||||
|
@Operation(summary="题目选项-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_question_option:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolQuestionOptionService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "题目选项-通过id查询")
|
||||||
|
@Operation(summary="题目选项-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolQuestionOption> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolQuestionOption aiolQuestionOption = aiolQuestionOptionService.getById(id);
|
||||||
|
if(aiolQuestionOption==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolQuestionOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolQuestionOption
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_question_option:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolQuestionOption aiolQuestionOption) {
|
||||||
|
return super.exportXls(request, aiolQuestionOption, AiolQuestionOption.class, "题目选项");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_question_option:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolQuestionOption.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,220 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolQuestionRepo;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolRepo;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolQuestionRepoService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolRepoService;
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 题库题目
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="题库题目")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolQuestionRepo")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolQuestionRepoController extends JeecgController<AiolQuestionRepo, IAiolQuestionRepoService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolQuestionRepoService aiolQuestionRepoService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolRepoService aiolRepoService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolQuestionRepo
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "题库题目-分页列表查询")
|
||||||
|
@Operation(summary="题库题目-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolQuestionRepo>> queryPageList(AiolQuestionRepo aiolQuestionRepo,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolQuestionRepo> queryWrapper = QueryGenerator.initQueryWrapper(aiolQuestionRepo, req.getParameterMap());
|
||||||
|
Page<AiolQuestionRepo> page = new Page<AiolQuestionRepo>(pageNo, pageSize);
|
||||||
|
IPage<AiolQuestionRepo> pageList = aiolQuestionRepoService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolQuestionRepo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题库题目-添加")
|
||||||
|
@Operation(summary="题库题目-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_question_repo:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
@Transactional
|
||||||
|
public Result<String> add(@RequestBody AiolQuestionRepo aiolQuestionRepo) {
|
||||||
|
aiolQuestionRepoService.save(aiolQuestionRepo);
|
||||||
|
// 2. 获取题库ID
|
||||||
|
String repoId = aiolQuestionRepo.getRepoId();
|
||||||
|
// 3. 查询该题库
|
||||||
|
AiolRepo repo = aiolRepoService.getById(repoId);
|
||||||
|
if (repo != null) {
|
||||||
|
if(repo.getQuestionCount() != null){
|
||||||
|
repo.setQuestionCount(repo.getQuestionCount() + 1);
|
||||||
|
}else {
|
||||||
|
// 查询当前题库中的题目数量
|
||||||
|
List<String> questionIds = aiolQuestionRepoService.questionList(repoId);
|
||||||
|
int questionCount = questionIds.size();
|
||||||
|
// 更新题库的题目数量
|
||||||
|
repo.setQuestionCount(questionCount);
|
||||||
|
}
|
||||||
|
aiolRepoService.updateById(repo);
|
||||||
|
}
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolQuestionRepo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题库题目-编辑")
|
||||||
|
@Operation(summary="题库题目-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_question_repo:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolQuestionRepo aiolQuestionRepo) {
|
||||||
|
aiolQuestionRepoService.updateById(aiolQuestionRepo);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题库题目-通过id删除")
|
||||||
|
@Operation(summary="题库题目-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_question_repo:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
@Transactional
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
// 获取题库ID
|
||||||
|
String repoId = aiolQuestionRepoService.getById(id).getRepoId();
|
||||||
|
aiolQuestionRepoService.removeById(id);
|
||||||
|
// 查询该题库
|
||||||
|
AiolRepo repo = aiolRepoService.getById(repoId);
|
||||||
|
if (repo != null) {
|
||||||
|
if(repo.getQuestionCount() != null){
|
||||||
|
repo.setQuestionCount(repo.getQuestionCount() - 1);
|
||||||
|
}else {
|
||||||
|
// 查询当前题库中的题目数量
|
||||||
|
List<String> questionIds = aiolQuestionRepoService.questionList(repoId);
|
||||||
|
int questionCount = questionIds.size() - 1;
|
||||||
|
// 更新题库的题目数量
|
||||||
|
repo.setQuestionCount(questionCount);
|
||||||
|
}
|
||||||
|
aiolRepoService.updateById(repo);
|
||||||
|
}
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题库题目-批量删除")
|
||||||
|
@Operation(summary="题库题目-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_question_repo:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolQuestionRepoService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "题库题目-通过id查询")
|
||||||
|
@Operation(summary="题库题目-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolQuestionRepo> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolQuestionRepo aiolQuestionRepo = aiolQuestionRepoService.getById(id);
|
||||||
|
if(aiolQuestionRepo==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolQuestionRepo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolQuestionRepo
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_question_repo:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolQuestionRepo aiolQuestionRepo) {
|
||||||
|
return super.exportXls(request, aiolQuestionRepo, AiolQuestionRepo.class, "题库题目");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_question_repo:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolQuestionRepo.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,955 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
|
import org.jeecg.modules.aiol.constant.EntityLinkConst;
|
||||||
|
import org.jeecg.modules.aiol.dto.*;
|
||||||
|
import org.jeecg.modules.aiol.entity.*;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolRepoMapper;
|
||||||
|
import org.jeecg.modules.aiol.service.*;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
|
import org.jeecg.modules.system.service.ISysUserService;
|
||||||
|
import org.jeecgframework.poi.excel.ExcelExportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 题库
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name = "题库")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolRepo")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolRepoController extends JeecgController<AiolRepo, IAiolRepoService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolRepoService aiolRepoService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolEntityPermissionService aiolEntityPermissionService;
|
||||||
|
@Autowired
|
||||||
|
private ISysBaseAPI sysBaseApi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolRepo
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "题库-分页列表查询")
|
||||||
|
@Operation(summary = "题库-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolRepo>> queryPageList(AiolRepo aiolRepo,
|
||||||
|
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
|
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolRepo> queryWrapper = QueryGenerator.initQueryWrapper(aiolRepo, req.getParameterMap());
|
||||||
|
Page<AiolRepo> page = new Page<AiolRepo>(pageNo, pageSize);
|
||||||
|
IPage<AiolRepo> pageList = aiolRepoService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolRepo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题库-添加")
|
||||||
|
@Operation(summary = "题库-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_repo:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolRepo aiolRepo) {
|
||||||
|
aiolRepoService.save(aiolRepo);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolRepo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题库-编辑")
|
||||||
|
@Operation(summary = "题库-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_repo:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolRepo aiolRepo) {
|
||||||
|
aiolRepoService.updateById(aiolRepo);
|
||||||
|
return Result.OK(aiolRepo.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题库-通过id删除")
|
||||||
|
@Operation(summary = "题库-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_repo:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
aiolRepoService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "题库-批量删除")
|
||||||
|
@Operation(summary = "题库-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_repo:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||||
|
this.aiolRepoService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "题库-通过id查询")
|
||||||
|
@Operation(summary = "题库-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolRepo> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
AiolRepo aiolRepo = aiolRepoService.getById(id);
|
||||||
|
if (aiolRepo == null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolRepo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolRepo
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_repo:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolRepo aiolRepo) {
|
||||||
|
return super.exportXls(request, aiolRepo, AiolRepo.class, "题库");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_repo:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolRepo.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AiolRepoMapper repoMapper;
|
||||||
|
@Autowired
|
||||||
|
private IAiolQuestionRepoService questionRepoService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolEntityLinkService entityLinkBizService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolQuestionService questionService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolQuestionOptionService questionOptionService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolQuestionAnswerService questionAnswerService;
|
||||||
|
@Autowired
|
||||||
|
private ISysUserService sysUserService;
|
||||||
|
|
||||||
|
@PostMapping("course_add")
|
||||||
|
@Operation(summary = "课程下新建题库")
|
||||||
|
@Transactional
|
||||||
|
public Result<Integer> correct(@RequestBody Map<String, Object> data) {
|
||||||
|
String title = (String) data.get("title");
|
||||||
|
String remark = (String) data.get("remark");
|
||||||
|
String courseId = (String) data.get("courseId");
|
||||||
|
|
||||||
|
AiolRepo repo = new AiolRepo();
|
||||||
|
repo.setTitle(title);
|
||||||
|
repo.setRemark(remark);
|
||||||
|
|
||||||
|
repoMapper.insert(repo);
|
||||||
|
entityLinkBizService.save(EntityLinkConst.SourceType.COURSE, courseId, EntityLinkConst.TargetType.REPO, repo.getId());
|
||||||
|
return Result.OK(repo.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("repoList")
|
||||||
|
@Operation(summary = "获取有权限的所有题库")
|
||||||
|
public Result<List<Map<String, Object>>> repoList(HttpServletRequest request) {
|
||||||
|
// 尝试获取token,判断用户id
|
||||||
|
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
if (token != null && !token.trim().isEmpty()) {
|
||||||
|
try {
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
|
||||||
|
if (sysUser != null) {
|
||||||
|
// 获取用户有权限的题库ID列表
|
||||||
|
List<AiolEntityPermission> list = aiolEntityPermissionService.list(new QueryWrapper<AiolEntityPermission>()
|
||||||
|
.eq("user_id", sysUser.getId())
|
||||||
|
.eq("entity_type", "repo")
|
||||||
|
);
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
return Result.error("该用户没有权限访问任意题库");
|
||||||
|
}
|
||||||
|
List<String> repoIds = list.stream().map(AiolEntityPermission::getEntityId).collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 构建查询条件
|
||||||
|
QueryWrapper<AiolRepo> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.in("id", repoIds)
|
||||||
|
.select("aiol_repo.*", "(SELECT realname FROM sys_user WHERE username = aiol_repo.create_by) as createByName");
|
||||||
|
|
||||||
|
// 根据ID列表查询题库
|
||||||
|
List<Map<String, Object>> repoList = repoMapper.selectMaps(queryWrapper);
|
||||||
|
return Result.OK(repoList);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// token无效或解析失败,忽略错误,继续执行原有逻辑
|
||||||
|
log.debug("Token解析失败,按未登录用户处理: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.error("请检查登录状态");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping(value = "/courseAdd")
|
||||||
|
@Operation(summary = "课程新建题库")
|
||||||
|
@Transactional
|
||||||
|
public Result<String> courseAdd(@RequestBody AiolRepo repo,HttpServletRequest request) {
|
||||||
|
aiolRepoService.save(repo);
|
||||||
|
AiolEntityPermission aiolEntityPermission = new AiolEntityPermission();
|
||||||
|
aiolEntityPermission.setEntityId(repo.getId());
|
||||||
|
aiolEntityPermission.setEntityType("repo");
|
||||||
|
// 尝试获取token,判断用户id
|
||||||
|
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
if (token != null && !token.trim().isEmpty()) {
|
||||||
|
try {
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
|
||||||
|
if (sysUser != null) {
|
||||||
|
aiolEntityPermission.setUserId(sysUser.getId());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// token无效或解析失败,忽略错误,继续执行原有逻辑
|
||||||
|
log.debug("Token解析失败,按未登录用户处理: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aiolEntityPermissionService.save(aiolEntityPermission);
|
||||||
|
return Result.OK(repo.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("userList")
|
||||||
|
@Operation(summary = "获取用户")
|
||||||
|
public Result<List<UserPermission>> userList(
|
||||||
|
@RequestParam(required = false) String username,
|
||||||
|
@RequestParam(required = false) String employeeNumber,
|
||||||
|
@RequestParam String repoId) {
|
||||||
|
|
||||||
|
// 创建查询条件
|
||||||
|
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
|
||||||
|
// 当用户名不为空时,添加用户名查询条件(模糊查询)
|
||||||
|
if (StringUtils.isNotBlank(username)) {
|
||||||
|
queryWrapper.like(SysUser::getUsername, username);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当用户工号不为空时,添加工号查询条件(精确查询)
|
||||||
|
if (StringUtils.isNotBlank(employeeNumber)) {
|
||||||
|
queryWrapper.eq(SysUser::getWorkNo, employeeNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行查询
|
||||||
|
List<SysUser> userList = sysUserService.list(queryWrapper);
|
||||||
|
|
||||||
|
// 获取有权限的用户列表
|
||||||
|
Result<List<UserPermission>> result = userListByRepoId(repoId);
|
||||||
|
List<UserPermission> userListByRepo = result != null ? result.getResult() : null;
|
||||||
|
|
||||||
|
// 创建ID到UserPermission的映射
|
||||||
|
Map<String, UserPermission> userPermissionMap;
|
||||||
|
if (userListByRepo == null || userListByRepo.isEmpty()) {
|
||||||
|
userPermissionMap = new HashMap<>();
|
||||||
|
} else {
|
||||||
|
userPermissionMap = userListByRepo.stream()
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
UserPermission::getUserId,
|
||||||
|
user -> user,
|
||||||
|
(existing, replacement) -> existing
|
||||||
|
));
|
||||||
|
}
|
||||||
|
List<UserPermission> userPermissionList = new ArrayList<>();
|
||||||
|
userList.forEach(user -> {
|
||||||
|
// 如果当前用户在用户列表中
|
||||||
|
if (userPermissionMap.containsKey(user.getId())) {
|
||||||
|
userPermissionList.add(userPermissionMap.get(user.getId()));
|
||||||
|
}else {
|
||||||
|
UserPermission userPermission = new UserPermission();
|
||||||
|
userPermission.setUserId(user.getId()); // 用户ID
|
||||||
|
userPermission.setUserName(user.getUsername()); // 用户名
|
||||||
|
userPermission.setRealName(user.getRealname()); // 用户真实姓名
|
||||||
|
userPermission.setUserAvatar(user.getAvatar()); // 用户头像
|
||||||
|
userPermission.setPermission(false);
|
||||||
|
userPermissionList.add(userPermission);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 返回结果
|
||||||
|
return Result.ok(userPermissionList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("addOrDeletePermission")
|
||||||
|
@Operation(summary = "添加权限")
|
||||||
|
@Transactional
|
||||||
|
public Result<String> addOrDeletePermission(@RequestParam String userId, @RequestParam String repoId,@RequestParam String type) {
|
||||||
|
AiolEntityPermission aiolEntityPermission = new AiolEntityPermission();
|
||||||
|
aiolEntityPermission.setEntityId(repoId);
|
||||||
|
aiolEntityPermission.setEntityType("repo");
|
||||||
|
aiolEntityPermission.setUserId(userId);
|
||||||
|
if(type.equals("add")){
|
||||||
|
aiolEntityPermissionService.saveOrUpdate(aiolEntityPermission);
|
||||||
|
return Result.OK("添加成功");
|
||||||
|
}
|
||||||
|
else if(type.equals("delete")){
|
||||||
|
aiolEntityPermissionService.remove(new QueryWrapper<>(aiolEntityPermission));
|
||||||
|
return Result.OK("删除成功");
|
||||||
|
}
|
||||||
|
return Result.OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取有权限的用户
|
||||||
|
@GetMapping("userListByRepoId/{repoId}")
|
||||||
|
@Operation(summary = "获取题库有权限的用户列表")
|
||||||
|
public Result<List<UserPermission>> userListByRepoId(@PathVariable String repoId) {
|
||||||
|
// 获取用户有权限的题库ID列表
|
||||||
|
List<AiolEntityPermission> list = aiolEntityPermissionService.list(new QueryWrapper<AiolEntityPermission>()
|
||||||
|
.eq("entity_id", repoId)
|
||||||
|
.eq("entity_type", "repo")
|
||||||
|
);
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
return Result.ok();
|
||||||
|
}
|
||||||
|
List<String> userIds = list.stream().map(AiolEntityPermission::getUserId).collect(Collectors.toList());
|
||||||
|
List<SysUser> sysUsers = sysUserService.listByIds(userIds);
|
||||||
|
List<UserPermission> userPermissionList = new ArrayList<>();
|
||||||
|
sysUsers.forEach(user -> {
|
||||||
|
if (user != null) {
|
||||||
|
UserPermission userPermission = new UserPermission();
|
||||||
|
userPermission.setUserId(user.getId()); // 用户ID
|
||||||
|
userPermission.setUserName(user.getUsername()); // 用户名
|
||||||
|
userPermission.setRealName(user.getRealname()); // 用户真实姓名
|
||||||
|
userPermission.setUserAvatar(user.getAvatar()); // 用户头像
|
||||||
|
userPermission.setPermission(true);
|
||||||
|
userPermissionList.add(userPermission);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 根据ID列表查询用户
|
||||||
|
return Result.ok(userPermissionList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/questionList/{repoId}")
|
||||||
|
@Operation(summary = "查询题库下题目")
|
||||||
|
public Result<List<QuestionWithCreator>> questionList(@PathVariable String repoId) {
|
||||||
|
// 获取题库中的题目ID列表
|
||||||
|
List<String> repoQuestionIds = questionRepoService.questionList(repoId);
|
||||||
|
if (repoQuestionIds.isEmpty()) {
|
||||||
|
return Result.error("该题库下没有题目或该题库不存在");
|
||||||
|
}
|
||||||
|
// 根据ID列表查询题目
|
||||||
|
List<AiolQuestion> questions = questionService.listByIds(repoQuestionIds);
|
||||||
|
if (questions.isEmpty()) {
|
||||||
|
return Result.error("题目不存在");
|
||||||
|
}
|
||||||
|
//获取所有创建人id
|
||||||
|
List<String> createIds = questions.stream()
|
||||||
|
.map(AiolQuestion::getCreateBy)
|
||||||
|
.collect(Collectors.toSet())
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
// 根据ID列表查询用户信息
|
||||||
|
Map<String, String> createIdToUsernameMap = new HashMap<>();
|
||||||
|
if (!createIds.isEmpty()) {
|
||||||
|
List<SysUser> users = sysUserService.list(
|
||||||
|
new LambdaQueryWrapper<SysUser>()
|
||||||
|
.in(SysUser::getUsername, createIds)
|
||||||
|
);
|
||||||
|
// 创建ID到用户名的映射
|
||||||
|
createIdToUsernameMap = users.stream()
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
SysUser::getUsername,
|
||||||
|
SysUser::getRealname,
|
||||||
|
(existing, replacement) -> existing
|
||||||
|
));
|
||||||
|
}
|
||||||
|
//获取复选题id
|
||||||
|
List<String> type5Ids = questions.stream()
|
||||||
|
.filter(question -> question.getType() == 5)
|
||||||
|
.map(AiolQuestion::getId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
//获取复选题所包含的题目
|
||||||
|
List<AiolQuestion> type5Questions = new ArrayList<>();
|
||||||
|
if (!type5Ids.isEmpty()) {
|
||||||
|
type5Questions = questionService.list(
|
||||||
|
new LambdaQueryWrapper<AiolQuestion>()
|
||||||
|
.in(AiolQuestion::getParentId, type5Ids)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// 创建一个映射,用于快速查找父ID对应的子题目
|
||||||
|
Map<String, List<AiolQuestion>> parentToChildrenMap = type5Questions.stream()
|
||||||
|
.collect(Collectors.groupingBy(AiolQuestion::getParentId));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 构建结果列表
|
||||||
|
List<QuestionWithCreator> resultQuestions = new ArrayList<>();
|
||||||
|
for (AiolQuestion question : questions) {
|
||||||
|
// 创建扩展对象
|
||||||
|
QuestionWithCreator questionWithCreator = new QuestionWithCreator();
|
||||||
|
BeanUtils.copyProperties(question, questionWithCreator);
|
||||||
|
|
||||||
|
// 设置创建人用户名
|
||||||
|
String createBy = question.getCreateBy();
|
||||||
|
if (StringUtils.isNotBlank(createBy)) {
|
||||||
|
questionWithCreator.setCreateByName(createIdToUsernameMap.getOrDefault(createBy, ""));
|
||||||
|
} else {
|
||||||
|
questionWithCreator.setCreateByName("");
|
||||||
|
}
|
||||||
|
|
||||||
|
resultQuestions.add(questionWithCreator);
|
||||||
|
|
||||||
|
if (question.getType() == 5) {
|
||||||
|
List<AiolQuestion> children = parentToChildrenMap.getOrDefault(question.getId(), Collections.emptyList());
|
||||||
|
for (AiolQuestion child : children) {
|
||||||
|
// 创建子题目的扩展对象
|
||||||
|
QuestionWithCreator childWithCreator = new QuestionWithCreator();
|
||||||
|
BeanUtils.copyProperties(child, childWithCreator);
|
||||||
|
|
||||||
|
// 设置子题目的创建人用户名
|
||||||
|
String childCreateBy = child.getCreateBy();
|
||||||
|
if (StringUtils.isNotBlank(childCreateBy)) {
|
||||||
|
childWithCreator.setCreateByName(createIdToUsernameMap.getOrDefault(childCreateBy, ""));
|
||||||
|
} else {
|
||||||
|
childWithCreator.setCreateByName("");
|
||||||
|
}
|
||||||
|
|
||||||
|
resultQuestions.add(childWithCreator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.ok(resultQuestions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("course_list")
|
||||||
|
@Operation(summary = "获取课程下的题库")
|
||||||
|
public Result<List<AiolRepo>> courseList(@RequestParam String courseId) {
|
||||||
|
List<String> targetIds = entityLinkBizService.listTargetIds(EntityLinkConst.SourceType.COURSE, courseId, EntityLinkConst.TargetType.REPO);
|
||||||
|
|
||||||
|
if (targetIds.size() > 0) {
|
||||||
|
List<AiolRepo> list = repoMapper.selectByIds(targetIds);
|
||||||
|
return Result.OK(list);
|
||||||
|
} else {
|
||||||
|
return Result.OK(new ArrayList<>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/repoList/{questionId}")
|
||||||
|
@Operation(summary = "查询题目详情")
|
||||||
|
public Result<?> questionDetail(@PathVariable String questionId) {
|
||||||
|
AiolQuestion rootQuestion = questionService.getById(questionId);
|
||||||
|
if (rootQuestion == null) {
|
||||||
|
return Result.error("题目不存在");
|
||||||
|
}
|
||||||
|
QuestionAnswerDTO questionAnswerDTO = new QuestionAnswerDTO();
|
||||||
|
questionAnswerDTO.setQuestion(rootQuestion);
|
||||||
|
if (rootQuestion.getType() >= 0 && rootQuestion.getType() <= 2) {
|
||||||
|
questionAnswerDTO.setAnswer(choiceDetail(questionId));
|
||||||
|
return Result.ok(questionAnswerDTO);
|
||||||
|
} else if (rootQuestion.getType() == 3 || rootQuestion.getType() == 4) {
|
||||||
|
questionAnswerDTO.setAnswer(answerDetail(questionId));
|
||||||
|
return Result.ok(questionAnswerDTO);
|
||||||
|
} else {
|
||||||
|
//查询复合题所包含的题目
|
||||||
|
List<AiolQuestion> list = questionService.list(
|
||||||
|
new LambdaQueryWrapper<AiolQuestion>().
|
||||||
|
eq(AiolQuestion::getParentId, questionId)
|
||||||
|
);
|
||||||
|
//根据题目类型进行分组(false:选择多选判断题,true:填空简答题)
|
||||||
|
Map<Boolean, List<AiolQuestion>> groupedQuestions = list.stream()
|
||||||
|
.collect(Collectors.partitioningBy(
|
||||||
|
q -> q.getType() > 2
|
||||||
|
));
|
||||||
|
//获取选择题,多选题,判断题答案
|
||||||
|
List<AiolQuestion> question = groupedQuestions.get(false);
|
||||||
|
if (!question.isEmpty()) {
|
||||||
|
question.forEach(q -> {
|
||||||
|
QuestionAnswerDTO qad = new QuestionAnswerDTO();
|
||||||
|
qad.setQuestion(q);
|
||||||
|
qad.setAnswer(choiceDetail(q.getId()));
|
||||||
|
questionAnswerDTO.getChildren().add(qad);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//获取填空题,简答题答案
|
||||||
|
List<AiolQuestion> question1 = groupedQuestions.get(true);
|
||||||
|
if (!question1.isEmpty()) {
|
||||||
|
question1.forEach(q -> {
|
||||||
|
QuestionAnswerDTO qad = new QuestionAnswerDTO();
|
||||||
|
qad.setQuestion(q);
|
||||||
|
qad.setAnswer(answerDetail(q.getId()));
|
||||||
|
questionAnswerDTO.getChildren().add(qad);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Result.ok(questionAnswerDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//题库题目excel导出
|
||||||
|
@GetMapping("/exportXls")
|
||||||
|
@Operation(summary = "题库题目excel导出")
|
||||||
|
public void exportXls(@RequestParam(name = "repoId", required = true) String repoId, HttpServletResponse response) {
|
||||||
|
try {
|
||||||
|
// 1. 获取题库信息
|
||||||
|
AiolRepo repo = aiolRepoService.getById(repoId);
|
||||||
|
if (repo == null) {
|
||||||
|
throw new RuntimeException("题库不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 获取题库下的所有题目
|
||||||
|
List<AiolQuestion> questions = questionService.list(new LambdaQueryWrapper<AiolQuestion>()
|
||||||
|
.inSql(AiolQuestion::getId, "SELECT question_id FROM aiol_question_repo WHERE repo_id = '" + repoId + "'"));
|
||||||
|
List<AiolQuestion> questionList = new ArrayList<>();
|
||||||
|
if (questions.isEmpty()) {
|
||||||
|
throw new RuntimeException("题库下没有题目");
|
||||||
|
} else {
|
||||||
|
//获取复合题id
|
||||||
|
List<String> parentIds = questions.stream().filter(q -> q.getType() == 5).map(AiolQuestion::getId).collect(Collectors.toList());
|
||||||
|
//获取复合题下的子题
|
||||||
|
if (!parentIds.isEmpty()) {
|
||||||
|
List<AiolQuestion> childQuestions = questionService.list(new LambdaQueryWrapper<AiolQuestion>().in(AiolQuestion::getParentId, parentIds));
|
||||||
|
//将子题目放到复合题后面
|
||||||
|
// 创建一个映射,用于快速查找父ID对应的子题目
|
||||||
|
Map<String, List<AiolQuestion>> parentToChildrenMap = childQuestions.stream()
|
||||||
|
.collect(Collectors.groupingBy(AiolQuestion::getParentId));
|
||||||
|
// 将子题目添加到原始列表中,保持原有顺序
|
||||||
|
for (AiolQuestion question : questions) {
|
||||||
|
questionList.add(question);
|
||||||
|
if (question.getType() == 5) {
|
||||||
|
List<AiolQuestion> children = parentToChildrenMap.getOrDefault(question.getId(), Collections.emptyList());
|
||||||
|
questionList.addAll(children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
questionList.addAll(questions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 3. 转换为ExcelDTO
|
||||||
|
List<QuestionExcelDTO> dtoList = new ArrayList<>();
|
||||||
|
for (AiolQuestion question : questionList) {
|
||||||
|
QuestionExcelDTO dto = new QuestionExcelDTO();
|
||||||
|
dto.setQuestionId(question.getId());
|
||||||
|
dto.setContent(question.getContent());
|
||||||
|
dto.setAnalysis(question.getAnalysis());
|
||||||
|
dto.setScore(Double.valueOf(question.getScore()));
|
||||||
|
|
||||||
|
// 设置题目类型
|
||||||
|
switch (question.getType()) {
|
||||||
|
case 0:
|
||||||
|
dto.setType("单选");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
dto.setType("多选");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
dto.setType("判断");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
dto.setType("填空");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
dto.setType("简答");
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
dto.setType("复合题");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置难度
|
||||||
|
switch (question.getDifficulty()) {
|
||||||
|
case 0:
|
||||||
|
dto.setDifficulty("简单");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
dto.setDifficulty("中等");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
dto.setDifficulty("困难");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置程度
|
||||||
|
switch (question.getDegree()) {
|
||||||
|
case 0:
|
||||||
|
dto.setDegree("了解");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
dto.setDegree("熟悉");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
dto.setDegree("掌握");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置能力
|
||||||
|
switch (question.getAbility()) {
|
||||||
|
case 0:
|
||||||
|
dto.setAbility("识记");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
dto.setAbility("理解");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
dto.setAbility("应用");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置选项和答案
|
||||||
|
if (question.getType() >= 0 && question.getType() <= 2) {
|
||||||
|
// 选择题、多选题、判断题
|
||||||
|
List<AiolQuestionOption> options = questionOptionService.list(
|
||||||
|
new LambdaQueryWrapper<AiolQuestionOption>()
|
||||||
|
.eq(AiolQuestionOption::getQuestionId, question.getId())
|
||||||
|
.orderByAsc(AiolQuestionOption::getOrderNo)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 设置选项
|
||||||
|
for (int i = 0; i < options.size(); i++) {
|
||||||
|
AiolQuestionOption option = options.get(i);
|
||||||
|
char optionLabel = (char) ('A' + i);
|
||||||
|
switch (optionLabel) {
|
||||||
|
case 'A':
|
||||||
|
dto.setOptionA(option.getContent());
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
dto.setOptionB(option.getContent());
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
dto.setOptionC(option.getContent());
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
dto.setOptionD(option.getContent());
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
dto.setOptionE(option.getContent());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置正确答案
|
||||||
|
StringBuilder correctAnswers = new StringBuilder();
|
||||||
|
for (AiolQuestionOption option : options) {
|
||||||
|
if (option.getIzCorrent() == 1) {
|
||||||
|
char optionLabel = (char) ('A' + (option.getOrderNo() - 1));
|
||||||
|
if (!correctAnswers.isEmpty()) correctAnswers.append(",");
|
||||||
|
correctAnswers.append(optionLabel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dto.setCorrectAnswers(correctAnswers.toString());
|
||||||
|
} else if (question.getType() == 3 || question.getType() == 4) {
|
||||||
|
// 填空题、简答题
|
||||||
|
List<AiolQuestionAnswer> answers = questionAnswerService.list(
|
||||||
|
new LambdaQueryWrapper<AiolQuestionAnswer>()
|
||||||
|
.eq(AiolQuestionAnswer::getQuestionId, question.getId())
|
||||||
|
.orderByAsc(AiolQuestionAnswer::getOrderNo)
|
||||||
|
);
|
||||||
|
|
||||||
|
StringBuilder answerTexts = new StringBuilder();
|
||||||
|
int orderNo = 1;
|
||||||
|
for (AiolQuestionAnswer answer : answers) {
|
||||||
|
if (!answerTexts.isEmpty()) {
|
||||||
|
if (orderNo != answer.getOrderNo()) {
|
||||||
|
answerTexts.append(",");
|
||||||
|
orderNo = answer.getOrderNo();
|
||||||
|
} else {
|
||||||
|
answerTexts.append("|");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
answerTexts.append(answer.getAnswerText());
|
||||||
|
}
|
||||||
|
dto.setCorrectAnswers(answerTexts.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
dtoList.add(dto);
|
||||||
|
}
|
||||||
|
// 设置响应头
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
String fileName = URLEncoder.encode(repo.getTitle() + "_题目导出", "UTF-8").replaceAll("\\+", "%");
|
||||||
|
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
|
||||||
|
|
||||||
|
// 使用AutoPoi创建Workbook
|
||||||
|
ExportParams exportParams = new ExportParams("题目列表", "题库题目数据");
|
||||||
|
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, QuestionExcelDTO.class, dtoList);
|
||||||
|
|
||||||
|
// 写入响应流
|
||||||
|
workbook.write(response.getOutputStream());
|
||||||
|
// 关闭资源
|
||||||
|
workbook.close();
|
||||||
|
response.getOutputStream().flush();
|
||||||
|
response.getOutputStream().close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("导出题库题目失败", e);
|
||||||
|
throw new RuntimeException("导出题库题目失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/importXls")
|
||||||
|
@Operation(summary = "题库题目excel导入")
|
||||||
|
@Transactional
|
||||||
|
public Result<String> importXls(@RequestParam(name = "file", required = true) MultipartFile file,
|
||||||
|
@RequestParam(name = "repoId", required = true) String repoId) {
|
||||||
|
try {
|
||||||
|
// 1. 验证题库是否存在
|
||||||
|
AiolRepo repo = aiolRepoService.getById(repoId);
|
||||||
|
if (repo == null) {
|
||||||
|
return Result.error("题库不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 读取Excel文件
|
||||||
|
ImportParams params = new ImportParams();
|
||||||
|
params.setTitleRows(1); // 标题行数
|
||||||
|
params.setHeadRows(1); // 表头行数
|
||||||
|
List<QuestionExcelDTO> dtoList = ExcelImportUtil.importExcel(file.getInputStream(), QuestionExcelDTO.class, params);
|
||||||
|
if (CollectionUtils.isEmpty(dtoList)) {
|
||||||
|
return Result.error("Excel文件为空或格式不正确");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 处理导入数据
|
||||||
|
List<AiolQuestion> questions = new ArrayList<>();
|
||||||
|
List<AiolQuestionOption> options = new ArrayList<>();
|
||||||
|
List<AiolQuestionAnswer> answers = new ArrayList<>();
|
||||||
|
List<AiolQuestionRepo> questionRepos = new ArrayList<>();
|
||||||
|
|
||||||
|
String parentId = null;
|
||||||
|
for (QuestionExcelDTO dto : dtoList) {
|
||||||
|
// 3.1 创建题目
|
||||||
|
AiolQuestion question = new AiolQuestion();
|
||||||
|
question.setId(String.valueOf(IdWorker.getId()));
|
||||||
|
question.setContent(dto.getContent());
|
||||||
|
question.setAnalysis(dto.getAnalysis());
|
||||||
|
question.setScore(dto.getScore().intValue());
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(dto.getParentId()) && dto.getParentId().equals("^")) {
|
||||||
|
question.setParentId(parentId);
|
||||||
|
} else {
|
||||||
|
parentId = question.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(dto.getType());
|
||||||
|
// 设置题目类型
|
||||||
|
switch (dto.getType()) {
|
||||||
|
case "单选":
|
||||||
|
question.setType(0);
|
||||||
|
break;
|
||||||
|
case "多选":
|
||||||
|
question.setType(1);
|
||||||
|
break;
|
||||||
|
case "判断":
|
||||||
|
question.setType(2);
|
||||||
|
break;
|
||||||
|
case "填空":
|
||||||
|
question.setType(3);
|
||||||
|
break;
|
||||||
|
case "简答":
|
||||||
|
question.setType(4);
|
||||||
|
break;
|
||||||
|
case "复合题":
|
||||||
|
question.setType(5);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("题目类型不正确:" + dto.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置难度
|
||||||
|
switch (dto.getDifficulty()) {
|
||||||
|
case "简单":
|
||||||
|
question.setDifficulty(0);
|
||||||
|
break;
|
||||||
|
case "中等":
|
||||||
|
question.setDifficulty(1);
|
||||||
|
break;
|
||||||
|
case "困难":
|
||||||
|
question.setDifficulty(2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置程度
|
||||||
|
switch (dto.getDegree()) {
|
||||||
|
case "了解":
|
||||||
|
question.setDegree(0);
|
||||||
|
break;
|
||||||
|
case "熟悉":
|
||||||
|
question.setDegree(1);
|
||||||
|
break;
|
||||||
|
case "掌握":
|
||||||
|
question.setDegree(2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置能力
|
||||||
|
switch (dto.getAbility()) {
|
||||||
|
case "识记":
|
||||||
|
question.setAbility(0);
|
||||||
|
break;
|
||||||
|
case "理解":
|
||||||
|
question.setAbility(1);
|
||||||
|
break;
|
||||||
|
case "应用":
|
||||||
|
question.setAbility(2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
questions.add(question);
|
||||||
|
|
||||||
|
// 3.2 处理选项和答案
|
||||||
|
if (question.getType() >= 0 && question.getType() <= 2) {
|
||||||
|
// 选择题、多选题、判断题
|
||||||
|
String correctAnswers = dto.getCorrectAnswers();
|
||||||
|
if (StringUtils.isEmpty(correctAnswers)) {
|
||||||
|
return Result.error("题目 {} 缺少正确答案", dto.getContent());
|
||||||
|
}
|
||||||
|
String[] answerLabels = correctAnswers.split(",");
|
||||||
|
List<String> optionContents = Arrays.asList(
|
||||||
|
dto.getOptionA(),
|
||||||
|
dto.getOptionB(),
|
||||||
|
dto.getOptionC(),
|
||||||
|
dto.getOptionD(),
|
||||||
|
dto.getOptionE()
|
||||||
|
).stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
for (int i = 0; i < optionContents.size(); i++) {
|
||||||
|
AiolQuestionOption option = new AiolQuestionOption();
|
||||||
|
option.setQuestionId(question.getId());
|
||||||
|
option.setContent(optionContents.get(i));
|
||||||
|
option.setOrderNo(i + 1);
|
||||||
|
|
||||||
|
// 检查是否为正确答案
|
||||||
|
boolean isCorrect = Arrays.asList(answerLabels)
|
||||||
|
.contains(String.valueOf((char) ('A' + i)));
|
||||||
|
option.setIzCorrent(isCorrect ? 1 : 0);
|
||||||
|
options.add(option);
|
||||||
|
}
|
||||||
|
} else if (question.getType() == 3 || question.getType() == 4) {
|
||||||
|
// 填空题、简答题
|
||||||
|
String correctAnswers = dto.getCorrectAnswers();
|
||||||
|
if (StringUtils.isEmpty(correctAnswers)) {
|
||||||
|
return Result.error("题目 {} 缺少正确答案", dto.getContent());
|
||||||
|
}
|
||||||
|
String[] answerTexts = correctAnswers.split(",");
|
||||||
|
for (int i = 0; i < answerTexts.length; i++) {
|
||||||
|
AiolQuestionAnswer answer = new AiolQuestionAnswer();
|
||||||
|
answer.setQuestionId(question.getId());
|
||||||
|
answer.setAnswerText(answerTexts[i]);
|
||||||
|
answer.setOrderNo(i + 1);
|
||||||
|
answers.add(answer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3.3 创建题库题目关联关系
|
||||||
|
AiolQuestionRepo questionRepo = new AiolQuestionRepo();
|
||||||
|
questionRepo.setRepoId(repoId);
|
||||||
|
questionRepo.setQuestionId(question.getId());
|
||||||
|
questionRepos.add(questionRepo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 批量保存数据
|
||||||
|
questionService.saveBatch(questions);
|
||||||
|
questionOptionService.saveBatch(options);
|
||||||
|
questionAnswerService.saveBatch(answers);
|
||||||
|
questionRepoService.saveBatch(questionRepos);
|
||||||
|
|
||||||
|
// 5. 更新题库题目数量
|
||||||
|
repo.setQuestionCount(repo.getQuestionCount() != null ? repo.getQuestionCount()+questionRepos.size():questionRepos.size());
|
||||||
|
aiolRepoService.updateById(repo);
|
||||||
|
|
||||||
|
return Result.OK("导入成功");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("导入题库题目失败", e);
|
||||||
|
return Result.error("导入失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//查询选择题,多选题,判断题答案
|
||||||
|
public List<AiolQuestionOption> choiceDetail(String questionId) {
|
||||||
|
return questionOptionService.list(
|
||||||
|
new LambdaQueryWrapper<AiolQuestionOption>().
|
||||||
|
eq(AiolQuestionOption::getQuestionId, questionId).
|
||||||
|
orderByAsc(AiolQuestionOption::getOrderNo)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//查询填空题,简答题答案
|
||||||
|
public List<AiolQuestionAnswer> answerDetail(String questionId) {
|
||||||
|
return questionAnswerService.list(
|
||||||
|
new LambdaQueryWrapper<AiolQuestionAnswer>().
|
||||||
|
eq(AiolQuestionAnswer::getQuestionId, questionId).
|
||||||
|
orderByAsc(AiolQuestionAnswer::getOrderNo)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,219 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolResourceContent;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolResourceContentService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
import org.jeecg.config.shiro.IgnoreAuth;
|
||||||
|
/**
|
||||||
|
* @Description: 资源内容
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-23
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="资源内容")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolResourceContent")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolResourceContentController extends JeecgController<AiolResourceContent, IAiolResourceContentService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolResourceContentService aiolResourceContentService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolResourceContent
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "资源内容-分页列表查询")
|
||||||
|
@Operation(summary="资源内容-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolResourceContent>> queryPageList(AiolResourceContent aiolResourceContent,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolResourceContent> queryWrapper = QueryGenerator.initQueryWrapper(aiolResourceContent, req.getParameterMap());
|
||||||
|
Page<AiolResourceContent> page = new Page<AiolResourceContent>(pageNo, pageSize);
|
||||||
|
IPage<AiolResourceContent> pageList = aiolResourceContentService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolResourceContent
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "资源内容-添加")
|
||||||
|
@Operation(summary="资源内容-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_resource_content:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolResourceContent aiolResourceContent) {
|
||||||
|
aiolResourceContentService.save(aiolResourceContent);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolResourceContent
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "资源内容-编辑")
|
||||||
|
@Operation(summary="资源内容-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_resource_content:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolResourceContent aiolResourceContent) {
|
||||||
|
aiolResourceContentService.updateById(aiolResourceContent);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "资源内容-通过id删除")
|
||||||
|
@Operation(summary="资源内容-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_resource_content:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolResourceContentService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "资源内容-批量删除")
|
||||||
|
@Operation(summary="资源内容-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_resource_content:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolResourceContentService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "资源内容-通过id查询")
|
||||||
|
@Operation(summary="资源内容-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolResourceContent> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolResourceContent aiolResourceContent = aiolResourceContentService.getById(id);
|
||||||
|
if(aiolResourceContent==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolResourceContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询视频总结
|
||||||
|
* 根据资源ID在 aiol_resource_content 表查询 content_type=video_summary 的记录
|
||||||
|
*/
|
||||||
|
@Operation(summary = "查询视频总结", description = "根据资源ID查询content_type=video_summary的资源内容")
|
||||||
|
@IgnoreAuth
|
||||||
|
@GetMapping(value = "/video_summary")
|
||||||
|
public Result<AiolResourceContent> queryVideoSummary(@RequestParam(name = "resourceId") String resourceId) {
|
||||||
|
try {
|
||||||
|
QueryWrapper<AiolResourceContent> wrapper = new QueryWrapper<>();
|
||||||
|
wrapper.eq("resource_id", resourceId).eq("content_type", "video_summary");
|
||||||
|
// 存在多条时仅取第一条,避免抛异常
|
||||||
|
AiolResourceContent record = aiolResourceContentService.getOne(wrapper, false);
|
||||||
|
return Result.OK(record);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询视频总结失败: resourceId={}, error={}", resourceId, e.getMessage(), e);
|
||||||
|
return Result.error("查询视频总结失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "查询视频字幕", description = "根据资源ID查询content_type=video_subtitle的资源内容")
|
||||||
|
@IgnoreAuth
|
||||||
|
@GetMapping(value = "/video_subtitle")
|
||||||
|
public Result<AiolResourceContent> queryVideoSubtitle(@RequestParam(name = "resourceId") String resourceId) {
|
||||||
|
try {
|
||||||
|
QueryWrapper<AiolResourceContent> wrapper = new QueryWrapper<>();
|
||||||
|
wrapper.eq("resource_id", resourceId).eq("content_type", "video_subtitle");
|
||||||
|
// 存在多条时仅取第一条,避免抛异常
|
||||||
|
AiolResourceContent record = aiolResourceContentService.getOne(wrapper, false);
|
||||||
|
return Result.OK(record);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询视频字幕失败: resourceId={}, error={}", resourceId, e.getMessage(), e);
|
||||||
|
return Result.error("查询视频字幕失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolResourceContent
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_resource_content:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolResourceContent aiolResourceContent) {
|
||||||
|
return super.exportXls(request, aiolResourceContent, AiolResourceContent.class, "资源内容");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_resource_content:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolResourceContent.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,585 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.common.util.MinioUtil;
|
||||||
|
import org.jeecg.common.util.oss.OssBootUtil;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import org.jeecg.config.shiro.IgnoreAuth;
|
||||||
|
import org.jeecg.modules.aiol.constant.EntityLinkConst;
|
||||||
|
import org.jeecg.modules.aiol.constant.ResourceTypeConst;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolResource;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolEntityLinkService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolResourceService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import ws.schild.jave.MultimediaObject;
|
||||||
|
import ws.schild.jave.info.MultimediaInfo;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 资源
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name = "资源")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolResource")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolResourceController extends JeecgController<AiolResource, IAiolResourceService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolResourceService aiolResourceService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolResource
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "资源-分页列表查询")
|
||||||
|
@Operation(summary = "资源-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolResource>> queryPageList(AiolResource aiolResource,
|
||||||
|
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
|
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolResource> queryWrapper = QueryGenerator.initQueryWrapper(aiolResource, req.getParameterMap());
|
||||||
|
Page<AiolResource> page = new Page<AiolResource>(pageNo, pageSize);
|
||||||
|
IPage<AiolResource> pageList = aiolResourceService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolResource
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "资源-添加")
|
||||||
|
@Operation(summary = "资源-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_resource:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolResource aiolResource) {
|
||||||
|
aiolResourceService.save(aiolResource);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolResource
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "资源-编辑")
|
||||||
|
@Operation(summary = "资源-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_resource:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolResource aiolResource) {
|
||||||
|
aiolResourceService.updateById(aiolResource);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "资源-通过id删除")
|
||||||
|
@Operation(summary = "资源-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_resource:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
aiolResourceService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "资源-批量删除")
|
||||||
|
@Operation(summary = "资源-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_resource:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||||
|
this.aiolResourceService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "资源-通过id查询")
|
||||||
|
@Operation(summary = "资源-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolResource> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
AiolResource aiolResource = aiolResourceService.getById(id);
|
||||||
|
if (aiolResource == null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolResource
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_resource:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolResource aiolResource) {
|
||||||
|
return super.exportXls(request, aiolResource, AiolResource.class, "资源");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_resource:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolResource.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolEntityLinkService entityLinkBizService;
|
||||||
|
|
||||||
|
@GetMapping("/feature")
|
||||||
|
@Operation(summary = "查询精品资源")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<AiolResource>> queryFeatureResource() {
|
||||||
|
List<AiolResource> list = aiolResourceService.list(new QueryWrapper<AiolResource>().eq("iz_featured", 1));
|
||||||
|
return Result.OK(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/video")
|
||||||
|
@Operation(summary = "按课程分类查询视频资源")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<AiolResource>> queryVideoResource(@RequestParam("categoryId") String courseCategoryId) {
|
||||||
|
List<String> targetIds = entityLinkBizService.listTargetIds(EntityLinkConst.SourceType.COURSE_CATEGORY, courseCategoryId, EntityLinkConst.TargetType.RESOURCE);
|
||||||
|
List<AiolResource> list = new ArrayList<>();
|
||||||
|
for (String targetId : targetIds) {
|
||||||
|
AiolResource resource = aiolResourceService.getById(targetId);
|
||||||
|
if (resource.getType() == EntityLinkConst.ResourceType.VIDEO) {
|
||||||
|
list.add(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.OK(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/image")
|
||||||
|
@Operation(summary = "按课程分类查询图片资源")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<AiolResource>> queryImageResource(@RequestParam("categoryId") String courseCategoryId) {
|
||||||
|
List<String> targetIds = entityLinkBizService.listTargetIds(EntityLinkConst.SourceType.COURSE_CATEGORY, courseCategoryId, EntityLinkConst.TargetType.RESOURCE);
|
||||||
|
List<AiolResource> list = new ArrayList<>();
|
||||||
|
for (String targetId : targetIds) {
|
||||||
|
AiolResource resource = aiolResourceService.getById(targetId);
|
||||||
|
if (resource.getType() == EntityLinkConst.ResourceType.IMAGE) {
|
||||||
|
list.add(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.OK(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/video_upload")
|
||||||
|
@Operation(summary = "课程视频文件上传", description = "课程视频文件上传,创建资源记录并关联到课程")
|
||||||
|
public Result<AiolResource> upload(
|
||||||
|
@RequestParam("file") MultipartFile file,
|
||||||
|
@RequestParam("courseId") String courseId,
|
||||||
|
@RequestParam("name") String name,
|
||||||
|
@RequestParam(value = "description", required = false) String description,
|
||||||
|
HttpServletRequest request) throws Exception {
|
||||||
|
|
||||||
|
if (file == null || file.isEmpty()) {
|
||||||
|
return Result.error("没有找到上传的文件");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (courseId == null || courseId.trim().isEmpty()) {
|
||||||
|
return Result.error("课程ID不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == null || name.trim().isEmpty()) {
|
||||||
|
return Result.error("视频名称不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 上传视频文件,获取各清晰度的m3u8地址
|
||||||
|
Map<String, String> qualityUrls = aiolResourceService.uploadHls(file, request);
|
||||||
|
|
||||||
|
// 2. 将m3u8地址用逗号拼接成字符串
|
||||||
|
String fileUrl = String.join(",", qualityUrls.values());
|
||||||
|
|
||||||
|
// 3. TODO 获取视频时长和文件大小
|
||||||
|
Integer duration = (int) 0;
|
||||||
|
Integer fileSize = (int) file.getSize();
|
||||||
|
|
||||||
|
// 4. 创建资源记录
|
||||||
|
AiolResource resource = new AiolResource();
|
||||||
|
resource.setName(name.trim());
|
||||||
|
resource.setDescription(description != null ? description.trim() : "");
|
||||||
|
resource.setType(ResourceTypeConst.VIDEO);
|
||||||
|
resource.setFileUrl(fileUrl);
|
||||||
|
resource.setDuration(duration);
|
||||||
|
resource.setFileSize(fileSize);
|
||||||
|
|
||||||
|
// 5. 保存资源记录
|
||||||
|
boolean saved = aiolResourceService.save(resource);
|
||||||
|
if (!saved) {
|
||||||
|
return Result.error("保存资源记录失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 创建课程与资源的关联关系
|
||||||
|
entityLinkBizService.save(
|
||||||
|
EntityLinkConst.SourceType.COURSE,
|
||||||
|
courseId,
|
||||||
|
EntityLinkConst.TargetType.RESOURCE,
|
||||||
|
resource.getId()
|
||||||
|
);
|
||||||
|
|
||||||
|
log.info("视频上传成功: resourceId={}, courseId={}, name={}",
|
||||||
|
resource.getId(), courseId, name);
|
||||||
|
|
||||||
|
return Result.OK(resource);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("视频上传失败: courseId={}, name={}, error={}",
|
||||||
|
courseId, name, e.getMessage(), e);
|
||||||
|
return Result.error("视频上传失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/document_upload")
|
||||||
|
@Operation(summary = "课程文档文件上传", description = "上传文档文件并关联到课程,支持word、ppt、excel、pdf、txt、markdown等格式")
|
||||||
|
public Result<AiolResource> uploadDocument(
|
||||||
|
@RequestParam("file") MultipartFile file,
|
||||||
|
@RequestParam("courseId") String courseId,
|
||||||
|
@RequestParam("name") String name,
|
||||||
|
@RequestParam(value = "description", required = false) String description,
|
||||||
|
HttpServletRequest request) throws Exception {
|
||||||
|
|
||||||
|
if (file == null || file.isEmpty()) {
|
||||||
|
return Result.error("没有找到上传的文件");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (courseId == null || courseId.trim().isEmpty()) {
|
||||||
|
return Result.error("课程ID不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == null || name.trim().isEmpty()) {
|
||||||
|
return Result.error("文档名称不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查文件类型
|
||||||
|
String originalFilename = file.getOriginalFilename();
|
||||||
|
if (originalFilename == null || !isValidDocumentType(originalFilename)) {
|
||||||
|
return Result.error("不支持的文件类型,仅支持word、ppt、excel、pdf、txt、markdown等格式");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 上传文档文件
|
||||||
|
String fileUrl = uploadDocumentFile(file, request);
|
||||||
|
|
||||||
|
// 2. 获取文件大小
|
||||||
|
Integer fileSize = (int) file.getSize();
|
||||||
|
|
||||||
|
// 3. 创建资源记录
|
||||||
|
AiolResource resource = new AiolResource();
|
||||||
|
resource.setName(name.trim());
|
||||||
|
resource.setDescription(description != null ? description.trim() : "");
|
||||||
|
resource.setType(ResourceTypeConst.DOCUMENT); // 2:文档
|
||||||
|
resource.setFileUrl(fileUrl);
|
||||||
|
resource.setFileSize(fileSize);
|
||||||
|
|
||||||
|
// 4. 保存资源记录
|
||||||
|
boolean saved = aiolResourceService.save(resource);
|
||||||
|
if (!saved) {
|
||||||
|
return Result.error("保存资源记录失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 创建课程与资源的关联关系
|
||||||
|
entityLinkBizService.save(
|
||||||
|
EntityLinkConst.SourceType.COURSE,
|
||||||
|
courseId,
|
||||||
|
EntityLinkConst.TargetType.RESOURCE,
|
||||||
|
resource.getId()
|
||||||
|
);
|
||||||
|
|
||||||
|
log.info("文档上传成功: resourceId={}, courseId={}, name={}",
|
||||||
|
resource.getId(), courseId, name);
|
||||||
|
|
||||||
|
return Result.OK(resource);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("文档上传失败: courseId={}, name={}, error={}",
|
||||||
|
courseId, name, e.getMessage(), e);
|
||||||
|
return Result.error("文档上传失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/image_upload")
|
||||||
|
@Operation(summary = "课程图片文件上传", description = "上传图片文件并关联到课程,支持jpg、jpeg、png、gif、bmp、webp等格式")
|
||||||
|
public Result<AiolResource> uploadImage(
|
||||||
|
@RequestParam("file") MultipartFile file,
|
||||||
|
@RequestParam("courseId") String courseId,
|
||||||
|
@RequestParam("name") String name,
|
||||||
|
@RequestParam(value = "description", required = false) String description,
|
||||||
|
HttpServletRequest request) throws Exception {
|
||||||
|
|
||||||
|
if (file == null || file.isEmpty()) {
|
||||||
|
return Result.error("没有找到上传的文件");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (courseId == null || courseId.trim().isEmpty()) {
|
||||||
|
return Result.error("课程ID不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == null || name.trim().isEmpty()) {
|
||||||
|
return Result.error("图片名称不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查文件类型
|
||||||
|
String originalFilename = file.getOriginalFilename();
|
||||||
|
if (originalFilename == null || !isValidImageType(originalFilename)) {
|
||||||
|
return Result.error("不支持的文件类型,仅支持jpg、jpeg、png、gif、bmp、webp等格式");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 上传图片文件
|
||||||
|
String fileUrl = uploadImageFile(file, request);
|
||||||
|
|
||||||
|
// 2. 获取文件大小
|
||||||
|
Integer fileSize = (int) file.getSize();
|
||||||
|
|
||||||
|
// 3. 创建资源记录
|
||||||
|
AiolResource resource = new AiolResource();
|
||||||
|
resource.setName(name.trim());
|
||||||
|
resource.setDescription(description != null ? description.trim() : "");
|
||||||
|
resource.setType(ResourceTypeConst.IMAGE); // 1:图片
|
||||||
|
resource.setFileUrl(fileUrl);
|
||||||
|
resource.setFileSize(fileSize);
|
||||||
|
|
||||||
|
// 4. 保存资源记录
|
||||||
|
boolean saved = aiolResourceService.save(resource);
|
||||||
|
if (!saved) {
|
||||||
|
return Result.error("保存资源记录失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 创建课程与资源的关联关系
|
||||||
|
entityLinkBizService.save(
|
||||||
|
EntityLinkConst.SourceType.COURSE,
|
||||||
|
courseId,
|
||||||
|
EntityLinkConst.TargetType.RESOURCE,
|
||||||
|
resource.getId()
|
||||||
|
);
|
||||||
|
|
||||||
|
log.info("图片上传成功: resourceId={}, courseId={}, name={}",
|
||||||
|
resource.getId(), courseId, name);
|
||||||
|
|
||||||
|
return Result.OK(resource);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("图片上传失败: courseId={}, name={}, error={}",
|
||||||
|
courseId, name, e.getMessage(), e);
|
||||||
|
return Result.error("图片上传失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/course_materials")
|
||||||
|
@Operation(summary = "查询课程课件", description = "根据课程ID、资源分类和资源名关键词查询课程相关资源")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<AiolResource>> queryCourseMaterials(
|
||||||
|
@RequestParam("courseId") String courseId,
|
||||||
|
@RequestParam(value = "resourceType", required = false) Integer resourceType,
|
||||||
|
@RequestParam(value = "name", required = false) String name) {
|
||||||
|
try {
|
||||||
|
// 1. 根据课程ID查询关联的资源ID列表
|
||||||
|
List<String> resourceIds = entityLinkBizService.listTargetIds(
|
||||||
|
EntityLinkConst.SourceType.COURSE,
|
||||||
|
courseId,
|
||||||
|
EntityLinkConst.TargetType.RESOURCE
|
||||||
|
);
|
||||||
|
|
||||||
|
if (resourceIds.isEmpty()) {
|
||||||
|
return Result.OK(new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 根据资源ID列表查询资源详情
|
||||||
|
QueryWrapper<AiolResource> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.in("id", resourceIds);
|
||||||
|
|
||||||
|
// 3. 根据资源分类过滤
|
||||||
|
if (resourceType != null) {
|
||||||
|
queryWrapper.eq("type", resourceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 根据资源名关键词过滤
|
||||||
|
if (name != null && !name.trim().isEmpty()) {
|
||||||
|
queryWrapper.like("name", name.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<AiolResource> resourceList = aiolResourceService.list(queryWrapper);
|
||||||
|
|
||||||
|
log.info("查询课程课件成功: courseId={}, resourceType={}, name={}, 结果数量={}",
|
||||||
|
courseId, resourceType, name, resourceList.size());
|
||||||
|
|
||||||
|
return Result.OK(resourceList);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询课程课件失败: courseId={}, resourceType={}, name={}, error={}",
|
||||||
|
courseId, resourceType, name, e.getMessage(), e);
|
||||||
|
return Result.error("查询课程课件失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否为有效的文档类型
|
||||||
|
*/
|
||||||
|
private boolean isValidDocumentType(String filename) {
|
||||||
|
if (filename == null) return false;
|
||||||
|
|
||||||
|
String lowerFilename = filename.toLowerCase();
|
||||||
|
return lowerFilename.endsWith(".doc") || lowerFilename.endsWith(".docx") || // Word
|
||||||
|
lowerFilename.endsWith(".ppt") || lowerFilename.endsWith(".pptx") || // PowerPoint
|
||||||
|
lowerFilename.endsWith(".xls") || lowerFilename.endsWith(".xlsx") || // Excel
|
||||||
|
lowerFilename.endsWith(".pdf") || // PDF
|
||||||
|
lowerFilename.endsWith(".txt") || // Text
|
||||||
|
lowerFilename.endsWith(".md") || lowerFilename.endsWith(".markdown"); // Markdown
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否为有效的图片类型
|
||||||
|
*/
|
||||||
|
private boolean isValidImageType(String filename) {
|
||||||
|
if (filename == null) return false;
|
||||||
|
|
||||||
|
String lowerFilename = filename.toLowerCase();
|
||||||
|
return lowerFilename.endsWith(".jpg") || lowerFilename.endsWith(".jpeg") || // JPEG
|
||||||
|
lowerFilename.endsWith(".png") || // PNG
|
||||||
|
lowerFilename.endsWith(".gif") || // GIF
|
||||||
|
lowerFilename.endsWith(".bmp") || // BMP
|
||||||
|
lowerFilename.endsWith(".webp"); // WebP
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文档文件
|
||||||
|
*/
|
||||||
|
private String uploadDocumentFile(MultipartFile file, HttpServletRequest request) throws Exception {
|
||||||
|
// 读取上传类型
|
||||||
|
String configUploadType = SpringContextUtils.getApplicationContext().getEnvironment().getProperty("jeecg.uploadType", "minio");
|
||||||
|
String uploadType = configUploadType;
|
||||||
|
|
||||||
|
// 生成文件路径
|
||||||
|
String uuid = UUID.randomUUID().toString();
|
||||||
|
String originalFilename = file.getOriginalFilename();
|
||||||
|
String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
|
||||||
|
String fileName = uuid + fileExtension;
|
||||||
|
String relativePath = "document/" + fileName;
|
||||||
|
|
||||||
|
try (InputStream inputStream = file.getInputStream()) {
|
||||||
|
String fileUrl = "";
|
||||||
|
if ("minio".equals(uploadType)) {
|
||||||
|
fileUrl = MinioUtil.upload(inputStream, relativePath);
|
||||||
|
} else if ("alioss".equals(uploadType)) {
|
||||||
|
OssBootUtil.upload(inputStream, relativePath);
|
||||||
|
fileUrl = relativePath; // 可在网关拼域名
|
||||||
|
} else {
|
||||||
|
// 本地存储
|
||||||
|
String uploadpath = SpringContextUtils.getApplicationContext().getEnvironment().getProperty("jeecg.path.upload");
|
||||||
|
Path target = Path.of(uploadpath, relativePath);
|
||||||
|
Files.createDirectories(target.getParent());
|
||||||
|
Files.copy(inputStream, target, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
fileUrl = relativePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("文档文件上传成功: originalFilename={}, fileUrl={}", originalFilename, fileUrl);
|
||||||
|
return fileUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传图片文件
|
||||||
|
*/
|
||||||
|
private String uploadImageFile(MultipartFile file, HttpServletRequest request) throws Exception {
|
||||||
|
// 读取上传类型
|
||||||
|
String configUploadType = SpringContextUtils.getApplicationContext().getEnvironment().getProperty("jeecg.uploadType", "minio");
|
||||||
|
String uploadType = configUploadType;
|
||||||
|
|
||||||
|
// 生成文件路径
|
||||||
|
String uuid = UUID.randomUUID().toString();
|
||||||
|
String originalFilename = file.getOriginalFilename();
|
||||||
|
String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
|
||||||
|
String fileName = uuid + fileExtension;
|
||||||
|
String relativePath = "image/" + fileName;
|
||||||
|
|
||||||
|
try (InputStream inputStream = file.getInputStream()) {
|
||||||
|
String fileUrl = "";
|
||||||
|
if ("minio".equals(uploadType)) {
|
||||||
|
fileUrl = MinioUtil.upload(inputStream, relativePath);
|
||||||
|
} else if ("alioss".equals(uploadType)) {
|
||||||
|
OssBootUtil.upload(inputStream, relativePath);
|
||||||
|
fileUrl = relativePath; // 可在网关拼域名
|
||||||
|
} else {
|
||||||
|
// 本地存储
|
||||||
|
String uploadpath = SpringContextUtils.getApplicationContext().getEnvironment().getProperty("jeecg.path.upload");
|
||||||
|
Path target = Path.of(uploadpath, relativePath);
|
||||||
|
Files.createDirectories(target.getParent());
|
||||||
|
Files.copy(inputStream, target, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
fileUrl = relativePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("图片文件上传成功: originalFilename={}, fileUrl={}", originalFilename, fileUrl);
|
||||||
|
return fileUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,470 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolClass;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolClassStudent;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolHomework;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolCourseSection;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolDiscussion;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolEntityLink;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolResource;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolComment;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolClassService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolClassStudentService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolHomeworkService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolCourseSectionService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolDiscussionService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolEntityLinkService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolResourceService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolCommentService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Tag(name = "统计")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/statistics")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolStatisticsController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolClassService aiolClassService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolClassStudentService aiolClassStudentService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolHomeworkService aiolHomeworkService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolCourseSectionService aiolCourseSectionService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolDiscussionService aiolDiscussionService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolEntityLinkService aiolEntityLinkService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolResourceService aiolResourceService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAiolCommentService aiolCommentService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 课程基础数据统计
|
||||||
|
*
|
||||||
|
* @param courseId 课程ID
|
||||||
|
* @return 课程统计数据
|
||||||
|
*/
|
||||||
|
@Operation(summary = "课程基础数据统计", description = "统计课程下的学生人数、班级数量、作业数量、考试数量、练习数量、讨论数量")
|
||||||
|
@GetMapping(value = "/course-basic-stats")
|
||||||
|
public Result<Map<String, Object>> getCourseBasicStats(@RequestParam(name = "courseId", required = true) String courseId) {
|
||||||
|
try {
|
||||||
|
log.info("开始统计课程基础数据,课程ID: {}", courseId);
|
||||||
|
|
||||||
|
Map<String, Object> stats = new HashMap<>();
|
||||||
|
|
||||||
|
// 1. 统计课程下班级数量
|
||||||
|
long classCount = getClassCount(courseId);
|
||||||
|
stats.put("classCount", classCount);
|
||||||
|
|
||||||
|
// 2. 统计课程下学生人数
|
||||||
|
long studentCount = getStudentCount(courseId);
|
||||||
|
stats.put("studentCount", studentCount);
|
||||||
|
|
||||||
|
// 3. 统计课程下作业数量
|
||||||
|
long homeworkCount = getHomeworkCount(courseId);
|
||||||
|
stats.put("homeworkCount", homeworkCount);
|
||||||
|
|
||||||
|
// 4. 统计课程下考试数量 (type=2)
|
||||||
|
long examCount = getExamCount(courseId);
|
||||||
|
stats.put("examCount", examCount);
|
||||||
|
|
||||||
|
// 5. 统计课程下练习数量 (type=4)
|
||||||
|
long practiceCount = getPracticeCount(courseId);
|
||||||
|
stats.put("practiceCount", practiceCount);
|
||||||
|
|
||||||
|
// 6. 统计课程下讨论数量
|
||||||
|
long discussionCount = getDiscussionCount(courseId);
|
||||||
|
stats.put("discussionCount", discussionCount);
|
||||||
|
|
||||||
|
log.info("课程基础数据统计完成,课程ID: {}, 统计结果: {}", courseId, stats);
|
||||||
|
return Result.OK(stats);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("课程基础数据统计失败,课程ID: {}, 错误: {}", courseId, e.getMessage(), e);
|
||||||
|
return Result.error("统计失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计课程下班级数量
|
||||||
|
*
|
||||||
|
* @param courseId 课程ID
|
||||||
|
* @return 班级数量
|
||||||
|
*/
|
||||||
|
private long getClassCount(String courseId) {
|
||||||
|
QueryWrapper<AiolClass> classQuery = new QueryWrapper<>();
|
||||||
|
classQuery.eq("course_id", courseId);
|
||||||
|
long count = aiolClassService.count(classQuery);
|
||||||
|
log.debug("课程 {} 班级数量: {}", courseId, count);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计课程下学生人数
|
||||||
|
*
|
||||||
|
* @param courseId 课程ID
|
||||||
|
* @return 学生人数
|
||||||
|
*/
|
||||||
|
private long getStudentCount(String courseId) {
|
||||||
|
// 1. 先查询课程下的所有班级
|
||||||
|
QueryWrapper<AiolClass> classQuery = new QueryWrapper<>();
|
||||||
|
classQuery.eq("course_id", courseId);
|
||||||
|
List<AiolClass> classList = aiolClassService.list(classQuery);
|
||||||
|
|
||||||
|
if (classList.isEmpty()) {
|
||||||
|
log.debug("课程 {} 没有班级,学生人数为 0", courseId);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 收集所有班级ID
|
||||||
|
List<String> classIds = classList.stream()
|
||||||
|
.map(AiolClass::getId)
|
||||||
|
.collect(java.util.stream.Collectors.toList());
|
||||||
|
|
||||||
|
// 3. 查询这些班级下的所有学生,使用Set去重
|
||||||
|
QueryWrapper<AiolClassStudent> studentQuery = new QueryWrapper<>();
|
||||||
|
studentQuery.in("class_id", classIds);
|
||||||
|
List<AiolClassStudent> studentList = aiolClassStudentService.list(studentQuery);
|
||||||
|
|
||||||
|
// 4. 去重统计学生人数(一个学生可能在多个班级中)
|
||||||
|
Set<String> uniqueStudentIds = new HashSet<>();
|
||||||
|
for (AiolClassStudent student : studentList) {
|
||||||
|
uniqueStudentIds.add(student.getStudentId());
|
||||||
|
}
|
||||||
|
|
||||||
|
long count = uniqueStudentIds.size();
|
||||||
|
log.debug("课程 {} 学生人数: {} (去重后)", courseId, count);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计课程下作业数量
|
||||||
|
*
|
||||||
|
* @param courseId 课程ID
|
||||||
|
* @return 作业数量
|
||||||
|
*/
|
||||||
|
private long getHomeworkCount(String courseId) {
|
||||||
|
QueryWrapper<AiolHomework> homeworkQuery = new QueryWrapper<>();
|
||||||
|
homeworkQuery.eq("course_id", courseId);
|
||||||
|
long count = aiolHomeworkService.count(homeworkQuery);
|
||||||
|
log.debug("课程 {} 作业数量: {}", courseId, count);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计课程下考试数量 (type=2)
|
||||||
|
*
|
||||||
|
* @param courseId 课程ID
|
||||||
|
* @return 考试数量
|
||||||
|
*/
|
||||||
|
private long getExamCount(String courseId) {
|
||||||
|
QueryWrapper<AiolCourseSection> examQuery = new QueryWrapper<>();
|
||||||
|
examQuery.eq("course_id", courseId)
|
||||||
|
.eq("type", 2);
|
||||||
|
long count = aiolCourseSectionService.count(examQuery);
|
||||||
|
log.debug("课程 {} 考试数量: {}", courseId, count);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计课程下练习数量 (type=4)
|
||||||
|
*
|
||||||
|
* @param courseId 课程ID
|
||||||
|
* @return 练习数量
|
||||||
|
*/
|
||||||
|
private long getPracticeCount(String courseId) {
|
||||||
|
QueryWrapper<AiolCourseSection> practiceQuery = new QueryWrapper<>();
|
||||||
|
practiceQuery.eq("course_id", courseId)
|
||||||
|
.eq("type", 4);
|
||||||
|
long count = aiolCourseSectionService.count(practiceQuery);
|
||||||
|
log.debug("课程 {} 练习数量: {}", courseId, count);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计课程下讨论数量
|
||||||
|
*
|
||||||
|
* @param courseId 课程ID
|
||||||
|
* @return 讨论数量
|
||||||
|
*/
|
||||||
|
private long getDiscussionCount(String courseId) {
|
||||||
|
QueryWrapper<AiolDiscussion> discussionQuery = new QueryWrapper<>();
|
||||||
|
discussionQuery.eq("course_id", courseId);
|
||||||
|
long count = aiolDiscussionService.count(discussionQuery);
|
||||||
|
log.debug("课程 {} 讨论数量: {}", courseId, count);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 课程教学建设数据统计
|
||||||
|
*
|
||||||
|
* @param courseId 课程ID
|
||||||
|
* @return 课程教学建设统计数据
|
||||||
|
*/
|
||||||
|
@Operation(summary = "课程教学建设数据统计", description = "统计课程下的课件/视频数量、资料/文档数量、题库数量、试卷数量")
|
||||||
|
@GetMapping(value = "/course-teaching-stats")
|
||||||
|
public Result<Map<String, Object>> getCourseTeachingStats(@RequestParam(name = "courseId", required = true) String courseId) {
|
||||||
|
try {
|
||||||
|
log.info("开始统计课程教学建设数据,课程ID: {}", courseId);
|
||||||
|
|
||||||
|
Map<String, Object> stats = new HashMap<>();
|
||||||
|
|
||||||
|
// 1. 统计课件/视频数量和资料/文档数量
|
||||||
|
Map<String, Long> resourceStats = getResourceStats(courseId);
|
||||||
|
stats.put("videoCount", resourceStats.get("videoCount"));
|
||||||
|
stats.put("documentCount", resourceStats.get("documentCount"));
|
||||||
|
|
||||||
|
// 2. 统计题库数量
|
||||||
|
long questionCount = getQuestionCount(courseId);
|
||||||
|
stats.put("questionCount", questionCount);
|
||||||
|
|
||||||
|
log.info("课程教学建设数据统计完成,课程ID: {}, 统计结果: {}", courseId, stats);
|
||||||
|
return Result.OK(stats);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("课程教学建设数据统计失败,课程ID: {}, 错误: {}", courseId, e.getMessage(), e);
|
||||||
|
return Result.error("统计失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计课程下资源数量(视频和文档)
|
||||||
|
*
|
||||||
|
* @param courseId 课程ID
|
||||||
|
* @return 资源统计结果
|
||||||
|
*/
|
||||||
|
private Map<String, Long> getResourceStats(String courseId) {
|
||||||
|
Map<String, Long> resourceStats = new HashMap<>();
|
||||||
|
long videoCount = 0;
|
||||||
|
long documentCount = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 查询课程关联的资源链接
|
||||||
|
QueryWrapper<AiolEntityLink> linkQuery = new QueryWrapper<>();
|
||||||
|
linkQuery.eq("source_type", "course")
|
||||||
|
.eq("source_id", courseId)
|
||||||
|
.eq("target_type", "resource");
|
||||||
|
|
||||||
|
List<AiolEntityLink> entityLinks = aiolEntityLinkService.list(linkQuery);
|
||||||
|
log.debug("课程 {} 关联的资源链接数量: {}", courseId, entityLinks.size());
|
||||||
|
|
||||||
|
if (!entityLinks.isEmpty()) {
|
||||||
|
// 2. 收集所有资源ID
|
||||||
|
List<String> resourceIds = entityLinks.stream()
|
||||||
|
.map(AiolEntityLink::getTargetId)
|
||||||
|
.collect(java.util.stream.Collectors.toList());
|
||||||
|
|
||||||
|
// 3. 查询资源详情并按类型统计
|
||||||
|
QueryWrapper<AiolResource> resourceQuery = new QueryWrapper<>();
|
||||||
|
resourceQuery.in("id", resourceIds);
|
||||||
|
List<AiolResource> resources = aiolResourceService.list(resourceQuery);
|
||||||
|
|
||||||
|
// 4. 按类型分类统计
|
||||||
|
for (AiolResource resource : resources) {
|
||||||
|
Integer type = resource.getType();
|
||||||
|
if (type != null) {
|
||||||
|
if (type == 0) {
|
||||||
|
// 视频类型
|
||||||
|
videoCount++;
|
||||||
|
} else if (type == 1 || type == 2) {
|
||||||
|
// 图片(1)和文档(2)统称为资料/文档
|
||||||
|
documentCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("课程 {} 资源统计完成 - 视频: {}, 文档: {}", courseId, videoCount, documentCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("统计课程 {} 资源数量时发生异常: {}", courseId, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceStats.put("videoCount", videoCount);
|
||||||
|
resourceStats.put("documentCount", documentCount);
|
||||||
|
return resourceStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计课程下题库数量
|
||||||
|
*
|
||||||
|
* @param courseId 课程ID
|
||||||
|
* @return 题库数量
|
||||||
|
*/
|
||||||
|
private long getQuestionCount(String courseId) {
|
||||||
|
QueryWrapper<AiolEntityLink> repoQuery = new QueryWrapper<>();
|
||||||
|
repoQuery.eq("source_type", "course")
|
||||||
|
.eq("source_id", courseId)
|
||||||
|
.eq("target_type", "repo");
|
||||||
|
long count = aiolEntityLinkService.count(repoQuery);
|
||||||
|
log.debug("课程 {} 题库数量: {}", courseId, count);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 课程评论数量统计(按天)
|
||||||
|
*
|
||||||
|
* @param courseId 课程ID
|
||||||
|
* @param limit 天数限制,统计从今天往前limit天的数据
|
||||||
|
* @return 每天的评论数量统计
|
||||||
|
*/
|
||||||
|
@Operation(summary = "课程评论数量统计", description = "统计课程下指定天数内每天的评论数量,包括子评论")
|
||||||
|
@GetMapping(value = "/course-comment-stats")
|
||||||
|
public Result<Map<String, Object>> getCourseCommentStats(
|
||||||
|
@RequestParam(name = "courseId", required = true) String courseId,
|
||||||
|
@RequestParam(name = "limit", defaultValue = "7") Integer limit) {
|
||||||
|
try {
|
||||||
|
log.info("开始统计课程评论数据,课程ID: {}, 天数限制: {}", courseId, limit);
|
||||||
|
|
||||||
|
// 1. 查询课程的直接评论
|
||||||
|
List<AiolComment> courseComments = getCourseDirectComments(courseId, limit);
|
||||||
|
log.debug("课程 {} 直接评论数量: {}", courseId, courseComments.size());
|
||||||
|
|
||||||
|
// 2. 递归查询所有子评论
|
||||||
|
List<AiolComment> allComments = new ArrayList<>(courseComments);
|
||||||
|
for (AiolComment comment : courseComments) {
|
||||||
|
List<AiolComment> subComments = getAllSubComments(comment.getId());
|
||||||
|
allComments.addAll(subComments);
|
||||||
|
}
|
||||||
|
log.debug("课程 {} 总评论数量(含子评论): {}", courseId, allComments.size());
|
||||||
|
|
||||||
|
// 3. 按日期分组统计
|
||||||
|
Map<String, Long> dailyStats = groupCommentsByDate(allComments, limit);
|
||||||
|
|
||||||
|
// 4. 构建返回结果
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
result.put("courseId", courseId);
|
||||||
|
result.put("limit", limit);
|
||||||
|
result.put("totalComments", allComments.size());
|
||||||
|
result.put("dailyStats", dailyStats);
|
||||||
|
|
||||||
|
log.info("课程评论数据统计完成,课程ID: {}, 总评论数: {}", courseId, allComments.size());
|
||||||
|
return Result.OK(result);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("课程评论数据统计失败,课程ID: {}, 错误: {}", courseId, e.getMessage(), e);
|
||||||
|
return Result.error("统计失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取课程的直接评论(指定天数内)
|
||||||
|
*
|
||||||
|
* @param courseId 课程ID
|
||||||
|
* @param limit 天数限制
|
||||||
|
* @return 课程直接评论列表
|
||||||
|
*/
|
||||||
|
private List<AiolComment> getCourseDirectComments(String courseId, Integer limit) {
|
||||||
|
QueryWrapper<AiolComment> commentQuery = new QueryWrapper<>();
|
||||||
|
commentQuery.eq("target_type", "course")
|
||||||
|
.eq("target_id", courseId);
|
||||||
|
|
||||||
|
// 添加时间范围限制
|
||||||
|
if (limit != null && limit > 0) {
|
||||||
|
LocalDateTime startTime = LocalDate.now().minusDays(limit - 1).atStartOfDay();
|
||||||
|
Date startDate = Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant());
|
||||||
|
commentQuery.ge("create_time", startDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
commentQuery.orderByDesc("create_time");
|
||||||
|
return aiolCommentService.list(commentQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归获取评论的所有子评论
|
||||||
|
*
|
||||||
|
* @param commentId 父评论ID
|
||||||
|
* @return 所有子评论列表
|
||||||
|
*/
|
||||||
|
private List<AiolComment> getAllSubComments(String commentId) {
|
||||||
|
List<AiolComment> allSubComments = new ArrayList<>();
|
||||||
|
|
||||||
|
// 查询直接子评论
|
||||||
|
QueryWrapper<AiolComment> subCommentQuery = new QueryWrapper<>();
|
||||||
|
subCommentQuery.eq("target_type", "comment")
|
||||||
|
.eq("target_id", commentId)
|
||||||
|
.orderByDesc("create_time");
|
||||||
|
|
||||||
|
List<AiolComment> directSubComments = aiolCommentService.list(subCommentQuery);
|
||||||
|
allSubComments.addAll(directSubComments);
|
||||||
|
|
||||||
|
// 递归查询子评论的子评论
|
||||||
|
for (AiolComment subComment : directSubComments) {
|
||||||
|
List<AiolComment> subSubComments = getAllSubComments(subComment.getId());
|
||||||
|
allSubComments.addAll(subSubComments);
|
||||||
|
}
|
||||||
|
|
||||||
|
return allSubComments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按日期分组统计评论数量
|
||||||
|
*
|
||||||
|
* @param comments 所有评论列表
|
||||||
|
* @param limit 天数限制
|
||||||
|
* @return 每日评论数量统计
|
||||||
|
*/
|
||||||
|
private Map<String, Long> groupCommentsByDate(List<AiolComment> comments, Integer limit) {
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||||
|
|
||||||
|
// 初始化指定天数的日期统计(确保每天都有数据,即使是0)
|
||||||
|
Map<String, Long> dailyStats = new LinkedHashMap<>();
|
||||||
|
for (int i = limit - 1; i >= 0; i--) {
|
||||||
|
String date = LocalDate.now().minusDays(i).format(formatter);
|
||||||
|
dailyStats.put(date, 0L);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按创建日期分组统计评论数量
|
||||||
|
Map<String, Long> commentStats = comments.stream()
|
||||||
|
.filter(comment -> comment.getCreateTime() != null)
|
||||||
|
.collect(Collectors.groupingBy(
|
||||||
|
comment -> {
|
||||||
|
Date createTime = comment.getCreateTime();
|
||||||
|
LocalDateTime localDateTime = createTime.toInstant()
|
||||||
|
.atZone(ZoneId.systemDefault())
|
||||||
|
.toLocalDateTime();
|
||||||
|
return localDateTime.toLocalDate().format(formatter);
|
||||||
|
},
|
||||||
|
Collectors.counting()
|
||||||
|
));
|
||||||
|
|
||||||
|
// 合并统计结果
|
||||||
|
commentStats.forEach((date, count) -> {
|
||||||
|
if (dailyStats.containsKey(date)) {
|
||||||
|
dailyStats.put(date, count);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return dailyStats;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,182 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolTag;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolTagService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 标签
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="标签")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolTag")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolTagController extends JeecgController<AiolTag, IAiolTagService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolTagService aiolTagService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolTag
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "标签-分页列表查询")
|
||||||
|
@Operation(summary="标签-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolTag>> queryPageList(AiolTag aiolTag,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolTag> queryWrapper = QueryGenerator.initQueryWrapper(aiolTag, req.getParameterMap());
|
||||||
|
Page<AiolTag> page = new Page<AiolTag>(pageNo, pageSize);
|
||||||
|
IPage<AiolTag> pageList = aiolTagService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolTag
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "标签-添加")
|
||||||
|
@Operation(summary="标签-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_tag:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolTag aiolTag) {
|
||||||
|
aiolTagService.save(aiolTag);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolTag
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "标签-编辑")
|
||||||
|
@Operation(summary="标签-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_tag:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolTag aiolTag) {
|
||||||
|
aiolTagService.updateById(aiolTag);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "标签-通过id删除")
|
||||||
|
@Operation(summary="标签-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_tag:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolTagService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "标签-批量删除")
|
||||||
|
@Operation(summary="标签-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_tag:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolTagService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "标签-通过id查询")
|
||||||
|
@Operation(summary="标签-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolTag> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolTag aiolTag = aiolTagService.getById(id);
|
||||||
|
if(aiolTag==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolTag
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_tag:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolTag aiolTag) {
|
||||||
|
return super.exportXls(request, aiolTag, AiolTag.class, "标签");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_tag:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolTag.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,495 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
|
import org.jeecg.common.system.vo.DictModel;
|
||||||
|
import org.jeecg.common.util.PasswordUtil;
|
||||||
|
import org.jeecg.common.util.RedisUtil;
|
||||||
|
import org.jeecg.config.shiro.IgnoreAuth;
|
||||||
|
import org.jeecg.modules.aiol.dto.TeacherInfo;
|
||||||
|
import org.jeecg.modules.aiol.dto.UserInfoResponse;
|
||||||
|
import org.jeecg.modules.aiol.dto.EditProfileDTO;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolClass;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolClassStudent;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolUserInfo;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolUserInfoMapper;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolClassService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolClassStudentService;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolUserInfoService;
|
||||||
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
|
import org.jeecg.modules.system.service.ISysUserService;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Tag(name = "前台用户")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolUser")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolUserController {
|
||||||
|
@Autowired
|
||||||
|
private ISysUserService sysUserService;
|
||||||
|
@Autowired
|
||||||
|
private RedisUtil redisUtil;
|
||||||
|
@Autowired
|
||||||
|
private IAiolUserInfoService userBizService;
|
||||||
|
@Autowired
|
||||||
|
private AiolUserInfoMapper userInfoMapper;
|
||||||
|
@Autowired
|
||||||
|
private ISysBaseAPI sysBaseApi;
|
||||||
|
@Autowired
|
||||||
|
private IAiolClassService aiolClassService;
|
||||||
|
@Autowired
|
||||||
|
private IAiolClassStudentService aiolClassStudentService;
|
||||||
|
|
||||||
|
@PostMapping("/login")
|
||||||
|
@Operation(summary = "用户登录")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<JSONObject> login(@RequestBody Map<String, String> user, HttpServletRequest request) {
|
||||||
|
Result<JSONObject> result = new Result<JSONObject>();
|
||||||
|
String username = user.get("username");
|
||||||
|
String password = user.get("password");
|
||||||
|
if (isLoginFailOvertimes(username)) {
|
||||||
|
return result.error500("该用户登录失败次数过多,请于10分钟后再次登录!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// step.2 校验用户是否存在且有效
|
||||||
|
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysUser::getUsername, username);
|
||||||
|
SysUser sysUser = sysUserService.getOne(queryWrapper);
|
||||||
|
Result<?> checkResult = sysUserService.checkUserIsEffective(sysUser);
|
||||||
|
if (!checkResult.isSuccess()) {
|
||||||
|
return result.error500(checkResult.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// step.3 校验用户名或密码是否正确
|
||||||
|
String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt());
|
||||||
|
String syspassword = sysUser.getPassword();
|
||||||
|
if (!syspassword.equals(userpassword)) {
|
||||||
|
addLoginFailOvertimes(username);
|
||||||
|
result.error500("用户名或密码错误");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// step.4 登录成功获取用户信息
|
||||||
|
JSONObject obj = new JSONObject(new LinkedHashMap<>());
|
||||||
|
// 1.生成token
|
||||||
|
String token = JwtUtil.sign(username, syspassword);
|
||||||
|
// 设置token缓存有效时间
|
||||||
|
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
||||||
|
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
|
||||||
|
obj.put("token", token);
|
||||||
|
|
||||||
|
// TODO 查询用户信息
|
||||||
|
|
||||||
|
result.setResult(obj);
|
||||||
|
result.success("登录成功");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录失败超出次数5 返回true
|
||||||
|
*
|
||||||
|
* @param username
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean isLoginFailOvertimes(String username) {
|
||||||
|
String key = CommonConstant.LOGIN_FAIL + username;
|
||||||
|
Object failTime = redisUtil.get(key);
|
||||||
|
if (failTime != null) {
|
||||||
|
Integer val = Integer.parseInt(failTime.toString());
|
||||||
|
if (val > 5) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录登录失败次数
|
||||||
|
*
|
||||||
|
* @param username
|
||||||
|
*/
|
||||||
|
private void addLoginFailOvertimes(String username) {
|
||||||
|
String key = CommonConstant.LOGIN_FAIL + username;
|
||||||
|
Object failTime = redisUtil.get(key);
|
||||||
|
Integer val = 0;
|
||||||
|
if (failTime != null) {
|
||||||
|
val = Integer.parseInt(failTime.toString());
|
||||||
|
}
|
||||||
|
// 10分钟,一分钟为60s
|
||||||
|
redisUtil.set(key, ++val, 600);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/all_teachers")
|
||||||
|
@Operation(summary = "查询师资力量", description = "categoryId为all则查询全部")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<TeacherInfo>> queryAllTeachers(@RequestParam("categoryId") String categoryId) {
|
||||||
|
List<TeacherInfo> list = userBizService.queryAllTeachers(categoryId);
|
||||||
|
return Result.OK(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/info")
|
||||||
|
@Operation(summary = "查询用户信息", description = "通过JWT token获取当前用户的详细信息,包括基本信息、角色和扩展信息")
|
||||||
|
public Result<UserInfoResponse> queryUserInfo(HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
// 1. 从JWT中获取用户名
|
||||||
|
String username = JwtUtil.getUserNameByToken(request);
|
||||||
|
if (username == null || username.trim().isEmpty()) {
|
||||||
|
return Result.error(401, "用户未登录或token无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 根据用户名查询系统用户信息
|
||||||
|
SysUser sysUser = sysUserService.getUserByName(username);
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error(404, "用户不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 查询用户角色
|
||||||
|
List<String> roles = sysUserService.getUserRolesSet(username).stream()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 4. 根据用户ID查询user_info表信息
|
||||||
|
AiolUserInfo userInfo = userInfoMapper.selectOne(
|
||||||
|
new QueryWrapper<AiolUserInfo>().eq("user_id", sysUser.getId()));
|
||||||
|
|
||||||
|
// 5. 构建返回结果
|
||||||
|
UserInfoResponse response = new UserInfoResponse();
|
||||||
|
|
||||||
|
// 基本用户信息
|
||||||
|
UserInfoResponse.BaseInfo baseInfo = new UserInfoResponse.BaseInfo();
|
||||||
|
BeanUtils.copyProperties(sysUser, baseInfo);
|
||||||
|
response.setBaseInfo(baseInfo);
|
||||||
|
response.setRoles(roles);
|
||||||
|
|
||||||
|
// 扩展用户信息
|
||||||
|
if (userInfo != null) {
|
||||||
|
UserInfoResponse.ExtendedInfo extendedInfo = new UserInfoResponse.ExtendedInfo();
|
||||||
|
BeanUtils.copyProperties(userInfo, extendedInfo);
|
||||||
|
response.setExtendedInfo(extendedInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.OK(response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询用户信息失败:" + e.getMessage(), e);
|
||||||
|
return Result.error(500, "查询用户信息失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/schools")
|
||||||
|
@Operation(summary = "查询学校列表")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<String>> querySchools() {
|
||||||
|
List<DictModel> list = sysBaseApi.getDictItems("school_list");
|
||||||
|
List<String> schools = list.stream()
|
||||||
|
.map(d -> d.getLabel())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return Result.OK(schools);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/teachers")
|
||||||
|
@Operation(summary = "查询所有教师用户", description = "支持按教师姓名和工号进行可选查询")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<Map<String, Object>>> queryAllTeachers(
|
||||||
|
@RequestParam(value = "realName", required = false) String realName,
|
||||||
|
@RequestParam(value = "workNo", required = false) String workNo) {
|
||||||
|
try {
|
||||||
|
// 构建查询条件
|
||||||
|
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
|
||||||
|
// 只查询教师角色的用户
|
||||||
|
queryWrapper.inSql(SysUser::getId,
|
||||||
|
"SELECT user_id FROM sys_user_role WHERE role_id = '1955367301787348993'"); // 教师角色ID
|
||||||
|
|
||||||
|
// 可选条件:按姓名查询
|
||||||
|
if (realName != null && !realName.trim().isEmpty()) {
|
||||||
|
queryWrapper.like(SysUser::getRealname, realName.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 可选条件:按工号查询
|
||||||
|
if (workNo != null && !workNo.trim().isEmpty()) {
|
||||||
|
queryWrapper.like(SysUser::getWorkNo, workNo.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询用户列表
|
||||||
|
List<SysUser> teachers = sysUserService.list(queryWrapper);
|
||||||
|
|
||||||
|
// 构建返回结果
|
||||||
|
List<Map<String, Object>> result = teachers.stream().map(teacher -> {
|
||||||
|
Map<String, Object> teacherInfo = new LinkedHashMap<>();
|
||||||
|
teacherInfo.put("id", teacher.getId());
|
||||||
|
teacherInfo.put("username", teacher.getUsername());
|
||||||
|
teacherInfo.put("realname", teacher.getRealname());
|
||||||
|
teacherInfo.put("workNo", teacher.getWorkNo());
|
||||||
|
teacherInfo.put("phone", teacher.getPhone());
|
||||||
|
teacherInfo.put("email", teacher.getEmail());
|
||||||
|
teacherInfo.put("avatar", teacher.getAvatar());
|
||||||
|
teacherInfo.put("status", teacher.getStatus());
|
||||||
|
teacherInfo.put("createTime", teacher.getCreateTime());
|
||||||
|
|
||||||
|
// 查询扩展信息
|
||||||
|
AiolUserInfo userInfo = userInfoMapper.selectOne(
|
||||||
|
new QueryWrapper<AiolUserInfo>().eq("user_id", teacher.getId()));
|
||||||
|
if (userInfo != null) {
|
||||||
|
teacherInfo.put("major", userInfo.getMajor());
|
||||||
|
teacherInfo.put("college", userInfo.getCollege());
|
||||||
|
teacherInfo.put("education", userInfo.getEducation());
|
||||||
|
teacherInfo.put("title", userInfo.getTitle());
|
||||||
|
teacherInfo.put("tag", userInfo.getTag());
|
||||||
|
}
|
||||||
|
|
||||||
|
return teacherInfo;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
return Result.OK(result);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询教师用户失败: realName={}, workNo={}, error={}", realName, workNo, e.getMessage(), e);
|
||||||
|
return Result.error("查询教师用户失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/register")
|
||||||
|
@Operation(summary = "学生注册", description = "学生通过学号、邀请码和密码进行注册,注册成功后自动加入对应班级")
|
||||||
|
@IgnoreAuth
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Result<JSONObject> studentRegister(@RequestBody Map<String, String> registerData) {
|
||||||
|
Result<JSONObject> result = new Result<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 获取注册参数
|
||||||
|
String studentNumber = registerData.get("studentNumber");
|
||||||
|
String inviteCode = registerData.get("inviteCode");
|
||||||
|
String password = registerData.get("password");
|
||||||
|
|
||||||
|
// 2. 参数验证
|
||||||
|
if (studentNumber == null || studentNumber.trim().isEmpty()) {
|
||||||
|
return result.error500("学号不能为空");
|
||||||
|
}
|
||||||
|
if (inviteCode == null || inviteCode.trim().isEmpty()) {
|
||||||
|
return result.error500("邀请码不能为空");
|
||||||
|
}
|
||||||
|
if (password == null || password.trim().isEmpty()) {
|
||||||
|
return result.error500("密码不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 检查学号是否已被注册
|
||||||
|
SysUser existingUser = sysUserService.getUserByName(studentNumber);
|
||||||
|
if (existingUser != null) {
|
||||||
|
return result.error500("学号已被注册,请使用其他学号");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 检查邀请码是否对应某个班级
|
||||||
|
LambdaQueryWrapper<AiolClass> classQuery = new LambdaQueryWrapper<>();
|
||||||
|
classQuery.eq(AiolClass::getInviteCode, inviteCode);
|
||||||
|
// 允许存在重复邀请码时仅取第一条,避免抛出“期望1条结果却查询到多条”的异常
|
||||||
|
AiolClass targetClass = aiolClassService.getOne(classQuery, false);
|
||||||
|
if (targetClass == null) {
|
||||||
|
return result.error500("邀请码无效,请检查邀请码是否正确");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 使用通用方法创建学生用户
|
||||||
|
SysUser studentUser = sysUserService.createStudentUser(studentNumber, studentNumber, password);
|
||||||
|
|
||||||
|
// 6. 设置工号(学号)
|
||||||
|
studentUser.setWorkNo(studentNumber);
|
||||||
|
sysUserService.updateById(studentUser);
|
||||||
|
|
||||||
|
// 7. 自动加入班级
|
||||||
|
AiolClassStudent classStudent = new AiolClassStudent();
|
||||||
|
classStudent.setClassId(targetClass.getId());
|
||||||
|
classStudent.setStudentId(studentUser.getId());
|
||||||
|
classStudent.setCreateBy("system"); // 系统创建
|
||||||
|
classStudent.setCreateTime(new Date());
|
||||||
|
|
||||||
|
boolean classStudentSaved = aiolClassStudentService.save(classStudent);
|
||||||
|
if (!classStudentSaved) {
|
||||||
|
throw new RuntimeException("加入班级失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. 构建返回结果
|
||||||
|
JSONObject response = new JSONObject();
|
||||||
|
response.put("userId", studentUser.getId());
|
||||||
|
response.put("username", studentUser.getUsername());
|
||||||
|
response.put("workNo", studentUser.getWorkNo());
|
||||||
|
response.put("classId", targetClass.getId());
|
||||||
|
response.put("className", targetClass.getName());
|
||||||
|
response.put("message", "注册成功,已自动加入班级:" + targetClass.getName());
|
||||||
|
|
||||||
|
log.info("学生注册成功: 学号={}, 班级ID={}, 班级名={}",
|
||||||
|
studentNumber, targetClass.getId(), targetClass.getName());
|
||||||
|
|
||||||
|
result.setResult(response);
|
||||||
|
result.success("注册成功");
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("学生注册失败: {}", e.getMessage(), e);
|
||||||
|
return result.error500("注册失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/edit_profile")
|
||||||
|
@Operation(summary = "编辑个人信息", description = "更新用户的基本信息和扩展信息,分别存储到sys_user和aiol_user_info表")
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Result<String> editProfile(@RequestBody EditProfileDTO profileDTO, HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
// 1. 从JWT中获取当前用户信息
|
||||||
|
String username = JwtUtil.getUserNameByToken(request);
|
||||||
|
if (username == null || username.trim().isEmpty()) {
|
||||||
|
return Result.error(401, "用户未登录或token无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
SysUser currentUser = sysUserService.getUserByName(username);
|
||||||
|
if (currentUser == null) {
|
||||||
|
return Result.error(404, "用户不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
String id = currentUser.getId();
|
||||||
|
|
||||||
|
// 2. 更新sys_user表的基本信息
|
||||||
|
SysUser userToUpdate = new SysUser();
|
||||||
|
userToUpdate.setId(id);
|
||||||
|
|
||||||
|
if (profileDTO.getRealname() != null) {
|
||||||
|
userToUpdate.setRealname(profileDTO.getRealname());
|
||||||
|
}
|
||||||
|
if (profileDTO.getAvatar() != null) {
|
||||||
|
userToUpdate.setAvatar(profileDTO.getAvatar());
|
||||||
|
}
|
||||||
|
if (profileDTO.getBirthday() != null) {
|
||||||
|
userToUpdate.setBirthday(profileDTO.getBirthday());
|
||||||
|
}
|
||||||
|
if (profileDTO.getSex() != null) {
|
||||||
|
userToUpdate.setSex(profileDTO.getSex());
|
||||||
|
}
|
||||||
|
if (profileDTO.getEmail() != null) {
|
||||||
|
userToUpdate.setEmail(profileDTO.getEmail());
|
||||||
|
}
|
||||||
|
if (profileDTO.getPhone() != null) {
|
||||||
|
userToUpdate.setPhone(profileDTO.getPhone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置更新信息
|
||||||
|
userToUpdate.setUpdateBy(username);
|
||||||
|
userToUpdate.setUpdateTime(new Date());
|
||||||
|
|
||||||
|
boolean userUpdated = sysUserService.updateById(userToUpdate);
|
||||||
|
if (!userUpdated) {
|
||||||
|
return Result.error(500, "更新用户基本信息失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 更新aiol_user_info表的扩展信息
|
||||||
|
AiolUserInfo userInfo = userInfoMapper.selectOne(
|
||||||
|
new QueryWrapper<AiolUserInfo>().eq("user_id", id));
|
||||||
|
|
||||||
|
if (userInfo == null) {
|
||||||
|
// 如果扩展信息不存在,创建新记录
|
||||||
|
userInfo = new AiolUserInfo();
|
||||||
|
userInfo.setUserId(id);
|
||||||
|
userInfo.setCreateBy(username);
|
||||||
|
userInfo.setCreateTime(new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新扩展信息字段
|
||||||
|
if (profileDTO.getMajor() != null) {
|
||||||
|
userInfo.setMajor(profileDTO.getMajor());
|
||||||
|
}
|
||||||
|
if (profileDTO.getCollege() != null) {
|
||||||
|
userInfo.setCollege(profileDTO.getCollege());
|
||||||
|
}
|
||||||
|
if (profileDTO.getEducation() != null) {
|
||||||
|
userInfo.setEducation(profileDTO.getEducation());
|
||||||
|
}
|
||||||
|
if (profileDTO.getTitle() != null) {
|
||||||
|
userInfo.setTitle(profileDTO.getTitle());
|
||||||
|
}
|
||||||
|
if (profileDTO.getTag() != null) {
|
||||||
|
userInfo.setTag(profileDTO.getTag());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置更新信息
|
||||||
|
userInfo.setUpdateBy(username);
|
||||||
|
userInfo.setUpdateTime(new Date());
|
||||||
|
|
||||||
|
boolean userInfoUpdated;
|
||||||
|
if (userInfo.getId() == null) {
|
||||||
|
// 新增记录
|
||||||
|
userInfoUpdated = userInfoMapper.insert(userInfo) > 0;
|
||||||
|
} else {
|
||||||
|
// 更新记录
|
||||||
|
userInfoUpdated = userInfoMapper.updateById(userInfo) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!userInfoUpdated) {
|
||||||
|
return Result.error(500, "更新用户扩展信息失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("用户个人信息更新成功: userId={}, username={}", id, username);
|
||||||
|
return Result.OK("个人信息更新成功");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("编辑个人信息失败: {}", e.getMessage(), e);
|
||||||
|
return Result.error(500, "编辑个人信息失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//密码修改
|
||||||
|
@AutoLog(value = "用户信息-修改密码")
|
||||||
|
@Operation(summary="用户信息-修改密码")
|
||||||
|
@PostMapping(value = "/updatePassword")
|
||||||
|
public Result<?> updatePassword(@RequestBody Map<String, String> params, HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
// 1. 从JWT中获取当前用户信息
|
||||||
|
String username = JwtUtil.getUserNameByToken(request);
|
||||||
|
if (username == null || username.trim().isEmpty()) {
|
||||||
|
return Result.error(401, "用户未登录或token无效");
|
||||||
|
}
|
||||||
|
SysUser currentUser = sysUserService.getUserByName(username);
|
||||||
|
if (currentUser == null) {
|
||||||
|
return Result.error(404, "用户不存在");
|
||||||
|
}
|
||||||
|
String oldPassword = params.get("oldPassword");
|
||||||
|
String newPassword = params.get("newPassword");
|
||||||
|
String id = currentUser.getId();
|
||||||
|
//判断密码是否一致
|
||||||
|
String oldPasswordEncrypt = PasswordUtil.encrypt(username, oldPassword, currentUser.getSalt());
|
||||||
|
String passwordEncrypt = currentUser.getPassword();
|
||||||
|
if (newPassword == null || newPassword.trim().isEmpty()) {
|
||||||
|
return Result.error(400, "新密码不允许为空");
|
||||||
|
}
|
||||||
|
if (newPassword.equals(oldPassword)) {
|
||||||
|
return Result.error(400, "新密码不能与旧密码相同");
|
||||||
|
}
|
||||||
|
if (!oldPasswordEncrypt.equals(passwordEncrypt)) {
|
||||||
|
return Result.error(400, "旧密码不正确");
|
||||||
|
}
|
||||||
|
//更新密码
|
||||||
|
String password = PasswordUtil.encrypt(username, newPassword, currentUser.getSalt());
|
||||||
|
currentUser.setPassword(password);
|
||||||
|
sysUserService.updateById(currentUser);
|
||||||
|
log.info("用户密码修改成功: userId={}, username={}", id, username);
|
||||||
|
return Result.OK("密码修改成功");
|
||||||
|
}catch (Exception e){
|
||||||
|
log.error("密码修改失败: {}", e.getMessage(), e);
|
||||||
|
return Result.error(500, "密码修改失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,435 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolUserFollow;
|
||||||
|
import org.jeecg.modules.aiol.entity.UserFollow;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolUserFollowService;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
|
import org.jeecg.modules.system.service.impl.SysUserServiceImpl;
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 关注关系
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-11
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name = "关注关系")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolUserFollow")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolUserFollowController extends JeecgController<AiolUserFollow, IAiolUserFollowService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolUserFollowService aiolUserFollowService;
|
||||||
|
@Autowired
|
||||||
|
private ISysBaseAPI sysBaseApi;
|
||||||
|
@Autowired
|
||||||
|
private SysUserServiceImpl sysUserService;
|
||||||
|
@Autowired
|
||||||
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolUserFollow
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "关注关系-分页列表查询")
|
||||||
|
@Operation(summary = "关注关系-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolUserFollow>> queryPageList(AiolUserFollow aiolUserFollow,
|
||||||
|
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
|
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolUserFollow> queryWrapper = QueryGenerator.initQueryWrapper(aiolUserFollow, req.getParameterMap());
|
||||||
|
Page<AiolUserFollow> page = new Page<AiolUserFollow>(pageNo, pageSize);
|
||||||
|
IPage<AiolUserFollow> pageList = aiolUserFollowService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolUserFollow
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "关注关系-添加")
|
||||||
|
@Operation(summary = "关注关系-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_user_follow:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolUserFollow aiolUserFollow) {
|
||||||
|
aiolUserFollowService.save(aiolUserFollow);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolUserFollow
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "关注关系-编辑")
|
||||||
|
@Operation(summary = "关注关系-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_user_follow:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolUserFollow aiolUserFollow) {
|
||||||
|
aiolUserFollowService.updateById(aiolUserFollow);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "关注关系-通过id删除")
|
||||||
|
@Operation(summary = "关注关系-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_user_follow:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
aiolUserFollowService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "关注关系-批量删除")
|
||||||
|
@Operation(summary = "关注关系-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_user_follow:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||||
|
this.aiolUserFollowService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "关注关系-通过id查询")
|
||||||
|
@Operation(summary = "关注关系-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolUserFollow> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||||
|
AiolUserFollow aiolUserFollow = aiolUserFollowService.getById(id);
|
||||||
|
if (aiolUserFollow == null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolUserFollow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关注用户
|
||||||
|
*
|
||||||
|
* @param followedId 被关注者ID
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "关注关系-关注用户")
|
||||||
|
@Operation(summary = "关注用户", description = "当前登录用户关注指定用户")
|
||||||
|
@PostMapping(value = "/follow")
|
||||||
|
public Result<String> follow(@RequestParam(name = "followedId", required = true) String followedId,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
// 1. 获取当前登录用户信息
|
||||||
|
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error("用户未登录或登录已过期");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 检查是否已经关注
|
||||||
|
QueryWrapper<AiolUserFollow> checkWrapper = new QueryWrapper<>();
|
||||||
|
checkWrapper.eq("follower_id", sysUser.getId())
|
||||||
|
.eq("followed_id", followedId);
|
||||||
|
AiolUserFollow existingFollow = aiolUserFollowService.getOne(checkWrapper);
|
||||||
|
|
||||||
|
if (existingFollow != null) {
|
||||||
|
return Result.error("已经关注过该用户");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 检查是否关注自己
|
||||||
|
if (sysUser.getId().equals(followedId)) {
|
||||||
|
return Result.error("不能关注自己");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 创建关注关系
|
||||||
|
AiolUserFollow userFollow = new AiolUserFollow();
|
||||||
|
userFollow.setFollowerId(sysUser.getId());
|
||||||
|
userFollow.setFollowedId(followedId);
|
||||||
|
userFollow.setCreateBy(sysUser.getUsername());
|
||||||
|
userFollow.setCreateTime(new Date());
|
||||||
|
|
||||||
|
aiolUserFollowService.save(userFollow);
|
||||||
|
|
||||||
|
// 添加到Redis缓存
|
||||||
|
String recentFollowKey = "user:recent:follow:" + sysUser.getId();
|
||||||
|
String frequentVisitKey = "user:frequent:visit:" + sysUser.getId();
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
|
// 使用RedisTemplate操作Redis
|
||||||
|
// 存储最近关注(使用时间戳作为分数)
|
||||||
|
redisTemplate.opsForZSet().add(recentFollowKey, followedId, currentTime);
|
||||||
|
// 存储访问频率(初始值为1)
|
||||||
|
redisTemplate.opsForZSet().add(frequentVisitKey, followedId, 1);
|
||||||
|
// 设置过期时间(例如30天)
|
||||||
|
redisTemplate.expire(recentFollowKey, 30, TimeUnit.DAYS);
|
||||||
|
redisTemplate.expire(frequentVisitKey, 30, TimeUnit.DAYS);
|
||||||
|
|
||||||
|
return Result.OK("关注成功!");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("关注用户失败: followedId={}, error={}", followedId, e.getMessage(), e);
|
||||||
|
return Result.error("关注失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//查询关注列表
|
||||||
|
@AutoLog(value = "关注关系-查询关注列表")
|
||||||
|
@Operation(summary = "查询关注列表", description = "当前登录用户关注的所有用户")
|
||||||
|
@GetMapping(value = "/followList")
|
||||||
|
public Result<List<?>> followList(HttpServletRequest req) {
|
||||||
|
try {
|
||||||
|
// 1. 获取当前登录用户信息
|
||||||
|
String token = req.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error("用户未登录或登录已过期");
|
||||||
|
}
|
||||||
|
// 2. 查询关注列表
|
||||||
|
QueryWrapper<AiolUserFollow> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("follower_id", sysUser.getId());
|
||||||
|
List<AiolUserFollow> list = aiolUserFollowService.list(queryWrapper);
|
||||||
|
if (list != null && !list.isEmpty()) {
|
||||||
|
// 使用Stream提取被关注者的ID列表
|
||||||
|
List<String> followedIds = list.stream()
|
||||||
|
.map(AiolUserFollow::getFollowedId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
// 根据被关注者的ID列表查询用户信息
|
||||||
|
List<SysUser> followedUsers = sysUserService.listByIds(followedIds);
|
||||||
|
if (followedUsers != null && !followedUsers.isEmpty()) {
|
||||||
|
List<UserFollow> userFollows = new ArrayList<>();
|
||||||
|
for (SysUser followedUser : followedUsers) {
|
||||||
|
UserFollow userFollow = new UserFollow();
|
||||||
|
userFollow.setId(followedUser.getId());
|
||||||
|
userFollow.setIsFollow(true);
|
||||||
|
userFollow.setRealName(followedUser.getRealname());
|
||||||
|
userFollow.setAvatar(followedUser.getAvatar());
|
||||||
|
userFollows.add(userFollow);
|
||||||
|
}
|
||||||
|
return Result.OK(userFollows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
return Result.OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
//查询最近关注
|
||||||
|
@AutoLog(value = "关注关系-查询最近关注")
|
||||||
|
@Operation(summary = "查询最近关注", description = "当前登录用户最近关注的用户")
|
||||||
|
@GetMapping(value = "/recentFollowList")
|
||||||
|
public Result<List<?>> recentFollowList(HttpServletRequest req) {
|
||||||
|
try {
|
||||||
|
// 1. 获取当前登录用户信息
|
||||||
|
String token = req.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error("用户未登录或登录已过期");
|
||||||
|
}
|
||||||
|
// 2. 查询最近关注列表
|
||||||
|
String recentFollowKey = "user:recent:follow:" + sysUser.getId();
|
||||||
|
Set<Object> objects = redisTemplate.opsForZSet().range(recentFollowKey, 0, -1);
|
||||||
|
Set<String> followedIds = objects.stream()
|
||||||
|
.map(obj -> String.valueOf(obj))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
if (followedIds != null && !followedIds.isEmpty()) {
|
||||||
|
// 根据被关注者的ID列表查询用户信息
|
||||||
|
List<SysUser> followedUsers = sysUserService.listByIds(followedIds);
|
||||||
|
if (followedUsers != null && !followedUsers.isEmpty()) {
|
||||||
|
List<UserFollow> userFollows = new ArrayList<>();
|
||||||
|
for (SysUser followedUser : followedUsers) {
|
||||||
|
UserFollow userFollow = new UserFollow();
|
||||||
|
userFollow.setId(followedUser.getId());
|
||||||
|
userFollow.setIsFollow(true);
|
||||||
|
userFollow.setRealName(followedUser.getRealname());
|
||||||
|
userFollow.setAvatar(followedUser.getAvatar());
|
||||||
|
userFollows.add(userFollow);
|
||||||
|
}
|
||||||
|
return Result.OK(userFollows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
return Result.OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
//查询最常访问
|
||||||
|
@AutoLog(value = "关注关系-查询最常访问")
|
||||||
|
@Operation(summary = "查询最常访问", description = "当前登录用户最常访问的用户")
|
||||||
|
@GetMapping(value = "/frequentVisitList")
|
||||||
|
public Result<List<?>> frequentVisitList(HttpServletRequest req) {
|
||||||
|
try {
|
||||||
|
// 1. 获取当前登录用户信息
|
||||||
|
String token = req.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error("用户未登录或登录已过期");
|
||||||
|
}
|
||||||
|
// 2. 查询最常访问列表
|
||||||
|
String frequentVisitKey = "user:frequent:visit:" + sysUser.getId();
|
||||||
|
Set<Object> objects = redisTemplate.opsForZSet().range(frequentVisitKey, 0, -1);
|
||||||
|
Set<String> followedIds = objects.stream()
|
||||||
|
.map(obj -> String.valueOf(obj))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
if (followedIds != null && !followedIds.isEmpty()) {
|
||||||
|
// 根据被关注者的ID列表查询用户信息
|
||||||
|
List<SysUser> followedUsers = sysUserService.listByIds(followedIds);
|
||||||
|
if (followedUsers != null && !followedUsers.isEmpty()) {
|
||||||
|
List<UserFollow> userFollows = new ArrayList<>();
|
||||||
|
for (SysUser followedUser : followedUsers) {
|
||||||
|
UserFollow userFollow = new UserFollow();
|
||||||
|
userFollow.setId(followedUser.getId());
|
||||||
|
userFollow.setIsFollow(true);
|
||||||
|
userFollow.setRealName(followedUser.getRealname());
|
||||||
|
userFollow.setAvatar(followedUser.getAvatar());
|
||||||
|
userFollows.add(userFollow);
|
||||||
|
}
|
||||||
|
return Result.OK(userFollows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch (Exception e){
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
return Result.OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消关注用户
|
||||||
|
*
|
||||||
|
* @param followedId 被关注者ID
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "关注关系-取消关注用户")
|
||||||
|
@Operation(summary = "取消关注用户", description = "当前登录用户取消关注指定用户")
|
||||||
|
@DeleteMapping(value = "/unfollow")
|
||||||
|
public Result<String> unfollow(@RequestParam(name = "followedId", required = true) String followedId,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
// 1. 获取当前登录用户信息
|
||||||
|
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error("用户未登录或登录已过期");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 查找关注关系
|
||||||
|
QueryWrapper<AiolUserFollow> deleteWrapper = new QueryWrapper<>();
|
||||||
|
deleteWrapper.eq("follower_id", sysUser.getId())
|
||||||
|
.eq("followed_id", followedId);
|
||||||
|
|
||||||
|
boolean removed = aiolUserFollowService.remove(deleteWrapper);
|
||||||
|
if (removed) {
|
||||||
|
// 从Redis中删除关注记录
|
||||||
|
String recentFollowKey = "user:recent:follow:" + sysUser.getId();
|
||||||
|
String frequentVisitKey = "user:frequent:visit:" + sysUser.getId();
|
||||||
|
// 从最近关注列表中删除
|
||||||
|
redisTemplate.opsForZSet().remove(recentFollowKey, followedId);
|
||||||
|
// 从访问频率列表中删除
|
||||||
|
redisTemplate.opsForZSet().remove(frequentVisitKey, followedId);
|
||||||
|
return Result.OK("取消关注成功!");
|
||||||
|
} else {
|
||||||
|
return Result.error("未找到关注关系");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("取消关注用户失败: followedId={}, error={}", followedId, e.getMessage(), e);
|
||||||
|
return Result.error("取消关注失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolUserFollow
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_user_follow:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolUserFollow aiolUserFollow) {
|
||||||
|
return super.exportXls(request, aiolUserFollow, AiolUserFollow.class, "关注关系");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_user_follow:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolUserFollow.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,182 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolUserInfo;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolUserInfoService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 用户信息
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="用户信息")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolUserInfo")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolUserInfoController extends JeecgController<AiolUserInfo, IAiolUserInfoService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolUserInfoService aiolUserInfoService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolUserInfo
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "用户信息-分页列表查询")
|
||||||
|
@Operation(summary="用户信息-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolUserInfo>> queryPageList(AiolUserInfo aiolUserInfo,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolUserInfo> queryWrapper = QueryGenerator.initQueryWrapper(aiolUserInfo, req.getParameterMap());
|
||||||
|
Page<AiolUserInfo> page = new Page<AiolUserInfo>(pageNo, pageSize);
|
||||||
|
IPage<AiolUserInfo> pageList = aiolUserInfoService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolUserInfo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "用户信息-添加")
|
||||||
|
@Operation(summary="用户信息-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_user_info:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolUserInfo aiolUserInfo) {
|
||||||
|
aiolUserInfoService.save(aiolUserInfo);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolUserInfo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "用户信息-编辑")
|
||||||
|
@Operation(summary="用户信息-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_user_info:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolUserInfo aiolUserInfo) {
|
||||||
|
aiolUserInfoService.updateById(aiolUserInfo);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "用户信息-通过id删除")
|
||||||
|
@Operation(summary="用户信息-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_user_info:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolUserInfoService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "用户信息-批量删除")
|
||||||
|
@Operation(summary="用户信息-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_user_info:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolUserInfoService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "用户信息-通过id查询")
|
||||||
|
@Operation(summary="用户信息-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolUserInfo> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolUserInfo aiolUserInfo = aiolUserInfoService.getById(id);
|
||||||
|
if(aiolUserInfo==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolUserInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolUserInfo
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_user_info:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolUserInfo aiolUserInfo) {
|
||||||
|
return super.exportXls(request, aiolUserInfo, AiolUserInfo.class, "用户信息");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_user_info:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolUserInfo.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,239 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.config.shiro.IgnoreAuth;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolViewLog;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolViewLogService;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
/**
|
||||||
|
* @Description: 访问日志
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-26
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Tag(name="访问日志")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolViewLog")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolViewLogController extends JeecgController<AiolViewLog, IAiolViewLogService> {
|
||||||
|
@Autowired
|
||||||
|
private IAiolViewLogService aiolViewLogService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页列表查询
|
||||||
|
*
|
||||||
|
* @param aiolViewLog
|
||||||
|
* @param pageNo
|
||||||
|
* @param pageSize
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "访问日志-分页列表查询")
|
||||||
|
@Operation(summary="访问日志-分页列表查询")
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
public Result<IPage<AiolViewLog>> queryPageList(AiolViewLog aiolViewLog,
|
||||||
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
|
||||||
|
|
||||||
|
QueryWrapper<AiolViewLog> queryWrapper = QueryGenerator.initQueryWrapper(aiolViewLog, req.getParameterMap());
|
||||||
|
Page<AiolViewLog> page = new Page<AiolViewLog>(pageNo, pageSize);
|
||||||
|
IPage<AiolViewLog> pageList = aiolViewLogService.page(page, queryWrapper);
|
||||||
|
return Result.OK(pageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加
|
||||||
|
*
|
||||||
|
* @param aiolViewLog
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "访问日志-添加")
|
||||||
|
@Operation(summary="访问日志-添加")
|
||||||
|
@RequiresPermissions("aiol:aiol_view_log:add")
|
||||||
|
@PostMapping(value = "/add")
|
||||||
|
public Result<String> add(@RequestBody AiolViewLog aiolViewLog) {
|
||||||
|
aiolViewLogService.save(aiolViewLog);
|
||||||
|
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param aiolViewLog
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "访问日志-编辑")
|
||||||
|
@Operation(summary="访问日志-编辑")
|
||||||
|
@RequiresPermissions("aiol:aiol_view_log:edit")
|
||||||
|
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> edit(@RequestBody AiolViewLog aiolViewLog) {
|
||||||
|
aiolViewLogService.updateById(aiolViewLog);
|
||||||
|
return Result.OK("编辑成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id删除
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "访问日志-通过id删除")
|
||||||
|
@Operation(summary="访问日志-通过id删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_view_log:delete")
|
||||||
|
@DeleteMapping(value = "/delete")
|
||||||
|
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||||
|
aiolViewLogService.removeById(id);
|
||||||
|
return Result.OK("删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "访问日志-批量删除")
|
||||||
|
@Operation(summary="访问日志-批量删除")
|
||||||
|
@RequiresPermissions("aiol:aiol_view_log:deleteBatch")
|
||||||
|
@DeleteMapping(value = "/deleteBatch")
|
||||||
|
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||||
|
this.aiolViewLogService.removeByIds(Arrays.asList(ids.split(",")));
|
||||||
|
return Result.OK("批量删除成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
//@AutoLog(value = "访问日志-通过id查询")
|
||||||
|
@Operation(summary="访问日志-通过id查询")
|
||||||
|
@GetMapping(value = "/queryById")
|
||||||
|
public Result<AiolViewLog> queryById(@RequestParam(name="id",required=true) String id) {
|
||||||
|
AiolViewLog aiolViewLog = aiolViewLogService.getById(id);
|
||||||
|
if(aiolViewLog==null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
return Result.OK(aiolViewLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param aiolViewLog
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_view_log:exportXls")
|
||||||
|
@RequestMapping(value = "/exportXls")
|
||||||
|
public ModelAndView exportXls(HttpServletRequest request, AiolViewLog aiolViewLog) {
|
||||||
|
return super.exportXls(request, aiolViewLog, AiolViewLog.class, "访问日志");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过excel导入数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("aiol:aiol_view_log:importExcel")
|
||||||
|
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||||
|
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.importExcel(request, response, AiolViewLog.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录实体访问量
|
||||||
|
*
|
||||||
|
* @param entityType 实体类型(video或course)
|
||||||
|
* @param entityId 实体ID
|
||||||
|
* @param request HTTP请求对象
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "访问日志-记录实体访问量")
|
||||||
|
@Operation(summary="记录实体访问量")
|
||||||
|
@IgnoreAuth
|
||||||
|
@PostMapping(value = "/recordView")
|
||||||
|
public Result<String> recordView(@RequestParam(name="type", required=true) String entityType,
|
||||||
|
@RequestParam(name="id", required=true) String entityId,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
// 验证实体类型
|
||||||
|
if (!"video".equals(entityType) && !"course".equals(entityType)) {
|
||||||
|
return Result.error("实体类型只能是video或course");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从Headers获取用户ID
|
||||||
|
String userId = request.getHeader("userId");
|
||||||
|
if (oConvertUtils.isEmpty(userId)) {
|
||||||
|
userId = null; // 未登录用户置空
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建访问日志记录
|
||||||
|
AiolViewLog viewLog = new AiolViewLog();
|
||||||
|
viewLog.setEntityType(entityType);
|
||||||
|
viewLog.setEntityId(entityId);
|
||||||
|
viewLog.setUserId(userId);
|
||||||
|
viewLog.setViewTime(new Date());
|
||||||
|
|
||||||
|
// 保存访问日志
|
||||||
|
aiolViewLogService.save(viewLog);
|
||||||
|
|
||||||
|
return Result.OK("访问记录成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看实体访问量
|
||||||
|
*
|
||||||
|
* @param entityId 实体ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Operation(summary="查看实体访问量")
|
||||||
|
@IgnoreAuth
|
||||||
|
@GetMapping(value = "/getViewCount")
|
||||||
|
public Result<Long> getViewCount(@RequestParam(name="id", required=true) String entityId) {
|
||||||
|
QueryWrapper<AiolViewLog> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("entity_id", entityId);
|
||||||
|
Long viewCount = aiolViewLogService.count(queryWrapper);
|
||||||
|
return Result.OK(viewCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.config.shiro.IgnoreAuth;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolCourseCategory;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolCourseService;
|
||||||
|
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.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Tag(name="师资力量")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/faculty")
|
||||||
|
@Slf4j
|
||||||
|
public class FacultyController {
|
||||||
|
@Autowired
|
||||||
|
private IAiolCourseService aiolCourseService;
|
||||||
|
|
||||||
|
@GetMapping("/skilledFieldList")
|
||||||
|
@Operation(summary = "查询擅长领域列表")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<AiolCourseCategory>> querySkilledFieldList() {
|
||||||
|
List<AiolCourseCategory> list = aiolCourseService.getCourseCategoryList();
|
||||||
|
return Result.OK(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolCourse;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description = "课程保存DTO,扩展课程分类和班级")
|
||||||
|
public class AiolCourseSaveDTO extends AiolCourse {
|
||||||
|
|
||||||
|
@Schema(description = "课程分类ID,支持多个,用英文逗号分割")
|
||||||
|
private String categoryId;
|
||||||
|
|
||||||
|
@Schema(description = "班级ID,支持多个,用英文逗号分割")
|
||||||
|
private String classId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolCourseSection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 课程章节DTO
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-01-20
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description = "课程章节DTO")
|
||||||
|
public class AiolCourseSectionDTO extends AiolCourseSection {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 资源ID
|
||||||
|
*/
|
||||||
|
@Schema(description = "资源ID")
|
||||||
|
private String targetId;
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolCourse;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description = "课程DTO,包含分类ID和班级ID(逗号分隔)")
|
||||||
|
public class AiolCourseWithLinkDTO extends AiolCourse {
|
||||||
|
|
||||||
|
@Schema(description = "课程分类ID,多个以逗号分隔")
|
||||||
|
private String categoryId;
|
||||||
|
|
||||||
|
@Schema(description = "班级ID,多个以逗号分隔")
|
||||||
|
private String classId;
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolDiscussion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 讨论保存DTO
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-01-16
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Schema(description = "讨论保存DTO")
|
||||||
|
public class AiolDiscussionSaveDTO extends AiolDiscussion {
|
||||||
|
|
||||||
|
@Schema(description = "关联的章节ID")
|
||||||
|
private String sectionId;
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolHomework;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 作业保存DTO
|
||||||
|
* 继承AiolHomework实体,增加班级ID、课程ID、章节ID字段
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "作业保存DTO")
|
||||||
|
public class AiolHomeworkSaveDTO extends AiolHomework {
|
||||||
|
@Schema(description = "章节ID")
|
||||||
|
private String sectionId;
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolChat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 会话详情DTO,包含未读消息数
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-01-16
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Schema(description = "会话详情,包含未读消息数")
|
||||||
|
public class ChatWithUnreadCountDTO extends AiolChat {
|
||||||
|
|
||||||
|
@Schema(description = "未读消息数")
|
||||||
|
private Integer unreadCount;
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolComment;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description = "评论信息(包含用户信息)")
|
||||||
|
public class CommentWithUserInfo extends AiolComment {
|
||||||
|
@Schema(description = "用户姓名")
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
@Schema(description = "用户头像")
|
||||||
|
private String userAvatar;
|
||||||
|
|
||||||
|
@Schema(description = "用户标签")
|
||||||
|
private String userTag;
|
||||||
|
|
||||||
|
@Schema(description = "子评论列表")
|
||||||
|
private List<CommentWithUserInfo> replies;
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolCourse;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description = "课程信息(包含讲师信息)")
|
||||||
|
public class CourseWithTeacherInfo extends AiolCourse {
|
||||||
|
@Schema(description = "授课讲师列表")
|
||||||
|
private List<TeacherInfo> teacherList;
|
||||||
|
/**
|
||||||
|
* 是否已报名该课程
|
||||||
|
*/
|
||||||
|
@Schema(description = "是否已报名该课程")
|
||||||
|
private Boolean isEnrolled = false;
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolDiscussion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 讨论详情DTO
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-01-16
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Schema(description = "讨论详情")
|
||||||
|
public class DiscussionWithSectionDTO extends AiolDiscussion {
|
||||||
|
|
||||||
|
@Schema(description = "关联的章节ID")
|
||||||
|
private String sectionId;
|
||||||
|
|
||||||
|
@Schema(description = "章节名称")
|
||||||
|
private String sectionName;
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑个人信息DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "编辑个人信息DTO")
|
||||||
|
public class EditProfileDTO {
|
||||||
|
|
||||||
|
@Schema(description = "真实姓名")
|
||||||
|
private String realname;
|
||||||
|
|
||||||
|
@Schema(description = "头像")
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
@Schema(description = "生日")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "GMT+8")
|
||||||
|
private Date birthday;
|
||||||
|
|
||||||
|
@Schema(description = "性别(1:男 2:女)")
|
||||||
|
private Integer sex;
|
||||||
|
|
||||||
|
@Schema(description = "邮箱")
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
@Schema(description = "电话")
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
@Schema(description = "介绍")
|
||||||
|
private String tag;
|
||||||
|
|
||||||
|
@Schema(description = "专业")
|
||||||
|
private String major;
|
||||||
|
|
||||||
|
@Schema(description = "学院")
|
||||||
|
private String college;
|
||||||
|
|
||||||
|
@Schema(description = "学历")
|
||||||
|
private String education;
|
||||||
|
|
||||||
|
@Schema(description = "职称")
|
||||||
|
private String title;
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolExamAnswer;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolQuestion;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ExaminationResult {
|
||||||
|
//题目内容
|
||||||
|
private AiolQuestion question;
|
||||||
|
//选项答案
|
||||||
|
private List<?> answer;
|
||||||
|
//用户答案
|
||||||
|
private AiolExamAnswer userAnswer;
|
||||||
|
//子题目列表
|
||||||
|
private List<ExaminationResult> children;
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolHomeworkSubmit;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 作业提交详情DTO
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-01-16
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Schema(description = "作业提交详情")
|
||||||
|
public class HomeworkSubmitDetailDTO extends AiolHomeworkSubmit {
|
||||||
|
|
||||||
|
// 作业信息
|
||||||
|
@Schema(description = "作业标题")
|
||||||
|
private String homeworkTitle;
|
||||||
|
|
||||||
|
@Schema(description = "作业说明")
|
||||||
|
private String homeworkDescription;
|
||||||
|
|
||||||
|
@Schema(description = "作业满分")
|
||||||
|
private Integer homeworkMaxScore;
|
||||||
|
|
||||||
|
@Schema(description = "作业及格分数")
|
||||||
|
private Integer homeworkPassScore;
|
||||||
|
|
||||||
|
@Schema(description = "作业开始时间")
|
||||||
|
private Date homeworkStartTime;
|
||||||
|
|
||||||
|
@Schema(description = "作业结束时间")
|
||||||
|
private Date homeworkEndTime;
|
||||||
|
|
||||||
|
@Schema(description = "作业状态")
|
||||||
|
private Integer homeworkStatus;
|
||||||
|
|
||||||
|
@Schema(description = "作业通知时间")
|
||||||
|
private Integer homeworkNotifyTime;
|
||||||
|
|
||||||
|
@Schema(description = "是否允许补交")
|
||||||
|
private Integer homeworkAllowMakeup;
|
||||||
|
|
||||||
|
@Schema(description = "补交截止时间")
|
||||||
|
private Date homeworkMakeupTime;
|
||||||
|
|
||||||
|
// 学生用户信息
|
||||||
|
@Schema(description = "学生用户名")
|
||||||
|
private String studentUsername;
|
||||||
|
|
||||||
|
@Schema(description = "学生真实姓名")
|
||||||
|
private String studentRealname;
|
||||||
|
|
||||||
|
@Schema(description = "学生头像")
|
||||||
|
private String studentAvatar;
|
||||||
|
|
||||||
|
// 班级信息
|
||||||
|
@Schema(description = "班级ID")
|
||||||
|
private String classId;
|
||||||
|
|
||||||
|
@Schema(description = "班级名称")
|
||||||
|
private String className;
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolHomework;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 作业详情DTO
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-01-16
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Schema(description = "作业详情")
|
||||||
|
public class HomeworkWithDetailsDTO extends AiolHomework {
|
||||||
|
|
||||||
|
@Schema(description = "班级名称列表")
|
||||||
|
private List<String> classNames;
|
||||||
|
|
||||||
|
@Schema(description = "章节ID")
|
||||||
|
private String sectionId;
|
||||||
|
|
||||||
|
@Schema(description = "章节标题")
|
||||||
|
private String sectionTitle;
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolQuestion;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class QuestionAnswerDTO {
|
||||||
|
//题目内容
|
||||||
|
private AiolQuestion question;
|
||||||
|
//答案
|
||||||
|
private List<?> answer;
|
||||||
|
//子题目列表
|
||||||
|
private List<QuestionAnswerDTO> children = new ArrayList<>();
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolExamAnswer;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolQuestion;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolQuestionAnswer;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class QuestionAnswerUser {
|
||||||
|
//题目内容
|
||||||
|
private AiolQuestion question;
|
||||||
|
//答案
|
||||||
|
private AiolQuestionAnswer answer;
|
||||||
|
//用户答案
|
||||||
|
private AiolExamAnswer userAnswer;
|
||||||
|
//满分
|
||||||
|
private Double fullMark;
|
||||||
|
}
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class QuestionExcelDTO {
|
||||||
|
@Excel(name = "题目ID", width = 15)
|
||||||
|
private String questionId;
|
||||||
|
|
||||||
|
@Excel(name = "父题目ID", width = 15)
|
||||||
|
private String parentId;
|
||||||
|
|
||||||
|
@Excel(name = "题目类型", width = 15)
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@Excel(name = "题干", width = 50)
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
@Excel(name = "选项A", width = 30)
|
||||||
|
private String optionA;
|
||||||
|
|
||||||
|
@Excel(name = "选项B", width = 30)
|
||||||
|
private String optionB;
|
||||||
|
|
||||||
|
@Excel(name = "选项C", width = 30)
|
||||||
|
private String optionC;
|
||||||
|
|
||||||
|
@Excel(name = "选项D", width = 30)
|
||||||
|
private String optionD;
|
||||||
|
|
||||||
|
@Excel(name = "选项E", width = 30)
|
||||||
|
private String optionE;
|
||||||
|
|
||||||
|
@Excel(name = "选项F", width = 30)
|
||||||
|
private String optionF;
|
||||||
|
|
||||||
|
@Excel(name = "选项G", width = 30)
|
||||||
|
private String optionG;
|
||||||
|
|
||||||
|
@Excel(name = "正确答案", width = 15)
|
||||||
|
private String correctAnswers;
|
||||||
|
|
||||||
|
@Excel(name = "题目解析", width = 50)
|
||||||
|
private String analysis;
|
||||||
|
|
||||||
|
@Excel(name = "难度", width = 15)
|
||||||
|
private String difficulty;
|
||||||
|
|
||||||
|
@Excel(name = "程度", width = 15)
|
||||||
|
private String degree;
|
||||||
|
|
||||||
|
@Excel(name = "能力", width = 15)
|
||||||
|
private String ability;
|
||||||
|
|
||||||
|
@Excel(name = "分值", width = 15)
|
||||||
|
private Double score;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 内部使用,存储解析后的选项列表
|
||||||
|
private List<OptionEntry> options = new ArrayList<>();
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class OptionEntry {
|
||||||
|
private String content;
|
||||||
|
private boolean isCorrect;
|
||||||
|
private Integer orderNo;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolQuestion;
|
||||||
|
|
||||||
|
public class QuestionWithCreator extends AiolQuestion {
|
||||||
|
private String createByName;
|
||||||
|
|
||||||
|
public String getCreateByName() {
|
||||||
|
return createByName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateByName(String createByName) {
|
||||||
|
this.createByName = createByName;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "学生提交作业")
|
||||||
|
public class StudentSubmitHomework {
|
||||||
|
/**作业id*/
|
||||||
|
@Schema(description = "作业id")
|
||||||
|
private String homeworkId;
|
||||||
|
/**学生id*/
|
||||||
|
@Schema(description = "学生id")
|
||||||
|
private String studentId;
|
||||||
|
/**作业内容*/
|
||||||
|
@Schema(description = "作业内容")
|
||||||
|
private String content;
|
||||||
|
/**附件*/
|
||||||
|
@Schema(description = "附件")
|
||||||
|
private String attachment;
|
||||||
|
/**状态*/
|
||||||
|
@Schema(description = "状态")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "讲师信息")
|
||||||
|
public class TeacherInfo {
|
||||||
|
@Schema(description = "讲师ID")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "讲师姓名")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "讲师头像")
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
@Schema(description = "职称")
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@Schema(description = "标签")
|
||||||
|
private String tag;
|
||||||
|
|
||||||
|
@Schema(description = "显示顺序")
|
||||||
|
private Integer sortOrder;
|
||||||
|
}
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "用户信息响应对象")
|
||||||
|
public class UserInfoResponse {
|
||||||
|
|
||||||
|
@Schema(description = "用户基本信息")
|
||||||
|
private BaseInfo baseInfo;
|
||||||
|
|
||||||
|
@Schema(description = "用户角色列表")
|
||||||
|
private List<String> roles;
|
||||||
|
|
||||||
|
@Schema(description = "扩展用户信息")
|
||||||
|
private ExtendedInfo extendedInfo;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "用户基本信息")
|
||||||
|
public static class BaseInfo {
|
||||||
|
@Schema(description = "用户ID")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "用户名")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Schema(description = "真实姓名")
|
||||||
|
private String realname;
|
||||||
|
|
||||||
|
@Schema(description = "头像")
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
@Schema(description = "手机号")
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
@Schema(description = "邮箱")
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
@Schema(description = "性别(1-男,2-女)")
|
||||||
|
private Integer sex;
|
||||||
|
|
||||||
|
@Schema(description = "生日")
|
||||||
|
private Date birthday;
|
||||||
|
|
||||||
|
@Schema(description = "状态(1-正常,2-冻结)")
|
||||||
|
private Integer status;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "扩展用户信息")
|
||||||
|
public static class ExtendedInfo {
|
||||||
|
@Schema(description = "专业")
|
||||||
|
private String major;
|
||||||
|
|
||||||
|
@Schema(description = "学院")
|
||||||
|
private String college;
|
||||||
|
|
||||||
|
@Schema(description = "学历")
|
||||||
|
private String education;
|
||||||
|
|
||||||
|
@Schema(description = "职称")
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@Schema(description = "标签")
|
||||||
|
private String tag;
|
||||||
|
|
||||||
|
@Schema(description = "显示顺序")
|
||||||
|
private Integer sortOrder;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
package org.jeecg.modules.aiol.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class UserPermission {
|
||||||
|
@Schema(description = "用户ID")
|
||||||
|
private String userId;
|
||||||
|
@Schema(description = "用户名")
|
||||||
|
private String userName;
|
||||||
|
@Schema(description = "用户真实姓名")
|
||||||
|
private String realName;
|
||||||
|
@Schema(description = "用户头像")
|
||||||
|
private String userAvatar;
|
||||||
|
@Schema(description = "用户是否有权限")
|
||||||
|
private boolean permission;
|
||||||
|
}
|
||||||
@ -0,0 +1,105 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 活动
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_activity")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="活动")
|
||||||
|
public class AiolActivity implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**标题*/
|
||||||
|
@Excel(name = "标题", width = 15)
|
||||||
|
@Schema(description = "标题")
|
||||||
|
private java.lang.String title;
|
||||||
|
/**介绍*/
|
||||||
|
@Excel(name = "介绍", width = 15)
|
||||||
|
@Schema(description = "介绍")
|
||||||
|
private java.lang.String introduction;
|
||||||
|
/**说明图片*/
|
||||||
|
@Excel(name = "说明图片", width = 15)
|
||||||
|
@Schema(description = "说明图片")
|
||||||
|
private java.lang.String imgs;
|
||||||
|
/**头图*/
|
||||||
|
@Excel(name = "头图", width = 15)
|
||||||
|
@Schema(description = "头图")
|
||||||
|
private java.lang.String banner;
|
||||||
|
/**介绍视频*/
|
||||||
|
@Excel(name = "介绍视频", width = 15)
|
||||||
|
@Schema(description = "介绍视频")
|
||||||
|
private java.lang.String video;
|
||||||
|
/**报名人数上限*/
|
||||||
|
@Excel(name = "报名人数上限", width = 15)
|
||||||
|
@Schema(description = "报名人数上限")
|
||||||
|
private java.lang.Integer maxNum;
|
||||||
|
/**开始时间*/
|
||||||
|
@Excel(name = "开始时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "开始时间")
|
||||||
|
private java.util.Date startTime;
|
||||||
|
/**结束时间*/
|
||||||
|
@Excel(name = "结束时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "结束时间")
|
||||||
|
private java.util.Date endTime;
|
||||||
|
/**扩展字段*/
|
||||||
|
@Excel(name = "扩展字段", width = 15)
|
||||||
|
@Schema(description = "扩展字段")
|
||||||
|
private java.lang.String extra;
|
||||||
|
/**附件*/
|
||||||
|
@Excel(name = "附件", width = 15)
|
||||||
|
@Schema(description = "附件")
|
||||||
|
private java.lang.String attachment;
|
||||||
|
/**状态*/
|
||||||
|
@Excel(name = "状态", width = 15, dicCode = "course_status")
|
||||||
|
@Dict(dicCode = "course_status")
|
||||||
|
@Schema(description = "状态")
|
||||||
|
private java.lang.String status;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,86 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 活动报名
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_activity_signup")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="活动报名")
|
||||||
|
public class AiolActivitySignup implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**姓名*/
|
||||||
|
@Excel(name = "姓名", width = 15)
|
||||||
|
@Schema(description = "姓名")
|
||||||
|
private java.lang.String name;
|
||||||
|
/**年龄*/
|
||||||
|
@Excel(name = "年龄", width = 15)
|
||||||
|
@Schema(description = "年龄")
|
||||||
|
private java.lang.String age;
|
||||||
|
/**手机号*/
|
||||||
|
@Excel(name = "手机号", width = 15)
|
||||||
|
@Schema(description = "手机号")
|
||||||
|
private java.lang.String phone;
|
||||||
|
/**邮箱*/
|
||||||
|
@Excel(name = "邮箱", width = 15)
|
||||||
|
@Schema(description = "邮箱")
|
||||||
|
private java.lang.String email;
|
||||||
|
/**扩展字段*/
|
||||||
|
@Excel(name = "扩展字段", width = 15)
|
||||||
|
@Schema(description = "扩展字段")
|
||||||
|
private java.lang.String extra;
|
||||||
|
/**附件*/
|
||||||
|
@Excel(name = "附件", width = 15)
|
||||||
|
@Schema(description = "附件")
|
||||||
|
private java.lang.String attachment;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
/**活动id*/
|
||||||
|
@Schema(description = "活动id")
|
||||||
|
private java.lang.String activityId;
|
||||||
|
/**用户id*/
|
||||||
|
@Schema(description = "用户id")
|
||||||
|
private java.lang.String userId;
|
||||||
|
}
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 会话
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-11
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_chat")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="会话")
|
||||||
|
public class AiolChat implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**会话类型*/
|
||||||
|
@Excel(name = "会话类型", width = 15)
|
||||||
|
@Schema(description = "会话类型")
|
||||||
|
private java.lang.Integer type;
|
||||||
|
/**群聊名称*/
|
||||||
|
@Excel(name = "群聊名称", width = 15)
|
||||||
|
@Schema(description = "群聊名称")
|
||||||
|
private java.lang.String name;
|
||||||
|
/**群聊头像*/
|
||||||
|
@Excel(name = "群聊头像", width = 15)
|
||||||
|
@Schema(description = "群聊头像")
|
||||||
|
private java.lang.String avatar;
|
||||||
|
/**关联id*/
|
||||||
|
@Excel(name = "关联id", width = 15)
|
||||||
|
@Schema(description = "关联id")
|
||||||
|
private java.lang.String refId;
|
||||||
|
/**是否全员禁言*/
|
||||||
|
@Excel(name = "是否全员禁言", width = 15)
|
||||||
|
@Schema(description = "是否全员禁言")
|
||||||
|
private java.lang.Integer izAllMuted;
|
||||||
|
/**是否显示教师标签*/
|
||||||
|
@Excel(name = "是否显示教师标签", width = 15)
|
||||||
|
@Schema(description = "是否显示教师标签")
|
||||||
|
private java.lang.Integer showLabel;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 会话用户
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-11
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_chat_member")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="会话用户")
|
||||||
|
public class AiolChatMember implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**会话id*/
|
||||||
|
@Excel(name = "会话id", width = 15)
|
||||||
|
@Schema(description = "会话id")
|
||||||
|
private java.lang.String chatId;
|
||||||
|
/**用户id*/
|
||||||
|
@Excel(name = "用户id", width = 15)
|
||||||
|
@Schema(description = "用户id")
|
||||||
|
private java.lang.String userId;
|
||||||
|
/**成员角色*/
|
||||||
|
@Excel(name = "成员角色", width = 15)
|
||||||
|
@Schema(description = "成员角色")
|
||||||
|
private java.lang.Integer role;
|
||||||
|
/**是否禁言*/
|
||||||
|
@Excel(name = "是否禁言", width = 15)
|
||||||
|
@Schema(description = "是否禁言")
|
||||||
|
private java.lang.Integer izMuted;
|
||||||
|
/**是否免打扰*/
|
||||||
|
@Excel(name = "是否免打扰", width = 15)
|
||||||
|
@Schema(description = "是否免打扰")
|
||||||
|
private java.lang.Integer izNotDisturb;
|
||||||
|
/**最后已读消息id*/
|
||||||
|
@Excel(name = "最后已读消息id", width = 15)
|
||||||
|
@Schema(description = "最后已读消息id")
|
||||||
|
private java.lang.String lastReadMsgId;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,88 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 会话消息
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-11
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_chat_message")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="会话消息")
|
||||||
|
public class AiolChatMessage implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**会话id*/
|
||||||
|
@Excel(name = "会话id", width = 15)
|
||||||
|
@Schema(description = "会话id")
|
||||||
|
private java.lang.String chatId;
|
||||||
|
/**发送者id*/
|
||||||
|
@Excel(name = "发送者id", width = 15)
|
||||||
|
@Schema(description = "发送者id")
|
||||||
|
private java.lang.String senderId;
|
||||||
|
/**内容*/
|
||||||
|
@Excel(name = "内容", width = 15)
|
||||||
|
@Schema(description = "内容")
|
||||||
|
private java.lang.String content;
|
||||||
|
/**消息类型*/
|
||||||
|
@Excel(name = "消息类型", width = 15)
|
||||||
|
@Schema(description = "消息类型")
|
||||||
|
private java.lang.Integer messageType;
|
||||||
|
/**状态*/
|
||||||
|
@Excel(name = "状态", width = 15)
|
||||||
|
@Schema(description = "状态")
|
||||||
|
private java.lang.Integer status;
|
||||||
|
/**文件url*/
|
||||||
|
@Excel(name = "文件url", width = 15)
|
||||||
|
@Schema(description = "文件url")
|
||||||
|
private java.lang.String fileUrl;
|
||||||
|
/**文件名*/
|
||||||
|
@Excel(name = "文件名", width = 15)
|
||||||
|
@Schema(description = "文件名")
|
||||||
|
private java.lang.String fileName;
|
||||||
|
/**文件大小*/
|
||||||
|
@Excel(name = "文件大小", width = 15)
|
||||||
|
@Schema(description = "文件大小")
|
||||||
|
private java.lang.String fileSize;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: aiol_class
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-11
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_class")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="aiol_class")
|
||||||
|
public class AiolClass implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**id*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "id")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**班级名*/
|
||||||
|
@Excel(name = "班级名", width = 15)
|
||||||
|
@Schema(description = "班级名")
|
||||||
|
private java.lang.String name;
|
||||||
|
/**课程id*/
|
||||||
|
@Excel(name = "课程id", width = 15)
|
||||||
|
@Schema(description = "课程id")
|
||||||
|
private java.lang.String courseId;
|
||||||
|
/**邀请码*/
|
||||||
|
@Excel(name = "邀请码", width = 15)
|
||||||
|
@Schema(description = "邀请码")
|
||||||
|
private java.lang.String inviteCode;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 班级学生
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-04
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_class_student")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="班级学生")
|
||||||
|
public class AiolClassStudent implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**班级id*/
|
||||||
|
@Excel(name = "班级id", width = 15)
|
||||||
|
@Schema(description = "班级id")
|
||||||
|
private java.lang.String classId;
|
||||||
|
/**学生id*/
|
||||||
|
@Excel(name = "学生id", width = 15)
|
||||||
|
@Schema(description = "学生id")
|
||||||
|
private java.lang.String studentId;
|
||||||
|
/**状态*/
|
||||||
|
@Excel(name = "状态", width = 15)
|
||||||
|
@Schema(description = "状态")
|
||||||
|
private java.lang.Integer status;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 评论
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_comment")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="评论")
|
||||||
|
public class AiolComment implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**用户id*/
|
||||||
|
@Excel(name = "用户id", width = 15)
|
||||||
|
@Schema(description = "用户id")
|
||||||
|
private java.lang.String userId;
|
||||||
|
/**目标类型*/
|
||||||
|
@Excel(name = "目标类型", width = 15)
|
||||||
|
@Schema(description = "目标类型")
|
||||||
|
private java.lang.String targetType;
|
||||||
|
/**目标id*/
|
||||||
|
@Excel(name = "目标id", width = 15)
|
||||||
|
@Schema(description = "目标id")
|
||||||
|
private java.lang.String targetId;
|
||||||
|
/**内容*/
|
||||||
|
@Excel(name = "内容", width = 15)
|
||||||
|
@Schema(description = "内容")
|
||||||
|
private java.lang.String content;
|
||||||
|
/**图片*/
|
||||||
|
@Excel(name = "图片", width = 15)
|
||||||
|
@Schema(description = "图片")
|
||||||
|
private java.lang.String imgs;
|
||||||
|
/**是否置顶*/
|
||||||
|
@Excel(name = "是否置顶", width = 15)
|
||||||
|
@Schema(description = "是否置顶")
|
||||||
|
private java.lang.Integer izTop;
|
||||||
|
/**点赞数*/
|
||||||
|
@Excel(name = "点赞数", width = 15)
|
||||||
|
@Schema(description = "点赞数")
|
||||||
|
private java.lang.Integer likeCount;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 内容配置
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_content_config")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="内容配置")
|
||||||
|
public class AiolContentConfig implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**配置标识*/
|
||||||
|
@Excel(name = "配置标识", width = 15)
|
||||||
|
@Schema(description = "配置标识")
|
||||||
|
private java.lang.String contentKey;
|
||||||
|
/**配置值*/
|
||||||
|
@Excel(name = "配置值", width = 15)
|
||||||
|
@Schema(description = "配置值")
|
||||||
|
private java.lang.String contentValue;
|
||||||
|
/**值类型*/
|
||||||
|
@Excel(name = "值类型", width = 15)
|
||||||
|
@Schema(description = "值类型")
|
||||||
|
private java.lang.String valueType;
|
||||||
|
/**描述*/
|
||||||
|
@Excel(name = "描述", width = 15)
|
||||||
|
@Schema(description = "描述")
|
||||||
|
private java.lang.String description;
|
||||||
|
}
|
||||||
@ -0,0 +1,168 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 课程
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-17
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_course")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="课程")
|
||||||
|
public class AiolCourse implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**课程名*/
|
||||||
|
@Excel(name = "课程名", width = 15)
|
||||||
|
@Schema(description = "课程名")
|
||||||
|
private java.lang.String name;
|
||||||
|
/**封面图*/
|
||||||
|
@Excel(name = "封面图", width = 15)
|
||||||
|
@Schema(description = "封面图")
|
||||||
|
private java.lang.String cover;
|
||||||
|
/**介绍视频*/
|
||||||
|
@Excel(name = "介绍视频", width = 15)
|
||||||
|
@Schema(description = "介绍视频")
|
||||||
|
private java.lang.String video;
|
||||||
|
/**学校*/
|
||||||
|
@Excel(name = "学校", width = 15)
|
||||||
|
@Schema(description = "学校")
|
||||||
|
private java.lang.String school;
|
||||||
|
/**课程概述*/
|
||||||
|
@Excel(name = "课程概述", width = 15)
|
||||||
|
@Schema(description = "课程概述")
|
||||||
|
private java.lang.String description;
|
||||||
|
/**课程类型*/
|
||||||
|
@Excel(name = "课程类型", width = 15, dicCode = "course_type")
|
||||||
|
@Dict(dicCode = "course_type")
|
||||||
|
@Schema(description = "课程类型")
|
||||||
|
private java.lang.Integer type;
|
||||||
|
/**授课目标*/
|
||||||
|
@Excel(name = "授课目标", width = 15)
|
||||||
|
@Schema(description = "授课目标")
|
||||||
|
private java.lang.String target;
|
||||||
|
/**课程难度*/
|
||||||
|
@Excel(name = "课程难度", width = 15, dicCode = "course_difficulty")
|
||||||
|
@Dict(dicCode = "course_difficulty")
|
||||||
|
@Schema(description = "课程难度")
|
||||||
|
private java.lang.Integer difficulty;
|
||||||
|
/**所属专题*/
|
||||||
|
@Excel(name = "所属专题", width = 15, dicCode = "course_subject")
|
||||||
|
@Dict(dicCode = "course_subject")
|
||||||
|
@Schema(description = "所属专题")
|
||||||
|
private java.lang.String subject;
|
||||||
|
/**课程大纲*/
|
||||||
|
@Excel(name = "课程大纲", width = 15)
|
||||||
|
@Schema(description = "课程大纲")
|
||||||
|
private java.lang.String outline;
|
||||||
|
/**预备知识*/
|
||||||
|
@Excel(name = "预备知识", width = 15)
|
||||||
|
@Schema(description = "预备知识")
|
||||||
|
private java.lang.String prerequisite;
|
||||||
|
/**参考资料*/
|
||||||
|
@Excel(name = "参考资料", width = 15)
|
||||||
|
@Schema(description = "参考资料")
|
||||||
|
private java.lang.String reference;
|
||||||
|
/**学时安排*/
|
||||||
|
@Excel(name = "学时安排", width = 15)
|
||||||
|
@Schema(description = "学时安排")
|
||||||
|
private java.lang.String arrangement;
|
||||||
|
/**开课时间*/
|
||||||
|
@Excel(name = "开课时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "开课时间")
|
||||||
|
private java.util.Date startTime;
|
||||||
|
/**结课时间*/
|
||||||
|
@Excel(name = "结课时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "结课时间")
|
||||||
|
private java.util.Date endTime;
|
||||||
|
/**已报名人数*/
|
||||||
|
@Excel(name = "已报名人数", width = 15)
|
||||||
|
@Schema(description = "已报名人数")
|
||||||
|
private java.lang.Integer enrollCount;
|
||||||
|
/**最大报名人数*/
|
||||||
|
@Excel(name = "最大报名人数", width = 15)
|
||||||
|
@Schema(description = "最大报名人数")
|
||||||
|
private java.lang.Integer maxEnroll;
|
||||||
|
/**状态*/
|
||||||
|
@Excel(name = "状态", width = 15, dicCode = "course_status")
|
||||||
|
@Dict(dicCode = "course_status")
|
||||||
|
@Schema(description = "状态")
|
||||||
|
private java.lang.Integer status;
|
||||||
|
/**常见问题*/
|
||||||
|
@Excel(name = "常见问题", width = 15)
|
||||||
|
@Schema(description = "常见问题")
|
||||||
|
private java.lang.String question;
|
||||||
|
/**是否ai伴学模式1*/
|
||||||
|
@Excel(name = "是否ai伴学模式1", width = 15)
|
||||||
|
@Schema(description = "是否ai伴学模式1")
|
||||||
|
private java.lang.Integer izAi;
|
||||||
|
/**离开页面是否暂停视频播放*/
|
||||||
|
@Excel(name = "离开页面是否暂停视频播放", width = 15)
|
||||||
|
@Schema(description = "离开页面是否暂停视频播放")
|
||||||
|
private java.lang.Integer pauseExit;
|
||||||
|
/**是否允许倍速播放*/
|
||||||
|
@Excel(name = "是否允许倍速播放", width = 15)
|
||||||
|
@Schema(description = "是否允许倍速播放")
|
||||||
|
private java.lang.Integer allowSpeed;
|
||||||
|
/**是否显示字幕*/
|
||||||
|
@Excel(name = "是否显示字幕", width = 15)
|
||||||
|
@Schema(description = "是否显示字幕")
|
||||||
|
private java.lang.Integer showSubtitle;
|
||||||
|
/**上架状态*/
|
||||||
|
@Excel(name = "上架状态", width = 15)
|
||||||
|
@Schema(description = "上架状态")
|
||||||
|
private java.lang.Integer publishStatus;
|
||||||
|
/**学期*/
|
||||||
|
@Excel(name = "学期", width = 15)
|
||||||
|
@Schema(description = "学期")
|
||||||
|
private java.lang.String semester;
|
||||||
|
/**是否允许下载*/
|
||||||
|
@Excel(name = "是否允许下载", width = 15)
|
||||||
|
@Schema(description = "是否允许下载")
|
||||||
|
private java.lang.Integer allowDownload;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建时间*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新时间*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新时间")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 课程分类
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_course_category")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="课程分类")
|
||||||
|
public class AiolCourseCategory implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**分类名*/
|
||||||
|
@Excel(name = "分类名", width = 15)
|
||||||
|
@Schema(description = "分类名")
|
||||||
|
private java.lang.String name;
|
||||||
|
/**排序*/
|
||||||
|
@Excel(name = "排序", width = 15)
|
||||||
|
@Schema(description = "排序")
|
||||||
|
private java.lang.Integer sortOrder;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建时间*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新时间*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新时间")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,82 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 课程章节
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_course_section")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="课程章节")
|
||||||
|
public class AiolCourseSection implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**课程id*/
|
||||||
|
@Excel(name = "课程id", width = 15)
|
||||||
|
@Schema(description = "课程id")
|
||||||
|
private java.lang.String courseId;
|
||||||
|
/**章节名*/
|
||||||
|
@Excel(name = "章节名", width = 15)
|
||||||
|
@Schema(description = "章节名")
|
||||||
|
private java.lang.String name;
|
||||||
|
/**章节类型*/
|
||||||
|
@Excel(name = "章节类型", width = 15, dicCode = "course_section_type")
|
||||||
|
@Dict(dicCode = "course_section_type")
|
||||||
|
@Schema(description = "章节类型")
|
||||||
|
private java.lang.Integer type;
|
||||||
|
/**排序号*/
|
||||||
|
@Excel(name = "排序号", width = 15)
|
||||||
|
@Schema(description = "排序号")
|
||||||
|
private java.lang.Integer sortOrder;
|
||||||
|
/**父章节id*/
|
||||||
|
@Excel(name = "父章节id", width = 15)
|
||||||
|
@Schema(description = "父章节id")
|
||||||
|
private java.lang.String parentId;
|
||||||
|
/**章节层级*/
|
||||||
|
@Excel(name = "章节层级", width = 15, dicCode = "course_section_level")
|
||||||
|
@Dict(dicCode = "course_section_level")
|
||||||
|
@Schema(description = "章节层级")
|
||||||
|
private java.lang.Integer level;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 课程报名
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_course_signup")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="课程报名")
|
||||||
|
public class AiolCourseSignup implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**用户id*/
|
||||||
|
@Excel(name = "用户id", width = 15)
|
||||||
|
@Schema(description = "用户id")
|
||||||
|
private java.lang.String userId;
|
||||||
|
/**课程id*/
|
||||||
|
@Excel(name = "课程id", width = 15)
|
||||||
|
@Schema(description = "课程id")
|
||||||
|
private java.lang.String courseId;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 授课教师
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_course_teacher")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="授课教师")
|
||||||
|
public class AiolCourseTeacher implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**课程id*/
|
||||||
|
@Excel(name = "课程id", width = 15)
|
||||||
|
@Schema(description = "课程id")
|
||||||
|
private java.lang.String courseId;
|
||||||
|
/**教师id*/
|
||||||
|
@Excel(name = "教师id", width = 15)
|
||||||
|
@Schema(description = "教师id")
|
||||||
|
private java.lang.String teacherId;
|
||||||
|
/**授课角色*/
|
||||||
|
@Excel(name = "授课角色", width = 15, dicCode = "course_role")
|
||||||
|
@Dict(dicCode = "course_role")
|
||||||
|
@Schema(description = "授课角色")
|
||||||
|
private java.lang.String role;
|
||||||
|
/**显示顺序*/
|
||||||
|
@Excel(name = "显示顺序", width = 15)
|
||||||
|
@Schema(description = "显示顺序")
|
||||||
|
private java.lang.Integer sortOrder;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 讨论
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-20
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_discussion")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="讨论")
|
||||||
|
public class AiolDiscussion implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**讨论标题*/
|
||||||
|
@Excel(name = "讨论标题", width = 15)
|
||||||
|
@Schema(description = "讨论标题")
|
||||||
|
private java.lang.String title;
|
||||||
|
/**讨论描述*/
|
||||||
|
@Excel(name = "讨论描述", width = 15)
|
||||||
|
@Schema(description = "讨论描述")
|
||||||
|
private java.lang.String description;
|
||||||
|
/**课程id*/
|
||||||
|
@Excel(name = "课程id", width = 15)
|
||||||
|
@Schema(description = "课程id")
|
||||||
|
private java.lang.String courseId;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 主体绑定
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_entity_link")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="主体绑定")
|
||||||
|
public class AiolEntityLink implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**主体类型*/
|
||||||
|
@Excel(name = "主体类型", width = 15)
|
||||||
|
@Schema(description = "主体类型")
|
||||||
|
private java.lang.String sourceType;
|
||||||
|
/**主体id*/
|
||||||
|
@Excel(name = "主体id", width = 15)
|
||||||
|
@Schema(description = "主体id")
|
||||||
|
private java.lang.String sourceId;
|
||||||
|
/**内容类型*/
|
||||||
|
@Excel(name = "内容类型", width = 15)
|
||||||
|
@Schema(description = "内容类型")
|
||||||
|
private java.lang.String targetType;
|
||||||
|
/**内容id*/
|
||||||
|
@Excel(name = "内容id", width = 15)
|
||||||
|
@Schema(description = "内容id")
|
||||||
|
private java.lang.String targetId;
|
||||||
|
/**排序*/
|
||||||
|
@Excel(name = "排序", width = 15)
|
||||||
|
@Schema(description = "排序")
|
||||||
|
private java.lang.Integer sortOrder;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 实体权限
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-05
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_entity_permission")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="实体权限")
|
||||||
|
public class AiolEntityPermission implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**实体类型*/
|
||||||
|
@Excel(name = "实体类型", width = 15)
|
||||||
|
@Schema(description = "实体类型")
|
||||||
|
private java.lang.String entityType;
|
||||||
|
/**实体id*/
|
||||||
|
@Excel(name = "实体id", width = 15)
|
||||||
|
@Schema(description = "实体id")
|
||||||
|
private java.lang.String entityId;
|
||||||
|
/**用户id*/
|
||||||
|
@Excel(name = "用户id", width = 15)
|
||||||
|
@Schema(description = "用户id")
|
||||||
|
private java.lang.String userId;
|
||||||
|
/**模式*/
|
||||||
|
@Excel(name = "模式", width = 15)
|
||||||
|
@Schema(description = "模式")
|
||||||
|
private java.lang.String mode;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,88 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 考试
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_exam")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="考试")
|
||||||
|
public class AiolExam implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**考试名称*/
|
||||||
|
@Excel(name = "考试名称", width = 15)
|
||||||
|
@Schema(description = "考试名称")
|
||||||
|
private java.lang.String name;
|
||||||
|
/**试卷id*/
|
||||||
|
@Excel(name = "试卷id", width = 15)
|
||||||
|
@Schema(description = "试卷id")
|
||||||
|
private java.lang.String paperId;
|
||||||
|
/**开始时间*/
|
||||||
|
@Excel(name = "开始时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "开始时间")
|
||||||
|
private java.util.Date startTime;
|
||||||
|
/**结束时间*/
|
||||||
|
@Excel(name = "结束时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "结束时间")
|
||||||
|
private java.util.Date endTime;
|
||||||
|
/**考试时长*/
|
||||||
|
@Excel(name = "考试时长", width = 15)
|
||||||
|
@Schema(description = "考试时长")
|
||||||
|
private java.lang.Integer totalTime;
|
||||||
|
/**考试类型*/
|
||||||
|
@Excel(name = "考试类型", width = 15)
|
||||||
|
@Schema(description = "考试类型")
|
||||||
|
private java.lang.Integer type;
|
||||||
|
/**状态*/
|
||||||
|
@Excel(name = "状态", width = 15)
|
||||||
|
@Schema(description = "状态")
|
||||||
|
private java.lang.Integer status;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 考试答题
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_exam_answer")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="考试答题")
|
||||||
|
public class AiolExamAnswer implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**考试id*/
|
||||||
|
@Excel(name = "考试id", width = 15)
|
||||||
|
@Schema(description = "考试id")
|
||||||
|
private java.lang.String examId;
|
||||||
|
/**用户id*/
|
||||||
|
@Excel(name = "用户id", width = 15)
|
||||||
|
@Schema(description = "用户id")
|
||||||
|
private java.lang.String userId;
|
||||||
|
/**复合题id*/
|
||||||
|
@Excel(name = "复合题id", width = 15)
|
||||||
|
@Schema(description = "复合题id")
|
||||||
|
private java.lang.String parentQuestionId;
|
||||||
|
/**题目id*/
|
||||||
|
@Excel(name = "题目id", width = 15)
|
||||||
|
@Schema(description = "题目id")
|
||||||
|
private java.lang.String questionId;
|
||||||
|
/**答案*/
|
||||||
|
@Excel(name = "答案", width = 15)
|
||||||
|
@Schema(description = "答案")
|
||||||
|
private java.lang.String answer;
|
||||||
|
/**是否正确*/
|
||||||
|
@Excel(name = "是否正确", width = 15)
|
||||||
|
@Schema(description = "是否正确")
|
||||||
|
private java.lang.Integer izCorrect;
|
||||||
|
/**题目得分*/
|
||||||
|
@Excel(name = "题目得分", width = 15)
|
||||||
|
@Schema(description = "题目得分")
|
||||||
|
private java.lang.Double score;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,86 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 考试记录
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_exam_record")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="考试记录")
|
||||||
|
public class AiolExamRecord implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**考试id*/
|
||||||
|
@Excel(name = "考试id", width = 15)
|
||||||
|
@Schema(description = "考试id")
|
||||||
|
private java.lang.String examId;
|
||||||
|
/**用户id*/
|
||||||
|
@Excel(name = "用户id", width = 15)
|
||||||
|
@Schema(description = "用户id")
|
||||||
|
private java.lang.String userId;
|
||||||
|
/**总分*/
|
||||||
|
@Excel(name = "总分", width = 15)
|
||||||
|
@Schema(description = "总分")
|
||||||
|
private java.lang.Double totalScore;
|
||||||
|
/**状态*/
|
||||||
|
@Excel(name = "状态", width = 15)
|
||||||
|
@Schema(description = "状态")
|
||||||
|
private java.lang.Integer status;
|
||||||
|
/**提交时间*/
|
||||||
|
@Excel(name = "提交时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "提交时间")
|
||||||
|
private java.util.Date submittedAt;
|
||||||
|
/**ip地址*/
|
||||||
|
@Excel(name = "ip地址", width = 15)
|
||||||
|
@Schema(description = "ip地址")
|
||||||
|
private java.lang.String ipAddress;
|
||||||
|
/**设备信息*/
|
||||||
|
@Excel(name = "设备信息", width = 15)
|
||||||
|
@Schema(description = "设备信息")
|
||||||
|
private java.lang.String deviceInfo;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,115 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 作业
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-20
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_homework")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="作业")
|
||||||
|
public class AiolHomework implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**所属课程id*/
|
||||||
|
@Excel(name = "所属课程id", width = 15)
|
||||||
|
@Schema(description = "所属课程id")
|
||||||
|
private java.lang.String courseId;
|
||||||
|
/**班级id*/
|
||||||
|
@Excel(name = "班级id", width = 15)
|
||||||
|
@Schema(description = "班级id")
|
||||||
|
private java.lang.String classId;
|
||||||
|
/**标题*/
|
||||||
|
@Excel(name = "标题", width = 15)
|
||||||
|
@Schema(description = "标题")
|
||||||
|
private java.lang.String title;
|
||||||
|
/**说明*/
|
||||||
|
@Excel(name = "说明", width = 15)
|
||||||
|
@Schema(description = "说明")
|
||||||
|
private java.lang.String description;
|
||||||
|
/**附件*/
|
||||||
|
@Excel(name = "附件", width = 15)
|
||||||
|
@Schema(description = "附件")
|
||||||
|
private java.lang.String attachment;
|
||||||
|
/**满分*/
|
||||||
|
@Excel(name = "满分", width = 15)
|
||||||
|
@Schema(description = "满分")
|
||||||
|
private java.lang.Integer maxScore;
|
||||||
|
/**及格分数*/
|
||||||
|
@Excel(name = "及格分数", width = 15)
|
||||||
|
@Schema(description = "及格分数")
|
||||||
|
private java.lang.Integer passScore;
|
||||||
|
/**开始时间*/
|
||||||
|
@Excel(name = "开始时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "开始时间")
|
||||||
|
private java.util.Date startTime;
|
||||||
|
/**结束时间*/
|
||||||
|
@Excel(name = "结束时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "结束时间")
|
||||||
|
private java.util.Date endTime;
|
||||||
|
/**状态*/
|
||||||
|
@Excel(name = "状态", width = 15, dicCode = "course_status")
|
||||||
|
@Dict(dicCode = "course_status")
|
||||||
|
@Schema(description = "状态")
|
||||||
|
private java.lang.Integer status;
|
||||||
|
/**是否允许补交*/
|
||||||
|
@Excel(name = "是否允许补交", width = 15)
|
||||||
|
@Schema(description = "是否允许补交")
|
||||||
|
private java.lang.Integer allowMakeup;
|
||||||
|
/**补交截止时间*/
|
||||||
|
@Excel(name = "补交截止时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "补交截止时间")
|
||||||
|
private java.util.Date makeupTime;
|
||||||
|
/**作业通知时间*/
|
||||||
|
@Excel(name = "作业通知时间", width = 15)
|
||||||
|
@Schema(description = "作业通知时间")
|
||||||
|
private java.lang.Integer notifyTime;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 作业提交
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_homework_submit")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="作业提交")
|
||||||
|
public class AiolHomeworkSubmit implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**作业id*/
|
||||||
|
@Excel(name = "作业id", width = 15)
|
||||||
|
@Schema(description = "作业id")
|
||||||
|
private java.lang.String homeworkId;
|
||||||
|
/**学生id*/
|
||||||
|
@Excel(name = "学生id", width = 15)
|
||||||
|
@Schema(description = "学生id")
|
||||||
|
private java.lang.String studentId;
|
||||||
|
/**作业内容*/
|
||||||
|
@Excel(name = "作业内容", width = 15)
|
||||||
|
@Schema(description = "作业内容")
|
||||||
|
private java.lang.String content;
|
||||||
|
/**附件*/
|
||||||
|
@Excel(name = "附件", width = 15)
|
||||||
|
@Schema(description = "附件")
|
||||||
|
private java.lang.String attachment;
|
||||||
|
/**得分*/
|
||||||
|
@Excel(name = "得分", width = 15)
|
||||||
|
@Schema(description = "得分")
|
||||||
|
private java.lang.Integer score;
|
||||||
|
/**批改意见*/
|
||||||
|
@Excel(name = "批改意见", width = 15)
|
||||||
|
@Schema(description = "批改意见")
|
||||||
|
private java.lang.String comment;
|
||||||
|
/**批改时间*/
|
||||||
|
@Excel(name = "批改时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "批改时间")
|
||||||
|
private java.util.Date gradedTime;
|
||||||
|
/**状态*/
|
||||||
|
@Excel(name = "状态", width = 15)
|
||||||
|
@Schema(description = "状态")
|
||||||
|
private java.lang.Integer status;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 学习进度
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_learn_progress")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="学习进度")
|
||||||
|
public class AiolLearnProgress implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**用户id*/
|
||||||
|
@Excel(name = "用户id", width = 15)
|
||||||
|
@Schema(description = "用户id")
|
||||||
|
private java.lang.String userId;
|
||||||
|
/**课程id*/
|
||||||
|
@Excel(name = "课程id", width = 15)
|
||||||
|
@Schema(description = "课程id")
|
||||||
|
private java.lang.String courseId;
|
||||||
|
/**章节id*/
|
||||||
|
@Excel(name = "章节id", width = 15)
|
||||||
|
@Schema(description = "章节id")
|
||||||
|
private java.lang.String sectionId;
|
||||||
|
/**进度*/
|
||||||
|
@Excel(name = "进度", width = 15)
|
||||||
|
@Schema(description = "进度")
|
||||||
|
private java.lang.Integer progress;
|
||||||
|
/**时长*/
|
||||||
|
@Excel(name = "时长", width = 15)
|
||||||
|
@Schema(description = "时长")
|
||||||
|
private java.lang.Integer duration;
|
||||||
|
/**状态*/
|
||||||
|
@Excel(name = "状态", width = 15)
|
||||||
|
@Schema(description = "状态")
|
||||||
|
private java.lang.Integer status;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 前台菜单
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-09-29
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_menu")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="前台菜单")
|
||||||
|
public class AiolMenu implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**菜单项名称*/
|
||||||
|
@Excel(name = "菜单项名称", width = 15)
|
||||||
|
@Schema(description = "菜单项名称")
|
||||||
|
private java.lang.String name;
|
||||||
|
/**路径*/
|
||||||
|
@Excel(name = "路径", width = 15)
|
||||||
|
@Schema(description = "路径")
|
||||||
|
private java.lang.String path;
|
||||||
|
/**类型*/
|
||||||
|
@Excel(name = "类型", width = 15)
|
||||||
|
@Schema(description = "类型")
|
||||||
|
private java.lang.String type;
|
||||||
|
/**图标*/
|
||||||
|
@Excel(name = "图标", width = 15)
|
||||||
|
@Schema(description = "图标")
|
||||||
|
private java.lang.String icon;
|
||||||
|
/**父级菜单id*/
|
||||||
|
@Excel(name = "父级菜单id", width = 15)
|
||||||
|
@Schema(description = "父级菜单id")
|
||||||
|
private java.lang.String parentId;
|
||||||
|
/**排序号*/
|
||||||
|
@Excel(name = "排序号", width = 15)
|
||||||
|
@Schema(description = "排序号")
|
||||||
|
private java.lang.Integer sortOrder;
|
||||||
|
/**是否显示*/
|
||||||
|
@Excel(name = "是否显示", width = 15)
|
||||||
|
@Schema(description = "是否显示")
|
||||||
|
private java.lang.Integer izVisible;
|
||||||
|
/**权限标识符*/
|
||||||
|
@Excel(name = "权限标识符", width = 15)
|
||||||
|
@Schema(description = "权限标识符")
|
||||||
|
private java.lang.String permissionKey;
|
||||||
|
}
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
package org.jeecg.modules.aiol.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import org.jeecg.common.constant.ProvinceCityArea;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 试卷
|
||||||
|
* @Author: jeecg-boot
|
||||||
|
* @Date: 2025-08-31
|
||||||
|
* @Version: V1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("aiol_paper")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description="试卷")
|
||||||
|
public class AiolPaper implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**主键*/
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private java.lang.String id;
|
||||||
|
/**试卷标题*/
|
||||||
|
@Excel(name = "试卷标题", width = 15)
|
||||||
|
@Schema(description = "试卷标题")
|
||||||
|
private java.lang.String title;
|
||||||
|
/**组卷模式*/
|
||||||
|
@Excel(name = "组卷模式", width = 15)
|
||||||
|
@Schema(description = "组卷模式")
|
||||||
|
private java.lang.Integer generateMode;
|
||||||
|
/**组卷规则*/
|
||||||
|
@Excel(name = "组卷规则", width = 15)
|
||||||
|
@Schema(description = "组卷规则")
|
||||||
|
private java.lang.String rules;
|
||||||
|
/**题库id*/
|
||||||
|
@Excel(name = "题库id", width = 15)
|
||||||
|
@Schema(description = "题库id")
|
||||||
|
private java.lang.String repoId;
|
||||||
|
/**总分*/
|
||||||
|
@Excel(name = "总分", width = 15)
|
||||||
|
@Schema(description = "总分")
|
||||||
|
private java.lang.Double totalScore;
|
||||||
|
/**及格分*/
|
||||||
|
@Excel(name = "及格分", width = 15)
|
||||||
|
@Schema(description = "及格分")
|
||||||
|
private java.lang.Double passScore;
|
||||||
|
/**是否需要批阅*/
|
||||||
|
@Excel(name = "是否需要批阅", width = 15)
|
||||||
|
@Schema(description = "是否需要批阅")
|
||||||
|
private java.lang.Integer requireReview;
|
||||||
|
/**创建人*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private java.lang.String createBy;
|
||||||
|
/**创建日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "创建日期")
|
||||||
|
private java.util.Date createTime;
|
||||||
|
/**更新人*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private java.lang.String updateBy;
|
||||||
|
/**更新日期*/
|
||||||
|
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "更新日期")
|
||||||
|
private java.util.Date updateTime;
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user