mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 18:28:43 +08:00 
			
		
		
		
	1. 基于 db 实现文件的存储
This commit is contained in:
		| @@ -0,0 +1,12 @@ | ||||
| package cn.iocoder.dashboard.framework.file.config; | ||||
|  | ||||
| import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
|  | ||||
| /** | ||||
|  * 文件 配置类 | ||||
|  */ | ||||
| @Configuration | ||||
| @EnableConfigurationProperties(FileProperties.class) | ||||
| public class FileConfiguration { | ||||
| } | ||||
| @@ -0,0 +1,23 @@ | ||||
| package cn.iocoder.dashboard.framework.file.config; | ||||
|  | ||||
| import cn.iocoder.dashboard.modules.system.controller.common.SysFileController; | ||||
| import lombok.Data; | ||||
| import org.springframework.boot.context.properties.ConfigurationProperties; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
|  | ||||
| import javax.validation.constraints.NotNull; | ||||
|  | ||||
| @ConfigurationProperties(prefix = "yudao.file") | ||||
| @Validated | ||||
| @Data | ||||
| public class FileProperties { | ||||
|  | ||||
|     /** | ||||
|      * 对应 {@link SysFileController#} | ||||
|      */ | ||||
|     @NotNull(message = "基础文件路径不能为空") | ||||
|     private String basePath; | ||||
|  | ||||
|     // TODO 七牛、等等 | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,16 @@ | ||||
| /** | ||||
|  * 文件的存储,推荐使用七牛、阿里云、华为云、腾讯云等文件服务 | ||||
|  * | ||||
|  * 在不采用云服务的情况下,我们有几种技术选型: | ||||
|  * 方案 1. 使用自建的文件服务,例如说 minIO、FastDFS 等等 | ||||
|  * 方案 2. 使用服务器的文件系统存储 | ||||
|  * 方案 3. 使用数据库进行存储 | ||||
|  * | ||||
|  * 如果考虑额外在搭建服务,推荐方案 1。 | ||||
|  * 对于方案 2 来说,如果要实现文件存储的高可用,需要多台服务器之间做实时同步,可以基于 rsync + inotify 来做 | ||||
|  * 对于方案 3 的话,实现起来最简单,但是数据库本身不适合存储海量的文件 | ||||
|  * | ||||
|  * 综合考虑,暂时使用方案 3 的方式,比较适合这样一个 all in one 的项目。 | ||||
|  * 随着文件的量级大了之后,还是推荐采用云服务。 | ||||
|  */ | ||||
| package cn.iocoder.dashboard.framework.file; | ||||
| @@ -1,7 +1,6 @@ | ||||
| package cn.iocoder.dashboard.framework.security.config; | ||||
|  | ||||
| import cn.iocoder.dashboard.framework.security.core.filter.JwtAuthenticationTokenFilter; | ||||
| import cn.iocoder.dashboard.framework.security.core.handler.AuthenticationEntryPointImpl; | ||||
| import cn.iocoder.dashboard.framework.security.core.handler.LogoutSuccessHandlerImpl; | ||||
| import cn.iocoder.dashboard.framework.web.config.WebProperties; | ||||
| import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||||
| @@ -19,8 +18,6 @@ import org.springframework.security.crypto.password.PasswordEncoder; | ||||
| import org.springframework.security.web.AuthenticationEntryPoint; | ||||
| import org.springframework.security.web.access.AccessDeniedHandler; | ||||
| import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||||
| import org.springframework.security.web.authentication.logout.LogoutFilter; | ||||
| import org.springframework.web.filter.CorsFilter; | ||||
|  | ||||
| import javax.annotation.Resource; | ||||
|  | ||||
| @@ -126,12 +123,13 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { | ||||
|                 // 登陆的接口,可匿名访问 | ||||
|                 .antMatchers(webProperties.getApiPrefix() + "/login").anonymous() | ||||
|                 // 通用的接口,可匿名访问 | ||||
|                 .antMatchers( webProperties.getApiPrefix() + "/captcha/**").anonymous() | ||||
|                 .antMatchers( webProperties.getApiPrefix() + "/system/captcha/**").anonymous() | ||||
|                 // TODO | ||||
|                 .antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll() | ||||
|                 .antMatchers("/profile/**").anonymous() | ||||
|                 .antMatchers("/common/download**").anonymous() | ||||
|                 .antMatchers("/common/download/resource**").anonymous() | ||||
|                 // 文件的获取接口,可匿名访问 | ||||
|                 .antMatchers(webProperties.getApiPrefix() + "/system/file/get/**").anonymous() | ||||
|                 // TODO | ||||
|                 .antMatchers("/swagger-ui.html").anonymous() | ||||
|                 .antMatchers("/swagger-resources/**").anonymous() | ||||
|                 .antMatchers("/webjars/**").anonymous() | ||||
|   | ||||
| @@ -15,7 +15,7 @@ import static cn.iocoder.dashboard.common.pojo.CommonResult.success; | ||||
|  | ||||
| @Api(tags = "验证码 API") | ||||
| @RestController | ||||
| @RequestMapping("/captcha") | ||||
| @RequestMapping("/system/captcha") | ||||
| public class SysCaptchaController { | ||||
|  | ||||
|     @Resource | ||||
|   | ||||
| @@ -0,0 +1,47 @@ | ||||
| package cn.iocoder.dashboard.modules.system.controller.common; | ||||
|  | ||||
| import cn.hutool.core.io.IoUtil; | ||||
| import cn.iocoder.dashboard.common.pojo.CommonResult; | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.common.SysFileDO; | ||||
| import cn.iocoder.dashboard.modules.system.service.common.SysFileService; | ||||
| import cn.iocoder.dashboard.util.servlet.ServletUtils; | ||||
| import io.swagger.annotations.Api; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.web.multipart.MultipartFile; | ||||
|  | ||||
| import javax.annotation.Resource; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
|  | ||||
| import java.io.IOException; | ||||
|  | ||||
| import static cn.iocoder.dashboard.common.pojo.CommonResult.success; | ||||
|  | ||||
| @Api(tags = "文件 API") | ||||
| @RestController | ||||
| @RequestMapping("/system/file") | ||||
| @Slf4j | ||||
| public class SysFileController { | ||||
|  | ||||
|     @Resource | ||||
|     private SysFileService fileService; | ||||
|  | ||||
|     @PostMapping("/upload") | ||||
|     public CommonResult<String> uploadFile(@RequestParam("file") MultipartFile file, | ||||
|                                            @RequestParam("path") String path) throws IOException { | ||||
|         return success(fileService.createFile(path, IoUtil.readBytes(file.getInputStream()))); | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/get/{path}") | ||||
|     public void getFile(HttpServletResponse response, @PathVariable("path") String path) throws IOException { | ||||
|         SysFileDO file = fileService.getFile(path); | ||||
|         if (file == null) { | ||||
|             log.warn("[getFile][path({}) 文件不存在]", path); | ||||
|             response.setStatus(HttpStatus.NOT_FOUND.value()); | ||||
|             return; | ||||
|         } | ||||
|         ServletUtils.writeAttachment(response, path, file.getContent()); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.controller.dept; | ||||
| import cn.iocoder.dashboard.common.enums.CommonStatusEnum; | ||||
| import cn.iocoder.dashboard.common.pojo.CommonResult; | ||||
| import cn.iocoder.dashboard.common.pojo.PageResult; | ||||
| import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils; | ||||
| import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.*; | ||||
| import cn.iocoder.dashboard.modules.system.convert.dept.SysPostConvert; | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysPostDO; | ||||
| @@ -14,6 +15,8 @@ import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
|  | ||||
| import javax.annotation.Resource; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| import java.io.IOException; | ||||
| import java.util.Collections; | ||||
| import java.util.Comparator; | ||||
| import java.util.List; | ||||
| @@ -80,12 +83,16 @@ public class SysPostController { | ||||
|         return success(SysPostConvert.INSTANCE.convert(postService.getPost(id))); | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/export") | ||||
|     @ApiOperation("岗位管理") | ||||
| //    @Log(title = "岗位管理", businessType = BusinessType.EXPORT) | ||||
| //    @PreAuthorize("@ss.hasPermi('system:post:export')") | ||||
| //    @GetMapping("/export") | ||||
| //    public AjaxResult export(SysPost post) { | ||||
| //        List<SysPost> list = postService.selectPostList(post); | ||||
| //        ExcelUtil<SysPost> util = new ExcelUtil<SysPost>(SysPost.class); | ||||
| //        return util.exportExcel(list, "岗位数据"); | ||||
| //    } | ||||
|     public void export(HttpServletResponse response, @Validated SysPostExportReqVO reqVO) throws IOException { | ||||
|         List<SysPostDO> posts = postService.listPosts(reqVO); | ||||
|         List<SysPostExcelVO> excelPosts = SysPostConvert.INSTANCE.convertList03(posts); | ||||
|         // 输出 | ||||
|         ExcelUtils.write(response, "岗位数据.xls", "岗位列表", | ||||
|                 SysPostExcelVO.class, excelPosts); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,27 +0,0 @@ | ||||
| package cn.iocoder.dashboard.modules.system.controller.dept.vo.post; | ||||
|  | ||||
| import cn.iocoder.dashboard.framework.excel.Excel; | ||||
| import lombok.Data; | ||||
|  | ||||
| /** | ||||
|  * 岗位 Excel 导出响应 VO | ||||
|  */ | ||||
| @Data | ||||
| public class SysPostExcelRespVO { | ||||
|  | ||||
|     @Excel(name = "岗位序号", cellType = Excel.ColumnType.NUMERIC) | ||||
|     private Long id; | ||||
|  | ||||
|     @Excel(name = "岗位编码") | ||||
|     private String code; | ||||
|  | ||||
|     @Excel(name = "岗位名称") | ||||
|     private String name; | ||||
|  | ||||
|     @Excel(name = "岗位排序") | ||||
|     private String sort; | ||||
|  | ||||
|     @Excel(name = "状态", readConverterExp = "0=正常,1=停用") | ||||
|     private String status; | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,32 @@ | ||||
| package cn.iocoder.dashboard.modules.system.controller.dept.vo.post; | ||||
|  | ||||
| import cn.iocoder.dashboard.framework.excel.core.annotations.DictFormat; | ||||
| import cn.iocoder.dashboard.framework.excel.core.convert.DictConvert; | ||||
| import com.alibaba.excel.annotation.ExcelProperty; | ||||
| import lombok.Data; | ||||
|  | ||||
| import static cn.iocoder.dashboard.modules.system.enums.dict.DictTypeEnum.SYS_COMMON_STATUS; | ||||
|  | ||||
| /** | ||||
|  * 岗位 Excel 导出响应 VO | ||||
|  */ | ||||
| @Data | ||||
| public class SysPostExcelVO { | ||||
|  | ||||
|     @ExcelProperty("岗位序号") | ||||
|     private Long id; | ||||
|  | ||||
|     @ExcelProperty("岗位编码") | ||||
|     private String code; | ||||
|  | ||||
|     @ExcelProperty("岗位名称") | ||||
|     private String name; | ||||
|  | ||||
|     @ExcelProperty("岗位排序") | ||||
|     private String sort; | ||||
|  | ||||
|     @ExcelProperty(value = "状态", converter = DictConvert.class) | ||||
|     @DictFormat(SYS_COMMON_STATUS) | ||||
|     private String status; | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,17 @@ | ||||
| package cn.iocoder.dashboard.modules.system.controller.dept.vo.post; | ||||
|  | ||||
| import io.swagger.annotations.ApiModel; | ||||
| import io.swagger.annotations.ApiModelProperty; | ||||
| import lombok.Data; | ||||
|  | ||||
| @ApiModel(value = "岗位导出 Request VO", description = "参数和 SysPostExcelVO 是一致的") | ||||
| @Data | ||||
| public class SysPostExportReqVO { | ||||
|  | ||||
|     @ApiModelProperty(value = "岗位名称", example = "芋道", notes = "模糊匹配") | ||||
|     private String name; | ||||
|  | ||||
|     @ApiModelProperty(value = "展示状态", example = "1", notes = "参见 SysCommonStatusEnum 枚举类") | ||||
|     private Integer status; | ||||
|  | ||||
| } | ||||
| @@ -1,10 +1,7 @@ | ||||
| package cn.iocoder.dashboard.modules.system.convert.dept; | ||||
|  | ||||
| import cn.iocoder.dashboard.common.pojo.PageResult; | ||||
| import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostCreateReqVO; | ||||
| import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostRespVO; | ||||
| import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostSimpleRespVO; | ||||
| import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostUpdateReqVO; | ||||
| import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.*; | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysPostDO; | ||||
| import com.baomidou.mybatisplus.core.metadata.IPage; | ||||
| import org.mapstruct.Mapper; | ||||
| @@ -31,4 +28,6 @@ public interface SysPostConvert { | ||||
|  | ||||
|     SysPostDO convert(SysPostUpdateReqVO reqVO); | ||||
|  | ||||
|     List<SysPostExcelVO> convertList03(List<SysPostDO> list); | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,15 @@ | ||||
| package cn.iocoder.dashboard.modules.system.dal.mysql.dao.common; | ||||
|  | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.common.SysFileDO; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | ||||
| import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||||
| import org.apache.ibatis.annotations.Mapper; | ||||
|  | ||||
| @Mapper | ||||
| public interface SysFileMapper extends BaseMapper<SysFileDO> { | ||||
|  | ||||
|     default Integer selectCountById(String id) { | ||||
|         return selectCount(new QueryWrapper<SysFileDO>().eq("id", id)); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -2,6 +2,7 @@ package cn.iocoder.dashboard.modules.system.dal.mysql.dao.dept; | ||||
|  | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.query.QueryWrapperX; | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.util.MyBatisUtils; | ||||
| import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostExportReqVO; | ||||
| import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostPageReqVO; | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysPostDO; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | ||||
| @@ -26,6 +27,11 @@ public interface SysPostMapper extends BaseMapper<SysPostDO> { | ||||
|                         .eqIfPresent("status", reqVO.getStatus())); | ||||
|     } | ||||
|  | ||||
|     default List<SysPostDO> selectList(SysPostExportReqVO reqVO) { | ||||
|         return selectList(new QueryWrapperX<SysPostDO>().likeIfPresent("name", reqVO.getName()) | ||||
|                 .eqIfPresent("status", reqVO.getStatus())); | ||||
|     } | ||||
|  | ||||
|     default SysPostDO selectByName(String name) { | ||||
|         return selectOne(new QueryWrapper<SysPostDO>().eq("name", name)); | ||||
|     } | ||||
|   | ||||
| @@ -0,0 +1,30 @@ | ||||
| package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.common; | ||||
|  | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; | ||||
| import com.baomidou.mybatisplus.annotation.IdType; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
|  | ||||
| /** | ||||
|  * 文件表 | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| @Data | ||||
| @TableName("sys_file") | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| public class SysFileDO extends BaseDO { | ||||
|  | ||||
|     /** | ||||
|      * 文件路径 | ||||
|      */ | ||||
|     @TableId(type = IdType.INPUT) | ||||
|     private String id; | ||||
|     /** | ||||
|      * 文件内容 | ||||
|      */ | ||||
|     private byte[] content; | ||||
|  | ||||
| } | ||||
| @@ -8,7 +8,7 @@ import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
|  | ||||
| /** | ||||
|  * 部门表 sys_dept | ||||
|  * 部门表 | ||||
|  * | ||||
|  * @author ruoyi | ||||
|  */ | ||||
|   | ||||
| @@ -69,4 +69,6 @@ public interface SysErrorCodeConstants { | ||||
|     // ========== 通知公告 1002008000 ========== | ||||
|     ErrorCode NOTICE_NOT_FOUND = new ErrorCode(1002008001, "当前通知公告不存在"); | ||||
|  | ||||
|     // ========== 文件 1002009000 ========== | ||||
|     ErrorCode FILE_PATH_EXISTS = new ErrorCode(1002009001, "文件路径已经存在"); | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,29 @@ | ||||
| package cn.iocoder.dashboard.modules.system.service.common; | ||||
|  | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.common.SysFileDO; | ||||
|  | ||||
| /** | ||||
|  * 文件 Service 接口 | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| public interface SysFileService { | ||||
|  | ||||
|     /** | ||||
|      * 保存文件,并返回文件的访问路径 | ||||
|      * | ||||
|      * @param path 文件路径 | ||||
|      * @param content 文件内容 | ||||
|      * @return 文件路径 | ||||
|      */ | ||||
|     String createFile(String path, byte[] content); | ||||
|  | ||||
|     /** | ||||
|      * 获得文件 | ||||
|      * | ||||
|      * @param path 文件路径 | ||||
|      * @return 文件 | ||||
|      */ | ||||
|     SysFileDO getFile(String path); | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,47 @@ | ||||
| package cn.iocoder.dashboard.modules.system.service.common.impl; | ||||
|  | ||||
| import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil; | ||||
| import cn.iocoder.dashboard.framework.file.config.FileProperties; | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dao.common.SysFileMapper; | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.common.SysFileDO; | ||||
| import cn.iocoder.dashboard.modules.system.service.common.SysFileService; | ||||
| import org.springframework.stereotype.Service; | ||||
|  | ||||
| import javax.annotation.Resource; | ||||
|  | ||||
| import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.FILE_PATH_EXISTS; | ||||
|  | ||||
| /** | ||||
|  * 文件 Service 实现类 | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| @Service | ||||
| public class SysFileServiceImpl implements SysFileService { | ||||
|  | ||||
|     @Resource | ||||
|     private SysFileMapper fileMapper; | ||||
|  | ||||
|     @Resource | ||||
|     private FileProperties fileProperties; | ||||
|  | ||||
|     @Override | ||||
|     public String createFile(String path, byte[] content) { | ||||
|         if (fileMapper.selectCountById(path) > 0) { | ||||
|             throw ServiceExceptionUtil.exception(FILE_PATH_EXISTS); | ||||
|         } | ||||
|         // 保存到数据库 | ||||
|         SysFileDO file = new SysFileDO(); | ||||
|         file.setId(path); | ||||
|         file.setContent(content); | ||||
|         fileMapper.insert(file); | ||||
|         // 拼接路径返回 | ||||
|         return fileProperties.getBasePath() + path; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public SysFileDO getFile(String path) { | ||||
|         return fileMapper.selectById(path); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -2,6 +2,7 @@ package cn.iocoder.dashboard.modules.system.service.dept; | ||||
|  | ||||
| import cn.iocoder.dashboard.common.pojo.PageResult; | ||||
| import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostCreateReqVO; | ||||
| import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostExportReqVO; | ||||
| import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostPageReqVO; | ||||
| import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostUpdateReqVO; | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysPostDO; | ||||
| @@ -18,7 +19,7 @@ import java.util.List; | ||||
| public interface SysPostService { | ||||
|  | ||||
|     /** | ||||
|      * 获得所有岗位列表 | ||||
|      * 获得符合条件的岗位列表 | ||||
|      * | ||||
|      * @param ids 岗位编号数组。如果为空,不进行筛选 | ||||
|      * @param statuses 状态数组。如果为空,不进行筛选 | ||||
| @@ -34,6 +35,14 @@ public interface SysPostService { | ||||
|      */ | ||||
|     PageResult<SysPostDO> pagePosts(SysPostPageReqVO reqVO); | ||||
|  | ||||
|     /** | ||||
|      * 获得岗位列表 | ||||
|      * | ||||
|      * @param reqVO 查询条件 | ||||
|      * @return 部门列表 | ||||
|      */ | ||||
|     List<SysPostDO> listPosts(SysPostExportReqVO reqVO); | ||||
|  | ||||
|     /** | ||||
|      * 获得岗位信息 | ||||
|      * | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.service.dept.impl; | ||||
| import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil; | ||||
| import cn.iocoder.dashboard.common.pojo.PageResult; | ||||
| import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostCreateReqVO; | ||||
| import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostExportReqVO; | ||||
| import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostPageReqVO; | ||||
| import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostUpdateReqVO; | ||||
| import cn.iocoder.dashboard.modules.system.convert.dept.SysPostConvert; | ||||
| @@ -38,6 +39,11 @@ public class SysPostServiceImpl implements SysPostService { | ||||
|         return SysPostConvert.INSTANCE.convertPage02(postMapper.selectList(reqVO)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<SysPostDO> listPosts(SysPostExportReqVO reqVO) { | ||||
|         return postMapper.selectList(reqVO); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public SysPostDO getPost(Long id) { | ||||
|         return postMapper.selectById(id); | ||||
|   | ||||
| @@ -1,11 +1,13 @@ | ||||
| package cn.iocoder.dashboard.util.servlet; | ||||
|  | ||||
| import cn.hutool.core.io.IoUtil; | ||||
| import cn.hutool.extra.servlet.ServletUtil; | ||||
| import com.alibaba.fastjson.JSON; | ||||
| import org.springframework.http.MediaType; | ||||
|  | ||||
|  | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| import java.io.IOException; | ||||
| import java.net.URLEncoder; | ||||
|  | ||||
| /** | ||||
|  * 客户端工具类 | ||||
| @@ -14,10 +16,32 @@ import javax.servlet.http.HttpServletResponse; | ||||
|  */ | ||||
| public class ServletUtils { | ||||
|  | ||||
|     /** | ||||
|      * 返回 JSON 字符串 | ||||
|      * | ||||
|      * @param response 响应 | ||||
|      * @param object 对象,会序列化成 JSON 字符串 | ||||
|      */ | ||||
|     @SuppressWarnings("deprecation") // 必须使用 APPLICATION_JSON_UTF8_VALUE,否则会乱码 | ||||
|     public static void writeJSON(HttpServletResponse response, Object object) { | ||||
|         String content = JSON.toJSONString(object); | ||||
|         ServletUtil.write(response, content, MediaType.APPLICATION_JSON_UTF8_VALUE); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 返回附件 | ||||
|      * | ||||
|      * @param response 响应 | ||||
|      * @param filename 文件名 | ||||
|      * @param content 附件内容 | ||||
|      * @throws IOException | ||||
|      */ | ||||
|     public static void writeAttachment(HttpServletResponse response, String filename, byte[] content) throws IOException { | ||||
|         // 设置 header 和 contentType | ||||
|         response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8")); | ||||
|         response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); | ||||
|         // 输出附件 | ||||
|         IoUtil.write(response.getOutputStream(), false, content); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -17,6 +17,12 @@ spring: | ||||
|     database: 0 | ||||
|     # 连接超时时间 | ||||
|     timeout: 10s | ||||
|   # Servlet 配置 | ||||
|   servlet: | ||||
|     # 文件上传相关配置项 | ||||
|     multipart: | ||||
|       max-file-size: 16MB # 单个文件大小 | ||||
|       max-request-size: 32MB # 设置总上传的文件大小 | ||||
|  | ||||
| # 芋道配置项,设置当前项目所有自定义的配置 | ||||
| yudao: | ||||
| @@ -38,6 +44,8 @@ yudao: | ||||
|     timeout: 5m | ||||
|     width: 160 | ||||
|     height: 60 | ||||
|   file: | ||||
|     base-path: http://127.0.0.1:1024/api/file/get/ | ||||
|  | ||||
| # MyBatis Plus 的配置项 | ||||
| mybatis-plus: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV