Browse Source

群聊功能开发中

master
xie.bx 3 years ago
parent
commit
67b4ead333
  1. 5
      im-platform/src/main/java/com/lx/implatform/entity/Group.java
  2. 11
      im-platform/src/main/java/com/lx/implatform/service/IGroupMemberService.java
  3. 57
      im-platform/src/main/java/com/lx/implatform/service/impl/GroupMemberServiceImpl.java
  4. 39
      im-platform/src/main/java/com/lx/implatform/service/impl/GroupServiceImpl.java
  5. 8
      im-platform/src/main/java/com/lx/implatform/vo/GroupVO.java
  6. 4
      im-ui/src/components/friend/AddFriend.vue
  7. 2
      im-ui/src/components/group/GroupItem.vue
  8. 10
      im-ui/src/store/groupStore.js
  9. 98
      im-ui/src/view/Group.vue

5
im-platform/src/main/java/com/lx/implatform/entity/Group.java

@ -63,11 +63,6 @@ public class Group extends Model<Group> {
@TableField("notice") @TableField("notice")
private String notice; private String notice;
/**
* 群备注
*/
@TableField("remark")
private String remark;
/** /**
* 创建时间 * 创建时间

11
im-platform/src/main/java/com/lx/implatform/service/IGroupMemberService.java

@ -3,6 +3,8 @@ package com.lx.implatform.service;
import com.lx.implatform.entity.GroupMember; import com.lx.implatform.entity.GroupMember;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/** /**
* <p> * <p>
* 群成员 服务类 * 群成员 服务类
@ -13,4 +15,13 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/ */
public interface IGroupMemberService extends IService<GroupMember> { public interface IGroupMemberService extends IService<GroupMember> {
GroupMember findByGroupAndUserId(Long groupId,Long userId);
List<GroupMember> findByUserId(Long userId);
List<GroupMember> findByGroupId(Long groupId);
void removeByGroupId(long groupId);
} }

57
im-platform/src/main/java/com/lx/implatform/service/impl/GroupMemberServiceImpl.java

@ -1,11 +1,14 @@
package com.lx.implatform.service.impl; package com.lx.implatform.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lx.implatform.entity.GroupMember; import com.lx.implatform.entity.GroupMember;
import com.lx.implatform.mapper.GroupMemberMapper; import com.lx.implatform.mapper.GroupMemberMapper;
import com.lx.implatform.service.IGroupMemberService; import com.lx.implatform.service.IGroupMemberService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List;
/** /**
* <p> * <p>
* 群成员 服务实现类 * 群成员 服务实现类
@ -17,4 +20,58 @@ import org.springframework.stereotype.Service;
@Service @Service
public class GroupMemberServiceImpl extends ServiceImpl<GroupMemberMapper, GroupMember> implements IGroupMemberService { public class GroupMemberServiceImpl extends ServiceImpl<GroupMemberMapper, GroupMember> implements IGroupMemberService {
/**
* 根据群聊id和用户id查询群聊成员
*
* @param groupId 群聊id
* @param userId 用户id
* @return
*/
@Override
public GroupMember findByGroupAndUserId(Long groupId, Long userId) {
QueryWrapper<GroupMember> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(GroupMember::getGroupId,groupId)
.eq(GroupMember::getUserId,userId);
return this.getOne(wrapper);
}
/**
* 根据用户id查询群聊成员
*
* @param userId 用户id
* @return
*/
@Override
public List<GroupMember> findByUserId(Long userId) {
QueryWrapper<GroupMember> memberWrapper = new QueryWrapper();
memberWrapper.lambda().eq(GroupMember::getUserId, userId);
return this.list(memberWrapper);
}
/**
* 根据群聊id查询群聊成员
*
* @param groupId 群聊id
* @return
*/
@Override
public List<GroupMember> findByGroupId(Long groupId) {
QueryWrapper<GroupMember> memberWrapper = new QueryWrapper();
memberWrapper.lambda().eq(GroupMember::getGroupId, groupId);
return this.list(memberWrapper);
}
/**
*根据群聊id删除成员信息
*
* @param groupId 群聊id
* @return
*/
@Override
public void removeByGroupId(long groupId) {
QueryWrapper<GroupMember> wrapper = new QueryWrapper();
wrapper.lambda().eq(GroupMember::getGroupId,groupId);
this.remove(wrapper);
}
} }

39
im-platform/src/main/java/com/lx/implatform/service/impl/GroupServiceImpl.java

@ -20,6 +20,7 @@ import com.lx.implatform.session.UserSession;
import com.lx.implatform.vo.GroupInviteVO; import com.lx.implatform.vo.GroupInviteVO;
import com.lx.implatform.vo.GroupMemberVO; import com.lx.implatform.vo.GroupMemberVO;
import com.lx.implatform.vo.GroupVO; import com.lx.implatform.vo.GroupVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -76,17 +77,25 @@ public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements
* @Param GroupVO 群聊信息 * @Param GroupVO 群聊信息
* @return GroupVO * @return GroupVO
**/ **/
@Transactional
@Override @Override
public GroupVO modifyGroup(GroupVO vo) { public GroupVO modifyGroup(GroupVO vo) {
UserSession session = SessionContext.getSession(); UserSession session = SessionContext.getSession();
// 校验是不是群主,只有群主能改信息 // 校验是不是群主,只有群主能改信息
Group group = this.getById(vo.getId()); Group group = this.getById(vo.getId());
if(group.getOwnerId() != session.getId()){ // 群主有权修改群基本信息
throw new GlobalException(ResultCode.PROGRAM_ERROR,"您不是群主,不可修改群信息"); if(group.getOwnerId() == session.getId()){
group = BeanUtils.copyProperties(vo,Group.class);
this.save(group);
} }
// 保存群信息 // 更新成员信息
group = BeanUtils.copyProperties(vo,Group.class); GroupMember member = groupMemberService.findByGroupAndUserId(vo.getId(),session.getId());
this.save(group); if(member == null){
throw new GlobalException(ResultCode.PROGRAM_ERROR,"您不是群聊的成员");
}
member.setAliasName(StringUtils.isEmpty(vo.getAliasName())?session.getNickName():vo.getAliasName());
member.setRemark(StringUtils.isEmpty(vo.getRemark())?group.getName():vo.getRemark());
groupMemberService.updateById(member);
return vo; return vo;
} }
@ -110,9 +119,7 @@ public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements
// 删除群数据 // 删除群数据
this.removeById(groupId); this.removeById(groupId);
// 删除成员数据 // 删除成员数据
QueryWrapper<GroupMember> wrapper = new QueryWrapper(); groupMemberService.removeByGroupId(groupId);
wrapper.lambda().eq(GroupMember::getGroupId,groupId);
groupMemberService.remove(wrapper);
} }
/** /**
@ -124,9 +131,7 @@ public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements
public List<GroupVO> findGroups() { public List<GroupVO> findGroups() {
UserSession session = SessionContext.getSession(); UserSession session = SessionContext.getSession();
// 查询当前用户的群id列表 // 查询当前用户的群id列表
QueryWrapper<GroupMember> memberWrapper = new QueryWrapper(); List<GroupMember> groupMembers = groupMemberService.findByUserId(session.getId());
memberWrapper.lambda().eq(GroupMember::getUserId, session.getId());
List<GroupMember> groupMembers = groupMemberService.list(memberWrapper);
if(groupMembers.isEmpty()){ if(groupMembers.isEmpty()){
return Collections.EMPTY_LIST; return Collections.EMPTY_LIST;
} }
@ -138,6 +143,9 @@ public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements
// 转vo // 转vo
List<GroupVO> vos = groups.stream().map(g -> { List<GroupVO> vos = groups.stream().map(g -> {
GroupVO vo = BeanUtils.copyProperties(g, GroupVO.class); GroupVO vo = BeanUtils.copyProperties(g, GroupVO.class);
GroupMember member = groupMembers.stream().filter(m -> g.getId() == m.getGroupId()).findFirst().get();
vo.setAliasName(member.getAliasName());
vo.setRemark(member.getRemark());
return vo; return vo;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
return vos; return vos;
@ -153,9 +161,7 @@ public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements
public void invite(GroupInviteVO vo) { public void invite(GroupInviteVO vo) {
UserSession session = SessionContext.getSession(); UserSession session = SessionContext.getSession();
// 群聊人数校验 // 群聊人数校验
QueryWrapper<GroupMember> memberWrapper = new QueryWrapper(); List<GroupMember> members = groupMemberService.findByGroupId(vo.getGroupId());
memberWrapper.lambda().eq(GroupMember::getGroupId, vo.getGroupId());
List<GroupMember> members = groupMemberService.list(memberWrapper);
if(vo.getFriendIds().size() + members.size() > Constant.MAX_GROUP_MEMBER){ if(vo.getFriendIds().size() + members.size() > Constant.MAX_GROUP_MEMBER){
throw new GlobalException(ResultCode.PROGRAM_ERROR, "群聊人数不能大于"+Constant.MAX_GROUP_MEMBER+"人"); throw new GlobalException(ResultCode.PROGRAM_ERROR, "群聊人数不能大于"+Constant.MAX_GROUP_MEMBER+"人");
} }
@ -196,10 +202,7 @@ public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements
**/ **/
@Override @Override
public List<GroupMemberVO> findGroupMembers(Long groupId) { public List<GroupMemberVO> findGroupMembers(Long groupId) {
QueryWrapper<GroupMember> memberWrapper = new QueryWrapper(); List<GroupMember> members = groupMemberService.findByGroupId(groupId);
memberWrapper.lambda().eq(GroupMember::getGroupId, groupId);
List<GroupMember> members = groupMemberService.list(memberWrapper);
List<GroupMemberVO> vos = members.stream().map(m->{ List<GroupMemberVO> vos = members.stream().map(m->{
GroupMemberVO vo = BeanUtils.copyProperties(m,GroupMemberVO.class); GroupMemberVO vo = BeanUtils.copyProperties(m,GroupMemberVO.class);
return vo; return vo;

8
im-platform/src/main/java/com/lx/implatform/vo/GroupVO.java

@ -23,7 +23,7 @@ public class GroupVO {
@ApiModelProperty(value = "群名称") @ApiModelProperty(value = "群名称")
private String name; private String name;
@NotEmpty(message = "群主id不可为空") @NotNull(message = "群主id不可为空")
@ApiModelProperty(value = "群主id") @ApiModelProperty(value = "群主id")
private Long ownerId; private Long ownerId;
@ -36,8 +36,10 @@ public class GroupVO {
@ApiModelProperty(value = "群公告") @ApiModelProperty(value = "群公告")
private String notice; private String notice;
@ApiModelProperty(value = "群备注") @ApiModelProperty(value = "用户在群显示昵称")
private String remark; private String aliasName;
@ApiModelProperty(value = "群聊显示备注")
private String remark;
} }

4
im-ui/src/components/friend/AddFriend.vue

@ -1,6 +1,6 @@
<template> <template>
<el-dialog title="添加好友" :visible.sync="dialogVisible" width="350px" :before-close="handleClose"> <el-dialog title="添加好友" :visible.sync="dialogVisible" width="30%" :before-close="handleClose">
<el-input width="200px" placeholder="搜索好友" class="input-with-select" v-model="searchText" @keyup.enter.native="handleSearch()"> <el-input placeholder="搜索好友" class="input-with-select" v-model="searchText" @keyup.enter.native="handleSearch()">
<el-button slot="append" icon="el-icon-search" @click="handleSearch()"></el-button> <el-button slot="append" icon="el-icon-search" @click="handleSearch()"></el-button>
</el-input> </el-input>
<el-scrollbar style="height:400px"> <el-scrollbar style="height:400px">

2
im-ui/src/components/group/GroupItem.vue

@ -4,7 +4,7 @@
<head-image :url="group.headImage"> </head-image> <head-image :url="group.headImage"> </head-image>
</div> </div>
<div class="text"> <div class="text">
<div>{{group.name}}</div> <div>{{group.remark}}</div>
</div> </div>
</div> </div>
</template> </template>

10
im-ui/src/store/groupStore.js

@ -20,6 +20,16 @@ export default {
}, },
activeGroup(state,index){ activeGroup(state,index){
state.activeIndex = index; state.activeIndex = index;
},
addGroup(state,group){
state.groups.unshift(group);
},
updateGroup(state,group){
state.groups.forEach((g,index)=>{
if(g.id==group.id){
state.groups[index] = group;
}
})
} }
} }
} }

98
im-ui/src/view/Group.vue

@ -12,14 +12,14 @@
</div> </div>
<div v-for="(group,index) in groupStore.groups" :key="group.id"> <div v-for="(group,index) in groupStore.groups" :key="group.id">
<group-item v-show="group.name.startsWith(searchText)" :group="group" :active="index === groupStore.activeIndex" <group-item v-show="group.remark.startsWith(searchText)" :group="group" :active="index === groupStore.activeIndex"
@click.native="handleActiveItem(group,index)"> @click.native="handleActiveItem(group,index)">
</group-item> </group-item>
</div> </div>
</el-aside> </el-aside>
<el-container class="r-group-box"> <el-container class="r-group-box">
<div class="r-group-header"> <div class="r-group-header">
{{activeGroup.name}} {{activeGroup.remark}}
</div> </div>
<div class="r-group-container"> <div class="r-group-container">
<div v-show="groupStore.activeIndex>=0"> <div v-show="groupStore.activeIndex>=0">
@ -45,28 +45,25 @@
</el-form> </el-form>
</div> </div>
<div class="btn-group"> <div class="btn-group">
<el-button class="send-btn" @click="handleSendMessage()">保存</el-button> <el-button class="send-btn" @click="handleSaveGroup()">保存</el-button>
<el-button class="send-btn" @click="handleSendMessage()">发消息</el-button> <el-button class="send-btn" @click="handleSendMessage()">发消息</el-button>
<el-button type="danger" class="send-btn" @click="handleSendMessage()">退出</el-button> <el-button type="danger" class="send-btn" @click="handleSendMessage()">退出</el-button>
<el-button type="danger" class="send-btn" @click="handleSendMessage()">解散</el-button> <el-button type="danger" class="send-btn" @click="handleSendMessage()">解散</el-button>
</div> </div>
<el-divider content-position="center"></el-divider> <el-divider content-position="center"></el-divider>
<el-scrollbar style="height:400px;"> <el-scrollbar style="height:400px;">
<div class="r-group-member-list"> <div class="r-group-member-list">
<div v-for="(member) in groupMembers" :key="member.id"> <div v-for="(member) in groupMembers" :key="member.id">
<group-member class="r-group-member" :member="member" :showDel="true"></group-member> <group-member class="r-group-member" :member="member" :showDel="true"></group-member>
</div> </div>
<div class="r-group-invite"> <div class="r-group-invite">
<div class="invite-member-btn" title="邀请好友进群聊" @click="handleInviteMember()"> <div class="invite-member-btn" title="邀请好友进群聊" @click="handleInviteMember()">
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
</div>
<div class="invite-member-text">邀请</div>
<add-group-member :visible="showAddGroupMember"
:groupId="activeGroup.id"
:members="groupMembers"
@reload="loadGroupMembers"
@close="handleCloseAddGroupMember"></add-group-member>
</div> </div>
<div class="invite-member-text">邀请</div>
<add-group-member :visible="showAddGroupMember" :groupId="activeGroup.id" :members="groupMembers" @reload="loadGroupMembers"
@close="handleCloseAddGroupMember"></add-group-member>
</div>
</div> </div>
</el-scrollbar> </el-scrollbar>
</div> </div>
@ -94,7 +91,11 @@
return { return {
searchText: "", searchText: "",
maxSize: 5 * 1024 * 1024, maxSize: 5 * 1024 * 1024,
groupMembers:[], activeGroup: {
empty: true,
remark: ""
},
groupMembers: [],
showAddGroupMember: false showAddGroupMember: false
}; };
}, },
@ -109,35 +110,48 @@
this.$http({ this.$http({
url: `/api/group/create?groupName=${o.value}`, url: `/api/group/create?groupName=${o.value}`,
method: 'post' method: 'post'
}).then((groupInfo) => { }).then((group) => {
console.log(groupInfo); this.$store.commit("addGroup", group);
}) })
}) })
}, },
handleActiveItem(group, index) { handleActiveItem(group, index) {
this.$store.commit("activeGroup", index); this.$store.commit("activeGroup", index);
// store
this.activeGroup = JSON.parse(JSON.stringify(group));
// //
this.loadGroupMembers(); this.loadGroupMembers();
}, },
handleInviteMember(){ handleInviteMember() {
this.showAddGroupMember = true; this.showAddGroupMember = true;
}, },
handleCloseAddGroupMember(){ handleCloseAddGroupMember() {
this.showAddGroupMember = false; this.showAddGroupMember = false;
}, },
handleUploadSuccess() { handleUploadSuccess(res) {
this.activeGroup.headImage = res.data.originUrl;
this.activeGroup.headImageThumb = res.data.thumbUrl;
},
handleSaveGroup() {
let vo = this.activeGroup;
this.$http({
url: "/api/group/modify",
method: "put",
data: vo
}).then((group) => {
this.$store.commit("updateGroup",group);
this.$message.success("修改成功");
})
}, },
handleSendMessage() { handleSendMessage() {
}, },
loadGroupMembers() {
loadGroupMembers(){
this.$http({ this.$http({
url: `/api/group/members/${this.activeGroup.id}`, url: `/api/group/members/${this.activeGroup.id}`,
method: "get" method: "get"
}).then((members)=>{ }).then((members) => {
this.groupMembers = members; this.groupMembers = members;
}) })
} }
@ -145,18 +159,6 @@
computed: { computed: {
groupStore() { groupStore() {
return this.$store.state.groupStore; return this.$store.state.groupStore;
},
activeGroup() {
if (this.groupStore.activeIndex >= 0) {
return this.groupStore.groups[this.groupStore.activeIndex];
}
return this.emptyGroup;
},
emptyGroup() {
return {
empty: true,
name: ""
}
} }
} }
} }
@ -174,6 +176,7 @@
align-items: center; align-items: center;
padding: 5px; padding: 5px;
background-color: white; background-color: white;
.l-group-search { .l-group-search {
flex: 1; flex: 1;
} }
@ -239,23 +242,25 @@
} }
} }
.r-group-member-list{ .r-group-member-list {
padding: 20px; padding: 20px;
display: flex; display: flex;
align-items: center; align-items: center;
flex-wrap: wrap; flex-wrap: wrap;
font-size: 16px; font-size: 16px;
text-align: center; text-align: center;
.r-group-member { .r-group-member {
margin-right: 15px ; margin-right: 15px;
} }
.r-group-invite{ .r-group-invite {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
width: 60px; width: 60px;
.invite-member-btn{
.invite-member-btn {
width: 100%; width: 100%;
height: 60px; height: 60px;
line-height: 60px; line-height: 60px;
@ -263,7 +268,8 @@
font-size: 25px; font-size: 25px;
cursor: pointer; cursor: pointer;
box-sizing: border-box; box-sizing: border-box;
&:hover{
&:hover {
border: #aaaaaa solid 1px; border: #aaaaaa solid 1px;
} }
} }
@ -275,8 +281,8 @@
height: 30px; height: 30px;
line-height: 30px; line-height: 30px;
white-space: nowrap; white-space: nowrap;
text-overflow:ellipsis; text-overflow: ellipsis;
overflow:hidden overflow: hidden
} }
} }

Loading…
Cancel
Save