Spring Boot项目学习10之发帖模块
1.帖子的表设计
最显著的三个字段是帖子标题、帖子内容、帖子类别。但是除了这些字段外,还有一些必要的字段。
- 用户 id
- 阅读数量
- 评论数量
- 收藏数量
- 发布时间
同时,在发布帖子时,为了防止有人重复提交、重复发帖,提交表单时又加了一个验证码字段。
USE `my_bbs_db`;
DROP TABLE IF EXISTS `tb_post_category`;
CREATE TABLE `tb_post_category` (
`category_id` int NOT NULL AUTO_INCREMENT COMMENT '分类表主键',
`category_name` varchar(16) NOT NULL COMMENT '分类的名称',
`category_rank` int NOT NULL DEFAULT '1' COMMENT '分类的排序值 被使用的越多数值越大',
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除 0=否 1=是',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`category_id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;
insert into `tb_post_category`(`category_id`,`category_name`,`category_rank`,`is_deleted`,`create_time`) values (1,'提问',10,0,'2021-08-10 14:47:38'),(2,'分享',9,0,'2021-08-10 14:47:38'),(3,'建议',8,0,'2021-08-10 14:47:38'),(4,'讨论',7,0,'2021-08-10 14:47:38'),(5,'动态',6,0,'2021-08-10 14:47:38'),(6,'其它',5,0,'2021-08-10 14:47:38');
DROP TABLE IF EXISTS `tb_bbs_post`;
CREATE TABLE `tb_bbs_post` (
`post_id` bigint NOT NULL AUTO_INCREMENT COMMENT '帖子主键id',
`publish_user_id` bigint NOT NULL COMMENT '发布者id',
`post_title` varchar(64) NOT NULL DEFAULT '' COMMENT '帖子标题',
`post_content` mediumtext NOT NULL COMMENT '帖子内容',
`post_category_id` int NOT NULL COMMENT '帖子分类id',
`post_category_name` varchar(50) NOT NULL COMMENT '帖子分类(冗余字段)',
`post_status` tinyint NOT NULL DEFAULT '1' COMMENT '0-未审核 1-审核通过 2-审核失败',
`post_views` bigint NOT NULL DEFAULT '0' COMMENT '阅读量',
`post_comments` bigint NOT NULL DEFAULT '0' COMMENT '评论量',
`post_collects` bigint NOT NULL DEFAULT '0' COMMENT '收藏量',
`last_update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最新修改时间',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间',
PRIMARY KEY (`post_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;
2.跳转至发帖子功能
2.1Controller 处理跳转
首先新建 BBSPostController.java,该方法用于处理 /addPostPage 请求,由于是新增帖子的操作,所以只需要查询出分类数据供用户进行选择即可。如果是修改帖子的操作则需要进行帖子信息的查询,之后跳转到 templates/jie 目录下的 add.html 中。
@Controller
public class BBSPostController {
@Resource
private BBSPostCategoryService bbsPostCategoryService;
@GetMapping("/addPostPage")
public String addPostPage(HttpServletRequest request) {
List<BBSPostCategory> bbsPostCategories = bbsPostCategoryService.getBBSPostCategories();
if (CollectionUtils.isEmpty(bbsPostCategories)) {
return "error/error_404";
}
//将分类数据封装到request域中
request.setAttribute("bbsPostCategories", bbsPostCategories);
return "jie/add";
}
}
2.2 完成获取帖子分类列表功能
2.2.1 创建帖子分类实体类
/**
* 帖子分类-实体类
*/
public class BBSPostCategory {
private Integer categoryId;
private String categoryName;
private Integer categoryRank;
private Byte isDeleted;
private Date createTime;
public Integer getCategoryId() {
return categoryId;
}
public void setCategoryId(Integer categoryId) {
this.categoryId = categoryId;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName == null ? null : categoryName.trim();
}
public Integer getCategoryRank() {
return categoryRank;
}
public void setCategoryRank(Integer categoryRank) {
this.categoryRank = categoryRank;
}
public Byte getIsDeleted() {
return isDeleted;
}
public void setIsDeleted(Byte isDeleted) {
this.isDeleted = isDeleted;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", categoryId=").append(categoryId);
sb.append(", categoryName=").append(categoryName);
sb.append(", categoryRank=").append(categoryRank);
sb.append(", isDeleted=").append(isDeleted);
sb.append(", createTime=").append(createTime);
sb.append("]");
return sb.toString();
}
}
2.2.2 业务层
public interface BBSPostCategoryService {
/**
* 获取分类列表
*
* @return
*/
List<BBSPostCategory> getBBSPostCategories();
}
@Service
public class BBSPostCategoryServiceImpl implements BBSPostCategoryService {
@Autowired
private BBSPostCategoryMapper bbsPostCategoryMapper;
@Override
public List<BBSPostCategory> getBBSPostCategories() {
return bbsPostCategoryMapper.getBBSPostCategories();
}
}
2.2.3 数据持久层
public interface BBSPostCategoryMapper {
List<BBSPostCategory> getBBSPostCategories();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.picacho.bbs.dao.BBSPostCategoryMapper">
<resultMap id="BaseResultMap" type="top.picacho.bbs.entity.BBSPostCategory">
<id column="category_id" jdbcType="INTEGER" property="categoryId" />
<result column="category_name" jdbcType="VARCHAR" property="categoryName" />
<result column="category_rank" jdbcType="INTEGER" property="categoryRank" />
<result column="is_deleted" jdbcType="TINYINT" property="isDeleted" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
</resultMap>
<sql id="Base_Column_List">
category_id, category_name, category_rank, is_deleted, create_time
</sql>
<select id="getBBSPostCategories" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from tb_post_category
where is_deleted = 0 order by category_rank desc
</select>
</mapper>
2.3 创建帖子
接下来,把编辑页面按照字段来完善一下,将帖子表中需要输入内容的字段填充到页面 DOM 中。
其中帖子标题字段是直接使用的 input 框,帖子详情内容的输入使用的是 wangEditor 编辑器,发布按钮在页面的右上角并绑定了 onclick() 事件,点击后由 addBBSPost() 方法进行处理。最后把富文本编辑器和图片上传插件的初始化代码加进来。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="header::head-fragment('发布帖子')">
</head>
<body>
<div th:replace="header::header-fragment"></div>
<div class="layui-container fly-marginTop">
<div class="fly-panel" pad20 style="padding-top: 5px;">
<div class="layui-form layui-form-pane">
<div class="layui-tab layui-tab-brief" lay-filter="user">
<ul class="layui-tab-title">
<li class="layui-this">发表新帖<!-- 编辑帖子 --></li>
</ul>
<div class="layui-form layui-tab-content" id="LAY_ucm" style="padding: 20px 0;">
<div class="layui-tab-item layui-show">
<form method="post" id="postForm" onsubmit="return false;" action="##">
<div class="layui-row layui-col-space15 layui-form-item">
<div class="layui-col-md6">
<label for="postTitle" class="layui-form-label">标题</label>
<div class="layui-input-block">
<input type="text" id="postTitle" name="postTitle" required
autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-col-md6">
<label class="layui-form-label">所在专栏</label>
<div class="layui-input-block">
<select name="class" lay-filter="column"
id="postCategoryId">
<option value="0"></option>
<th:block th:unless="${null == bbsPostCategories}">
<th:block th:each="c : ${bbsPostCategories}">
<option th:value="${c.categoryId}" th:text="${c.categoryName}">提问
</option>
</th:block>
</th:block>
</select>
</div>
</div>
</div>
<div class="layui-form-item layui-form-text">
<div class="layui-input-block">
<div id="wangEditor" name="postContent" required
placeholder="详细描述"
style="height: 260px;"></div>
</div>
</div>
<div class="layui-form-item" style="margin-top: 56px;">
<label for="verifyCode" class="layui-form-label">验证码</label>
<div class="layui-input-inline">
<input type="text" id="verifyCode" name="verifyCode" required
placeholder="验证码" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-mid">
<span style="color: #c00;"><img data-tooltip="看不清楚?换一张"
th:src="@{/common/captcha}"
onclick="this.src='/common/captcha?d='+new Date()*1"
alt="单击图片刷新!"></span>
</div>
</div>
<div class="layui-form-item">
<button class="layui-btn" lay-filter="*" lay-submit onclick="addBBSPost()">立即发布</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="fly-footer">
<p>My-BBS社区 2021 © <a href="填写自己的博客" target="_blank">picacho</a></p>
</div>
<script th:src="@{/js/public.js}"></script>
<script th:src="@{/layui/layui.js}"></script>
<!-- wangEditor -->
<script type="text/javascript" src="//unpkg.com/wangeditor/dist/wangEditor.min.js"></script>
<script type="text/javascript">
layui.use(['layer', 'element', 'jquery', 'form'], function () {
var layer = layui.layer, $ = layui.$, element = layui.element, form = layui.form;
var editorD;
//富文本编辑器,用于帖子详情编辑
const E = window.wangEditor;
editorD = new E('#wangEditor')
// 设置编辑区域高度为 260px
editorD.config.height = 260
editorD.config.zIndex = 1
//配置服务端图片上传地址
editorD.config.uploadImgServer = '/uploadFiles'
editorD.config.uploadFileName = 'files'
//限制图片大小 2M
editorD.config.uploadImgMaxSize = 2 * 1024 * 1024
//限制一次最多能传几张图片 一次最多上传 5 个图片
editorD.config.uploadImgMaxLength = 5
//隐藏插入网络图片的功能
editorD.config.showLinkImg = false
editorD.config.uploadImgHooks = {
// 图片上传并返回了结果,图片插入已成功
success: function (xhr) {
console.log('success', xhr)
},
// 图片上传并返回了结果,但图片插入时出错了
fail: function (xhr, editor, resData) {
console.log('fail', resData)
},
// 上传图片出错,一般为 http 请求的错误
error: function (xhr, editor, resData) {
console.log('error', xhr, resData)
},
// 上传图片超时
timeout: function (xhr) {
console.log('timeout')
},
customInsert: function (insertImgFn, result) {
if (result != null && result.resultCode == 200) {
// insertImgFn 可把图片插入到编辑器,传入图片 src ,执行函数即可
result.data.forEach(img => {
insertImgFn(img)
});
} else {
alert("error");
}
}
}
editorD.create();
});
</script>
</body>
</html>
2.4 测试效果
同样该请求需要在登陆状态下访问,http://localhost:8080/addPostPage。可以看到查询到帖子的分类列表。
3.完成发帖功能
3.1 帖子实体类
/**
* 帖子-实体类
*/
public class BBSPost {
private Long postId;
private Long publishUserId;
private String postTitle;
private Integer postCategoryId;
private String postCategoryName;
private Byte postStatus;
private Long postViews;
private Long postComments;
private Long postCollects;
private Date lastUpdateTime;
private Date createTime;
private String postContent;
public Long getPostId() {
return postId;
}
public void setPostId(Long postId) {
this.postId = postId;
}
public Long getPublishUserId() {
return publishUserId;
}
public void setPublishUserId(Long publishUserId) {
this.publishUserId = publishUserId;
}
public String getPostTitle() {
return postTitle;
}
public void setPostTitle(String postTitle) {
this.postTitle = postTitle == null ? null : postTitle.trim();
}
public Integer getPostCategoryId() {
return postCategoryId;
}
public void setPostCategoryId(Integer postCategoryId) {
this.postCategoryId = postCategoryId;
}
public String getPostCategoryName() {
return postCategoryName;
}
public void setPostCategoryName(String postCategoryName) {
this.postCategoryName = postCategoryName == null ? null : postCategoryName.trim();
}
public Byte getPostStatus() {
return postStatus;
}
public void setPostStatus(Byte postStatus) {
this.postStatus = postStatus;
}
public Long getPostViews() {
return postViews;
}
public void setPostViews(Long postViews) {
this.postViews = postViews;
}
public Long getPostComments() {
return postComments;
}
public void setPostComments(Long postComments) {
this.postComments = postComments;
}
public Long getPostCollects() {
return postCollects;
}
public void setPostCollects(Long postCollects) {
this.postCollects = postCollects;
}
public Date getLastUpdateTime() {
return lastUpdateTime;
}
public void setLastUpdateTime(Date lastUpdateTime) {
this.lastUpdateTime = lastUpdateTime;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getPostContent() {
return postContent;
}
public void setPostContent(String postContent) {
this.postContent = postContent == null ? null : postContent.trim();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", postId=").append(postId);
sb.append(", publishUserId=").append(publishUserId);
sb.append(", postTitle=").append(postTitle);
sb.append(", postCategoryId=").append(postCategoryId);
sb.append(", postCategoryName=").append(postCategoryName);
sb.append(", postStatus=").append(postStatus);
sb.append(", postViews=").append(postViews);
sb.append(", postComments=").append(postComments);
sb.append(", postCollects=").append(postCollects);
sb.append(", lastUpdateTime=").append(lastUpdateTime);
sb.append(", createTime=").append(createTime);
sb.append(", postContent=").append(postContent);
sb.append("]");
return sb.toString();
}
}
3.2 帖子发布接口
帖子发布接口负责接收前端的 POST 请求并处理其中的参数,接收的参数为用户在帖子编辑页面输入的所有字段内容,字段名称与对应的含义如下:
- “postTitle”: 帖子标题
- “postCategoryId”: 帖子类别
- “postContent”: 帖子内容(wangEditor 编辑器中的内容)
- “verifyCode”:验证码
3.2.1 BBSPostController控制层
在 BBSPostController 中新增 addPost() 方法,接口的映射地址为 /addPost,请求方法为 POST。
/**
* 添加一条帖子数据
*/
@PostMapping("/addPost")
@ResponseBody
public Result addPost(@RequestParam("postTitle") String postTitle,
@RequestParam("postCategoryId") Integer postCategoryId,
@RequestParam("postContent") String postContent,
@RequestParam("verifyCode") String verifyCode,
HttpSession httpSession) {
if (!StringUtils.hasLength(postTitle)) {
return ResultGenerator.genFailResult("postTitle参数错误");
}
if (null == postCategoryId || postCategoryId < 0) {
return ResultGenerator.genFailResult("postCategoryId参数错误");
}
BBSPostCategory bbsPostCategory = bbsPostCategoryService.selectById(postCategoryId);
if (null == bbsPostCategory) {
return ResultGenerator.genFailResult("postCategoryId参数错误");
}
if (!StringUtils.hasLength(postContent)) {
return ResultGenerator.genFailResult("postContent参数错误");
}
if (postTitle.trim().length() > 32) {
return ResultGenerator.genFailResult("标题过长");
}
if (postContent.trim().length() > 100000) {
return ResultGenerator.genFailResult("内容过长");
}
String kaptchaCode = httpSession.getAttribute(Constants.VERIFY_CODE_KEY) + "";
if (!StringUtils.hasLength(kaptchaCode) || !verifyCode.equals(kaptchaCode)) {
return ResultGenerator.genFailResult(ServiceResultEnum.LOGIN_VERIFY_CODE_ERROR.getResult());
}
BBSUser bbsUser = (BBSUser) httpSession.getAttribute(Constants.USER_SESSION_KEY);
BBSPost bbsPost = new BBSPost();
bbsPost.setPublishUserId(bbsUser.getUserId());
bbsPost.setPostTitle(postTitle);
bbsPost.setPostContent(postContent);
bbsPost.setPostCategoryId(postCategoryId);
bbsPost.setPostCategoryName(bbsPostCategory.getCategoryName());
if (bbsPostService.savePost(bbsPost) > 0) {
httpSession.removeAttribute(Constants.VERIFY_CODE_KEY);//清空session中的验证码信息
return ResultGenerator.genSuccessResult();
} else {
return ResultGenerator.genFailResult("请求失败,请检查参数及账号是否有操作权限");
}
}
添加接口中,首先会对参数进行校验,之后获取当前登录用户的信息,并将帖子实体的 publishUserId 字段设置好,之后交给业务层代码进行操作。
由于要检查帖子分类的合法性,所以需要通过帖子分类id来查询分类,是否为一个存在的分类。
3.2.2 通过id获取帖子分类功能
业务层
BBSPostCategory selectById(Integer categoryId);
@Override
public BBSPostCategory selectById(Integer categoryId) {
return bbsPostCategoryMapper.selectByPrimaryKey(categoryId);
}
数据持久层
BBSPostCategory selectByPrimaryKey(Integer categoryId);
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from tb_post_category
where category_id = #{categoryId,jdbcType=INTEGER}
</select>
3.2.3 业务层
service 包中新建 BBSPostService 并定义接口方法 savePost()。
public interface BBSPostService {
/**
* 保存帖子
*
* @param bbsPost
* @return
*/
int savePost(BBSPost bbsPost);
}
@Service
public class BBSPostServiceImpl implements BBSPostService {
@Autowired
private BBSPostCategoryMapper bbsPostCategoryMapper;
@Autowired
private BBSPostMapper bbsPostMapper;
@Autowired
private BBSUserMapper bbsUserMapper;
@Override
public int savePost(BBSPost bbsPost) {
BBSUser bbsUser = bbsUserMapper.selectByPrimaryKey(bbsPost.getPublishUserId());
if (bbsUser == null || bbsUser.getUserStatus().intValue() == 1) {
//账号已被封禁
return 0;
}
BBSPostCategory bbsPostCategory = bbsPostCategoryMapper.selectByPrimaryKey(bbsPost.getPostCategoryId());
if (bbsPostCategory == null) {
//分类数据错误
return 0;
}
return bbsPostMapper.insertSelective(bbsPost);
}
}
帖子添加接口的业务实现方法操作步骤如下:
- 根据 publishUserId 查询当前登录用户信息
- 如果账号不存在或者账号已被封禁则返回错误信息
- 根据 postCategoryId 查询分类信息
- 如果分类数据错误返回错误信息
- 进行入库操作,向帖子表中新增一条记录
- 将新增结果返回给上层调用方法
3.2.4 数据持久层
public interface BBSPostMapper {
int insertSelective(BBSPost record);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.picacho.bbs.dao.BBSPostMapper">
<resultMap id="BaseResultMap" type="top.picacho.bbs.entity.BBSPost">
<id column="post_id" jdbcType="BIGINT" property="postId"/>
<result column="publish_user_id" jdbcType="BIGINT" property="publishUserId"/>
<result column="post_title" jdbcType="VARCHAR" property="postTitle"/>
<result column="post_category_id" jdbcType="INTEGER" property="postCategoryId"/>
<result column="post_category_name" jdbcType="VARCHAR" property="postCategoryName"/>
<result column="post_status" jdbcType="TINYINT" property="postStatus"/>
<result column="post_views" jdbcType="BIGINT" property="postViews"/>
<result column="post_comments" jdbcType="BIGINT" property="postComments"/>
<result column="post_collects" jdbcType="BIGINT" property="postCollects"/>
<result column="last_update_time" jdbcType="TIMESTAMP" property="lastUpdateTime"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="top.picacho.bbs.entity.BBSPost">
<result column="post_content" jdbcType="LONGVARCHAR" property="postContent"/>
</resultMap>
<sql id="Base_Column_List">
post_id, publish_user_id, post_title, post_category_id, post_category_name,
post_status, post_views, post_comments, post_collects, last_update_time,
create_time
</sql>
<sql id="Blob_Column_List">
post_content
</sql>
<insert id="insertSelective" parameterType="top.picacho.bbs.entity.BBSPost">
insert into tb_bbs_post
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="postId != null">
post_id,
</if>
<if test="publishUserId != null">
publish_user_id,
</if>
<if test="postTitle != null">
post_title,
</if>
<if test="postCategoryId != null">
post_category_id,
</if>
<if test="postCategoryName != null">
post_category_name,
</if>
<if test="postStatus != null">
post_status,
</if>
<if test="postViews != null">
post_views,
</if>
<if test="postComments != null">
post_comments,
</if>
<if test="postCollects != null">
post_collects,
</if>
<if test="lastUpdateTime != null">
last_update_time,
</if>
<if test="createTime != null">
create_time,
</if>
<if test="postContent != null">
post_content,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="postId != null">
#{postId,jdbcType=BIGINT},
</if>
<if test="publishUserId != null">
#{publishUserId,jdbcType=BIGINT},
</if>
<if test="postTitle != null">
#{postTitle,jdbcType=VARCHAR},
</if>
<if test="postCategoryId != null">
#{postCategoryId,jdbcType=INTEGER},
</if>
<if test="postCategoryName != null">
#{postCategoryName,jdbcType=VARCHAR},
</if>
<if test="postStatus != null">
#{postStatus,jdbcType=TINYINT},
</if>
<if test="postViews != null">
#{postViews,jdbcType=BIGINT},
</if>
<if test="postComments != null">
#{postComments,jdbcType=BIGINT},
</if>
<if test="postCollects != null">
#{postCollects,jdbcType=BIGINT},
</if>
<if test="lastUpdateTime != null">
#{lastUpdateTime,jdbcType=TIMESTAMP},
</if>
<if test="createTime != null">
#{createTime,jdbcType=TIMESTAMP},
</if>
<if test="postContent != null">
#{postContent,jdbcType=LONGVARCHAR},
</if>
</trim>
</insert>
</mapper>
3.2.5 Ajax 调用帖子添加接口
在信息录入完成后可以点击页面的立即发布按钮,此时会调用后端接口并进行数据的交互。
window.addBBSPost = function () {
var postTitle = $("#postTitle").val();
if (isNull(postTitle)) {
layer.alert("请输入标题!", {
title: "提醒",
skin: "layui-layer-molv",
icon: 2,
});
return;
}
var verifyCode = $("#verifyCode").val();
if (!validLength(verifyCode, 5)) {
layer.alert("请输入正确的验证码!", {
title: "提醒",
skin: "layui-layer-molv",
icon: 2,
});
return;
}
var postCategoryId = $("#postCategoryId option:selected").val();
if (isNull(postCategoryId)) {
layer.alert("请选择分类!", {
title: "提醒",
skin: "layui-layer-molv",
icon: 2,
});
return;
}
var postContent = editorD.txt.html();
if (!validLength(postContent, 100000)) {
layer.alert("内容超出长度!", {
title: "提醒",
skin: "layui-layer-molv",
icon: 2,
});
return;
}
var url = "/addPost";
var data = {
postTitle: postTitle,
verifyCode: verifyCode,
postCategoryId: postCategoryId,
postContent: postContent,
};
$.ajax({
type: "POST", //方法类型
url: url,
data: data,
success: function (result) {
if (result.resultCode == 200) {
window.location.href = "/index";
} else {
layer.msg(result.message);
}
},
error: function () {
layer.alert("操作失败!", {
title: "提醒",
skin: "layui-layer-molv",
icon: 2,
});
},
});
};
该方法逻辑如下:
- 前端对用户输入的标题、帖子内容、验证码进行简单的正则验证
- 封装帖子实体的参数
- 向对应的后端发布帖子接口发送 Ajax 请求
- 请求成功后提醒用户请求成功并跳转到首页
- 请求失败则提醒对应的错误信息
4.验证效果
将帖子内容编辑完成,就可以点击立即发布完成发帖。
可以看到这个帖子被保存到了数据库了并且跳转到了首页,只是首页还没有制作完成,共用了登陆功能的跳转页面首页。
项目源码下载地址:源码下载