- 发送私信
- 采用异步的方式发送私信。
- 发送成功后刷新私信列表。
- 设置已读
- 访问私信详情时, 将显示的私信设置为已读状态。
发送私信
功能一览
数据层
首先在MessageMapper里新增两个方法,一个新增消息,一个修改消息状态的方法。
//新增消息
int insertMessage(Message message);
//修改状态
int updateStatus(List<Integer> ids,int status);
然后在message_mapper.xml里面实现这两个方法。
myBatis的foreach语句
<sql id="insertFields">
from_id,to_id,conversation_id,content,status,create_time
</sql>
<insert id="insertMessage" parameterType="Message" keyProperty="id">
insert into message(<include refid="insertFields"> </include>)
values(#{fromId},#{toId},#{conversationId},#{content},#{status},#{createTime})
</insert>
<update id="updateStatus">
update message set status = #{status}
where id in
<foreach collection="ids" item="id" open="(" separator="," close=")"> // myBatis的foreach语句
#{id} // 把集合 ids 里面的元素 id,拼接到 ( )里并用 , 分隔
</foreach>
</update>
where in
https://blog.csdn.net/k8080880/article/details/8482659
业务层
业务层很简单,主要就是过滤一个html标签和敏感词
public int addMessage(Message message){
message.setContent(HtmlUtils.htmlEscape(message.getContent())); // 过滤html标签
message.setContent(sensitiveFilter.filter(message.getContent())); // 过滤敏感词
return messageMapper.insertMessage(message);
}
public int readMessage(List<Integer> ids){
return messageMapper.updateStatus(ids,1);
}
表现层
首先是发送私信方法。这里我们需要补充一个方法,用户发送私信的时候肯定只知道用户名,所以在userService里新增一个用户名查找的方法。
public User findUserByName(String username){
return userMapper.selectByName(username);
}
接收前端传来的用户名和内容,创建message对象,补充相关内容,拼接conversationId的时候把小的拼在前面。返回服务器一个json字符串,表示处理post请求的结果
@RequestMapping(path = "/letter/send",method = RequestMethod.POST)
@ResponseBody
public String sendLetter(String toName,String content){
User target=userService.findUserByName(toName);
if (target==null){
return CommunityUtil.getJSONString(1,"目标用户不存在");
}
Message message=new Message();
message.setFromId(hostHolder.getUser().getId());
message.setToId(target.getId());
if(message.getFromId()<message.getToId()){
message.setConversationId(message.getFromId()+"_"+message.getToId());
}else {
message.setConversationId(message.getToId()+"_"+message.getFromId());
}
message.setContent(content);
message.setCreateTime(new Date());
messageService.addMessage(message);
return CommunityUtil.getJSONString(0); // 将服务器的返回结果,封装成json字符串
}
前端
AJAX
// jQuery库
$(function(){
$("#sendBtn").click(send_letter); // 单击弹出框 sendBtn 按钮时执行 send_letter()函数
$(".close").click(delete_msg);
});
function send_letter() {
$("#sendModal").modal("hide"); // 先隐藏弹出框
// 向服务器发送post
var toName = $("#recipient-name").val();
var content = $("#message-text").val();
$.post(
CONTEXT_PATH + "/letter/send",
{"toName":toName,"content":content},
function(data) {
data = $.parseJSON(data);
if(data.code == 0) { // 接受服务器返回数据
$("#hintBody").text("发送成功!");
} else {
$("#hintBody").text(data.msg);
}
$("#hintModal").modal("show"); // 隐藏弹出框,显示提示框
setTimeout(function(){
$("#hintModal").modal("hide");
location.reload(); // 重新载入当前文档,即2s后刷新
}, 2000);
}
);
}
function delete_msg() {
// TODO 删除数据
$(this).parents(".media").remove();
}
1、$(function(){ } 这是jquery里的,是当文档载入完毕就执行的意思。即页面所有的html标签(包括图片等)都加载完了,即浏览器已经响应完了,加载完了,全部展现到浏览器界面上了。
$(function(){})什么时候执行:
https://blog.csdn.net/sadleaflzh/article/details/81584144
2、用 JQuery 实现 AJAX
https://editor.csdn.net/md/?articleId=115605937#_50
未读消息设置已读
表现层
实现把未读消息改成已读。
在之前 私信详情
功能(getLetterDetail方法)里进行补充。首先写一个方法获取所有未读消息的id,之前已经获得过 letterList (这是当前用户 与 某个其它用户 的私信详情列表)
private List<Integer> getLetterIds(List<Message> letterList){
List<Integer> ids=new ArrayList<>();
if(letterList!=null){
for (Message message:letterList){
if(hostHolder.getUser().getId()==message.getToId() && message.getStatus()==0){
ids.add(message.getId());
}
}
}
return ids;
}
代码逻辑:当前用户的id(hostHolder.getUser().getId())是接受id(message.getToId()),且消息状态是未读(message.getStatus()==0),则将该消息的id 放入列表里返回。
然后在getLetterDetail方法里加上
//设置已读
List<Integer> ids =getLetterIds(letterList);
if (!ids.isEmpty()){
messageService.readMessage(ids);
}
代码逻辑:若 当前私信详情列表(letterList)的所有未读消息列表 ids 不为空,则使用业务层方法 messageService.readMessage,将未读消息设置为已读