tchttpservice.cpp 13 KB

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