#include "tchttpservice.h" QScopedPointer TCHttpService::m_instance; TCHttpService *TCHttpService::getInstance() { if (m_instance.isNull()) { m_instance.reset(new TCHttpService); } return m_instance.data(); } void TCHttpService::apiLogin() { QByteArray pwdMd5 = QCryptographicHash::hash(m_firstPwd.toUtf8(), QCryptographicHash::Md5); QString md5Hex = pwdMd5.toHex(); QString urlStr; if (m_enableSsl) urlStr = "https://" + m_domain + "/api/login"; else urlStr = "http://" + m_domain + "/api/login"; QUrl url(urlStr); QJsonObject jsonObj; jsonObj["user"]=m_userName; jsonObj["pwd"]=md5Hex; QJsonDocument jsonDoc(jsonObj); QByteArray jsonData = jsonDoc.toJson(); QMap headers; headers.insert("Content-Type", "application/json"); QNetworkReply* reply = nullptr; QNetworkRequest request(url); for (auto ite = headers.constBegin(); ite != headers.constEnd(); ite++){ request.setRawHeader(ite.key().toUtf8(), ite.value().toUtf8()); } reply = m_manager.post(request, jsonData); QObject::connect(reply, &QNetworkReply::finished, [this, reply]() { QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll()); if (jsonDoc.isEmpty()) return; QJsonObject jsonObj = jsonDoc.object(); int code = jsonObj["code"].toInt(); if (code == 0) { this->m_token = jsonObj["token"].toString(); qDebug() << this->m_token; m_isOnline = true; ImageManager::instance()->addDomainUser(m_domain, m_userName); emit signal_loginSuc(); } }); } #if 0 void TCHttpService::apiMyfileCount() { QString urlStr; if (m_enableSsl) urlStr = "https://" + m_domain + "/api/myfiles"; else urlStr = "http://" + m_domain + "/api/myfiles"; QMap headers; headers.insert("Content-Type", "application/json"); QMap params; params.insert("cmd", "count"); QUrl url = encodeUrl(urlStr, params); QJsonObject jsonObj; jsonObj["token"] = m_token; jsonObj["user"] = m_userName; QJsonDocument jsonDoc(jsonObj); QByteArray jsonData = jsonDoc.toJson(); QNetworkRequest request(url); for (auto ite = headers.constBegin(); ite != headers.constEnd(); ite++){ request.setRawHeader(ite.key().toUtf8(), ite.value().toUtf8()); } QNetworkReply* reply = nullptr; reply = m_manager.post(request, jsonData); QObject::connect(reply, &QNetworkReply::finished, [this, reply](){ emit requestFinished(reply, "myfilecount"); }); } void TCHttpService::apiMyfileNormal(int start, int count) { QString urlStr; if (m_enableSsl) urlStr = "https://" + m_domain + "/api/myfiles"; else urlStr = "http://" + m_domain + "/api/myfiles"; QMap headers; headers.insert("Content-Type", "application/json"); QMap params; params.insert("cmd", "normal"); QUrl url = encodeUrl(urlStr, params); QNetworkRequest request(url); for (auto ite = headers.constBegin(); ite != headers.constEnd(); ite++){ request.setRawHeader(ite.key().toUtf8(), ite.value().toUtf8()); } QJsonObject jsonObj; jsonObj["token"] = m_token; jsonObj["user"] = m_userName; jsonObj["count"] = count; jsonObj["start"] = start; QJsonDocument jsonDoc(jsonObj); QByteArray jsonData = jsonDoc.toJson(); QNetworkReply* reply = nullptr; reply = m_manager.post(request, jsonData); connect(reply, &QNetworkReply::finished, [this, reply](){ emit requestFinished(reply, "myfilenormal"); }); } void TCHttpService::apiMd5(const QString& filePath) { QFile file(filePath); if (!file.open(QIODevice::ReadOnly)) { return; } QByteArray fileMd5; QCryptographicHash hash(QCryptographicHash::Md5); if (hash.addData(&file)) { fileMd5 = hash.result().toHex(); } else return; QString urlStr; if (m_enableSsl) urlStr = "https://" + m_domain + "/api/md5"; else urlStr = "http://" + m_domain + "/api/md5"; QMap headers; headers.insert("Content-Type", "application/json"); QString md5Str = QString::fromUtf8(fileMd5); QJsonObject jsonObj; jsonObj["token"] = m_token; jsonObj["md5"] = md5Str; jsonObj["filename"] = QFileInfo(file).fileName(); jsonObj["user"] = m_userName; file.close(); QJsonDocument jsonDoc(jsonObj); QByteArray jsonData = jsonDoc.toJson(); QNetworkReply* reply = nullptr; QNetworkRequest request(urlStr); reply = m_manager.post(request, jsonData); QObject::connect(reply, &QNetworkReply::finished, [this, reply](){ emit requestFinished(reply, "md5"); }); } #endif void TCHttpService::apiUpload(const QString &filePath) { QString urlStr; if (m_enableSsl) urlStr = "https://" + m_domain + "/api/upload"; else urlStr = "http://" + m_domain + "/api/upload"; QFile *file = new QFile(filePath); if (!file->open(QIODevice::ReadOnly)) { qDebug() << "无法打开文件:" << filePath; delete file; return; } // 计算文件 MD5 QCryptographicHash hash(QCryptographicHash::Md5); hash.addData(file); QString md5 = hash.result().toHex(); // 重置文件指针 file->seek(0); // 获取文件大小 qint64 fileSize = file->size(); // 创建 multipart 请求 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); #else QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormData); #endif // 添加文件部分 QHttpPart filePart; filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream")); filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\"" + QFileInfo(filePath).fileName() + "\"")); filePart.setBodyDevice(file); multiPart->append(filePart); // 添加用户信息部分 QHttpPart userPart; userPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"user\"")); userPart.setBody(m_userName.toUtf8()); multiPart->append(userPart); // 添加 MD5 部分 QHttpPart md5Part; md5Part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"md5\"")); md5Part.setBody(md5.toUtf8()); multiPart->append(md5Part); // 添加文件大小部分 QHttpPart sizePart; sizePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"size\"")); sizePart.setBody(QString::number(fileSize).toUtf8()); multiPart->append(sizePart); // 创建网络请求 QNetworkRequest request(urlStr); // 替换为实际的服务器地址 request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary=" + multiPart->boundary()); // 发送请求 // QNetworkAccessManager *manager = new QNetworkAccessManager(this); QNetworkReply *reply = m_manager.post(request, multiPart); // 连接信号槽 connect(reply, &QNetworkReply::finished, this, [=]() { if (reply->error() == QNetworkReply::NoError) { qDebug() << "上传成功:"; QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll()); QJsonObject jsonObj = jsonDoc.object(); QString fileUrl = jsonObj["url"].toString(); emit signal_uploadFileSec(fileUrl); } else { qDebug() << "上传失败:" << reply->errorString(); } reply->deleteLater(); multiPart->deleteLater(); }); connect(reply, &QNetworkReply::uploadProgress, this, [](qint64 bytesSent, qint64 bytesTotal) { if (bytesTotal > 0) { int progress = (bytesSent * 100) / bytesTotal; qDebug() << "上传进度:" << progress << "%"; } }); } void TCHttpService::apiSharePicShare(const QString &fileName, const QString &md5) { QString urlStr; if (m_enableSsl) urlStr = "https://" + m_domain + "/api/sharepic"; else urlStr = "http://" + m_domain + "/api/sharepic"; QMap headers; QMap body; QMap params; headers.insert("Content-Type", "application/json"); QString bodyStr = QString("\"%1\":\"%2\",\"%3\":\"%4\",\"%5\":\"%6\",\"%7\":\"%8\"").arg("token").arg(m_token). arg("user").arg(m_userName).arg("md5").arg(md5).arg("filename").arg(fileName); params.insert("cmd", "share"); } void TCHttpService::setConfiguration(QString userName, QString firstPwd, QString domain) { this->m_domain = domain; this->m_userName = userName; this->m_firstPwd = firstPwd; #if 0 connect(this, &TCHttpService::requestFinished, [this](QNetworkReply* reply, QString api){ QByteArray rawData = reply->readAll(); if (api == "login") { QJsonDocument jsonDoc = QJsonDocument::fromJson(rawData); if (jsonDoc.isEmpty()) return; QJsonObject jsonObj = jsonDoc.object(); int code = jsonObj["code"].toInt(); if (code == 0) { this->m_token = jsonObj["token"].toString(); qDebug() << this->m_token; m_isOnline = true; emit signal_loginSuc(); // apiMyfileCount(); } } #if 0 if (api == "myfilecount") { QJsonDocument jsonDoc = QJsonDocument::fromJson(rawData); if (jsonDoc.isEmpty()) return; QJsonObject jsonObj = jsonDoc.object(); int code = jsonObj["code"].toInt(); if (code == 0) { int total = jsonObj["total"].toInt(); this->m_total = total; int n = total / 10 + 1; int pendingRequests = n; for (int i = 0; i < n; i++) { int count = (total - i * 10 >= 10) ? 10 : (total - i * 10); apiMyfileNormal(i*10, count); } } } if (api == "myfilenormal") { static int loginCnt = 0; QJsonDocument jsonDoc = QJsonDocument::fromJson(rawData); if (jsonDoc.isEmpty()) return; QJsonObject jsonObj = jsonDoc.object(); int code = jsonObj["code"].toInt(); if (code != 0) return; QJsonArray jsonArray = jsonObj["files"].toArray(); for (const QJsonValue& value : jsonArray) { QJsonObject jsonObj = value.toObject(); QString file_name = jsonObj["file_name"].toString(); int share_status = jsonObj["share_status"].toInt(); QString url = jsonObj["url"].toString(); qint64 size = jsonObj["size"].toInt(); QString md5 = jsonObj["md5"].toString(); QMap::iterator ite; ite = m_fileMap.find(md5); if (ite == m_fileMap.end()) { qDebug() << file_name; file_info_t info; info.share_status = share_status; info.size = size; info.url = url; info.file_name = file_name; if (m_isOnline) { qDebug() << "now upload"; emit signal_uploadFileSec(url); } m_fileMap.insert(md5, info); // if (m_fileMap.size() == m_total && m_isOnline == false) } #if !DEBUG // for(auto ite = m_fileMap.constBegin(); ite != m_fileMap.constEnd(); ite++) { // qDebug() << "fileMap debug:" << ite.value().file_name; // } qDebug() << "fileMap size:" << m_fileMap.size(); #endif } // if (!m_isOnline) { // loginCnt++; // qDebug() << "loginCnt:" << loginCnt; // if (loginCnt == m_total/10+1) { // m_isOnline = true; // qDebug() << "login success"; // } // } } // if (api == "upload") { // qDebug() <<"upload"; // QJsonDocument jsondoc = QJsonDocument::fromJson(rawData); // QJsonObject jsonObj = jsondoc.object(); // int code = jsonObj["code"].toInt(); // if (code == 0) // this->apiMyfileCount(); // } #endif reply->deleteLater(); }); #endif apiLogin(); } void TCHttpService::setSsl(bool enable) { this->m_enableSsl = enable; } bool TCHttpService::getOnlineState() { return m_isOnline; } void TCHttpService::setUploadNum(int nb) { this->m_uploadNum = nb; } void TCHttpService::downloadImage(const QString &requestId, const QUrl &imageUrl) { QNetworkRequest request(imageUrl); QNetworkReply* reply = m_manager.get(request); connect(reply, &QNetworkReply::finished, [this, reply](){ QString requestId = m_pendingRequests.take(reply); if (reply->error() != QNetworkReply::NoError) { emit signal_downloadFailed(requestId, reply->errorString()); } else { QPixmap pixmap; if (pixmap.loadFromData(reply->readAll())) { emit signal_imageDownloaded(requestId, pixmap); } else { emit signal_downloadFailed(requestId, "Failed to load image data"); } } reply->deleteLater(); }); m_pendingRequests[reply] = requestId; } QUrl TCHttpService::encodeUrl(QString urlStr, QMap params) { QUrlQuery query; for(auto ite = params.constBegin(); ite != params.constEnd(); ite++){ query.addQueryItem(ite.key(), ite.value()); } QUrl url(urlStr); url.setQuery(query); return url; } TCHttpService::TCHttpService(QObject *parent) : QObject(parent) { } void TCHttpService::slot_downloadFinished(QNetworkReply *reply) { QString requestId = m_pendingRequests.take(reply); if (reply->error() != QNetworkReply::NoError) { emit signal_downloadFailed(requestId, reply->errorString()); } else { QPixmap pixmap; if (pixmap.loadFromData(reply->readAll())) { emit signal_imageDownloaded(requestId, pixmap); } else { emit signal_downloadFailed(requestId, "Failed to load image data"); } } reply->deleteLater(); }