dujy-modules/dujy-demo/pom.xml
@@ -124,6 +124,13 @@ <artifactId>dujy-system</artifactId> </dependency> <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.4.3</version> </dependency> </dependencies> </project> dujy-modules/dujy-demo/src/main/java/org/dromara/demo/config/MinioConfig.java
New file @@ -0,0 +1,36 @@ package org.dromara.demo.config; import io.minio.MinioClient; import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; @Data @Configuration public class MinioConfig { @Value("${minio.endpoint}") private String endpoint; @Value("${minio.accessKey}") private String accessKey; @Value("${minio.secretKey}") private String secretKey; /** * 注入minio 客户端 * * @return */ @Bean public MinioClient minioClient() { return MinioClient.builder() .endpoint(endpoint) .credentials(accessKey, secretKey) .build(); } } dujy-modules/dujy-demo/src/main/java/org/dromara/demo/controller/FileUploadController.java
New file @@ -0,0 +1,40 @@ package org.dromara.demo.controller; import io.minio.Result; import org.dromara.common.core.domain.R; import org.dromara.demo.util.MinioUtil; import org.redisson.remote.ResponseEntry; 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.RequestPart; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.util.List; @RestController @RequestMapping("/file") public class FileUploadController { @Autowired private MinioUtil minioUtil; @PostMapping("/img") public R<String> uploadMinio(@RequestPart MultipartFile[] file) throws Exception { /*//拿到图片 MultipartFile封装接受的类 //拿到图片的名称 String filename = file.getOriginalFilename(); //拿到图片的 UUId + 图片类型 (解决图片重名的问题 ) String uuid = UUID.randomUUID().toString(); String imgType = filename.substring(filename.lastIndexOf(".")); //图片文件的新名称 xxx/uuid.jpg 图片拼接后的名 String fileName = uuid + imgType;*/ List<String> uploads = minioUtil.uploads(file); return R.ok(uploads.toString()); } } dujy-modules/dujy-demo/src/main/java/org/dromara/demo/controller/RsSceneryOperationDataController.java
New file @@ -0,0 +1,105 @@ package org.dromara.demo.controller; import java.util.List; import lombok.RequiredArgsConstructor; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.constraints.*; import cn.dev33.satoken.annotation.SaCheckPermission; import org.springframework.web.bind.annotation.*; import org.springframework.validation.annotation.Validated; import org.dromara.common.idempotent.annotation.RepeatSubmit; import org.dromara.common.log.annotation.Log; import org.dromara.common.web.core.BaseController; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.core.domain.R; import org.dromara.common.core.validate.AddGroup; import org.dromara.common.core.validate.EditGroup; import org.dromara.common.log.enums.BusinessType; import org.dromara.common.excel.utils.ExcelUtil; import org.dromara.demo.domain.vo.RsSceneryOperationDataVo; import org.dromara.demo.domain.bo.RsSceneryOperationDataBo; import org.dromara.demo.service.IRsSceneryOperationDataService; import org.dromara.common.mybatis.core.page.TableDataInfo; /** * 景区运行数据 * * @author Lion Li * @date 2024-02-27 */ @Validated @RequiredArgsConstructor @RestController @RequestMapping("/sc/sceneryOperationData") public class RsSceneryOperationDataController extends BaseController { private final IRsSceneryOperationDataService rsSceneryOperationDataService; /** * 查询景区运行数据列表 */ @SaCheckPermission("rs:sceneryOperationData:list") @GetMapping("/list") public TableDataInfo<RsSceneryOperationDataVo> list(RsSceneryOperationDataBo bo, PageQuery pageQuery) { return rsSceneryOperationDataService.queryPageList(bo, pageQuery); } /** * 导出景区运行数据列表 */ @SaCheckPermission("rs:sceneryOperationData:export") @Log(title = "景区运行数据", businessType = BusinessType.EXPORT) @PostMapping("/export") public void export(RsSceneryOperationDataBo bo, HttpServletResponse response) { List<RsSceneryOperationDataVo> list = rsSceneryOperationDataService.queryList(bo); ExcelUtil.exportExcel(list, "景区运行数据", RsSceneryOperationDataVo.class, response); } /** * 获取景区运行数据详细信息 * * @param id 主键 */ @SaCheckPermission("rs:sceneryOperationData:query") @GetMapping("/{id}") public R<RsSceneryOperationDataVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) { return R.ok(rsSceneryOperationDataService.queryById(id)); } /** * 新增景区运行数据 */ @SaCheckPermission("system:sceneryOperationData:add") @Log(title = "景区运行数据", businessType = BusinessType.INSERT) @RepeatSubmit() @PostMapping() public R<Void> add(@Validated(AddGroup.class) @RequestBody RsSceneryOperationDataBo bo) { return toAjax(rsSceneryOperationDataService.insertByBo(bo)); } /** * 修改景区运行数据 */ @SaCheckPermission("system:sceneryOperationData:edit") @Log(title = "景区运行数据", businessType = BusinessType.UPDATE) @RepeatSubmit() @PutMapping() public R<Void> edit(@Validated(EditGroup.class) @RequestBody RsSceneryOperationDataBo bo) { return toAjax(rsSceneryOperationDataService.updateByBo(bo)); } /** * 删除景区运行数据 * * @param ids 主键串 */ @SaCheckPermission("system:sceneryOperationData:remove") @Log(title = "景区运行数据", businessType = BusinessType.DELETE) @DeleteMapping("/{ids}") public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) { return toAjax(rsSceneryOperationDataService.deleteWithValidByIds(List.of(ids), true)); } } dujy-modules/dujy-demo/src/main/java/org/dromara/demo/domain/RsSceneryOperationData.java
New file @@ -0,0 +1,86 @@ package org.dromara.demo.domain; import org.dromara.common.mybatis.core.domain.BaseEntity; import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import lombok.EqualsAndHashCode; import java.io.Serial; /** * 景区运行数据对象 rs_scenery_operation_data * * @author Lion Li * @date 2024-02-27 */ @Data //@EqualsAndHashCode(callSuper = true) @TableName("rs_scenery_operation_data") public class RsSceneryOperationData { @Serial private static final long serialVersionUID = 1L; /** * id */ @TableId(value = "id") private Long id; /** * 周期年 */ private Long periodYear; /** * 周期月 */ private Long periodMonth; /** * 车流量 */ private Long carFlowNum; /** * 人流量 */ private Long personFlowNum; /** * 游客预约 */ private Long visitorSubNum; /** * 入园人数 */ private Long enterGardenNum; /** * 在岗警力 */ private Long onPolice; /** * 在岗警车 */ private Long onPaddyWagon; /** * 备勤警力 */ private Long standbyPolice; /** * 状态 1启用 0未启用 */ private Long status; /** * 景区id */ private Long scId; } dujy-modules/dujy-demo/src/main/java/org/dromara/demo/domain/bo/RsSceneryOperationDataBo.java
New file @@ -0,0 +1,96 @@ package org.dromara.demo.domain.bo; import org.dromara.demo.domain.RsSceneryOperationData; import org.dromara.common.mybatis.core.domain.BaseEntity; import org.dromara.common.core.validate.AddGroup; import org.dromara.common.core.validate.EditGroup; import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; import lombok.EqualsAndHashCode; import jakarta.validation.constraints.*; /** * 景区运行数据业务对象 rs_scenery_operation_data * * @author Lion Li * @date 2024-02-27 */ @Data @EqualsAndHashCode(callSuper = true) @AutoMapper(target = RsSceneryOperationData.class, reverseConvertGenerate = false) public class RsSceneryOperationDataBo extends BaseEntity { /** * id */ @NotNull(message = "id不能为空", groups = { EditGroup.class }) private Long id; /** * 周期年 */ @NotNull(message = "周期年不能为空", groups = { AddGroup.class, EditGroup.class }) private Long periodYear; /** * 周期月 */ @NotNull(message = "周期月不能为空", groups = { AddGroup.class, EditGroup.class }) private Long periodMonth; /** * 车流量 */ @NotNull(message = "车流量不能为空", groups = { AddGroup.class, EditGroup.class }) private Long carFlowNum; /** * 人流量 */ @NotNull(message = "人流量不能为空", groups = { AddGroup.class, EditGroup.class }) private Long personFlowNum; /** * 游客预约 */ @NotNull(message = "游客预约不能为空", groups = { AddGroup.class, EditGroup.class }) private Long visitorSubNum; /** * 入园人数 */ @NotNull(message = "入园人数不能为空", groups = { AddGroup.class, EditGroup.class }) private Long enterGardenNum; /** * 在岗警力 */ @NotNull(message = "在岗警力不能为空", groups = { AddGroup.class, EditGroup.class }) private Long onPolice; /** * 在岗警车 */ @NotNull(message = "在岗警车不能为空", groups = { AddGroup.class, EditGroup.class }) private Long onPaddyWagon; /** * 备勤警力 */ @NotNull(message = "备勤警力不能为空", groups = { AddGroup.class, EditGroup.class }) private Long standbyPolice; /** * 状态 1启用 0未启用 */ @NotNull(message = "状态 1启用 0未启用不能为空", groups = { AddGroup.class, EditGroup.class }) private Long status; /** * 景区id */ @NotNull(message = "景区id不能为空", groups = { AddGroup.class, EditGroup.class }) private Long scId; } dujy-modules/dujy-demo/src/main/java/org/dromara/demo/domain/vo/RsSceneryOperationDataVo.java
New file @@ -0,0 +1,104 @@ package org.dromara.demo.domain.vo; import org.dromara.demo.domain.RsSceneryOperationData; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; import org.dromara.common.excel.annotation.ExcelDictFormat; import org.dromara.common.excel.convert.ExcelDictConvert; import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; import java.io.Serial; import java.io.Serializable; import java.util.Date; /** * 景区运行数据视图对象 rs_scenery_operation_data * * @author Lion Li * @date 2024-02-27 */ @Data @ExcelIgnoreUnannotated @AutoMapper(target = RsSceneryOperationData.class) public class RsSceneryOperationDataVo implements Serializable { @Serial private static final long serialVersionUID = 1L; /** * id */ @ExcelProperty(value = "id") private Long id; /** * 周期年 */ @ExcelProperty(value = "周期年") private Long periodYear; /** * 周期月 */ @ExcelProperty(value = "周期月") private Long periodMonth; /** * 车流量 */ @ExcelProperty(value = "车流量") private Long carFlowNum; /** * 人流量 */ @ExcelProperty(value = "人流量") private Long personFlowNum; /** * 游客预约 */ @ExcelProperty(value = "游客预约") private Long visitorSubNum; /** * 入园人数 */ @ExcelProperty(value = "入园人数") private Long enterGardenNum; /** * 在岗警力 */ @ExcelProperty(value = "在岗警力") private Long onPolice; /** * 在岗警车 */ @ExcelProperty(value = "在岗警车") private Long onPaddyWagon; /** * 备勤警力 */ @ExcelProperty(value = "备勤警力") private Long standbyPolice; /** * 状态 1启用 0未启用 */ @ExcelProperty(value = "状态 1启用 0未启用") private Long status; /** * 景区id */ @ExcelProperty(value = "景区id") private Long scId; } dujy-modules/dujy-demo/src/main/java/org/dromara/demo/mapper/RsSceneryOperationDataMapper.java
New file @@ -0,0 +1,15 @@ package org.dromara.demo.mapper; import org.dromara.demo.domain.RsSceneryOperationData; import org.dromara.demo.domain.vo.RsSceneryOperationDataVo; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; /** * 景区运行数据Mapper接口 * * @author Lion Li * @date 2024-02-27 */ public interface RsSceneryOperationDataMapper extends BaseMapperPlus<RsSceneryOperationData, RsSceneryOperationDataVo> { } dujy-modules/dujy-demo/src/main/java/org/dromara/demo/service/IRsSceneryOperationDataService.java
New file @@ -0,0 +1,49 @@ package org.dromara.demo.service; import org.dromara.demo.domain.RsSceneryOperationData; import org.dromara.demo.domain.vo.RsSceneryOperationDataVo; import org.dromara.demo.domain.bo.RsSceneryOperationDataBo; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; import java.util.Collection; import java.util.List; /** * 景区运行数据Service接口 * * @author Lion Li * @date 2024-02-27 */ public interface IRsSceneryOperationDataService { /** * 查询景区运行数据 */ RsSceneryOperationDataVo queryById(Long id); /** * 查询景区运行数据列表 */ TableDataInfo<RsSceneryOperationDataVo> queryPageList(RsSceneryOperationDataBo bo, PageQuery pageQuery); /** * 查询景区运行数据列表 */ List<RsSceneryOperationDataVo> queryList(RsSceneryOperationDataBo bo); /** * 新增景区运行数据 */ Boolean insertByBo(RsSceneryOperationDataBo bo); /** * 修改景区运行数据 */ Boolean updateByBo(RsSceneryOperationDataBo bo); /** * 校验并批量删除景区运行数据信息 */ Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); } dujy-modules/dujy-demo/src/main/java/org/dromara/demo/service/impl/RsSceneryOperationDataServiceImpl.java
New file @@ -0,0 +1,119 @@ package org.dromara.demo.service.impl; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.dromara.demo.domain.bo.RsSceneryOperationDataBo; import org.dromara.demo.domain.vo.RsSceneryOperationDataVo; import org.dromara.demo.domain.RsSceneryOperationData; import org.dromara.demo.mapper.RsSceneryOperationDataMapper; import org.dromara.demo.service.IRsSceneryOperationDataService; import java.util.List; import java.util.Map; import java.util.Collection; /** * 景区运行数据Service业务层处理 * * @author Lion Li * @date 2024-02-27 */ @RequiredArgsConstructor @Service public class RsSceneryOperationDataServiceImpl implements IRsSceneryOperationDataService { private final RsSceneryOperationDataMapper baseMapper; /** * 查询景区运行数据 */ @Override public RsSceneryOperationDataVo queryById(Long id){ return baseMapper.selectVoById(id); } /** * 查询景区运行数据列表 */ @Override public TableDataInfo<RsSceneryOperationDataVo> queryPageList(RsSceneryOperationDataBo bo, PageQuery pageQuery) { LambdaQueryWrapper<RsSceneryOperationData> lqw = buildQueryWrapper(bo); Page<RsSceneryOperationDataVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); return TableDataInfo.build(result); } /** * 查询景区运行数据列表 */ @Override public List<RsSceneryOperationDataVo> queryList(RsSceneryOperationDataBo bo) { LambdaQueryWrapper<RsSceneryOperationData> lqw = buildQueryWrapper(bo); return baseMapper.selectVoList(lqw); } private LambdaQueryWrapper<RsSceneryOperationData> buildQueryWrapper(RsSceneryOperationDataBo bo) { Map<String, Object> params = bo.getParams(); LambdaQueryWrapper<RsSceneryOperationData> lqw = Wrappers.lambdaQuery(); lqw.eq(bo.getPeriodYear() != null, RsSceneryOperationData::getPeriodYear, bo.getPeriodYear()); lqw.eq(bo.getPeriodMonth() != null, RsSceneryOperationData::getPeriodMonth, bo.getPeriodMonth()); lqw.eq(bo.getCarFlowNum() != null, RsSceneryOperationData::getCarFlowNum, bo.getCarFlowNum()); lqw.eq(bo.getPersonFlowNum() != null, RsSceneryOperationData::getPersonFlowNum, bo.getPersonFlowNum()); lqw.eq(bo.getVisitorSubNum() != null, RsSceneryOperationData::getVisitorSubNum, bo.getVisitorSubNum()); lqw.eq(bo.getEnterGardenNum() != null, RsSceneryOperationData::getEnterGardenNum, bo.getEnterGardenNum()); lqw.eq(bo.getOnPolice() != null, RsSceneryOperationData::getOnPolice, bo.getOnPolice()); lqw.eq(bo.getOnPaddyWagon() != null, RsSceneryOperationData::getOnPaddyWagon, bo.getOnPaddyWagon()); lqw.eq(bo.getStandbyPolice() != null, RsSceneryOperationData::getStandbyPolice, bo.getStandbyPolice()); lqw.eq(bo.getStatus() != null, RsSceneryOperationData::getStatus, bo.getStatus()); lqw.eq(bo.getScId() != null, RsSceneryOperationData::getScId, bo.getScId()); return lqw; } /** * 新增景区运行数据 */ @Override public Boolean insertByBo(RsSceneryOperationDataBo bo) { RsSceneryOperationData add = MapstructUtils.convert(bo, RsSceneryOperationData.class); validEntityBeforeSave(add); boolean flag = baseMapper.insert(add) > 0; if (flag) { bo.setId(add.getId()); } return flag; } /** * 修改景区运行数据 */ @Override public Boolean updateByBo(RsSceneryOperationDataBo bo) { RsSceneryOperationData update = MapstructUtils.convert(bo, RsSceneryOperationData.class); validEntityBeforeSave(update); return baseMapper.updateById(update) > 0; } /** * 保存前的数据校验 */ private void validEntityBeforeSave(RsSceneryOperationData entity){ //TODO 做一些数据校验,如唯一约束 } /** * 批量删除景区运行数据 */ @Override public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { if(isValid){ //TODO 做一些业务上的校验,判断是否需要校验 } return baseMapper.deleteBatchIds(ids) > 0; } } dujy-modules/dujy-demo/src/main/java/org/dromara/demo/util/MinioUtil.java
New file @@ -0,0 +1,238 @@ package org.dromara.demo.util; import io.minio.*; import io.minio.messages.DeleteError; import io.minio.messages.DeleteObject; import io.minio.messages.Item; import org.apache.commons.compress.utils.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; /** * @description: minio工具类 * @version */ @Component public class MinioUtil { @Autowired private MinioClient minioClient; @Value("${minio.bucketName}") private String bucketName; /** * description: 判断bucket是否存在,不存在则创建 * * @return: void */ public void existBucket(String name) { try { boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build()); if (!exists) { minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build()); } } catch (Exception e) { e.printStackTrace(); } } /** * 创建存储bucket * @param bucketName 存储bucket名称 * @return Boolean */ public Boolean makeBucket(String bucketName) { try { minioClient.makeBucket(MakeBucketArgs.builder() .bucket(bucketName) .build()); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * 删除存储bucket * @param bucketName 存储bucket名称 * @return Boolean */ public Boolean removeBucket(String bucketName) { try { minioClient.removeBucket(RemoveBucketArgs.builder() .bucket(bucketName) .build()); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * description: 上传文件 * * @param multipartFile * @return: java.lang.String */ public List<String> uploads(MultipartFile[] multipartFile) { List<String> names = new ArrayList<>(multipartFile.length); for (MultipartFile file : multipartFile) { String fileName = file.getOriginalFilename(); String[] split = fileName.split("\\."); if (split.length > 1) { fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1]; } else { fileName = fileName + System.currentTimeMillis(); } InputStream in = null; try { in = file.getInputStream(); minioClient.putObject(PutObjectArgs.builder() .bucket(bucketName) .object(fileName) .stream(in, in.available(), -1) .contentType(file.getContentType()) .build() ); } catch (Exception e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } names.add(fileName); } return names; } /** * 上传单个文件 * @param multipartFile * @return */ public String upload(MultipartFile multipartFile) { String fileName = multipartFile.getOriginalFilename(); String[] split = fileName.split("\\."); if (split.length > 1) { fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1]; } else { fileName = fileName + System.currentTimeMillis(); } InputStream in = null; try { in = multipartFile.getInputStream(); minioClient.putObject(PutObjectArgs.builder() .bucket(bucketName) .object(fileName) .stream(in, in.available(), -1) .contentType(multipartFile.getContentType()) .build() ); } catch (Exception e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } return fileName; } /** * description: 下载文件 * * @param fileName * @return: org.springframework.http.ResponseEntity<byte [ ]> */ public ResponseEntity<byte[]> download(String fileName) { ResponseEntity<byte[]> responseEntity = null; InputStream in = null; ByteArrayOutputStream out = null; try { in = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build()); out = new ByteArrayOutputStream(); IOUtils.copy(in, out); //封装返回值 byte[] bytes = out.toByteArray(); HttpHeaders headers = new HttpHeaders(); try { headers.add("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } headers.setContentLength(bytes.length); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); headers.setAccessControlExposeHeaders(Arrays.asList("*")); responseEntity = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK); } catch (Exception e) { e.printStackTrace(); } finally { try { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (out != null) { out.close(); } } catch (IOException e) { e.printStackTrace(); } } return responseEntity; } /** * 查看文件对象 * @param bucketName 存储bucket名称 * @return 存储bucket内文件对象信息 */ /** * 批量删除文件对象 * @param bucketName 存储bucket名称 * @param objects 对象名称集合 */ public Iterable<Result<DeleteError>> removeObjects(String bucketName, List<String> objects) { List<DeleteObject> dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList()); Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build()); return results; } }