附件管理,开发数据库配置更新

master
chen 2 years ago
parent a0e687b9ff
commit fd25c70c41
  1. 6
      pom.xml
  2. 3
      src/main/java/com/huoran/iasf/common/exception/handler/RestExceptionHandler.java
  3. 19
      src/main/java/com/huoran/iasf/common/filter/AuthFilter.java
  4. 24
      src/main/java/com/huoran/iasf/common/shiro/ShiroConfig.java
  5. 39
      src/main/java/com/huoran/iasf/controller/SysFilesController.java
  6. 5
      src/main/java/com/huoran/iasf/entity/BaseEntity.java
  7. 50
      src/main/java/com/huoran/iasf/entity/SysFilesEntity.java
  8. 11
      src/main/java/com/huoran/iasf/service/SysFilesService.java
  9. 107
      src/main/java/com/huoran/iasf/service/impl/SysFilesServiceImpl.java
  10. 26
      src/main/java/com/huoran/iasf/vo/req/FileParameters.java
  11. 6
      src/main/resources/application-dev.yml

@ -161,6 +161,12 @@
<version>3.14.9</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.3.6</version>
</dependency>
</dependencies>
<build>

@ -41,7 +41,8 @@ public class RestExceptionHandler {
@ExceptionHandler(value = BusinessException.class)
R businessExceptionHandler(BusinessException e) {
log.error("Exception,exception:{}", e, e);
return new R(e.getMessageCode(), e.getDetailMessage());
return new R(e.getMessageCode(), e.getMessage());
}
/**

@ -1,3 +1,4 @@
/*
package com.huoran.iasf.common.filter;
import com.alibaba.fastjson.JSON;
@ -20,12 +21,14 @@ import static com.huoran.iasf.service.HttpApiSessionService.USER_ID_KEY;
import static com.huoran.iasf.service.HttpApiSessionService.USER_USERNAME_KEY;
@Slf4j
@WebFilter(filterName = "authFilter", urlPatterns = "/iasf/app/api/*")
@WebFilter(filterName = "authFilter", urlPatterns = "/iasf/*")
@Order(1)
public class AuthFilter implements Filter {
/**
* 白名单
*/
*/
/**
* 白名单*//*
private static final String[] whiteList = {"/iasf/app/api/login", "/iasf/app/api/open/test"};
@Resource
HttpApiSessionService httpApiSessionService;
@ -69,11 +72,14 @@ public class AuthFilter implements Filter {
}
/**
*/
/**
* responseResult
* @param response
* @param result
*/
*//*
private void responseResult(HttpServletResponse response, R result) {
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-type", "application/json;charset=UTF-8");
@ -85,3 +91,4 @@ public class AuthFilter implements Filter {
}
}
}
*/

@ -1,3 +1,4 @@
/*
package com.huoran.iasf.common.shiro;
import com.huoran.iasf.common.config.FileUploadProperties;
@ -14,13 +15,16 @@ import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;
*/
/**
* ShiroConfig
*
* @author cheney
* @version V1.0
* @date 2022年7月28日
*/
*//*
@Configuration
@EnableConfigurationProperties(FileUploadProperties.class)
public class ShiroConfig {
@ -33,9 +37,11 @@ public class ShiroConfig {
return new CustomHashedCredentialsMatcher();
}
/**
* 创建realm
*/
*/
/**
* 创建realm*//*
@Bean
public CustomRealm customRealm() {
CustomRealm customRealm = new CustomRealm();
@ -97,12 +103,15 @@ public class ShiroConfig {
return shiroFilterFactoryBean;
}
/**
*/
/**
* 开启shiro aop注解支持.
* 使用代理方式;所以需要开启代码支持;
*
* @return org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor
*/
* @return org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor*//*
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
@ -113,3 +122,4 @@ public class ShiroConfig {
}
*/

@ -1,19 +1,24 @@
package com.huoran.iasf.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huoran.iasf.common.utils.R;
import com.huoran.iasf.entity.SysFilesEntity;
import com.huoran.iasf.service.SysFilesService;
import com.huoran.iasf.vo.req.FileParameters;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
@ -34,29 +39,51 @@ public class SysFilesController {
@ApiOperation(value = "新增")
@PostMapping("/upload")
@RequiresPermissions(value = {"sysFiles:add", "sysContent:update", "sysContent:add"}, logical = Logical.OR)
public R add(@RequestParam(value = "file") MultipartFile file) {
public R add(@RequestParam(value = "file") MultipartFile file, FileParameters fileParameters) {
//判断文件是否空
if (file == null || file.getOriginalFilename() == null || "".equalsIgnoreCase(file.getOriginalFilename().trim())) {
return R.fail("文件为空");
}
return sysFilesService.saveFile(file);
return sysFilesService.saveFile(file,fileParameters);
}
@ApiOperation(value = "文件预览")
@GetMapping("/preview/{id}")
public void preview(@PathVariable Integer id, HttpServletRequest req, HttpServletResponse res) {
sysFilesService.preview(id, req, res);
}
@ApiOperation(value = "文件下载")
@GetMapping("/download/{id}")
public void download(@PathVariable Integer id, HttpServletRequest req, HttpServletResponse res) {
sysFilesService.download(id, req, res);
}
@ApiOperation(value = "删除")
@DeleteMapping("/delete")
@RequiresPermissions("sysFiles:delete")
public R delete(@RequestBody @ApiParam(value = "id集合") List<String> ids) {
public R delete(@RequestBody @ApiParam(value = "id集合") List<Integer> ids) {
sysFilesService.removeByIdsAndFiles(ids);
return R.success();
}
@ApiOperation(value = "查询分页数据")
@ApiOperation(value = "查询分页数据",response = SysFilesEntity.class)
@PostMapping("/listByPage")
@RequiresPermissions("sysFiles:list")
public R findListByPage(@RequestBody SysFilesEntity sysFiles) {
IPage<SysFilesEntity> iPage = sysFilesService.page(sysFiles.getQueryPage(), Wrappers.<SysFilesEntity>lambdaQuery().orderByDesc(SysFilesEntity::getCreateDate));
LambdaQueryWrapper<SysFilesEntity> queryWrapper = Wrappers.lambdaQuery();
if (!StringUtils.isEmpty(sysFiles.getFileName())) {
queryWrapper.like(SysFilesEntity::getFileName, sysFiles.getFileName());
}
if (!StringUtils.isEmpty(sysFiles.getType())) {
queryWrapper.eq(SysFilesEntity::getType, sysFiles.getType());
}
if (!StringUtils.isEmpty(sysFiles.getSite())) {
queryWrapper.eq(SysFilesEntity::getSite, sysFiles.getSite());
}
queryWrapper.orderByDesc(SysFilesEntity::getCreateDate);
IPage<SysFilesEntity> iPage = sysFilesService.page(sysFiles.getQueryPage(),queryWrapper);
return R.success(iPage);
}
}

@ -3,6 +3,7 @@ package com.huoran.iasf.entity;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@ -19,16 +20,19 @@ public class BaseEntity {
@JSONField(serialize = false)
@TableField(exist = false)
@ApiModelProperty(value = "页码",example = "1")
private int page = 1;
@JSONField(serialize = false)
@TableField(exist = false)
@ApiModelProperty(value = "页数",example = "10")
private int limit = 10;
/**
* 数据权限用户id
*/
@TableField(exist = false)
@ApiModelProperty(value = "用户id")
private List<String> createIds;
/**
@ -36,6 +40,7 @@ public class BaseEntity {
* @param <T>
* @return
*/
@ApiModelProperty(value = "getQueryPage", hidden = true)
public <T> Page getQueryPage() {
return new Page<T>(page, limit);
}

@ -1,9 +1,6 @@
package com.huoran.iasf.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -24,34 +21,45 @@ import java.util.Date;
public class SysFilesEntity extends BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId("id")
@ApiModelProperty(value = "主键")
private String id;
@TableId(value = "id", type = IdType.AUTO)
private int id;
/**
* URL地址
*/
@TableField("url")
@ApiModelProperty(value = "url地址")
private String url;
/**
* 创建时间
*/
@TableField(value = "create_date", fill = FieldFill.INSERT)
@ApiModelProperty(value = "创建时间")
private Date createDate;
@TableField("file_name")
@ApiModelProperty(value = "文件名称")
private String fileName;
@TableField("file_path")
@ApiModelProperty(value = "文件路径")
private String filePath;
@TableField("type")
@ApiModelProperty(value = "文件类型")
private String type;
@ApiModelProperty(value = "文件格式")
private String format;
@ApiModelProperty(value = "文件大小")
private Integer fileSize;
@ApiModelProperty(value = "上传人")
private String uploader;
@ApiModelProperty(value = "引用地方")
private String quote;
@TableField("site")
@ApiModelProperty(value = "站点来源")
private String site;
@ApiModelProperty(value = "是否已删除,未删除表示该文件正在使用")
@TableField(fill = FieldFill.INSERT)
private Integer deleted;
@TableField(value = "create_date", fill = FieldFill.INSERT)
@ApiModelProperty(value = "创建时间")
private Date createDate;
}

@ -3,8 +3,11 @@ package com.huoran.iasf.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.huoran.iasf.common.utils.R;
import com.huoran.iasf.entity.SysFilesEntity;
import com.huoran.iasf.vo.req.FileParameters;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
@ -16,8 +19,12 @@ import java.util.List;
*/
public interface SysFilesService extends IService<SysFilesEntity> {
R saveFile(MultipartFile file);
R saveFile(MultipartFile file, FileParameters fileParameters);
void removeByIdsAndFiles(List<String> ids);
void removeByIdsAndFiles(List<Integer> ids);
void preview(Integer id, HttpServletRequest req, HttpServletResponse res);
void download(Integer id, HttpServletRequest req, HttpServletResponse res);
}

@ -1,20 +1,28 @@
package com.huoran.iasf.service.impl;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huoran.iasf.common.config.FileUploadProperties;
import com.huoran.iasf.common.exception.BusinessException;
import com.huoran.iasf.common.utils.R;
import com.huoran.iasf.common.utils.DateUtils;
import com.huoran.iasf.common.utils.R;
import com.huoran.iasf.entity.SysFilesEntity;
import com.huoran.iasf.mapper.SysFilesMapper;
import com.huoran.iasf.service.SysFilesService;
import com.huoran.iasf.vo.req.FileParameters;
import org.apache.commons.io.FileUtils;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.File;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
/**
@ -27,11 +35,12 @@ import java.util.*;
@EnableConfigurationProperties(FileUploadProperties.class)
@Service("sysFilesService")
public class SysFilesServiceImpl extends ServiceImpl<SysFilesMapper, SysFilesEntity> implements SysFilesService {
@Resource
private FileUploadProperties fileUploadProperties;
@Override
public R saveFile(MultipartFile file) {
public R saveFile(MultipartFile file, FileParameters fileParameters) {
//存储文件夹
String createTime = DateUtils.format(new Date(), DateUtils.DATEPATTERN);
String newPath = fileUploadProperties.getPath() + createTime + File.separator;
@ -45,10 +54,14 @@ public class SysFilesServiceImpl extends ServiceImpl<SysFilesMapper, SysFilesEnt
}
try {
String fileName = file.getOriginalFilename();
//获取文件大小
int fileSize = (int) file.getSize();
//获取文件的后缀名
String suffixName = fileName.substring(fileName.lastIndexOf(".")+1);
//id与filename保持一直,删除文件
String fileNameNew = UUID.randomUUID().toString().replace("-", "") + getFileType(fileName);
String newFilePathName = newPath + fileNameNew;
String url = fileUploadProperties.getUrl() + "/" + createTime + "/" + fileNameNew;
// String url = fileUploadProperties.getUrl() + "/" + createTime + "/" + fileNameNew;
//创建输出文件对象
File outFile = new File(newFilePathName);
//拷贝文件到输出文件对象
@ -57,10 +70,17 @@ public class SysFilesServiceImpl extends ServiceImpl<SysFilesMapper, SysFilesEnt
SysFilesEntity sysFilesEntity = new SysFilesEntity();
sysFilesEntity.setFileName(fileName);
sysFilesEntity.setFilePath(newFilePathName);
sysFilesEntity.setUrl(url);
// sysFilesEntity.setUrl(url);
sysFilesEntity.setFileSize(fileSize);
sysFilesEntity.setFormat(suffixName);
sysFilesEntity.setUploader(fileParameters.getUploader());
sysFilesEntity.setQuote(fileParameters.getQuote());
sysFilesEntity.setSite(fileParameters.getSite());
sysFilesEntity.setType(fileParameters.getType());
this.save(sysFilesEntity);
String url = fileUploadProperties.getUrl() + "/preview" + "/" + sysFilesEntity.getId();
Map<String, String> resultMap = new HashMap<>();
resultMap.put("src", url);
resultMap.put("url", url);
return R.success(resultMap);
} catch (Exception e) {
throw new BusinessException("上传文件失败");
@ -68,7 +88,80 @@ public class SysFilesServiceImpl extends ServiceImpl<SysFilesMapper, SysFilesEnt
}
@Override
public void removeByIdsAndFiles(List<String> ids) {
public void preview(Integer id, HttpServletRequest req, HttpServletResponse res) {
if (id != null) {
SysFilesEntity entity = this.getById(id);
String path = entity.getFilePath();
res.setContentLength(entity.getFileSize());
File file = new File(path);
byte[] buffer = FileUtil.readBytes(path);
if (file.exists()) {
try {
//设置contentType
res.setContentType(MediaType.ALL_VALUE);
res.setCharacterEncoding("UTF-8");
//获取outputStream
ServletOutputStream outputStream = res.getOutputStream();
//输出
IoUtil.write(outputStream, true, buffer);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
}
@Override
public void download(Integer id, HttpServletRequest req, HttpServletResponse res) {
if (id != null) {
SysFilesEntity entity = this.getById(id);
String path = entity.getFilePath();
setDownloadContent(entity.getFileName(), req, res);
// 重要,需要设置此值,否则下载后打开文件会提示文件需要修复
res.setContentLength(entity.getFileSize());
File file = new File(path);
if (file.exists()) {
byte[] buffer = new byte[1024];
//输出流
OutputStream os;
try (FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);) {
os = res.getOutputStream();
int i = bis.read(buffer);
while (i != -1) {
os.write(buffer, 0, i);
i = bis.read(buffer);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
}
/**
* 客户端下载文件上response header的设置
*
* @param fileName 文件名
* @param request 请求
* @param response 响应
*/
private void setDownloadContent(String fileName, HttpServletRequest request, HttpServletResponse response) {
String agent = request.getHeader("User-Agent");
try {
if (null != agent && agent.toUpperCase().indexOf("MSIE") > 0) {
fileName = URLEncoder.encode(fileName, "UTF-8");
} else {
fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
}
} catch (UnsupportedEncodingException e1) {
}
response.setContentType("application/x-msdownload;");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
}
@Override
public void removeByIdsAndFiles(List<Integer> ids) {
List<SysFilesEntity> list = this.listByIds(ids);
list.forEach(entity -> {
//如果之前的文件存在,删除

@ -0,0 +1,26 @@
package com.huoran.iasf.vo.req;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Author chen
* @DATE 2022/8/8 11:15
* @Version 1.0
*/
@Data
public class FileParameters {
@ApiModelProperty(value = "站点来源",example = "粒子研究院中文站点")
private String site;
@ApiModelProperty(value = "上传人",example = "管理员")
private String uploader;
@ApiModelProperty(value = "引用地方",example = "某某文章")
private String quote;
@ApiModelProperty(value = "文件类型",example = "图片")
private String type;
}

@ -6,9 +6,9 @@ spring:
datasource:
master:
username: root
password: root
password: HuoRan@2021
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://121.37.12.51:3308/iasf?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2b8
url: jdbc:mysql://139.9.47.170:3306/iasf?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2b8
redis:
host: localhost # Redis服务器地址
database: 0 # Redis数据库索引(默认为0)
@ -27,4 +27,4 @@ file:
path: D:/files/ #windows
#path: /data/files/ #linux
#文件预览、下载的url, 末尾请勿加 /
url: http://localhost:10000/files
url: http://localhost:10000/iasf/sysFiles

Loading…
Cancel
Save