From f18f179f3d5b718b6552904b7cb9a7e4a449f4b3 Mon Sep 17 00:00:00 2001 From: sh Date: Mon, 22 Jun 2026 17:26:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=92=E8=81=94=E7=BD=91?= =?UTF-8?q?=E5=B2=97=E4=BD=8D=E4=B8=8A=E4=BC=A0=E9=99=84=E4=BB=B6=EF=BC=8C?= =?UTF-8?q?=E6=9C=AA=E4=BD=9C=E6=89=B9=E9=87=8F=E5=A4=84=E7=90=86=EF=BC=88?= =?UTF-8?q?job=EF=BC=89=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cms/CmsFileJobUploadController.java | 85 ++++++++ .../ruoyi/cms/mapper/FileJobUploadMapper.java | 29 +++ .../cms/service/IFileJobUploadService.java | 61 ++++++ .../impl/FileJobUploadServiceImpl.java | 200 ++++++++++++++++++ .../mapper/app/FileJobUploadMapper.xml | 88 ++++++++ .../core/domain/entity/FileJobUpload.java | 38 ++++ 6 files changed, 501 insertions(+) create mode 100644 ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/CmsFileJobUploadController.java create mode 100644 ruoyi-bussiness/src/main/java/com/ruoyi/cms/mapper/FileJobUploadMapper.java create mode 100644 ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/IFileJobUploadService.java create mode 100644 ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/FileJobUploadServiceImpl.java create mode 100644 ruoyi-bussiness/src/main/resources/mapper/app/FileJobUploadMapper.xml create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/FileJobUpload.java diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/CmsFileJobUploadController.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/CmsFileJobUploadController.java new file mode 100644 index 0000000..85329c1 --- /dev/null +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/CmsFileJobUploadController.java @@ -0,0 +1,85 @@ +package com.ruoyi.cms.controller.cms; + +import com.ruoyi.cms.service.IFileJobUploadService; +import com.ruoyi.cms.util.file.FileValid; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.FileJobUpload; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.utils.ServletUtils; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; +import java.util.List; + +@RestController +@RequestMapping("/cms/fileJobUpload") +public class CmsFileJobUploadController extends BaseController { + @Autowired + private IFileJobUploadService fileJobUploadService; + + //文件大小限制 10MB + private static final long MAX_FILE_SIZE = 100 * 1024 * 1024; + + @ApiOperation("上传文件") + @PreAuthorize("@ss.hasPermi('cms:fileJobUpload:upload')") + @PostMapping("/upload") + public AjaxResult upload(@RequestParam("file") MultipartFile file) { + if (file.isEmpty()) return AjaxResult.error("文件不能为空!"); + if (file.getSize() > MAX_FILE_SIZE) { + return AjaxResult.error("文件大小超出限制!"); + } + boolean isValid = FileValid.validateFile(file); + if (!isValid) { + return AjaxResult.error("文件类型不合法或内容被篡改!"); + } + return fileJobUploadService.upload(file); + } + + @ApiOperation("获取附件列表") + @PreAuthorize("@ss.hasPermi('cms:fileJobUpload:list')") + @GetMapping("/list") + public TableDataInfo list(FileJobUpload file,HttpServletRequest request) + { + String host = request.getHeader("Host"); + List allowedHosts = Arrays.asList( + "localhost", + "127.0.0.1", + "10.98.80.146", + "10.98.80.50", + "www.xjksly.cn", + "ks.zhaopinzao8dian.com" + ); + + if (host != null) { + if (host.contains(":")) { + host = host.split(":")[0]; + } + if (!allowedHosts.contains(host)) { + return error(401,"非法请求来源"); + } + } + + //修复CORS 跨域漏洞 + HttpServletResponse response = ServletUtils.getResponse(); + response.setHeader("Access-Control-Allow-Origin", ""); + response.setHeader("Access-Control-Allow-Credentials", ""); + startPage(); + List results = fileJobUploadService.selectFileList(file); + return getDataTable(results); + } + + @ApiOperation("删除附件") + @PreAuthorize("@ss.hasPermi('cms:fileJobUpload:remove')") + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return toAjax(fileJobUploadService.deleteFileByIds(new Long[]{id})); + } +} diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/mapper/FileJobUploadMapper.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/mapper/FileJobUploadMapper.java new file mode 100644 index 0000000..c384f8c --- /dev/null +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/mapper/FileJobUploadMapper.java @@ -0,0 +1,29 @@ +package com.ruoyi.cms.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.common.core.domain.entity.FileJobUpload; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 文件Mapper接口 + * @author ${author} + * @date 2025-03-18 + */ +public interface FileJobUploadMapper extends BaseMapper +{ + /** + * 查询文件列表 + * + * @param file 文件 + * @return 文件集合 + */ + public List selectFileList(FileJobUpload file); + + public int updateBussinessids(@Param("longs") List longs,@Param("newBussinessid") Long bussinessid); + + public List selectFileListByBussinessIds(@Param("longs") List longs); + + public int updateIds(@Param("longs") List longs,@Param("newBussinessid") Long bussinessid); +} diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/IFileJobUploadService.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/IFileJobUploadService.java new file mode 100644 index 0000000..725a31a --- /dev/null +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/IFileJobUploadService.java @@ -0,0 +1,61 @@ +package com.ruoyi.cms.service; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.FileJobUpload; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +/** + * 文件Service接口 + * + * @author ${author} + * @date 2025-03-18 + */ +public interface IFileJobUploadService +{ + /** + * 查询文件 + * + * @param id 文件主键 + * @return 文件 + */ + public FileJobUpload selectFileById(Long id); + + /** + * 查询文件列表 + * + * @param file 文件 + * @return 文件集合 + */ + public List selectFileList(FileJobUpload file); + + /** + * 新增文件 + * + * @param file 文件 + * @return 结果 + */ + public int insertFile(FileJobUpload file); + + /** + * 修改文件 + * + * @param file 文件 + * @return 结果 + */ + public int updateFile(FileJobUpload file); + + /** + * 批量删除文件 + * + * @param ids 需要删除的文件主键集合 + * @return 结果 + */ + public int deleteFileByIds(Long[] ids); + + AjaxResult upload(MultipartFile file); + + AjaxResult uploadFile(MultipartFile file, HttpServletRequest request); +} diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/FileJobUploadServiceImpl.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/FileJobUploadServiceImpl.java new file mode 100644 index 0000000..6b5d78b --- /dev/null +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/FileJobUploadServiceImpl.java @@ -0,0 +1,200 @@ +package com.ruoyi.cms.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.cms.mapper.FileJobUploadMapper; +import com.ruoyi.cms.service.IFileJobUploadService; +import com.ruoyi.cms.util.StringUtil; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.FileJobUpload; +import com.ruoyi.common.utils.uuid.UUID; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; + +/** + * 文件Service业务层处理 + * + * @author ${author} + * @date 2025-03-18 + */ +@Service +public class FileJobUploadServiceImpl extends ServiceImpl implements IFileJobUploadService +{ + @Autowired + private FileJobUploadMapper fileJobUploadMapper; + @Value("${file.upload-dir}") + private String uploadDir; + /** + * 查询文件 + * + * @param id 文件主键 + * @return 文件 + */ + @Override + public FileJobUpload selectFileById(Long id) + { + return fileJobUploadMapper.selectById(id); + } + + /** + * 查询文件列表 + * + * @param file 文件 + * @return 文件 + */ + @Override + public List selectFileList(FileJobUpload file) + { + return fileJobUploadMapper.selectFileList(file); + } + + /** + * 新增文件 + * + * @param file 文件 + * @return 结果 + */ + @Override + public int insertFile(FileJobUpload file) + { + return fileJobUploadMapper.insert(file); + } + + /** + * 修改文件 + * + * @param file 文件 + * @return 结果 + */ + @Override + public int updateFile(FileJobUpload file) + { + return fileJobUploadMapper.updateById(file); + } + + /** + * 批量删除文件 + * + * @param ids 需要删除的文件主键 + * @return 结果 + */ + @Override + public int deleteFileByIds(Long[] ids) + { + return fileJobUploadMapper.deleteBatchIds(Arrays.asList(ids)); + } + + @Override + public AjaxResult upload(MultipartFile file) { + if (file.isEmpty()) { + return AjaxResult.error("文件为空,请选择文件上传"); + } + + try { + // 创建上传目录 + java.io.File dir = new java.io.File(uploadDir).getCanonicalFile(); + if (!dir.exists()) { + dir.mkdirs(); + } + + // 生成唯一的文件名 + String fileName = UUID.randomUUID().toString() + "_" + file.getOriginalFilename(); + + Path basePath = Paths.get(getCanonicalPath(uploadDir)).normalize(); + Path filePath = basePath.resolve(fileName).normalize(); + + if (!filePath.startsWith(basePath)) { + throw new SecurityException("非法路径,禁止访问"); + } + + // 保存文件到服务器 + Files.copy(file.getInputStream(), filePath); + + java.io.File destFile = filePath.toFile(); + destFile.setReadable(true, false); // 所有用户可读 + destFile.setWritable(false); // 禁止写入 + destFile.setExecutable(false); + + // 保存文件信息到数据库 + saveFileInfo(fileName); + + return AjaxResult.success(StringUtil.PATH_PROXY_50+fileName); + } catch (IOException e) { + e.printStackTrace(); + return AjaxResult.error("文件上传失败"); + } + } + + /** + * 添加返回bussinessid的接口,新增时使用 + * @param file + * @return + */ + @Override + public AjaxResult uploadFile(MultipartFile file, HttpServletRequest request) { + if (file.isEmpty()) { + return AjaxResult.error("文件为空,请选择文件上传"); + } + + try { + // 创建上传目录 + java.io.File dir = new java.io.File(uploadDir).getCanonicalFile(); + if (!dir.exists()) { + dir.mkdirs(); + } + + // 生成唯一的文件名 + String fileName = UUID.randomUUID().toString() + "_" + file.getOriginalFilename(); + + Path basePath = Paths.get(getCanonicalPath(uploadDir)).normalize(); + Path filePath = basePath.resolve(fileName).normalize(); + + if (!filePath.startsWith(basePath)) { + throw new SecurityException("非法路径,禁止访问"); + } + + // 保存文件到服务器 + Files.copy(file.getInputStream(), filePath); + + java.io.File destFile = filePath.toFile(); + destFile.setReadable(true, false); // 所有用户可读 + destFile.setWritable(false); // 禁止写入 + destFile.setExecutable(false); + + // 保存文件信息到数据库 + FileJobUpload svFile=saveFileInfo(fileName); + AjaxResult ajaxResult=AjaxResult.success(); + ajaxResult.put("filePath", StringUtil.getFilePath(request)+fileName); + ajaxResult.put("id",String.valueOf(svFile.getId())); + return ajaxResult; + } catch (IOException e) { + e.printStackTrace(); + return AjaxResult.error("文件上传失败"); + } + } + + private FileJobUpload saveFileInfo(String fileName) { + // 这里假设你已经有了一个FileService来处理数据库操作 + FileJobUpload file = new FileJobUpload(); + file.setFileUrl(fileName); + this.save(file); + return file; + } + + private String getCanonicalPath(String path) { + try { + return new java.io.File(path).getCanonicalPath(); + } catch (Exception e) { + return path; + } + } +} diff --git a/ruoyi-bussiness/src/main/resources/mapper/app/FileJobUploadMapper.xml b/ruoyi-bussiness/src/main/resources/mapper/app/FileJobUploadMapper.xml new file mode 100644 index 0000000..a432f26 --- /dev/null +++ b/ruoyi-bussiness/src/main/resources/mapper/app/FileJobUploadMapper.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + select id, file_url, bussinessid, del_flag, create_by, create_time, update_by, update_time from file_job_upload + + + + + + update file_job_upload + + set bussinessid = #{newBussinessid} + + + set bussinessid = bussinessid + where 1 = 2 + + where + + bussinessid in ( + + #{oldId} + + ) + + + 1 = 2 + + + + + + + update file_job_upload + + set bussinessid = #{newBussinessid} + + + set bussinessid = bussinessid + where 1 = 2 + + where + + id in ( + + #{oldId} + + ) + + + 1 = 2 + + + + \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/FileJobUpload.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/FileJobUpload.java new file mode 100644 index 0000000..572aea9 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/FileJobUpload.java @@ -0,0 +1,38 @@ +package com.ruoyi.common.core.domain.entity; + +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 com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 文件对象 FileJobUpload + * @author ${author} + * @date 2025-03-18 + */ +@Data +@ApiModel("文件") +@TableName(value = "file_job_upload") +public class FileJobUpload extends BaseEntity +{ + @TableField(exist = false) + private static final long serialVersionUID = 1L; + + @TableId(value = "id",type = IdType.AUTO) + @ApiModelProperty("id") + private Long id; + + @Excel(name = "url") + @ApiModelProperty("url") + private String fileUrl; + + @Excel(name = "业务id") + @ApiModelProperty("业务id") + private Long bussinessid; + +}