tchttpservice.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. #include "tchttpservice.h"
  2. QScopedPointer<TCHttpService> TCHttpService::m_instance;
  3. TCHttpService *TCHttpService::getInstance()
  4. {
  5. if (m_instance.isNull()) {
  6. m_instance.reset(new TCHttpService);
  7. }
  8. return m_instance.data();
  9. }
  10. void TCHttpService::apiLogin()
  11. {
  12. QByteArray pwdMd5 = QCryptographicHash::hash(m_firstPwd.toUtf8(), QCryptographicHash::Md5);
  13. QString md5Hex = pwdMd5.toHex();
  14. QString urlStr;
  15. if (m_enableSsl)
  16. urlStr = "https://" + m_domain + "/api/login";
  17. else
  18. urlStr = "http://" + m_domain + "/api/login";
  19. QUrl url(urlStr);
  20. QJsonObject jsonObj;
  21. jsonObj["user"]=m_userName;
  22. jsonObj["pwd"]=md5Hex;
  23. QJsonDocument jsonDoc(jsonObj);
  24. QByteArray jsonData = jsonDoc.toJson();
  25. QMap<QString, QString> headers;
  26. headers.insert("Content-Type", "application/json");
  27. QNetworkReply* reply = nullptr;
  28. QNetworkRequest request(url);
  29. for (auto ite = headers.constBegin(); ite != headers.constEnd(); ite++){
  30. request.setRawHeader(ite.key().toUtf8(), ite.value().toUtf8());
  31. }
  32. reply = m_manager.post(request, jsonData);
  33. QObject::connect(reply, &QNetworkReply::finished, [this, reply]() {
  34. QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
  35. if (jsonDoc.isEmpty())
  36. return;
  37. QJsonObject jsonObj = jsonDoc.object();
  38. int code = jsonObj["code"].toInt();
  39. if (code == 0) {
  40. this->m_token = jsonObj["token"].toString();
  41. qDebug() << this->m_token;
  42. m_isOnline = true;
  43. ImageManager::instance()->addDomainUser(m_domain, m_userName);
  44. emit signal_loginSuc();
  45. }
  46. });
  47. }
  48. #if 0
  49. void TCHttpService::apiMyfileCount()
  50. {
  51. QString urlStr;
  52. if (m_enableSsl)
  53. urlStr = "https://" + m_domain + "/api/myfiles";
  54. else
  55. urlStr = "http://" + m_domain + "/api/myfiles";
  56. QMap<QString, QString> headers;
  57. headers.insert("Content-Type", "application/json");
  58. QMap<QString, QString> params;
  59. params.insert("cmd", "count");
  60. QUrl url = encodeUrl(urlStr, params);
  61. QJsonObject jsonObj;
  62. jsonObj["token"] = m_token;
  63. jsonObj["user"] = m_userName;
  64. QJsonDocument jsonDoc(jsonObj);
  65. QByteArray jsonData = jsonDoc.toJson();
  66. QNetworkRequest request(url);
  67. for (auto ite = headers.constBegin(); ite != headers.constEnd(); ite++){
  68. request.setRawHeader(ite.key().toUtf8(), ite.value().toUtf8());
  69. }
  70. QNetworkReply* reply = nullptr;
  71. reply = m_manager.post(request, jsonData);
  72. QObject::connect(reply, &QNetworkReply::finished, [this, reply](){
  73. emit requestFinished(reply, "myfilecount");
  74. });
  75. }
  76. void TCHttpService::apiMyfileNormal(int start, int count)
  77. {
  78. QString urlStr;
  79. if (m_enableSsl)
  80. urlStr = "https://" + m_domain + "/api/myfiles";
  81. else
  82. urlStr = "http://" + m_domain + "/api/myfiles";
  83. QMap<QString, QString> headers;
  84. headers.insert("Content-Type", "application/json");
  85. QMap<QString, QString> params;
  86. params.insert("cmd", "normal");
  87. QUrl url = encodeUrl(urlStr, params);
  88. QNetworkRequest request(url);
  89. for (auto ite = headers.constBegin(); ite != headers.constEnd(); ite++){
  90. request.setRawHeader(ite.key().toUtf8(), ite.value().toUtf8());
  91. }
  92. QJsonObject jsonObj;
  93. jsonObj["token"] = m_token;
  94. jsonObj["user"] = m_userName;
  95. jsonObj["count"] = count;
  96. jsonObj["start"] = start;
  97. QJsonDocument jsonDoc(jsonObj);
  98. QByteArray jsonData = jsonDoc.toJson();
  99. QNetworkReply* reply = nullptr;
  100. reply = m_manager.post(request, jsonData);
  101. connect(reply, &QNetworkReply::finished, [this, reply](){
  102. emit requestFinished(reply, "myfilenormal");
  103. });
  104. }
  105. void TCHttpService::apiMd5(const QString& filePath)
  106. {
  107. QFile file(filePath);
  108. if (!file.open(QIODevice::ReadOnly)) {
  109. return;
  110. }
  111. QByteArray fileMd5;
  112. QCryptographicHash hash(QCryptographicHash::Md5);
  113. if (hash.addData(&file)) {
  114. fileMd5 = hash.result().toHex();
  115. }
  116. else
  117. return;
  118. QString urlStr;
  119. if (m_enableSsl)
  120. urlStr = "https://" + m_domain + "/api/md5";
  121. else
  122. urlStr = "http://" + m_domain + "/api/md5";
  123. QMap<QString, QString> headers;
  124. headers.insert("Content-Type", "application/json");
  125. QString md5Str = QString::fromUtf8(fileMd5);
  126. QJsonObject jsonObj;
  127. jsonObj["token"] = m_token;
  128. jsonObj["md5"] = md5Str;
  129. jsonObj["filename"] = QFileInfo(file).fileName();
  130. jsonObj["user"] = m_userName;
  131. file.close();
  132. QJsonDocument jsonDoc(jsonObj);
  133. QByteArray jsonData = jsonDoc.toJson();
  134. QNetworkReply* reply = nullptr;
  135. QNetworkRequest request(urlStr);
  136. reply = m_manager.post(request, jsonData);
  137. QObject::connect(reply, &QNetworkReply::finished, [this, reply](){
  138. emit requestFinished(reply, "md5");
  139. });
  140. }
  141. #endif
  142. void TCHttpService::apiUpload(const QString &filePath)
  143. {
  144. QString urlStr;
  145. if (m_enableSsl)
  146. urlStr = "https://" + m_domain + "/api/upload";
  147. else
  148. urlStr = "http://" + m_domain + "/api/upload";
  149. QFile *file = new QFile(filePath);
  150. if (!file->open(QIODevice::ReadOnly)) {
  151. qDebug() << "无法打开文件:" << filePath;
  152. delete file;
  153. return;
  154. }
  155. // 计算文件 MD5
  156. QCryptographicHash hash(QCryptographicHash::Md5);
  157. hash.addData(file);
  158. QString md5 = hash.result().toHex();
  159. // 重置文件指针
  160. file->seek(0);
  161. // 获取文件大小
  162. qint64 fileSize = file->size();
  163. // 创建 multipart 请求
  164. #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
  165. QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
  166. #else
  167. QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormData);
  168. #endif
  169. // 添加文件部分
  170. QHttpPart filePart;
  171. filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
  172. filePart.setHeader(QNetworkRequest::ContentDispositionHeader,
  173. QVariant("form-data; name=\"file\"; filename=\"" + QFileInfo(filePath).fileName() + "\""));
  174. filePart.setBodyDevice(file);
  175. multiPart->append(filePart);
  176. // 添加用户信息部分
  177. QHttpPart userPart;
  178. userPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"user\""));
  179. userPart.setBody(m_userName.toUtf8());
  180. multiPart->append(userPart);
  181. // 添加 MD5 部分
  182. QHttpPart md5Part;
  183. md5Part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"md5\""));
  184. md5Part.setBody(md5.toUtf8());
  185. multiPart->append(md5Part);
  186. // 添加文件大小部分
  187. QHttpPart sizePart;
  188. sizePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"size\""));
  189. sizePart.setBody(QString::number(fileSize).toUtf8());
  190. multiPart->append(sizePart);
  191. // 创建网络请求
  192. QNetworkRequest request(urlStr); // 替换为实际的服务器地址
  193. request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary=" + multiPart->boundary());
  194. // 发送请求
  195. // QNetworkAccessManager *manager = new QNetworkAccessManager(this);
  196. QNetworkReply *reply = m_manager.post(request, multiPart);
  197. // 连接信号槽
  198. connect(reply, &QNetworkReply::finished, this, [=]() {
  199. if (reply->error() == QNetworkReply::NoError) {
  200. qDebug() << "上传成功:";
  201. QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
  202. QJsonObject jsonObj = jsonDoc.object();
  203. QString fileUrl = jsonObj["url"].toString();
  204. emit signal_uploadFileSec(fileUrl);
  205. } else {
  206. qDebug() << "上传失败:" << reply->errorString();
  207. }
  208. reply->deleteLater();
  209. multiPart->deleteLater();
  210. });
  211. connect(reply, &QNetworkReply::uploadProgress, this, [](qint64 bytesSent, qint64 bytesTotal) {
  212. if (bytesTotal > 0) {
  213. int progress = (bytesSent * 100) / bytesTotal;
  214. qDebug() << "上传进度:" << progress << "%";
  215. }
  216. });
  217. }
  218. void TCHttpService::apiSharePicShare(const QString &fileName, const QString &md5)
  219. {
  220. QString urlStr;
  221. if (m_enableSsl)
  222. urlStr = "https://" + m_domain + "/api/sharepic";
  223. else
  224. urlStr = "http://" + m_domain + "/api/sharepic";
  225. QMap<QString, QString> headers;
  226. QMap<QString, QString> body;
  227. QMap<QString, QString> params;
  228. headers.insert("Content-Type", "application/json");
  229. QString bodyStr = QString("\"%1\":\"%2\",\"%3\":\"%4\",\"%5\":\"%6\",\"%7\":\"%8\"").arg("token").arg(m_token).
  230. arg("user").arg(m_userName).arg("md5").arg(md5).arg("filename").arg(fileName);
  231. params.insert("cmd", "share");
  232. }
  233. void TCHttpService::setConfiguration(QString userName, QString firstPwd, QString domain)
  234. {
  235. this->m_domain = domain;
  236. this->m_userName = userName;
  237. this->m_firstPwd = firstPwd;
  238. #if 0
  239. connect(this, &TCHttpService::requestFinished, [this](QNetworkReply* reply, QString api){
  240. QByteArray rawData = reply->readAll();
  241. if (api == "login") {
  242. QJsonDocument jsonDoc = QJsonDocument::fromJson(rawData);
  243. if (jsonDoc.isEmpty())
  244. return;
  245. QJsonObject jsonObj = jsonDoc.object();
  246. int code = jsonObj["code"].toInt();
  247. if (code == 0) {
  248. this->m_token = jsonObj["token"].toString();
  249. qDebug() << this->m_token;
  250. m_isOnline = true;
  251. emit signal_loginSuc();
  252. // apiMyfileCount();
  253. }
  254. }
  255. #if 0
  256. if (api == "myfilecount") {
  257. QJsonDocument jsonDoc = QJsonDocument::fromJson(rawData);
  258. if (jsonDoc.isEmpty())
  259. return;
  260. QJsonObject jsonObj = jsonDoc.object();
  261. int code = jsonObj["code"].toInt();
  262. if (code == 0) {
  263. int total = jsonObj["total"].toInt();
  264. this->m_total = total;
  265. int n = total / 10 + 1;
  266. int pendingRequests = n;
  267. for (int i = 0; i < n; i++) {
  268. int count = (total - i * 10 >= 10) ? 10 : (total - i * 10);
  269. apiMyfileNormal(i*10, count);
  270. }
  271. }
  272. }
  273. if (api == "myfilenormal") {
  274. static int loginCnt = 0;
  275. QJsonDocument jsonDoc = QJsonDocument::fromJson(rawData);
  276. if (jsonDoc.isEmpty())
  277. return;
  278. QJsonObject jsonObj = jsonDoc.object();
  279. int code = jsonObj["code"].toInt();
  280. if (code != 0)
  281. return;
  282. QJsonArray jsonArray = jsonObj["files"].toArray();
  283. for (const QJsonValue& value : jsonArray) {
  284. QJsonObject jsonObj = value.toObject();
  285. QString file_name = jsonObj["file_name"].toString();
  286. int share_status = jsonObj["share_status"].toInt();
  287. QString url = jsonObj["url"].toString();
  288. qint64 size = jsonObj["size"].toInt();
  289. QString md5 = jsonObj["md5"].toString();
  290. QMap<QString, file_info_t>::iterator ite;
  291. ite = m_fileMap.find(md5);
  292. if (ite == m_fileMap.end()) {
  293. qDebug() << file_name;
  294. file_info_t info;
  295. info.share_status = share_status;
  296. info.size = size;
  297. info.url = url;
  298. info.file_name = file_name;
  299. if (m_isOnline) {
  300. qDebug() << "now upload";
  301. emit signal_uploadFileSec(url);
  302. }
  303. m_fileMap.insert(md5, info);
  304. // if (m_fileMap.size() == m_total && m_isOnline == false)
  305. }
  306. #if !DEBUG
  307. // for(auto ite = m_fileMap.constBegin(); ite != m_fileMap.constEnd(); ite++) {
  308. // qDebug() << "fileMap debug:" << ite.value().file_name;
  309. // }
  310. qDebug() << "fileMap size:" << m_fileMap.size();
  311. #endif
  312. }
  313. // if (!m_isOnline) {
  314. // loginCnt++;
  315. // qDebug() << "loginCnt:" << loginCnt;
  316. // if (loginCnt == m_total/10+1) {
  317. // m_isOnline = true;
  318. // qDebug() << "login success";
  319. // }
  320. // }
  321. }
  322. // if (api == "upload") {
  323. // qDebug() <<"upload";
  324. // QJsonDocument jsondoc = QJsonDocument::fromJson(rawData);
  325. // QJsonObject jsonObj = jsondoc.object();
  326. // int code = jsonObj["code"].toInt();
  327. // if (code == 0)
  328. // this->apiMyfileCount();
  329. // }
  330. #endif
  331. reply->deleteLater();
  332. });
  333. #endif
  334. apiLogin();
  335. }
  336. void TCHttpService::setSsl(bool enable)
  337. {
  338. this->m_enableSsl = enable;
  339. }
  340. bool TCHttpService::getOnlineState()
  341. {
  342. return m_isOnline;
  343. }
  344. void TCHttpService::setUploadNum(int nb)
  345. {
  346. this->m_uploadNum = nb;
  347. }
  348. void TCHttpService::downloadImage(const QString &requestId, const QUrl &imageUrl)
  349. {
  350. QNetworkRequest request(imageUrl);
  351. QNetworkReply* reply = m_manager.get(request);
  352. connect(reply, &QNetworkReply::finished, [this, reply](){
  353. QString requestId = m_pendingRequests.take(reply);
  354. if (reply->error() != QNetworkReply::NoError) {
  355. emit signal_downloadFailed(requestId, reply->errorString());
  356. }
  357. else {
  358. QPixmap pixmap;
  359. if (pixmap.loadFromData(reply->readAll())) {
  360. emit signal_imageDownloaded(requestId, pixmap);
  361. }
  362. else {
  363. emit signal_downloadFailed(requestId, "Failed to load image data");
  364. }
  365. }
  366. reply->deleteLater();
  367. });
  368. m_pendingRequests[reply] = requestId;
  369. }
  370. QUrl TCHttpService::encodeUrl(QString urlStr, QMap<QString, QString> params)
  371. {
  372. QUrlQuery query;
  373. for(auto ite = params.constBegin(); ite != params.constEnd(); ite++){
  374. query.addQueryItem(ite.key(), ite.value());
  375. }
  376. QUrl url(urlStr);
  377. url.setQuery(query);
  378. return url;
  379. }
  380. TCHttpService::TCHttpService(QObject *parent) : QObject(parent)
  381. {
  382. }
  383. void TCHttpService::slot_downloadFinished(QNetworkReply *reply)
  384. {
  385. QString requestId = m_pendingRequests.take(reply);
  386. if (reply->error() != QNetworkReply::NoError) {
  387. emit signal_downloadFailed(requestId, reply->errorString());
  388. }
  389. else {
  390. QPixmap pixmap;
  391. if (pixmap.loadFromData(reply->readAll())) {
  392. emit signal_imageDownloaded(requestId, pixmap);
  393. }
  394. else {
  395. emit signal_downloadFailed(requestId, "Failed to load image data");
  396. }
  397. }
  398. reply->deleteLater();
  399. }