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. 106
      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")
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.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
* 群成员 服务类
@ -13,4 +15,13 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
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;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lx.implatform.entity.GroupMember;
import com.lx.implatform.mapper.GroupMemberMapper;
import com.lx.implatform.service.IGroupMemberService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* <p>
* 群成员 服务实现类
@ -17,4 +20,58 @@ import org.springframework.stereotype.Service;
@Service
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.GroupMemberVO;
import com.lx.implatform.vo.GroupVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -76,17 +77,25 @@ public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements
* @Param GroupVO 群聊信息
* @return GroupVO
**/
@Transactional
@Override
public GroupVO modifyGroup(GroupVO vo) {
UserSession session = SessionContext.getSession();
// 校验是不是群主,只有群主能改信息
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);
this.save(group);
// 更新成员信息
GroupMember member = groupMemberService.findByGroupAndUserId(vo.getId(),session.getId());
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;
}
@ -110,9 +119,7 @@ public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements
// 删除群数据
this.removeById(groupId);
// 删除成员数据
QueryWrapper<GroupMember> wrapper = new QueryWrapper();
wrapper.lambda().eq(GroupMember::getGroupId,groupId);
groupMemberService.remove(wrapper);
groupMemberService.removeByGroupId(groupId);
}
/**
@ -124,9 +131,7 @@ public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements
public List<GroupVO> findGroups() {
UserSession session = SessionContext.getSession();
// 查询当前用户的群id列表
QueryWrapper<GroupMember> memberWrapper = new QueryWrapper();
memberWrapper.lambda().eq(GroupMember::getUserId, session.getId());
List<GroupMember> groupMembers = groupMemberService.list(memberWrapper);
List<GroupMember> groupMembers = groupMemberService.findByUserId(session.getId());
if(groupMembers.isEmpty()){
return Collections.EMPTY_LIST;
}
@ -138,6 +143,9 @@ public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements
// 转vo
List<GroupVO> vos = groups.stream().map(g -> {
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;
}).collect(Collectors.toList());
return vos;
@ -153,9 +161,7 @@ public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements
public void invite(GroupInviteVO vo) {
UserSession session = SessionContext.getSession();
// 群聊人数校验
QueryWrapper<GroupMember> memberWrapper = new QueryWrapper();
memberWrapper.lambda().eq(GroupMember::getGroupId, vo.getGroupId());
List<GroupMember> members = groupMemberService.list(memberWrapper);
List<GroupMember> members = groupMemberService.findByGroupId(vo.getGroupId());
if(vo.getFriendIds().size() + members.size() > 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
public List<GroupMemberVO> findGroupMembers(Long groupId) {
QueryWrapper<GroupMember> memberWrapper = new QueryWrapper();
memberWrapper.lambda().eq(GroupMember::getGroupId, groupId);
List<GroupMember> members = groupMemberService.list(memberWrapper);
List<GroupMember> members = groupMemberService.findByGroupId(groupId);
List<GroupMemberVO> vos = members.stream().map(m->{
GroupMemberVO vo = BeanUtils.copyProperties(m,GroupMemberVO.class);
return vo;

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

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

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

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

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

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

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

@ -20,6 +20,16 @@ export default {
},
activeGroup(state,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;
}
})
}
}
}

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

@ -12,14 +12,14 @@
</div>
<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)">
</group-item>
</div>
</el-aside>
<el-container class="r-group-box">
<div class="r-group-header">
{{activeGroup.name}}
{{activeGroup.remark}}
</div>
<div class="r-group-container">
<div v-show="groupStore.activeIndex>=0">
@ -45,28 +45,25 @@
</el-form>
</div>
<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 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>
<el-divider content-position="center"></el-divider>
<el-scrollbar style="height:400px;">
<div class="r-group-member-list">
<div v-for="(member) in groupMembers" :key="member.id">
<group-member class="r-group-member" :member="member" :showDel="true"></group-member>
</div>
<div class="r-group-invite">
<div class="invite-member-btn" title="邀请好友进群聊" @click="handleInviteMember()">
<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 v-for="(member) in groupMembers" :key="member.id">
<group-member class="r-group-member" :member="member" :showDel="true"></group-member>
</div>
<div class="r-group-invite">
<div class="invite-member-btn" title="邀请好友进群聊" @click="handleInviteMember()">
<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>
</el-scrollbar>
</div>
@ -81,7 +78,7 @@
import FileUpload from '../components/common/FileUpload';
import GroupMember from '../components/group/GroupMember.vue';
import AddGroupMember from '../components/group/AddGroupMember.vue';
export default {
name: "group",
components: {
@ -94,7 +91,11 @@
return {
searchText: "",
maxSize: 5 * 1024 * 1024,
groupMembers:[],
activeGroup: {
empty: true,
remark: ""
},
groupMembers: [],
showAddGroupMember: false
};
},
@ -109,35 +110,48 @@
this.$http({
url: `/api/group/create?groupName=${o.value}`,
method: 'post'
}).then((groupInfo) => {
console.log(groupInfo);
}).then((group) => {
this.$store.commit("addGroup", group);
})
})
},
handleActiveItem(group, index) {
this.$store.commit("activeGroup", index);
// store
this.activeGroup = JSON.parse(JSON.stringify(group));
//
this.loadGroupMembers();
},
handleInviteMember(){
handleInviteMember() {
this.showAddGroupMember = true;
},
handleCloseAddGroupMember(){
handleCloseAddGroupMember() {
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() {
},
loadGroupMembers(){
loadGroupMembers() {
this.$http({
url: `/api/group/members/${this.activeGroup.id}`,
method: "get"
}).then((members)=>{
}).then((members) => {
this.groupMembers = members;
})
}
@ -145,18 +159,6 @@
computed: {
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;
padding: 5px;
background-color: white;
.l-group-search {
flex: 1;
}
@ -239,23 +242,25 @@
}
}
.r-group-member-list{
.r-group-member-list {
padding: 20px;
display: flex;
align-items: center;
flex-wrap: wrap;
font-size: 16px;
text-align: center;
.r-group-member {
margin-right: 15px ;
margin-right: 15px;
}
.r-group-invite{
.r-group-invite {
display: flex;
flex-direction: column;
align-items: center;
width: 60px;
.invite-member-btn{
.invite-member-btn {
width: 100%;
height: 60px;
line-height: 60px;
@ -263,11 +268,12 @@
font-size: 25px;
cursor: pointer;
box-sizing: border-box;
&:hover{
&:hover {
border: #aaaaaa solid 1px;
}
}
.invite-member-text {
font-size: 16px;
text-align: center;
@ -275,11 +281,11 @@
height: 30px;
line-height: 30px;
white-space: nowrap;
text-overflow:ellipsis;
overflow:hidden
text-overflow: ellipsis;
overflow: hidden
}
}
}
}
}

Loading…
Cancel
Save