//
// Created by HW on 2023/07/27.
//

#include <QProcess>
#include <QScreen>
#include <QCryptographicHash>
#include <wbemidl.h>
#include "netio.h"
#include "config.h"
#include <cstdlib>
#include <ctime>
#include <QEventLoop>
#include <QTimer>
#include <cstring>
#include <QJsonArray>
#include <QSysInfo>
#include <QStorageInfo>
#include <comutil.h>
#include <iostream>
#include <QGuiApplication>
#include <QApplication>
#include <ctime>
#include <qDebug>
#include "globalvariables.h"
#include "buttonstruct.h"
#pragma comment(lib, "wbemuuid.lib")
#ifdef _DEBUG
#pragma comment(lib, "Qt5Networkd.lib")
#else
#pragma comment(lib, "Qt5Network.lib")
#endif
#pragma comment(lib,"comsuppw.lib")
//读取注册表获取MachineUUID
bool IsWin11AndLater()
{

	//Windows 10 从内部版本 10240 开始，以内部版本 19044 结束。Windows 11 从内部版本 22000 开始，那么：
	//Environment.OSVersion.Version.Build >= 22000;
	NTSTATUS(WINAPI * RtlGetVersion)(LPOSVERSIONINFOEXW);
	OSVERSIONINFOEXW osInfo;
	*(FARPROC*)&RtlGetVersion = GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion");
	if (NULL != RtlGetVersion)
	{
		osInfo.dwOSVersionInfoSize = sizeof(osInfo);
		RtlGetVersion(&osInfo);

		return (osInfo.dwMajorVersion >= 10 && osInfo.dwBuildNumber >= 22000);
	}

	return false;
}
RequestBodyBase::RequestBodyBase(){
    wchar_t unix_time[65]={0};
    wsprintf(unix_time,L"%ld",std::time(0));
    QString request_id=QString::fromWCharArray(unix_time);
    //打开配置文件
	QString dir=QApplication::applicationDirPath();
    QFile *infFile=new QFile(dir+"/config/information.kmd");
    if(!infFile->open(QIODevice::ReadOnly|QIODevice::Text)){
        QMessageBox::critical(nullptr,QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("无法打开配置文件"));
        delete infFile;
        exit_manager.exit(1);
    }
    //读取配置文件
    QByteArray bytes;
    bytes=infFile->readAll();
    infFile->close();
    delete infFile;
    //转化为json
    qJsonDocument=QJsonDocument::fromJson(bytes);
    if(qJsonDocument.isObject()){
        //读取数据，写入对应字段
        QJsonObject obj_root=qJsonDocument.object();
        if(obj_root.value("product")==QJsonValue::Undefined){
            QMessageBox::critical(nullptr, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("配置文件损坏"));
            exit_manager.exit(1);
        }
        product=obj_root.value("product").toString();
        if(obj_root.value("partner_id")==QJsonValue::Undefined){
            QMessageBox::critical(nullptr , QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("配置文件损坏"));
            exit_manager.exit(1);
        }
        parter_id=obj_root.value("partner_id").toString();
    }else{
        //处理错误
        QMessageBox::critical(nullptr, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("配置文件损坏"));
        exit_manager.exit(1);
    }
    //获取操作系统版本
    this->os="Windows";
    OSVERSIONINFOEXW os;
    os.dwOSVersionInfoSize=sizeof(os);
    GetVersionEx((OSVERSIONINFO *)&os);
	NTSTATUS(WINAPI * RtlGetVersion)(LPOSVERSIONINFOEXW);
	*(FARPROC*)&RtlGetVersion = GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion");
	if (RtlGetVersion != nullptr) {
		RtlGetVersion(&os);
		switch (os.dwMajorVersion) {//主版本号
		case 5: //不兼容Windows 2000，因此5.x一定是Windows XP
			os_version = "Windows XP";
			break;
		case 6:
			switch (os.dwMinorVersion) { //次版本号
			case 0:
				os_version = "Windows Vista or Windows Server 2008";
				break;
			case 1:
				os_version = "Windows 7 or Windows Server 2008 R2";
				break;
			case 2:
				os_version = "Windows 8 or Windows Server 2012";
				break;
			case 3:
				os_version = "Windows 8.1 or Windows Server 2012 R2";
				break;
			default:
				os_version = "Unknown";
			}
		 case 10: //这几个系统都是10.0
			if (IsWin11AndLater()) {
				os_version = "Windows 11 or Windows Server 2022";
			}
			else {
				os_version = "Windows 10, Windows Server 2016 or Windows Server 2019";
			}
			break;
		default:
			os_version = "Unknown";
		}
	}
	else {
		os_version = "Unknown";
	}
    
	this->release = RELEASE;
	this->version = VERSION;
	//读取MachineGUID并取MD5作为device_id
	QByteArray hash = QCryptographicHash::hash(getMachineGUID().toUtf8(), QCryptographicHash::Md5);
	device_id = hash.toHex();
	//加入json序列
	QJsonValue value = device_id;
	QJsonObject obj_root = qJsonDocument.object();
	obj_root.insert("device_id", value);
	QJsonValue version_json = this->version;
	obj_root.insert("version", version_json);
	QJsonValue release_json = this->release;
	obj_root.insert("release", release_json);
	qJsonDocument.setObject(obj_root);
	QJsonValue os_json(this->os);
	QJsonValue os_version_json(this->os_version);
	QString key_hash = QCryptographicHash::hash(QString(KEY).toUtf8(), QCryptographicHash::Md5).toHex();
	QByteArray request_id_byte = request_id.toUtf8();
	QByteArray sign_byte= QCryptographicHash::hash(key_hash.toUtf8()+request_id_byte, QCryptographicHash::Md5);
	sign = sign_byte.toHex();
	QJsonValue sign_json(sign);
    QJsonValue requestId_json=QJsonValue(request_id);
    obj_root=qJsonDocument.object();
    //插入request_id
    obj_root.insert(QString::fromLocal8Bit("request_id"),requestId_json);
	obj_root.insert(QString::fromLocal8Bit("os"), os_json);
	obj_root.insert(QString::fromLocal8Bit("os_version"), os_version_json);
	obj_root.insert(QString::fromLocal8Bit("sign"), sign_json);
    qJsonDocument.setObject(obj_root);
	url_param = "?";
	url_param += "product=";
	url_param += product;
	url_param += "&parter_id=";
	url_param += parter_id;
	url_param += "&os=";
	url_param += this->os;
	url_param += "&os_version=";
	url_param += os_version;
	url_param += "&device_id=";
	url_param += device_id;
	url_param += "&request_id=";
	url_param += request_id;
	url_param += "&version=";
	url_param += version;
	url_param += "&release=";
	url_param += release;
	url_param += "&sign=";
	url_param += sign;
	qDebug() << url_param;
}



void ConfigRequest::sendRequest(ConfigResponse *configResponse) {
	timer = new QTimer(this);
    if(agree)
    {
        QJsonObject obj_root = qJsonDocument.object();
        obj_root.insert("autostart", autostart);
        qJsonDocument.setObject(obj_root);
    }
   
    QNetworkAccessManager *httpMgr = new QNetworkAccessManager();
    QNetworkRequest requestInfo;
    //HTTP请求
    //请求头
	QString url = CONFIG_URL;
    requestInfo.setUrl(QUrl(CONFIG_URL));
    requestInfo.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json"));
    //保存响应的变量
    reply =  httpMgr->post(requestInfo,qJsonDocument.toJson());
	qDebug() << qJsonDocument.toJson();
    //开启一个循环，直到超时或者获取到数据为止
    connect(reply,&QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
    //设置定时器防止超时
    connect(timer,&QTimer::timeout,this,&ConfigRequest::cancelDownload);
    timer->start(5000);
    //启动循环
	eventLoop.exec();
	timer->stop();
    //delete httpMgr;
    QJsonDocument result;
    QByteArray buffer;
	configResponse->succeed = false;
    //memset(configResponse,0,sizeof(*configResponse));
	auto error = reply->error();
    //如果没有错误
    if(reply->error() == QNetworkReply::NoError) {
        buffer = reply->readAll();
    }else{
        //如果有错误
        configResponse->succeed=false;
        //delete reply;
        delete timer;
		delete httpMgr;
        return;
    }
	//qDebug() << result.toJson();
    result = QJsonDocument::fromJson(buffer);
    //如果数据完整
    if(result.isObject()){
        QJsonObject obj_root=result.object();
        QJsonArray array;

        array = obj_root.value("data").toObject().value("menu").toArray();
		QJsonObject obj_basic = obj_root.value("data").toObject().value("basic").toObject();
		configResponse->basic.logo_url = obj_basic.value("logo").toString();
		configResponse->basic.device_id = obj_basic.value("device_id").toString();
		configResponse->basic.dev_id = obj_basic.value("dev_id").toString();
		configResponse->basic.token = obj_basic.value("token").toString();
		configResponse->basic.backgroud_color = obj_basic.value("backgroud_color").toString();
		configResponse->basic.title_color = obj_basic.value("title_color").toString();
		configResponse->basic.title_cover_color = obj_basic.value("title_cover_color").toString();
        auto i=0;
        for(auto value:array){
            QJsonObject object=value.toObject();
			Button button;
            button.img=object.value("img").toString();
           // button.img_cover=object.value("img_cover").toString();
			button.title=object.value("title").toString();
            button.categroy_id = object.value("category_id").toString();
            button.op = object.value("op").toString();
            button.func=object.value("func").toString();
        	button.url=object.value("url").toString();
			configResponse->buttons << button;
            i++;
        }
		configResponse->succeed = true;
    }else{
        //数据不完整
        configResponse->succeed=false;
        //delete reply;
        delete timer;
		delete httpMgr;
        return;
    }
	delete httpMgr;
}
void RequestBodyBase::cancelDownload() {
    downloadSuccess = false;
	disconnect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
	eventLoop.quit();
	reply->abort();
}
void RequestBodyBase::sendRequest() {
    timer = new QTimer(this);
    QNetworkAccessManager *httpMgr = new QNetworkAccessManager();
    QNetworkRequest requestInfo;
    //HTTP请求
    //请求头
    requestInfo.setUrl(QUrl(OP_URL));
    requestInfo.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json"));
    //保存响应的变量
    reply =  httpMgr->post(requestInfo,qJsonDocument.toJson());
    //开启一个循环，直到超时或者获取到数据为止
    connect(reply,&QNetworkReply::finished, this, &RequestBodyBase::cancelDownload);
    //设置定时器防止超时
    connect(timer,&QTimer::timeout,&eventLoop,&QEventLoop::quit);
    timer->start(5000);
    //启动循环
    eventLoop.exec();
    delete timer;
    delete httpMgr;
    delete reply;
}


DeviceRequest::DeviceRequest() : RequestBodyBase() {
    //CPU
    QString cpu = QSysInfo::currentCpuArchitecture();
    //内存大小
    MEMORYSTATUSEX status;
    status.dwLength = sizeof(status);
    GlobalMemoryStatusEx(&status);
    int ram = status.ullTotalPhys / 1024 / 1024;
    //硬盘大小
    QStorageInfo storage = QStorageInfo::root();
    int disk = storage.bytesTotal() / static_cast<qulonglong>(1024 * 1024 * 1024);
    //显卡型号
    QStringList gpus;
    BOOL success;
    DWORD deviceIndex = 0;
    DISPLAY_DEVICE displayDevice;
    displayDevice.cb = sizeof(displayDevice);
    while (EnumDisplayDevices(NULL, deviceIndex, &displayDevice, 0)) {
        WCHAR valueName[128];
        DWORD valueSize;
        DWORD valueType;
        BYTE valueData[MAX_PATH];
        HKEY hKey;
        WCHAR keyName[128];
        wsprintf(keyName, L"SYSTEM\\CurrentControlSet\\Control\\Video\\%s\\HardwareInformation",
                 displayDevice.DeviceID);
        if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
            valueSize = sizeof(valueData);
            wsprintf(valueName, L"HardwareInformation.AdapterString");
            if (RegQueryValueEx(hKey, valueName, NULL, &valueType, valueData, &valueSize) == ERROR_SUCCESS) {
                Q_ASSERT(valueType == REG_SZ);
                QString adapterString = QString::fromWCharArray((wchar_t *) valueData, valueSize / sizeof(wchar_t) - 1);
                gpus.append(adapterString);
            }
            RegCloseKey(hKey);
        }
        deviceIndex++;
        displayDevice.cb = sizeof(displayDevice);
    }
    //主板型号
    QString motherboard = QSysInfo::prettyProductName();
    //WMI获取网卡型号
    HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hr)) {
        std::cerr << "Failed to initialize COM library." << std::endl;
        return;
    }
    QStringList netCards;
    hr = CoInitializeSecurity(
            NULL,
            -1,
            NULL,
            NULL,
            RPC_C_AUTHN_LEVEL_DEFAULT,
            RPC_C_IMP_LEVEL_IMPERSONATE,
            NULL,
            EOAC_NONE,
            NULL
    );
    if (FAILED(hr)) {
        std::cerr << "Failed to initialize security." << std::endl;
        CoUninitialize();
        return;
    }

    IWbemLocator* pLoc = NULL;
    hr = CoCreateInstance(
            CLSID_WbemLocator,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_IWbemLocator,
            (LPVOID*)&pLoc
    );
    if (FAILED(hr)) {
        std::cerr << "Failed to create IWbemLocator object." << std::endl;
        CoUninitialize();
        return;
    }

    IWbemServices* pSvc = NULL;
    hr = pLoc->ConnectServer(
            _bstr_t(L"ROOT\\CIMV2"),
            NULL,
            NULL,
            0,
            NULL,
            0,
            0,
            &pSvc
    );
    if (FAILED(hr)) {
        std::cerr << "Failed to connect to WMI service." << std::endl;
        pLoc->Release();
        CoUninitialize();
        return;
    }

    hr = CoSetProxyBlanket(
            pSvc,
            RPC_C_AUTHN_WINNT,
            RPC_C_AUTHZ_NONE,
            NULL,
            RPC_C_AUTHN_LEVEL_CALL,
            RPC_C_IMP_LEVEL_IMPERSONATE,
            NULL,
            EOAC_NONE
    );
    if (FAILED(hr)) {
        std::cerr << "Failed to set security blanket." << std::endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return;
    }

    IEnumWbemClassObject* pEnumerator = NULL;
    hr = pSvc->ExecQuery(
            _bstr_t("WQL"),
            _bstr_t("SELECT * FROM Win32_NetworkAdapter WHERE PhysicalAdapter = TRUE AND NetConnectionStatus = 3"),
            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
            NULL,
            &pEnumerator
    );
    if (FAILED(hr)) {
        std::cerr << "Failed to execute WQL query for Win32_NetworkAdapter." << std::endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return;
    }
    IWbemClassObject* pClassObj = NULL;
    ULONG uReturn = 0;
    while (pEnumerator) {
        hr = pEnumerator->Next(WBEM_INFINITE, 1, &pClassObj, &uReturn);
        if (uReturn == 0) {
            break;
        }

        VARIANT vtProp;
        hr = pClassObj->Get(L"Caption", 0, &vtProp, 0, 0);
        if (SUCCEEDED(hr)) {
            QString str=QString::fromWCharArray(vtProp.bstrVal);
            VariantClear(&vtProp);
            netCards.append(str);
        }

        pClassObj->Release();
    }
    //WMI获取声卡型号
    hr = pSvc->ExecQuery(
            _bstr_t("WQL"),
            _bstr_t("SELECT * FROM Win32_SoundDevice"),
            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
            NULL,
            &pEnumerator
    );
    if (FAILED(hr)) {
        std::cerr << "Failed to execute WQL query for Win32_SoundDevice." << std::endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return;
    }
    QStringList audioCards;
    while (pEnumerator) {
        hr = pEnumerator->Next(WBEM_INFINITE, 1, &pClassObj, &uReturn);
        if (uReturn == 0) {
            break;
        }

        VARIANT vtProp;
        hr = pClassObj->Get(L"Name", 0, &vtProp, 0, 0);
        if (SUCCEEDED(hr)) {
            QString str=QString::fromWCharArray(vtProp.bstrVal);
            VariantClear(&vtProp);
            audioCards.append(str);
        }

        pClassObj->Release();
    }
    hr = pSvc->ExecQuery(
            bstr_t("WQL"),
            bstr_t("SELECT * FROM Win32_PhysicalMemory"),
            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
            NULL,
            &pEnumerator
    );
    if (FAILED(hr))
    {
        std::cout << "Query failed. Error code: " << hr << std::endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return;
    }
    QStringList RAMModel;
    while (pEnumerator)
    {
        hr = pEnumerator->Next(WBEM_INFINITE, 1, &pClassObj, &uReturn);
        if (uReturn == 0)
        {
            break;
        }

        VARIANT vtProp;
        hr = pClassObj->Get(L"Manufacturer", 0, &vtProp, 0, 0);
        if (SUCCEEDED(hr))
        {
            std::wcout << "Manufacturer: " << vtProp.bstrVal << std::endl;
            VariantClear(&vtProp);
        }

        hr = pClassObj->Get(L"PartNumber", 0, &vtProp, 0, 0);
        if (SUCCEEDED(hr))
        {
            RAMModel.append(QString::fromWCharArray(vtProp.bstrVal));
            VariantClear(&vtProp);
        }

        pClassObj->Release();
    }
    pSvc->Release();
    pLoc->Release();
    CoUninitialize();
    DISPLAY_DEVICE d = { sizeof(DISPLAY_DEVICE) };
    ::EnumDisplayDevices(NULL, 0, &d, 0);
    QString monitor=QString::fromWCharArray(d.DeviceString, wcslen(d.DeviceString));
    //发送
    //构造JSON
    QJsonDocument *device=new QJsonDocument;
    QJsonObject *object=new QJsonObject;
    object->insert("CPU",QJsonValue(cpu));
    object->insert("RAM",QJsonValue(ram));
    object->insert("Hard_Disk",QJsonValue(disk));
    QJsonArray *gpu_array=new QJsonArray;
    for(auto gpu:gpus) {
        gpu_array->append(gpu);
    }
    object->insert("GPU",*gpu_array);
    delete gpu_array;
    object->insert("Mother_Board",motherboard);
    QJsonArray *RAMModel_json=new QJsonArray;
    for(auto RAM:RAMModel){
        RAMModel_json->append(RAM);
    }
    object->insert("Net_Card",*RAMModel_json);
    delete RAMModel_json;
    QJsonArray *netCards_json=new QJsonArray;
    for(auto netCard:netCards){
        netCards_json->append(netCard);
    }
    object->insert("Net_Card",*netCards_json);
    delete netCards_json;
    QJsonArray *audioCards_json=new QJsonArray;
    for(auto audioCard:audioCards){
        audioCards_json->append(audioCard);
    }
    object->insert("Audio_Card",*audioCards_json);
    delete audioCards_json;
    object->insert("Monitor",monitor);
    device->setObject(*object);
    delete object;
    QJsonObject obj_root=qJsonDocument.object();
    obj_root.insert("data",QString(device->toJson()));
    delete device;
    qJsonDocument.setObject(obj_root);
    timer = new QTimer(this);
    QNetworkAccessManager *httpMgr = new QNetworkAccessManager();
    QNetworkRequest requestInfo;
    //HTTP请求
    //请求头
    requestInfo.setUrl(QUrl(DEVICE_URL));
    requestInfo.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json"));
    //保存响应的变量
    reply =  httpMgr->post(requestInfo,qJsonDocument.toJson());
    //开启一个循环，直到超时或者获取到数据为止
    connect(reply,&QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
    //设置定时器防止超时
    connect(timer,&QTimer::timeout,this,&DeviceRequest::cancelDownload);
    timer->start(5000);
    //启动循环
    eventLoop.exec();
    delete httpMgr;
}
bool SoftwareRequest::sendRequest(QHash<QString,QString>&startMenu, QHash<QString, Record> *records)
{
    timer = new QTimer(this);
    QNetworkAccessManager* httpMgr = new QNetworkAccessManager();
    QNetworkRequest requestInfo;
    //HTTP请求
    //请求头
    QJsonArray array;
    for(auto record : *records)
    {
        QJsonObject object;
        object.insert("orig_name", record.orig_name);
        object.insert("path", record.path);
        array.append(object);
    }
    QJsonArray menu_list;
    for(auto name:startMenu.keys())
    {
        QJsonObject object;
        object.insert("name", name);
        object.insert("path", startMenu[name]);
        menu_list.append(object);
    }
    QJsonObject obj_root = qJsonDocument.object();
    QJsonObject object;
    object.insert("reg", array);
    object.insert("start", menu_list);
    obj_root.insert("data", object);
    obj_root.insert("type", "update");
    qJsonDocument.setObject(obj_root);
    QString url = SOFTWARE_URL;
    requestInfo.setUrl(url);
    requestInfo.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
    //保存响应的变量
    reply = httpMgr->post(requestInfo, qJsonDocument.toJson());
    qDebug() << qJsonDocument.toJson();
    //开启一个循环，直到超时或者获取到数据为止
    connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
    //设置定时器防止超时
    connect(timer, &QTimer::timeout, this, &SoftwareRequest::cancelDownload);
    timer->start(5000);
    //启动循环
    eventLoop.exec();
    timer->stop();
    delete timer;
    QJsonDocument result;
   // auto error = reply->error();
    //如果没有错误
    qDebug() << reply->error();
    if (reply->error() == QNetworkReply::NoError) {
        result = QJsonDocument::fromJson(reply->readAll());
    }
    else {
        //如果有错误
        delete httpMgr;
        return false;
    }
    //qDebug() << result.toJson();

    //如果数据完整
    if (result.isObject()) {
        QJsonObject obj_root2 = result.object();
        QJsonArray array = obj_root2.value("data").toObject().value("menu").toArray();
        for (auto value : array) {
            QJsonObject object = value.toObject();
            QString orig_name = object.value("orig_name").toString();
            if (orig_name.isEmpty())
            {
                delete httpMgr;
                return false;
            }
            QNetworkAccessManager manager;
            downloadSuccess = true;
            QUrl url_logo(object.value("img").toString());
            QNetworkRequest* request_logo = new QNetworkRequest(url_logo);
            reply = manager.get(*request_logo);
            QTimer timer;
            timer.setInterval(5000);
            connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
            connect(&timer, &QTimer::timeout, this, &SoftwareRequest::cancelDownload);
            eventLoop.exec();
            timer.stop();
            QByteArray buffer;
            delete request_logo;
            reply->close();
            QString dir = QApplication::applicationDirPath() + "/images/software/";
            if (downloadSuccess == true) {
                buffer = reply->readAll();
                QFile file(dir + orig_name + ".svg");
                if (file.open(QIODevice::WriteOnly | QIODevice::Text))
                {
                    file.write(buffer);
                    file.close();
                }
            }

            (*records)[orig_name].logo = dir + orig_name + ".svg";
            (*records)[orig_name].name = object.value("name").toString();
            (*records)[orig_name].locked = object.value("locked").toBool();
            (*records)[orig_name].url = object.value("url").toString();
            (*records)[orig_name].path = object.value("path").toString();
            if ((*records)[orig_name].path.isEmpty())
            {
                delete httpMgr;
                return false;
            }
        }
    }
    else {
        //数据不完整
        //delete reply;
        delete httpMgr;
        return false;
    }
    delete httpMgr;
    return true;
}

QString OpenWeChatRequest::sendRequest(bool notuse)
{
    timer = new QTimer(this);
    QNetworkAccessManager* httpMgr = new QNetworkAccessManager();
    QNetworkRequest requestInfo;
    //HTTP请求
    //请求头
    requestInfo.setUrl(QUrl(WECHAT_URL));
    requestInfo.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
    //保存响应的变量
    reply = httpMgr->post(requestInfo, qJsonDocument.toJson());
    //开启一个循环，直到超时或者获取到数据为止
    connect(reply, &QNetworkReply::finished, this, &OpenWeChatRequest::cancelDownload);
    //设置定时器防止超时
    connect(timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit);
    timer->start(5000);
    //启动循环
    eventLoop.exec();
    timer->stop();
    QByteArray buffer = reply->readAll();
    QJsonDocument reply_json = QJsonDocument::fromJson(buffer);
    if(!reply_json.isObject())
    {
        delete timer;
        delete httpMgr;
        delete reply;
        return "ok";
    }
    delete timer;
    delete httpMgr;
    delete reply;
    return reply_json.object().value("msg").toString();
}

void OpRequest::sendRequest()
{
    timer = new QTimer(this);
    QJsonObject object = qJsonDocument.object();
    object.insert(op, op_value);
    qJsonDocument.setObject(object);
    QNetworkAccessManager* httpMgr = new QNetworkAccessManager();
    QNetworkRequest requestInfo;
    //HTTP请求
    //请求头
    requestInfo.setUrl(QUrl(OP_URL));
    requestInfo.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
    //保存响应的变量
    reply = httpMgr->post(requestInfo, qJsonDocument.toJson());
    //开启一个循环，直到超时或者获取到数据为止
    connect(reply, &QNetworkReply::finished, this, &OpRequest::cancelDownload);
    //设置定时器防止超时
    connect(timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit);
    timer->start(5000);
    //启动循环
    eventLoop.exec();
    timer->stop();
    delete timer;
    delete httpMgr;
    delete reply;
}

