fix: 修改频道和频道成员及提醒项扩展字段保存错误问题

This commit is contained in:
SL 2025-05-20 11:59:32 +08:00
parent 66fb59ac67
commit 95f07c5add
9 changed files with 114 additions and 55 deletions

View File

@ -127,4 +127,6 @@
### 1.6.3 ### 1.6.3
* fix: 优化在未收到服务端心跳消息时主动断开重连 * fix: 优化在未收到服务端心跳消息时主动断开重连
### 1.6.4 ### 1.6.4
* fix: 新增监听头像改变事件 * fix: 新增监听头像改变事件###
### 1.6.5
* fix: 修改频道和频道成员及提醒项扩展字段保存错误问题

View File

@ -1,3 +1,4 @@
import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
@ -13,27 +14,28 @@ class HttpUtils {
// static String apiURL = "https://api.githubim.com"; // static String apiURL = "https://api.githubim.com";
static String apiURL = "http://62.234.8.38:7090/v1"; static String apiURL = "http://62.234.8.38:7090/v1";
// static String apiURL = "http://175.27.245.108:15001"; // static String apiURL = "http://175.27.245.108:15001";
static Dio? _dio; static Dio? _dio;
/// Get Dio instance with trust all certificates configuration /// Get Dio instance with trust all certificates configuration
static Dio get dio { static Dio get dio {
if (_dio == null) { if (_dio == null) {
final httpClient = HttpClient(); final httpClient = HttpClient();
httpClient.badCertificateCallback = httpClient.badCertificateCallback =
(X509Certificate cert, String host, int port) => true; // Trust all certificates (X509Certificate cert, String host, int port) =>
true; // Trust all certificates
_dio = Dio(BaseOptions( _dio = Dio(BaseOptions(
baseUrl: apiURL, baseUrl: apiURL,
// //
validateStatus: (status) => true, validateStatus: (status) => true,
)); ));
(_dio!.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (_dio!.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
(client) => httpClient; (client) => httpClient;
} }
return _dio!; return _dio!;
} }
static String getAvatarUrl(String uid) { static String getAvatarUrl(String uid) {
return "$apiURL/users/$uid/avatar"; return "$apiURL/users/$uid/avatar";
} }
@ -50,7 +52,7 @@ class HttpUtils {
'device_flag': 0, 'device_flag': 0,
'device_level': 1 'device_level': 1
}); });
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
UserInfo.name = response.data['name']; UserInfo.name = response.data['name'];
} }
@ -73,8 +75,8 @@ class HttpUtils {
return ''; return '';
} }
static Future<void> syncConversation(String lastSsgSeqs, int msgCount, int version, static Future<void> syncConversation(String lastSsgSeqs, int msgCount,
Function(WKSyncConversation) back) async { int version, Function(WKSyncConversation) back) async {
try { try {
// //
if (UserInfo.uid.isEmpty) { if (UserInfo.uid.isEmpty) {
@ -90,7 +92,7 @@ class HttpUtils {
"msg_count": msgCount, "msg_count": msgCount,
"device_uuid": UserInfo.uid, "device_uuid": UserInfo.uid,
}); });
WKSyncConversation conversation = WKSyncConversation(); WKSyncConversation conversation = WKSyncConversation();
conversation.conversations = []; conversation.conversations = [];
@ -149,11 +151,11 @@ class HttpUtils {
"channel_id": channelID, "channel_id": channelID,
"channel_type": channelType, "channel_type": channelType,
"start_message_seq": startMsgSeq, "start_message_seq": startMsgSeq,
"end_message_seq": endMsgSeq, "end_message_seq": endMsgSeq,
"limit": limit, "limit": limit,
"pull_mode": pullMode "pull_mode": pullMode
}); });
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
var data = response.data; var data = response.data;
WKSyncChannelMsg msg = WKSyncChannelMsg(); WKSyncChannelMsg msg = WKSyncChannelMsg();
@ -232,7 +234,7 @@ class HttpUtils {
} }
final response = await dio.get('/groups/$groupId'); final response = await dio.get('/groups/$groupId');
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
var json = response.data; var json = response.data;
var channel = WKChannel(groupId, WKChannelType.group); var channel = WKChannel(groupId, WKChannelType.group);
@ -266,12 +268,15 @@ class HttpUtils {
} }
final response = await dio.get('/users/$uid'); final response = await dio.get('/users/$uid');
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
var json = response.data; var json = response.data;
var channel = WKChannel(uid, WKChannelType.personal); var channel = WKChannel(uid, WKChannelType.personal);
channel.channelName = json['name']; channel.channelName = json['name'];
channel.avatar = json['avatar']; channel.avatar = json['avatar'];
//
// channel.remoteExtraMap = jsonEncode({"name": "xx", "sex": 1});
// channel.localExtra = jsonEncode({"name1": "xx", "sex1": 1, "t": "2"});
WKIM.shared.channelManager.addOrUpdateChannel(channel); WKIM.shared.channelManager.addOrUpdateChannel(channel);
} else { } else {
print('获取用户信息失败: HTTP ${response.statusCode}'); print('获取用户信息失败: HTTP ${response.statusCode}');
@ -285,8 +290,8 @@ class HttpUtils {
} }
} }
static Future<bool> revokeMsg(String clientMsgNo, String channelId, int channelType, static Future<bool> revokeMsg(String clientMsgNo, String channelId,
int msgSeq, String msgId) async { int channelType, int msgSeq, String msgId) async {
try { try {
// //
if (clientMsgNo.isEmpty || channelId.isEmpty || msgId.isEmpty) { if (clientMsgNo.isEmpty || channelId.isEmpty || msgId.isEmpty) {
@ -308,7 +313,7 @@ class HttpUtils {
'message_seq': msgSeq, 'message_seq': msgSeq,
'message_id': msgId, 'message_id': msgId,
}); });
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
print('消息撤回成功'); print('消息撤回成功');
return true; return true;
@ -325,8 +330,8 @@ class HttpUtils {
} }
} }
static Future<bool> deleteMsg(String clientMsgNo, String channelId, int channelType, static Future<bool> deleteMsg(String clientMsgNo, String channelId,
int msgSeq, String msgId) async { int channelType, int msgSeq, String msgId) async {
try { try {
// //
if (clientMsgNo.isEmpty || channelId.isEmpty || msgId.isEmpty) { if (clientMsgNo.isEmpty || channelId.isEmpty || msgId.isEmpty) {
@ -347,7 +352,7 @@ class HttpUtils {
'message_seq': msgSeq, 'message_seq': msgSeq,
'message_id': msgId, 'message_id': msgId,
}); });
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
WKIM.shared.messageManager.deleteWithClientMsgNo(clientMsgNo); WKIM.shared.messageManager.deleteWithClientMsgNo(clientMsgNo);
print('消息删除成功'); print('消息删除成功');
@ -365,7 +370,8 @@ class HttpUtils {
} }
} }
static Future<void> syncMsgExtra(String channelId, int channelType, int version) async { static Future<void> syncMsgExtra(
String channelId, int channelType, int version) async {
try { try {
final response = await dio.post('/message/extra/sync', data: { final response = await dio.post('/message/extra/sync', data: {
'login_uid': UserInfo.uid, 'login_uid': UserInfo.uid,
@ -375,7 +381,7 @@ class HttpUtils {
'limit': 100, 'limit': 100,
'extra_version': version, 'extra_version': version,
}); });
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
var arrJson = response.data; var arrJson = response.data;
if (arrJson != null && arrJson.length > 0) { if (arrJson != null && arrJson.length > 0) {
@ -409,7 +415,7 @@ class HttpUtils {
'channel_type': channelType, 'channel_type': channelType,
'unread': 0, 'unread': 0,
}); });
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
print('Unread count cleared successfully'); print('Unread count cleared successfully');
} }
@ -423,14 +429,14 @@ class HttpUtils {
try { try {
int maxSeq = await WKIM.shared.messageManager int maxSeq = await WKIM.shared.messageManager
.getMaxMessageSeq(channelId, channelType); .getMaxMessageSeq(channelId, channelType);
final response = await dio.post('/message/offset', data: { final response = await dio.post('/message/offset', data: {
'login_uid': UserInfo.uid, 'login_uid': UserInfo.uid,
'channel_id': channelId, 'channel_id': channelId,
'channel_type': channelType, 'channel_type': channelType,
'message_seq': maxSeq 'message_seq': maxSeq
}); });
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
WKIM.shared.messageManager.clearWithChannel(channelId, channelType); WKIM.shared.messageManager.clearWithChannel(channelId, channelType);
} }

View File

@ -51,6 +51,8 @@ class ChatListDataState extends State<ChatList> {
.then((channel) { .then((channel) {
WKIM.shared.channelManager.fetchChannelInfo(channelID, channelType); WKIM.shared.channelManager.fetchChannelInfo(channelID, channelType);
title = '${channel?.channelName}'; title = '${channel?.channelName}';
print("扩展:${channel?.localExtra}");
print("扩展1${channel?.remoteExtraMap}");
}); });
} }
List<UIMsg> msgList = []; List<UIMsg> msgList = [];
@ -506,7 +508,7 @@ Widget _buildItem(UIMsg uiMsg, BuildContext context) {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => ChatPage(), builder: (context) => const ChatPage(),
settings: RouteSettings( settings: RouteSettings(
arguments: ChatChannel( arguments: ChatChannel(
uiMsg.wkMsg.channelID, uiMsg.wkMsg.channelID,

View File

@ -1,6 +1,9 @@
import 'dart:convert';
import 'package:example/const.dart'; import 'package:example/const.dart';
import 'package:example/http.dart'; import 'package:example/http.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:wukongimfluttersdk/db/const.dart';
import 'package:wukongimfluttersdk/entity/conversation.dart'; import 'package:wukongimfluttersdk/entity/conversation.dart';
import 'package:wukongimfluttersdk/entity/reminder.dart'; import 'package:wukongimfluttersdk/entity/reminder.dart';
import 'package:wukongimfluttersdk/type/const.dart'; import 'package:wukongimfluttersdk/type/const.dart';
@ -81,10 +84,10 @@ class ListViewShowDataState extends State<ListViewShowData> {
for (var i = 0; i < msgList.length; i++) { for (var i = 0; i < msgList.length; i++) {
msgList[i].msg.unreadCount = 0; msgList[i].msg.unreadCount = 0;
} }
// //
_sortMessagesByTimestamp(); _sortMessagesByTimestamp();
setState(() {}); setState(() {});
}); });
WKIM.shared.conversationManager WKIM.shared.conversationManager
@ -111,9 +114,9 @@ class ListViewShowDataState extends State<ListViewShowData> {
if (list.isNotEmpty) { if (list.isNotEmpty) {
msgList.addAll(list); msgList.addAll(list);
} }
_sortMessagesByTimestamp(); _sortMessagesByTimestamp();
if (mounted) { if (mounted) {
setState(() {}); setState(() {});
} }
@ -127,10 +130,10 @@ class ListViewShowDataState extends State<ListViewShowData> {
msgList[i].msg.setWkChannel(channel); msgList[i].msg.setWkChannel(channel);
msgList[i].channelAvatar = "${HttpUtils.apiURL}/${channel.avatar}"; msgList[i].channelAvatar = "${HttpUtils.apiURL}/${channel.avatar}";
msgList[i].channelName = channel.channelName; msgList[i].channelName = channel.channelName;
// //
_sortMessagesByTimestamp(); _sortMessagesByTimestamp();
setState(() {}); setState(() {});
break; break;
} }
@ -140,7 +143,8 @@ class ListViewShowDataState extends State<ListViewShowData> {
/// ///
void _sortMessagesByTimestamp() { void _sortMessagesByTimestamp() {
msgList.sort((a, b) => b.msg.lastMsgTimestamp.compareTo(a.msg.lastMsgTimestamp)); msgList.sort(
(a, b) => b.msg.lastMsgTimestamp.compareTo(a.msg.lastMsgTimestamp));
} }
void _getDataList() { void _getDataList() {
@ -150,7 +154,7 @@ class ListViewShowDataState extends State<ListViewShowData> {
for (var i = 0; i < result.length; i++) { for (var i = 0; i < result.length; i++) {
msgList.add(UIConversation(result[i])); msgList.add(UIConversation(result[i]));
} }
_sortMessagesByTimestamp(); _sortMessagesByTimestamp();
setState(() {}); setState(() {});
}); });
@ -183,8 +187,16 @@ class ListViewShowDataState extends State<ListViewShowData> {
if (uiConversation.reminders![i].type == if (uiConversation.reminders![i].type ==
WKMentionType.wkReminderTypeMentionMe && WKMentionType.wkReminderTypeMentionMe &&
uiConversation.reminders![i].done == 0) { uiConversation.reminders![i].done == 0) {
content = uiConversation.reminders![i].data; var d = uiConversation.reminders![i].data;
content = '[有人@你]'; if (d is Map) {
content = d['type'];
} else if (d is String && WKDBConst.isJsonString(d)) {
var obj = jsonDecode(d);
content = obj['type'];
} else {
content = d;
}
// content = uiConversation.reminders![i].data;
break; break;
} }
} }
@ -441,13 +453,16 @@ class ListViewShowDataState extends State<ListViewShowData> {
WKReminder reminder = WKReminder(); WKReminder reminder = WKReminder();
reminder.needUpload = 0; reminder.needUpload = 0;
reminder.type = WKMentionType.wkReminderTypeMentionMe; reminder.type = WKMentionType.wkReminderTypeMentionMe;
reminder.data = '[有人@你]'; // reminder.data = '[有人@你]';
reminder.done = 0; reminder.done = 0;
reminder.reminderID = 11; reminder.reminderID = 11;
reminder.version = 1; reminder.version = 1;
reminder.publisher = "uid_1"; reminder.publisher = "uid_1";
reminder.channelID = uiMsg.msg.channelID; reminder.channelID = uiMsg.msg.channelID;
reminder.channelType = uiMsg.msg.channelType; reminder.channelType = uiMsg.msg.channelType;
//
reminder.data = "[有人@你]";
// reminder.data = jsonEncode({"type": "[有人@你]"});
list.add(reminder); list.add(reminder);
WKIM.shared.reminderManager.saveOrUpdateReminders(list); WKIM.shared.reminderManager.saveOrUpdateReminders(list);
})); }));

View File

@ -1,6 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:collection'; import 'dart:collection';
import 'dart:convert';
import 'package:sqflite/sqflite.dart'; import 'package:sqflite/sqflite.dart';
import 'package:wukongimfluttersdk/db/const.dart'; import 'package:wukongimfluttersdk/db/const.dart';
@ -216,12 +215,8 @@ class ChannelDB {
data['device_flag'] = channel.deviceFlag; data['device_flag'] = channel.deviceFlag;
data['parent_channel_id'] = channel.parentChannelID; data['parent_channel_id'] = channel.parentChannelID;
data['parent_channel_type'] = channel.parentChannelType; data['parent_channel_type'] = channel.parentChannelType;
if (channel.remoteExtraMap != null) { data['remote_extra'] = channel.remoteExtraMap?.toString() ?? "";
data['remote_extra'] = jsonEncode(channel.remoteExtraMap); data['extra'] = channel.localExtra?.toString() ?? "";
}
if (channel.localExtra != null) {
data['extra'] = jsonEncode(channel.localExtra);
}
return data; return data;
} }
} }

View File

@ -1,5 +1,3 @@
import 'dart:convert';
import 'package:sqflite/sqflite.dart'; import 'package:sqflite/sqflite.dart';
import '../entity/channel_member.dart'; import '../entity/channel_member.dart';
@ -152,9 +150,7 @@ class ChannelMemberDB {
map['forbidden_expiration_time'] = member.forbiddenExpirationTime; map['forbidden_expiration_time'] = member.forbiddenExpirationTime;
map['created_at'] = member.createdAt; map['created_at'] = member.createdAt;
map['updated_at'] = member.updatedAt; map['updated_at'] = member.updatedAt;
if (member.extraMap != null) { map['extra'] = member.extraMap?.toString() ?? "";
map['extra'] = jsonEncode(member.extraMap);
}
return map; return map;
} }
} }

View File

@ -1,5 +1,4 @@
import 'dart:collection'; import 'dart:collection';
import 'dart:convert';
import 'package:sqflite/sqflite.dart'; import 'package:sqflite/sqflite.dart';
import 'package:wukongimfluttersdk/db/const.dart'; import 'package:wukongimfluttersdk/db/const.dart';
@ -180,12 +179,13 @@ class ReminderDB {
map['done'] = reminder.done; map['done'] = reminder.done;
map['need_upload'] = reminder.needUpload; map['need_upload'] = reminder.needUpload;
map['publisher'] = reminder.publisher; map['publisher'] = reminder.publisher;
if (reminder.data != null) { //
map['data'] = jsonEncode(reminder.data); var len = reminder.data?.toString().length ?? 0;
if (len < 1000000) {
map['data'] = reminder.data?.toString() ?? "";
} else { } else {
map['data'] = ''; map['data'] = '';
} }
return map; return map;
} }
} }

View File

@ -15,7 +15,7 @@ description: wukong IM flutter sdk
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
version: 1.6.4 version: 1.6.5
homepage: https://github.com/WuKongIM/WuKongIMFlutterSDK homepage: https://github.com/WuKongIM/WuKongIMFlutterSDK
environment: environment:

View File

@ -0,0 +1,43 @@
import 'dart:convert';
void main() {
// dynamic
dynamic emptyList = [];
print('Empty list: ${jsonEncode(emptyList)}');
dynamic emptyMap = {};
print('Empty map: ${jsonEncode(emptyMap)}');
//
dynamic emptyInt = 0;
print('Empty int (0): ${jsonEncode(emptyInt)}');
dynamic emptyDouble = 0.0;
print('Empty double (0.0): ${jsonEncode(emptyDouble)}');
dynamic emptyBool = false;
print('Empty bool (false): ${jsonEncode(emptyBool)}');
// null
print('Null value: ${jsonEncode(null)}');
//
String emptyString = '';
print('Empty string: ${jsonEncode(emptyString)}');
//
String normalString = 'Hello World';
print('Normal string: ${jsonEncode(normalString)}');
//
String specialString = 'Hello "World" with \'quotes\' and \\backslash\\';
print('Special string: ${jsonEncode(specialString)}');
//
String multilineString = 'Line 1\nLine 2\nLine 3';
print('Multiline string: ${jsonEncode(multilineString)}');
// Unicode字符的字符串
String unicodeString = '你好,世界!';
print('Unicode string: ${jsonEncode(unicodeString)}');
}