216 lines
5.2 KiB
Markdown
216 lines
5.2 KiB
Markdown
|
# 发布帖子
|
|||
|
|
|||
|
---
|
|||
|
|
|||
|
<img src="https://gitee.com/veal98/images/raw/master/img/20210122102856.png" style="zoom: 33%;" />
|
|||
|
|
|||
|
## Util
|
|||
|
|
|||
|
工具类:将服务端返回的消息封装成 JSON 格式的字符串
|
|||
|
|
|||
|
```java
|
|||
|
/**
|
|||
|
* 将服务端返回的消息封装成 JSON 格式的字符串
|
|||
|
* @param code 状态码
|
|||
|
* @param msg 提示消息
|
|||
|
* @param map 业务数据
|
|||
|
* @return 返回 JSON 格式字符串
|
|||
|
*/
|
|||
|
public static String getJSONString(int code, String msg, Map<String, Object> map) {
|
|||
|
JSONObject json = new JSONObject();
|
|||
|
json.put("code", code);
|
|||
|
json.put("msg", msg);
|
|||
|
if (map != null) {
|
|||
|
for (String key : map.keySet()) {
|
|||
|
json.put(key, map.get(key));
|
|||
|
}
|
|||
|
}
|
|||
|
return json.toJSONString();
|
|||
|
}
|
|||
|
|
|||
|
// 重载 getJSONString 方法,服务端方法可能不返回业务数据
|
|||
|
public static String getJSONString(int code, String msg) {
|
|||
|
return getJSONString(code, msg, null);
|
|||
|
}
|
|||
|
|
|||
|
// 重载 getJSONString 方法,服务端方法可能不返回业务数据和提示消息
|
|||
|
public static String getJSONString(int code) {
|
|||
|
return getJSONString(code, null, null);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 测试
|
|||
|
* @param args
|
|||
|
*/
|
|||
|
public static void main(String[] args) {
|
|||
|
Map<String, Object> map = new HashMap<>();
|
|||
|
map.put("name", "Jack");
|
|||
|
map.put("age", 18);
|
|||
|
// {"msg":"ok","code":0,"name":"Jack","age":18}
|
|||
|
System.out.println(getJSONString(0, "ok", map));
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
|
|||
|
## DAO
|
|||
|
|
|||
|
`DiscussPostMapper`
|
|||
|
|
|||
|
```java
|
|||
|
/**
|
|||
|
* 插入/添加帖子
|
|||
|
* @param discussPost
|
|||
|
* @return
|
|||
|
*/
|
|||
|
int insertDiscussPost(DiscussPost discussPost);
|
|||
|
```
|
|||
|
|
|||
|
对应的 `mapper.xml`
|
|||
|
|
|||
|
```xml
|
|||
|
<!--插入/添加帖子-->
|
|||
|
<insert id="insertDiscussPost" parameterType="DiscussPost" keyProperty="id">
|
|||
|
insert into discuss_post (<include refid="insertFields"></include>)
|
|||
|
values(#{userId}, #{title}, #{content}, #{type}, #{status}, #{createTime}, #{commentCount}, #{score})
|
|||
|
</insert>
|
|||
|
```
|
|||
|
|
|||
|
## Service
|
|||
|
|
|||
|
```java
|
|||
|
/**
|
|||
|
* 添加帖子
|
|||
|
* @param discussPost
|
|||
|
* @return
|
|||
|
*/
|
|||
|
public int addDiscussPost(DiscussPost discussPost) {
|
|||
|
if (discussPost == null) {
|
|||
|
throw new IllegalArgumentException("参数不能为空");
|
|||
|
}
|
|||
|
|
|||
|
// 转义 HTML 标记,防止在 HTML 标签中注入攻击语句
|
|||
|
discussPost.setTitle(HtmlUtils.htmlEscape(discussPost.getTitle()));
|
|||
|
discussPost.setContent(HtmlUtils.htmlEscape(discussPost.getContent()));
|
|||
|
|
|||
|
// 过滤敏感词
|
|||
|
discussPost.setTitle(sensitiveFilter.filter(discussPost.getTitle()));
|
|||
|
discussPost.setContent(sensitiveFilter.filter(discussPost.getContent()));
|
|||
|
|
|||
|
return discussPostMapper.insertDiscussPost(discussPost);
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
转义 HTML 标记,防止在 HTML 标签中注入攻击语句,比如 `<script>alert('哈哈')</script>`
|
|||
|
|
|||
|
## Controller
|
|||
|
|
|||
|
```java
|
|||
|
@Controller
|
|||
|
@RequestMapping("/discuss")
|
|||
|
public class DiscussPostController {
|
|||
|
|
|||
|
@Autowired
|
|||
|
private DiscussPostSerivce discussPostSerivce;
|
|||
|
|
|||
|
@Autowired
|
|||
|
private HostHolder hostHolder;
|
|||
|
|
|||
|
/**
|
|||
|
* 添加帖子(发帖)
|
|||
|
* @param title
|
|||
|
* @param content
|
|||
|
* @return
|
|||
|
*/
|
|||
|
@PostMapping("/add")
|
|||
|
@ResponseBody
|
|||
|
public String addDiscussPost(String title, String content) {
|
|||
|
User user = hostHolder.getUser();
|
|||
|
if (user == null) {
|
|||
|
return CommunityUtil.getJSONString(403, "您还未登录");
|
|||
|
}
|
|||
|
|
|||
|
DiscussPost discussPost = new DiscussPost();
|
|||
|
discussPost.setUserId(user.getId());
|
|||
|
discussPost.setTitle(title);
|
|||
|
discussPost.setContent(content);
|
|||
|
discussPost.setCreateTime(new Date());
|
|||
|
|
|||
|
discussPostSerivce.addDiscussPost(discussPost);
|
|||
|
|
|||
|
// 报错的情况将来会统一处理
|
|||
|
return CommunityUtil.getJSONString(0, "发布成功");
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
|
|||
|
## 前端
|
|||
|
|
|||
|
```java
|
|||
|
<button data-toggle="modal" data-target="#publishModal"
|
|||
|
th:if="${loginUser != null}">我要发布</button>
|
|||
|
|
|||
|
<!-- 弹出框 -->
|
|||
|
<div class="modal fade" id="publishModal">
|
|||
|
标题:<input id="recipient-name">
|
|||
|
正文:<textarea id="message-text"></textarea>
|
|||
|
<button id="publishBtn">发布</button>
|
|||
|
</div>
|
|||
|
|
|||
|
<!-- 提示框 -->
|
|||
|
<div class="modal fade" id="hintModal">
|
|||
|
......
|
|||
|
</div>
|
|||
|
```
|
|||
|
|
|||
|
对应的 js:
|
|||
|
|
|||
|
```js
|
|||
|
$(function(){
|
|||
|
$("#publishBtn").click(publish);
|
|||
|
});
|
|||
|
|
|||
|
function publish() {
|
|||
|
$("#publishModal").modal("hide");
|
|||
|
// 获取标题和内容
|
|||
|
var title = $("#recipient-name").val();
|
|||
|
var content = $("#message-text").val();
|
|||
|
// 发送异步请求
|
|||
|
$.post(
|
|||
|
CONTEXT_PATH + "/discuss/add",
|
|||
|
{"title": title, "content": content},
|
|||
|
// 处理服务端返回的数据
|
|||
|
function (data) {
|
|||
|
// String -> Json 对象
|
|||
|
data = $.parseJSON(data);
|
|||
|
// 在提示框 hintBody 显示服务端返回的消息
|
|||
|
$("#hintBody").text(data.msg);
|
|||
|
// 显示提示框
|
|||
|
$("#hintModal").modal("show");
|
|||
|
// 2s 后自动隐藏提示框
|
|||
|
setTimeout(function(){
|
|||
|
$("#hintModal").modal("hide");
|
|||
|
// 刷新页面
|
|||
|
if (data.code == 0) {
|
|||
|
window.location.reload();
|
|||
|
}
|
|||
|
}, 2000);
|
|||
|
|
|||
|
}
|
|||
|
)
|
|||
|
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
|
|||
|
```js
|
|||
|
var title = $("#recipient-name").val();
|
|||
|
```
|
|||
|
|
|||
|
获取选择框 id = recipient-name 里面的值
|
|||
|
|