Files
picpanel/core_support/tchttpservice/tchttpservice.cpp
2025-03-27 00:56:01 +08:00

358 lines
11 KiB
C++

#include "tchttpservice.h"
QScopedPointer<TCHttpService> 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<QString, QString> 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);
QString stdPath = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
ImageManager::instance()->initialize(stdPath + "/picpanel.db");
emit signal_loginSuc();
}
});
}
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();
ImageManager::instance()->addImageUrl(m_domain, m_userName, fileUrl);
emit signal_uploadFileSec(fileUrl);
} else {
qDebug() << "上传失败:" << reply->errorString();
}
reply->deleteLater();
multiPart->deleteLater();
});
connect(reply, &QNetworkReply::uploadProgress, this, [this](qint64 bytesSent, qint64 bytesTotal) {
if (bytesTotal > 0) {
int progress = (bytesSent * 100) / bytesTotal;
emit signal_progressUpdate(progress);
qDebug() << "上传进度:" << progress << "%";
}
});
}
void TCHttpService::setConfiguration(QString userName, QString firstPwd, QString domain)
{
this->m_domain = domain;
this->m_userName = userName;
this->m_firstPwd = firstPwd;
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)
{
#if 1
QPixmap cachedPixmap;
if (QPixmapCache::find(imageUrl.toString(), &cachedPixmap)) {
emit signal_imageDownloaded(requestId, cachedPixmap);
return;
}
if (getCachedImage(imageUrl, cachedPixmap)) {
QPixmapCache::insert(imageUrl.toString(), cachedPixmap);
emit signal_imageDownloaded(requestId, cachedPixmap);
return;
}
#endif
QNetworkRequest request(imageUrl);
request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork);
QNetworkReply* reply = m_manager.get(request);
m_pendingRequests[reply] = requestId;
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())) {
cacheImage(reply->url(), pixmap);
emit signal_imageDownloaded(requestId, pixmap);
}
else {
emit signal_downloadFailed(requestId, "Failed to load image data");
}
}
reply->deleteLater();
});
// connect(reply, &QNetworkReply::finished, [this, reply, imageUrl](){
// 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())) {
// QPixmapCache::insert(imageUrl.toString(), pixmap);
// emit signal_imageDownloaded(requestId, pixmap);
// }
// else {
// emit signal_downloadFailed(requestId, "Failed to load image data");
// }
// }
// reply->deleteLater();
// });
// connect(reply, &QNetworkReply::finished, this, &TCHttpService::slot_downloadFinished);
}
QUrl TCHttpService::encodeUrl(QString urlStr, QMap<QString, QString> 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;
}
void TCHttpService::cleanOldCacheFiles()
{
QDir cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
cacheDir.setNameFilters(QStringList() << "*.png" << "*.jpg" << "*.jpeg" << "*.svg");
cacheDir.setFilter(QDir::Files);
foreach (QString dirFile, cacheDir.entryList()) {
QFileInfo fileInfo(cacheDir.absoluteFilePath(dirFile));
if (fileInfo.lastModified().daysTo(QDateTime::currentDateTime()) > m_max_cache_days) {
cacheDir.remove(dirFile);
}
}
qint64 totalSize = 0;
QFileInfoList files = cacheDir.entryInfoList(QDir::Files, QDir::Time | QDir::Reversed);
foreach(QFileInfo file, files) {
totalSize += file.size();
}
if (totalSize > m_disk_cache_size_mb * 1024 * 1024) {
foreach (QFileInfo file, files) {
if (totalSize <= m_disk_cache_size_mb * 1024 * 1024 * 0.9)
break;
totalSize -= file.size();
QFile::remove(file.absoluteFilePath());
}
}
}
bool TCHttpService::getCachedImage(const QUrl &imageUrl, QPixmap &pixmap)
{
QString filePath = getCacheFilePath(imageUrl);
if (QFile::exists(filePath)) {
QFileInfo info(filePath);
if (info.lastModified().daysTo(QDateTime::currentDateTime()) > m_max_cache_days) {
QFile::remove(filePath);
return false;
}
if (pixmap.load(filePath)) {
return true;
}
}
return false;
}
QString TCHttpService::getCacheFilePath(const QUrl &imageUrl)
{
QCryptographicHash hash(QCryptographicHash::Md5);
hash.addData(imageUrl.toString().toUtf8());
QString fileName = hash.result().toHex() + ".png";
return QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/" + fileName;
}
void TCHttpService::cacheImage(const QUrl &imageUrl, const QPixmap &pixmap)
{
QPixmapCache::insert(imageUrl.toString(), pixmap);
QString filePath = getCacheFilePath(imageUrl);
pixmap.save(filePath, "PNG");
cleanOldCacheFiles();
}
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())) {
cacheImage(reply->url(), pixmap);
emit signal_imageDownloaded(requestId, pixmap);
}
else {
emit signal_downloadFailed(requestId, "Failed to load image data");
}
}
reply->deleteLater();
}