From a6e57e160f66ec4477c5e844994682386c5d6cda Mon Sep 17 00:00:00 2001 From: Elune <201507802@qq.com> Date: Fri, 20 Dec 2019 19:31:37 +0800 Subject: [PATCH] =?UTF-8?q?@Query=20=E5=8A=A0=E5=85=A5NOT=5FNULL=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=EF=BC=8C=E4=BC=98=E5=8C=96=E5=9B=BE=E5=BA=8A=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0=EF=BC=8C=E5=8A=A0=E5=85=A5=E5=9B=BE=E5=BA=8A=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/me/zhengjie/annotation/Query.java | 2 + .../me/zhengjie/utils/ElAdminConstant.java | 2 +- .../java/me/zhengjie/utils/QueryHelp.java | 3 + .../quartz/rest/QuartzJobController.java | 7 +- .../quartz/service/QuartzJobService.java | 5 +- .../service/impl/QuartzJobServiceImpl.java | 18 +-- .../src/main/resources/config/application.yml | 5 +- .../main/java/me/zhengjie/domain/Picture.java | 53 ++++++ .../repository/PictureRepository.java | 26 +++ .../me/zhengjie/rest/PictureController.java | 78 +++++++++ .../me/zhengjie/service/PictureService.java | 66 ++++++++ .../service/dto/PictureQueryCriteria.java | 26 +++ .../service/impl/PictureServiceImpl.java | 152 ++++++++++++++++++ 13 files changed, 427 insertions(+), 16 deletions(-) create mode 100644 eladmin-tools/src/main/java/me/zhengjie/domain/Picture.java create mode 100644 eladmin-tools/src/main/java/me/zhengjie/repository/PictureRepository.java create mode 100644 eladmin-tools/src/main/java/me/zhengjie/rest/PictureController.java create mode 100644 eladmin-tools/src/main/java/me/zhengjie/service/PictureService.java create mode 100644 eladmin-tools/src/main/java/me/zhengjie/service/dto/PictureQueryCriteria.java create mode 100644 eladmin-tools/src/main/java/me/zhengjie/service/impl/PictureServiceImpl.java diff --git a/eladmin-common/src/main/java/me/zhengjie/annotation/Query.java b/eladmin-common/src/main/java/me/zhengjie/annotation/Query.java index e659a9bb..6a2d866f 100644 --- a/eladmin-common/src/main/java/me/zhengjie/annotation/Query.java +++ b/eladmin-common/src/main/java/me/zhengjie/annotation/Query.java @@ -54,6 +54,8 @@ public @interface Query { ,NOT_EQUAL // between ,BETWEEN + // 不为空 + ,NOT_NULL } /** diff --git a/eladmin-common/src/main/java/me/zhengjie/utils/ElAdminConstant.java b/eladmin-common/src/main/java/me/zhengjie/utils/ElAdminConstant.java index 47199dba..22f37a36 100644 --- a/eladmin-common/src/main/java/me/zhengjie/utils/ElAdminConstant.java +++ b/eladmin-common/src/main/java/me/zhengjie/utils/ElAdminConstant.java @@ -20,6 +20,6 @@ public class ElAdminConstant { * 常用接口 */ public static class Url{ - public static final String SM_MS_URL = "https://sm.ms/api/upload"; + public static final String SM_MS_URL = "https://sm.ms/api"; } } diff --git a/eladmin-common/src/main/java/me/zhengjie/utils/QueryHelp.java b/eladmin-common/src/main/java/me/zhengjie/utils/QueryHelp.java index 3a93ce4e..c42a514e 100644 --- a/eladmin-common/src/main/java/me/zhengjie/utils/QueryHelp.java +++ b/eladmin-common/src/main/java/me/zhengjie/utils/QueryHelp.java @@ -110,6 +110,9 @@ public class QueryHelp { case NOT_EQUAL: list.add(cb.notEqual(getExpression(attributeName,join,root), val)); break; + case NOT_NULL: + list.add(cb.isNotNull(getExpression(attributeName,join,root))); + break; case BETWEEN: List between = new ArrayList<>((List)val); list.add(cb.between(getExpression(attributeName, join, root).as((Class) between.get(0).getClass()), diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/rest/QuartzJobController.java b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/rest/QuartzJobController.java index afb79f14..4b487366 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/rest/QuartzJobController.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/rest/QuartzJobController.java @@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.util.Set; /** * @author Zheng Jie @@ -107,10 +108,10 @@ public class QuartzJobController { @Log("删除定时任务") @ApiOperation("删除定时任务") - @DeleteMapping(value = "/{id}") + @DeleteMapping @PreAuthorize("@el.check('timing:del')") - public ResponseEntity delete(@PathVariable Long id){ - quartzJobService.delete(quartzJobService.findById(id)); + public ResponseEntity delete(@RequestBody Set ids){ + quartzJobService.delete(ids); return new ResponseEntity<>(HttpStatus.OK); } } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/QuartzJobService.java b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/QuartzJobService.java index 63805782..a8c83881 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/QuartzJobService.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/QuartzJobService.java @@ -8,6 +8,7 @@ import org.springframework.data.domain.Pageable; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; +import java.util.Set; /** * @author Zheng Jie @@ -60,9 +61,9 @@ public interface QuartzJobService { /** * 删除任务 - * @param quartzJob / + * @param ids / */ - void delete(QuartzJob quartzJob); + void delete(Set ids); /** * 根据ID查询 diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/impl/QuartzJobServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/impl/QuartzJobServiceImpl.java index 0f111e80..c331468a 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/impl/QuartzJobServiceImpl.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/impl/QuartzJobServiceImpl.java @@ -23,10 +23,7 @@ import org.springframework.transaction.annotation.Transactional; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** * @author Zheng Jie @@ -131,12 +128,15 @@ public class QuartzJobServiceImpl implements QuartzJobService { @Override @CacheEvict(allEntries = true) @Transactional(rollbackFor = Exception.class) - public void delete(QuartzJob quartzJob) { - if(quartzJob.getId().equals(1L)){ - throw new BadRequestException("该任务不可操作"); + public void delete(Set ids) { + for (Long id : ids) { + if(id.equals(1L)){ + throw new BadRequestException("更新访客记录不可删除,你可以在后台代码中取消该限制"); + } + QuartzJob quartzJob = findById(id); + quartzManage.deleteJob(quartzJob); + quartzJobRepository.delete(quartzJob); } - quartzManage.deleteJob(quartzJob); - quartzJobRepository.delete(quartzJob); } @Override diff --git a/eladmin-system/src/main/resources/config/application.yml b/eladmin-system/src/main/resources/config/application.yml index cf7bf659..83b764db 100644 --- a/eladmin-system/src/main/resources/config/application.yml +++ b/eladmin-system/src/main/resources/config/application.yml @@ -55,4 +55,7 @@ loginCode: #密码加密传输,前端公钥加密,后端私钥解密 rsa: - private_key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A== \ No newline at end of file + private_key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A== + +smms: + token: 1oOP3ykFDI0K6ifmtvU7c8Y1eTWZSlyl \ No newline at end of file diff --git a/eladmin-tools/src/main/java/me/zhengjie/domain/Picture.java b/eladmin-tools/src/main/java/me/zhengjie/domain/Picture.java new file mode 100644 index 00000000..b829c9a0 --- /dev/null +++ b/eladmin-tools/src/main/java/me/zhengjie/domain/Picture.java @@ -0,0 +1,53 @@ +package me.zhengjie.domain; + +import lombok.Data; +import org.hibernate.annotations.CreationTimestamp; + +import javax.persistence.*; +import java.io.Serializable; +import java.sql.Timestamp; + +/** + * sm.ms图床 + * + * @author Zheng Jie + * @date 2018-12-27 + */ +@Data +@Entity +@Table(name = "picture") +public class Picture implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String filename; + + private String url; + + private String size; + + private String height; + + private String width; + + @Column(name = "delete_url") + private String delete; + + private String username; + + @CreationTimestamp + @Column(name = "create_time") + private Timestamp createTime; + + /** 用于检测文件是否重复 */ + private String md5Code; + + @Override + public String toString() { + return "Picture{" + + "filename='" + filename + '\'' + + '}'; + } +} diff --git a/eladmin-tools/src/main/java/me/zhengjie/repository/PictureRepository.java b/eladmin-tools/src/main/java/me/zhengjie/repository/PictureRepository.java new file mode 100644 index 00000000..62fe84b6 --- /dev/null +++ b/eladmin-tools/src/main/java/me/zhengjie/repository/PictureRepository.java @@ -0,0 +1,26 @@ +package me.zhengjie.repository; + +import me.zhengjie.domain.Picture; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** + * @author Zheng Jie + * @date 2018-12-27 + */ +public interface PictureRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据 Mds 值查询文件 + * @param code 值 + * @return / + */ + Picture findByMd5Code(String code); + + /** + * 根据连接地址查询 + * @param url / + * @return / + */ + boolean existsByUrl(String url); +} diff --git a/eladmin-tools/src/main/java/me/zhengjie/rest/PictureController.java b/eladmin-tools/src/main/java/me/zhengjie/rest/PictureController.java new file mode 100644 index 00000000..6f87bc94 --- /dev/null +++ b/eladmin-tools/src/main/java/me/zhengjie/rest/PictureController.java @@ -0,0 +1,78 @@ +package me.zhengjie.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import me.zhengjie.aop.log.Log; +import me.zhengjie.domain.Picture; +import me.zhengjie.service.PictureService; +import me.zhengjie.service.dto.PictureQueryCriteria; +import me.zhengjie.utils.SecurityUtils; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * @author 郑杰 + * @date 2018/09/20 14:13:32 + */ +@RestController +@RequestMapping("/api/pictures") +@Api(tags = "工具:免费图床管理") +public class PictureController { + + private final PictureService pictureService; + + public PictureController(PictureService pictureService) { + this.pictureService = pictureService; + } + + @Log("查询图片") + @PreAuthorize("@el.check('pictures:list')") + @GetMapping + @ApiOperation("查询图片") + public ResponseEntity getRoles(PictureQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(pictureService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @Log("导出数据") + @ApiOperation("导出数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('pictures:list')") + public void download(HttpServletResponse response, PictureQueryCriteria criteria) throws IOException { + pictureService.download(pictureService.queryAll(criteria), response); + } + + @Log("上传图片") + @PreAuthorize("@el.check('pictures:add')") + @PostMapping + @ApiOperation("上传图片") + public ResponseEntity upload(@RequestParam MultipartFile file){ + String userName = SecurityUtils.getUsername(); + Picture picture = pictureService.upload(file,userName); + return new ResponseEntity<>(picture,HttpStatus.OK); + } + + @Log("同步图床数据") + @ApiOperation("同步图床数据") + @PostMapping(value = "/synchronize") + public ResponseEntity synchronize(){ + pictureService.synchronize(); + return new ResponseEntity<>(HttpStatus.OK); + } + + @Log("多选删除图片") + @ApiOperation("多选删除图片") + @PreAuthorize("@el.check('pictures:del')") + @DeleteMapping + public ResponseEntity deleteAll(@RequestBody Long[] ids) { + pictureService.deleteAll(ids); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/eladmin-tools/src/main/java/me/zhengjie/service/PictureService.java b/eladmin-tools/src/main/java/me/zhengjie/service/PictureService.java new file mode 100644 index 00000000..bf43709d --- /dev/null +++ b/eladmin-tools/src/main/java/me/zhengjie/service/PictureService.java @@ -0,0 +1,66 @@ +package me.zhengjie.service; + +import me.zhengjie.domain.Picture; +import me.zhengjie.service.dto.PictureQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +/** + * @author Zheng Jie + * @date 2018-12-27 + */ +public interface PictureService { + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAll(PictureQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部数据 + * @param criteria 条件 + * @return / + */ + List queryAll(PictureQueryCriteria criteria); + + /** + * 上传文件 + * @param file / + * @param username / + * @return / + */ + Picture upload(MultipartFile file, String username); + + /** + * 根据ID查询 + * @param id / + * @return / + */ + Picture findById(Long id); + + /** + * 多选删除 + * @param ids / + */ + void deleteAll(Long[] ids); + + /** + * 导出 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; + + /** + * 同步数据 + */ + void synchronize(); +} diff --git a/eladmin-tools/src/main/java/me/zhengjie/service/dto/PictureQueryCriteria.java b/eladmin-tools/src/main/java/me/zhengjie/service/dto/PictureQueryCriteria.java new file mode 100644 index 00000000..44b8363e --- /dev/null +++ b/eladmin-tools/src/main/java/me/zhengjie/service/dto/PictureQueryCriteria.java @@ -0,0 +1,26 @@ +package me.zhengjie.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; + +import java.sql.Timestamp; +import java.util.List; + +/** + * sm.ms图床 + * + * @author Zheng Jie + * @date 2019-6-4 09:52:09 + */ +@Data +public class PictureQueryCriteria{ + + @Query(type = Query.Type.INNER_LIKE) + private String filename; + + @Query(type = Query.Type.INNER_LIKE) + private String username; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/eladmin-tools/src/main/java/me/zhengjie/service/impl/PictureServiceImpl.java b/eladmin-tools/src/main/java/me/zhengjie/service/impl/PictureServiceImpl.java new file mode 100644 index 00000000..8d0e2b43 --- /dev/null +++ b/eladmin-tools/src/main/java/me/zhengjie/service/impl/PictureServiceImpl.java @@ -0,0 +1,152 @@ +package me.zhengjie.service.impl; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.domain.Picture; +import me.zhengjie.repository.PictureRepository; +import me.zhengjie.service.PictureService; +import me.zhengjie.service.dto.PictureQueryCriteria; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.utils.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.IOException; +import java.util.*; + +/** + * @author Zheng Jie + * @date 2018-12-27 + */ +@Slf4j +@Service(value = "pictureService") +@CacheConfig(cacheNames = "picture") +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class PictureServiceImpl implements PictureService { + + @Value("${smms.token}") + private String token; + + private final PictureRepository pictureRepository; + + private static final String SUCCESS = "success"; + + private static final String CODE = "code"; + + private static final String MSG = "message"; + + public PictureServiceImpl(PictureRepository pictureRepository) { + this.pictureRepository = pictureRepository; + } + + @Override + public Object queryAll(PictureQueryCriteria criteria, Pageable pageable){ + return PageUtil.toPage(pictureRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable)); + } + + @Override + public List queryAll(PictureQueryCriteria criteria) { + return pictureRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)); + } + + @Override + @Transactional(rollbackFor = Throwable.class) + public Picture upload(MultipartFile multipartFile, String username) { + File file = FileUtil.toFile(multipartFile); + // 验证是否重复上传 + Picture picture = pictureRepository.findByMd5Code(FileUtil.getMd5(file)); + if(picture != null){ + return picture; + } + HashMap paramMap = new HashMap<>(1); + paramMap.put("smfile", file); + // 上传文件 + String result= HttpRequest.post(ElAdminConstant.Url.SM_MS_URL + "/v2/upload") + .header("Authorization", token) + .form(paramMap) + .timeout(20000) + .execute().body(); + JSONObject jsonObject = JSONUtil.parseObj(result); + if(!jsonObject.get(CODE).toString().equals(SUCCESS)){ + throw new BadRequestException(TranslatorUtil.translate(jsonObject.get(MSG).toString())); + } + picture = JSON.parseObject(jsonObject.get("data").toString(), Picture.class); + picture.setSize(FileUtil.getSize(Integer.parseInt(picture.getSize()))); + picture.setUsername(username); + picture.setMd5Code(FileUtil.getMd5(file)); + picture.setFilename(FileUtil.getFileNameNoEx(multipartFile.getOriginalFilename())+"."+FileUtil.getExtensionName(multipartFile.getOriginalFilename())); + pictureRepository.save(picture); + //删除临时文件 + FileUtil.del(file); + return picture; + + } + + @Override + public Picture findById(Long id) { + Picture picture = pictureRepository.findById(id).orElseGet(Picture::new); + ValidationUtil.isNull(picture.getId(),"Picture","id",id); + return picture; + } + + @Override + public void deleteAll(Long[] ids) { + for (Long id : ids) { + Picture picture = findById(id); + try { + HttpUtil.get(picture.getDelete()); + pictureRepository.delete(picture); + } catch(Exception e){ + pictureRepository.delete(picture); + } + } + } + + @Override + public void synchronize() { + //链式构建请求 + String result = HttpRequest.get(ElAdminConstant.Url.SM_MS_URL + "/v2/upload_history") + //头信息,多个头信息多次调用此方法即可 + .header("Authorization", token) + .timeout(20000) + .execute().body(); + JSONObject jsonObject = JSONUtil.parseObj(result); + List pictures = JSON.parseArray(jsonObject.get("data").toString(), Picture.class); + for (Picture picture : pictures) { + if(!pictureRepository.existsByUrl(picture.getUrl())){ + picture.setSize(FileUtil.getSize(Integer.parseInt(picture.getSize()))); + picture.setUsername("System Sync"); + picture.setMd5Code(""); + pictureRepository.save(picture); + } + } + } + + @Override + public void download(List queryAll, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (Picture picture : queryAll) { + Map map = new LinkedHashMap<>(); + map.put("文件名", picture.getFilename()); + map.put("图片地址", picture.getUrl()); + map.put("文件大小", picture.getSize()); + map.put("操作人", picture.getUsername()); + map.put("高度", picture.getHeight()); + map.put("宽度", picture.getWidth()); + map.put("删除地址", picture.getDelete()); + map.put("创建日期", picture.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } +}