Browse Source

群聊回执消息-完成

master
Blue 2 years ago
parent
commit
5c4cc56e55
  1. 32
      im-platform/src/main/java/com/bx/implatform/IMPlatformApp.java
  2. 6
      im-platform/src/main/java/com/bx/implatform/entity/GroupMessage.java
  3. 7
      im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java
  4. 3
      im-platform/src/main/java/com/bx/implatform/vo/GroupMessageVO.java
  5. 10
      im-platform/src/main/resources/application.yml
  6. 1
      im-platform/src/main/resources/db/db.sql
  7. 4
      im-server/pom.xml
  8. 4
      im-server/src/main/resources/application.yml
  9. 11
      im-ui/src/components/chat/ChatGroupReaded.vue
  10. 11
      im-ui/src/components/chat/ChatMessageItem.vue
  11. 3
      im-ui/src/view/Home.vue
  12. 3
      im-uniapp/App.vue
  13. 7
      im-uniapp/components/chat-message-item/chat-message-item.vue

32
im-platform/src/main/java/com/bx/implatform/IMPlatformApp.java

@ -1,19 +1,49 @@
package com.bx.implatform; package com.bx.implatform;
import cn.hutool.core.util.StrUtil;
import com.bx.implatform.contant.RedisKey;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@Slf4j @Slf4j
@EnableAspectJAutoProxy(exposeProxy = true) @EnableAspectJAutoProxy(exposeProxy = true)
@MapperScan(basePackages = {"com.bx.implatform.mapper"}) @MapperScan(basePackages = {"com.bx.implatform.mapper"})
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})// 禁用secrity @SpringBootApplication(exclude = {SecurityAutoConfiguration.class})// 禁用secrity
public class IMPlatformApp { public class IMPlatformApp implements ApplicationRunner {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(IMPlatformApp.class, args); SpringApplication.run(IMPlatformApp.class, args);
} }
@Autowired
private RedisTemplate<String,Object> redisTemplate;
@Override
public void run(ApplicationArguments args) throws Exception {
// String matchKey = RedisKey.IM_GROUP_READED_POSITION+"*";
// Set<String> keys = redisTemplate.keys(matchKey);
// Map<String, Map<String,Object>> map = new HashMap<>();
// for(String key:keys){
// String[] arr = key.split(":");
// String groupId = arr[4];
// String userId = arr[5];
// Object messageId = redisTemplate.opsForValue().get(key);
// String newKey = StrUtil.join(":",RedisKey.IM_GROUP_READED_POSITION,groupId);
// redisTemplate.opsForHash().put(newKey,userId,messageId);
// redisTemplate.delete(key);
// log.info("key:{},value:{}",newKey,messageId);
// }
}
} }

6
im-platform/src/main/java/com/bx/implatform/entity/GroupMessage.java

@ -73,6 +73,12 @@ public class GroupMessage extends Model<GroupMessage> {
@TableField("receipt") @TableField("receipt")
private Boolean receipt; private Boolean receipt;
/**
* 回执消息是否完成
*/
@TableField("receipt_ok")
private Boolean receiptOk;
/** /**
* 状态 MessageStatus * 状态 MessageStatus
*/ */

7
im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java

@ -233,6 +233,7 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
wrapper.eq(GroupMessage::getGroupId, groupId); wrapper.eq(GroupMessage::getGroupId, groupId);
wrapper.gt(!Objects.isNull(maxReadedId), GroupMessage::getId, maxReadedId); wrapper.gt(!Objects.isNull(maxReadedId), GroupMessage::getId, maxReadedId);
wrapper.le(!Objects.isNull(maxReadedId), GroupMessage::getId, message.getId()); wrapper.le(!Objects.isNull(maxReadedId), GroupMessage::getId, message.getId());
wrapper.ne(GroupMessage::getStatus, MessageStatus.RECALL.code());
wrapper.eq(GroupMessage::getReceipt, true); wrapper.eq(GroupMessage::getReceipt, true);
List<GroupMessage> receiptMessages = this.list(wrapper); List<GroupMessage> receiptMessages = this.list(wrapper);
if (CollectionUtil.isNotEmpty(receiptMessages)) { if (CollectionUtil.isNotEmpty(receiptMessages)) {
@ -240,10 +241,16 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
Map<Object, Object> maxIdMap = redisTemplate.opsForHash().entries(key); Map<Object, Object> maxIdMap = redisTemplate.opsForHash().entries(key);
for (GroupMessage receiptMessage : receiptMessages) { for (GroupMessage receiptMessage : receiptMessages) {
Integer readedCount = getReadedUserIds(maxIdMap, receiptMessage.getId(),receiptMessage.getSendId()).size(); Integer readedCount = getReadedUserIds(maxIdMap, receiptMessage.getId(),receiptMessage.getSendId()).size();
// 如果所有人都已读,记录回执消息完成标记
if(readedCount >= userIds.size() - 1){
receiptMessage.setReceiptOk(true);
this.updateById(receiptMessage);
}
msgInfo = new GroupMessageVO(); msgInfo = new GroupMessageVO();
msgInfo.setId(receiptMessage.getId()); msgInfo.setId(receiptMessage.getId());
msgInfo.setGroupId(groupId); msgInfo.setGroupId(groupId);
msgInfo.setReadedCount(readedCount); msgInfo.setReadedCount(readedCount);
msgInfo.setReceiptOk(receiptMessage.getReceiptOk());
msgInfo.setType(MessageType.RECEIPT.code());; msgInfo.setType(MessageType.RECEIPT.code());;
sendMessage = new IMGroupMessage<>(); sendMessage = new IMGroupMessage<>();
sendMessage.setSender(new IMUserInfo(session.getUserId(), session.getTerminal())); sendMessage.setSender(new IMUserInfo(session.getUserId(), session.getTerminal()));

3
im-platform/src/main/java/com/bx/implatform/vo/GroupMessageVO.java

@ -33,6 +33,9 @@ public class GroupMessageVO {
@ApiModelProperty(value = "是否回执消息") @ApiModelProperty(value = "是否回执消息")
private Boolean receipt; private Boolean receipt;
@ApiModelProperty(value = "回执消息是否完成")
private Boolean receiptOk;
@ApiModelProperty(value = "已读消息数量") @ApiModelProperty(value = "已读消息数量")
private Integer readedCount = 0; private Integer readedCount = 0;

10
im-platform/src/main/resources/application.yml

@ -1,7 +1,5 @@
#这是配置服务的端口
server: server:
port: 8888 port: 8888
#配置项目的数据源
spring: spring:
application: application:
name: im-platform name: im-platform
@ -17,7 +15,7 @@ spring:
redis: redis:
host: 127.0.0.1 host: 127.0.0.1
port: 6379 port: 6379
database: 1
servlet: servlet:
multipart: multipart:
@ -26,12 +24,10 @@ spring:
mybatis-plus: mybatis-plus:
configuration: configuration:
# 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN(下划线命名) 到经典 Java 属性名 aColumn(驼峰命名) 的类似映射 # 是否开启自动驼峰命名规则
map-underscore-to-camel-case: false map-underscore-to-camel-case: false
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# mapper
mapper-locations: mapper-locations:
# *.xml的具体路径
- classpath*:mapper/*.xml - classpath*:mapper/*.xml
minio: minio:
endpoint: http://127.0.0.1:9001 #内网地址 endpoint: http://127.0.0.1:9001 #内网地址

1
im-platform/src/main/resources/db/db.sql

@ -71,6 +71,7 @@ create table `im_group_message`(
`content` text comment '发送内容', `content` text comment '发送内容',
`at_user_ids` varchar(1024) comment '被@的用户id列表,逗号分隔', `at_user_ids` varchar(1024) comment '被@的用户id列表,逗号分隔',
`receipt` tinyint DEFAULT 0 comment '是否回执消息', `receipt` tinyint DEFAULT 0 comment '是否回执消息',
`receipt_ok` tinyint DEFAULT 0 comment '回执消息是否完成',
`type` tinyint(1) NOT NULL comment '消息类型 0:文字 1:图片 2:文件 3:语音 4:视频 10:系统提示' , `type` tinyint(1) NOT NULL comment '消息类型 0:文字 1:图片 2:文件 3:语音 4:视频 10:系统提示' ,
`status` tinyint(1) DEFAULT 0 comment '状态 0:未发出 1:已送达 2:撤回 3:已读', `status` tinyint(1) DEFAULT 0 comment '状态 0:未发出 1:已送达 2:撤回 3:已读',
`send_time` datetime DEFAULT CURRENT_TIMESTAMP comment '发送时间', `send_time` datetime DEFAULT CURRENT_TIMESTAMP comment '发送时间',

4
im-server/pom.xml

@ -22,10 +22,6 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId> <artifactId>spring-boot</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency> <dependency>
<groupId>io.netty</groupId> <groupId>io.netty</groupId>
<artifactId>netty-all</artifactId> <artifactId>netty-all</artifactId>

4
im-server/src/main/resources/application.yml

@ -1,11 +1,7 @@
server:
port: 8877
spring: spring:
redis: redis:
host: 127.0.0.1 host: 127.0.0.1
port: 6379 port: 6379
database: 1
websocket: websocket:
enable: true enable: true

11
im-ui/src/components/chat/ChatGroupReaded.vue

@ -49,7 +49,6 @@ export default {
y: 0, y: 0,
arrowY: 0 arrowY: 0
}, },
msgInfo: {},
readedMembers: [], readedMembers: [],
unreadMembers: [] unreadMembers: []
} }
@ -57,15 +56,17 @@ export default {
props: { props: {
groupMembers: { groupMembers: {
type: Array type: Array
} },
msgInfo: {
type: Object
}
}, },
methods: { methods: {
close() { close() {
this.show = false; this.show = false;
}, },
open(msgInfo, rect) { open(rect) {
this.show = true; this.show = true;
this.msgInfo = msgInfo;
this.pos.arrowY = 200; this.pos.arrowY = 200;
// //
if (this.msgInfo.selfSend) { if (this.msgInfo.selfSend) {
@ -93,7 +94,7 @@ export default {
}).then(userIds => { }).then(userIds => {
this.groupMembers.forEach(member => { this.groupMembers.forEach(member => {
// 退 // 退
if (member.userId == this.msgInfo.sendId && member.quit) { if (member.userId == this.msgInfo.sendId || member.quit) {
return; return;
} }
// //

11
im-ui/src/components/chat/ChatMessageItem.vue

@ -53,8 +53,9 @@
<span class="chat-unread" v-show="msgInfo.selfSend && !msgInfo.groupId <span class="chat-unread" v-show="msgInfo.selfSend && !msgInfo.groupId
&& msgInfo.status != $enums.MESSAGE_STATUS.READED">未读</span> && msgInfo.status != $enums.MESSAGE_STATUS.READED">未读</span>
<div class="chat-receipt" v-show="msgInfo.receipt" @click="onShowReadedBox"> <div class="chat-receipt" v-show="msgInfo.receipt" @click="onShowReadedBox">
<span v-if="msgInfo.readedCount>=0">{{msgInfo.readedCount}}人已读</span> <span v-if="msgInfo.receiptOk" class="icon iconfont icon-ok" title="全体已读"></span>
<span v-else class="icon iconfont icon-ok" title="全体已读"></span> <span v-else>{{msgInfo.readedCount}}人已读</span>
</div> </div>
</div> </div>
</div> </div>
@ -62,7 +63,7 @@
</div> </div>
<right-menu v-show="menu && rightMenu.show" :pos="rightMenu.pos" :items="menuItems" @close="rightMenu.show = false" <right-menu v-show="menu && rightMenu.show" :pos="rightMenu.pos" :items="menuItems" @close="rightMenu.show = false"
@select="onSelectMenu"></right-menu> @select="onSelectMenu"></right-menu>
<chat-group-readed ref="chatGroupReadedBox" :groupMembers="groupMembers"></chat-group-readed> <chat-group-readed ref="chatGroupReadedBox" :msgInfo="msgInfo" :groupMembers="groupMembers"></chat-group-readed>
</div> </div>
</template> </template>
@ -149,7 +150,7 @@ export default {
}, },
onShowReadedBox() { onShowReadedBox() {
let rect = this.$refs.chatMsgBox.getBoundingClientRect(); let rect = this.$refs.chatMsgBox.getBoundingClientRect();
this.$refs.chatGroupReadedBox.open(this.msgInfo, rect); this.$refs.chatGroupReadedBox.open(rect);
} }
}, },
computed: { computed: {
@ -370,7 +371,7 @@ export default {
.icon-ok { .icon-ok {
font-size: 20px; font-size: 20px;
color: green; color: #329432;
} }
} }
} }

3
im-ui/src/view/Home.vue

@ -236,7 +236,8 @@ export default {
let msgInfo = { let msgInfo = {
id: msg.id, id: msg.id,
groupId: msg.groupId, groupId: msg.groupId,
readedCount: msg.readedCount readedCount: msg.readedCount,
receiptOk: msg.receiptOk
}; };
this.$store.commit("updateMessage", msgInfo) this.$store.commit("updateMessage", msgInfo)
return; return;

3
im-uniapp/App.vue

@ -172,7 +172,8 @@
let msgInfo = { let msgInfo = {
id: msg.id, id: msg.id,
groupId: msg.groupId, groupId: msg.groupId,
readedCount: msg.readedCount readedCount: msg.readedCount,
receiptOk: msg.receiptOk
}; };
this.$store.commit("updateMessage", msgInfo) this.$store.commit("updateMessage", msgInfo)
return; return;

7
im-uniapp/components/chat-message-item/chat-message-item.vue

@ -45,8 +45,9 @@
<text class="chat-unread" v-show="msgInfo.selfSend && !msgInfo.groupId <text class="chat-unread" v-show="msgInfo.selfSend && !msgInfo.groupId
&& msgInfo.status!=$enums.MESSAGE_STATUS.READED">未读</text> && msgInfo.status!=$enums.MESSAGE_STATUS.READED">未读</text>
<view class="chat-receipt" v-show="msgInfo.receipt" @click="onShowReadedBox"> <view class="chat-receipt" v-show="msgInfo.receipt" @click="onShowReadedBox">
<text v-show="msgInfo.readedCount>=0">{{msgInfo.readedCount}}人已读</text> <text v-if="msgInfo.receiptOk" class="tool-icon iconfont icon-ok"></text>
<text v-show="msgInfo.readedCount<0" class="tool-icon iconfont icon-ok"></text> <text v-else>{{msgInfo.readedCount}}人已读</text>
</view> </view>
<!-- <!--
<view class="chat-msg-voice" v-if="msgInfo.type==$enums.MESSAGE_TYPE.AUDIO" @click="onPlayVoice()"> <view class="chat-msg-voice" v-if="msgInfo.type==$enums.MESSAGE_TYPE.AUDIO" @click="onPlayVoice()">
@ -360,7 +361,7 @@
.icon-ok { .icon-ok {
font-size: 20px; font-size: 20px;
color: green; color: #329432;
} }
} }
} }

Loading…
Cancel
Save