持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情
这里需要修改一下文章的数据库,有一些字段需要修改,多的字段暂时就不删除了,不然就改动的很多。
DROP TABLE IF EXISTS `person_article`;
CREATE TABLE `person_article` (
`id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '主键',
`author` VARCHAR(128) NOT NULL COMMENT '作者',
`title` VARCHAR(255) NOT NULL COMMENT '文章标题',
`user_id` INT(11) NOT NULL COMMENT '用户id',
`category_id` INT(11) NULL COMMENT '分类id',
`content` LONGTEXT NOT NULL COMMENT '文章内容',
`views` BIGINT NOT NULL DEFAULT 0 COMMENT '文章浏览量',
`total_words` BIGINT NOT NULL DEFAULT 0 COMMENT '文章总字数',
`commentable_id` INT NULL COMMENT '评论id',
`art_status` TINYINT NOT NULL DEFAULT 1 COMMENT '发布,默认1, 1-发布, 2-仅我可见 3-草稿',
`description` VARCHAR(255) NULL COMMENT '描述',
`image_url` VARCHAR(255) NULL COMMENT '文章logo',
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间'
) ENGINE = InnoDB
CHARACTER SET = utf8mb4
COLLATE = utf8mb4_bin
ROW_FORMAT = Dynamic
COMMENT '文章管理表';
还有文章和标签的关联表数据库也要修改一下,把表的id删除掉,这个字段多余的。
DROP TABLE IF EXISTS `person_article_tag`;
CREATE TABLE `person_article_tag` (
`tag_id` INT(11) NOT NULL COMMENT '标签id',
`article_id` INT(11) NOT NULL COMMENT '文章id'
) ENGINE = InnoDB
CHARACTER SET = utf8mb4
COLLATE = utf8mb4_bin
ROW_FORMAT = Dynamic
COMMENT '文章和标签关联表';
相对应的实体类和xml这两个文件要把id删除掉,这里我就不展示了,只删除id即可。
保存草稿功能相对于保存文章比较简单,不需要进入到弹出框之前就结束了这个功能,先找到我们之前写的保存草稿页面,点击功能需要完善即可。这里就修改了一下点击的方法名称。
<el-button type="warning"
size="medium"
@click="saveDraft"
style="margin-left:10px"
v-if="article.id === '' || article.artStatus == 3"
>保存草稿</el-button>
接下来我们来实现saveDraft方法的功能。
saveDraft() {
this.article.artStatus = 3;
if (this.article.title.trim() == "") {
this.$message.error("文章标题不能为空");
return false;
}
if (this.article.content.trim() == "") {
this.$message.error("文章内容不能为空");
return false;
}
var body = this.article;
addArticle(body).then(res => {
if(res.code === 200) {
this.$message({
type: 'success',
message: '保存草稿成功!'
});
} else {
this.$message({
type: 'error',
message: '保存草稿失败!'
});
}
})
},
从以上代码可以看出,我先校验了文章的标题和内容,然后调用了添加文章的接口进行文章保存。
这里还要修改一下文章保存的接口,我们之前设计的不太合理,现在需要再完善一下。
首先添加一个文章保存的对象:ArticleInsertBO.java
package com.blog.personalblog.bo;
import lombok.Data;
/**
* @author: SuperMan
* @create: 2022-10-02
*/
@Data
public class ArticleInsertBO {
/**
* 文章id
*/
private Integer id;
/**
* 文章标题
*/
private String title;
/**
* 分类id
*/
private Integer categoryId;
/**
* 文章内容
*/
private String content;
/**
* 发布,默认1, 1-发布, 2-仅我可见 3-草稿
*/
private Integer artStatus;
/**
* 描述
*/
private String description;
/**
* 文章logo
*/
private String imageUrl;
/**
* 分类名称
*/
private String categoryName;
/**
* 文章标签
*/
private List<String> tagNameList;
}
然后修改接口,这里我将修改个添加整合到一个接口中,可以减少重复的代码
/**
* 新建文章
* @param bo
* @return
*/
void insertOrUpdateArticle(ArticleInsertBO bo);
分类还要新加一个根据分类名称查询分类的接口以及实现方法,我这里就直接把代码列出来,相信大家对这操作也都比较熟练了。
/**
* 获取分类
* @param categoryName
* @return
*/
Category getCategoryByName(String categoryName);
@Override
public Category getCategoryByName(String categoryName) {
Category category = categoryMapper.getCategoryByName(categoryName);
return category;
}
CategoryMapper.java:
Category getCategoryByName(String categoryName);
<select id="getCategoryByName" resultType="com.blog.personalblog.entity.Category">
select * from person_category where category_name = #{categoryName, jdbcType=VARCHAR}
</select>
再将文章的发布形式单独提出来,写成一个枚举类,方便以后维护。
package com.blog.personalblog.common;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author: SuperMan
* @create: 2022-10-10
**/
@Getter
@AllArgsConstructor
public enum ArticleArtStatusEnum {
/**
* 发布
*/
PUBLISH(1, "发布"),
/**
* 仅我可见
*/
ONLYME(2, "仅我可见"),
/**
* 草稿
*/
DRAFT(3, "草稿");
/**
* 状态
*/
private final Integer status;
/**
* 描述
*/
private final String desc;
}
然后我们来写文章保存或修改的实现类。
这一块的逻辑相比较之前的有了一些变化,希望大家好好看一下这个逻辑,如果看不明白可以留言,我这里不再讲述了。
@Resource
private CategoryService categoryService;
@Resource
private UserService userService;
@Override
public void insertOrUpdateArticle(ArticleInsertBO bo) {
//分类添加
Category category = saveCategory(bo);
Article article = BeanUtil.copyProperties(bo, Article.class);
if (category != null) {
article.setCategoryId(category.getCategoryId());
}
String username = (String) SecurityUtils.getSubject().getPrincipal();
User user = userService.getUserByUserName(username);
article.setUserId(user.getId());
article.setAuthor(user.getUserName());
article.setViews(0L);
article.setTotalWords(0L);
if (bo.getId() != null) {
articleMapper.updateArticle(article);
} else {
articleMapper.createArticle(article);
}
articleMap.put(article.getId(), article);
//添加文章标签
saveTags(bo, article.getId());
//添加文章发送邮箱提醒
try {
String content = "【{0}】您好:\n" +
"您已成功发布了标题为: {1} 的文章 \n" +
"请注意查收!\n";
MailInfo build = MailInfo.builder()
.receiveMail(user.getEmail())
.content(MessageFormat.format(content, user.getUserName(), article.getTitle()))
.title("文章发布")
.build();
SendMailConfig.sendMail(build);
} catch (Exception e) {
log.error("邮件发送失败{}", e.getMessage());
}
}
private Category saveCategory(ArticleInsertBO bo) {
if (StrUtil.isEmpty(bo.getCategoryName())) {
return null;
}
Category category = categoryService.getCategoryByName(bo.getCategoryName());
if (category == null && !ArticleArtStatusEnum.DRAFT.getStatus().equals(bo.getArtStatus())) {
category.setCategoryName(bo.getCategoryName());
categoryService.saveCategory(category);
}
return category;
}
private void saveTags(ArticleInsertBO bo, Integer articleId) {
//首先判断是不是更新文章
if (bo.getId() == null) {
articleTagService.deleteTag(bo.getId());
}
//添加文章标签
List<String> tagNameList = bo.getTagNameList();
List<Integer> tagIdList = new ArrayList<>();
if (CollUtil.isNotEmpty(tagNameList)) {
//先查看添加的标签数据库里有没有
for (String tagName : tagNameList) {
Tag one = tagService.findByTagName(tagName);
if (one == null) {
Tag tag = new Tag();
tag.setTagName(tagName);
tagService.saveTag(tag);
tagIdList.add(tag.getId());
} else {
tagIdList.add(one.getId());
}
}
}
articleTagService.deleteTag(articleId);
if (tagIdList != null) {
List<ArticleTag> articleTagList = tagIdList.stream().map(tagId -> ArticleTag.builder()
.tagId(tagId)
.articleId(articleId)
.build()).collect(Collectors.toList());
articleTagService.insertBatch(articleTagList);
}
}
好啦,后端修改完成了,别忘了文章的数据库表更新成最新修改的。接下来我们运行项目,启动后端项目,然后我们测试一下数据有没有成功。
显示操作成功了,说明接口是通的,然后我们再去看一下数据库有没有这条数据。
有数据,那我们的保存草稿功能就完成了。