wumu
2025-11-06 fcc4de01b336e73df6788fa6129ec15162ac6701
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
#include "etfstockinfo.h"
#include "ui_etfstockinfo.h"
 
#include <QNetworkCookie>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QMessageBox>
#include <QDateTime>
 
ETFStockInfo::ETFStockInfo(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::ETFStockInfo)
{
    ui->setupUi(this);
 
    m_model_market = new QStandardItemModel(0,17,this);
    m_model_position = new QStandardItemModel(0,7,this);
 
    ui->tableView_market->setModel(m_model_market);
//    ui->tableView_position->setModel(m_model_position);
 
    m_customModel = new CustomSortProxyModel; // 可自定义排序的模型
    m_customModel->setSourceModel(m_model_position); // 设置源模型
    ui->tableView_position->setModel(m_customModel);
    // 表格列排序
    ui->tableView_position->setSortingEnabled(true);
 
    QStringList labels_market;
    labels_market<<"基金代码"<<"基金名称"<<"成交额(亿)"<<"涨跌额"<<"累计净值"<<"etf类型"<<"涨跌幅"<<"成交量"<<"市价"
                <<"年涨跌幅"<<"粉丝"<<"市值(亿)"<<"手续费"<<"交易量-单批"<<"单位净值"<<"总股数"<<"时间";
 
    m_model_market->setHorizontalHeaderLabels(labels_market);
 
    QStringList labels_position;
    labels_position<<"股票名"<<"股票代码"<<"机构名称"<<"持股数(亿)"<<"持股比例%"<<"截止日期"<<"基金数量(家)";
 
    m_model_position->setHorizontalHeaderLabels(labels_position);
 
 
    // 处理数据爬取的操作
    // 模拟浏览器的参数
    QString userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36";
    m_cookie = "__utma=1.731742638.1647403301.1699341909.1700229030.32; device_id=196eef62baf016c7d95a22752d9bdbab; smidV2=20240414233939e95389ecf7ecd2f4d08524ce770aacd500753aa68e9640320; s=c611de27gr; cookiesu=651726298794778; xq_a_token=220b0abef0fac476d076c9f7a3938b7edac35f48; xqat=220b0abef0fac476d076c9f7a3938b7edac35f48; xq_r_token=1d46f0ed628506486164e5055a4993f9b54b2f4c; xq_id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1aWQiOi0xLCJpc3MiOiJ1YyIsImV4cCI6MTcyOTIxMjc4NCwiY3RtIjoxNzI3NDkwOTU3MjA0LCJjaWQiOiJkOWQwbjRBWnVwIn0.C_GmKEhTaaioDMLWkgZyMXDl4duYEVmsdJHsTi7gbcNz0Tohc-uxHsaw0yBT5k-qmbrJ_RaLMCSxy06v14-R3dwL-MsiKRHxHa5qvQZN4BjEgvPRkqqvPgE_fkPLte8qQOEgd5iVkhr-4mjip0-9WCeXYiH7DygxFOBXGlgoPtpPzAtOTm5TWJmXh0ipDsIZxfNOl8jipXYaIdkv_kqLul5gqiBi5qqnwONDa24Zx-Kvpm8ySWiPFBLzZBqTuRBs4oKAMpSdOiYGLVL7dcSDDZyWqAexmrN4f19hkmd6gBHL4dCczRMDGYc1e98sQtlbZ5lgeEuuM24jjcuwCxsxXQ; u=651726298794778; Hm_lvt_1db88642e346389874251b5a1eded6e3=1727099939,1727251802,1727488707,1727491020; HMACCOUNT=1628106D67895387; acw_tc=2760828017275244258732552e9880f861be6db0c40facbdd5f223490decc2; acw_sc__v2=66f7ee8290dc3f63112948801ef331b8c97ccb35; Hm_lpvt_1db88642e346389874251b5a1eded6e3=1727524485; .thumbcache_f24b8bbe5a5934237bbc0eda20c1b6e7=t00N841S/BEpxTGOoJrbm0blWik12om0ew/whcq/V2DNtyEA8um7J+yzeGOli+6iP/TrvrH0YKH2kHlsmDb5EQ%3D%3D; ssxmod_itna=YqAOBKYve+x0ODfxBcDB4DKM7RtAA4454DkDIEC+GAqGNK3DZDiqAPGhDC8RzeL4Ko7+e2aeQvSeopd5pYDk0Ge5TB0PIjaIDB3DEx06TCCQxiiSDCeDIDWeDiDG4Gm4qGtDpxG=DjDytZ9TtDm4GWGqDmDGYBWqDgDYQDGwIXD7QDIqtW07tQDDNQKpAKDiYeHlL5uMRMtOrK7DtDjdTD/3+kZCbCcPwVFeFO=nPcDB6wxBjZRq00Un+g4mNqLYf4IDAxQuYKtgheYYoAfDhTKhhLSGx4tGY4+GDKSiMS2DDAIvdKeD; ssxmod_itna2=YqAOBKYve+x0ODfxBcDB4DKM7RtAA4454DkDIEC+GDA69mqD/YttDFhxMltFKApT7bCMH+bytp7GQQyCbBWukeAF3+jxeN2wLjbQAFcdwbeNeoohjQ4qtEnLg4TKyX2LqVL=CGaV=GqZZqbDby8DFnFbgWiZEH8zoBzBCbzqWeqwoPq7/TpL=gIRY8sVhEpnWWHQU8sz+S8=+8oRerHq0wtQnSzyQDK7Dmvr3a+VY7fezRmxKF=bDeqexYUbuuzw2eR3In9evW6tzHbQY6vp=AIOUc9l6vc0vOl9plD6D07zGGQ41uxpii2Y5s7KvYQDWGYExD7=DYKKeD==";
    QByteArray cookieByte = m_cookie.toUtf8();
    QList<QNetworkCookie> list;
    list.push_back(QNetworkCookie(cookieByte));
 
    QVariant var;
    var.setValue(list);
    // 设置要访问的网址
    m_request.setUrl(QUrl("https://xueqiu.com/hq#hot"));
    // 设置请求头,用户代理,用来模拟浏览器
    m_request.setHeader(QNetworkRequest::UserAgentHeader,userAgent);
    // 设置cookie
    //m_request.setHeader(QNetworkRequest::CookieHeader, var);
 
    // 查看manager都支持哪些协议
    qDebug()<<"支持的协议:"<<m_manager.supportedSchemes();
    // 关联信号槽,当请求管理对象完全打开网页之后,会将数据给槽函数处理
    connect(&m_manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(showAplyData(QNetworkReply*)));
 
    qDebug()<<"开始请求";
    m_manager.get(m_request);
    qDebug()<<"请求中...";
 
    ui->dateTimeEdit->setDateTime(QDateTime::currentDateTime());
    ui->dateTimeEdit_3->setDateTime(QDateTime::currentDateTime());
 
}
 
ETFStockInfo::~ETFStockInfo()
{
    delete ui;
}
 
void ETFStockInfo::initMySQL()
{
    //添加一个数据库
      db=QSqlDatabase::addDatabase("QMYSQL");    //括号内要写出数据库的类型
      //设置数据库
      db.setHostName("127.0.0.1"); //设置数据库的主机ip
      //设置数据库的用户名
      db.setUserName("root");
      //设置数据库的密码
      db.setPassword("root");    //这个就是安装MySQL时设置的密码
      //设置数据库的名字
      db.setDatabaseName("stock_plan");
      //打开数据库(已经安装过mysql驱动了)
      if(db.open()==false){
          QMessageBox::warning(this,"waring",db.lastError().text());
      }else{
          qDebug()<<"mysql conn ok";
      }
}
 
void ETFStockInfo::getEtfInfo(QByteArray &buffer)
{
    m_model_market->setRowCount(0);
//    qDebug()<<"ETF:"<<buffer;
    // 使用JSON进行数据处理
    QJsonDocument jd = QJsonDocument::fromJson(buffer);
    if(jd.isArray()){
        qDebug()<<"js array";
 
    }else if(jd.isObject()){
        qDebug()<<"js object";
        QJsonObject jobject = jd.object();
        QStringList jlist = jobject.keys();
        qDebug()<<"jlist:"<<jlist; // 输出一下一级键的情况
        // 通过键值对的方式提取数据
        int count = jobject["data"].toObject()["count"].toInt();
        qDebug()<<"count:"<<count;
        QJsonArray listData = jobject["data"].toObject()["list"].toArray();
        count = listData.size(); // 适应新版的处理
        for(int i=0;i<count;++i){
            QString symbol = listData.at(i).toObject().value("symbol").toString(); // 股票代号
            double amount = listData.at(i).toObject().value("amount").toDouble()/100000000; // 成交额 单位 亿
            double chg = listData.at(i).toObject().value("chg").toDouble(); // 涨跌额
            double acc_unit_nav = listData.at(i).toObject().value("acc_unit_nav").toDouble(); // 累计净值
            QString etf_types; // = listData.at(i).toObject().value("etf_types").toString();  //etf类型
            QJsonArray type_arr = listData.at(i).toObject().value("etf_types").toArray();
            for(int i=0;i<type_arr.size();++i){
                etf_types += type_arr.at(i).toString()+" ";
            }
 
            double percent = listData.at(i).toObject().value("percent").toDouble(); // 涨跌幅 百分比,大于0上涨,小于0下跌
            int volume = listData.at(i).toObject().value("volume").toInt(); // 成交量 单位 手
            double current = listData.at(i).toObject().value("current").toDouble(); // 收盘价
            double current_year_percent = listData.at(i).toObject().value("current_year_percent").toDouble(); // 年涨跌幅
            double followers = listData.at(i).toObject().value("followers").toInt(); // 粉丝数量
            QString name = listData.at(i).toObject().value("name").toString();  // 股票名字
            double market_capital = listData.at(i).toObject().value("market_capital").toDouble()/100000000; // 总市值 单位 亿
            double premium_rate = listData.at(i).toObject().value("premium_rate").toDouble(); // 手续费率
            double lot_size = listData.at(i).toObject().value("lot_size").toDouble(); // 单批-交易量
            double unit_nav = listData.at(i).toObject().value("unit_nav").toDouble(); // 单位净值
            int total_shares = listData.at(i).toObject().value("total_shares").toDouble(); // 单位净值
            double timestamp = listData.at(i).toObject().value("timestamp").toDouble();  // 时间戳
 
 
            QList<QStandardItem*> rowItems;
            rowItems.append(new QStandardItem(symbol));
            rowItems.append(new QStandardItem(name));
            rowItems.append(new QStandardItem(QString::number(amount)));
            rowItems.append(new QStandardItem(QString::number(chg)));
            rowItems.append(new QStandardItem(QString::number(acc_unit_nav)));
            rowItems.append(new QStandardItem(etf_types));
 
            QStandardItem *percentItem =  new QStandardItem(QString::number(percent));
            if(percent > 0){
                percentItem->setData(QColor("red"),Qt::DecorationRole); // 添加一个装饰的颜色为红色
                percentItem->setData(QColor("red"),Qt::TextColorRole);  // 将字体颜色设置为红色
                rowItems.at(0)->setData(QColor("red"),Qt::TextColorRole);  // 将股票名字设置为红色
             }
            else if(percent < 0){
                percentItem->setData(QColor("green"),Qt::BackgroundColorRole);
                rowItems.at(0)->setData(QColor("green"),Qt::TextColorRole);
            }
            rowItems.append(percentItem);
 
            rowItems.append(new QStandardItem(QString::number(volume)));
            rowItems.append(new QStandardItem(QString::number(current)));
            rowItems.append(new QStandardItem(QString::number(current_year_percent)));
            rowItems.append(new QStandardItem(QString::number(followers)));
 
            rowItems.append(new QStandardItem(QString::number(market_capital,'f',2)));
            rowItems.append(new QStandardItem(QString::number(premium_rate,'f',2)));
            rowItems.append(new QStandardItem(QString::number(lot_size)));
            rowItems.append(new QStandardItem(QString::number(unit_nav)));
            rowItems.append(new QStandardItem(QString::number(total_shares)));
            rowItems.append(new QStandardItem(QString::number(timestamp)));
 
            // 添加一行数据项到模型中
            //m_model->appendRow(rowItems);
            m_model_market->appendRow(rowItems);
 
            // 保存etf基金的代号和名字
            m_codeNamesEtf[symbol] = name;
        }
    }
 
}
 
/* 响应情况
{"data":{"chg_date":"2025中报","fund_items":[{"to_float_shares_ratio":32.27,"org_name_or_fund_name":"全部合计","held_num":214204071},
{"to_float_shares_ratio":1.7792,"org_name_or_fund_name":"华泰柏瑞沪深300交易型开放式指数证券投资基金","held_num":11809096},
{"to_float_shares_ratio":1.6554,"org_name_or_fund_name":"华夏国证半导体芯片交易型开放式指数证券投资基金","held_num":10987221},
*/
void ETFStockInfo::getStockFundPosition(QByteArray &buffer,QString url)
{
    int index = url.indexOf(QRegularExpression("[A-Z]{2}\\d{6}"));
    qDebug()<<"index:"<<index<<url.mid(index,8);
    QString symbol = url.mid(index,8);
    QString name=" ";
    if(m_codeNames.size() > 0){
        name = m_codeNames[symbol];
    }
 
    //    m_model_position->setRowCount(0);
    //    qDebug()<<"ETF:"<<buffer;
    // 使用JSON进行数据处理
    QJsonDocument jd = QJsonDocument::fromJson(buffer);
    if(jd.isArray()){
        qDebug()<<"js array";
 
    }else if(jd.isObject()){
        qDebug()<<"js object";
        QJsonObject jobject = jd.object();
        QStringList jlist = jobject.keys();
        qDebug()<<"jlist:"<<jlist; // 输出一下一级键的情况
        // 通过键值对的方式提取数据
        QString chg_date = jobject["data"].toObject()["chg_date"].toString(); // 修改时间 按季度来显示
 
        QJsonArray fund_items = jobject["data"].toObject()["fund_items"].toArray();
        int count = fund_items.size(); // 适应新版的处理
        qDebug()<<"基金数量 count:"<<count;
        for(int i=0;i<1;++i){
            double to_float_shares_ratio = fund_items.at(i).toObject().value("to_float_shares_ratio").toDouble(); // 流通股比例
            QString org_name_or_fund_name = fund_items.at(i).toObject().value("org_name_or_fund_name").toString(); // 机构名
            double held_num = fund_items.at(i).toObject().value("held_num").toInt()/100000000.0; // 持股数 [按亿算]
 
            qDebug()<<to_float_shares_ratio<<org_name_or_fund_name<<held_num<<chg_date<<count;
 
            QList<QStandardItem*> items;
            items.append(new QStandardItem(name));
            items.append(new QStandardItem(symbol));
            items.append(new QStandardItem(org_name_or_fund_name));
            items.append(new QStandardItem(QString::number(held_num)));
            items.append(new QStandardItem(QString::number(to_float_shares_ratio)));
            items.append(new QStandardItem(chg_date));
            items.append(new QStandardItem(QString::number(count)));
 
            m_model_position->appendRow(items);
        }
    }
}
 
void ETFStockInfo::getStockOne(QByteArray &buffer)
{
    QJsonDocument jd = QJsonDocument::fromJson(buffer);
    if(jd.isObject()){
        QJsonObject jObject = jd.object();
        QJsonArray jArr = jObject.value("data").toObject().value("item").toArray(); // 通过键值对取值
        int cnt = jArr.count();
        qDebug()<<"数组size:"<<cnt;
        QString symbol = jObject.value("data").toObject().value("symbol").toString();
        QString code = symbol; // 股票代号
        QString name = m_codeNamesEtf[code];
        qDebug()<<"历史:"<<code<<symbol;
 
        // 以批量写入的方式来获取多年数据
        QString sql = "insert into etf_day_info (code,name,amount,chg,percent,volume,close,time_trade) values ";
        //qDebug()<<"sql 1:"<<sql;
        for(int i=0;i<cnt;++i){
            qint64 timestamp = jArr.at(i).toArray().at(0).toVariant().toLongLong();
//            double open = jArr.at(i).toArray().at(2).toVariant().toDouble();
//            double high = jArr.at(i).toArray().at(3).toVariant().toDouble();
//            double low = jArr.at(i).toArray().at(4).toVariant().toDouble();
            double close = jArr.at(i).toArray().at(5).toVariant().toDouble();
            double percent = jArr.at(i).toArray().at(7).toVariant().toDouble();
//            double turnoverrate = jArr.at(i).toArray().at(8).toVariant().toDouble();
            double amount = jArr.at(i).toArray().at(9).toVariant().toDouble();
//            double pe_ttm = jArr.at(i).toArray().at(16).toVariant().toDouble();
//            double market_capital = jArr.at(i).toArray().at(17).toVariant().toDouble();
            long long volume = jArr.at(i).toArray().at(1).toVariant().toLongLong()/100;
            double chg = jArr.at(i).toArray().at(6).toVariant().toDouble();
 
            //long long amount = jArr.at(i).toArray().at(9).toVariant().toLongLong()/100000000; // 亿
            QString curDateTime = QDateTime::fromMSecsSinceEpoch(timestamp).toString("yyyy-MM-dd");
//            qDebug()<<timestamp<<curDateTime<<close<<volume<<amount;
 
            // 处理数据保存到模型中
            QString vals = QString("('%1','%2',%3,%4,%5,%6,%7,'%8')").arg(code).arg(name).arg(QString::number(amount))
                    .arg(QString::number(chg)).arg(QString::number(percent)).arg(QString::number(volume)).arg(QString::number(close))
                    .arg(curDateTime);
            if(i != cnt - 1){
                vals.append(",");
            }
            sql.append(vals);
            //qDebug()<<"sql 3:"<<sql;
 
        }
        qDebug()<<"over:"<<sql.size();
//        qDebug()<<"sql 2:"<<sql; // 太大了 显示不出来
 
        QSqlQuery que(db);
        if(que.exec(sql)){
            qDebug()<<"insert ok";
        }else{
            qDebug()<<"insert fail"<<que.lastError().text();
        }
    }
 
}
 
void ETFStockInfo::showAplyData(QNetworkReply *reply)
{
    qDebug()<<"收到响应etf";
    // 将响应的数据,一把读取完,放到字节数组里面来处理
    QByteArray buffer = reply->readAll();
 
 
    // 下面使用JSON进行数据处理
    if(reply->url() == QUrl("https://xueqiu.com/")){
        qDebug()<<"发现首页url";
        qDebug()<<buffer;
 
    }else if(reply->url().toString().indexOf("https://stock.xueqiu.com/v5/stock/chart/kline.json") != -1){
        qDebug()<<"查看个股情况:";
        getStockOne(buffer);
 
    }else if(reply->url().toString().indexOf("https://stock.xueqiu.com/v5/stock/screener/quote/list.json?page=1&size=100&order=desc&order_by=percent&market=CN&ind_code") != -1){
        qDebug()<<"根据行业获取股票信息"<<reply->url();
        QString industryCode = reply->url().toString().split("=").back();
        qDebug()<<"行业信息:"<<industryCode;
//        getStockByIndustry(buffer,industryCode);
 
    }else if(reply->url().toString().indexOf("https://stock.xueqiu.com/v5/stock/screener/quote/list.json") != -1){
        qDebug()<<"获取所有沪深股票 可以干活了";
//        getStockAllCode(buffer);
    }else if(reply->url().toString().indexOf("https://stock.xueqiu.com/v5/stock/screener/industries.json") != -1){
        qDebug()<<"获取行业信息";
//        getIndustryInfo(buffer);
    }else if(reply->url().toString().indexOf("https://stock.xueqiu.com/v5/stock/screener/fund/list.json") != -1){
        qDebug()<<"获取到ETF基金信息";
        getEtfInfo(buffer);
    }else if(reply->url().toString().indexOf("https://stock.xueqiu.com/v5/stock/f10/cn/org_holding/detail.json") != -1){
        qDebug()<<"获取到股票基金持仓信息";
        qDebug()<<"基金持仓 url:"<<reply->url().toString();
        getStockFundPosition(buffer,reply->url().toString());
    }
 
    reply->deleteLater();
}
 
void ETFStockInfo::on_pushButton_market_clicked()
{
    QString url = "https://stock.xueqiu.com/v5/stock/screener/fund/list.json?page=1&size=3000&order=desc&order_by=percent&type=18&parent_type=1";
 
    m_request.setUrl(QUrl(url));
    m_manager.get(m_request);
}
 
// 查询基金持仓情况 按总量来查询
void ETFStockInfo::on_pushButton_position_search_clicked()
{
    QString type = ui->comboBox_type->currentText();
    QString count_rank = ui->comboBox_rank->currentText(); // 前N名
    QString url = "https://stock.xueqiu.com/v5/stock/f10/cn/org_holding/detail.json?symbol=SH603986&timestamp=1759161600000&extend=true";
 
    // 拿出前N名,进行请求,然后获取对应股票的基金持仓情况
//    m_request.setUrl(QUrl(url));
//    m_manager.get(m_request);
 
    emit sendSymbolNums(count_rank.toInt()); // 发获取股票代号的信号
 
}
 
void ETFStockInfo::saveCodeNames(QMap<QString, QString> &cns)
{
    m_codeNames = cns; // 拷贝股票代号和名字过来
    qDebug()<<__FUNCTION__<<"收到股票代号和名字的信息";
}
 
void ETFStockInfo::getStockFundPosSlot(QString symbol)
{
    QStringList tts = {"1759161600000","1751212800000","1743350400000"};
    for(auto &tt:tts){
        QString timestamp = tt;
        QString url = QString("https://stock.xueqiu.com/v5/stock/f10/cn/org_holding/detail.json?symbol=%1&timestamp=%2&extend=true").arg(symbol).arg(timestamp);
        m_request.setUrl(QUrl(url));
        m_manager.get(m_request);
    }
 
}
 
void ETFStockInfo::on_pushButton_search_date_clicked()
{
    // 按日期查询数据库,了解趋势
    QString cur_date = ui->dateTimeEdit->date().toString("yyyy-MM-dd");
    QString sql = QString("select *  from etf_day_info where time_trade = '%1' order by percent desc").arg(cur_date);
 
    QSqlQuery que(db);
    if(que.exec(sql)){
        qDebug()<<"select ok";
 
        m_model_market->setRowCount(0); // 重置模型行数
        int rows = 0;
        while (que.next()) {
            QString code = que.value(1).toString();
            QString name = que.value(2).toString();
            QString amount = QString::number(que.value(3).toDouble()/100000000);
            QString chg = QString::number(que.value(4).toDouble());
            QString percent = que.value(5).toString();
            QString volume = que.value(6).toString();
            QString close = que.value(7).toString();
            QString time_trade = que.value(8).toString();
 
//            QString turnover_rate = que.value(7).toString();
//            QString pe_ttm = que.value(8).toString();
//            QString amount_rank = que.value(9).toString();
 
//            m_modelDatas.append({name,code,market_capital,percent,close,amount,volume,turnover_rate,pe_ttm,amount_rank});
 
            QList<QStandardItem*> items;
            items.append(new QStandardItem(code));
            items.append(new QStandardItem(name));
            items.append(new QStandardItem(amount));
            items.append(new QStandardItem(chg));
            items.append(new QStandardItem("0"));
            items.append(new QStandardItem("0"));
            QStandardItem *percentItem =  new QStandardItem(percent);
            if(percent.toDouble() > 0){
                percentItem->setData(QColor("red"),Qt::DecorationRole); // 添加一个装饰的颜色为红色
                percentItem->setData(QColor("red"),Qt::TextColorRole);  // 将字体颜色设置为红色
                items.at(0)->setData(QColor("red"),Qt::TextColorRole);  // 将股票名字设置为红色
             }
            else if(percent.toDouble() < 0){
                percentItem->setData(QColor("green"),Qt::BackgroundColorRole);
                items.at(0)->setData(QColor("green"),Qt::TextColorRole);
            }
            items.append(percentItem);
            items.append(new QStandardItem(volume));
            items.append(new QStandardItem(close));
            items.append(new QStandardItem(time_trade));
 
//            items.append(new QStandardItem(pe_ttm));
//            items.append(new QStandardItem(amount_rank));
            m_model_market->appendRow(items);
            rows++;
        }
        qDebug()<<"查询到行数:"<<rows;
 
 
    }else{
        qDebug()<<"select fail"<<que.lastError().text();
    }
 
}
 
void ETFStockInfo::on_pushButton_update_clicked()
{
    // 更新到最新,默认全更
    // 也可以指定天数的数量来更新
 
    // 先保证获取到当前所有的etf基金的代码和名字,然后根据代码来发起更新请求
    m_days = ui->comboBox_days->currentText().toInt();
 
    if(m_days == 0) return;
 
    if(m_codeNamesEtf.size() > 0){
        qint64 cur_time = QDateTime::currentMSecsSinceEpoch();
 
        for(auto code:m_codeNamesEtf.keys()){
            QString url = QString("https://stock.xueqiu.com/v5/stock/chart/kline.json?symbol=%1&begin=%2&period=day&type=before&count=-%3&indicator=kline,pe,market_capital,ma")
                    .arg(code).arg(QString::number(cur_time)).arg(m_days);
            m_request.setUrl(QUrl(url));
            m_manager.get(m_request);
 
        }
        qDebug()<<"发起请求完成";
    }else{
        // 如果为空,则需要去刷新一下最新的情况,获取基金信息
        on_pushButton_market_clicked();
    }
 
}
 
void ETFStockInfo::on_checkBox_update_clicked()
{
 
    if(ui->checkBox_update->isChecked()){
        ui->pushButton_update->setEnabled(true);
    }else{
        ui->pushButton_update->setEnabled(false);
    }
}