diff --git a/src/main/java/cc/ryanc/halo/model/domain/Post.java b/src/main/java/cc/ryanc/halo/model/domain/Post.java index 4f54480e5..be77d3827 100755 --- a/src/main/java/cc/ryanc/halo/model/domain/Post.java +++ b/src/main/java/cc/ryanc/halo/model/domain/Post.java @@ -1,6 +1,9 @@ package cc.ryanc.halo.model.domain; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; import com.fasterxml.jackson.annotation.JsonFormat; +import io.undertow.util.DateUtils; import lombok.Data; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; @@ -154,4 +157,17 @@ public class Post implements Serializable { public Date getPostUpdate() { return postUpdate; } + + @PrePersist + public void prePersist() { + DateTime now = DateUtil.date(); + postDate = now; + postUpdate = now; + postId = null; + } + + @PreUpdate + public void preUpdate() { + postUpdate = DateUtil.date(); + } } diff --git a/src/main/java/cc/ryanc/halo/model/dto/JsonResult.java b/src/main/java/cc/ryanc/halo/model/dto/JsonResult.java index 4f9f89ebc..6db965806 100644 --- a/src/main/java/cc/ryanc/halo/model/dto/JsonResult.java +++ b/src/main/java/cc/ryanc/halo/model/dto/JsonResult.java @@ -1,9 +1,11 @@ package cc.ryanc.halo.model.dto; +import cc.ryanc.halo.model.enums.ResultCodeEnum; import lombok.Data; import org.springframework.http.HttpStatus; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** *
@@ -112,4 +114,56 @@ public class JsonResult { public static JsonResult ok(@Nullable String message) { return ok(message, null); } + + /** + * Creates an fail result with message only. + * + * @param message message of result must not be blank + * @return fail result with message only + */ + public static JsonResult fail(@NonNull String message) { + Assert.hasText(message, "Message of result must not be blank"); + + return new JsonResult(ResultCodeEnum.FAIL.getCode(), message); + } + + /** + * Creates an fail result. + * + * @param message message of result must not be blank + * @return fail result + */ + public static JsonResult fail(@NonNull String message, @NonNull Object data) { + Assert.notNull(data, "Data of result must not be null"); + + JsonResult failResult = fail(message); + failResult.setResult(data); + return failResult; + } + + /** + * Creates an success result with message only. + * + * @param message message of result must not be blank + * @return success result with message only + */ + public static JsonResult success(@NonNull String message) { + Assert.hasText(message, "Message of result must not be blank"); + + return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), message); + } + + /** + * Creates an success result. + * + * @param message message of result must not be blank + * @return success result + */ + public static JsonResult success(@NonNull String message, @NonNull Object data) { + Assert.notNull(data, "Data of result must not be null"); + + JsonResult successResult = success(message); + successResult.setResult(data); + return successResult; + } } diff --git a/src/main/java/cc/ryanc/halo/service/impl/AttachmentServiceImpl.java b/src/main/java/cc/ryanc/halo/service/impl/AttachmentServiceImpl.java index 64542626d..9edb134d2 100644 --- a/src/main/java/cc/ryanc/halo/service/impl/AttachmentServiceImpl.java +++ b/src/main/java/cc/ryanc/halo/service/impl/AttachmentServiceImpl.java @@ -1,5 +1,6 @@ package cc.ryanc.halo.service.impl; +import cc.ryanc.halo.logging.Logger; import cc.ryanc.halo.model.domain.Attachment; import cc.ryanc.halo.model.dto.QiNiuPutSet; import cc.ryanc.halo.model.enums.AttachLocationEnum; @@ -31,6 +32,7 @@ import org.springframework.cache.annotation.Cacheable; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; +import org.springframework.util.Assert; import org.springframework.web.multipart.MultipartFile; import javax.imageio.ImageIO; @@ -54,6 +56,8 @@ import static cc.ryanc.halo.model.dto.HaloConst.OPTIONS; @Service public class AttachmentServiceImpl extends AbstractCrudServiceimplements AttachmentService { + private final Logger log = Logger.getLogger(getClass()); + private static final String ATTACHMENTS_CACHE_NAME = "attachments"; private final AttachmentRepository attachmentRepository; @@ -160,6 +164,9 @@ public class AttachmentServiceImpl extends AbstractCrudService */ @Override public Map attachUpload(MultipartFile file, HttpServletRequest request) { + Assert.notNull(file, "MultipartFile must not be null"); + Assert.notNull(request, "Http servlet request must not be null"); + final Map resultMap = new HashMap<>(6); final String dateString = DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss"); try { @@ -277,17 +284,11 @@ public class AttachmentServiceImpl extends AbstractCrudService putSet = new Gson().fromJson(response.bodyString(), QiNiuPutSet.class); } catch (QiniuException e) { final Response r = e.response; - System.err.println(r.toString()); - try { - System.err.println(r.bodyString()); - } catch (QiniuException ex2) { - //ignore - } - } catch (JsonSyntaxException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); + log.error("Qiniu error response: [{}]", r); + } catch (JsonSyntaxException | IOException e) { + log.error("Failed to attach QiNiu resource", e); } + final String filePath = domain.trim() + "/" + key; resultMap.put("fileName", file.getOriginalFilename()); resultMap.put("filePath", filePath.trim()); @@ -297,7 +298,7 @@ public class AttachmentServiceImpl extends AbstractCrudService resultMap.put("wh", putSet.getW() + "x" + putSet.getH()); resultMap.put("location", AttachLocationEnum.QINIU.getDesc()); } catch (Exception e) { - e.printStackTrace(); + log.debug("Failed to generate md5 check sum", e); } return resultMap; } @@ -347,7 +348,7 @@ public class AttachmentServiceImpl extends AbstractCrudService resultMap.put("location", AttachLocationEnum.UPYUN.getDesc()); } catch (Exception e) { - e.printStackTrace(); + log.error("Failed to attach UpYun resource", e); } return resultMap; } @@ -400,10 +401,8 @@ public class AttachmentServiceImpl extends AbstractCrudService upYun.setApiDomain(UpYun.ED_AUTO); try { flag = upYun.deleteFile(ossSrc + fileName); - } catch (IOException e) { - e.printStackTrace(); - } catch (UpException e) { - e.printStackTrace(); + } catch (IOException | UpException e) { + log.error("Failed to delete UpYun attachment", e); } return flag; } diff --git a/src/main/java/cc/ryanc/halo/web/controller/admin/AdminController.java b/src/main/java/cc/ryanc/halo/web/controller/admin/AdminController.java index 0014e7ddf..80d729455 100755 --- a/src/main/java/cc/ryanc/halo/web/controller/admin/AdminController.java +++ b/src/main/java/cc/ryanc/halo/web/controller/admin/AdminController.java @@ -1,5 +1,6 @@ package cc.ryanc.halo.web.controller.admin; +import cc.ryanc.halo.logging.Logger; import cc.ryanc.halo.model.domain.*; import cc.ryanc.halo.model.dto.JsonResult; import cc.ryanc.halo.model.dto.LogsRecord; @@ -12,11 +13,10 @@ import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.IoUtil; import cn.hutool.core.lang.Validator; -import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.http.HtmlUtil; -import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -24,6 +24,7 @@ import org.springframework.data.web.PageableDefault; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -43,11 +44,12 @@ import static cc.ryanc.halo.model.dto.HaloConst.USER_SESSION_KEY; * @author : RYAN0UP * @date : 2017/12/5 */ -@Slf4j @Controller @RequestMapping(value = "/admin") public class AdminController extends BaseController { + private final Logger log = Logger.getLogger(getClass()); + @Autowired private PostService postService; @@ -79,7 +81,6 @@ public class AdminController extends BaseController { * 请求后台页面 * * @param model model - * * @return 模板路径admin/admin_index */ @GetMapping(value = {"", "/index"}) @@ -119,17 +120,13 @@ public class AdminController extends BaseController { * 处理跳转到登录页的请求 * * @param session session - * * @return 模板路径admin/admin_login */ @GetMapping(value = "/login") public String login(HttpSession session) { final User user = (User) session.getAttribute(USER_SESSION_KEY); //如果session存在,跳转到后台首页 - if (null != user) { - return "redirect:/admin"; - } - return "admin/admin_login"; + return user != null ? "redirect:/admin" : "admin/admin_login"; } /** @@ -138,7 +135,6 @@ public class AdminController extends BaseController { * @param loginName 登录名:邮箱/用户名 * @param loginPwd loginPwd 密码 * @param session session session - * * @return JsonResult JsonResult */ @PostMapping(value = "/getLogin") @@ -148,6 +144,7 @@ public class AdminController extends BaseController { HttpSession session) { //已注册账号,单用户,只有一个 final User aUser = userService.findUser(); + //首先判断是否已经被禁用已经是否已经过了10分钟 Date loginLast = DateUtil.date(); if (null != aUser.getLoginLast()) { @@ -155,24 +152,26 @@ public class AdminController extends BaseController { } final Long between = DateUtil.between(loginLast, DateUtil.date(), DateUnit.MINUTE); if (StrUtil.equals(aUser.getLoginEnable(), TrueFalseEnum.FALSE.getDesc()) && (between < CommonParamsEnum.TEN.getValue())) { - return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.login.disabled")); + return JsonResult.fail(localeMessageUtil.getMessage("code.admin.login.disabled")); } + //验证用户名和密码 - User user = null; + User user; if (Validator.isEmail(loginName)) { user = userService.userLoginByEmail(loginName, SecureUtil.md5(loginPwd)); } else { user = userService.userLoginByName(loginName, SecureUtil.md5(loginPwd)); } userService.updateUserLoginLast(DateUtil.date()); + //判断User对象是否相等 - if (ObjectUtil.equal(aUser, user)) { + if (Objects.equals(aUser, user)) { session.setAttribute(USER_SESSION_KEY, aUser); //重置用户的登录状态为正常 userService.updateUserNormal(); logsService.save(LogsRecord.LOGIN, LogsRecord.LOGIN_SUCCESS, request); log.info("User {} login succeeded.", aUser.getUserDisplayName()); - return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), localeMessageUtil.getMessage("code.admin.login.success")); + return JsonResult.success(localeMessageUtil.getMessage("code.admin.login.success")); } else { //更新失败次数 final Integer errorCount = userService.updateUserLoginError(); @@ -181,8 +180,7 @@ public class AdminController extends BaseController { userService.updateUserLoginEnable(TrueFalseEnum.FALSE.getDesc()); } logsService.save(LogsRecord.LOGIN, LogsRecord.LOGIN_ERROR + "[" + HtmlUtil.escape(loginName) + "," + HtmlUtil.escape(loginPwd) + "]", request); - final Object[] args = {(5 - errorCount)}; - return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.login.failed", args)); + return JsonResult.fail(localeMessageUtil.getMessage("code.admin.login.failed", new Integer[]{5 - errorCount})); } } @@ -190,7 +188,6 @@ public class AdminController extends BaseController { * 退出登录 销毁session * * @param session session - * * @return 重定向到/admin/login */ @GetMapping(value = "/logOut") @@ -206,7 +203,6 @@ public class AdminController extends BaseController { * 查看所有日志 * * @param model model model - * * @return 模板路径admin/widget/_logs-all */ @GetMapping(value = "/logs") @@ -226,7 +222,7 @@ public class AdminController extends BaseController { try { logsService.removeAll(); } catch (Exception e) { - log.error("Clear log failed:{}" + e.getMessage()); + log.error("Clear log failed", e); } return "redirect:/admin"; } @@ -249,8 +245,8 @@ public class AdminController extends BaseController { @GetMapping(value = "/getToken") @ResponseBody public JsonResult getToken() { - final String token = (System.currentTimeMillis() + new Random().nextInt(999999999)) + ""; - return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), HttpStatus.OK.getReasonPhrase(), SecureUtil.md5(token)); + final String token = String.valueOf(System.currentTimeMillis() + RandomUtil.randomInt(Integer.MAX_VALUE)); + return JsonResult.success(HttpStatus.OK.getReasonPhrase(), SecureUtil.md5(token)); } /** @@ -278,7 +274,6 @@ public class AdminController extends BaseController { * * @param file file * @param request request - * * @return JsonResult */ @PostMapping(value = "/tools/markdownImport") @@ -291,48 +286,44 @@ public class AdminController extends BaseController { final String content = MarkdownUtils.renderMarkdown(markdown); final Map > frontMatters = MarkdownUtils.getFrontMatter(markdown); final Post post = new Post(); - List elementValue = null; - final List tags = new ArrayList<>(); - final List categories = new ArrayList<>(); - Tag tag = null; - Category category = null; - if (frontMatters.size() > 0) { - for (String key : frontMatters.keySet()) { - elementValue = frontMatters.get(key); - for (String ele : elementValue) { - if ("title".equals(key)) { - post.setPostTitle(ele); - } else if ("date".equals(key)) { - post.setPostDate(DateUtil.parse(ele)); - } else if ("updated".equals(key)) { - post.setPostUpdate(DateUtil.parse(ele)); - } else if ("tags".equals(key)) { - tag = tagService.findTagByTagName(ele); - if (null == tag) { - tag = new Tag(); - tag.setTagName(ele); - tag.setTagUrl(ele); - tag = tagService.create(tag); - } - tags.add(tag); - } else if ("categories".equals(key)) { - category = categoryService.findByCateName(ele); - if (null == category) { - category = new Category(); - category.setCateName(ele); - category.setCateUrl(ele); - category.setCateDesc(ele); - category = categoryService.create(category); - } - categories.add(category); - } + final List tags = new LinkedList<>(); + final List categories = new LinkedList<>(); + + if (!CollectionUtils.isEmpty(frontMatters)) { + // Iterate the map and inner list + frontMatters.forEach((key, elementValue) -> elementValue.forEach(ele -> { + if ("title".equals(key)) { + post.setPostTitle(ele); + } else if ("date".equals(key)) { + post.setPostDate(DateUtil.parse(ele)); + } else if ("updated".equals(key)) { + post.setPostUpdate(DateUtil.parse(ele)); + } else if ("tags".equals(key)) { + Tag tag = Optional.ofNullable(tagService.findTagByTagName(ele)).orElseGet(() -> { + Tag aTag = new Tag(); + aTag.setTagName(ele); + aTag.setTagUrl(ele); + return tagService.create(aTag); + }); + tags.add(tag); + } else if ("categories".equals(key)) { + Category category = Optional.ofNullable(categoryService.findByCateName(ele)).orElseGet(() -> { + Category catg = new Category(); + catg.setCateName(ele); + catg.setCateUrl(ele); + catg.setCateDesc(ele); + return categoryService.create(catg); + }); + categories.add(category); } - } - } else { - post.setPostDate(new Date()); - post.setPostUpdate(new Date()); + })); + } + + if (StrUtil.isBlank(post.getPostTitle())) { post.setPostTitle(file.getOriginalFilename()); } + + post.setPostContentMd(markdown); post.setPostContent(content); post.setPostType(PostTypeEnum.POST_TYPE_POST.getDesc()); @@ -341,12 +332,6 @@ public class AdminController extends BaseController { post.setTags(tags); post.setCategories(categories); post.setPostUrl(StrUtil.removeSuffix(file.getOriginalFilename(), ".md")); - if (null == post.getPostDate()) { - post.setPostDate(new Date()); - } - if (null == post.getPostUpdate()) { - post.setPostUpdate(new Date()); - } postService.create(post); return new JsonResult(ResultCodeEnum.SUCCESS.getCode()); } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index f2bc0ef77..5ada624e5 100755 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -38,6 +38,7 @@ spring: hibernate: ddl-auto: update show-sql: false + open-in-view: false freemarker: allow-request-override: false cache: false