diff --git a/src/main/java/com/ld/poetry/config/PoetryApplicationRunner.java b/src/main/java/com/ld/poetry/config/PoetryApplicationRunner.java index abe1113..9829801 100644 --- a/src/main/java/com/ld/poetry/config/PoetryApplicationRunner.java +++ b/src/main/java/com/ld/poetry/config/PoetryApplicationRunner.java @@ -12,6 +12,7 @@ import com.ld.poetry.utils.CommonQuery; import com.ld.poetry.utils.PoetryCache; import com.ld.poetry.utils.PoetryEnum; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; @@ -28,6 +29,9 @@ import java.util.stream.Collectors; @Component public class PoetryApplicationRunner implements ApplicationRunner { + @Value("${store.type}") + private String defaultType; + @Autowired private WebInfoMapper webInfoMapper; @@ -51,6 +55,7 @@ public class PoetryApplicationRunner implements ApplicationRunner { LambdaQueryChainWrapper wrapper = new LambdaQueryChainWrapper<>(webInfoMapper); List list = wrapper.list(); if (!CollectionUtils.isEmpty(list)) { + list.get(0).setDefaultStoreType(defaultType); PoetryCache.put(CommonConst.WEB_INFO, list.get(0)); } diff --git a/src/main/java/com/ld/poetry/config/PoetryFilter.java b/src/main/java/com/ld/poetry/config/PoetryFilter.java index b32ec88..8ec5a74 100644 --- a/src/main/java/com/ld/poetry/config/PoetryFilter.java +++ b/src/main/java/com/ld/poetry/config/PoetryFilter.java @@ -1,7 +1,10 @@ package com.ld.poetry.config; +import com.alibaba.fastjson.JSON; +import com.ld.poetry.utils.CodeMsg; import com.ld.poetry.utils.CommonQuery; import com.ld.poetry.utils.PoetryUtil; +import com.ld.poetry.utils.storage.FileFilter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; @@ -18,11 +21,23 @@ public class PoetryFilter extends OncePerRequestFilter { @Autowired private CommonQuery commonQuery; + @Autowired + private FileFilter fileFilter; + @Override protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException { - try { - commonQuery.saveHistory(PoetryUtil.getIpAddr(httpServletRequest)); - } catch (Exception e) { + if (!"OPTIONS".equals(httpServletRequest.getMethod())) { + try { + commonQuery.saveHistory(PoetryUtil.getIpAddr(httpServletRequest)); + } catch (Exception e) { + } + + if (fileFilter.doFilterFile(httpServletRequest, httpServletResponse)) { + httpServletResponse.setHeader("Access-Control-Allow-Origin", "*"); + httpServletResponse.setContentType("application/json;charset=UTF-8"); + httpServletResponse.getWriter().write(JSON.toJSONString(PoetryResult.fail(CodeMsg.PARAMETER_ERROR.getCode(), CodeMsg.PARAMETER_ERROR.getMsg()))); + return; + } } filterChain.doFilter(httpServletRequest, httpServletResponse); diff --git a/src/main/java/com/ld/poetry/config/SaveCheckAspect.java b/src/main/java/com/ld/poetry/config/SaveCheckAspect.java index fcd7224..86b3c7e 100644 --- a/src/main/java/com/ld/poetry/config/SaveCheckAspect.java +++ b/src/main/java/com/ld/poetry/config/SaveCheckAspect.java @@ -40,7 +40,7 @@ public class SaveCheckAspect { PoetryCache.put(CommonConst.SAVE_COUNT_USER_ID + user.getId().toString(), atomicInteger, CommonConst.SAVE_EXPIRE); } int userIdCount = atomicInteger.getAndIncrement(); - if (userIdCount > CommonConst.SAVE_MAX_COUNT) { + if (userIdCount >= CommonConst.SAVE_MAX_COUNT) { log.info("用户保存超限:" + user.getId().toString() + ",次数:" + userIdCount); flag = true; } diff --git a/src/main/java/com/ld/poetry/controller/ArticleController.java b/src/main/java/com/ld/poetry/controller/ArticleController.java index 780beb9..54522bc 100644 --- a/src/main/java/com/ld/poetry/controller/ArticleController.java +++ b/src/main/java/com/ld/poetry/controller/ArticleController.java @@ -76,12 +76,10 @@ public class ArticleController { /** * 查询文章 - *

- * flag = true:查询可见的文章 */ @GetMapping("/getArticleById") - public PoetryResult getArticleById(@RequestParam("id") Integer id, @RequestParam("flag") Boolean flag, @RequestParam(value = "password", required = false) String password) { - return articleService.getArticleById(id, flag, password); + public PoetryResult getArticleById(@RequestParam("id") Integer id, @RequestParam(value = "password", required = false) String password) { + return articleService.getArticleById(id, password); } } diff --git a/src/main/java/com/ld/poetry/controller/QiniuController.java b/src/main/java/com/ld/poetry/controller/QiniuController.java index 2846c05..cba0c06 100644 --- a/src/main/java/com/ld/poetry/controller/QiniuController.java +++ b/src/main/java/com/ld/poetry/controller/QiniuController.java @@ -3,8 +3,9 @@ package com.ld.poetry.controller; import com.ld.poetry.config.LoginCheck; import com.ld.poetry.config.PoetryResult; import com.ld.poetry.config.SaveCheck; -import com.ld.poetry.utils.QiniuUtil; +import com.ld.poetry.utils.storage.QiniuUtil; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -15,13 +16,14 @@ import org.springframework.web.bind.annotation.RestController; */ @RestController @RequestMapping("/qiniu") +@ConditionalOnBean(QiniuUtil.class) public class QiniuController { @Autowired private QiniuUtil qiniuUtil; /** - * 获取覆盖凭证 + * 获取覆盖凭证,用于七牛云 */ @GetMapping("/getUpToken") @LoginCheck diff --git a/src/main/java/com/ld/poetry/controller/ResourceController.java b/src/main/java/com/ld/poetry/controller/ResourceController.java index f2f7f5a..58103a0 100644 --- a/src/main/java/com/ld/poetry/controller/ResourceController.java +++ b/src/main/java/com/ld/poetry/controller/ResourceController.java @@ -6,21 +6,18 @@ import com.ld.poetry.config.LoginCheck; import com.ld.poetry.config.PoetryResult; import com.ld.poetry.entity.Resource; import com.ld.poetry.service.ResourceService; -import com.ld.poetry.utils.CommonConst; -import com.ld.poetry.utils.PoetryEnum; -import com.ld.poetry.utils.PoetryUtil; -import com.ld.poetry.utils.QiniuUtil; +import com.ld.poetry.utils.storage.StoreService; +import com.ld.poetry.utils.*; +import com.ld.poetry.utils.storage.FileStorageService; import com.ld.poetry.vo.BaseRequestVO; +import com.ld.poetry.vo.FileVO; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; -import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; /** @@ -35,14 +32,11 @@ import java.util.stream.Collectors; @RequestMapping("/resource") public class ResourceController { - @Value("${qiniu.downloadUrl}") - private String downloadUrl; - @Autowired private ResourceService resourceService; @Autowired - private QiniuUtil qiniuUtil; + private FileStorageService fileStorageService; /** * 保存 @@ -58,44 +52,50 @@ public class ResourceController { re.setType(resource.getType()); re.setSize(resource.getSize()); re.setMimeType(resource.getMimeType()); + re.setStoreType(resource.getStoreType()); re.setUserId(PoetryUtil.getUserId()); resourceService.save(re); return PoetryResult.success(); } + /** + * 上传文件 + */ + @PostMapping("/upload") + @LoginCheck + public PoetryResult upload(@RequestParam("file") MultipartFile file, FileVO fileVO) { + if (file == null || !StringUtils.hasText(fileVO.getType()) || !StringUtils.hasText(fileVO.getRelativePath())) { + return PoetryResult.fail("文件和资源类型和资源路径不能为空!"); + } + + fileVO.setFile(file); + StoreService storeService = fileStorageService.getFileStorage(fileVO.getStoreType()); + FileVO result = storeService.saveFile(fileVO); + + Resource re = new Resource(); + re.setPath(result.getVisitPath()); + re.setType(fileVO.getType()); + re.setSize(Integer.valueOf(Long.toString(file.getSize()))); + re.setMimeType(file.getContentType()); + re.setStoreType(fileVO.getStoreType()); + re.setUserId(PoetryUtil.getUserId()); + resourceService.save(re); + return PoetryResult.success(result.getVisitPath()); + } + /** * 删除 */ @PostMapping("/deleteResource") @LoginCheck(0) public PoetryResult deleteResource(@RequestParam("path") String path) { - qiniuUtil.deleteFile(Collections.singletonList(path.replace(downloadUrl, ""))); - resourceService.lambdaUpdate().eq(Resource::getPath, path).remove(); - return PoetryResult.success(); - } - - @GetMapping("/getResourceInfo") - @LoginCheck(0) - public PoetryResult getResourceInfo() { - List resources = resourceService.lambdaQuery() - .select(Resource::getId, Resource::getPath) - .like(Resource::getPath, downloadUrl) - .isNull(Resource::getSize) - .list(); - if (!CollectionUtils.isEmpty(resources)) { - Map resourceMap = resources.stream().collect(Collectors.toMap(resource -> resource.getPath().replace(downloadUrl, ""), Resource::getId)); - Map> fileInfo = qiniuUtil.getFileInfo(new ArrayList<>(resourceMap.keySet())); - if (!CollectionUtils.isEmpty(fileInfo)) { - List collect = fileInfo.entrySet().stream().map(entry -> { - Resource resource = new Resource(); - resource.setId(resourceMap.get(entry.getKey())); - resource.setSize(Integer.valueOf(entry.getValue().get("size"))); - resource.setMimeType(entry.getValue().get("mimeType")); - return resource; - }).collect(Collectors.toList()); - resourceService.updateBatchById(collect); - } + Resource resource = resourceService.lambdaQuery().select(Resource::getStoreType).eq(Resource::getPath, path).one(); + if (resource == null) { + return PoetryResult.fail("文件不存在:" + path); } + + StoreService storeService = fileStorageService.getFileStorageByStoreType(resource.getStoreType()); + storeService.deleteFile(Collections.singletonList(path)); return PoetryResult.success(); } diff --git a/src/main/java/com/ld/poetry/controller/UserController.java b/src/main/java/com/ld/poetry/controller/UserController.java index 175ba38..032018a 100644 --- a/src/main/java/com/ld/poetry/controller/UserController.java +++ b/src/main/java/com/ld/poetry/controller/UserController.java @@ -151,5 +151,18 @@ public class UserController { public PoetryResult> getUserByUsername(@RequestParam("username") String username) { return userService.getUserByUsername(username); } + + /** + * 订阅/取消订阅专栏(标签) + *

+ * flag = true:订阅 + * flag = false:取消订阅 + */ + @GetMapping("/subscribe") + @LoginCheck + public PoetryResult subscribe(@RequestParam("labelId") Integer labelId, @RequestParam("flag") Boolean flag) { + PoetryCache.remove(CommonConst.USER_CACHE + PoetryUtil.getUserId().toString()); + return userService.subscribe(labelId, flag); + } } diff --git a/src/main/java/com/ld/poetry/controller/WebInfoController.java b/src/main/java/com/ld/poetry/controller/WebInfoController.java index 912e53c..56b8228 100644 --- a/src/main/java/com/ld/poetry/controller/WebInfoController.java +++ b/src/main/java/com/ld/poetry/controller/WebInfoController.java @@ -17,6 +17,7 @@ import com.ld.poetry.vo.BaseRequestVO; import com.ld.poetry.vo.ResourcePathVO; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; @@ -40,6 +41,9 @@ import java.util.stream.Collectors; @RequestMapping("/webInfo") public class WebInfoController { + @Value("${store.type}") + private String defaultType; + @Autowired private WebInfoService webInfoService; @@ -73,6 +77,7 @@ public class WebInfoController { LambdaQueryChainWrapper wrapper = new LambdaQueryChainWrapper<>(webInfoService.getBaseMapper()); List list = wrapper.list(); if (!CollectionUtils.isEmpty(list)) { + list.get(0).setDefaultStoreType(defaultType); PoetryCache.put(CommonConst.WEB_INFO, list.get(0)); } return PoetryResult.success(); @@ -228,16 +233,39 @@ public class WebInfoController { return PoetryResult.fail("信息不全!"); } ResourcePath friend = new ResourcePath(); + friend.setClassify(CommonConst.DEFAULT_FRIEND); friend.setTitle(resourcePathVO.getTitle()); friend.setIntroduction(resourcePathVO.getIntroduction()); friend.setCover(resourcePathVO.getCover()); friend.setUrl(resourcePathVO.getUrl()); + friend.setRemark(PoetryUtil.getUserId().toString()); friend.setType(CommonConst.RESOURCE_PATH_TYPE_FRIEND); friend.setStatus(Boolean.FALSE); resourcePathMapper.insert(friend); return PoetryResult.success(); } + /** + * 查询友链 + */ + @GetMapping("/listFriend") + public PoetryResult>> listFriend() { + LambdaQueryChainWrapper wrapper = new LambdaQueryChainWrapper<>(resourcePathMapper); + List resourcePaths = wrapper.eq(ResourcePath::getType, CommonConst.RESOURCE_PATH_TYPE_FRIEND) + .eq(ResourcePath::getStatus, Boolean.TRUE) + .orderByAsc(ResourcePath::getCreateTime) + .list(); + Map> collect = new HashMap<>(); + if (!CollectionUtils.isEmpty(resourcePaths)) { + collect = resourcePaths.stream().map(rp -> { + ResourcePathVO resourcePathVO = new ResourcePathVO(); + BeanUtils.copyProperties(rp, resourcePathVO); + return resourcePathVO; + }).collect(Collectors.groupingBy(ResourcePathVO::getClassify)); + } + return PoetryResult.success(collect); + } + /** * 删除 diff --git a/src/main/java/com/ld/poetry/entity/Article.java b/src/main/java/com/ld/poetry/entity/Article.java index e23dc59..e27d3fe 100644 --- a/src/main/java/com/ld/poetry/entity/Article.java +++ b/src/main/java/com/ld/poetry/entity/Article.java @@ -70,6 +70,12 @@ public class Article implements Serializable { @TableField("password") private String password; + /** + * 提示 + */ + @TableField("tips") + private String tips; + /** * 是否可见[0:否,1:是] */ diff --git a/src/main/java/com/ld/poetry/entity/Resource.java b/src/main/java/com/ld/poetry/entity/Resource.java index b93af72..f049a64 100644 --- a/src/main/java/com/ld/poetry/entity/Resource.java +++ b/src/main/java/com/ld/poetry/entity/Resource.java @@ -49,6 +49,12 @@ public class Resource implements Serializable { @TableField("status") private Boolean status; + /** + * 存储平台 + */ + @TableField("store_type") + private String storeType; + /** * 资源路径 */ diff --git a/src/main/java/com/ld/poetry/entity/User.java b/src/main/java/com/ld/poetry/entity/User.java index bc15449..55ded39 100644 --- a/src/main/java/com/ld/poetry/entity/User.java +++ b/src/main/java/com/ld/poetry/entity/User.java @@ -82,6 +82,12 @@ public class User implements Serializable { @TableField("admire") private String admire; + /** + * 订阅 + */ + @TableField("subscribe") + private String subscribe; + /** * 简介 */ diff --git a/src/main/java/com/ld/poetry/entity/WebInfo.java b/src/main/java/com/ld/poetry/entity/WebInfo.java index 1decfd8..521cdc4 100644 --- a/src/main/java/com/ld/poetry/entity/WebInfo.java +++ b/src/main/java/com/ld/poetry/entity/WebInfo.java @@ -101,4 +101,7 @@ public class WebInfo implements Serializable { @TableField(exist = false) private String historyDayCount; + + @TableField(exist = false) + private String defaultStoreType; } diff --git a/src/main/java/com/ld/poetry/service/ArticleService.java b/src/main/java/com/ld/poetry/service/ArticleService.java index 2b3d219..778896e 100644 --- a/src/main/java/com/ld/poetry/service/ArticleService.java +++ b/src/main/java/com/ld/poetry/service/ArticleService.java @@ -25,7 +25,7 @@ public interface ArticleService extends IService

{ PoetryResult listArticle(BaseRequestVO baseRequestVO); - PoetryResult getArticleById(Integer id, Boolean flag, String password); + PoetryResult getArticleById(Integer id, String password); PoetryResult listAdminArticle(BaseRequestVO baseRequestVO, Boolean isBoss); diff --git a/src/main/java/com/ld/poetry/service/UserService.java b/src/main/java/com/ld/poetry/service/UserService.java index a002949..6c7420d 100644 --- a/src/main/java/com/ld/poetry/service/UserService.java +++ b/src/main/java/com/ld/poetry/service/UserService.java @@ -49,4 +49,6 @@ public interface UserService extends IService { PoetryResult> getUserByUsername(String username); PoetryResult token(String userToken); + + PoetryResult subscribe(Integer labelId, Boolean flag); } diff --git a/src/main/java/com/ld/poetry/service/impl/ArticleServiceImpl.java b/src/main/java/com/ld/poetry/service/impl/ArticleServiceImpl.java index 2eb3e90..2f84c02 100644 --- a/src/main/java/com/ld/poetry/service/impl/ArticleServiceImpl.java +++ b/src/main/java/com/ld/poetry/service/impl/ArticleServiceImpl.java @@ -1,21 +1,22 @@ package com.ld.poetry.service.impl; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ld.poetry.config.PoetryResult; import com.ld.poetry.dao.ArticleMapper; -import com.ld.poetry.entity.Article; -import com.ld.poetry.entity.Label; -import com.ld.poetry.entity.Sort; -import com.ld.poetry.entity.User; +import com.ld.poetry.dao.LabelMapper; +import com.ld.poetry.entity.*; import com.ld.poetry.service.ArticleService; +import com.ld.poetry.service.UserService; import com.ld.poetry.utils.*; import com.ld.poetry.vo.ArticleVO; import com.ld.poetry.vo.BaseRequestVO; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; @@ -42,6 +43,18 @@ public class ArticleServiceImpl extends ServiceImpl impl @Autowired private CommonQuery commonQuery; + @Autowired + private UserService userService; + + @Autowired + private MailUtil mailUtil; + + @Autowired + private LabelMapper labelMapper; + + @Value("${user.subscribe.format}") + private String subscribeFormat; + @Override public PoetryResult saveArticle(ArticleVO articleVO) { if (articleVO.getViewStatus() != null && !articleVO.getViewStatus() && !StringUtils.hasText(articleVO.getPassword())) { @@ -53,6 +66,7 @@ public class ArticleServiceImpl extends ServiceImpl impl } if (articleVO.getViewStatus() != null && !articleVO.getViewStatus() && StringUtils.hasText(articleVO.getPassword())) { article.setPassword(articleVO.getPassword()); + article.setTips(articleVO.getTips()); } article.setViewStatus(articleVO.getViewStatus()); article.setCommentStatus(articleVO.getCommentStatus()); @@ -68,9 +82,41 @@ public class ArticleServiceImpl extends ServiceImpl impl if (!CollectionUtils.isEmpty(sortInfo)) { PoetryCache.put(CommonConst.SORT_INFO, sortInfo); } + + try { + if (articleVO.getViewStatus()) { + List users = userService.lambdaQuery().select(User::getEmail, User::getSubscribe).eq(User::getUserStatus, PoetryEnum.STATUS_ENABLE.getCode()).list(); + List emails = users.stream().filter(u -> { + List sub = JSON.parseArray(u.getSubscribe(), Integer.class); + return !CollectionUtils.isEmpty(sub) && sub.contains(articleVO.getLabelId()); + }).map(User::getEmail).collect(Collectors.toList()); + + if (!CollectionUtils.isEmpty(emails)) { + LambdaQueryChainWrapper