移动端聊天实现

This commit is contained in:
2023-10-08 21:38:22 +08:00
parent 7aa2e17897
commit df59768830
25 changed files with 505 additions and 377 deletions

View File

@@ -0,0 +1,18 @@
2023-10-06 11:20:31 -Shutting down ExecutorService 'applicationTaskExecutor'
2023-10-06 11:59:33 -Starting AppServiceApplication on luojie with PID 10500 (E:\workplace\huashi_project\im-system\hs-im-app-server\target\classes started by coolp in E:\workplace\huashi_project\im-system\hs-im-app-server)
2023-10-06 11:59:33 -The following profiles are active: dev
2023-10-06 11:59:34 -Tomcat initialized with port(s): 8989 (http)
2023-10-06 11:59:34 -Initializing ProtocolHandler ["http-nio-8989"]
2023-10-06 11:59:34 -Starting service [Tomcat]
2023-10-06 11:59:34 -Starting Servlet engine: [Apache Tomcat/9.0.37]
2023-10-06 11:59:34 -Initializing Spring embedded WebApplicationContext
2023-10-06 11:59:34 -Root WebApplicationContext: initialization completed in 554 ms
2023-10-06 11:59:35 -Initializing ExecutorService 'applicationTaskExecutor'
2023-10-06 11:59:35 -Starting ProtocolHandler ["http-nio-8989"]
2023-10-06 11:59:35 -Tomcat started on port(s): 8989 (http) with context path ''
2023-10-06 11:59:35 -Started AppServiceApplication in 2.549 seconds (JVM running for 3.426)
2023-10-06 12:00:10 -Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-10-06 12:00:10 -Initializing Servlet 'dispatcherServlet'
2023-10-06 12:00:10 -Completed initialization in 2 ms
2023-10-06 12:00:10 -HikariPool-1 - Starting...
2023-10-06 12:00:11 -HikariPool-1 - Start completed.

View File

@@ -32,7 +32,7 @@ mybatis:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
appConfig: appConfig:
imUrl: http://127.0.0.1:28000 imUrl: http://192.168.1.117:28000
imVersion: v1 imVersion: v1
appId: 10000 appId: 10000
adminId: admin adminId: admin

View File

@@ -9,7 +9,7 @@
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>common</artifactId> <artifactId>im-common</artifactId>
<properties> <properties>
<java.version>1.8</java.version> <java.version>1.8</java.version>

View File

@@ -14,6 +14,7 @@ public class SyncReq extends RequestBase {
private Long lastSequence; private Long lastSequence;
//一次拉取多少 //一次拉取多少
private Integer maxLimit; private Integer maxLimit;
private Integer appId;
private String operater; private String operater;
} }

View File

@@ -14,7 +14,7 @@
<java.version>1.8</java.version> <java.version>1.8</java.version>
</properties> </properties>
<artifactId>service</artifactId> <artifactId>im-service</artifactId>
<dependencies> <dependencies>
<!-- rabbitmq --> <!-- rabbitmq -->
@@ -84,15 +84,10 @@
<!-- common --> <!-- common -->
<dependency> <dependency>
<groupId>com.lld</groupId> <groupId>com.lld</groupId>
<artifactId>common</artifactId> <artifactId>im-common</artifactId>
<version>1.0.0-SNAPSHOT</version> <version>1.0.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>com.lld</groupId>
<artifactId>im-system</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@@ -42,7 +42,7 @@ public class ConversationController {
@RequestMapping("/syncConversationList") @RequestMapping("/syncConversationList")
public ResponseVO syncFriendShipList(@RequestBody @Validated SyncReq req,Integer appId) { public ResponseVO syncFriendShipList(@RequestBody @Validated SyncReq req,Integer appId) {
req.setAppId(appId); // req.setAppId(appId);
return conversationService.syncConversationSet(req); return conversationService.syncConversationSet(req);
} }

View File

@@ -181,9 +181,11 @@ public class ConversationService {
queryWrapper.last(" limit " + req.getMaxLimit()); queryWrapper.last(" limit " + req.getMaxLimit());
queryWrapper.orderByAsc("sequence"); queryWrapper.orderByAsc("sequence");
log.info("============================= syncConversationSet ========================"); log.info("============================= syncConversationSet ========================");
log.info("============================= syncConversationSet ========================"); log.info("============================= syncConversationSet ========================");
log.info("============================= syncConversationSet ========================"); log.info("============================= syncConversationSet ========================");
log.info(req.toString()); log.info(req.toString());
List<ImConversationSetEntity> list = imConversationSetMapper List<ImConversationSetEntity> list = imConversationSetMapper

View File

@@ -75,6 +75,9 @@ public class ChatOperateReceiver {
//消息接收确认 //消息接收确认
MessageReadedContent messageContent MessageReadedContent messageContent
= jsonObject.toJavaObject(MessageReadedContent.class); = jsonObject.toJavaObject(MessageReadedContent.class);
logger.error("==============服务端接收到1106的信号{}",messageContent);
messageSyncService.readMark(messageContent); messageSyncService.readMark(messageContent);
}else if (Objects.equals(command, MessageCommand.MSG_RECALL.getCommand())) { }else if (Objects.equals(command, MessageCommand.MSG_RECALL.getCommand())) {
// 撤回消息 // 撤回消息

View File

@@ -29,7 +29,7 @@ import java.util.concurrent.TimeUnit;
/** /**
* @description: * @description:
* @author: lld * @author: rowger
* @version: 1.0 * @version: 1.0
*/ */
@Service @Service

View File

@@ -9,7 +9,7 @@
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>tcp</artifactId> <artifactId>im-tcp</artifactId>
<properties> <properties>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<mybatis-plus.version>3.3.0</mybatis-plus.version> <mybatis-plus.version>3.3.0</mybatis-plus.version>

View File

@@ -150,7 +150,6 @@ public class NettyServerHandler extends SimpleChannelInboundHandler<Message> {
|| command == GroupEventCommand.MSG_GROUP.getCommand()){ || command == GroupEventCommand.MSG_GROUP.getCommand()){
logger.info("***********************收到单聊或者群聊消息:{}", msg); logger.info("***********************收到单聊或者群聊消息:{}", msg);
try { try {
String toId = ""; String toId = "";
CheckSendMessageReq req = new CheckSendMessageReq(); CheckSendMessageReq req = new CheckSendMessageReq();

View File

@@ -88,12 +88,6 @@
<groupId>com.github.sgroschupf</groupId> <groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId> <artifactId>zkclient</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.lld</groupId>
<artifactId>common</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency> <dependency>
<groupId>com.netflix.feign</groupId> <groupId>com.netflix.feign</groupId>
<artifactId>feign-core</artifactId> <artifactId>feign-core</artifactId>

View File

@@ -23,20 +23,10 @@
// todo 下列两行 // todo 下列两行
uni.setStorageSync('device', 'H5'); uni.setStorageSync('device', 'H5');
uni.setStorageSync('version', versionName); uni.setStorageSync('version', versionName);
this.$http.request({
url: '/common/getVersion',
success: (res) => {
if(res.data.data.upgrade=='Y'){
console.log(
`%c 有新版本 `+res.data.data.version,
'background:#007aff ;padding: 1px; border-radius: 0 3px 3px 0; color: #fff; font-weight: bold;'
)
}
}
});
// #endif // #endif
console.log('App Launch') console.log('App Launch')
let token= uni.getStorageSync('Authorization'); let token= uni.getStorageSync('imUserSign');
if (!token) { if (!token) {
//不存在则跳转至登录页 //不存在则跳转至登录页
// #ifdef APP-PLUS // #ifdef APP-PLUS
@@ -104,29 +94,7 @@
}) })
} }
// #ifdef APP-PLUS // #ifdef APP-PLUS
//升级检测
uni.getSystemInfo({
success: (res)=> {
uni.setStorageSync('device', res.platform);
plus.runtime.getProperty(plus.runtime.appid, (widgetInfo)=> {
uni.setStorageSync('version', widgetInfo.version);
this.$http.request({
url: '/common/getVersion',
success: (res) => {
if(res.data.data.upgrade=='Y'){
appUpgrade.init({
titleText: '版本更新'+res.data.data.version,
packageUrl:res.data.data.url,
content: res.data.data.content,
forceUpgrade:res.data.data.forceUpgrade=='Y' ? true : false
});
appUpgrade.show();
}
}
});
});
}
});
uni.onNetworkStatusChange( (res)=> { uni.onNetworkStatusChange( (res)=> {
if(res.isConnected){ if(res.isConnected){
this.$store.dispatch('get_UserInfo') this.$store.dispatch('get_UserInfo')

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -2,6 +2,9 @@ import http from '@/common/request'
import browser from '@/common/browser' import browser from '@/common/browser'
import store from '../store' import store from '../store'
import pinyin from '@/common/pinyin.js'; import pinyin from '@/common/pinyin.js';
import * as dayjs from 'dayjs'
export default { export default {
// 获取字典 // 获取字典
getdict(dict) { getdict(dict) {
@@ -464,6 +467,12 @@ export default {
store.dispatch('getChatList'); store.dispatch('getChatList');
var chatWindowData = store.state.chatDatalist[userId].list var chatWindowData = store.state.chatDatalist[userId].list
var chatListInfo = store.state.chatlist[userId] var chatListInfo = store.state.chatlist[userId]
var data2 = this.getKeyObjectStorage(store.state.userInfo.userId + '_' +
'chatlistData')
// var _num=data2[userId].num||
console.log("===========data2:",JSON.stringify(data2[userId]))
// 找到数组中对象属性值一样的对象并返回 // 找到数组中对象属性值一样的对象并返回
function arrfindobject({ function arrfindobject({
arr, arr,
@@ -508,11 +517,11 @@ export default {
nickName: fromInfo.nickName, nickName: fromInfo.nickName,
portrait: fromInfo.portrait, portrait: fromInfo.portrait,
content: msgTypeLabel, content: msgTypeLabel,
time: time, time: dayjs(time).format("YYYY/MM/DD HH:mm:ss"),
num: disturb == 'Y' ? 'dot' : (chatListInfo.num ? chatListInfo.num + 1 : 1), num: disturb == 'Y' ? 'dot' : (chatListInfo.num ? chatListInfo.num + 1 : 1),
windowType: windowType, windowType: windowType,
disturb: disturb, //是否静默消息 disturb: "N", //是否静默消息
top: top, //是否置顶 top: "N", //是否置顶
userType: fromInfo.userType userType: fromInfo.userType
} }
} }
@@ -526,7 +535,7 @@ export default {
time: time, time: time,
num: disturb == 'Y' ? 'dot' : (chatListInfo.num ? chatListInfo.num + 1 : 1), num: disturb == 'Y' ? 'dot' : (chatListInfo.num ? chatListInfo.num + 1 : 1),
windowType: windowType, windowType: windowType,
disturb: disturb, //是否静默消息 disturb: "N", //是否静默消息
top: top, //是否置顶 top: top, //是否置顶
userType: 'GROUP' userType: 'GROUP'
} }
@@ -990,6 +999,31 @@ export default {
}); });
// #endif // #endif
}, },
formatMessage(msg){
msg.pushType="MSG"
const _data=JSON.parse(msg.messageBody)
msg.msgContent={
msgType:"TEXT",
content:_data.content,
disturb:false,
top:false,
}
msg.windowType="SINGLE"
msg.createTime=msg.messageTime;
msg.userId=msg.fromId;
msg.fromInfo={
userId:msg.fromId,
userType:1,
nickName:msg.fromId,
portrait:"https://shudong2022.oss-cn-hangzhou.aliyuncs.com/common/user/logo.png"
};
msg.groupInfo={};
msg.msgId=msg.messageKey;
return msg
},
debounce(func, wait = 1000, immediate = true) { debounce(func, wait = 1000, immediate = true) {
/** /**
* @desc 函数防抖 * @desc 函数防抖

View File

@@ -4,9 +4,10 @@ let retimer = null
import store from '../store' import store from '../store'
import * as sdk from "@/common/imSdk/lim-sdk.js"; import * as sdk from "@/common/imSdk/lim-sdk.js";
import lim from "@/common/imSdk/sdk-bridge.js"; import lim from "@/common/imSdk/sdk-bridge.js";
import publicFc from '@/common/publicFc';
export default { export default {
socketTask: null, socketTask: null,
// 连接WebSocket // 连接WebSocket
@@ -28,42 +29,40 @@ export default {
onSocketReConnectSuccessEvent: () => { onSocketReConnectSuccessEvent: () => {
console.log("重连成功"); console.log("重连成功");
}, },
onOfflineMessage:(e)=>{ onOfflineMessage: (e) => {
console.log("====================拉取到离线消息") console.log("====================拉取到离线消息")
console.log(e) console.log(e)
setTimeout(function() {
if (e.length > 0) {
e.map((msg) => {
console.log(msg)
setTimeout(()=>{
const _data = publicFc.formatMessage(msg)
uni.$emit('onP2PMessage', _data);
store.dispatch('onP2PMessage', _data)
},500)
})
}
}, 2000);
}, },
onTestMessage: (e) => { onTestMessage: (e) => {
console.log("onTestMessage " + e); console.log("onTestMessage ");
store.dispatch('onP2PMessage',e) store.dispatch('onP2PMessage', e)
}, },
onP2PMessage: (e) => { onP2PMessage: (e) => {
console.log("onP2PMessage " + e); console.log("onP2PMessag e :::");
console.log(JSON.parse(e))
e = JSON.parse(e) e = JSON.parse(e)
e.data.pushType="MSG"
const _data=JSON.parse(e.data.messageBody)
e.data.msgContent={
msgType:"TEXT",
content:_data.content,
disturb:false,
top:false,
}
e.data.windowType="SINGLE" const _data = publicFc.formatMessage(e.data)
e.data.createTime=e.data.messageTime;
e.data.userId=e.data.fromId; uni.$emit('onP2PMessage', _data);
e.data.fromInfo={ store.dispatch('onP2PMessage', _data)
userId:e.data.fromId
};
e.data.groupInfo={};
e.data.msgId=e.data.messageId;
uni.$emit('onP2PMessage', e.data);
store.dispatch('onP2PMessage',e.data)
}, },
onLogin: (uid) => { onLogin: (uid) => {
console.log("用户" + uid + "登陆sdk成功"); console.log("用户" + uid + "登陆sdk成功");
} }
}; };
@@ -79,7 +78,7 @@ export default {
console.log(lim) console.log(lim)
// 防止多次建立ws链接貌似还没有生效需要检查 // 防止多次建立ws链接貌似还没有生效需要检查
if (this.socketTask != null) { if (this.socketTask != null) {
return false return false
} }
@@ -92,12 +91,12 @@ export default {
console.log(this.socketTask) console.log(this.socketTask)
console.log('sdk 成功连接的回调, 可以使用 sdk 请求数据了.'); console.log('sdk 成功连接的回调, 可以使用 sdk 请求数据了.');
sdk.getAllFriend().then(res => { // sdk.getAllFriend().then(res => {
console.warn(res) // console.warn(res)
}) // })
sdk.getUserSequence().then(res => { // sdk.getUserSequence().then(res => {
console.warn(res) // console.warn(res)
}) // })
sdk.getUserConversationList(0).then(res => { sdk.getUserConversationList(0).then(res => {
console.warn(res) console.warn(res)

View File

@@ -12,6 +12,7 @@
"author": "zmm2113@qq.com", "author": "zmm2113@qq.com",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"dayjs": "^1.11.10",
"localforage": "^1.10.0" "localforage": "^1.10.0"
} }
} }

View File

@@ -1,283 +1,343 @@
import http from '@/common/request'; import http from '@/common/request';
import publicFc from '@/common/publicFc'; import publicFc from '@/common/publicFc';
import * as sdk from "@/common/imSdk/lim-sdk.js";
import lim from "@/common/imSdk/sdk-bridge.js";
const _im = lim.lim.im
function sortBy(field) {
//根据传过来的字段进行排序
return (x, y) => {
return x[field] - y[field]
}
}
// #ifndef VUE3 // #ifndef VUE3
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
Vue.use(Vuex) Vue.use(Vuex)
const store = new Vuex.Store({ const store = new Vuex.Store({
// #endif // #endif
// #ifdef VUE3
import * as sdk from "@/common/imSdk/lim-sdk.js"; import {
import lim from "@/common/imSdk/sdk-bridge.js"; createStore
} from 'vuex'
const _im=lim.lim.im const store = createStore({
// #ifdef VUE3
import { createStore } from 'vuex'
const store = createStore({
// #endif
state: {
watermark:'HS-IM',
userInfo:'',
chatlist:[],
chatDatalist:[],
chatListNum:0,
chatDataState:1,
chatDataUserId:'',
topicReply:{},
topicRed:{},
friendApply:{}
},
mutations: {
update_UserInfo(state, data) {//个人信息
state.userInfo = JSON.parse(data)
},
update_ChatList(state, data) {
state.chatlist = data
},
update_chatDatalist(state, data) {
state.chatDatalist = data
},
update_topicReply(state, data) {
state.topicReply = data
uni.setStorageSync('topicReply', JSON.stringify(data));
},
update_topicRed(state, data) {
state.topicRed = data
uni.setStorageSync('topicRed', JSON.stringify(data));
},
update_friendApply(state, data) {
state.friendApply = data
uni.setStorageSync('friendApply', JSON.stringify(data));
}
},
actions: {
onP2PMessage(context,data){
console.log("========================store 收到信息")
console.log("========================store 收到信息")
console.log("========================store 收到信息")
console.error(data)
publicFc.getPush(data)
},
sendMsg(context,data){
console.log("========================")
console.log("========================")
console.log("========================")
console.error(data)
_im.sendP2PMessage(_im.createP2PTextMessage(data.userId,data.data.content))
},
updateChatDataState(context,data){
context.state.chatDataState++
context.state.chatDataUserId=data
},
tabBarpull(context){
context.dispatch('get_UserInfo').then(res=>{
context.dispatch('getChatList')
// 朋友圈新消息
var topicReply=publicFc.getKeyObjectStorage('topicReply')
context.state.topicReply=topicReply
// 新朋友圈
var topicRed=publicFc.getKeyObjectStorage('topicRed')
context.state.topicRed=topicRed
// 新朋友
var friendApply=publicFc.getKeyObjectStorage('friendApply')
context.state.friendApply=friendApply
var chatListNum=context.state.chatListNum ? context.state.chatListNum : 0
var topicReplyCount=topicReply.count ? topicReply.count : 0
var friendApplyCount=friendApply.count ? friendApply.count : 0
var sumCount=chatListNum+topicReplyCount+friendApplyCount
// #ifdef APP-PLUS
plus.runtime.setBadgeNumber(sumCount);
// #endif // #endif
}) state: {
}, watermark: 'HS-IM',
get_UserInfo (context) { userInfo: '',
// TODO 改用SDK的更新用户数据 chatlist: [],
return new Promise((resolve, reject) => { chatDatalist: [],
const userId = uni.getStorageSync("userId") chatListNum: 0,
chatDataState: 1,
chatDataUserId: '',
topicReply: {},
topicRed: {},
friendApply: {}
},
mutations: {
update_UserInfo(state, data) { //个人信息
state.userInfo = JSON.parse(data)
},
update_ChatList(state, data) {
state.chatlist = data
},
update_chatDatalist(state, data) {
state.chatDatalist = data
},
update_topicReply(state, data) {
state.topicReply = data
uni.setStorageSync('topicReply', JSON.stringify(data));
},
update_topicRed(state, data) {
state.topicRed = data
uni.setStorageSync('topicRed', JSON.stringify(data));
},
update_friendApply(state, data) {
state.friendApply = data
uni.setStorageSync('friendApply', JSON.stringify(data));
}
},
actions: {
onP2PMessage(context, data) {
console.log("========================store 收到信息")
console.log(data)
publicFc.getPush(data)
lim.lim.im.getSingleUserInfo(userId).then((res)=>{ },
if(res.code==200){ sendMsg(context, data) {
context.commit('update_UserInfo',JSON.stringify(res.data)) console.log("========================")
resolve(res.data) // console.log("========================")
}else{ // console.log("========================")
reject(res.data) // console.error(data)
} _im.sendP2PMessage(_im.createP2PTextMessage(data.userId, data.data.content))
}) },
}) sendP2PMessageReciveAck(context, data) {
}, _im.sendP2PMessageReciveAck(data)
getchatDatalist(context) {//获取聊天数据列表 },
var data=publicFc.getKeyObjectStorage(context.state.userInfo.userId+'_'+'chatData') sendMsgReadedReceipt(context, data) {
context.commit('update_chatDatalist',data) _im.sendP2PMessageReadedReceipt(data)
}, },
updateChatById(context,data) {//更新聊天数据 updateChatDataState(context, data) {
var getKey=data.userId context.state.chatDataState++
var retdata=publicFc.getKeyObjectStorage(context.state.userInfo.userId+'_'+'chatData') context.state.chatDataUserId = data
retdata[getKey]['list']=data.data },
uni.setStorageSync(context.state.userInfo.userId+'_'+'chatData', JSON.stringify(retdata)); tabBarpull(context) {
}, context.dispatch('get_UserInfo').then(res => {
updateChatObjById(context,data) {//更新聊天数据对象 context.dispatch('getChatList')
var getKey=data.userId // 朋友圈新消息
var retdata=publicFc.getKeyObjectStorage(context.state.userInfo.userId+'_'+'chatData') var topicReply = publicFc.getKeyObjectStorage('topicReply')
retdata[getKey]=data.data context.state.topicReply = topicReply
uni.setStorageSync(context.state.userInfo.userId+'_'+'chatData', JSON.stringify(retdata)); // 新朋友圈
}, var topicRed = publicFc.getKeyObjectStorage('topicRed')
getChatList(context) {//获取聊天记录列表 context.state.topicRed = topicRed
var data=publicFc.getKeyObjectStorage(context.state.userInfo.userId+'_'+'chatlistData') // 新朋友
var sum=0 var friendApply = publicFc.getKeyObjectStorage('friendApply')
for(var key in data){ context.state.friendApply = friendApply
sum+=data[key].num var chatListNum = context.state.chatListNum ? context.state.chatListNum : 0
} var topicReplyCount = topicReply.count ? topicReply.count : 0
context.state.chatListNum=sum var friendApplyCount = friendApply.count ? friendApply.count : 0
context.commit('update_ChatList',data) var sumCount = chatListNum + topicReplyCount + friendApplyCount
}, // #ifdef APP-PLUS
updateChatListInfoById(context,data) {//修改聊天记录 plus.runtime.setBadgeNumber(sumCount);
console.log("修改聊天记录 2") // #endif
var getKey=data.userId })
var retdata=publicFc.getKeyObjectStorage(context.state.userInfo.userId+'_'+'chatlistData') },
retdata[getKey]=data.data get_UserInfo(context) {
uni.setStorageSync(context.state.userInfo.userId+'_'+'chatlistData', JSON.stringify(retdata)); // TODO 改用SDK的更新用户数据
}, return new Promise((resolve, reject) => {
createChatObj(context,data){ const userId = uni.getStorageSync("userId")
console.log("修改聊天记录 3")
console.log("context.state.userInfo.userId:",context.state.userInfo.userId)
console.log("data.userId:",data.userId)
var userId=data.userId
var windowType=data.windowType
//初始化聊天记录 lim.lim.im.getSingleUserInfo(userId).then((res) => {
var data2=publicFc.getKeyObjectStorage(context.state.userInfo.userId+'_'+'chatlistData')
if(!data2[userId]){
data2[userId]=new Object()
}
uni.setStorageSync(context.state.userInfo.userId+'_'+'chatlistData', JSON.stringify(data2));
// 初始化聊天数据
var data1=publicFc.getKeyObjectStorage(context.state.userInfo.userId+'_'+'chatData')
return new Promise((resolve, reject)=>{
if(!data1[userId]){
console.log('初始化聊天')
switch (windowType){
case 'SINGLE':
// lim.lim.im.getSingleUserInfo(userId).then(res=>{
// console.warn(res)
// })
_im.getSingleUserInfo(userId).then((res)=>{
console.log(res.data)
console.log(res.data)
console.log(res.data)
console.log(res.data)
if (res.code == 200) { if (res.code == 200) {
var detail=res.data context.commit('update_UserInfo', JSON.stringify(res.data))
data1[userId]={ resolve(res.data)
fromInfo:{ } else {
nickName: detail.nickName, reject(res.data)
portrait: detail.photo, }
userId: detail.userId, })
userType:detail.userType })
}, },
groupInfo:{}, getchatDatalist(context) { //获取聊天数据列表
list:[] var data = publicFc.getKeyObjectStorage(context.state.userInfo.userId + '_' +
} 'chatData')
context.commit('update_chatDatalist', data)
},
updateChatById(context, data) { //更新聊天数据
var getKey = data.userId
var retdata = publicFc.getKeyObjectStorage(context.state.userInfo.userId + '_' +
'chatData')
uni.setStorageSync(context.state.userInfo.userId+'_'+'chatData', JSON.stringify(data1)); //TODO 排序方法可以优化
// 创建记录 data.data = data.data.sort(sortBy('time'))
var msgList = {
userId: detail.userId, retdata[getKey]['list'] = data.data
personId: context.state.userInfo.userId, uni.setStorageSync(context.state.userInfo.userId + '_' + 'chatData', JSON.stringify(
nickName: detail.nickName, retdata));
portrait: detail.photo, },
content: '', updateChatObjById(context, data) { //更新聊天数据对象
time: publicFc.getNewDate('format',true), var getKey = data.userId
num: 0, var retdata = publicFc.getKeyObjectStorage(context.state.userInfo.userId + '_' +
windowType: 'SINGLE', 'chatData')
disturb:'N',//是否静默消息
top:'N',//是否置顶 //TODO 排序方法可以优化
userType:'SINGLE' data.data = data.data.sort(sortBy('time'))
} retdata[getKey] = data.data
context.dispatch('updateChatListInfoById', { uni.setStorageSync(context.state.userInfo.userId + '_' + 'chatData', JSON.stringify(
userId: detail.userId, retdata));
data: msgList },
}); getChatList(context) { //获取聊天记录列表
resolve({ var data = publicFc.getKeyObjectStorage(context.state.userInfo.userId + '_' +
msg:'创建成功', 'chatlistData')
data:data1[userId] var sum = 0
}) for (var key in data) {
}else{ sum += data[key].num
reject({ }
msg:'创建失败' context.state.chatListNum = sum
}); context.commit('update_ChatList', data)
} },
} updateChatListInfoById(context, data) { //修改聊天记录
); console.log("*********************** 修改聊天记录 2 ********************")
break; console.log("*********************** 修改聊天记录 2 ********************")
case 'GROUP': console.log("*********************** 修改聊天记录 2 ********************")
http.request({ console.log(data)
url: '/group/getInfo/'+userId, var getKey = data.userId
complete:(res)=>{ var retdata = publicFc.getKeyObjectStorage(context.state.userInfo.userId + '_' +
if (res.data.code == 200) { 'chatlistData')
var detail=res.data.data console.log(retdata[getKey])
var portraits=[] retdata[getKey] = data.data
for (var i = 0; i < detail.user.length; i++) { uni.setStorageSync(context.state.userInfo.userId + '_' + 'chatlistData', JSON.stringify(
portraits.push(detail.user[i].portrait) retdata));
} },
data1[userId]={ createChatObj(context, data) {
fromInfo:{}, console.log("初始化聊天记录")
groupInfo:{ // console.log("context.state.userInfo.userId:", context.state.userInfo.userId)
nickName: detail.group.name, // console.log("data.userId:", data.userId)
portrait: JSON.stringify(portraits), var userId = data.userId
userId: detail.group.groupId, var windowType = data.windowType
},
list:[] //初始化聊天记录
} var data2 = publicFc.getKeyObjectStorage(context.state.userInfo.userId + '_' +
uni.setStorageSync(context.state.userInfo.userId+'_'+'chatData', JSON.stringify(data1)); 'chatlistData')
// 创建记录
var msgList = { // console.log("===========data2:",JSON.stringify(data2[userId]))
userId: detail.group.groupId,
personId: context.state.userInfo.userId, var _num=0
nickName: detail.group.name, console.error(data2[userId])
portrait: JSON.stringify(portraits), if (!data2[userId]) {
content: '', data2[userId] = new Object()
time: publicFc.getNewDate('format',true), }else{
num: 0, console.warn(data2[userId].num)
windowType: 'GROUP', // _num=data2[userId].num+1
disturb:'N',//是否静默消息 }
top:'N',//是否置顶 uni.setStorageSync(context.state.userInfo.userId + '_' + 'chatlistData', JSON.stringify(
userType:'GROUP' data2));
} // 初始化聊天数据
context.dispatch('updateChatListInfoById', { var data1 = publicFc.getKeyObjectStorage(context.state.userInfo.userId + '_' +
userId: detail.group.groupId, 'chatData')
data: msgList return new Promise((resolve, reject) => {
}); if (!data1[userId]) {
resolve({ console.log('初始化聊天')
msg:'创建成功', switch (windowType) {
data:data1[userId] case 'SINGLE':
})
}else{ // lim.lim.im.getSingleUserInfo(userId).then(res=>{
reject({ // console.warn(res)
msg:'创建失败' // })
});
_im.getSingleUserInfo(userId).then((res) => {
// console.log(res.data)
if (res.code == 200) {
var detail = res.data
data1[userId] = {
fromInfo: {
nickName: detail.nickName,
portrait: detail.photo,
userId: detail.userId,
userType: detail.userType
},
groupInfo: {},
list: []
}
uni.setStorageSync(context.state.userInfo
.userId + '_' + 'chatData', JSON
.stringify(data1));
// 创建记录
console.log("============= 创建记录 ")
var msgList = {
userId: detail.userId,
personId: context.state.userInfo.userId,
nickName: detail.nickName,
portrait: detail.photo,
content: '',
time: publicFc.getNewDate('format',
true),
num: 0,
windowType: 'SINGLE',
disturb: 'N', //是否静默消息
top: 'N', //是否置顶
userType: 'SINGLE'
}
context.dispatch('updateChatListInfoById', {
userId: detail.userId,
data: msgList
});
resolve({
msg: '创建成功',
data: data1[userId]
})
} else {
reject({
msg: '创建失败'
});
}
});
break;
case 'GROUP':
http.request({
url: '/group/getInfo/' + userId,
complete: (res) => {
if (res.data.code == 200) {
var detail = res.data.data
var portraits = []
for (var i = 0; i < detail.user
.length; i++) {
portraits.push(detail.user[i]
.portrait)
}
data1[userId] = {
fromInfo: {},
groupInfo: {
nickName: detail.group.name,
portrait: JSON.stringify(
portraits),
userId: detail.group
.groupId,
},
list: []
}
uni.setStorageSync(context.state
.userInfo.userId + '_' +
'chatData', JSON.stringify(
data1));
// 创建记录
var msgList = {
userId: detail.group.groupId,
personId: context.state.userInfo
.userId,
nickName: detail.group.name,
portrait: JSON.stringify(
portraits),
content: '',
time: publicFc.getNewDate(
'format', true),
num: 0,
windowType: 'GROUP',
disturb: 'N', //是否静默消息
top: 'N', //是否置顶
userType: 'GROUP'
}
context.dispatch(
'updateChatListInfoById', {
userId: detail.group
.groupId,
data: msgList
});
resolve({
msg: '创建成功',
data: data1[userId]
})
} else {
reject({
msg: '创建失败'
});
}
}
});
break;
default:
break;
} }
} else {
resolve({
msg: '已存在',
data: data1[userId]
})
} }
}); });
break; },
default: createChat(context, data) {
break;
}
}else{
resolve({
msg:'已存在',
data:data1[userId]
})
}
});
},
createChat(context,data){
} }
} }
}) })
export default store export default store

View File

@@ -174,7 +174,7 @@
onLoad(e) { onLoad(e) {
// // 监听接收聊天信息 // // 监听接收聊天信息
// uni.$on('onP2PMessage', this.onMessage) uni.$on('onP2PMessage', this.onMessage)
this.talkTo = e; this.talkTo = e;
console.log(this.talkTo) console.log(this.talkTo)
@@ -232,8 +232,6 @@
); );
}, },
onPageScroll() { onPageScroll() {
this.clickToSubmitSure(); this.clickToSubmitSure();
@@ -267,7 +265,19 @@
}, },
methods: { methods: {
onMessage(message) { onMessage(message) {
//判断当前是单聊还是群聊
if (this.talkTo.windowType != 'SINGLE') {
return;
}
//如果是单聊,则判断当前消息发送人是不是当前窗口的聊天对象
if(this.talkTo.userId!=message.fromId){
return;
}
console.log("message 聊天页收到回调")
console.log(message)
//如果当前消息发送人和当前窗口的聊天对象一致,则发送已读回执
console.log("########### 此时需要发送已读回执 ###########")
this.$store.dispatch('sendP2PMessageReciveAck',message)
}, },
addMsg(e) { addMsg(e) {
this.msg += e; this.msg += e;

View File

@@ -158,12 +158,7 @@
this.$store.dispatch('tabBarpull'); this.$store.dispatch('tabBarpull');
}, },
mounted() { mounted() {
this.$socketTask.connectSocket() this.$socketTask.connectSocket()
}, },
methods: { methods: {
longpressItem(e, i, v) { longpressItem(e, i, v) {

View File

@@ -25,6 +25,9 @@ enum MessageCommand {
// //消息已读通知 1053 // //消息已读通知 1053
MSG_READED_NOTIFY = 0x41D, MSG_READED_NOTIFY = 0x41D,
// 消息已读回执,给原消息发送方 1054
MSG_READED_RECEIPT=0x41E,
} }
enum FriendShipCommand{ enum FriendShipCommand{

View File

@@ -20,7 +20,7 @@ export default class HttpApi {
let reqUrl = this.url + url; let reqUrl = this.url + url;
if(params != null){ if(params != null){
let paramStr = this.setQueryConfig(params) let paramStr = this.setQueryConfig(params)
console.log(paramStr); // console.log(paramStr);
reqUrl += paramStr; reqUrl += paramStr;
} }
@@ -89,7 +89,7 @@ export default class HttpApi {
}).then(res =>{ }).then(res =>{
log.info(`==> [${request.method}] ${url} back:` + Beans.json(res)); log.info(`==> [${request.method}] ${url} back:` + Beans.json(res));
const resp = this.response2ApiResponse(res); const resp = this.response2ApiResponse(res);
console.log(res) // console.log(res)
if(resp.isFailed()){ if(resp.isFailed()){
return Promise.reject(resp); return Promise.reject(resp);
} }
@@ -115,7 +115,7 @@ export default class HttpApi {
/*IFTRUE_UNIAPP*/ /*IFTRUE_UNIAPP*/
let rnfetch1 = Fetch.getFetchToolkit(); let rnfetch1 = Fetch.getFetchToolkit();
return rnfetch1(url as string, request).then(response =>{ return rnfetch1(url as string, request).then(response =>{
console.log(response) // console.log(response)
return response.json(); return response.json();
}).then(res =>{ }).then(res =>{
log.info(`==> [${request.method}] ${url} back:` + Beans.json(res)); log.info(`==> [${request.method}] ${url} back:` + Beans.json(res));

View File

@@ -54,7 +54,7 @@ export interface IListener {
onSocketCloseEvent(): void;//连接关闭事件 onSocketCloseEvent(): void;//连接关闭事件
onP2PMessage(e: any): void;//收到单聊消息事件 onP2PMessage(e: any): void;//收到单聊消息事件
onTestMessage(e: any): void;//收到消息事件 测试用 onTestMessage(e: any): void;//收到消息事件 测试用
// onOfflineMessage(data):void; // 拉取到离线消息事件 onOfflineMessage(data):void; // 拉取到离线消息事件
} }
export class ImClient { export class ImClient {
@@ -188,6 +188,10 @@ export class ImClient {
public buildMessagePack(command: number, messagePack: any) { public buildMessagePack(command: number, messagePack: any) {
var jsonData = JSON.stringify(messagePack); var jsonData = JSON.stringify(messagePack);
// console.log("=============buildMessagePack=========")
// log.info(jsonData);
let bodyLen = getLen(jsonData); let bodyLen = getLen(jsonData);
let pack = new ByteBuffer(null, 0); let pack = new ByteBuffer(null, 0);
@@ -332,6 +336,48 @@ export class ImClient {
} }
} }
// 消息接收ack
public sendP2PMessageReciveAck (rAck: any) {
console.log("=============== sendP2PMessageReciveAck")
console.log(rAck)
rAck.toId = rAck.fromId;
rAck.fromId = this.userId;
console.log(rAck)
let p2pPack_1107 = imClient.buildMessagePack(MessageCommand.MSG_RECIVE_ACK, rAck);
rAck.conversationType=0
let p2pPack_1106 = imClient.buildMessagePack(MessageCommand.MSG_READED, rAck);
let p2pPack_1054 = imClient.buildMessagePack(MessageCommand.MSG_READED_RECEIPT, rAck);
if (this.conn) {
// console.log("=============== sendP2PMessageReciveAck 正式开始消息接收ack")
this.conn.send(p2pPack_1107.pack(false));
this.conn.send(p2pPack_1106.pack(false));
this.conn.send(p2pPack_1054.pack(false));
}
}
// 消息已读回执,给原消息发送方 1054
public sendP2PMessageReadedReceipt (rAck: any) {
console.log("=============== sendP2PMessageReadedRECEIPT")
console.log(rAck)
rAck.toId = rAck.fromId;
rAck.fromId = this.userId;
console.log(rAck)
let p2pPack = imClient.buildMessagePack(MessageCommand.MSG_READED_RECEIPT, rAck);
if (this.conn) {
console.log("=============== sendP2PMessageReadedRECEIPT 正式开始发送已读回执")
this.conn.send(p2pPack.pack(false));
}
}
public getUserId() { public getUserId() {
return this.userId; return this.userId;
} }

View File

@@ -1,5 +1,5 @@
export default class Logger { export default class Logger {
static debug = true; static debug = false;
static info(message?: any, ...optionalParams: any[]): void { static info(message?: any, ...optionalParams: any[]): void {
if(Logger.debug){ if(Logger.debug){