【新增】 学生端上传文件 学号-试卷ID-文件Url
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
package pc.exam.pp.module.exam.dal.dataobject.student;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
import pc.exam.pp.framework.tenant.core.db.TenantBaseDO;
|
||||
|
||||
/**
|
||||
* 学生-试卷-文件表 DO
|
||||
*
|
||||
* @author rwb
|
||||
*/
|
||||
@TableName("exam_stu_paper_fileurl")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class StuPaperFileDO extends TenantBaseDO {
|
||||
|
||||
/**
|
||||
* Id
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 学生号
|
||||
*/
|
||||
private Long stuId;
|
||||
/**
|
||||
* 试卷ID
|
||||
*/
|
||||
private String paperId;
|
||||
/**
|
||||
* 学生文件URL
|
||||
*/
|
||||
private String url;
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
package pc.exam.pp.module.exam.dal.mysql.student;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import pc.exam.pp.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import pc.exam.pp.module.exam.dal.dataobject.student.StuPaperFileDO;
|
||||
|
||||
/**
|
||||
* 学生-试卷-文件 Mapper
|
||||
*
|
||||
* @author rwb
|
||||
*/
|
||||
@Mapper
|
||||
public interface StuPaperFileMapper extends BaseMapperX<StuPaperFileDO> {
|
||||
StuPaperFileDO findByStuIdAndPaperId(@Param("stuId") Long stuId, @Param("paperId") String paperId);
|
||||
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
package pc.exam.pp.module.exam.service.stu_paper_file;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import pc.exam.pp.framework.common.pojo.PageResult;
|
||||
import pc.exam.pp.module.exam.controller.admin.student.vo.StudentPageReqVO;
|
||||
import pc.exam.pp.module.exam.controller.admin.student.vo.StudentSaveReqVO;
|
||||
import pc.exam.pp.module.exam.dal.dataobject.student.StuPaperFileDO;
|
||||
import pc.exam.pp.module.exam.dal.dataobject.student.StudentDO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 学生-试卷-文件 Service 接口
|
||||
*
|
||||
* @author rwb
|
||||
*/
|
||||
public interface StuPaperFileService {
|
||||
|
||||
StuPaperFileDO findByStuIDAndPaperId(Long stuID, String paperID);
|
||||
|
||||
void insertStuPaperFile(StuPaperFileDO stuPaperFileDO);
|
||||
|
||||
void updateStuPaperFile(StuPaperFileDO stuPaperFileDO);
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
package pc.exam.pp.module.exam.service.stu_paper_file;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import pc.exam.pp.module.exam.dal.dataobject.student.StuPaperFileDO;
|
||||
import pc.exam.pp.module.exam.dal.mysql.student.StuPaperFileMapper;
|
||||
|
||||
/**
|
||||
* 学生-试卷-文件 Service 实现类
|
||||
*
|
||||
* @author rwb
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class StuPaperFileServiceImpl implements StuPaperFileService {
|
||||
|
||||
@Resource
|
||||
private StuPaperFileMapper stuPaperFileMapper;
|
||||
|
||||
@Override
|
||||
public StuPaperFileDO findByStuIDAndPaperId(Long stuID, String paperID) {
|
||||
return stuPaperFileMapper.findByStuIdAndPaperId(stuID, paperID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertStuPaperFile(StuPaperFileDO stuPaperFileDO) {
|
||||
stuPaperFileMapper.insert(stuPaperFileDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStuPaperFile(StuPaperFileDO stuPaperFileDO) {
|
||||
stuPaperFileMapper.updateById(stuPaperFileDO);
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
<?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="pc.exam.pp.module.exam.dal.mysql.student.StuPaperFileMapper">
|
||||
|
||||
<!--
|
||||
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
|
||||
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
|
||||
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
|
||||
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
|
||||
-->
|
||||
<select id="findByStuIdAndPaperId" resultType="pc.exam.pp.module.exam.dal.dataobject.student.StuPaperFileDO">
|
||||
SELECT * FROM exam_stu_paper_fileurl WHERE stu_id = #{stuId} AND paper_id = #{paperId}
|
||||
</select>
|
||||
|
||||
</mapper>
|
@@ -124,6 +124,12 @@
|
||||
<groupId>org.apache.tika</groupId>
|
||||
<artifactId>tika-core</artifactId> <!-- 文件客户端:文件类型的识别 -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>pc.exam.gg</groupId>
|
||||
<artifactId>exam-module-exam-biz</artifactId>
|
||||
<version>2.4.2-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
@@ -66,6 +66,14 @@ public class FileController {
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/upload_stu")
|
||||
@Operation(summary = "上传学生考试文件", description = "模式三:后端上传文件,带有学生ID")
|
||||
public CommonResult<String> uploadStuFile(StuFileUploadReqVO uploadReqVO) throws Exception {
|
||||
MultipartFile file = uploadReqVO.getFile();
|
||||
String path = uploadReqVO.getPath();
|
||||
return success(fileService.createStuFile(uploadReqVO.getStuId(), uploadReqVO.getPaperId(), file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream())));
|
||||
}
|
||||
|
||||
@GetMapping("/{configId}/get/**")
|
||||
@PermitAll
|
||||
@Operation(summary = "下载文件")
|
||||
|
@@ -0,0 +1,25 @@
|
||||
package pc.exam.pp.module.infra.controller.admin.file.vo.file;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@Schema(description = "管理后台 - 上传文件 Request VO")
|
||||
@Data
|
||||
public class StuFileUploadReqVO {
|
||||
|
||||
@Schema(description = "文件附件", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "文件附件不能为空")
|
||||
private MultipartFile file;
|
||||
|
||||
@Schema(description = "文件附件", example = "examyuanma.png")
|
||||
private String path;
|
||||
|
||||
@Schema(description = "学生ID")
|
||||
private Long stuId;
|
||||
|
||||
@Schema(description = "试卷ID")
|
||||
private String paperId;
|
||||
|
||||
}
|
@@ -31,6 +31,16 @@ public interface FileService {
|
||||
*/
|
||||
String createFile(String name, String path, byte[] content);
|
||||
|
||||
/**
|
||||
* 保存文件,并返回文件的访问路径
|
||||
*
|
||||
* @param name 文件名称
|
||||
* @param path 文件路径
|
||||
* @param content 文件内容
|
||||
* @return 文件路径
|
||||
*/
|
||||
String createStuFile(Long stuId, String paperId, String name, String path, byte[] content);
|
||||
|
||||
/**
|
||||
* 创建文件
|
||||
*
|
||||
|
@@ -5,6 +5,8 @@ import cn.hutool.core.util.StrUtil;
|
||||
import pc.exam.pp.framework.common.pojo.PageResult;
|
||||
import pc.exam.pp.framework.common.util.io.FileUtils;
|
||||
import pc.exam.pp.framework.common.util.object.BeanUtils;
|
||||
import pc.exam.pp.module.exam.dal.dataobject.student.StuPaperFileDO;
|
||||
import pc.exam.pp.module.exam.service.stu_paper_file.StuPaperFileService;
|
||||
import pc.exam.pp.module.infra.framework.file.core.client.FileClient;
|
||||
import pc.exam.pp.module.infra.framework.file.core.client.s3.FilePresignedUrlRespDTO;
|
||||
import pc.exam.pp.module.infra.framework.file.core.utils.FileTypeUtils;
|
||||
@@ -34,6 +36,9 @@ public class FileServiceImpl implements FileService {
|
||||
@Resource
|
||||
private FileMapper fileMapper;
|
||||
|
||||
@Resource
|
||||
private StuPaperFileService stuPaperFileService;
|
||||
|
||||
@Override
|
||||
public PageResult<FileDO> getFilePage(FilePageReqVO pageReqVO) {
|
||||
return fileMapper.selectPage(pageReqVO);
|
||||
@@ -69,6 +74,53 @@ public class FileServiceImpl implements FileService {
|
||||
return url;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public String createStuFile(Long stuId, String paperId, String name, String path, byte[] content) {
|
||||
// 计算默认的 path 名
|
||||
String type = FileTypeUtils.getMineType(content, name);
|
||||
if (StrUtil.isEmpty(path)) {
|
||||
path = FileUtils.generatePath(content, name);
|
||||
}
|
||||
// 如果 name 为空,则使用 path 填充
|
||||
if (StrUtil.isEmpty(name)) {
|
||||
name = path;
|
||||
}
|
||||
|
||||
// 上传到文件存储器
|
||||
FileClient client = fileConfigService.getMasterFileClient();
|
||||
Assert.notNull(client, "客户端(master) 不能为空");
|
||||
String url = client.upload(content, path, type);
|
||||
|
||||
// 保存到数据库
|
||||
FileDO file = new FileDO();
|
||||
file.setConfigId(client.getId());
|
||||
file.setName(name);
|
||||
file.setPath(path);
|
||||
file.setUrl(url);
|
||||
file.setType(type);
|
||||
file.setSize(content.length);
|
||||
fileMapper.insert(file);
|
||||
// 需要更新学生表
|
||||
// 1、先查询学生,试卷 是否已经存在数据
|
||||
StuPaperFileDO stuPaperFileDO = stuPaperFileService.findByStuIDAndPaperId(stuId, paperId);
|
||||
if (stuPaperFileDO == null) {
|
||||
// 说明没有上传过,需要新增进去
|
||||
StuPaperFileDO stuPaperFile = new StuPaperFileDO();
|
||||
stuPaperFile.setPaperId(paperId);
|
||||
stuPaperFile.setStuId(stuId);
|
||||
stuPaperFile.setUrl(url);
|
||||
stuPaperFileService.insertStuPaperFile(stuPaperFile);
|
||||
} else {
|
||||
// 说明已经上传过,判断url是否一致,不一致得,需要进行更新操作
|
||||
if (!url.equals(stuPaperFileDO.getUrl())) {
|
||||
stuPaperFileDO.setUrl(url);
|
||||
stuPaperFileService.updateStuPaperFile(stuPaperFileDO);
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long createFile(FileCreateReqVO createReqVO) {
|
||||
FileDO file = BeanUtils.toBean(createReqVO, FileDO.class);
|
||||
|
Reference in New Issue
Block a user