2025-12-12 17:46:37 +08:00
|
|
|
|
#include "instance/dataAccessor.h"
|
2025-12-19 18:28:13 +08:00
|
|
|
|
#include "communicationManager.h"
|
|
|
|
|
|
#include "uiCommunicationBus.h"
|
|
|
|
|
|
#include "configManager.h"
|
|
|
|
|
|
#include "diagramCavas.h"
|
|
|
|
|
|
#include "diagramConnectSetting.h"
|
2025-12-15 14:38:17 +08:00
|
|
|
|
#include <QVariant>
|
|
|
|
|
|
#include <QJsonObject>
|
|
|
|
|
|
#include <QJsonArray>
|
2025-12-19 18:28:13 +08:00
|
|
|
|
#include "global.h"
|
2025-12-12 17:46:37 +08:00
|
|
|
|
|
2025-12-25 09:03:35 +08:00
|
|
|
|
const int DIAGRAM_MAX_DATA_COUNT = 1000;
|
|
|
|
|
|
|
2025-12-12 17:46:37 +08:00
|
|
|
|
DataAccessor::DataAccessor(QObject* parent)
|
|
|
|
|
|
: QObject(parent)
|
2025-12-19 18:28:13 +08:00
|
|
|
|
,_parentCavas(nullptr)
|
2025-12-12 17:46:37 +08:00
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DataAccessor::~DataAccessor()
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2025-12-15 14:38:17 +08:00
|
|
|
|
|
|
|
|
|
|
void DataAccessor::onReceiveHttpData(const QString& sType,const QVariant& data)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(sType == "subscriptions"){
|
2025-12-19 18:28:13 +08:00
|
|
|
|
QMap<QString,QList<QPair<QString,QString>>>& tempRequest = UiCommunicationBus::instance()->getTempRequestMap();
|
2025-12-15 14:38:17 +08:00
|
|
|
|
QJsonObject dataObj = data.toJsonObject();
|
|
|
|
|
|
QString sClientId = dataObj.value("client_id").toString();
|
|
|
|
|
|
|
2025-12-19 18:28:13 +08:00
|
|
|
|
QMap<QString,QString> lstTarget;
|
2025-12-25 09:03:35 +08:00
|
|
|
|
QJsonArray targetArr = dataObj.value("targets").toArray();
|
|
|
|
|
|
for(const QJsonValue& value : targetArr){
|
2025-12-15 14:38:17 +08:00
|
|
|
|
QJsonObject obj = value.toObject();
|
|
|
|
|
|
QString sId = obj["id"].toString();
|
|
|
|
|
|
QString sCode = obj["code"].toString();
|
|
|
|
|
|
|
2025-12-25 09:03:35 +08:00
|
|
|
|
qDebug() << "subscription:"+sId+"_"+sCode;
|
2025-12-19 18:28:13 +08:00
|
|
|
|
if(!lstTarget.contains(sId)){
|
|
|
|
|
|
lstTarget.insert(sId,sCode);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QString sAction;
|
|
|
|
|
|
auto mapSesstion = UiCommunicationBus::instance()->getSesstionMap();
|
|
|
|
|
|
bool bClientExist = false;
|
|
|
|
|
|
for(auto& session:mapSesstion){
|
|
|
|
|
|
if(session.first == sClientId){ //在会话列表中已存在,是stop(暂只使用stop和start)
|
|
|
|
|
|
bClientExist = true;
|
|
|
|
|
|
sAction = "stop";
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(sAction.isEmpty()){ //不是stop的情况
|
|
|
|
|
|
QStringList lstKeys = lstTarget.keys();
|
|
|
|
|
|
for(auto it = tempRequest.begin(); it != tempRequest.end(); ++it){
|
|
|
|
|
|
const QString& page = it.key();
|
|
|
|
|
|
QList<QPair<QString, QString>>& tempList = it.value();
|
|
|
|
|
|
|
|
|
|
|
|
// 从 tempList 提取所有 first 元素
|
|
|
|
|
|
QStringList firstElements;
|
|
|
|
|
|
firstElements.reserve(tempList.size());
|
|
|
|
|
|
for (const auto& pair : tempList)
|
|
|
|
|
|
{
|
|
|
|
|
|
firstElements.append(pair.first);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 对两个列表进行排序(因为 moveMatchingRequests 内部会排序比较)
|
|
|
|
|
|
QStringList sortedFirstElements = firstElements;
|
|
|
|
|
|
QStringList sortedLstKeys = lstKeys;
|
|
|
|
|
|
|
|
|
|
|
|
std::sort(sortedFirstElements.begin(), sortedFirstElements.end());
|
|
|
|
|
|
std::sort(sortedLstKeys.begin(), sortedLstKeys.end());
|
|
|
|
|
|
|
|
|
|
|
|
// 比较两个列表是否相同
|
|
|
|
|
|
if (sortedFirstElements == sortedLstKeys)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 调用 moveMatchingRequests
|
|
|
|
|
|
for(auto& pair:tempList){
|
|
|
|
|
|
pair.second = "connecting";
|
|
|
|
|
|
}
|
2025-12-25 09:03:35 +08:00
|
|
|
|
UiCommunicationBus::instance()->insertSesstionMap(sClientId, lstTarget);
|
2025-12-19 18:28:13 +08:00
|
|
|
|
sAction = "start";
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(!lstTarget.isEmpty()){
|
|
|
|
|
|
if(sAction == "start"){
|
|
|
|
|
|
auto config = ConfigManager::instance()->getWebSocketConfig();
|
|
|
|
|
|
QString sPre = removeAfterStreamBySplit(config.endpoint); //手动移除
|
|
|
|
|
|
config.endpoint = sPre + "/" + sClientId;
|
|
|
|
|
|
CommunicationManager::instance()->updateWebSocketConfig(config,sClientId);
|
2025-12-25 09:03:35 +08:00
|
|
|
|
bool res = CommunicationManager::instance()->connectWebSocket(sClientId);
|
|
|
|
|
|
int a = 1;
|
2025-12-19 18:28:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
else if(sAction == "stop"){ //已经停止完毕,从session中移除会话
|
|
|
|
|
|
auto &map = UiCommunicationBus::instance()->getSesstionMap();
|
|
|
|
|
|
for(auto iter = map.begin();iter != map.end();++iter){
|
|
|
|
|
|
if(iter->first == sClientId){
|
|
|
|
|
|
iter = map.erase(iter);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2025-12-15 14:38:17 +08:00
|
|
|
|
}
|
2025-12-19 18:28:13 +08:00
|
|
|
|
CommunicationManager::instance()->disconnectWebSocket(sClientId);
|
|
|
|
|
|
CommunicationManager::instance()->removeChannel(sClientId);
|
2025-12-15 14:38:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-19 18:28:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
else if(sType == "recommend"){
|
|
|
|
|
|
QJsonArray dataArr = data.toJsonArray();
|
|
|
|
|
|
for(const QJsonValue& value:dataArr){
|
|
|
|
|
|
QJsonObject dataObj = value.toObject();
|
|
|
|
|
|
QString input = dataObj.value("input").toString();
|
|
|
|
|
|
int offSet = dataObj.value("offset").toInt();
|
|
|
|
|
|
QJsonArray recommendedList = dataObj.value("recommended_list").toArray();
|
|
|
|
|
|
|
|
|
|
|
|
HttpRecommandInfo info;
|
|
|
|
|
|
for(const QJsonValue& value : recommendedList){
|
|
|
|
|
|
QString content = value.toString();
|
|
|
|
|
|
info.lstRecommand.append(content);
|
|
|
|
|
|
}
|
|
|
|
|
|
info.sInput = input.left(offSet);
|
|
|
|
|
|
info.nOffset = offSet;
|
|
|
|
|
|
if(_parentCavas){
|
|
|
|
|
|
_parentCavas->passRecommmandHttpData(info);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-25 09:03:35 +08:00
|
|
|
|
else if(sType == "subscriptionTest"){
|
|
|
|
|
|
qDebug()<<"receive null data";
|
|
|
|
|
|
}
|
2025-12-19 18:28:13 +08:00
|
|
|
|
if(_parentCavas){
|
|
|
|
|
|
auto pDlg = _parentCavas->getConnectSettingDlg();
|
|
|
|
|
|
if(pDlg){
|
|
|
|
|
|
QJsonObject jsonObj = data.value<QJsonObject>();
|
|
|
|
|
|
QJsonDocument doc(jsonObj);
|
|
|
|
|
|
QString compactJson = doc.toJson(QJsonDocument::Compact);
|
|
|
|
|
|
pDlg->updateHttpLog(sType,compactJson);
|
|
|
|
|
|
}
|
2025-12-15 14:38:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DataAccessor::onReceiveWebsocketData(const QVariant& data)
|
|
|
|
|
|
{
|
|
|
|
|
|
QJsonObject dataObj = data.toJsonObject();
|
|
|
|
|
|
if(dataObj.contains("targets")){
|
|
|
|
|
|
QJsonArray arrTarget = dataObj.value("targets").toArray();
|
|
|
|
|
|
for (const QJsonValue& value : arrTarget) {
|
|
|
|
|
|
QJsonObject targetObj = value.toObject();
|
|
|
|
|
|
QString targetId = targetObj["id"].toString();
|
|
|
|
|
|
QJsonArray arrData = targetObj["datas"].toArray();
|
2025-12-19 18:28:13 +08:00
|
|
|
|
|
|
|
|
|
|
QMap<quint64, double> newInnerMap;
|
2025-12-15 14:38:17 +08:00
|
|
|
|
for (const QJsonValue& data : arrData){
|
|
|
|
|
|
QJsonObject dataObj = data.toObject();
|
|
|
|
|
|
QString sTime = dataObj["time"].toString();
|
2025-12-19 18:28:13 +08:00
|
|
|
|
double dVal = dataObj["value"].toDouble();
|
2025-12-15 14:38:17 +08:00
|
|
|
|
bool ok = false;
|
|
|
|
|
|
quint64 value = sTime.toULongLong(&ok);
|
|
|
|
|
|
if (ok) {
|
2025-12-19 18:28:13 +08:00
|
|
|
|
newInnerMap.insert(value,dVal);
|
2025-12-15 14:38:17 +08:00
|
|
|
|
}
|
2025-12-19 18:28:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-25 09:03:35 +08:00
|
|
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
|
|
auto& innerMap = _realTimeData[targetId]; // 自动创建或获取
|
|
|
|
|
|
// 批量插入
|
|
|
|
|
|
innerMap.insert(newInnerMap);
|
|
|
|
|
|
// 如果数量超限,从开始处批量删除
|
|
|
|
|
|
int currentSize = innerMap.size();
|
|
|
|
|
|
if (currentSize > DIAGRAM_MAX_DATA_COUNT) {
|
|
|
|
|
|
int toRemove = currentSize - DIAGRAM_MAX_DATA_COUNT;
|
|
|
|
|
|
auto it = innerMap.begin();
|
|
|
|
|
|
// 批量删除最旧的toRemove个元素
|
|
|
|
|
|
for (int i = 0; i < toRemove && it != innerMap.end(); ++i) {
|
|
|
|
|
|
it = innerMap.erase(it);
|
|
|
|
|
|
}
|
2025-12-15 14:38:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-19 18:28:13 +08:00
|
|
|
|
if(_parentCavas){
|
|
|
|
|
|
auto pDlg = _parentCavas->getConnectSettingDlg();
|
|
|
|
|
|
if(pDlg){
|
|
|
|
|
|
QJsonObject jsonObj = data.value<QJsonObject>();
|
|
|
|
|
|
QJsonDocument doc(jsonObj);
|
|
|
|
|
|
QString compactJson = doc.toJson(QJsonDocument::Compact);
|
|
|
|
|
|
pDlg->updateWebsocketLog(compactJson);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-19 20:05:50 +08:00
|
|
|
|
QMap<QString,QMap<quint64,double>> DataAccessor::getTargetData(QStringList paraLst)
|
|
|
|
|
|
{
|
|
|
|
|
|
QMap<QString, QMap<quint64, double>> mapData;
|
|
|
|
|
|
|
|
|
|
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
|
|
for (const QString& key : paraLst) {
|
|
|
|
|
|
if (_realTimeData.contains(key)) {
|
|
|
|
|
|
mapData.insert(key, _realTimeData.value(key));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return mapData;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-19 18:28:13 +08:00
|
|
|
|
QString DataAccessor::removeAfterStreamBySplit(const QString& url)
|
|
|
|
|
|
{
|
|
|
|
|
|
QStringList parts = url.split('/');
|
|
|
|
|
|
QStringList resultParts;
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < parts.size(); i++) {
|
|
|
|
|
|
if (parts[i] == "stream") {
|
|
|
|
|
|
// 找到 "stream" 后,停止添加后续部分
|
|
|
|
|
|
resultParts.append("stream");
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
resultParts.append(parts[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return resultParts.join('/');
|
2025-12-15 14:38:17 +08:00
|
|
|
|
}
|