From 56b317684dd5cbc02e63a26760480fd4540c7416 Mon Sep 17 00:00:00 2001 From: wanggeng <450292408@qq.com> Date: Tue, 2 Aug 2022 17:57:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=96=87=E4=BB=B6V2=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E4=BF=AE=E6=94=B9=E6=96=87=E4=BB=B6=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E6=96=B9=E5=BC=8F=E4=B8=BA=E9=87=8D=E5=AE=9A=E5=90=91?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=9F=A5=E7=9C=8B?= =?UTF-8?q?=E7=A0=81=E6=A0=A1=E9=AA=8C=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E4=B8=8B=E8=BD=BD=E6=AC=A1=E6=95=B0=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wgink/module/file/config/FileConfig.java | 31 ++ .../filedownload/FileDownloadController.java | 48 +++ .../controller/api/v2/FileController.java | 41 ++- .../FileDownloadRouteController.java | 28 ++ .../route/v2/FileRouteController.java | 52 ++++ .../dao/filedownload/IFileDownloadDao.java | 46 +++ .../wgink/module/file/filter/FilesFilter.java | 77 +++++ .../impl/DefaultFilesShowCodeServiceImpl.java | 69 +++++ .../module/file/init/build/BuildFileMenu.java | 40 +++ .../module/file/manager/FilesManager.java | 75 +++++ .../module/file/pojo/dtos/FileInfoDTO.java | 36 +++ .../dtos/filedownload/FileDownloadDTO.java | 56 ++++ .../pojo/dtos/v2/FileUploadSuccessDTO.java | 20 ++ .../pojo/vos/filedownload/FileDownloadVO.java | 38 +++ .../filedownload/IFileDownloadService.java | 69 +++++ .../impl/FileDownloadServiceImpl.java | 77 +++++ .../module/file/service/v2/IFileService.java | 39 +++ .../file/service/v2/impl/FileServiceImpl.java | 125 +++++++- .../module/file/startup/FilesStartUp.java | 33 ++ .../file-download/file-download-mapper.xml | 64 ++++ .../resources/mybatis/mapper/file-mapper.xml | 7 + .../templates/file-download/list.html | 121 ++++++++ .../resources/templates/file/v2/list.html | 290 ++++++++++++++++++ 23 files changed, 1474 insertions(+), 8 deletions(-) create mode 100644 module-file/src/main/java/ink/wgink/module/file/config/FileConfig.java create mode 100644 module-file/src/main/java/ink/wgink/module/file/controller/api/filedownload/FileDownloadController.java create mode 100644 module-file/src/main/java/ink/wgink/module/file/controller/route/filedownload/FileDownloadRouteController.java create mode 100644 module-file/src/main/java/ink/wgink/module/file/controller/route/v2/FileRouteController.java create mode 100644 module-file/src/main/java/ink/wgink/module/file/dao/filedownload/IFileDownloadDao.java create mode 100644 module-file/src/main/java/ink/wgink/module/file/filter/FilesFilter.java create mode 100644 module-file/src/main/java/ink/wgink/module/file/impl/DefaultFilesShowCodeServiceImpl.java create mode 100644 module-file/src/main/java/ink/wgink/module/file/init/build/BuildFileMenu.java create mode 100644 module-file/src/main/java/ink/wgink/module/file/manager/FilesManager.java create mode 100644 module-file/src/main/java/ink/wgink/module/file/pojo/dtos/filedownload/FileDownloadDTO.java create mode 100644 module-file/src/main/java/ink/wgink/module/file/pojo/vos/filedownload/FileDownloadVO.java create mode 100644 module-file/src/main/java/ink/wgink/module/file/service/filedownload/IFileDownloadService.java create mode 100644 module-file/src/main/java/ink/wgink/module/file/service/filedownload/impl/FileDownloadServiceImpl.java create mode 100644 module-file/src/main/java/ink/wgink/module/file/startup/FilesStartUp.java create mode 100644 module-file/src/main/resources/mybatis/mapper/file-download/file-download-mapper.xml create mode 100644 module-file/src/main/resources/templates/file-download/list.html create mode 100644 module-file/src/main/resources/templates/file/v2/list.html diff --git a/module-file/src/main/java/ink/wgink/module/file/config/FileConfig.java b/module-file/src/main/java/ink/wgink/module/file/config/FileConfig.java new file mode 100644 index 00000000..da86070a --- /dev/null +++ b/module-file/src/main/java/ink/wgink/module/file/config/FileConfig.java @@ -0,0 +1,31 @@ +package ink.wgink.module.file.config; + +import ink.wgink.module.file.filter.FilesFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @ClassName: FileConfig + * @Description: 文件配置 + * @Author: wanggeng + * @Date: 2022/8/1 09:48 + * @Version: 1.0 + */ +@Configuration +public class FileConfig { + + @Bean + public FilterRegistrationBean filesFilter() { + FilesFilter filesFilter = new FilesFilter(); + FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); + filterRegistrationBean.setFilter(filesFilter); + filterRegistrationBean.addUrlPatterns("/files/*"); + filterRegistrationBean.setName("filesFilter"); + filterRegistrationBean.setOrder(20); + return filterRegistrationBean; + } + + + +} diff --git a/module-file/src/main/java/ink/wgink/module/file/controller/api/filedownload/FileDownloadController.java b/module-file/src/main/java/ink/wgink/module/file/controller/api/filedownload/FileDownloadController.java new file mode 100644 index 00000000..7ded5b27 --- /dev/null +++ b/module-file/src/main/java/ink/wgink/module/file/controller/api/filedownload/FileDownloadController.java @@ -0,0 +1,48 @@ +package ink.wgink.module.file.controller.api.filedownload; + +import ink.wgink.common.base.DefaultBaseController; +import ink.wgink.interfaces.consts.ISystemConstant; +import ink.wgink.module.file.pojo.dtos.filedownload.FileDownloadDTO; +import ink.wgink.module.file.service.filedownload.IFileDownloadService; +import ink.wgink.pojo.ListPage; +import ink.wgink.pojo.result.ErrorResult; +import ink.wgink.pojo.result.SuccessResultList; +import io.swagger.annotations.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FileDownloadController + * @Description: 文件下载 + * @Author: wanggeng + * @Date: 2022/8/2 16:21 + * @Version: 1.0 + */ +@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "文件下载接口") +@RestController +@RequestMapping(ISystemConstant.API_PREFIX + "/file-download") +public class FileDownloadController extends DefaultBaseController { + + @Autowired + private IFileDownloadService fileDownloadService; + + @ApiOperation(value = "下载分页列表", notes = "下载分页列表接口") + @ApiImplicitParams({ + @ApiImplicitParam(name = "page", value = "当前页码", paramType = "query", dataType = "int", defaultValue = "1"), + @ApiImplicitParam(name = "rows", value = "显示数量", paramType = "query", dataType = "int", defaultValue = "20"), + }) + @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) + @GetMapping("listpage/file-id/{fileId}") + public SuccessResultList> listPageByFileId(@PathVariable("fileId") String fileId, ListPage page) { + Map params = requestParams(); + page.setParams(params); + return fileDownloadService.listPageByFileId(fileId, page); + } + +} diff --git a/module-file/src/main/java/ink/wgink/module/file/controller/api/v2/FileController.java b/module-file/src/main/java/ink/wgink/module/file/controller/api/v2/FileController.java index 622989c0..5f0104e7 100644 --- a/module-file/src/main/java/ink/wgink/module/file/controller/api/v2/FileController.java +++ b/module-file/src/main/java/ink/wgink/module/file/controller/api/v2/FileController.java @@ -3,18 +3,23 @@ package ink.wgink.module.file.controller.api.v2; import ink.wgink.common.base.DefaultBaseController; import ink.wgink.interfaces.consts.ISystemConstant; import ink.wgink.module.file.enums.UploadTypeEnum; +import ink.wgink.module.file.pojo.dtos.FileInfoDTO; import ink.wgink.module.file.pojo.dtos.v2.FileUploadSuccessDTO; import ink.wgink.module.file.service.v2.IFileService; +import ink.wgink.pojo.ListPage; import ink.wgink.pojo.result.ErrorResult; +import ink.wgink.pojo.result.SuccessResult; import ink.wgink.pojo.result.SuccessResultData; +import ink.wgink.pojo.result.SuccessResultList; import io.swagger.annotations.*; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + /** * @ClassName: FileController * @Description: 文件处理 @@ -22,7 +27,7 @@ import org.springframework.web.multipart.MultipartFile; * @Date: 2019/3/10 7:03 PM * @Version: 1.0 **/ -@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "文件接口") +@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "文件接口-V2") @RestController("fileControllerV2") @RequestMapping(ISystemConstant.API_PREFIX + "/file/v2") public class FileController extends DefaultBaseController { @@ -70,11 +75,35 @@ public class FileController extends DefaultBaseController { return uploadSingle(audio, UploadTypeEnum.AUDIO); } + @ApiOperation(value = "删除文件", notes = "删除文件接口") + @ApiImplicitParams({ + @ApiImplicitParam(name = "ids", value = "ID列表,用下划线分隔", paramType = "path", example = "1_2_3") + }) + @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) + @DeleteMapping("delete/{ids}") + public synchronized SuccessResult delete(@PathVariable("ids") String ids) { + fileService.delete(Arrays.asList(ids.split("\\_"))); + return new SuccessResult(); + } + + @ApiOperation(value = "文件分页列表", notes = "文件分页列表接口") + @ApiImplicitParams({ + @ApiImplicitParam(name = "page", value = "当前页码", paramType = "query", dataType = "int", defaultValue = "1"), + @ApiImplicitParam(name = "rows", value = "显示数量", paramType = "query", dataType = "int", defaultValue = "20"), + @ApiImplicitParam(name = "keywords", value = "关键字", paramType = "query", dataType = "String") + }) + @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) + @GetMapping("listpage") + public SuccessResultList> listPage(ListPage page) { + Map params = requestParams(); + page.setParams(params); + return fileService.listPage(page); + } + /** * 上传文件 * * @param uploadFile - * @param params * @return */ private SuccessResultData uploadSingle(MultipartFile uploadFile, UploadTypeEnum uploadTypeEnum) { diff --git a/module-file/src/main/java/ink/wgink/module/file/controller/route/filedownload/FileDownloadRouteController.java b/module-file/src/main/java/ink/wgink/module/file/controller/route/filedownload/FileDownloadRouteController.java new file mode 100644 index 00000000..ad424d7c --- /dev/null +++ b/module-file/src/main/java/ink/wgink/module/file/controller/route/filedownload/FileDownloadRouteController.java @@ -0,0 +1,28 @@ +package ink.wgink.module.file.controller.route.filedownload; + +import ink.wgink.interfaces.consts.ISystemConstant; +import io.swagger.annotations.Api; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.ModelAndView; + +/** + * @ClassName: FileDownloadRouteController + * @Description: 文件下载 + * @Author: wanggeng + * @Date: 2022/8/2 16:34 + * @Version: 1.0 + */ +@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "文件下载") +@Controller +@RequestMapping(ISystemConstant.ROUTE_PREFIX + "/file-download") +public class FileDownloadRouteController { + + @GetMapping("list") + public ModelAndView list() { + ModelAndView modelAndView = new ModelAndView("file-download/list"); + return modelAndView; + } + +} diff --git a/module-file/src/main/java/ink/wgink/module/file/controller/route/v2/FileRouteController.java b/module-file/src/main/java/ink/wgink/module/file/controller/route/v2/FileRouteController.java new file mode 100644 index 00000000..f9db53b3 --- /dev/null +++ b/module-file/src/main/java/ink/wgink/module/file/controller/route/v2/FileRouteController.java @@ -0,0 +1,52 @@ +package ink.wgink.module.file.controller.route.v2; + +import ink.wgink.interfaces.consts.ISystemConstant; +import ink.wgink.module.file.service.v2.IFileService; +import ink.wgink.pojo.result.ErrorResult; +import io.swagger.annotations.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @ClassName: FileRouteController + * @Description: 文件路由 + * @Author: wanggeng + * @Date: 2022/8/1 15:21 + * @Version: 1.0 + */ +@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "文件路由-V2") +@Controller("fileRouteControllerV2") +@RequestMapping(ISystemConstant.ROUTE_PREFIX + "/file/v2") +public class FileRouteController { + + @Autowired + private IFileService fileService; + + @GetMapping("list") + public ModelAndView list() { + ModelAndView modelAndView = new ModelAndView("file/v2/list"); + return modelAndView; + } + + @ApiOperation(value = "文件下载", notes = "文件下载接口") + @ApiImplicitParams({ + @ApiImplicitParam(name = "isOpen", value = "是否打开,true和false", paramType = "path"), + @ApiImplicitParam(name = "fileId", value = "文件ID", paramType = "path") + }) + @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) + @GetMapping("download/{isOpen}/{fileId}") + public void download(HttpServletRequest request, + HttpServletResponse response, + @PathVariable("isOpen") Boolean isOpen, + @PathVariable("fileId") String fileId) { + fileService.download(request, response, isOpen, fileId); + } + +} diff --git a/module-file/src/main/java/ink/wgink/module/file/dao/filedownload/IFileDownloadDao.java b/module-file/src/main/java/ink/wgink/module/file/dao/filedownload/IFileDownloadDao.java new file mode 100644 index 00000000..68e4207d --- /dev/null +++ b/module-file/src/main/java/ink/wgink/module/file/dao/filedownload/IFileDownloadDao.java @@ -0,0 +1,46 @@ +package ink.wgink.module.file.dao.filedownload; + +import ink.wgink.exceptions.SaveException; +import ink.wgink.exceptions.SearchException; +import ink.wgink.interfaces.init.IInitBaseTable; +import ink.wgink.module.file.pojo.dtos.filedownload.FileDownloadDTO; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: IFileDownloadDao + * @Description: 文件下载 + * @Author: wanggeng + * @Date: 2022/8/2 09:58 + * @Version: 1.0 + */ +@Repository +public interface IFileDownloadDao extends IInitBaseTable { + + /** + * 新增下载记录 + * + * @param params + */ + void save(Map params) throws SaveException; + + /** + * 下载记录列表 + * + * @param params + * @return + * @throws SearchException + */ + List list(Map params) throws SearchException; + + /** + * 下载记录统计 + * + * @param params + * @return + * @throws SearchException + */ + Integer count(Map params) throws SearchException; +} diff --git a/module-file/src/main/java/ink/wgink/module/file/filter/FilesFilter.java b/module-file/src/main/java/ink/wgink/module/file/filter/FilesFilter.java new file mode 100644 index 00000000..e95c5c09 --- /dev/null +++ b/module-file/src/main/java/ink/wgink/module/file/filter/FilesFilter.java @@ -0,0 +1,77 @@ +package ink.wgink.module.file.filter; + +import com.alibaba.fastjson.JSON; +import ink.wgink.exceptions.base.SystemException; +import ink.wgink.module.file.manager.FilesManager; +import ink.wgink.pojo.bos.files.FilesShowCode; +import ink.wgink.pojo.result.ErrorResult; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpStatus; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URLEncoder; + +/** + * @ClassName: FilesFilter + * @Description: 文件过滤器 + * @Author: wanggeng + * @Date: 2022/8/1 09:21 + * @Version: 1.0 + */ +public class FilesFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + Filter.super.init(filterConfig); + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) servletRequest; + HttpServletResponse response = (HttpServletResponse) servletResponse; + String fileId = request.getParameter("file"); + String code = request.getParameter("code"); + String isOpen = request.getParameter("open"); + if (StringUtils.isBlank(code)) { + notFoundResponse(response, "查看码不存在"); + return; + } + if (StringUtils.isBlank(fileId)) { + notFoundResponse(response, "文件不存在"); + return; + } + try { + FilesShowCode showCode = FilesManager.getInstance().getShowCode(fileId, code); + if (Integer.parseInt(isOpen) == 0) { + // 下载 + response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(showCode.getFileName(), "UTF-8")); + } + } catch (SystemException e) { + notFoundResponse(response, e.getMessage()); + return; + } + filterChain.doFilter(servletRequest, servletResponse); + } + + @Override + public void destroy() { + Filter.super.destroy(); + } + + /** + * 文件未找到 + * + * @param response + * @param errorInfo + * @throws IOException + */ + private void notFoundResponse(HttpServletResponse response, String errorInfo) throws IOException { + response.setStatus(HttpStatus.NOT_FOUND.value()); + response.setHeader("Content-Type", "application/json;charset=UTF-8"); + ErrorResult result = new ErrorResult(ErrorResult.ErrorResultCodeEnum.FILE_ERROR.getValue(), errorInfo); + response.getWriter().write(JSON.toJSONString(result)); + } +} diff --git a/module-file/src/main/java/ink/wgink/module/file/impl/DefaultFilesShowCodeServiceImpl.java b/module-file/src/main/java/ink/wgink/module/file/impl/DefaultFilesShowCodeServiceImpl.java new file mode 100644 index 00000000..7aed1f30 --- /dev/null +++ b/module-file/src/main/java/ink/wgink/module/file/impl/DefaultFilesShowCodeServiceImpl.java @@ -0,0 +1,69 @@ +package ink.wgink.module.file.impl; + +import ink.wgink.exceptions.ParamsException; +import ink.wgink.interfaces.manager.IFilesShowCodeService; +import ink.wgink.pojo.bos.files.FilesShowCode; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @ClassName: FileShowCodeServiceImpl + * @Description: 文件显示码 + * @Author: wanggeng + * @Date: 2022/8/1 17:16 + * @Version: 1.0 + */ +@Service +public class DefaultFilesShowCodeServiceImpl implements IFilesShowCodeService { + private static final Logger LOG = LoggerFactory.getLogger(DefaultFilesShowCodeServiceImpl.class); + private Map showCodeMap = new ConcurrentHashMap<>(); + + @Override + public void addShowCode(String code, String fileId, String fileName) { + showCodeMap.put(fileId, new FilesShowCode(code, fileId, fileName)); + } + + @Override + public void clearTimeoutShowCode() { + Set keySet = showCodeMap.keySet(); + long currentTimeMillis = System.currentTimeMillis(); + long clearTimeoutShowCodeCount = 0; + for (String key : keySet) { + FilesShowCode showCode = getShowCode(key); + if (currentTimeMillis - showCode.getLatestUpdateTime() > SHOW_CODE_TIMEOUT_MILLIS) { + showCodeMap.remove(key); + clearTimeoutShowCodeCount++; + } + } + LOG.trace(">>>>>> count of clear timeout show code: {}", clearTimeoutShowCodeCount); + } + + @Override + public FilesShowCode getShowCode(String fileId, String code) { + FilesShowCode showCode = getShowCode(fileId); + if (showCode == null) { + throw new ParamsException("查看码不存在"); + } + if (!StringUtils.equals(showCode.getCode(), code)) { + throw new ParamsException("查看码不匹配"); + } + return showCode; + } + + @Override + public synchronized FilesShowCode getShowCode(String fileId) { + FilesShowCode showCode = showCodeMap.get(fileId); + if (showCode != null) { + showCode.setLatestUpdateTime(System.currentTimeMillis()); + } + return showCode; + } + + +} diff --git a/module-file/src/main/java/ink/wgink/module/file/init/build/BuildFileMenu.java b/module-file/src/main/java/ink/wgink/module/file/init/build/BuildFileMenu.java new file mode 100644 index 00000000..de730375 --- /dev/null +++ b/module-file/src/main/java/ink/wgink/module/file/init/build/BuildFileMenu.java @@ -0,0 +1,40 @@ +package ink.wgink.module.file.init.build; + +import ink.wgink.interfaces.init.build.IBuildServiceMenu; +import ink.wgink.pojo.bos.menu.InitMenuBO; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +/** + * @ClassName: BuildFileMenu + * @Description: 构建文件菜单 + * @Author: wanggeng + * @Date: 2022/8/2 17:17 + * @Version: 1.0 + */ +@Component +public class BuildFileMenu implements IBuildServiceMenu { + + @Override + public void buildMenu(List initMenus) { + InitMenuBO fileParentMenu = new InitMenuBO(); + fileParentMenu.setMenuName("文件管理"); + fileParentMenu.setMenuSummary("文件管理"); + + // 获取子菜单 + List subMenus = new ArrayList<>(); + InitMenuBO initMenu = new InitMenuBO(); + initMenu.setMenuName("上传文件"); + initMenu.setMenuSummary("上传文件"); + initMenu.setMenuUrl("/route/file/v2/list"); + subMenus.add(initMenu); + + // 设置子菜单 + fileParentMenu.setSubMenus(subMenus); + // 更新子菜单 + initMenus.add(fileParentMenu); + } + +} diff --git a/module-file/src/main/java/ink/wgink/module/file/manager/FilesManager.java b/module-file/src/main/java/ink/wgink/module/file/manager/FilesManager.java new file mode 100644 index 00000000..f92ad2d3 --- /dev/null +++ b/module-file/src/main/java/ink/wgink/module/file/manager/FilesManager.java @@ -0,0 +1,75 @@ +package ink.wgink.module.file.manager; + +import ink.wgink.interfaces.manager.IFilesShowCodeService; +import ink.wgink.pojo.bos.files.FilesShowCode; +import ink.wgink.util.string.WStringUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @ClassName: FilesManager + * @Description: 文件管理 + * @Author: wanggeng + * @Date: 2022/8/1 10:47 + * @Version: 1.0 + */ +public class FilesManager { + private static final Logger LOG = LoggerFactory.getLogger(FilesManager.class); + // 查看码超时清理时间,1分钟 + private static FilesManager filesManager = FilesManagerBuilder.filesManager; + private IFilesShowCodeService filesShowCodeService; + + private FilesManager() { + + } + + public static FilesManager getInstance() { + return filesManager; + } + + /** + * 生成显示码 + * + * @param fileId + * @return + */ + public String generateCode(String fileId, String fileName) { + FilesShowCode showCode = filesShowCodeService.getShowCode(fileId); + String code; + if (showCode == null) { + code = WStringUtil.randomSubStr(fileId.replaceAll("-", ""), 4); + filesShowCodeService.addShowCode(code, fileId, fileName); + } else { + code = showCode.getCode(); + } + return code; + } + + /** + * 清除超时显示码 + * + * @return + */ + public void clearTimeoutShowCode() { + filesShowCodeService.clearTimeoutShowCode(); + } + + /** + * 获取显示码 + * + * @param fileId + * @param code + */ + public FilesShowCode getShowCode(String fileId, String code) { + return filesShowCodeService.getShowCode(fileId, code); + } + + public void setFilesShowCodeService(IFilesShowCodeService filesShowCodeService) { + this.filesShowCodeService = filesShowCodeService; + } + + private static class FilesManagerBuilder { + public static FilesManager filesManager = new FilesManager(); + } + +} diff --git a/module-file/src/main/java/ink/wgink/module/file/pojo/dtos/FileInfoDTO.java b/module-file/src/main/java/ink/wgink/module/file/pojo/dtos/FileInfoDTO.java index 92d930d8..c22cf23d 100644 --- a/module-file/src/main/java/ink/wgink/module/file/pojo/dtos/FileInfoDTO.java +++ b/module-file/src/main/java/ink/wgink/module/file/pojo/dtos/FileInfoDTO.java @@ -24,6 +24,12 @@ public class FileInfoDTO extends FileDTO { private String fileSummary; @ApiModelProperty(name = "isBack", value = "是否备份") private Integer isBack; + @ApiModelProperty(name = "creator", value = "创建人") + private String creator; + @ApiModelProperty(name = "gmtCreate", value = "创建时间") + private String gmtCreate; + @ApiModelProperty(name = "downloadCount", value = "下载次数") + private Integer downloadCount; public String getFilePath() { return filePath == null ? "" : filePath.trim(); @@ -59,6 +65,30 @@ public class FileInfoDTO extends FileDTO { this.isBack = isBack; } + public String getCreator() { + return creator == null ? "" : creator.trim(); + } + + public void setCreator(String creator) { + this.creator = creator; + } + + public String getGmtCreate() { + return gmtCreate == null ? "" : gmtCreate.trim(); + } + + public void setGmtCreate(String gmtCreate) { + this.gmtCreate = gmtCreate; + } + + public Integer getDownloadCount() { + return downloadCount == null ? 0 : downloadCount; + } + + public void setDownloadCount(Integer downloadCount) { + this.downloadCount = downloadCount; + } + @Override public String toString() { final StringBuilder sb = new StringBuilder("{"); @@ -70,6 +100,12 @@ public class FileInfoDTO extends FileDTO { .append(fileSummary).append('\"'); sb.append(",\"isBack\":") .append(isBack); + sb.append(",\"creator\":\"") + .append(creator).append('\"'); + sb.append(",\"gmtCreate\":\"") + .append(gmtCreate).append('\"'); + sb.append(",\"downloadCount\":") + .append(downloadCount); sb.append('}'); return sb.toString(); } diff --git a/module-file/src/main/java/ink/wgink/module/file/pojo/dtos/filedownload/FileDownloadDTO.java b/module-file/src/main/java/ink/wgink/module/file/pojo/dtos/filedownload/FileDownloadDTO.java new file mode 100644 index 00000000..e063dca7 --- /dev/null +++ b/module-file/src/main/java/ink/wgink/module/file/pojo/dtos/filedownload/FileDownloadDTO.java @@ -0,0 +1,56 @@ +package ink.wgink.module.file.pojo.dtos.filedownload; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * @ClassName: FileDownloadDTO + * @Description: 文件下载 + * @Author: wanggeng + * @Date: 2022/8/2 10:07 + * @Version: 1.0 + */ +@ApiModel +public class FileDownloadDTO { + + @ApiModelProperty(name = "fileDownloadId", value = "主键") + private String fileDownloadId; + @ApiModelProperty(name = "fileId", value = "文件ID") + private String fileId; + @ApiModelProperty(name = "clientIp", value = "客户端IP") + private String clientIp; + @ApiModelProperty(name = "gmtCreate", value = "下载时间") + private String gmtCreate; + + public String getFileDownloadId() { + return fileDownloadId == null ? "" : fileDownloadId.trim(); + } + + public void setFileDownloadId(String fileDownloadId) { + this.fileDownloadId = fileDownloadId; + } + + public String getFileId() { + return fileId == null ? "" : fileId.trim(); + } + + public void setFileId(String fileId) { + this.fileId = fileId; + } + + public String getClientIp() { + return clientIp == null ? "" : clientIp.trim(); + } + + public void setClientIp(String clientIp) { + this.clientIp = clientIp; + } + + public String getGmtCreate() { + return gmtCreate == null ? "" : gmtCreate.trim(); + } + + public void setGmtCreate(String gmtCreate) { + this.gmtCreate = gmtCreate; + } +} diff --git a/module-file/src/main/java/ink/wgink/module/file/pojo/dtos/v2/FileUploadSuccessDTO.java b/module-file/src/main/java/ink/wgink/module/file/pojo/dtos/v2/FileUploadSuccessDTO.java index 074e5609..db6f2b9a 100644 --- a/module-file/src/main/java/ink/wgink/module/file/pojo/dtos/v2/FileUploadSuccessDTO.java +++ b/module-file/src/main/java/ink/wgink/module/file/pojo/dtos/v2/FileUploadSuccessDTO.java @@ -23,6 +23,8 @@ public class FileUploadSuccessDTO implements Serializable { private String fileName; @ApiModelProperty(name = "fileSize", value = "文件大小") private Long fileSize; + @ApiModelProperty(name = "fileUrl", value = "文件路径") + private String fileUrl; public FileUploadSuccessDTO() { } @@ -33,6 +35,14 @@ public class FileUploadSuccessDTO implements Serializable { this.fileSize = fileSize; } + + public FileUploadSuccessDTO(String fileId, String fileName, Long fileSize, String fileUrl) { + this.fileId = fileId; + this.fileName = fileName; + this.fileSize = fileSize; + this.fileUrl = fileUrl; + } + public String getFileId() { return fileId == null ? "" : fileId.trim(); } @@ -57,6 +67,14 @@ public class FileUploadSuccessDTO implements Serializable { this.fileSize = fileSize; } + public String getFileUrl() { + return fileUrl == null ? "" : fileUrl.trim(); + } + + public void setFileUrl(String fileUrl) { + this.fileUrl = fileUrl; + } + @Override public String toString() { final StringBuilder sb = new StringBuilder("{"); @@ -66,6 +84,8 @@ public class FileUploadSuccessDTO implements Serializable { .append(fileName).append('\"'); sb.append(",\"fileSize\":") .append(fileSize); + sb.append(",\"fileUrl\":\"") + .append(fileUrl).append('\"'); sb.append('}'); return sb.toString(); } diff --git a/module-file/src/main/java/ink/wgink/module/file/pojo/vos/filedownload/FileDownloadVO.java b/module-file/src/main/java/ink/wgink/module/file/pojo/vos/filedownload/FileDownloadVO.java new file mode 100644 index 00000000..1b3fd68c --- /dev/null +++ b/module-file/src/main/java/ink/wgink/module/file/pojo/vos/filedownload/FileDownloadVO.java @@ -0,0 +1,38 @@ +package ink.wgink.module.file.pojo.vos.filedownload; + +/** + * @ClassName: FileDownloadVO + * @Description: 文件下载 + * @Author: wanggeng + * @Date: 2022/8/2 09:56 + * @Version: 1.0 + */ +public class FileDownloadVO { + + private String fileId; + private String clientIp; + + public FileDownloadVO() { + } + + public FileDownloadVO(String fileId, String clientIp) { + this.fileId = fileId; + this.clientIp = clientIp; + } + + public String getFileId() { + return fileId == null ? "" : fileId.trim(); + } + + public void setFileId(String fileId) { + this.fileId = fileId; + } + + public String getClientIp() { + return clientIp == null ? "" : clientIp.trim(); + } + + public void setClientIp(String clientIp) { + this.clientIp = clientIp; + } +} diff --git a/module-file/src/main/java/ink/wgink/module/file/service/filedownload/IFileDownloadService.java b/module-file/src/main/java/ink/wgink/module/file/service/filedownload/IFileDownloadService.java new file mode 100644 index 00000000..cfcaa8fb --- /dev/null +++ b/module-file/src/main/java/ink/wgink/module/file/service/filedownload/IFileDownloadService.java @@ -0,0 +1,69 @@ +package ink.wgink.module.file.service.filedownload; + +import ink.wgink.module.file.pojo.dtos.filedownload.FileDownloadDTO; +import ink.wgink.module.file.pojo.vos.filedownload.FileDownloadVO; +import ink.wgink.pojo.ListPage; +import ink.wgink.pojo.result.SuccessResultList; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: IFileDownloadService + * @Description: 文件下载 + * @Author: wanggeng + * @Date: 2022/8/2 09:58 + * @Version: 1.0 + */ +public interface IFileDownloadService { + + /** + * 新增下载记录 + * + * @param fileDownloadVO + */ + void save(FileDownloadVO fileDownloadVO); + + /** + * 下载列表 + * + * @param params + * @return + */ + List list(Map params); + + /** + * 下载列表 + * + * @param fileId + * @return + */ + List listByFileId(String fileId); + + /** + * 下载分页列表 + * + * @param page + * @return + */ + SuccessResultList> listPage(ListPage page); + + /** + * 下载分页列表 + * + * @param fileId + * @param page + * @return + */ + SuccessResultList> listPageByFileId(String fileId, ListPage page); + + + /** + * 统计下载列表 + * + * @param fileId + * @return + */ + Integer countByFileId(String fileId); + +} diff --git a/module-file/src/main/java/ink/wgink/module/file/service/filedownload/impl/FileDownloadServiceImpl.java b/module-file/src/main/java/ink/wgink/module/file/service/filedownload/impl/FileDownloadServiceImpl.java new file mode 100644 index 00000000..2410b673 --- /dev/null +++ b/module-file/src/main/java/ink/wgink/module/file/service/filedownload/impl/FileDownloadServiceImpl.java @@ -0,0 +1,77 @@ +package ink.wgink.module.file.service.filedownload.impl; + +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import ink.wgink.common.base.DefaultBaseService; +import ink.wgink.module.file.dao.filedownload.IFileDownloadDao; +import ink.wgink.module.file.pojo.dtos.filedownload.FileDownloadDTO; +import ink.wgink.module.file.pojo.vos.filedownload.FileDownloadVO; +import ink.wgink.module.file.service.filedownload.IFileDownloadService; +import ink.wgink.pojo.ListPage; +import ink.wgink.pojo.result.SuccessResultList; +import ink.wgink.util.UUIDUtil; +import ink.wgink.util.date.DateUtil; +import ink.wgink.util.map.HashMapUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FileDownloadServiceImpl + * @Description: 文件下载 + * @Author: wanggeng + * @Date: 2022/8/2 09:58 + * @Version: 1.0 + */ +@Service +public class FileDownloadServiceImpl extends DefaultBaseService implements IFileDownloadService { + + @Autowired + private IFileDownloadDao fileDownloadDao; + + @Override + public void save(FileDownloadVO fileDownloadVO) { + Map params = HashMapUtil.beanToMap(fileDownloadVO); + params.put("fileDownloadId", UUIDUtil.getUUID()); + params.put("gmtCreate", DateUtil.getTime()); + fileDownloadDao.save(params); + } + + @Override + public List list(Map params) { + params = params == null ? getHashMap(0) : params; + return fileDownloadDao.list(params); + } + + @Override + public List listByFileId(String fileId) { + Map params = getHashMap(2); + params.put("fileId", fileId); + return list(params); + } + + @Override + public SuccessResultList> listPage(ListPage page) { + PageHelper.startPage(page.getPage(), page.getRows()); + List fileDownloadDTOS = list(page.getParams()); + PageInfo pageInfo = new PageInfo<>(fileDownloadDTOS); + return new SuccessResultList<>(fileDownloadDTOS, pageInfo.getPageNum(), pageInfo.getTotal()); + } + + @Override + public SuccessResultList> listPageByFileId(String fileId, ListPage page) { + page.getParams().put("fileId", fileId); + return listPage(page); + } + + @Override + public Integer countByFileId(String fileId) { + Map params = getHashMap(2); + params.put("fileId", fileId); + return fileDownloadDao.count(params); + } + + +} diff --git a/module-file/src/main/java/ink/wgink/module/file/service/v2/IFileService.java b/module-file/src/main/java/ink/wgink/module/file/service/v2/IFileService.java index 309f788c..1e21ca78 100644 --- a/module-file/src/main/java/ink/wgink/module/file/service/v2/IFileService.java +++ b/module-file/src/main/java/ink/wgink/module/file/service/v2/IFileService.java @@ -1,13 +1,19 @@ package ink.wgink.module.file.service.v2; import ink.wgink.module.file.enums.UploadTypeEnum; +import ink.wgink.module.file.pojo.dtos.FileInfoDTO; import ink.wgink.module.file.pojo.dtos.v2.FileUploadSuccessDTO; import ink.wgink.module.file.pojo.vos.v2.FileSaveVO; import ink.wgink.module.file.pojo.vos.v2.FileUpdateVO; +import ink.wgink.pojo.ListPage; import ink.wgink.pojo.pos.FilePO; +import ink.wgink.pojo.result.SuccessResultList; import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import java.io.InputStream; +import java.util.List; import java.util.Map; /** @@ -96,6 +102,13 @@ public interface IFileService { */ void update(FileUpdateVO fileUpdateVO); + /** + * 删除文件 + * + * @param fileIds + */ + void delete(List fileIds); + /** * 获取文件 * @@ -112,4 +125,30 @@ public interface IFileService { */ FilePO getPO(String fileId); + /** + * 下载 + * + * @param request + * @param response + * @param isOpen 是否打开 + * @param fileId 文件ID + */ + void download(HttpServletRequest request, HttpServletResponse response, boolean isOpen, String fileId); + + /** + * 文件列表 + * + * @param params + * @return + */ + List list(Map params); + + /** + * 文件分页列表 + * + * @param page + * @return + */ + SuccessResultList> listPage(ListPage page); + } diff --git a/module-file/src/main/java/ink/wgink/module/file/service/v2/impl/FileServiceImpl.java b/module-file/src/main/java/ink/wgink/module/file/service/v2/impl/FileServiceImpl.java index 1e049939..cbdbbd29 100644 --- a/module-file/src/main/java/ink/wgink/module/file/service/v2/impl/FileServiceImpl.java +++ b/module-file/src/main/java/ink/wgink/module/file/service/v2/impl/FileServiceImpl.java @@ -1,24 +1,41 @@ package ink.wgink.module.file.service.v2.impl; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; import ink.wgink.common.base.DefaultBaseService; +import ink.wgink.exceptions.FileException; import ink.wgink.exceptions.SearchException; import ink.wgink.module.file.components.FileComponent; import ink.wgink.module.file.dao.IFileDao; import ink.wgink.module.file.enums.UploadTypeEnum; +import ink.wgink.module.file.manager.FilesManager; +import ink.wgink.module.file.pojo.dtos.FileInfoDTO; import ink.wgink.module.file.pojo.dtos.v2.FileUploadSuccessDTO; +import ink.wgink.module.file.pojo.vos.filedownload.FileDownloadVO; import ink.wgink.module.file.pojo.vos.v2.FileSaveVO; import ink.wgink.module.file.pojo.vos.v2.FileUpdateVO; +import ink.wgink.module.file.service.filedownload.IFileDownloadService; import ink.wgink.module.file.service.v2.IFileService; +import ink.wgink.pojo.ListPage; import ink.wgink.pojo.pos.FilePO; +import ink.wgink.pojo.result.SuccessResultList; import ink.wgink.util.UUIDUtil; import ink.wgink.util.date.DateUtil; +import ink.wgink.util.request.RequestUtil; +import ink.wgink.util.thread.CachedThreadPoolUtil; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.Map; /** @@ -35,6 +52,8 @@ public class FileServiceImpl extends DefaultBaseService implements IFileService private FileComponent fileComponent; @Autowired private IFileDao fileDao; + @Autowired + private IFileDownloadService fileDownloadService; @Override public FileUploadSuccessDTO uploadSingle(MultipartFile uploadFile, UploadTypeEnum uploadTypeEnum) { @@ -81,12 +100,13 @@ public class FileServiceImpl extends DefaultBaseService implements IFileService @Override public FileUploadSuccessDTO saveFile(FileSaveVO fileSaveVO) { + String fileUrl = fileComponent.getFileUrl(fileSaveVO.getUploadPath()); String fileId = UUIDUtil.getUUID(); Map params = getHashMap(10); params.put("fileId", fileId); params.put("fileName", fileSaveVO.getFileName()); params.put("filePath", fileSaveVO.getUploadPath()); - params.put("fileUrl", fileComponent.getFileUrl(fileSaveVO.getUploadPath())); + params.put("fileUrl", fileUrl); params.put("fileType", fileSaveVO.getFileType()); params.put("fileSize", fileSaveVO.getFileSize()); params.put("isBack", 0); @@ -99,7 +119,7 @@ public class FileServiceImpl extends DefaultBaseService implements IFileService params.put("isDelete", 0); fileDao.save(params); - return new FileUploadSuccessDTO(fileId, fileSaveVO.getFileName(), fileSaveVO.getFileSize()); + return new FileUploadSuccessDTO(fileId, fileSaveVO.getFileName(), fileSaveVO.getFileSize(), fileUrl); } @Override @@ -116,6 +136,26 @@ public class FileServiceImpl extends DefaultBaseService implements IFileService fileDao.update(params); } + @Override + public void delete(List fileIds) { + if (fileIds.isEmpty()) { + return; + } + Map params = getHashMap(2); + params.put("fileIds", fileIds); + List filePOS = fileDao.listPO(params); + // 删除源文件 + filePOS.forEach(filePO -> { + File file = new File(filePO.getFilePath()); + if (!file.exists()) { + return; + } + file.delete(); + }); + // 删除记录 + fileDao.delete(params); + } + @Override public FilePO getPO(Map params) { return fileDao.getPO(params); @@ -128,6 +168,87 @@ public class FileServiceImpl extends DefaultBaseService implements IFileService return getPO(params); } + @Override + public void download(HttpServletRequest request, HttpServletResponse response, boolean isOpen, String fileId) { + FilePO filePO = getPO(fileId); + if (filePO == null) { + throw new FileException("查询失败"); + } + File file = new File(filePO.getFilePath()); + if (!file.exists()) { + throw new FileException("文件不存在"); + } + try { + String requestIp = RequestUtil.getRequestIp(request); + String code = FilesManager.getInstance().generateCode(fileId, filePO.getFileName()); + response.sendRedirect(String.format("%s/%s?file=%s&code=%s&open=%d", request.getContextPath(), filePO.getFileUrl(), fileId, code, isOpen ? 1 : 0)); + if (!isOpen && !StringUtils.isBlank(requestIp)) { + // 记录下载历史 + CachedThreadPoolUtil.execute(() -> { + FileDownloadVO fileDownloadVO = new FileDownloadVO(filePO.getFileId(), requestIp); + fileDownloadService.save(fileDownloadVO); + }); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public List list(Map params) { + params = params == null ? getHashMap(0) : params; + setQueryFileType(params); + List fileInfoDTOs = fileDao.listInfo(params); + setDownloadCount(fileInfoDTOs); + return fileInfoDTOs; + } + + @Override + public SuccessResultList> listPage(ListPage page) { + PageHelper.startPage(page.getPage(), page.getRows()); + List fileInfoDTOs = list(page.getParams()); + setDownloadCount(fileInfoDTOs); + PageInfo pageInfo = new PageInfo<>(fileInfoDTOs); + return new SuccessResultList<>(fileInfoDTOs, pageInfo.getPageNum(), pageInfo.getTotal()); + } + + /** + * 设置查询文件类型 + * + * @param params + */ + private void setQueryFileType(Map params) { + String fileType = (String) params.get("fileType"); + if (StringUtils.isBlank(fileType)) { + return; + } + List fileTypes; + if (StringUtils.equals("image", fileType)) { + fileTypes = Arrays.asList(fileComponent.getImageTypes()); + } else if (StringUtils.equals("video", fileType)) { + fileTypes = Arrays.asList(fileComponent.getVideoTypes()); + } else if (StringUtils.equals("audio", fileType)) { + fileTypes = Arrays.asList(fileComponent.getAudioTypes()); + } else if (StringUtils.equals("file", fileType)) { + fileTypes = Arrays.asList(fileComponent.getFileTypes()); + } else { + fileTypes = new ArrayList<>(); + } + params.put("fileTypes", fileTypes); + } + + /** + * 设置下载次数 + * + * @param fileInfoDTOs + */ + private void setDownloadCount(List fileInfoDTOs) { + fileInfoDTOs.forEach(fileInfoDTO -> { + Integer downloadCount = fileDownloadService.countByFileId(fileInfoDTO.getFileId()); + fileInfoDTO.setDownloadCount(downloadCount); + }); + } + /** * 获取文件保存VO * diff --git a/module-file/src/main/java/ink/wgink/module/file/startup/FilesStartUp.java b/module-file/src/main/java/ink/wgink/module/file/startup/FilesStartUp.java new file mode 100644 index 00000000..7d0986b3 --- /dev/null +++ b/module-file/src/main/java/ink/wgink/module/file/startup/FilesStartUp.java @@ -0,0 +1,33 @@ +package ink.wgink.module.file.startup; + +import ink.wgink.interfaces.manager.IFilesShowCodeService; +import ink.wgink.module.file.manager.FilesManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +/** + * @ClassName: FileStartUp + * @Description: 文件启动类 + * @Author: wanggeng + * @Date: 2022/8/1 16:17 + * @Version: 1.0 + */ +@Component +public class FilesStartUp implements ApplicationRunner { + + @Autowired + private IFilesShowCodeService filesShowCodeService; + + @Override + public void run(ApplicationArguments args) throws Exception { + FilesManager.getInstance().setFilesShowCodeService(filesShowCodeService); + } + + @Scheduled(cron = "0 0/1 * * * ?") + public void clearTimeoutShowCode() { + FilesManager.getInstance().clearTimeoutShowCode(); + } +} diff --git a/module-file/src/main/resources/mybatis/mapper/file-download/file-download-mapper.xml b/module-file/src/main/resources/mybatis/mapper/file-download/file-download-mapper.xml new file mode 100644 index 00000000..bdcb4354 --- /dev/null +++ b/module-file/src/main/resources/mybatis/mapper/file-download/file-download-mapper.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + CREATE TABLE IF NOT EXISTS `sys_file_download` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `file_download_id` char(36) DEFAULT NULL COMMENT '主键', + `file_id` char(36) DEFAULT NULL COMMENT '文件ID', + `client_ip` varchar(20) DEFAULT NULL COMMENT '客户端IP', + `gmt_create` datetime DEFAULT NULL COMMENT '下载时间', + PRIMARY KEY (`id`), + UNIQUE KEY `file_download_id` (`file_download_id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + + + + INSERT INTO sys_file_download ( + file_download_id, + file_id, + client_ip, + gmt_create + ) VALUES( + #{fileDownloadId}, + #{fileId}, + #{clientIp}, + #{gmtCreate} + ) + + + + + + + + + + \ No newline at end of file diff --git a/module-file/src/main/resources/mybatis/mapper/file-mapper.xml b/module-file/src/main/resources/mybatis/mapper/file-mapper.xml index 233b6aee..be49eb9d 100644 --- a/module-file/src/main/resources/mybatis/mapper/file-mapper.xml +++ b/module-file/src/main/resources/mybatis/mapper/file-mapper.xml @@ -283,6 +283,13 @@ #{fileIds[${index}]} + + AND + file_type IN + + #{fileTypes[${index}]} + + diff --git a/module-file/src/main/resources/templates/file-download/list.html b/module-file/src/main/resources/templates/file-download/list.html new file mode 100644 index 00000000..982e5c6e --- /dev/null +++ b/module-file/src/main/resources/templates/file-download/list.html @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/module-file/src/main/resources/templates/file/v2/list.html b/module-file/src/main/resources/templates/file/v2/list.html new file mode 100644 index 00000000..e6a82d35 --- /dev/null +++ b/module-file/src/main/resources/templates/file/v2/list.html @@ -0,0 +1,290 @@ + + + + + + + + + + + + + + +
+
+
+
+
+
+
+ +
+
+ +
+ +
+
+ + +
+
+
+
+
+ + + + + \ No newline at end of file