Example #1
0
BOOL CUIRecentSessionList::UpdateItemConentBySId(IN const std::string& sId)
{
	Node* pNode = GetItemBySId(sId);
	PTR_FALSE(pNode);
	CControlUI* pListElement = pNode->data().list_elment_;
	PTR_FALSE(pListElement);

	CLabelUI* plastMsgTimeUI = static_cast<CLabelUI*>(paint_manager_.FindSubControlByName(pListElement, lastContentTimeControlName));
	if (!plastMsgTimeUI)
	{
		return FALSE;
	}
	CLabelUI* plastMsgUI = static_cast<CLabelUI*>(paint_manager_.FindSubControlByName(pListElement, klastmsgControlName));
	if (!plastMsgUI)
	{
		return FALSE;
	}
	CLabelUI* Unreadcnt_button = static_cast<CLabelUI*>(paint_manager_.FindSubControlByName(pListElement, kUnreadcntControlName));
	if (!Unreadcnt_button)
	{
		return FALSE;
	}
	
	//更新会话的最后一条消息
	module::SessionEntity*  pSessionEntity = SessionEntityManager::getInstance()->getSessionEntityBySId(sId);
	if (!pSessionEntity)
	{
		LOG__(ERR, _T("Can't find the SessionEntity"));
		return FALSE;
	}
	std::string msgDecrptyCnt;
	DECRYPT_MSG(pSessionEntity->latestMsgContent, msgDecrptyCnt);
	CString strContent = util::stringToCString(msgDecrptyCnt);
	ReceiveMsgManage::getInstance()->parseContent(strContent, TRUE, 400);//需要转换成本地的格式

	module::UserInfoEntity userInfo;
	CString strMsgTalkName;
	if (module::SESSION_GROUPTYPE == pSessionEntity->sessionType &&//只有群需要展示 消息的发送者
		module::getUserListModule()->getUserInfoBySId(pSessionEntity->latestMsgFromId, userInfo))
	{
		strMsgTalkName = userInfo.getRealName();
		strMsgTalkName += CString(_T(":"));
	}
	strContent = strMsgTalkName + strContent;
	plastMsgUI->SetText(strContent);

	if (!SessionDialogManager::getInstance()->findSessionDialogBySId(sId))//窗口不存在的时候更新计数
	{
		//更新未读计数
		UInt32 nCnt = ReceiveMsgManage::getInstance()->getUnReadMsgCountBySId(sId);
        SetTextUICount(Unreadcnt_button, nCnt);
	}

	//更新消息的时间
	CString strTime = module::getMiscModule()->makeShortTimeDescription(pSessionEntity->updatedTime);
	plastMsgTimeUI->SetText(strTime);
	
	sort();
	return TRUE;
}
BOOL SessionLayout::_DisplayUnreadMsg()
{
	SessionMessage_List msgList;
	if (!ReceiveMsgManage::getInstance()->popMessagesBySId(m_sId, msgList) && msgList.empty())
	{
		//没有未读消息
		return FALSE;
	}

	for (auto MessageInfo : msgList)
	{
        if (MESSAGE_RENDERTYPE_SYSTEMTIPS != MessageInfo.msgRenderType)
        {
            DECRYPT_MSG(MessageInfo.content, MessageInfo.content);
        }
		_DisplayMsgToIE(MessageInfo);
	}

	//保存到历史消息中
	module::getDatabaseModule()->sqlBatchInsertMessage(msgList);
	//离线消息需要重置获取历史消息的msgid
	MessageEntity msgFront = msgList.front();
	module::getMessageModule()->setSessionTopMsgId(msgFront.sessionId, msgFront.msgId -1);
	
    //更新总未读计数
    module::getSessionModule()->asynNotifyObserver(module::KEY_SESSION_UPDATE_TOTAL_UNREADMSG_COUNT);

	//发送已读确认
	auto msgBack = msgList.back();
	_AsynSendReadAck(msgBack);
	return TRUE;
}
void SessionLayout::_DafoNetWorkPicMsg(OUT MixedMsg& mixMsg)
{
	if (!mixMsg.IsPureTextMsg())
	{
		return;
	}
	const CString strDafo = _T("dafo:");
	UInt32 nPos = mixMsg.m_strTextData.Find(strDafo);
	if (0 == nPos)
	{
		CString strContent = mixMsg.m_strTextData.Mid(strDafo.GetLength());
		mixMsg.m_strTextData = MixedMsg::AddPicTeg2Pic(strContent);
		return;
	}
	const CString strRandom = _T("@random");
	nPos = mixMsg.m_strTextData.Find(strRandom);
	if (0 == nPos)
	{
		std::string sid = module::getUserListModule()->randomGetUser();
		module::UserInfoEntity userInfo;
		module::getUserListModule()->getUserInfoBySId(sid, userInfo);
		mixMsg.m_strTextData = _T("@") + userInfo.getRealName();
		return;
	}
	const CString strUnReadCnt = _T("@unreadcnt");
	nPos = mixMsg.m_strTextData.Find(strUnReadCnt);
	if (0 == nPos)
	{
		UInt32 nCount = module::getMessageModule()->getTotalUnReadMsgCount();
		mixMsg.m_strTextData = _T("我的总未读计数为:") + util::int32ToCString(nCount);
		return;
	}
	const UInt32 nMySid = module::getSysConfigModule()->userId();
	if (374 == nMySid || 135 == nMySid)//只有大佛和快刀可用
	{
		const CString strDecode = _T("decode:");
		nPos = mixMsg.m_strTextData.Find(strDecode);
		if (0 == nPos)
		{
			CString strContent = mixMsg.m_strTextData.Mid(strDecode.GetLength());
			std::string content = util::cStringToString(strContent);
			std::string msgDecrptyCnt;
			DECRYPT_MSG(content, msgDecrptyCnt);
			mixMsg.m_strTextData = util::stringToCString(msgDecrptyCnt);
			return;
		}
		const CString strEncode = _T("encode:");
		nPos = mixMsg.m_strTextData.Find(strEncode);
		if (0 == nPos)
		{
			CString strContent = mixMsg.m_strTextData.Mid(strEncode.GetLength());
			std::string content = util::cStringToString(strContent);
			std::string msgDecrptyCnt;
			ENCRYPT_MSG(content, msgDecrptyCnt);
			mixMsg.m_strTextData = util::stringToCString(msgDecrptyCnt);
			return;
		}
	}
}
BOOL DatabaseModule_Impl::sqlBatchInsertMessage(IN std::list<MessageEntity>& msgList)
{
	if (module::TCPCLIENT_STATE_DISCONNECT == module::getTcpClientModule()->getTcpClientNetState())
	{
		LOG__(ERR, _T("TCPCLIENT_STATE_DISCONNECT"));
		return FALSE;
	}
	if (msgList.empty())
	{
		LOG__(ERR, _T("msgList is empty!"));
		return FALSE;
	}
	MessageEntity msg;
	try
	{
		CppSQLite3Statement stmtBegin = m_pSqliteDB->compileStatement(BeginInsert.c_str());
		stmtBegin.execDML();

		std::list<MessageEntity>::iterator iter = msgList.begin();
		for (; iter != msgList.end(); ++iter)
		{
			MessageEntity msg = *iter;
			if (msg.msgId <= 0)//非法的msg消息不用存储
			{
				std::string msgDecrptyCnt;
				DECRYPT_MSG(msg.content,msgDecrptyCnt);
				LOG__(ERR, _T("msgid <= 0, msgid:%d msg_content:%s Don't save to DB!")
					, msg.msgId, util::stringToCString(msgDecrptyCnt));
				continue;
			}
			CppSQLite3Statement stmt = m_pSqliteDB->compileStatement(insertMessageSql.c_str());
			stmt.bind(1, (Int32)msg.msgId);
			stmt.bind(2, msg.sessionId.c_str());
			stmt.bind(3, msg.talkerSid.c_str());
			//对语音消息做个特殊处理,content存储的是json格式字符串
			if (MESSAGE_RENDERTYPE_AUDIO == msg.msgRenderType)
			{
				Json::Value root;
				root["msgAudioTime"] = msg.msgAudioTime;
				root["msgAudioId"] = msg.content;
				Json::FastWriter fstWrite;
				std::string audioContent = fstWrite.write(root);
				stmt.bind(4, audioContent.c_str());
			}
			else
			{
				stmt.bind(4, msg.content.c_str());
			}
			stmt.bind(5, msg.msgRenderType);
			stmt.bind(6, msg.msgSessionType);
			stmt.bind(7, (Int32)msg.msgTime);
			stmt.bind(8, time(0));
			stmt.execDML();
		}

		CppSQLite3Statement stmtEnd = m_pSqliteDB->compileStatement(EndInsert.c_str());
		stmtEnd.execDML();
	}
	catch (CppSQLite3Exception& e)
	{
		CString csErrMsg = util::stringToCString(e.errorMessage());
		LOG__(ERR, _T("db failed,error msg:%s"), csErrMsg);
		CppSQLite3Statement stmtRollback = m_pSqliteDB->compileStatement(RollBack.c_str());
		stmtRollback.execDML();
		_msgToTrace(msg);
		return FALSE;
	}
	catch (...)
	{
		LOG__(ERR, _T("db unknown exception"));
		_msgToTrace(msg);
		return FALSE;
	}

	return TRUE;
}
BOOL DatabaseModule_Impl::sqlInsertMessage(IN MessageEntity& msg)
{
	if (module::TCPCLIENT_STATE_DISCONNECT == module::getTcpClientModule()->getTcpClientNetState()
		|| MESSAGE_RENDERTYPE_SYSTEMTIPS == msg.msgRenderType)
	{
		return FALSE;
	}
	if (msg.msgId <= 0)
	{
		std::string msgDecrptyCnt;
		DECRYPT_MSG(msg.content, msgDecrptyCnt);
		LOG__(ERR, _T("msgid <= 0, msgid:%d msg_content:%s Don't save to DB!")
			, msg.msgId, util::stringToCString(msgDecrptyCnt));
		return FALSE;
	}

	try
	{
		CppSQLite3Statement stmt = m_pSqliteDB->compileStatement(insertMessageSql.c_str());
		stmt.bind(1, (Int32)msg.msgId);
		stmt.bind(2, msg.sessionId.c_str());
		stmt.bind(3, msg.talkerSid.c_str());
		//对语音消息做个特殊处理,content存储的是json格式字符串
		if (MESSAGE_RENDERTYPE_AUDIO == msg.msgRenderType)
		{
			Json::Value root;
			root["msgAudioTime"] = msg.msgAudioTime;
			root["msgAudioId"] = msg.content;
			Json::FastWriter fstWrite;
			std::string audioContent = fstWrite.write(root);
			stmt.bind(4, audioContent.c_str());
		}
		else
		{
			stmt.bind(4, msg.content.c_str());
		}
		stmt.bind(5, msg.msgRenderType);
		stmt.bind(6, msg.msgSessionType);
		stmt.bind(7, (Int32)msg.msgTime);
		stmt.bind(8, time(0));
		stmt.execDML();
	}

	catch (CppSQLite3Exception& sqliteException)
	{
#ifdef _DEBUG
		//MessageBoxA(0, sqliteException.errorMessage(), "BD ERROR", MB_OK | MB_ICONHAND);
#endif
		CString csErrMsg = util::stringToCString(sqliteException.errorMessage(), CP_UTF8);
		LOG__(ERR, _T("db failed,error msg:%s"), csErrMsg);
		_msgToTrace(msg);
		return FALSE;
	}
	catch (...)
	{
		LOG__(ERR, _T("db unknown exception"));
		_msgToTrace(msg);
		return FALSE;
	}

	return TRUE;
}
void SessionLayout::DoDisplayHistoryMsgToIE(std::vector<MessageEntity>& msgList, BOOL scrollBottom)
{
	Json::Value root;
	for (auto itMsg = msgList.rbegin();itMsg != msgList.rend(); ++itMsg)
	{
		module::UserInfoEntity userInfo;
		if (!module::getUserListModule()->getUserInfoBySId(itMsg->talkerSid, userInfo))
			continue;

		//组装json data
		Json::Value msgItem;
		msgItem["name"] = util::cStringToString(userInfo.getRealName());
		msgItem["avatar"] = userInfo.getAvatarPathWithoutOnlineState();
		msgItem["mtype"] = itMsg->isMySendMsg() ? "me" : "other";
		CTime time(itMsg->msgTime);
		msgItem["time"] = util::cStringToString(time.Format(_T("%Y-%m-%d %H:%M:%S")));
		msgItem["uuid"] = itMsg->talkerSid;
		msgItem["msgtype"] = itMsg->msgRenderType;

		if (MESSAGE_RENDERTYPE_AUDIO == itMsg->msgRenderType)
		{
			msgItem["voiceid"] = itMsg->content;
			CString sVoicetime;
			sVoicetime.Format(_T("%d秒"), itMsg->msgAudioTime);
			msgItem["voicetime"] = util::cStringToString(sVoicetime, CP_UTF8);
			msgItem["voiceisread"] = itMsg->isReaded() ? std::string("true") : string("false");
		}
		else
		{
			std::string msgDecrptyCnt;
			DECRYPT_MSG(itMsg->content, msgDecrptyCnt);
			CString content = util::stringToCString(msgDecrptyCnt);
			ReceiveMsgManage::getInstance()->parseContent(content, FALSE, GetWidth());
			msgItem["content"] = util::cStringToString(content);
		}

		root.append(msgItem);
	}

	Json::StyledWriter styleWrite;
	std::string record = styleWrite.write(root);
	CString jsData = _T("[]");
	Json::Reader jsonRead;
	Json::Value rootRead;
	if (!jsonRead.parse(record, rootRead) || rootRead.isNull())
	{
		CString csError = util::stringToCString(record, CP_UTF8);
		LOG__(ERR, _T("history is null or json parse error:%s"), csError);
		jsData = _T("[]");
	}
	else
	{
		jsData = util::stringToCString(record);
	}

	//调用js
	CComVariant result;
	BOOL bRet = m_pWebBrowser->CallJScript(_T("historyMessage"), jsData.GetBuffer(), &result);
	if (!bRet)
		LOG__(ERR, _T("CallJScript failed,%s"), jsData);
	if (scrollBottom)
	{
		module::getEventManager()->asynFireUIEventWithLambda(
			[=]()
		{
			CComVariant result;
			m_pWebBrowser->CallJScript(_T("scrollBottom"), _T(""), &result);
		});
	}
}