generated from wenxin/springboot-template
添加机器人处理指定群老师的消息;添加knife4j,便于生成接口文档;添加FileUtils,可以通过url上传远程文件系统;可将群消息处理到家庭作业答案
This commit is contained in:
parent
c654f079bd
commit
68fe006b2a
30
deviceInfo_20243037.json
Normal file
30
deviceInfo_20243037.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"deviceInfoVersion": 3,
|
||||
"data": {
|
||||
"display": "MIRAI.451530.001",
|
||||
"product": "mirai",
|
||||
"device": "mirai",
|
||||
"board": "mirai",
|
||||
"brand": "mamoe",
|
||||
"model": "mirai",
|
||||
"bootloader": "unknown",
|
||||
"fingerprint": "mamoe/mirai/mirai:10/MIRAI.200122.001/9029684:user/release-keys",
|
||||
"bootId": "0BBF2C49-3C4B-FBFC-8969-311C2F5D54C4",
|
||||
"procVersion": "Linux version 3.0.31-v23xIXJS (android-build@xxx.xxx.xxx.xxx.com)",
|
||||
"baseBand": "",
|
||||
"version": {
|
||||
"incremental": "5891938",
|
||||
"release": "10",
|
||||
"codename": "REL"
|
||||
},
|
||||
"simInfo": "T-Mobile",
|
||||
"osType": "android",
|
||||
"macAddress": "02:00:00:00:00:00",
|
||||
"wifiBSSID": "02:00:00:00:00:00",
|
||||
"wifiSSID": "<unknown ssid>",
|
||||
"imsiMd5": "6ba800c6d5513eb42b0fb90b6b5afd5c",
|
||||
"imei": "864237812540469",
|
||||
"apn": "wifi",
|
||||
"androidId": "906fe7e62819be1e"
|
||||
}
|
||||
}
|
25
pom.xml
25
pom.xml
@ -29,13 +29,34 @@
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.33</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>net.mamoe</groupId>
|
||||
<artifactId>mirai-core-jvm</artifactId>
|
||||
<version>2.99.0-local</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>3.5.9</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>4.12.0</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2</artifactId>
|
||||
<version>2.0.53</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
|
||||
<version>4.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
|
@ -7,9 +7,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
@SpringBootApplication
|
||||
@MapperScan("com.linxyun.homework.mapper")
|
||||
public class HomeworkApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(HomeworkApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
82
src/main/java/com/linxyun/homework/bot/MyBot.java
Normal file
82
src/main/java/com/linxyun/homework/bot/MyBot.java
Normal file
@ -0,0 +1,82 @@
|
||||
package com.linxyun.homework.bot;
|
||||
|
||||
import com.linxyun.homework.bot.handler.MyEventHandler;
|
||||
import com.linxyun.homework.domain.dto.ClassGroupTeacher;
|
||||
import com.linxyun.homework.mapper.ClassQqGroupTeacherMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.mamoe.mirai.BotFactory;
|
||||
import net.mamoe.mirai.auth.BotAuthorization;
|
||||
import net.mamoe.mirai.event.EventChannel;
|
||||
import net.mamoe.mirai.event.events.BotEvent;
|
||||
import net.mamoe.mirai.event.events.GroupMessageEvent;
|
||||
import net.mamoe.mirai.utils.BotConfiguration;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class MyBot implements ApplicationRunner {
|
||||
/* 监听对象 */
|
||||
public static CopyOnWriteArrayList<ClassGroupTeacher> listeningTarget;
|
||||
|
||||
private final ClassQqGroupTeacherMapper classQqGroupTeacherMapper;
|
||||
|
||||
private final MyEventHandler myEventHandler;
|
||||
|
||||
/* 登录QQ */
|
||||
@Value("${mirai.bot.qq}")
|
||||
public Long qq;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) {
|
||||
// 先加载需要处理的群和老师
|
||||
getListeningTarget();
|
||||
// 启动BOT
|
||||
runBot();
|
||||
}
|
||||
|
||||
public void getListeningTarget() {
|
||||
List<ClassGroupTeacher> classGroupTeachers = classQqGroupTeacherMapper.selectClassAndGroupTeacher();
|
||||
System.out.println(classGroupTeachers);
|
||||
listeningTarget = new CopyOnWriteArrayList<>(classGroupTeachers);
|
||||
}
|
||||
|
||||
public void runBot() {
|
||||
net.mamoe.mirai.Bot bot = BotFactory.INSTANCE.newBot(qq, BotAuthorization.byQRCode(), configuration -> {
|
||||
configuration.setProtocol(BotConfiguration.MiraiProtocol.MACOS);
|
||||
// 指定设备信息文件路径,文件不存在将自动生成一个默认的,存在就读取
|
||||
configuration.fileBasedDeviceInfo("deviceInfo_"+ qq + ".json");
|
||||
});
|
||||
bot.login();
|
||||
EventChannel<BotEvent> eventChannel = bot.getEventChannel();
|
||||
eventChannel
|
||||
.filterIsInstance(GroupMessageEvent.class)
|
||||
.filter(ev -> {
|
||||
long groupId = ev.getGroup().getId();
|
||||
long senderId = ev.getSender().getId();
|
||||
for (ClassGroupTeacher item : listeningTarget) {
|
||||
if (groupId == Long.parseLong(item.getQqGroupId()) && senderId == Long.parseLong(item.getTeacherGroupId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
).registerListenerHost(myEventHandler);
|
||||
new Thread(bot::join).start();
|
||||
}
|
||||
|
||||
public static ClassGroupTeacher getClassGroupTeacherByTeacherGroupId(String teacherGroupId) {
|
||||
return listeningTarget.stream()
|
||||
.filter(item -> Objects.equals(item.getTeacherGroupId(), teacherGroupId))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
package com.linxyun.homework.bot.handler;
|
||||
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsAddFileStatement;
|
||||
import com.linxyun.homework.bot.MyBot;
|
||||
import com.linxyun.homework.domain.dto.ClassGroupTeacher;
|
||||
import com.linxyun.homework.domain.po.TeacherQqMsgs;
|
||||
import com.linxyun.homework.mapper.TeacherQqMsgsMapper;
|
||||
import com.linxyun.homework.utils.FileUtils;
|
||||
import com.linxyun.homework.utils.TimeUtils;
|
||||
import kotlin.coroutines.CoroutineContext;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.mamoe.mirai.contact.file.AbsoluteFile;
|
||||
import net.mamoe.mirai.event.EventHandler;
|
||||
import net.mamoe.mirai.event.ListeningStatus;
|
||||
import net.mamoe.mirai.event.SimpleListenerHost;
|
||||
import net.mamoe.mirai.event.events.GroupMessageEvent;
|
||||
import net.mamoe.mirai.message.data.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class MyEventHandler extends SimpleListenerHost {
|
||||
private final FileUtils fileUtils;
|
||||
private final TeacherQqMsgsMapper teacherQqMsgsMapper;
|
||||
@Override
|
||||
public void handleException(@NotNull CoroutineContext context, @NotNull Throwable exception){
|
||||
// 处理事件处理时抛出的异常
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@EventHandler
|
||||
public ListeningStatus onMessage(@NotNull GroupMessageEvent event) { // 可以抛出任何异常, 将在 handleException 处理
|
||||
System.out.println("收到消息: " + event.getMessage());
|
||||
MessageChain messages = event.getMessage();
|
||||
// 发送人QQ
|
||||
String teacherId = String.valueOf(event.getSender().getId());
|
||||
StringBuilder strBuilder = null;
|
||||
StringBuilder contentBuilder = null;
|
||||
for (SingleMessage message : messages) {
|
||||
if (message instanceof PlainText plainText) {
|
||||
log.info("文本: " + plainText.getContent());
|
||||
if (strBuilder == null) {
|
||||
strBuilder = new StringBuilder();
|
||||
}
|
||||
strBuilder.append(plainText.getContent()).append("|||");
|
||||
}
|
||||
if (message instanceof Image image) {
|
||||
log.info("图片: " + image.getImageId());
|
||||
if (image.isEmoji()) continue;
|
||||
if (contentBuilder == null) contentBuilder = new StringBuilder();
|
||||
String url = Image.queryUrl(image);
|
||||
String fileName = UUID.randomUUID().toString().replace("-", "") + "." + image.getImageType().name().toLowerCase();
|
||||
String resultUrl = fileUtils.uploadFileByUrl(url, fileName);
|
||||
if (resultUrl == null) {
|
||||
log.error("图片上传失败: " + url);
|
||||
}
|
||||
contentBuilder.append(resultUrl).append(";");
|
||||
}
|
||||
if (message instanceof FileMessage file) {
|
||||
log.info("文件: " + file.getName());
|
||||
if (contentBuilder == null) contentBuilder = new StringBuilder();
|
||||
AbsoluteFile absoluteFile = file.toAbsoluteFile(event.getGroup());
|
||||
String url = absoluteFile.getUrl();
|
||||
String resultUrl = fileUtils.uploadFileByUrl(url, file.getName());
|
||||
if (resultUrl == null) {
|
||||
log.error("文件上传失败: " + url);
|
||||
}
|
||||
contentBuilder.append(resultUrl).append(";");
|
||||
}
|
||||
}
|
||||
// 插入数据库
|
||||
ClassGroupTeacher classGroupTeacher = MyBot.getClassGroupTeacherByTeacherGroupId(teacherId);
|
||||
TeacherQqMsgs teacherQqMsgs = new TeacherQqMsgs();
|
||||
teacherQqMsgs.setCreateTime(TimeUtils.getCurrentTime());
|
||||
teacherQqMsgs.setTeacherQqId(teacherId);
|
||||
teacherQqMsgs.setClassId(classGroupTeacher.getClassId());
|
||||
teacherQqMsgs.setCourseType(classGroupTeacher.getCourseType());
|
||||
Optional.ofNullable(strBuilder).ifPresent(item -> {
|
||||
String remarks = item.substring(0, item.length() - 3);
|
||||
log.info("提交的文本: " + remarks);
|
||||
teacherQqMsgs.setRemarks(remarks);
|
||||
});
|
||||
Optional.ofNullable(contentBuilder).ifPresent(item -> {
|
||||
String msgContent = item.deleteCharAt(item.length() - 1).toString();
|
||||
log.info("提交的图片: " + msgContent);
|
||||
teacherQqMsgs.setMsgContent(msgContent);
|
||||
});
|
||||
int row = teacherQqMsgsMapper.insert(teacherQqMsgs);
|
||||
if (row > 0) {
|
||||
log.info("插入成功: " + messages);
|
||||
} else {
|
||||
log.error("插入失败: " + messages);
|
||||
}
|
||||
return ListeningStatus.LISTENING; // 表示继续监听事件
|
||||
}
|
||||
|
||||
// @NotNull
|
||||
// @EventHandler
|
||||
// public ListeningStatus onMessage(@NotNull FriendMessageEvent event) throws Exception { // 可以抛出任何异常, 将在 handleException 处理
|
||||
// System.out.println("收到消息: " + event.getMessage());
|
||||
// MessageChain messages = event.getMessage();
|
||||
// messages.
|
||||
// event.getSubject().sendMessage("friend");
|
||||
// return ListeningStatus.LISTENING; // 表示继续监听事件
|
||||
// // return ListeningStatus.STOPPED; // 表示停止监听事件
|
||||
// }
|
||||
|
||||
}
|
60
src/main/java/com/linxyun/homework/common/entity/Result.java
Normal file
60
src/main/java/com/linxyun/homework/common/entity/Result.java
Normal file
@ -0,0 +1,60 @@
|
||||
package com.linxyun.homework.common.entity;
|
||||
|
||||
import com.linxyun.homework.common.enums.ErrorCode;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
@Schema(description = "统一返回结果")
|
||||
public class Result<E> {
|
||||
@Schema(description = "返回数据")
|
||||
public E data;
|
||||
@Schema(description = "状态码")
|
||||
public String code;
|
||||
@Schema(description = "返回信息")
|
||||
public String msg;
|
||||
@Schema(description = "是否成功")
|
||||
public boolean success = true;
|
||||
|
||||
public Result(E data, String code, String msg, boolean success) {
|
||||
this.data = data;
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(ErrorCode codeEnum) {
|
||||
return new Result<>(null, codeEnum.getCode(), codeEnum.getMessage(), false);
|
||||
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(String code, String msg) {
|
||||
return new Result<>(null, code, msg, false);
|
||||
}
|
||||
|
||||
public static <T> Result<T> ok() {
|
||||
return new Result<>(null, "0000", "操作成功", true);
|
||||
}
|
||||
|
||||
public static <T> Result<T> ok(String msg) {
|
||||
return new Result<>(null, "0000", msg, true);
|
||||
|
||||
}
|
||||
public static <T> Result<T> ok(T data) {
|
||||
return new Result<>(data, "0000", "操作成功", true);
|
||||
|
||||
}
|
||||
|
||||
public static <T> Result<T> ok(T data, String msg) {
|
||||
return new Result<>(data, "0000", msg, true);
|
||||
}
|
||||
|
||||
public Result() {
|
||||
this.success = false;
|
||||
this.code = "9999";
|
||||
this.msg = "操作失败";
|
||||
this.data = null;
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.linxyun.homework.common.enums;
|
||||
|
||||
public enum CourseType {
|
||||
// 语文 0
|
||||
CHINESE("0", "语文"),
|
||||
// 数学 1
|
||||
MATH("1", "数学"),
|
||||
// 英语 2
|
||||
ENGLISH("2", "英语");
|
||||
|
||||
private final String code;
|
||||
private final String desc;
|
||||
|
||||
CourseType(String code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public static String getDescByCode(String code) {
|
||||
for (CourseType type : CourseType.values()) {
|
||||
if (type.code.equals(code)) {
|
||||
return type.desc;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
122
src/main/java/com/linxyun/homework/common/enums/ErrorCode.java
Normal file
122
src/main/java/com/linxyun/homework/common/enums/ErrorCode.java
Normal file
@ -0,0 +1,122 @@
|
||||
package com.linxyun.homework.common.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum ErrorCode {
|
||||
|
||||
// 用户不存在或密码不匹配
|
||||
USER_NOT_FOUND_OR_PASSWORD_MISMATCH("1006", "用户不存在或密码不匹配"),
|
||||
|
||||
// 参数错误
|
||||
PARAMETER_ERROR("204", "参数错误"),
|
||||
|
||||
// URI 不存在
|
||||
URI_NOT_FOUND("240", "URI不存在"),
|
||||
|
||||
// URI 已经存在
|
||||
URI_ALREADY_EXISTS("241", "URI已经存在"),
|
||||
|
||||
// 服务的路由异常,请联系管理员
|
||||
ROUTING_EXCEPTION("320", "服务的路由异常,请联系管理员"),
|
||||
|
||||
// 处理超时,服务配置出错,请联系管理员
|
||||
TIMEOUT_ERROR("998", "处理超时,服务配置出错,请联系管理员"),
|
||||
|
||||
// 登录超时,请重新登录
|
||||
LOGIN_TIMEOUT("9998", "登录超时,请重新登录"),
|
||||
|
||||
// 登录超时,请重新登录
|
||||
LOGIN_TIMEOUT_2("401", "登录超时,请重新登录"),
|
||||
|
||||
// 操作失败
|
||||
OPERATION_FAIL("1005", "操作失败"),
|
||||
|
||||
// 用户已经存在
|
||||
USER_ALREADY_EXISTS("1007", "用户已经存在"),
|
||||
|
||||
// 操作ID配置错误,请联系管理员
|
||||
OPERATION_ID_ERROR("1008", "操作ID配置错误,请联系管理员"),
|
||||
|
||||
// 用户ID参数错误
|
||||
USER_ID_PARAMETER_ERROR("1009", "用户ID参数错误"),
|
||||
|
||||
// 用户邮箱地址错误
|
||||
USER_EMAIL_ERROR("1011", "用户邮箱地址错误"),
|
||||
|
||||
// 邮箱地址已经存在
|
||||
EMAIL_ALREADY_EXISTS("1012", "邮箱地址已经存在"),
|
||||
|
||||
// 手机号码格式不正确
|
||||
PHONE_NUMBER_FORMAT_ERROR("1013", "手机号码格式不正确"),
|
||||
|
||||
// 手机号码已经存在
|
||||
PHONE_NUMBER_ALREADY_EXISTS("1014", "手机号码已经存在"),
|
||||
|
||||
// 登录验证出错
|
||||
LOGIN_VALIDATION_ERROR("1020", "登录验证出错"),
|
||||
|
||||
// 用户没有登录
|
||||
USER_NOT_LOGGED_IN("1021", "用户没有登录"),
|
||||
|
||||
// 用户状态不正常
|
||||
USER_STATUS_ERROR("1022", "用户状态不正常"),
|
||||
|
||||
// 发送验证码失败
|
||||
SEND_VERIFICATION_CODE_FAIL("1023", "发送验证码失败"),
|
||||
|
||||
// 验证码验证失败
|
||||
VERIFICATION_CODE_FAIL("1024", "验证码验证失败"),
|
||||
|
||||
// 用户组已经存在
|
||||
USER_GROUP_ALREADY_EXISTS("1030", "用户组已经存在"),
|
||||
|
||||
// 用户组不存在
|
||||
USER_GROUP_NOT_EXISTS("1031", "用户组不经存在"),
|
||||
|
||||
// 操作出错
|
||||
OPERATION_ERROR("1999", "操作出错"),
|
||||
|
||||
// 前端处理验证数据出错
|
||||
FRONTEND_VALIDATION_ERROR("886000", "前端处理验证数据出错"),
|
||||
|
||||
// 请先删除内容
|
||||
DELETE_CONTENT_FIRST("2012", "请先删除内容"),
|
||||
// 文件不存在
|
||||
FILE_NOT_FOUND("3000", "文件不存在"),
|
||||
// 文件大小超出限制
|
||||
FILE_SIZE_EXCEEDED("3001", "文件大小超出限制"),
|
||||
// 文件上传失败
|
||||
FILE_UPLOAD_FAILED("3002", "文件上传失败"),
|
||||
// 请求失败
|
||||
REQUEST_FAILED("3003", "请求失败"),
|
||||
NONE("6666666", "站位");
|
||||
|
||||
|
||||
|
||||
private final String code;
|
||||
private final String message;
|
||||
|
||||
ErrorCode(String code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
// 根据错误代码获取对应的错误信息
|
||||
public static String getMessageByCode(String code) {
|
||||
for (ErrorCode errorCode : values()) {
|
||||
if (errorCode.getCode().equals(code)) {
|
||||
return errorCode.getMessage();
|
||||
}
|
||||
}
|
||||
return "未知错误";
|
||||
}
|
||||
}
|
25
src/main/java/com/linxyun/homework/config/OpenApiConfig.java
Normal file
25
src/main/java/com/linxyun/homework/config/OpenApiConfig.java
Normal file
@ -0,0 +1,25 @@
|
||||
package com.linxyun.homework.config;
|
||||
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.info.Contact;
|
||||
import io.swagger.v3.oas.models.info.Info;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class OpenApiConfig {
|
||||
|
||||
@Bean
|
||||
public OpenAPI springShopOpenAPI() {
|
||||
return new OpenAPI()
|
||||
// 接口文档标题
|
||||
.info(new Info()
|
||||
.title("家庭作业助手接口文档")
|
||||
// 接口文档描述
|
||||
.description("家庭作业助手接口")
|
||||
// 接口文档版本
|
||||
.version("v1.0")
|
||||
.contact(new Contact().name("wenxin"))
|
||||
);
|
||||
}
|
||||
}
|
19
src/main/java/com/linxyun/homework/config/WebConfig.java
Normal file
19
src/main/java/com/linxyun/homework/config/WebConfig.java
Normal file
@ -0,0 +1,19 @@
|
||||
package com.linxyun.homework.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
// 全局跨域
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**")
|
||||
.allowedOriginPatterns("*")
|
||||
.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
|
||||
.allowCredentials(true)
|
||||
.maxAge(3600)
|
||||
.allowedHeaders("*");
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package com.linxyun.homework.controller;
|
||||
|
||||
|
||||
import com.linxyun.homework.common.entity.Result;
|
||||
import com.linxyun.homework.common.enums.ErrorCode;
|
||||
import com.linxyun.homework.domain.po.Class;
|
||||
import com.linxyun.homework.service.ClassService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RequestMapping("/class")
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@Tag(name = "班级模块")
|
||||
public class ClassController {
|
||||
|
||||
private final ClassService classService;
|
||||
|
||||
/**
|
||||
* 添加班级
|
||||
* @param clazz 班级信息
|
||||
* @return Result
|
||||
*/
|
||||
@PostMapping
|
||||
@Operation(summary = "添加班级")
|
||||
public Result<Object> addClass(@RequestBody Class clazz) {
|
||||
boolean status = classService.save(clazz);
|
||||
if (!status) {
|
||||
return Result.error(ErrorCode.OPERATION_FAIL);
|
||||
}
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取班级列表
|
||||
* @return Result
|
||||
*/
|
||||
@GetMapping
|
||||
@Operation(summary = "获取班级列表")
|
||||
public Result<Object> getClassList() {
|
||||
return Result.ok(classService.list());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据班级id获取班级信息
|
||||
* @param classId 班级ID
|
||||
* @return Result
|
||||
*/
|
||||
@GetMapping("/{classId}")
|
||||
@Operation(summary = "根据班级id获取班级信息", parameters = { @Parameter(name = "classId", description = "班级ID", required = true) })
|
||||
public Result<Object> getClassById(@PathVariable Integer classId) {
|
||||
return Result.ok(classService.getById(classId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除班级
|
||||
* @param classId 班级ID
|
||||
* @return Result
|
||||
*/
|
||||
@DeleteMapping("/{classId}")
|
||||
@Operation(summary = "删除班级", parameters = { @Parameter(name = "classId", description = "班级ID", required = true) })
|
||||
public Result<Object> deleteClassById(@PathVariable Integer classId) {
|
||||
boolean status = classService.removeById(classId);
|
||||
if (!status) {
|
||||
return Result.error(ErrorCode.OPERATION_FAIL);
|
||||
}
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新班级信息
|
||||
* @param clazz 班级信息
|
||||
* @return Result
|
||||
*/
|
||||
@PatchMapping
|
||||
@Operation(summary = "更新班级信息")
|
||||
public Result<Object> updateClass(@RequestBody Class clazz) {
|
||||
boolean status = classService.updateById(clazz);
|
||||
if (!status) {
|
||||
return Result.error(ErrorCode.OPERATION_FAIL);
|
||||
}
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.linxyun.homework.controller;
|
||||
|
||||
import com.linxyun.homework.common.entity.Result;
|
||||
import com.linxyun.homework.service.ClassQqGroupTeacherService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/group/msg")
|
||||
public class GroupMsgController {
|
||||
private final ClassQqGroupTeacherService groupMsgService;
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.linxyun.homework.controller;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/group/teacher")
|
||||
public class GroupTeacherController {
|
||||
|
||||
// private final
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.linxyun.homework.controller;
|
||||
|
||||
import com.linxyun.homework.common.entity.Result;
|
||||
import com.linxyun.homework.domain.dto.AnswerMsg;
|
||||
import com.linxyun.homework.service.HomeworkAnswerService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/answer")
|
||||
@RequiredArgsConstructor
|
||||
@Tag(name = "作业答案模块")
|
||||
public class HomeworkAnswerController {
|
||||
private final HomeworkAnswerService homeworkAnswerService;
|
||||
|
||||
@PostMapping("/msg")
|
||||
@Operation(summary = "通过消息添加答案")
|
||||
public Result<Object> addAnswerByMsgId(@RequestBody AnswerMsg answerMsg) {
|
||||
return homeworkAnswerService.addAnswerByMsgId(answerMsg);
|
||||
}
|
||||
}
|
19
src/main/java/com/linxyun/homework/domain/dto/AnswerMsg.java
Normal file
19
src/main/java/com/linxyun/homework/domain/dto/AnswerMsg.java
Normal file
@ -0,0 +1,19 @@
|
||||
package com.linxyun.homework.domain.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(description = "作业答案消息")
|
||||
public class AnswerMsg {
|
||||
@Schema(description = "消息ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Integer msgId;
|
||||
@Schema(description = "会员ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Integer memberId;
|
||||
@Schema(description = "作业标题")
|
||||
private String title;
|
||||
@Schema(description = "作业内容,多文本以 ||| 分隔")
|
||||
private String content;
|
||||
@Schema(description = "作业文件,多文件以 ; 分隔")
|
||||
private String file;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.linxyun.homework.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ClassGroupTeacher {
|
||||
private String teacherGroupId;
|
||||
private String teacherNickname;
|
||||
private String courseType;
|
||||
private Integer classId;
|
||||
private String className;
|
||||
private String qqGroupId;
|
||||
}
|
59
src/main/java/com/linxyun/homework/domain/po/Class.java
Normal file
59
src/main/java/com/linxyun/homework/domain/po/Class.java
Normal file
@ -0,0 +1,59 @@
|
||||
package com.linxyun.homework.domain.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
*
|
||||
* @TableName tab_class
|
||||
*/
|
||||
@ToString
|
||||
@TableName(value ="tab_class")
|
||||
@Data
|
||||
@Schema(description="班级")
|
||||
public class Class implements Serializable {
|
||||
/**
|
||||
* 班级名
|
||||
*/
|
||||
@TableId(value = "ClassID", type = IdType.AUTO)
|
||||
@Schema(description = "班级ID")
|
||||
private Integer classId;
|
||||
|
||||
/**
|
||||
* 班级名
|
||||
*/
|
||||
@TableField(value = "ClassName")
|
||||
@Schema(description = "班级名")
|
||||
private String className;
|
||||
|
||||
/**
|
||||
* 对应年级枚举
|
||||
*/
|
||||
@TableField(value = "Greade")
|
||||
@Schema(description = "对应年级枚举")
|
||||
private String greade;
|
||||
|
||||
/**
|
||||
* 学校ID
|
||||
*/
|
||||
@TableField(value = "SchoolID")
|
||||
@Schema(description = "学校ID")
|
||||
private Integer schoolId;
|
||||
|
||||
/**
|
||||
* 班级QQ群ID
|
||||
*/
|
||||
@TableField(value = "QQGroupID")
|
||||
@Schema(description = "班级QQ群ID")
|
||||
private String qqGroupId;
|
||||
|
||||
@TableField(exist = false)
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.linxyun.homework.domain.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
*
|
||||
* @TableName tab_class_qqgroup_teacher
|
||||
*/
|
||||
@TableName(value ="tab_class_qqgroup_teacher")
|
||||
@Data
|
||||
@ToString
|
||||
public class ClassQqGroupTeacher implements Serializable {
|
||||
/**
|
||||
* 记录ID
|
||||
*/
|
||||
@TableId(value = "RecordID", type = IdType.AUTO)
|
||||
private Integer recordId;
|
||||
|
||||
/**
|
||||
* 班级ID
|
||||
*/
|
||||
@TableField(value = "ClassID")
|
||||
private Integer classId;
|
||||
|
||||
/**
|
||||
* 老师在QQ群的ID
|
||||
*/
|
||||
@TableField(value = "TeacherGroupID")
|
||||
private String teacherGroupId;
|
||||
|
||||
/**
|
||||
* QQ群中的名称
|
||||
*/
|
||||
@TableField(value = "TeacherNickName")
|
||||
private String teacherNickname;
|
||||
|
||||
/**
|
||||
* 课程类型
|
||||
*/
|
||||
@TableField(value = "CourseType")
|
||||
private String courseType;
|
||||
|
||||
@TableField(exist = false)
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package com.linxyun.homework.domain.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
*
|
||||
* @TableName tab_homework_answer
|
||||
*/
|
||||
@TableName(value ="tab_homework_answer")
|
||||
@Data
|
||||
@ToString
|
||||
public class HomeworkAnswer implements Serializable {
|
||||
/**
|
||||
* 答案ID
|
||||
*/
|
||||
@TableId(value = "AnswerID", type = IdType.AUTO)
|
||||
private Integer answerId;
|
||||
|
||||
/**
|
||||
* 标题说明
|
||||
*/
|
||||
@TableField(value = "Title")
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* 0:直接输入 1:选择资源
|
||||
*/
|
||||
@TableField(value = "ContentType")
|
||||
private Integer contentType;
|
||||
|
||||
/**
|
||||
* Content
|
||||
*/
|
||||
@TableField(value = "Content")
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 附件ID
|
||||
*/
|
||||
@TableField(value = "ContentFileID")
|
||||
private String contentFileId;
|
||||
|
||||
/**
|
||||
* 创建人会员ID
|
||||
*/
|
||||
@TableField(value = "MemberID")
|
||||
private Integer memberId;
|
||||
|
||||
/**
|
||||
* 学生ID
|
||||
*/
|
||||
@TableField(value = "StudentID")
|
||||
private Integer studentId;
|
||||
|
||||
/**
|
||||
* 0:个人 1:班级
|
||||
*/
|
||||
@TableField(value = "CreateType")
|
||||
private Integer createType;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(value = "CreateTime")
|
||||
private String createTime;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@TableField(value = "Remark")
|
||||
private String remark;
|
||||
|
||||
@TableField(exist = false)
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package com.linxyun.homework.domain.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
*
|
||||
* @TableName tab_teacher_qq_msgs
|
||||
*/
|
||||
@TableName(value ="tab_teacher_qq_msgs")
|
||||
@Data
|
||||
@ToString
|
||||
public class TeacherQqMsgs implements Serializable {
|
||||
/**
|
||||
* 消息ID
|
||||
*/
|
||||
@TableId(value = "MsgID", type = IdType.AUTO)
|
||||
private Integer msgId;
|
||||
|
||||
/**
|
||||
* 班级ID
|
||||
*/
|
||||
@TableField(value = "ClassID")
|
||||
private Integer classId;
|
||||
|
||||
/**
|
||||
* 老师的QQID
|
||||
*/
|
||||
@TableField(value = "TeacherQQID")
|
||||
private String teacherQqId;
|
||||
|
||||
/**
|
||||
* 课程类型,枚举
|
||||
*/
|
||||
@TableField(value = "CourseType")
|
||||
private String courseType;
|
||||
|
||||
/**
|
||||
* 消息类型,对应作业内容类型,枚举
|
||||
*/
|
||||
@TableField(value = "MsgType")
|
||||
private String msgType;
|
||||
|
||||
/**
|
||||
* 文本直接存内容,其它存附件的文件ID,逗号分隔
|
||||
*/
|
||||
@TableField(value = "MsgContent")
|
||||
private String msgContent;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(value = "CreateTime")
|
||||
private String createTime;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@TableField(value = "Remarks")
|
||||
private String remarks;
|
||||
|
||||
@TableField(exist = false)
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
18
src/main/java/com/linxyun/homework/mapper/ClassMapper.java
Normal file
18
src/main/java/com/linxyun/homework/mapper/ClassMapper.java
Normal file
@ -0,0 +1,18 @@
|
||||
package com.linxyun.homework.mapper;
|
||||
|
||||
import com.linxyun.homework.domain.po.Class;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @author wx_20
|
||||
* @description 针对表【tab_class】的数据库操作Mapper
|
||||
* @createDate 2024-11-25 09:45:12
|
||||
* @Entity com.linxyun.homework.domain.po.Class
|
||||
*/
|
||||
public interface ClassMapper extends BaseMapper<Class> {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
package com.linxyun.homework.mapper;
|
||||
|
||||
import com.linxyun.homework.domain.dto.ClassGroupTeacher;
|
||||
import com.linxyun.homework.domain.po.ClassQqGroupTeacher;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wx_20
|
||||
* @description 针对表【tab_class_qqgroup_teacher】的数据库操作Mapper
|
||||
* @createDate 2024-11-25 09:45:12
|
||||
* @Entity com.linxyun.homework.domain.po.ClassQqgroupTeacher
|
||||
*/
|
||||
public interface ClassQqGroupTeacherMapper extends BaseMapper<ClassQqGroupTeacher> {
|
||||
List<ClassGroupTeacher> selectClassAndGroupTeacher();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,18 @@
|
||||
package com.linxyun.homework.mapper;
|
||||
|
||||
import com.linxyun.homework.domain.po.HomeworkAnswer;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @author wx_20
|
||||
* @description 针对表【tab_homework_answer】的数据库操作Mapper
|
||||
* @createDate 2024-11-25 15:14:13
|
||||
* @Entity com.linxyun.homework.domain.po.HomeworkAnswer
|
||||
*/
|
||||
public interface HomeworkAnswerMapper extends BaseMapper<HomeworkAnswer> {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,18 @@
|
||||
package com.linxyun.homework.mapper;
|
||||
|
||||
import com.linxyun.homework.domain.po.TeacherQqMsgs;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @author wx_20
|
||||
* @description 针对表【tab_teacher_qq_msgs】的数据库操作Mapper
|
||||
* @createDate 2024-11-25 09:45:12
|
||||
* @Entity com.linxyun.homework.domain.po.TeacherQqMsgs
|
||||
*/
|
||||
public interface TeacherQqMsgsMapper extends BaseMapper<TeacherQqMsgs> {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
package com.linxyun.homework.service;
|
||||
|
||||
import com.linxyun.homework.domain.po.ClassQqGroupTeacher;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @author wx_20
|
||||
* @description 针对表【tab_class_qqgroup_teacher】的数据库操作Service
|
||||
* @createDate 2024-11-25 09:45:12
|
||||
*/
|
||||
public interface ClassQqGroupTeacherService extends IService<ClassQqGroupTeacher> {
|
||||
|
||||
}
|
13
src/main/java/com/linxyun/homework/service/ClassService.java
Normal file
13
src/main/java/com/linxyun/homework/service/ClassService.java
Normal file
@ -0,0 +1,13 @@
|
||||
package com.linxyun.homework.service;
|
||||
|
||||
import com.linxyun.homework.domain.po.Class;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @author wx_20
|
||||
* @description 针对表【tab_class】的数据库操作Service
|
||||
* @createDate 2024-11-25 09:45:12
|
||||
*/
|
||||
public interface ClassService extends IService<Class> {
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.linxyun.homework.service;
|
||||
|
||||
import com.linxyun.homework.common.entity.Result;
|
||||
import com.linxyun.homework.domain.dto.AnswerMsg;
|
||||
import com.linxyun.homework.domain.po.HomeworkAnswer;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @author wx_20
|
||||
* @description 针对表【tab_homework_answer】的数据库操作Service
|
||||
* @createDate 2024-11-25 15:14:13
|
||||
*/
|
||||
public interface HomeworkAnswerService extends IService<HomeworkAnswer> {
|
||||
|
||||
Result<Object> addAnswerByMsgId(AnswerMsg answerMsg);
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.linxyun.homework.service;
|
||||
|
||||
import com.linxyun.homework.domain.po.TeacherQqMsgs;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @author wx_20
|
||||
* @description 针对表【tab_teacher_qq_msgs】的数据库操作Service
|
||||
* @createDate 2024-11-25 09:45:12
|
||||
*/
|
||||
public interface TeacherQqMsgsService extends IService<TeacherQqMsgs> {
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.linxyun.homework.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.linxyun.homework.domain.po.ClassQqGroupTeacher;
|
||||
import com.linxyun.homework.service.ClassQqGroupTeacherService;
|
||||
import com.linxyun.homework.mapper.ClassQqGroupTeacherMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author wx_20
|
||||
* @description 针对表【tab_class_qqgroup_teacher】的数据库操作Service实现
|
||||
* @createDate 2024-11-25 09:45:12
|
||||
*/
|
||||
@Service
|
||||
public class ClassQqGroupTeacherServiceImpl extends ServiceImpl<ClassQqGroupTeacherMapper, ClassQqGroupTeacher>
|
||||
implements ClassQqGroupTeacherService {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,22 @@
|
||||
package com.linxyun.homework.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.linxyun.homework.domain.po.Class;
|
||||
import com.linxyun.homework.service.ClassService;
|
||||
import com.linxyun.homework.mapper.ClassMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author wx_20
|
||||
* @description 针对表【tab_class】的数据库操作Service实现
|
||||
* @createDate 2024-11-25 09:45:12
|
||||
*/
|
||||
@Service
|
||||
public class ClassServiceImpl extends ServiceImpl<ClassMapper, Class>
|
||||
implements ClassService{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,75 @@
|
||||
package com.linxyun.homework.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.linxyun.homework.common.entity.Result;
|
||||
import com.linxyun.homework.common.enums.CourseType;
|
||||
import com.linxyun.homework.common.enums.ErrorCode;
|
||||
import com.linxyun.homework.domain.dto.AnswerMsg;
|
||||
import com.linxyun.homework.domain.po.HomeworkAnswer;
|
||||
import com.linxyun.homework.domain.po.TeacherQqMsgs;
|
||||
import com.linxyun.homework.mapper.TeacherQqMsgsMapper;
|
||||
import com.linxyun.homework.service.HomeworkAnswerService;
|
||||
import com.linxyun.homework.mapper.HomeworkAnswerMapper;
|
||||
import com.linxyun.homework.utils.StringUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author wx_20
|
||||
* @description 针对表【tab_homework_answer】的数据库操作Service实现
|
||||
* @createDate 2024-11-25 15:14:13
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class HomeworkAnswerServiceImpl extends ServiceImpl<HomeworkAnswerMapper, HomeworkAnswer>
|
||||
implements HomeworkAnswerService{
|
||||
|
||||
private final HomeworkAnswerMapper homeworkAnswerMapper;
|
||||
private final TeacherQqMsgsMapper teacherQqMsgsMapper;
|
||||
|
||||
@Override
|
||||
public Result<Object> addAnswerByMsgId(AnswerMsg answerMsg) {
|
||||
Integer msgId = answerMsg.getMsgId();
|
||||
String title = answerMsg.getTitle();
|
||||
Integer memberId = answerMsg.getMemberId();
|
||||
if (msgId == null || memberId == null) {
|
||||
log.error("msgId is null");
|
||||
return Result.error(ErrorCode.PARAMETER_ERROR);
|
||||
}
|
||||
// 根据 msgId 查询 消息
|
||||
TeacherQqMsgs teacherQqMsgs = teacherQqMsgsMapper.selectById(msgId);
|
||||
if (teacherQqMsgs == null) {
|
||||
log.error("msgId: " + msgId + " not found");
|
||||
return Result.error(ErrorCode.PARAMETER_ERROR);
|
||||
}
|
||||
if (!(teacherQqMsgs.getMsgContent().contains(answerMsg.getFile()) && teacherQqMsgs.getRemarks().contains(answerMsg.getContent()))) {
|
||||
return Result.error(ErrorCode.PARAMETER_ERROR);
|
||||
}
|
||||
HomeworkAnswer homeworkAnswer = new HomeworkAnswer();
|
||||
homeworkAnswer.setMemberId(memberId);
|
||||
if (StringUtils.isEmpty(title)) {
|
||||
homeworkAnswer.setTitle(CourseType.getDescByCode(teacherQqMsgs.getCourseType())); // 课程类型
|
||||
} else {
|
||||
homeworkAnswer.setTitle(title);
|
||||
}
|
||||
homeworkAnswer.setCreateType(1); // 班级可看
|
||||
homeworkAnswer.setStudentId(teacherQqMsgs.getClassId());
|
||||
if(answerMsg.getFile() != null) {
|
||||
homeworkAnswer.setContentType(1);
|
||||
homeworkAnswer.setRemark(answerMsg.getContent());
|
||||
homeworkAnswer.setContentFileId(answerMsg.getFile()); // 文件资源
|
||||
} else {
|
||||
homeworkAnswer.setContentType(0);
|
||||
homeworkAnswer.setContent(answerMsg.getContent()); // 文字
|
||||
}
|
||||
int row = homeworkAnswerMapper.insert(homeworkAnswer);
|
||||
if (row < 1) {
|
||||
return Result.error(ErrorCode.OPERATION_FAIL);
|
||||
}
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,22 @@
|
||||
package com.linxyun.homework.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.linxyun.homework.domain.po.TeacherQqMsgs;
|
||||
import com.linxyun.homework.service.TeacherQqMsgsService;
|
||||
import com.linxyun.homework.mapper.TeacherQqMsgsMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author wx_20
|
||||
* @description 针对表【tab_teacher_qq_msgs】的数据库操作Service实现
|
||||
* @createDate 2024-11-25 09:45:12
|
||||
*/
|
||||
@Service
|
||||
public class TeacherQqMsgsServiceImpl extends ServiceImpl<TeacherQqMsgsMapper, TeacherQqMsgs>
|
||||
implements TeacherQqMsgsService{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
153
src/main/java/com/linxyun/homework/utils/FileUtils.java
Normal file
153
src/main/java/com/linxyun/homework/utils/FileUtils.java
Normal file
@ -0,0 +1,153 @@
|
||||
package com.linxyun.homework.utils;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.linxyun.homework.HomeworkApplication;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class FileUtils {
|
||||
private static final OkHttpClient client = new OkHttpClient();
|
||||
|
||||
@Value("${upload.base-url}")
|
||||
private String baseUrl;
|
||||
|
||||
/**
|
||||
* 下载文件到指定目录
|
||||
* @param fileUrl 文件 URL
|
||||
* @param targetDir 本地目标目录
|
||||
* @param fileName 保存的文件名
|
||||
* @throws IOException 如果发生 IO 异常
|
||||
*/
|
||||
public void downloadFile(String fileUrl, String targetDir, String fileName) throws IOException {
|
||||
// 构建请求
|
||||
Request request = new Request.Builder()
|
||||
.url(fileUrl)
|
||||
.build();
|
||||
|
||||
// 执行请求
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
if (!response.isSuccessful()) {
|
||||
throw new IOException("文件下载失败, HTTP 响应码: " + response.code());
|
||||
}
|
||||
|
||||
// 确保目标目录存在
|
||||
File directory = new File(targetDir);
|
||||
if (!directory.exists() && !directory.mkdirs()) {
|
||||
throw new IOException("无法创建目标目录: " + targetDir);
|
||||
}
|
||||
|
||||
// 获取输入流并保存文件
|
||||
try (InputStream inputStream = response.body().byteStream();
|
||||
FileOutputStream outputStream = new FileOutputStream(new File(directory, fileName))) {
|
||||
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("文件下载完成: " + targetDir + File.separator + fileName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载指定 URL 的文件,并将内容转化为字节数组。
|
||||
*
|
||||
* @param fileUrl 文件的 URL
|
||||
* @param fileName 文件名(可以用来关联下载到本地的文件)
|
||||
* @return 文件内容的字节数组
|
||||
*/
|
||||
public String uploadFileByUrl(String fileUrl, String fileName) {
|
||||
// 创建 GET 请求
|
||||
Request request = new Request.Builder()
|
||||
.url(fileUrl)
|
||||
.build();
|
||||
|
||||
// 执行请求
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
if (!response.isSuccessful()) {
|
||||
log.error("Failed to download file: " + response.message());
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取文件内容作为字节数组
|
||||
try (ResponseBody responseBody = response.body();
|
||||
InputStream inputStream = responseBody.byteStream();
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
|
||||
// 读取数据到缓冲区
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
byteArrayOutputStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
return uploadFile(byteArrayOutputStream.toByteArray(), fileName);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("FileUploadTool uploadFileByUrl exception: ", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 使用 OkHttp 上传文件
|
||||
*
|
||||
* @param fileBytes 文件字节数组
|
||||
* @param fileName 文件名
|
||||
* @return 上传成功时返回服务器响应的 "data" 字段;否则返回 null
|
||||
*/
|
||||
public String uploadFile(byte[] fileBytes, String fileName) {
|
||||
String uploadUrl = baseUrl + "/eslithe/uploadFile.action";
|
||||
// 创建请求体
|
||||
RequestBody fileBody = RequestBody.create(fileBytes, MediaType.parse("application/octet-stream"));
|
||||
MultipartBody requestBody = new MultipartBody.Builder()
|
||||
.setType(MultipartBody.FORM)
|
||||
.addFormDataPart("file", fileName, fileBody)
|
||||
.build();
|
||||
|
||||
// 创建请求
|
||||
Request request = new Request.Builder()
|
||||
.url(uploadUrl)
|
||||
.post(requestBody)
|
||||
.build();
|
||||
|
||||
// 执行请求
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
String responseBody = response.body().string();
|
||||
log.info("FileUploadTool uploadFile result: " + responseBody);
|
||||
|
||||
// 解析响应
|
||||
JSONObject jsonObject = JSONObject.parseObject(responseBody);
|
||||
if (jsonObject != null
|
||||
&& jsonObject.getBoolean("success") != null
|
||||
&& jsonObject.getBoolean("success")
|
||||
&& jsonObject.containsKey("data")) {
|
||||
return jsonObject.getString("data");
|
||||
} else {
|
||||
log.error("FileUploadTool uploadFile failed: " + responseBody);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
log.error("FileUploadTool uploadFile failed, HTTP code: " + response.code());
|
||||
return null;
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
log.error("FileUploadTool uploadFile exception: ", ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.linxyun.homework.utils;
|
||||
|
||||
public class StringUtils {
|
||||
public static boolean isEmpty(String str)
|
||||
{
|
||||
return str == null || str.isEmpty();
|
||||
}
|
||||
}
|
21
src/main/java/com/linxyun/homework/utils/TimeUtils.java
Normal file
21
src/main/java/com/linxyun/homework/utils/TimeUtils.java
Normal file
@ -0,0 +1,21 @@
|
||||
package com.linxyun.homework.utils;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class TimeUtils {
|
||||
static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); // 定义日期格式
|
||||
public static Date toDate(String dateStr) {
|
||||
try {
|
||||
return dateFormat.parse(dateStr);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(); // 如果有异常,输出错误信息
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getCurrentTime() {
|
||||
Date now = new Date();
|
||||
return dateFormat.format(now);
|
||||
}
|
||||
}
|
@ -6,9 +6,9 @@ spring: #springboot的配置
|
||||
datasource: #定义数据源
|
||||
#127.0.0.1为本机测试的ip,3306是mysql的端口号。serverTimezone是定义时区,照抄就好,mysql高版本需要定义这些东西
|
||||
#useSSL也是某些高版本mysql需要问有没有用SSL连接
|
||||
url: jdbc:mysql://127.0.0.1:3306/test?serverTimezone=GMT%2B8&useSSL=FALSE
|
||||
url: jdbc:mysql://117.89.254.176:8846/homeworkor?serverTimezone=GMT%2B8&useSSL=FALSE
|
||||
username: root #数据库用户名,root为管理员
|
||||
password: 123456 #该数据库用户的密码
|
||||
password: Home.lxy.com #该数据库用户的密码
|
||||
# 使用druid数据源
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
@ -33,3 +33,27 @@ mybatis-plus:
|
||||
call-setters-on-nulls: true
|
||||
# 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
|
||||
springdoc:
|
||||
swagger-ui:
|
||||
path: /swagger-ui.html
|
||||
tags-sorter: alpha
|
||||
operations-sorter: alpha
|
||||
api-docs:
|
||||
path: /v3/api-docs
|
||||
group-configs:
|
||||
- group: 'default'
|
||||
paths-to-match: '/**'
|
||||
packages-to-scan: com.linxyun.homework.controller
|
||||
# knife4j的增强配置,不需要增强可以不配
|
||||
knife4j:
|
||||
enable: true
|
||||
setting:
|
||||
language: zh_cn
|
||||
|
||||
mirai:
|
||||
bot:
|
||||
qq: 20243037
|
||||
|
||||
upload:
|
||||
base-url: http://www.linxyun.com
|
19
src/main/resources/mapper/ClassMapper.xml
Normal file
19
src/main/resources/mapper/ClassMapper.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.linxyun.homework.mapper.ClassMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="com.linxyun.homework.domain.po.Class">
|
||||
<id property="classid" column="ClassID" jdbcType="INTEGER"/>
|
||||
<result property="classname" column="ClassName" jdbcType="VARCHAR"/>
|
||||
<result property="greade" column="Greade" jdbcType="VARCHAR"/>
|
||||
<result property="schoolid" column="SchoolID" jdbcType="INTEGER"/>
|
||||
<result property="qqgroupid" column="QQGroupID" jdbcType="VARCHAR"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
ClassID,ClassName,Greade,
|
||||
SchoolID,QQGroupID
|
||||
</sql>
|
||||
</mapper>
|
29
src/main/resources/mapper/ClassQqGroupTeacherMapper.xml
Normal file
29
src/main/resources/mapper/ClassQqGroupTeacherMapper.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.linxyun.homework.mapper.ClassQqGroupTeacherMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="com.linxyun.homework.domain.po.ClassQqGroupTeacher">
|
||||
<id property="recordId" column="RecordID" jdbcType="INTEGER"/>
|
||||
<result property="classId" column="ClassID" jdbcType="INTEGER"/>
|
||||
<result property="teacherGroupId" column="TeacherGroupID" jdbcType="VARCHAR"/>
|
||||
<result property="teacherNickname" column="TeacherNickName" jdbcType="VARCHAR"/>
|
||||
<result property="courseType" column="CourseType" jdbcType="VARCHAR"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
RecordID,ClassID,TeacherGroupID,
|
||||
TeacherNickName,CourseType
|
||||
</sql>
|
||||
<select id="selectClassAndGroupTeacher" resultType="com.linxyun.homework.domain.dto.ClassGroupTeacher">
|
||||
select
|
||||
t.TeacherGroupID,
|
||||
t.TeacherNickName,
|
||||
t.ClassID, t.CourseType,
|
||||
c.ClassName,
|
||||
c.QQGroupID
|
||||
from tab_class_qqgroup_teacher t
|
||||
inner join tab_class c on t.ClassID = c.ClassID
|
||||
</select>
|
||||
</mapper>
|
26
src/main/resources/mapper/HomeworkAnswerMapper.xml
Normal file
26
src/main/resources/mapper/HomeworkAnswerMapper.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.linxyun.homework.mapper.HomeworkAnswerMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="com.linxyun.homework.domain.po.HomeworkAnswer">
|
||||
<id property="answerid" column="AnswerID" jdbcType="INTEGER"/>
|
||||
<result property="title" column="Title" jdbcType="VARCHAR"/>
|
||||
<result property="contenttype" column="ContentType" jdbcType="INTEGER"/>
|
||||
<result property="content" column="Content" jdbcType="VARCHAR"/>
|
||||
<result property="contentfileid" column="ContentFileID" jdbcType="VARCHAR"/>
|
||||
<result property="memberid" column="MemberID" jdbcType="INTEGER"/>
|
||||
<result property="studentid" column="StudentID" jdbcType="INTEGER"/>
|
||||
<result property="createtype" column="CreateType" jdbcType="INTEGER"/>
|
||||
<result property="createtime" column="CreateTime" jdbcType="VARCHAR"/>
|
||||
<result property="remark" column="Remark" jdbcType="VARCHAR"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
AnswerID,Title,ContentType,
|
||||
Content,ContentFileID,MemberID,
|
||||
StudentID,CreateType,CreateTime,
|
||||
Remark
|
||||
</sql>
|
||||
</mapper>
|
23
src/main/resources/mapper/TeacherQqMsgsMapper.xml
Normal file
23
src/main/resources/mapper/TeacherQqMsgsMapper.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.linxyun.homework.mapper.TeacherQqMsgsMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="com.linxyun.homework.domain.po.TeacherQqMsgs">
|
||||
<id property="msgid" column="MsgID" jdbcType="INTEGER"/>
|
||||
<result property="classid" column="ClassID" jdbcType="INTEGER"/>
|
||||
<result property="teacherqqid" column="TeacherQQID" jdbcType="VARCHAR"/>
|
||||
<result property="coursetype" column="CourseType" jdbcType="VARCHAR"/>
|
||||
<result property="msgtype" column="MsgType" jdbcType="VARCHAR"/>
|
||||
<result property="msgcontent" column="MsgContent" jdbcType="VARCHAR"/>
|
||||
<result property="createtime" column="CreateTime" jdbcType="VARCHAR"/>
|
||||
<result property="remarks" column="Remarks" jdbcType="VARCHAR"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
MsgID,ClassID,TeacherQQID,
|
||||
CourseType,MsgType,MsgContent,
|
||||
CreateTime,Remarks
|
||||
</sql>
|
||||
</mapper>
|
@ -1,13 +1,21 @@
|
||||
package com.linxyun.homework;
|
||||
|
||||
import com.linxyun.homework.utils.FileUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class HomeworkApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private FileUtils fileUtils;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
String url = "http://gchat.qpic.cn/download?appid=1407&fileid=EhQrqU1fCrXPCi9TYDHFtqLuEFeGBhi4ByD_CiiMnbCLvPaJAzIEcHJvZFCAvaMBWhCeolMmVCPCtR86R_2_Nq9x&rkey=CAQSOAB6JWENi5LMPAmzyUMyWlnciGpTV_s6NNl-6sRPEdwD-8haSCwEZCXEAROFKSCk0Vmp7_ZB0GmX&spec=0";
|
||||
String result = fileUtils.uploadFileByUrl(url, "test.png");
|
||||
System.out.println(result); // file_00001_20241125114456_00001.png
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user