inleft
2022-08-24 dc050f50a530ef7b0eaa378ca1790c26d4f0bfd5
commit | author | age
0613f2 1 /*
I 2 Copyright [2020] [https://www.xiaonuo.vip]
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8   http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15
16 Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
17
18 1.请不要删除和修改根目录下的LICENSE文件。
19 2.请不要删除和修改Snowy源码头部的版权声明。
20 3.请保留源码和相关描述文件的项目出处,作者声明等。
21 4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/snowy
22 5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/snowy
23 6.若您的项目无法满足以上几点,可申请商业授权,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
24  */
25 package vip.xiaonuo.modular.blogarticle.controller;
26
bd3bc1 27 import cn.hutool.core.bean.BeanUtil;
dc050f 28 import cn.hutool.core.collection.CollUtil;
ba780f 29 import cn.hutool.core.date.DateUnit;
31e475 30 import cn.hutool.core.date.DateUtil;
0613f2 31 import cn.hutool.core.util.PageUtil;
I 32 import cn.hutool.core.util.StrUtil;
bd3bc1 33 import cn.hutool.crypto.SecureUtil;
0613f2 34 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
20e5fc 35 import lombok.extern.slf4j.Slf4j;
552004 36 import org.springframework.validation.annotation.Validated;
I 37 import org.springframework.web.bind.annotation.*;
0613f2 38 import vip.xiaonuo.core.annotion.BusinessLog;
bd3bc1 39 import vip.xiaonuo.core.consts.MyConstant;
dc050f 40 import vip.xiaonuo.core.consts.SymbolConstant;
cfde48 41 import vip.xiaonuo.core.context.constant.ConstantContextHolder;
0613f2 42 import vip.xiaonuo.core.enums.LogAnnotionOpTypeEnum;
bd3bc1 43 import vip.xiaonuo.core.exception.BlogException;
I 44 import vip.xiaonuo.core.exception.enums.BlogExceptionEnum;
0613f2 45 import vip.xiaonuo.core.pojo.response.ResponseData;
I 46 import vip.xiaonuo.core.pojo.response.SuccessResponseData;
bd3bc1 47 import vip.xiaonuo.modular.blogarticle.entity.BlogArticle;
ba780f 48 import vip.xiaonuo.modular.blogarticle.entity.BlogArticleVo;
552004 49 import vip.xiaonuo.modular.blogarticle.param.BlogArticleAddDto;
0613f2 50 import vip.xiaonuo.modular.blogarticle.param.BlogArticleQueryDto;
I 51 import vip.xiaonuo.modular.blogarticle.service.BlogArticleService;
552004 52 import vip.xiaonuo.modular.blogarticletype.entity.BlogArticleType;
I 53 import vip.xiaonuo.modular.blogarticletype.service.BlogArticleTypeService;
cfde48 54 import vip.xiaonuo.sys.modular.file.entity.SysFileInfo;
I 55 import vip.xiaonuo.sys.modular.file.service.SysFileInfoService;
0613f2 56
I 57 import javax.annotation.Resource;
dc050f 58 import java.util.*;
20e5fc 59 import java.util.concurrent.Future;
dc050f 60 import java.util.function.Function;
0613f2 61 import java.util.stream.Collectors;
I 62
63 /**
64  * blog文章控制器 (提供给外部blog系统查询)
65  *
66  * @author inleft
67  * @date 2022-02-09 18:20:22
68  */
69 @RestController
70 @RequestMapping("/outside")
20e5fc 71 @Slf4j
0613f2 72 public class BlogArticleOutsideController {
I 73
74     @Resource
75     private BlogArticleService blogArticleService;
76
cfde48 77
I 78     @Resource
552004 79     private BlogArticleTypeService blogArticleTypeService;
I 80
81     @Resource
cfde48 82     private SysFileInfoService fileInfoService;
552004 83
I 84     @PostMapping("/blogArticle/add")
85     @BusinessLog(title = "外部blog系统_blog文章_增加", opType = LogAnnotionOpTypeEnum.ADD)
86     public ResponseData add(@RequestBody @Validated(BlogArticleAddDto.add.class) BlogArticleAddDto addDto) {
fc74b4 87         if (!SecureUtil.md5(addDto.getSecret()).equals(ConstantContextHolder.getPushCode())) {
552004 88             throw new BlogException("口令错误..");
I 89         }
90
91         if (MyConstant.Yes.equals(addDto.getIsTop()) && addDto.getTopValue() == null) {
92             throw new BlogException("选择了置顶需要指定置顶值..");
93         }
94
95         if (addDto.getIsLock().equals(MyConstant.Yes)) {
96             if (addDto.getAuthStatus().equals(MyConstant.AuthStatus.authCode) && StrUtil.isEmpty(addDto.getAuthPassword())) {
97                 throw new BlogException("选择了密码授权,密码不能为空");
98             }
99         } else {
100             addDto.setAuthPassword(null);
101         }
102
103         if (MyConstant.Yes.equals(addDto.getIsOnline())) {
104             if (addDto.getArticleFileId() == null || fileInfoService.getById(addDto.getArticleFileId()) == null) {
105                 throw new BlogException("已选择在线模式..文件id非法");
106             }
107         } else {
108             if (StrUtil.isEmpty(addDto.getContent())) {
109                 throw new BlogException("已选择在线模式..文件内容非法");
110             }
111         }
112
113         if (addDto.getCoverFileId() != null && fileInfoService.getById(addDto.getCoverFileId()) == null) {
114             throw new BlogException("封面文件id非法");
115         }
116
117         if (blogArticleTypeService.lambdaQuery()
118                 .eq(BlogArticleType::getIsEnable, MyConstant.Yes)
119                 .eq(BlogArticleType::getId, addDto.getArticleTypeId())
120                 .one() == null) {
121             throw new BlogException("分类id非法");
122         }
123
124         if (addDto.getPublishDate() == null) {
125             addDto.setPublishDate(new Date());
126         }
127
128         BlogArticle article = new BlogArticle();
129         BeanUtil.copyProperties(addDto, article);
31e475 130         article.setSeparateYear(DateUtil.year(article.getPublishDate()));
ba780f 131         article.setSeparateMonth(DateUtil.month(article.getPublishDate()) + 1);
31e475 132         article.setSeparateDay(DateUtil.dayOfMonth(article.getPublishDate()));
I 133
134         article.setIsEnable(MyConstant.Yes);
135         blogArticleService.save(article);
552004 136         return new SuccessResponseData();
I 137     }
cfde48 138
0613f2 139     /**
I 140      * 查询blog文章
141      *
142      * @author inleft
143      * @date 2022-02-09 18:20:22
144      */
145     @GetMapping("/blogArticle/queryBlogArticleList")
146     @BusinessLog(title = "外部blog系统_blog文章_查询", opType = LogAnnotionOpTypeEnum.QUERY)
147     public ResponseData queryBlogArticleList(BlogArticleQueryDto queryDto) {
148
149
150         Map<String, Object> param = new HashMap<>(16);
151         param.put("pageNo", PageUtil.getStart(queryDto.getPageNo() - 1, queryDto.getPageSize()));
152         param.put("pageSize", queryDto.getPageSize());
a9c4c9 153         param.put("typeId", queryDto.getTypeId());
d80267 154         param.put("fileType", queryDto.getFileType());
0613f2 155
cfde48 156         String blogSourcePrefix = ConstantContextHolder.getBlogSourcePrefix();
ba780f 157
I 158         Date now = DateUtil.date();
159         //空类型查询条件,排除笔记系列,按更新时间倒序
160         //含有类型查询,按发布时间倒序
a9c4c9 161         List<BlogArticleVo> resList = blogArticleService.searchList(param).stream().map(e -> {
504927 162             if (StrUtil.isNotEmpty(e.getCoverFileURL())) {
I 163                 if (!e.getCoverFileURL().startsWith("http")) {
164                     //补上访问参数
cfde48 165                     e.setCoverFileURL(blogSourcePrefix + e.getCoverFileURL());
504927 166                 }
0613f2 167             }
ba780f 168
20e5fc 169             //前端根据条件标注小红点(发布时间小于更新时间,且在7天内)
ba780f 170             if (e.getPublishDate().before(e.getUpdateDate())
I 171                     && DateUtil.between(e.getUpdateDate(), now, DateUnit.DAY) <= 7) {
172                 e.setIsAnyUpdate(MyConstant.Yes);
173             } else {
174                 e.setIsAnyUpdate(MyConstant.No);
175             }
176
0613f2 177             return e;
I 178         }).collect(Collectors.toList());
179
a9c4c9 180         long count = blogArticleService.searchListCount(param);
0613f2 181
I 182         Page<BlogArticleVo> queryPage = new Page<>(queryDto.getPageNo(), queryDto.getPageSize());
183         queryPage.setRecords(resList);
184         queryPage.setTotal(count);
185
186         return new SuccessResponseData(queryPage);
187     }
188
dc050f 189
I 190     /**
191      * 查询blog文章(月台专用列表)
192      *
193      * @author inleft
194      * @date 2022-02-09 18:20:22
195      */
196     @GetMapping("/blogArticle/platform")
197     @BusinessLog(title = "外部blog系统_blog月台_查询", opType = LogAnnotionOpTypeEnum.QUERY)
198     public ResponseData platform(BlogArticleQueryDto queryDto) {
199
200         Map<String, Object> param = new HashMap<>(16);
201         param.put("pageNo", PageUtil.getStart(queryDto.getPageNo() - 1, queryDto.getPageSize()));
202         param.put("pageSize", queryDto.getPageSize());
203
204         if (queryDto.getActiveKey().equals(MyConstant.platformType.type_2)) {
205             param.put("typeIds", new Long[]{10L});//临时id,后续需要修改(前方高能分类)
206             param.put("fileType", MyConstant.FileType.fileTypeVideo_3);
207         } else if (queryDto.getActiveKey().equals(MyConstant.platformType.type_3)) {
208             param.put("typeIds", new Long[]{99L});//临时id,后续需要修改
209             param.put("fileType", MyConstant.FileType.fileTypePhoto_9);
210         } else {
211             param.put("typeIds", new Long[]{4L});//临时id,后续需要修改(音乐分类)
212             param.put("fileType", MyConstant.FileType.fileTypeVideo_3);
213         }
214
215         String blogSourcePrefix = ConstantContextHolder.getBlogSourcePrefix();
216
217         //空类型查询条件,排除笔记系列,按更新时间倒序
218         //含有类型查询,按发布时间倒序
219         List<BlogArticleVo> resList = blogArticleService.searchPlatformList(param).stream().map(e -> {
220             if (StrUtil.isNotEmpty(e.getCoverFileURL())) {
221                 if (!e.getCoverFileURL().startsWith("http")) {
222                     //补上访问参数
223                     e.setCoverFileURL(blogSourcePrefix + e.getCoverFileURL());
224                 }
225             }
226
227             //补充视频组,图片组的url
228             if (StrUtil.isNotEmpty(e.getPictureIds())) {
229                 e.setPictureUrlList(this.getBlogSourceURLBatch(Arrays.stream(e.getPictureIds().split(SymbolConstant.COMMA)).collect(Collectors.toList())));
230             }
231
232             return e;
233         }).collect(Collectors.toList());
234
235         long count = blogArticleService.searchPlatformListCount(param);
236
237         Page<BlogArticleVo> queryPage = new Page<>(queryDto.getPageNo(), queryDto.getPageSize());
238         queryPage.setRecords(resList);
239         queryPage.setTotal(count);
240
241         return new SuccessResponseData(queryPage);
242     }
243
bd3bc1 244     @GetMapping("/blogArticle/queryBlogArticleDetail")
I 245     @BusinessLog(title = "外部blog系统_blog文章详情_查询", opType = LogAnnotionOpTypeEnum.QUERY)
246     public ResponseData queryBlogArticleDetail(BlogArticleQueryDto queryDto) {
247         BlogArticle find = blogArticleService.lambdaQuery()
248                 .eq(BlogArticle::getIsEnable, MyConstant.Yes)
249                 .eq(BlogArticle::getEditorStatus, MyConstant.Yes)
250                 .eq(BlogArticle::getId, queryDto.getId())
251                 .one();
252
253         if (find == null) {
254             throw new BlogException(BlogExceptionEnum.article_not_found);
255         }
256
257         //加密文章
258         if (find.getAuthStatus().equals(MyConstant.AuthStatus.authCode)) {
259             //授权码缺失
260             if (StrUtil.isEmpty(queryDto.getAuthWord())) {
261                 throw new BlogException(BlogExceptionEnum.article_auth_error);
262             }
263             //授权码比对
88f419 264             if (!find.getAuthPassword().equals(queryDto.getAuthWord())) {
bd3bc1 265                 throw new BlogException(BlogExceptionEnum.article_auth_pass_error);
I 266             }
cfde48 267         } else if (find.getAuthStatus().equals(MyConstant.AuthStatus.privateCode)) {
bd3bc1 268             throw new BlogException(BlogExceptionEnum.article_auth_private_error);
I 269         }
270
20e5fc 271         //异步查询相邻记录
I 272         Future<List<BlogArticleVo>> adjoiningRecord = blogArticleService.getAdjoiningRecord(queryDto);
273
bd3bc1 274         BlogArticleVo vo = new BlogArticleVo();
I 275
276         BeanUtil.copyProperties(find, vo);
277
31e475 278
e99de8 279         String tempURL = this.getBlogSourceURL(find.getArticleFileId());
cfde48 280
c49fa0 281         //if (StrUtil.isEmpty(tempURL))
20e5fc 282         //throw new BlogException(BlogExceptionEnum.article_file_lose);
e99de8 283
I 284         vo.setArticleFileURL(tempURL);
ff14c4 285         vo.setCoverFileURL(this.getBlogSourceURL(vo.getCoverFileId()));
20e5fc 286
I 287         while (!adjoiningRecord.isDone()) {
288             try {
1e152b 289                 Thread.sleep(50);
20e5fc 290             } catch (InterruptedException e) {
I 291             }
292         }
293
294         try {
295             vo.setPreviousRecord(adjoiningRecord.get().get(0));
296             vo.setNextRecord(adjoiningRecord.get().get(1));
297         } catch (Exception e) {
298             log.error("异步获取上下相邻日志id异常,id:{} ,msg:{}", queryDto.getId(), e.getMessage());
299         }
300
bd3bc1 301         return new SuccessResponseData(vo);
I 302     }
303
cfde48 304     private String getBlogSourceURL(Long fileId) {
I 305         SysFileInfo sysFileInfo = fileInfoService.getById(fileId);
306         if (sysFileInfo == null) {
307             return null;
308         } else {
309             String blogSourcePrefix = ConstantContextHolder.getBlogSourcePrefix();
e99de8 310             return blogSourcePrefix + sysFileInfo.getFileBucket() + "/" + sysFileInfo.getFileObjectName();
cfde48 311         }
I 312     }
0613f2 313
dc050f 314     private List<String> getBlogSourceURLBatch(List<String> fileIds) {
I 315         Map<String, SysFileInfo> sysFileInfoMap = fileInfoService.listByIds(fileIds).stream().collect(Collectors.toMap(e -> e.getId().toString(), Function.identity(), (k1, k2) -> k1));
316         if (CollUtil.isEmpty(sysFileInfoMap)) {
317             return null;
318         } else {
319             List<String> urlList = new ArrayList<>(fileIds.size());
320             String blogSourcePrefix = ConstantContextHolder.getBlogSourcePrefix();
321
322             SysFileInfo sysFileInfo;
323             for (String fileId : fileIds) {
324                 sysFileInfo = sysFileInfoMap.getOrDefault(fileId, null);
325                 if (sysFileInfo == null) {
326                     urlList.add(null);
327                 } else {
328                     urlList.add(blogSourcePrefix + sysFileInfo.getFileBucket() + "/" + sysFileInfo.getFileObjectName());
329                 }
330             }
331             return urlList;
332         }
333     }
334
0613f2 335 }