| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148 |
- #include "GeneralInterface.h"
- #include <QTime>
- #include <QRect>
- #include <QPoint>
- #include <QScreen>
- #include <QDateTime>
- #include <QCheckBox>
- #include <QApplication>
- #include <QCoreApplication>
- #include <QGraphicsScene>
- #include <QGraphicsProxyWidget>
- #include <QParallelAnimationGroup>
- #include <QPropertyAnimation>
- #include <QDataStream>
- #include <QScroller>
- #include <QPainter>
- #include <unistd.h>
- // libqrencode 相关头文件
- #include <qrencode.h>
- #include <QImage>
- #include <QBuffer>
- #include "Globals.h"
- #include "ConfigManager.h"
- #include "LoggerHelper.h"
- #include "OtherSettings/log/FormLogView.h"
- #include "VersionManager.h"
- template<typename T>
- T GeneralInterface::toInt(const QByteArray &data, int offset, bool networkOrder)
- {
- if ((offset + sizeof(T)) > static_cast<size_t>(data.size())) {
- return 0;
- }
- T value;
- memcpy(&value, data.constData() + offset, sizeof(T));
- if (networkOrder) {
- if constexpr (sizeof(T) == 2) {
- return qFromBigEndian(value);
- } else if constexpr (sizeof(T) == 4) {
- return qFromBigEndian(value);
- } else if constexpr (sizeof(T) == 8) {
- return qFromBigEndian<qint64>(value);
- }
- }
- return value;
- }
- /**
- * @brief 将QByteArray中的数据转换为uint8_t类型
- *
- * @param data QByteArray对象,包含要转换的数据
- * @param offset 数据在QByteArray中的偏移量
- * @return uint8_t 转换后的uint8_t类型数据
- */
- uint8_t GeneralInterface::toUInt8(const QByteArray &data, int offset)
- {
- return toInt<uint8_t>(data, offset);
- }
- /**
- * @brief 将QByteArray中的数据转换为uint16_t类型
- *
- * @param data QByteArray对象,包含要转换的数据
- * @param offset 数据在QByteArray中的偏移量
- * @param networkOrder 是否使用网络字节序
- * @return uint16_t 转换后的uint16_t值
- */
- uint16_t GeneralInterface::toUInt16(const QByteArray &data, int offset, bool networkOrder)
- {
- return toInt<uint16_t>(data, offset, networkOrder);
- }
- /**
- * @brief 将QByteArray中的数据转换为uint32_t类型
- *
- * @param data QByteArray对象,包含要转换的数据
- * @param offset 数据在QByteArray中的偏移量
- * @param networkOrder 是否使用网络字节序
- * @return uint32_t 转换后的uint32_t值
- */
- uint32_t GeneralInterface::toUInt32(const QByteArray &data, int offset, bool networkOrder) {
- return toInt<uint32_t>(data, offset, networkOrder);
- }
- /**
- * @brief 将QByteArray转换为uint64_t类型
- *
- * @param data QByteArray对象,包含要转换的数据
- * @param offset 数据在QByteArray中的偏移量
- * @param networkOrder 是否使用网络字节序
- *
- * @return uint64_t 转换后的uint64_t类型数据
- */
- uint64_t GeneralInterface::toUInt64(const QByteArray &data, int offset, bool networkOrder)
- {
- return toInt<uint64_t>(data, offset, networkOrder);
- }
- /**
- * @brief GeneralInterface::networkStructToByteArray 将MSG_HEAD结构体转换为网络字节序的字节数组
- * @param data MSG_HEAD结构体
- * @return QByteArray
- */
- QByteArray GeneralInterface::networkStructToByteArray(const MSG_HEAD &data)
- {
- // 将MSG_HEAD结构体转换为网络字节序的字节数组
- MSG_HEAD networkData;
- networkData.trans_id = qToBigEndian(data.trans_id);
- networkData.proto_id = qToBigEndian(data.proto_id);
- networkData.length = qToBigEndian(data.length);
- networkData.unit_id = qToBigEndian(data.unit_id);
- networkData.cmd = qToBigEndian(data.cmd);
- // 返回转换后的字节数组
- return QByteArray(reinterpret_cast<const char*>(&networkData), sizeof(MSG_HEAD));
- }
- /**
- * @brief GeneralInterface::encodeValue 将数据编码为指定长度的字节数组
- * @param data 要编码的数据
- * @param length 数据的长度
- * @return 编码后的字节数组
- */
- template<typename T>
- QByteArray GeneralInterface::encodeValue(T &data, const uint8_t &length)
- {
- QByteArray result;
- auto tempData = qToBigEndian(data);
- result.append(0x80 + sizeof(data));
- result.append(length);
- result.append(QByteArray(reinterpret_cast<const char*>(&tempData), sizeof(T)));
- return result;
- }
- /**
- * @brief GeneralInterface::decodeValue 将字节数组解码为指定类型的数据
- * @param data 字节数组
- * @return 解码后的数据
- */
- template<typename T>
- T GeneralInterface::decodeValue(const QByteArray &data)
- {
- return toInt<T>(data);
- }
- /**
- * @brief GeneralInterface::encodeStartChargeGunInfo 将START_CHARGE_CMD结构体编码为字节数组
- * @param data START_CHARGE_CMD结构体
- * @return 编码后的字节数组
- */
- QByteArray GeneralInterface::encodeStartChargeGunInfo(const START_CHARGE_CMD &data)
- {
- QByteArray ctl_array;
- ctl_array.append(encodeValue<const uint32_t>(data.GUNID, 1));
- ctl_array.append(0x81);
- ctl_array.append(sizeof(data.EMID));
- ctl_array.append(QByteArray(reinterpret_cast<const char*>(&data.EMID), sizeof(data.EMID)));
- ctl_array.append(encodeValue<const uint32_t>(data.requestKWs, 1));
- ctl_array.append(encodeValue<const uint32_t>(data.requestMinutes, 1));
- ctl_array.append(encodeValue<const uint32_t>(data.requestSOC, 1));
- ctl_array.append(encodeValue<const uint32_t>(data.authorizationResult, 1));
- return ctl_array;
- }
- /**
- * @brief GeneralInterface::encodeStopChargeGunInfo 将STOP_CHARGE_CMD结构体编码为字节数组
- * @param data STOP_CHARGE_CMD结构体
- * @return 编码后的字节数组
- */
- QByteArray GeneralInterface::encodeStopChargeGunInfo(const STOP_CHARGE_CMD &data)
- {
- QByteArray ctl_array;
- ctl_array.append(encodeValue<const uint32_t>(data.GUNID, 1));
- ctl_array.append(0x81);
- ctl_array.append(sizeof(data.EMID));
- ctl_array.append(QByteArray(reinterpret_cast<const char*>(&data.EMID), sizeof(data.EMID)));
- ctl_array.append(encodeValue<const uint32_t>(data.authorizated, 1));
- return ctl_array;
- }
- /**
- * @brief GeneralInterface::decodeChargeBasicInfo 将字节数组解码为charge_gun_basic_info_t结构体
- * @param data 字节数组
- * @return charge_gun_basic_info_t结构体
- */
- charge_gun_basic_info_t GeneralInterface::decodeChargeBasicInfo(const QByteArray &data)
- {
- charge_gun_basic_info_t basicInfo;
- int start_index = 2;
- basicInfo.GUNID = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- basicInfo.GUN_Error = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- basicInfo.GUN_State = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- basicInfo.GUN_Type = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- basicInfo.BOX_temp = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- basicInfo.OCPP_online = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- return basicInfo;
- }
- /**
- * @brief GeneralInterface::decodeChargeInfo 将字节数组解码为charge_gun_charge_info_t结构体
- * @param data 字节数组
- * @return charge_gun_charge_info_t结构体
- */
- charge_gun_charge_info_t GeneralInterface::decodeChargeInfo(const QByteArray &data)
- {
- charge_gun_charge_info_t charge_info;
- int start_index = 2;
- charge_info.GUNID = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- charge_info.transactionId = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- charge_info.SOC = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- charge_info.startUTC = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- charge_info.now_UTC = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- charge_info.startKW = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- charge_info.now_KW = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- charge_info.GUNLine_temp0 = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- charge_info.GUNLine_temp1 = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- charge_info.powerKW = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- charge_info.voltage = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- charge_info.current = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- start_index += (sizeof(uint32_t) + 2);
- charge_info.rts = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- return charge_info;
- }
- /**
- * @brief GeneralInterface::decodeReplyInfo 将字节数组解码为REPLY_INFO结构体
- * @param data 字节数组
- * @return REPLY_INFO结构体
- */
- REPLY_INFO GeneralInterface::decodeReplyInfo(const QByteArray& data)
- {
- REPLY_INFO info;
- int start_index = 2;
- info.result = decodeValue<uint32_t>(data.mid(start_index, sizeof(uint32_t)));
- return info;
- }
- /**
- * @brief GeneralInterface::encodeReplyInfo 将REPLY_INFO结构体编码为字节数组
- * @param info REPLY_INFO结构体
- * @return 编码后的字节数组
- */
- QByteArray GeneralInterface::encodeReplyInfo(const REPLY_INFO& info)
- {
- QByteArray result;
- result.append(encodeValue<const uint32_t>(info.result, 1));
- return result;
- }
- /**
- * @brief GeneralInterface::setCheckBoxChecked 设置widget下所有QCheckBox的checked属性
- * @param widget
- * @param checked
- */
- void GeneralInterface::setCheckBoxChecked(const QWidget *widget, const bool &checked)
- {
- QList<QCheckBox*> checkBoxes = widget->findChildren<QCheckBox*>();
- if (checkBoxes.isEmpty()) return;
- foreach (QCheckBox* checkBox, checkBoxes) {
- checkBox->setChecked(checked);
- }
- }
- /**
- * @brief GeneralInterface::setTouchScroller 设置QScrollArea的滚动方式为触摸滚动
- * @param area
- */
- void GeneralInterface::setTouchScroller(QScrollArea *area)
- {
- QScroller::grabGesture(area, QScroller::TouchGesture);
- QScroller::grabGesture(area->viewport(), QScroller::LeftMouseButtonGesture);
- }
- /**
- * @brief GeneralInterface::setTouchScroller 设置QListWidget的滚动方式为触摸滚动
- * @param listWidget
- */
- void GeneralInterface::setTouchScroller(QListWidget *listWidget)
- {
- QScroller::grabGesture(listWidget, QScroller::TouchGesture);
- QScroller::grabGesture(listWidget->viewport(), QScroller::LeftMouseButtonGesture);
- }
- /**
- * @brief GeneralInterface::setTouchScroller 设置QTableWidget的滚动方式为触摸滚动
- * @param tableWidget
- */
- void GeneralInterface::setTouchScroller(QTableWidget *tableWidget)
- {
- QScroller::grabGesture(tableWidget, QScroller::TouchGesture);
- QScroller::grabGesture(tableWidget->viewport(), QScroller::LeftMouseButtonGesture);
- }
- /**
- * @brief GeneralInterface::setTouchScroller 设置QTreeWidget的滚动方式为触摸滚动
- * @param treeWidget
- */
- void GeneralInterface::setTouchScroller(QTreeWidget *treeWidget)
- {
- QScroller::grabGesture(treeWidget, QScroller::TouchGesture);
- QScroller::grabGesture(treeWidget->viewport(), QScroller::LeftMouseButtonGesture);
- }
- /**
- * @brief GeneralInterface::setTouchScroller 设置QTextEdit的滚动方式为触摸滚动
- * @param textEdit
- */
- void GeneralInterface::setTouchScroller(QTextEdit *textEdit)
- {
- QScroller::grabGesture(textEdit, QScroller::TouchGesture);
- QScroller::grabGesture(textEdit->viewport(), QScroller::LeftMouseButtonGesture);
- }
- /**
- * @brief GeneralInterface::setTouchScroller 设置QAbstractScrollArea的滚动方式为触摸滚动
- * @param scrollArea
- */
- void GeneralInterface::setTouchScroller(QAbstractScrollArea *scrollArea)
- {
- QScroller::grabGesture(scrollArea, QScroller::TouchGesture);
- QScroller::grabGesture(scrollArea->viewport(), QScroller::LeftMouseButtonGesture);
- }
- void GeneralInterface::setControlEnabled(QWidget *control, QWidget *label, const int &userType)
- {
- // 管理员和根用户都有控制权
- const bool hasControl = (/*userType == General::UserType::ADMIN || */userType == General::UserType::ROOT);
- if (control) {
- control->setEnabled(hasControl);
- }
- if (label) {
- label->setEnabled(hasControl);
- }
- }
- void GeneralInterface::setControlVisiabled(QWidget *control, QWidget *label, const int &userType)
- {
- // 管理员和根用户都有控制权
- const bool hasControl = (userType == General::UserType::ROOT);
- if (control) {
- control->setVisible(hasControl);
- }
- if (label) {
- label->setVisible(hasControl);
- }
- }
- /**
- * @brief GeneralInterface::setAdvancedTouchScroller 设置高级触摸滚动配置
- * @param scrollArea 滚动区域
- * @param properties 滚动属性
- */
- void GeneralInterface::setAdvancedTouchScroller(QAbstractScrollArea *scrollArea,
- const QScrollerProperties &properties)
- {
- // 设置基本手势
- QScroller::grabGesture(scrollArea, QScroller::TouchGesture);
- QScroller::grabGesture(scrollArea->viewport(), QScroller::LeftMouseButtonGesture);
-
- // 应用自定义属性
- QScroller *scroller = QScroller::scroller(scrollArea);
- if (scroller) {
- scroller->setScrollerProperties(properties);
- }
- }
- /**
- * @brief GeneralInterface::setTouchScrollerWithProperties 设置带属性的触摸滚动
- * @param scrollArea 滚动区域
- * @param enableOvershoot 是否启用过度滚动
- * @param enableFlick 是否启用轻弹
- * @param decelerationFactor 减速度因子
- */
- void GeneralInterface::setTouchScrollerWithProperties(QAbstractScrollArea *scrollArea,
- bool enableOvershoot,
- bool enableFlick,
- qreal decelerationFactor)
- {
- // 设置基本手势
- QScroller::grabGesture(scrollArea, QScroller::TouchGesture);
- QScroller::grabGesture(scrollArea->viewport(), QScroller::LeftMouseButtonGesture);
-
- // 配置滚动属性
- QScroller *scroller = QScroller::scroller(scrollArea);
- if (scroller) {
- QScrollerProperties properties = scroller->scrollerProperties();
-
- // 设置过度滚动
- properties.setScrollMetric(QScrollerProperties::OvershootDragResistanceFactor, enableOvershoot ? 0.5 : 0.0);
- properties.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, enableOvershoot ? 0.5 : 0.0);
-
- // 设置轻弹
- properties.setScrollMetric(QScrollerProperties::DecelerationFactor, enableFlick ? decelerationFactor : 0.0);
-
- // 设置其他优化参数
- properties.setScrollMetric(QScrollerProperties::DragVelocitySmoothingFactor, 0.5);
- properties.setScrollMetric(QScrollerProperties::AxisLockThreshold, 0.5);
- properties.setScrollMetric(QScrollerProperties::ScrollingCurve, QEasingCurve::OutCubic);
-
- scroller->setScrollerProperties(properties);
- }
- }
- /**
- * @brief GeneralInterface::setTouchScrollerForChildren 为父控件的所有子控件设置触摸滚动
- * @param parent 父控件
- * @param className 指定类名(可选)
- */
- void GeneralInterface::setTouchScrollerForChildren(QWidget *parent, const QString &className)
- {
- if (!parent) return;
-
- // 查找所有可滚动的子控件
- QList<QAbstractScrollArea*> scrollAreas = parent->findChildren<QAbstractScrollArea*>();
-
- foreach (QAbstractScrollArea* area, scrollAreas) {
- if (className.isEmpty() || area->metaObject()->className() == className) {
- setTouchScroller(area);
- }
- }
-
- // 查找所有ListWidget
- QList<QListWidget*> listWidgets = parent->findChildren<QListWidget*>();
- foreach (QListWidget* listWidget, listWidgets) {
- if (className.isEmpty() || listWidget->metaObject()->className() == className) {
- setTouchScroller(listWidget);
- }
- }
-
- // 查找所有TableWidget
- QList<QTableWidget*> tableWidgets = parent->findChildren<QTableWidget*>();
- foreach (QTableWidget* tableWidget, tableWidgets) {
- if (className.isEmpty() || tableWidget->metaObject()->className() == className) {
- setTouchScroller(tableWidget);
- }
- }
-
- // 查找所有TreeWidget
- QList<QTreeWidget*> treeWidgets = parent->findChildren<QTreeWidget*>();
- foreach (QTreeWidget* treeWidget, treeWidgets) {
- if (className.isEmpty() || treeWidget->metaObject()->className() == className) {
- setTouchScroller(treeWidget);
- }
- }
-
- // 查找所有TextEdit
- QList<QTextEdit*> textEdits = parent->findChildren<QTextEdit*>();
- foreach (QTextEdit* textEdit, textEdits) {
- if (className.isEmpty() || textEdit->metaObject()->className() == className) {
- setTouchScroller(textEdit);
- }
- }
- }
- /**
- * @brief GeneralInterface::getWindowTitle 获取窗口标题
- * @param type 窗口类型
- * @return 窗口标题
- */
- QString GeneralInterface::getWindowTitle(const int &type)
- {
- switch (type) {
- case FormItem::GENERAL: return QCoreApplication::translate("GeneralInterface", "General Log");
- case FormItem::OCPP16: return QCoreApplication::translate("GeneralInterface", "OCPP 1.6 Log");
- case FormItem::SLAVE: return QCoreApplication::translate("GeneralInterface", "Lower machine log");
- default: return QString("");
- }
- }
- /**
- * @brief GeneralInterface::getLogFilePath 获取日志文件路径
- * @param type 窗口类型
- * @return 日志文件路径
- */
- QString GeneralInterface::getLogFilePath(const int &type)
- {
- switch (type) {
- case FormItem::GENERAL: return ConfigManager::instance()->tcu_cfg().log_config.general_log_path;
- case FormItem::OCPP16: return ConfigManager::instance()->tcu_cfg().log_config.ocpp16_log_path;
- case FormItem::SLAVE: return ConfigManager::instance()->tcu_cfg().log_config.slave_log_path;
- default: return QString("");
- }
- }
- /**
- * @brief GeneralInterface::getStateDescriptions 获取状态描述
- * @param code 状态码
- * @return 状态描述
- */
- QString GeneralInterface::getStateDescriptions(uint32_t code)
- {
- switch (code) {
- case GUNSTATE_IDLE: return QCoreApplication::translate("GeneralInterface", "Stand By");
- case GUN_PLUGOUT: return QCoreApplication::translate("GeneralInterface", "Plug Out");
- case GUN_PLUGIN: return QCoreApplication::translate("GeneralInterface", "Plug In");
- case GUN_STARTUP: return QCoreApplication::translate("GeneralInterface", "Start Up");
- case GUN_ELOCKED: return QCoreApplication::translate("GeneralInterface", "Elocked");
- case GUN_AUTHORIZED: return QCoreApplication::translate("GeneralInterface", "Authorized");
- case GUN_PARAMETERS: return QCoreApplication::translate("GeneralInterface", "Parameters");
- case GUN_INSULATION: return QCoreApplication::translate("GeneralInterface", "Insulation");
- case GUN_PRECHARGE: return QCoreApplication::translate("GeneralInterface", "Precharge");
- case GUN_CHARGING: return QCoreApplication::translate("GeneralInterface", "Charging");
- case GUN_SUSPEND: return QCoreApplication::translate("GeneralInterface", "Suspend");
- case GUN_STOPING: return QCoreApplication::translate("GeneralInterface", "Stop");
- case GUN_UNKNOW: return QCoreApplication::translate("GeneralInterface", "Unknow");
- case GUN_UNAVAILABLE: return QCoreApplication::translate("GeneralInterface", "UnAvailable");
- case GUN_INOPERAVIVE: return QCoreApplication::translate("GeneralInterface", "Inoperative");
- case GUN_RESERVED: return QCoreApplication::translate("GeneralInterface", "Reserved");
- default: return QCoreApplication::translate("GeneralInterface", "NULL");
- }
- }
- /**
- * @brief GeneralInterface::getGuiState 根据表单类型和状态码获取GUI状态
- * @param form 表单类型
- * @param state 状态码
- * @return GUI状态
- */
- gui_state_enum GeneralInterface::getGuiState(const charge_prepare_enum &form, const int &state)
- {
- switch (form) {
- case PLUG_OUT: return CHARGE_GUN_AVAILABLE;
- case AUTHENTICATION: {
- if (state == 0) {
- int authState = getAuthShowType(ConfigManager::instance()->tcu_cfg().auth_type_enable.qr,
- ConfigManager::instance()->tcu_cfg().auth_type_enable.nfc,
- ConfigManager::instance()->tcu_cfg().auth_type_enable.pos);
- return getGuiStateAuthForm(authState);
- } else {
- return getGuiStateAuthForm(state);
- }
- }
- case CHARGE_PREPARE: return getGuiStatePrepareForm(state);
- case CHARGING_FORM: return getGuiStateChargingForm(state);
- case FINISH_FORM: return RETURN_GUN;
- case ERROR_FORM: return getGuiStateErrorForm();
- default: return UNKOWN_STATE;
- }
- }
- /**
- * @brief GeneralInterface::getGuiStateAuthForm 根据状态码获取授权表单的GUI状态
- * @param state 状态码
- * @return 授权表单的GUI状态
- */
- gui_state_enum GeneralInterface::getGuiStateAuthForm(const int &state)
- {
- switch (state) {
- case AuthType::QR: return AUTHORIZATION_QR;
- case AuthType::CARD: return AUTHORIZATION_ID_CARD;
- case AuthType::QR_OR_CARD: return AUTHORIZATION_QR_ID_CARD;
- case AuthType::NO_CARD: return WAITING_NO_ID_CARD;
- case AuthType::NO_QR_OR_CARD: return WAITING_NO_ID_CARD_QR;
- default: return UNKOWN_STATE;
- }
- }
- int GeneralInterface::getAuthShowType(const bool &qrEnable, const bool &cardEnable, const bool &posEnable)
- {
- if (qrEnable && !cardEnable && !posEnable) {
- return AuthType::QR;
- } else if (qrEnable && cardEnable && !posEnable) {
- return AuthType::QR_OR_CARD;
- } else if (!qrEnable && cardEnable && !posEnable) {
- return AuthType::CARD;
- } else if (!qrEnable && !cardEnable && posEnable) {
- return AuthType::POS;
- }
- return -1;
- }
- /**
- * @brief GeneralInterface::getGuiStatePrepareForm 根据状态码获取准备表单的GUI状态
- * @param state 状态码
- * @return 准备表单的GUI状态
- */
- gui_state_enum GeneralInterface::getGuiStatePrepareForm(const int &state)
- {
- switch (state) {
- case 0: return RETRY_OR_RETURN_GUN;
- case 1: return SCAN_QR_OR_RETURN_GUN;
- case 2: return CARD_AUTHORIZATION_FAILED;
- case 3: return CHANGE_CARD;
- case 4: return BALANCE_NO_START;
- case 6: return TOP_UP_RETRY;
- case 7: return PREPARE_HANDSHAKING;
- case 8: return HANDSHAKING;
- case 9: return CONFIGUING;
- case 10: return START_CHARGING;
- case 11: return UNPLUG_RETRY_OR_CHANGE;
- default: return UNKOWN_STATE;
- }
- }
- /**
- * @brief GeneralInterface::getGuiStateChargingForm 根据状态码获取充电表单的GUI状态
- * @param state 状态码
- * @return 充电表单的GUI状态
- */
- gui_state_enum GeneralInterface::getGuiStateChargingForm(const int &state)
- {
- switch (state) {
- case 0: return RETURN_GUN;
- default: return UNKOWN_STATE;
- }
- }
- /**
- * @brief GeneralInterface::getGuiStateFinishForm 根据状态码获取完成表单的GUI状态
- * @param state 状态码
- * @return 完成表单的GUI状态
- */
- gui_state_enum GeneralInterface::getGuiStateFinishForm(const int &state)
- {
- switch (state) {
- case 0: return RETURN_GUN;
- default: return UNKOWN_STATE;
- }
- }
- /**
- * @brief GeneralInterface::getGuiStateErrorForm 根据状态码获取错误表单的GUI状态
- * @param state 状态码
- * @return 错误表单的GUI状态
- */
- gui_state_enum GeneralInterface::getGuiStateErrorForm(const int &state)
- {
- switch (state) {
- case 0: return RETURN_GUN;
- case 1: return CHARGE_GUN_UNAVILABLE;
- case 2: return OUT_OF_SERVICE;
- case 3: return MAX_POWER_LIMIT;
- default: return UNKOWN_STATE;
- }
- }
- /**
- * @brief GeneralInterface::getChargeProgress 根据表单类型获取充电进度
- * @param form 表单类型
- * @return 充电进度
- */
- charge_progress_enum GeneralInterface::getChargeProgress(const charge_prepare_enum &form)
- {
- switch (form) {
- case PLUG_OUT: return PLUG_IN_PROGRESS;
- case CHARGING_FORM: return CHARGING_PROGRESS;
- case CHARGE_PREPARE: return AUTHORIZATION_PROGRESS;
- case AUTHENTICATION: return AUTHORIZATION_PROGRESS;
- case FINISH_FORM: return FINISHED_PROGRESS;
- default: return UNKNOWN_PROGRESS;
- }
- }
- /**
- * @brief GeneralInterface::getChangedGunID 根据枪ID获取另一把枪的ID
- * @param gun_id 枪ID
- * @return 另一把枪的ID
- */
- int GeneralInterface::getChangedGunID(const int &gun_id)
- {
- switch (gun_id) {
- case CHARGE_GUN_DEFAULT_1: return CHARGE_GUN_DEFAULT_2;
- case CHARGE_GUN_DEFAULT_2: return CHARGE_GUN_DEFAULT_1;
- default: return 0;
- }
- }
- /**
- * @brief GeneralInterface::getMaxHeight 获取widget的最大高度
- * @param widget
- * @return widget的最大高度
- */
- int GeneralInterface::getMaxHeight(QWidget *widget)
- {
- if (!widget) return 0;
- // 获取widget在全局的底部y坐标
- QPoint globalBottomLeft = widget->mapToGlobal(QPoint(0, widget->height()));
- #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
- // Qt5.10及以上推荐用QScreen
- QScreen *screen = widget->screen();
- if (!screen) screen = QApplication::primaryScreen();
- QRect available = screen->availableGeometry();
- #else
- // Qt5.9及以下用QDesktopWidget
- QRect available = QApplication::desktop()->availableGeometry(widget);
- #endif
- int maxHeight = available.bottom() - globalBottomLeft.y();
- return maxHeight > 0 ? maxHeight : 0;
- }
- /**
- * @brief GeneralInterface::initTimezoneComboBox 初始化时区下拉框
- * @param combox
- */
- void GeneralInterface::initTimezoneComboBox(CustomComboBox *combox)
- {
- QStringList timezone_list;
- timezone_list << "Asia/Shanghai"
- << "Asia/Tokyo"
- << "Asia/Seoul"
- << "Asia/Kolkata"
- << "Asia/Singapore"
- << "Asia/Bangkok"
- << "Asia/Kuala_Lumpur"
- << "Europe/London"
- << "Europe/Berlin"
- << "Europe/Paris"
- << "Europe/Rome"
- << "Europe/Madrid"
- << "Europe/Moscow"
- << "America/New_York"
- << "America/Los_Angeles"
- << "America/Toronto"
- << "America/Sao_Paulo"
- << "America/Mexico_City";
- combox->addItems(timezone_list);
- }
- /**
- * @brief GeneralInterface::initLanguageComboBox 初始化语言下拉框
- * @param combox
- */
- void GeneralInterface::initLanguageComboBox(CustomComboBox *combox)
- {
- QStringList timezone_list;
- timezone_list << "Chinese (Simplified)"
- << "English (US)";
- combox->addItems(timezone_list);
- }
- void GeneralInterface::initCurrencySymbolMap()
- {
- QMap<QString, QString> currencySymbol;
- currencySymbol.insert("USD", "$");
- currencySymbol.insert("EUR", "€");
- currencySymbol.insert("GBP", "£");
- currencySymbol.insert("JPY", "¥");
- currencySymbol.insert("CNY", "¥");
- currencySymbol.insert("AUD", "A$");
- currencySymbol.insert("CAD", "C$");
- currencySymbol.insert("CHF", "Fr");
- currencySymbol.insert("HKD", "HK$");
- currencySymbol.insert("SGD", "S$");
- currencySymbol.insert("INR", "₹");
- currencySymbol.insert("BRL", "R$");
- currencySymbol.insert("RUB", "₽");
- currencySymbol.insert("KRW", "₩");
- currencySymbol.insert("MXN", "Mex$");
- currencySymbol.insert("NZD", "NZ$");
- currencySymbol.insert("SEK", "kr");
- currencySymbol.insert("DKK", "kr");
- currencySymbol.insert("NOK", "kr");
- currencySymbol.insert("SAR", "﷼");
- currencySymbol.insert("AED", "د.إ");
- currencySymbol.insert("ZAR", "R");
- currencySymbol.insert("TRY", "₺");
- currencySymbol.insert("CHF", "Fr");
- GLOBALS->setValue(Global::Keys::CURRENCY_SYMBOL_MAP, QVariant::fromValue(currencySymbol));
- }
- QString GeneralInterface::getCurrencySymbol(const QString &str)
- {
- auto map = GLOBALS->getValue(Global::Keys::CURRENCY_SYMBOL_MAP).value<QMap<QString, QString>>();
- return QString("%1(%2)").arg(str, map.value(str));
- }
- QString GeneralInterface::getCurrencySymbol(CustomComboBox *combox)
- {
- auto str = combox->currentText();
- auto list = str.split('(');
- return list[0];
- }
- void GeneralInterface::initCurrencySymbolComboBox(CustomComboBox *combox)
- {
- QStringList currencySymbol;
- auto map = GLOBALS->getValue(Global::Keys::CURRENCY_SYMBOL_MAP).value<QMap<QString, QString>>();
- foreach (const auto& key, map.keys()) {
- currencySymbol.append(QString("%1(%2)").arg(key, map.value(key)));
- }
- combox->addItems(currencySymbol);
- }
- /**
- * @brief GeneralInterface::clearGridLayoutChiledren 清空QGridLayout的子控件
- * @param layout
- */
- void GeneralInterface::clearGridLayoutChiledren(QGridLayout *layout)
- {
- if (!layout) return;
- // 删除所有子控件(widget)
- while (QLayoutItem* item = layout->takeAt(0)) {
- if (QWidget* widget = item->widget()) {
- layout->removeWidget(widget);
- widget->deleteLater(); // 安全删除 widget
- } else if (QLayout* childLayout = item->layout()) {
- clearGridLayoutChiledren(qobject_cast<QGridLayout*>(childLayout)); // 递归删除子 layout
- }
- layout->removeItem(item);
- delete item; // 删除 QLayoutItem 本身
- }
- for(int row = 0; row < layout->rowCount(); row ++) {
- layout->setRowStretch(row, 0);
- }
- layout->update();
- }
- /**
- * @brief GeneralInterface::gridLayoutAddWidget 向QGridLayout中添加控件
- * @param layout
- * @param widget
- */
- void GeneralInterface::gridLayoutAddWidget(QGridLayout *layout, QWidget *widget, int row, int col)
- {
- if (row == -1) row = layout->rowCount();
- layout->addWidget(widget, row, col);
- layout->setRowStretch(row, col);
- }
- /**
- * @brief GeneralInterface::gridLayoutAddStrtch 向QGridLayout中添加弹簧
- * @param layout
- */
- void GeneralInterface::gridLayoutAddStrtch(QGridLayout *layout)
- {
- int row = layout->rowCount();
- // 在最后一行添加弹簧(spacer),让控件靠上
- QSpacerItem* vSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
- layout->addItem(vSpacer, row, 0, 1, layout->columnCount());
- layout->setRowStretch(row, 1);
- }
- /**
- * @brief GeneralInterface::getChargingProfilePurposeIndex 根据充电配置目的获取索引
- * @param purpose 充电配置目的
- * @return
- */
- int GeneralInterface::getChargingProfilePurposeIndex(const QString &purpose)
- {
- if (purpose == ChargingProfiles::Purpose::CHARGE_POINT_MAX_PROFILE) {
- return Workspace::Settings::Ocpp::ChargingProfiles::CHARGE_POINT_MAX_PROFILE;
- } else if (purpose == ChargingProfiles::Purpose::TX_DEFAULT_PROFILE) {
- return Workspace::Settings::Ocpp::ChargingProfiles::TX_DEFAULT_PROFILE;
- } else if (purpose == ChargingProfiles::Purpose::TX_PROFILE) {
- return Workspace::Settings::Ocpp::ChargingProfiles::TX_PROFILE;
- }
- return 0;
- }
- /**
- * @brief GeneralInterface::getChargingProfileByPurpose 根据充电配置目的获取充电配置
- * @param data
- * @param dataList
- * @param purpose
- * @return
- */
- bool GeneralInterface::getChargingProfileByPurpose(charging_profiles_detail_info_t &data, const QList<charging_profiles_detail_info_t>& dataList, const QString &purpose)
- {
- QMap<QString, QPair<int, charging_profiles_detail_info_t>> stats;
- for (const auto& item : std::as_const(dataList)) {
- if (stats.contains(item.chargingProfilePurpose)) {
- auto& tempData = stats[item.chargingProfilePurpose];
- tempData.first++;
- if (tempData.second.stackLevel < item.stackLevel) {
- tempData.second = item;
- }
- } else {
- stats.insert(item.chargingProfilePurpose, {1, item});
- }
- }
- if (stats.contains(purpose)) {
- data = stats.value(purpose).second;
- }
- return stats.contains(purpose);
- }
- /**
- * @brief GeneralInterface::chargingProfileToMap 充电配置转map
- * @param dataList
- * @return
- */
- QVARIANTMAP_INT_MAP GeneralInterface::chargingProfileToMap(const QList<charging_profiles_detail_info_t> &dataList)
- {
- QVARIANTMAP_INT_MAP result;
- if (dataList.isEmpty()) return result;
- result = chargingProfileToMapByConnectorId(dataList);
- return result;
- }
- /**
- * @brief GeneralInterface::chargingProfileMapToList map转充电配置
- * @param dataMap
- * @return
- */
- QList<charging_profiles_detail_info_t> GeneralInterface::chargingProfileMapToList(const QMap<int, QVariant> &dataMap)
- {
- QList<charging_profiles_detail_info_t> result;
- if (dataMap.isEmpty()) return result;
- result = chargingProfileMapToListByConnectorId(dataMap);
- return result;
- }
- /**
- * @brief GeneralInterface::chargingProfileToMapByConnectorId 根据充电配置ID转map
- * @param dataList
- * @return
- */
- QMap<int, QVariant> GeneralInterface::chargingProfileToMapByConnectorId(const QList<charging_profiles_detail_info_t> &dataList)
- {
- QMap<int, QVariant> result;
- foreach (const auto& data, dataList) {
- auto map = chargingProfileToMapByPurpose(dataList,
- data.connectorId);
- result.insert(data.connectorId, QVariant::fromValue(map));
- }
- return result;
- }
- /**
- * @brief GeneralInterface::chargingProfileMapToListByConnectorId map转充电配置ID
- * @param dataMap
- * @return
- */
- QList<charging_profiles_detail_info_t> GeneralInterface::chargingProfileMapToListByConnectorId(const QMap<int, QVariant> &dataMap)
- {
- QList<charging_profiles_detail_info_t> result;
- foreach (const auto& data, dataMap) {
- result.append(chargingProfileMapToListByPurpose(data.value<QMap<QString, QVariant>>(), dataMap.key(data)));
- }
- return result;
- }
- /**
- * @brief GeneralInterface::chargingProfileToMapByPurpose 根据充电配置目的转map
- * @param dataList
- * @param connectorId 充电配置ID
- * @return
- */
- QMap<QString, QVariant> GeneralInterface::chargingProfileToMapByPurpose(const QList<charging_profiles_detail_info_t> &dataList,
- const int &connectorId)
- {
- QMap<QString, QVariant> result;
- foreach (const auto& data, dataList) {
- if (data.connectorId == connectorId) {
- auto map = chargingProfileToMapByKind(dataList,
- data.connectorId,
- data.chargingProfilePurpose);
- result.insert(data.chargingProfilePurpose, QVariant::fromValue(map));
- }
- }
- return result;
- }
- /**
- * @brief GeneralInterface::chargingProfileMapToListByPurpose map转充电配置目的
- * @param dataMap
- * @param connectorId
- * @return
- */
- QList<charging_profiles_detail_info_t> GeneralInterface::chargingProfileMapToListByPurpose(const QMap<QString, QVariant> &dataMap,
- const int &connectorId)
- {
- QList<charging_profiles_detail_info_t> result;
- foreach (const auto& data, dataMap) {
- result.append(chargingProfileMapToListByKind(data.value<QMap<QString, QVariant>>(),
- connectorId,
- dataMap.key(data)));
- }
- return result;
- }
- /**
- * @brief GeneralInterface::chargingProfileToMapByKind 根据充电配置类型转map
- * @param dataList
- * @param connectorId
- * @param purpose
- * @return
- */
- QMap<QString, QVariant> GeneralInterface::chargingProfileToMapByKind(const QList<charging_profiles_detail_info_t> &dataList,
- const int &connectorId,
- const QString &purpose)
- {
- QMap<QString, QVariant> result;
- foreach (const auto& data, dataList) {
- if (data.connectorId == connectorId &&
- data.chargingProfilePurpose == purpose) {
- auto map = chargingProfileToMapByRecurrencyKind(dataList,
- data.connectorId,
- data.chargingProfilePurpose,
- data.chargingProfileKind);
- result.insert(data.chargingProfileKind, QVariant::fromValue(map));
- }
- }
- return result;
- }
- /**
- * @brief GeneralInterface::chargingProfileMapToListByKind map转充电配置类型
- * @param dataMap
- * @param connectorId
- * @param purpose
- * @return
- */
- QList<charging_profiles_detail_info_t> GeneralInterface::chargingProfileMapToListByKind(const QMap<QString, QVariant> &dataMap,
- const int &connectorId,
- const QString &purpose)
- {
- QList<charging_profiles_detail_info_t> result;
- foreach (const auto& data, dataMap) {
- result.append(chargingProfileMapToListRecurrencyKind(data.value<QMap<QString, QVariant>>(),
- connectorId,
- purpose,
- dataMap.key(data)));
- }
- return result;
- }
- /**
- * @brief GeneralInterface::chargingProfileToMapByRecurrencyKind 根据充电配置周期转map
- * @param dataList
- * @param connectorId
- * @param purpose
- * @param kind
- * @return
- */
- QMap<QString, QVariant> GeneralInterface::chargingProfileToMapByRecurrencyKind(const QList<charging_profiles_detail_info_t> &dataList,
- const int &connectorId,
- const QString &purpose,
- const QString &kind)
- {
- QMap<QString, QVariant> result;
- foreach (const auto& data, dataList) {
- if (data.connectorId == connectorId &&
- data.chargingProfilePurpose == purpose &&
- data.chargingProfileKind == kind) {
- auto variantList = chargingProfileToMapByRecurrencyKind(dataList,
- data.connectorId,
- data.chargingProfilePurpose,
- data.chargingProfileKind,
- data.recurrencyKind);
- result.insert(data.recurrencyKind, QVariant::fromValue(variantList));
- }
- }
- return result;
- }
- /**
- * @brief GeneralInterface::chargingProfileMapToListRecurrencyKind map转充电配置周期
- * @param dataMap
- * @param connectorId
- * @param purpose
- * @param kind
- * @return
- */
- QList<charging_profiles_detail_info_t> GeneralInterface::chargingProfileMapToListRecurrencyKind(const QMap<QString, QVariant> &dataMap,
- const int &connectorId,
- const QString &purpose,
- const QString &kind)
- {
- QList<charging_profiles_detail_info_t> result;
- foreach (const auto& data, dataMap) {
- result.append(chargingProfileMapToListRecurrencyKind(data.value<QMap<int, QVariant>>(),
- connectorId,
- purpose,
- kind,
- dataMap.key(data)));
- }
- return result;
- }
- /**
- * @brief GeneralInterface::chargingProfileToMapByRecurrencyKind 根据充电配置栈级转map
- * @param dataList
- * @param connectorId
- * @param purpose
- * @param kind
- * @param recurrencyKind
- * @return
- */
- QMap<int, QVariant> GeneralInterface::chargingProfileToMapByRecurrencyKind(const QList<charging_profiles_detail_info_t> &dataList,
- const int &connectorId,
- const QString &purpose,
- const QString &kind,
- const QString &recurrencyKind)
- {
- QMap<int, QVariant> result;
- foreach (const auto& data, dataList) {
- if (data.connectorId == connectorId &&
- data.chargingProfilePurpose == purpose &&
- data.chargingProfileKind == kind &&
- data.recurrencyKind == recurrencyKind) {
- auto map = chargingProfileToMapByStackLevel(dataList,
- data.connectorId,
- data.chargingProfilePurpose,
- data.chargingProfileKind,
- data.recurrencyKind,
- data.stackLevel);
- result.insert(data.stackLevel, QVariant::fromValue(map));
- }
- }
- return result;
- }
- /**
- * @brief GeneralInterface::chargingProfileMapToListRecurrencyKind map转充电配置栈级
- * @param dataMap
- * @param connectorId
- * @param purpose
- * @param kind
- * @param recurrencyKind
- * @return
- */
- QList<charging_profiles_detail_info_t> GeneralInterface::chargingProfileMapToListRecurrencyKind(const QMap<int, QVariant> &dataMap,
- const int &connectorId,
- const QString &purpose,
- const QString &kind,
- const QString &recurrencyKind)
- {
- QList<charging_profiles_detail_info_t> result;
- foreach (const auto& data, dataMap) {
- result.append(chargingProfileMapToListByStackLevel(data.value<QVariantList>(),
- connectorId,
- purpose,
- kind,
- recurrencyKind,
- dataMap.key(data)));
- }
- return result;
- }
- /**
- * @brief GeneralInterface::chargingProfileToMapByStackLevel 根据充电配置栈级转map
- * @param dataList
- * @param connectorId
- * @param purpose
- * @param kind
- * @param recurrencyKind
- * @param stackLevel
- * @return
- */
- QVariantList GeneralInterface::chargingProfileToMapByStackLevel(const QList<charging_profiles_detail_info_t> &dataList, const int &connectorId, const QString &purpose, const QString &kind, const QString &recurrencyKind, const int &stackLevel)
- {
- QVariantList result;
- foreach (const auto& data, dataList) {
- if (data.connectorId == connectorId &&
- data.chargingProfilePurpose == purpose &&
- data.chargingProfileKind == kind &&
- data.recurrencyKind == recurrencyKind &&
- data.stackLevel == stackLevel) {
- result.append(QVariant::fromValue(data));
- }
- }
- return result;
- }
- /**
- * @brief GeneralInterface::chargingProfileMapToListByStackLevel map转充电配置栈级
- * @param dataMap
- * @param connectorId
- * @param purpose
- * @param kind
- * @param recurrencyKind
- * @param stackLevel
- * @return
- */
- QList<charging_profiles_detail_info_t> GeneralInterface::chargingProfileMapToListByStackLevel(const QVariantList &dataMap, const int &connectorId, const QString &purpose, const QString &kind, const QString &recurrencyKind, const int &stackLevel)
- {
- QList<charging_profiles_detail_info_t> result;
- foreach (const auto& data, dataMap) {
- if (data.value<charging_profiles_detail_info_t>().connectorId == connectorId &&
- data.value<charging_profiles_detail_info_t>().stackLevel == stackLevel &&
- data.value<charging_profiles_detail_info_t>().chargingProfilePurpose == purpose &&
- data.value<charging_profiles_detail_info_t>().chargingProfileKind == kind &&
- data.value<charging_profiles_detail_info_t>().recurrencyKind == recurrencyKind) {
- result.append(data.value<charging_profiles_detail_info_t>());
- }
- }
- return result;
- }
- /**
- * @brief GeneralInterface::getMaxElecment 获取最大值
- * @param list
- * @return list为空返回-1,否则返回最大值
- */
- int GeneralInterface::getMaxElecment(const QList<int> &list)
- {
- int result = -1;
- if (list.isEmpty()) return result;
- for (const auto& num : list) {
- if (num > result) result = num;
- }
- return result;
- }
- uint32_t GeneralInterface::getMaxElecment(const QList<uint32_t> &list)
- {
- uint32_t result = 0;
- if (list.isEmpty()) return result;
- for (const auto& num : list) {
- if (num > result) result = num;
- }
- return result;
- }
- uint32_t GeneralInterface::getMaxErrorCode(const ERROR_NOTE_LIST &info)
- {
- QList<uint32_t> error_code_list;
- foreach (const auto& data, info) {
- error_code_list.append(data.error_code);
- }
- return getMaxElecment(error_code_list);
- }
- /**
- * @brief GeneralInterface::getCurrentDate 获取当前时间
- * @param seconds 秒数
- * @return 返回"HH:mm:ss"的字符串
- */
- QString GeneralInterface::getCurrentDate(const int &seconds)
- {
- QDate date = QDate::currentDate();
- QTime time = QTime(0, 0, 0).addSecs(seconds);
- QDateTime dt(date, time);
- return dt.toString("HH:mm:ss");
- }
- /**
- * @brief GeneralInterface::getCurrentDate 获取当前时间
- * @param time 时间字符串
- * @return 返回秒数
- */
- int GeneralInterface::getCurrentDate(const QString &time)
- {
- QTime dt = QTime::fromString(time, "HH:mm:ss");
- return QTime(0, 0, 0).secsTo(dt);
- }
- /**
- * @brief GeneralInterface::getCurrentDateOfWeek 获取当前周时间
- * @param startTime 开始时间
- * @param seconds 秒数
- * @return 返回"HH:mm:ss"的字符串
- */
- QString GeneralInterface::getCurrentDateOfWeek(const QString &startTime, const int &seconds)
- {
- QDateTime dt = QDateTime::fromString(startTime, Qt::ISODate);
- dt.setTimeSpec(Qt::UTC);
- dt = dt.addSecs(seconds);
- return dt.toString("HH:mm:ss");
- }
- /**
- * @brief GeneralInterface::getCurrentDateSecondOfWeek 获取当前周时间
- * @param startTime 开始时间
- * @param seconds 秒数
- * @return 返回秒数
- */
- int GeneralInterface::getCurrentDateSecondOfWeek(const QString &startTime, const int &seconds)
- {
- // 1. 解析开始时间
- QDateTime startDt = QDateTime::fromString(startTime, Qt::ISODate);
- startDt.setTimeSpec(Qt::UTC);
- // 2. 计算目标时间
- QDateTime targetDt = startDt.addSecs(seconds);
- // 3. 获取当天00:00:00到目标时间的秒数
- int secondsOfDay = QTime(0, 0, 0).secsTo(targetDt.time());
- return secondsOfDay;
- }
- /**
- * @brief GeneralInterface::getCurrentDateOfWeek 获取当前周时间
- * @param startTime 开始时间
- * @param seconds 秒数
- * @param dayOfWeek 周几
- * @return 返回秒数
- */
- int GeneralInterface::getCurrentDateOfWeek(const QString &startTime, const int &seconds, const int &dayOfWeek)
- {
- // 1. 解析开始时间
- QDateTime startDt = QDateTime::fromString(startTime, Qt::ISODate);
- startDt.setTimeSpec(Qt::UTC);
- // 2. 获取开始时间所在周的周一
- QDate startDate = startDt.date();
- int startDayOfWeek = startDate.dayOfWeek(); // 1=周一
- QDate monday = startDate.addDays(1 - startDayOfWeek);
- // 3. 目标日期 = 本周的 dayOfWeek
- QDate targetDate = monday.addDays(dayOfWeek - 1);
- // 4. 用秒数构造 QTime
- QTime targetTime = QTime(0, 0, 0).addSecs(seconds);
- // 5. 构造目标 QDateTime
- QDateTime targetDt(targetDate, targetTime, Qt::UTC);
- // 6. 计算秒数差
- qint64 secondsDiff = startDt.secsTo(targetDt);
- return static_cast<int>(secondsDiff);
- }
- /**
- * @brief GeneralInterface::getCurrentDateOfWeek 获取当前周时间
- * @param startTime 开始时间
- * @param time 时间字符串
- * @param dayOfWeek 周几
- * @return
- */
- int GeneralInterface::getCurrentDateOfWeek(const QString &startTime, const QString &time, const int& dayOfWeek)
- {
- // 1. 解析开始时间
- QDateTime startDt = QDateTime::fromString(startTime, Qt::ISODate);
- startDt.setTimeSpec(Qt::UTC); // 若有Z,确保为UTC
- // 2. 获取开始时间所在周的周一
- QDate startDate = startDt.date();
- int startDayOfWeek = startDate.dayOfWeek(); // 1=周一
- QDate monday = startDate.addDays(1 - startDayOfWeek);
- // 3. 目标日期 = 本周的 dayOfWeek
- QDate targetDate = monday.addDays(dayOfWeek - 1);
- // 4. 解析当天时间
- QTime targetTime = QTime::fromString(time, "HH:mm:ss");
- // 5. 构造目标 QDateTime
- QDateTime targetDt(targetDate, targetTime, Qt::UTC);
- // 6. 计算秒数差
- qint64 secondsDiff = startDt.secsTo(targetDt);
- return static_cast<int>(secondsDiff);
- }
- /**
- * @brief GeneralInterface::getDayOfWeek 获取当前周几
- * @param time 时间字符串
- * @return 1=周一、2=周二、3=周三、4=周四、5=周五、6=周六、7=周日
- */
- int GeneralInterface::getDayOfWeek(const QString &time)
- {
- QDateTime dt = QDateTime::fromString(time, Qt::ISODate);
- dt.setTimeSpec(Qt::UTC); // 明确为UTC时间
- QDate date = dt.date();
- return date.dayOfWeek();
- }
- /**
- * @brief GeneralInterface::sortByStartPeriod 按开始时间排序
- * @param list
- */
- void GeneralInterface::sortByStartPeriod(QList<charging_schedule_period_info_t> &list)
- {
- std::sort(list.begin(), list.end(), [](const charging_schedule_period_info_t &a, const charging_schedule_period_info_t &b) {
- return a.startPeriod < b.startPeriod;
- });
- }
- /**
- * @brief GeneralInterface::sortByStackLevel 按优先级排序
- * @param list
- */
- void GeneralInterface::sortByStackLevel(QList<charging_profiles_detail_info_t> &list)
- {
- std::sort(list.begin(), list.end(), [](const charging_profiles_detail_info_t &a, const charging_profiles_detail_info_t &b) {
- return a.stackLevel > b.stackLevel;
- });
- }
- /**
- * @brief GeneralInterface::getMaxChargingProfileId 获取最大充电配置ID
- * @param list
- * @return list为空返回-1,否则返回最大值
- */
- int GeneralInterface::getMaxChargingProfileId(QList<charging_profiles_detail_info_t> &list)
- {
- QList<int> chargingProfileIdList;
- foreach (const auto& data, list) {
- chargingProfileIdList.append(data.chargingProfileId);
- }
- return getMaxElecment(chargingProfileIdList);
- }
- /**
- * @brief GeneralInterface::getVersion 获取版本号
- * @param appName
- * @return
- * HW_NAME: 硬件版本号
- * CCU_NAME: CCU版本号
- * TCU_NAME: TCU版本号
- * PCU_NAME: PCU版本号
- */
- QString GeneralInterface::getVersion(const QString &appName)
- {
- QString version;
- if (appName == AppName::HW_NAME) {
- version = VersionManager::getHardwareVersion();
- } else if (appName == AppName::CCU_NAME ||
- appName == AppName::TCU_NAME ||
- appName == AppName::PCU_NAME) {
- AppVersionInfo info = VersionManager::getAppVersion(appName);
- if (info.success) {
- version = QString("V%1.%2.%3").arg(info.major).arg(info.minor).arg(info.build);
- }
- }
- return version;
- }
- static char app_version[128] = {0};
- static const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
- char *GeneralInterface::formatAppVersion()
- {
- int i;
- int month = 0, mday, year, hour, min, sec;
- #define ASCII_CODE(x) ((x)==32? 0:((x)-'0'))
- mday = ASCII_CODE(__DATE__[4])*10 + ASCII_CODE(__DATE__[5]);
- year = ASCII_CODE(__DATE__[7])*1000 + ASCII_CODE(__DATE__[8])*100 + ASCII_CODE(__DATE__[9])*10 + ASCII_CODE(__DATE__[10]);
- hour = ASCII_CODE(__TIME__[0])*10 + ASCII_CODE(__TIME__[1]);
- min = ASCII_CODE(__TIME__[3])*10 + ASCII_CODE(__TIME__[4]);
- sec = ASCII_CODE(__TIME__[6])*10 + ASCII_CODE(__TIME__[7]);
- #undef ASCII_CODE
- for (i = 0; i < 12; i++)
- {
- if (strncmp(__DATE__, months[i], 3)==0)
- {
- month = i + 1;
- break;
- }
- }
- snprintf(app_version, 128, "app_TCU_V1R0B%04d%02d%02d %02d:%02d:%02d", year, month, mday, hour, min, sec);
- return app_version;
- }
- void GeneralInterface::initGlobals()
- {
- // 初始化充电枪基本信息
- for (int i = CHARGE_GUN_DEFAULT_1; i <= CHARGE_GUN_DEFAULT_2; i++) {
- BASIC_INFO basic_info;
- GLOBALS->setValue(i == CHARGE_GUN_DEFAULT_1 ? Global::Keys::GUN_BASIC_INFO_1 : Global::Keys::GUN_BASIC_INFO_2,
- QVariant::fromValue(basic_info));
- CHARGING_INFO charging_info;
- GLOBALS->setValue(i == CHARGE_GUN_DEFAULT_1 ? Global::Keys::CHARGING_INFO_1 : Global::Keys::CHARGING_INFO_2,
- QVariant::fromValue(charging_info));
- UINT32_QSTRING_MAP gun_error;
- GLOBALS->setValue(i == CHARGE_GUN_DEFAULT_1 ? Global::Keys::GUN_ERROR_1 : Global::Keys::GUN_ERROR_2,
- QVariant::fromValue(gun_error));
- UINT32_QSTRING_MAP gun_state;
- GLOBALS->setValue(i == CHARGE_GUN_DEFAULT_1 ? Global::Keys::GUN_STATE_1 : Global::Keys::GUN_STATE_2,
- QVariant::fromValue(gun_state));
- UINT8_QSTRING_MAP gun_type;
- GLOBALS->setValue(i == CHARGE_GUN_DEFAULT_1 ? Global::Keys::GUN_TYPE_1 : Global::Keys::GUN_TYPE_2,
- QVariant::fromValue(gun_type));
- }
- // 初始化其他全局变量
- GLOBALS->setValue(Global::Keys::AUTH_LIST, QVariant::fromValue(AUTH_LIST()));
- GLOBALS->setValue(Global::Keys::CCU_CFG, QVariant::fromValue(CCU_CFG()));
- GLOBALS->setValue(Global::Keys::CHARGING_PROFILES, QVariant::fromValue(CHARGING_PROFILES()));
- GLOBALS->setValue(Global::Keys::CHARGING_PROFILES_MAP, QVariant::fromValue(QVARIANTMAP_INT_MAP()));
- GLOBALS->setValue(Global::Keys::CFG_KEY, QVariant::fromValue(CONFIG_KEY_INFO()));
- GLOBALS->setValue(Global::Keys::OFFLINE_CHARGING_RECORDS, QVariant::fromValue(CHARGING_RECORDS_INFO()));
- GLOBALS->setValue(Global::Keys::TCU_CFG, QVariant::fromValue(TCU_CFG()));
- GLOBALS->setValue(Global::Keys::PCU_CFG, QVariant::fromValue(PCU_CFG()));
- GLOBALS->setValue(Global::Keys::PRICEINFO, QVariant::fromValue(PRICE_INFO()));
- VERSION version_info;
- version_info.ccu_version = GeneralInterface::getVersion(AppName::CCU_NAME);
- version_info.tcu_version = GeneralInterface::getVersion(AppName::TCU_NAME);
- version_info.pcu_version = GeneralInterface::getVersion(AppName::PCU_NAME);
- version_info.hw_version = GeneralInterface::getVersion(AppName::HW_NAME);
- GLOBALS->setValue(Global::Keys::VERSION, QVariant::fromValue(version_info));
- }
- int GeneralInterface::readLoadStyleFile(const QString &filapath)
- {
- QString styleSheetPath = filapath;
- // 检查资源文件是否存在
- QFile file;
- file.setFileName(styleSheetPath);
- if (!file.exists()) {
- LOG_ERROR(QString("Style file not found: %1").arg(styleSheetPath));
- return INIT_GUI_STYLE_LOAD_ERROR;
- }
- // 安全打开文件
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- LOG_ERROR(QString("Failed to open style file: %1, error: %2").arg(
- styleSheetPath, file.errorString()));
- return INIT_GUI_STYLE_LOAD_ERROR;
- }
- // 安全读取文件内容
- QByteArray content;
- try {
- // 设置文件读取缓冲区大小限制,防止大文件导致内存问题
- const qint64 maxSize = 2 * 1024 * 1024; // 2MB
- // 先检查文件大小
- qint64 fileSize = file.size();
- if (fileSize > maxSize) {
- LOG_WARNING(QString("Style file is large: %1 bytes, will limit to %2 bytes").arg(
- fileSize, maxSize));
- }
- // 读取文件内容
- content = file.read(maxSize);
- if (content.isEmpty() && !file.atEnd()) {
- LOG_ERROR("Failed to read style file content");
- file.close();
- return INIT_GUI_STYLE_LOAD_ERROR;
- }
- // 确保文件正确关闭
- file.close();
- // 检查内容是否有效
- if (content.isEmpty()) {
- LOG_WARNING("Style file is empty, skipping");
- return INIT_OK; // 允许程序继续运行
- }
- // 安全地设置样式表
- QString styleSheet = QString::fromUtf8(content);
- // 验证样式表语法是否有效(简单检查)
- if (styleSheet.count('{') != styleSheet.count('}')) {
- LOG_WARNING("Style sheet may have syntax errors, mismatched braces");
- }
- // 应用样式表 - 确保qApp有效
- if (qApp) {
- qApp->setStyleSheet(styleSheet);
- LOG_INFO("Style sheet loaded successfully");
- } else {
- LOG_ERROR("QApplication instance not available when setting style sheet");
- return INIT_GUI_STYLE_LOAD_ERROR;
- }
- } catch (const std::exception& e) {
- // 捕获可能的异常
- LOG_ERROR(QString("Exception while loading style sheet: %1").arg(e.what()));
- file.close();
- return INIT_GUI_STYLE_LOAD_ERROR;
- } catch (...) {
- LOG_ERROR("Unknown exception while loading style sheet");
- file.close();
- return INIT_GUI_STYLE_LOAD_ERROR;
- }
- return INIT_OK;
- }
- // ==================== 二维码生成相关方法 ====================
- /**
- * @brief 使用 libqrencode 生成二维码
- * @param text 要编码的文本内容(通常是URL)
- * @param size 二维码图片的尺寸(像素)
- * @param margin 二维码边距(模块数)
- * @param errorCorrectionLevel 错误纠正级别 (L=7%, M=15%, Q=25%, H=30%)
- * @return 生成的二维码图片,失败时返回空图片
- */
- QPixmap GeneralInterface::generateQRCode(const QString& text, int size, int margin, char errorCorrectionLevel)
- {
- if (text.isEmpty()) {
- return QPixmap();
- }
- // 将 QString 转换为 UTF-8 字节数组
- QByteArray textData = text.toUtf8();
-
- // 设置错误纠正级别
- QRecLevel level = QR_ECLEVEL_M; // 默认使用 M 级别
- switch (errorCorrectionLevel) {
- case 'L': level = QR_ECLEVEL_L; break;
- case 'M': level = QR_ECLEVEL_M; break;
- case 'Q': level = QR_ECLEVEL_Q; break;
- case 'H': level = QR_ECLEVEL_H; break;
- default: level = QR_ECLEVEL_M; break;
- }
- // 生成二维码数据
- QRcode* qrcode = QRcode_encodeString(textData.constData(), 0, level, QR_MODE_8, 1);
- if (!qrcode) {
- return QPixmap();
- }
- // 计算实际尺寸(包含边距)
- int qrSize = qrcode->width;
- int totalSize = qrSize + 2 * margin;
-
- // 创建图像
- QImage image(totalSize, totalSize, QImage::Format_ARGB32);
- image.fill(Qt::white);
- // 绘制二维码
- QPainter painter(&image);
- painter.setPen(Qt::black);
- painter.setBrush(Qt::black);
- // 计算每个模块的像素大小
- int moduleSize = size / totalSize;
- if (moduleSize < 1) moduleSize = 1;
- // 绘制二维码模块
- for (int y = 0; y < qrSize; y++) {
- for (int x = 0; x < qrSize; x++) {
- if (qrcode->data[y * qrSize + x] & 1) {
- int pixelX = (x + margin) * moduleSize;
- int pixelY = (y + margin) * moduleSize;
- painter.fillRect(pixelX, pixelY, moduleSize, moduleSize, Qt::black);
- }
- }
- }
- // 释放二维码数据
- QRcode_free(qrcode);
- // 转换为 QPixmap
- QPixmap pixmap = QPixmap::fromImage(image);
-
- // 如果指定尺寸与计算尺寸不同,进行缩放
- if (pixmap.width() != size) {
- pixmap = pixmap.scaled(size, size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
- }
- return pixmap;
- }
- QPixmap GeneralInterface::generateQRCodeDefault(const QString &text, int size)
- {
- QRcode *qr = QRcode_encodeString(text.toUtf8().constData(), 0, QR_ECLEVEL_L, QR_MODE_8, 1);
- if (!qr) return QPixmap();
- // 计算缩放比例(二维码实际大小可能小于请求的 size)
- int qrSize = qr->width > 0 ? qr->width : 1;
- int scale = size / qrSize;
- if (scale < 1) scale = 1;
- // 创建 QImage 并绘制二维码
- QImage image(qrSize * scale, qrSize * scale, QImage::Format_ARGB32);
- image.fill(QColor(Qt::transparent));
- QPainter painter(&image);
- painter.setPen(Qt::black);
- for (int y = 0; y < qrSize; y++) {
- for (int x = 0; x < qrSize; x++) {
- if (qr->data[y * qrSize + x] & 0x01) {
- painter.fillRect(x * scale, y * scale, scale, scale, Qt::black);
- }
- }
- }
- QRcode_free(qr);
- return QPixmap::fromImage(image);
- }
- QPixmap GeneralInterface::generateQRCodeWithIcon(const QString& text, int size, const QString& iconPath, int iconSize)
- {
- // 生成基础二维码
- QPixmap qrCode = generateQRCode(text, size);
- if (qrCode.isNull()) {
- return QPixmap();
- }
- // 如果未提供图标路径,直接返回基础二维码
- if (iconPath.isEmpty()) {
- return qrCode;
- }
- // 加载图标
- QPixmap icon(iconPath);
- if (icon.isNull()) {
- return qrCode; // 图标加载失败,返回基础二维码
- }
- // 确定图标大小
- int finalIconSize = iconSize;
- if (finalIconSize <= 0) {
- // 默认图标大小为二维码尺寸的1/4
- finalIconSize = size / 4;
- }
- // 缩放图标
- icon = icon.scaled(finalIconSize, finalIconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
- // 在二维码中心绘制图标
- QPainter painter(&qrCode);
- int iconX = (qrCode.width() - icon.width()) / 2;
- int iconY = (qrCode.height() - icon.height()) / 2;
- // 绘制一个白色背景,确保图标清晰可见
- painter.fillRect(iconX - 2, iconY - 2, icon.width() + 4, icon.height() + 4, Qt::white);
- painter.drawPixmap(iconX, iconY, icon);
- return qrCode;
- }
- /**
- * @brief 生成二维码并保存到文件
- * @param text 要编码的文本内容
- * @param filePath 保存文件路径
- * @param size 二维码图片的尺寸(像素)
- * @param margin 二维码边距(模块数)
- * @param errorCorrectionLevel 错误纠正级别
- * @return 是否保存成功
- */
- bool GeneralInterface::generateQRCodeToFile(const QString& text, const QString& filePath, int size, int margin, char errorCorrectionLevel)
- {
- QPixmap qrCode = generateQRCode(text, size, margin, errorCorrectionLevel);
- if (qrCode.isNull()) {
- return false;
- }
- // 根据文件扩展名确定保存格式
- QString extension = filePath.split('.').last().toLower();
- QString format = "PNG"; // 默认格式
-
- if (extension == "jpg" || extension == "jpeg") {
- format = "JPEG";
- } else if (extension == "bmp") {
- format = "BMP";
- }
- return qrCode.save(filePath, format.toUtf8().constData());
- }
- /**
- * @brief 生成二维码的字节数组(用于网络传输)
- * @param text 要编码的文本内容
- * @param size 二维码图片的尺寸(像素)
- * @param margin 二维码边距(模块数)
- * @param errorCorrectionLevel 错误纠正级别
- * @return 二维码图片的字节数组
- */
- QByteArray GeneralInterface::generateQRCodeBytes(const QString& text, int size, int margin, char errorCorrectionLevel)
- {
- QPixmap qrCode = generateQRCode(text, size, margin, errorCorrectionLevel);
- if (qrCode.isNull()) {
- return QByteArray();
- }
- // 将 QPixmap 转换为字节数组
- QBuffer buffer;
- buffer.open(QIODevice::WriteOnly);
-
- if (qrCode.save(&buffer, "PNG")) {
- return buffer.data();
- }
- return QByteArray();
- }
- /**
- * @brief GeneralInterface::formatMillisecondDifference 格式化毫秒差
- * @param ms1
- * @param ms2
- * @return
- */
- QString GeneralInterface::formatMillisecondDifference(qint64 ms1, qint64 ms2)
- {
- qint64 diffMs = qAbs(ms1 - ms2); // 取绝对值
- QTime time(0, 0);
- time = time.addMSecs(diffMs);
- return time.toString("HH:mm:ss");
- }
- /**
- * @brief GeneralInterface::makeLabelJump 使标签跳一下
- * @param label
- */
- void GeneralInterface::makeLabelJump(QLabel* label) {
- // 创建动画组
- QParallelAnimationGroup *group = new QParallelAnimationGroup(label);
- // 位置动画
- QPropertyAnimation *posAnim = new QPropertyAnimation(label, "pos", group);
- posAnim->setDuration(800);
- posAnim->setEasingCurve(QEasingCurve::OutQuad);
- posAnim->setKeyValueAt(0, label->pos());
- posAnim->setKeyValueAt(0.5, label->pos() + QPoint(0, -80));
- posAnim->setKeyValueAt(1, label->pos());
- // 缩放动画
- QPropertyAnimation *scaleAnim = new QPropertyAnimation(label, "geometry", group);
- scaleAnim->setDuration(800);
- scaleAnim->setEasingCurve(QEasingCurve::OutQuad);
- QRect startRect = label->geometry();
- scaleAnim->setKeyValueAt(0, startRect);
- scaleAnim->setKeyValueAt(0.5, QRect(
- startRect.x() - 10,
- startRect.y() - 80,
- startRect.width() + 20,
- startRect.height() + 20
- ));
- scaleAnim->setKeyValueAt(1, startRect);
- // 启动动画
- group->start(QAbstractAnimation::DeleteWhenStopped);
- }
- /**
- * @brief GeneralInterface::encodeAuthInfo 编码认证信息
- * @param data
- * @return
- */
- QByteArray GeneralInterface::encodeAuthInfo(const GUN_AUTH &data)
- {
- QByteArray result;
- result.append(encodeValue<const uint32_t>(data.GUNID, 1));
- result.append(0x81);
- result.append(sizeof(data.EMID));
- result.append(QByteArray(reinterpret_cast<const char*>(&data.EMID), sizeof(data.EMID)));
- result.append(encodeValue<const uint32_t>(data.requestKWs, 1));
- return result;
- }
- /**
- * @brief GeneralInterface::getGunIconUrl 获取枪口图标
- * @param type 枪口类型
- * @param isError 是否错误
- * @return 返回枪口图标URL
- */
- QString GeneralInterface::getGunIconUrl(const uint8_t &type, bool isError)
- {
- QString icon_url = "";
- switch (type) {
- case GUNTYPE_NACS:
- icon_url = QString(":/icons/%1.png").arg("nacs" + QString("%1").arg(isError ? "_faild" : ""));
- break;
- case GUNTYPE_CCS1:
- icon_url = QString(":/icons/%1.png").arg("ccs1" + QString("%1").arg(isError ? "_faild" : ""));
- break;
- case GUNTYPE_CCS2:
- icon_url = QString(":/icons/%1.png").arg("ccs2" + QString("%1").arg(isError ? "_faild" : ""));
- break;
- case GUNTYPE_CHADEMO:
- icon_url = QString(":/icons/%1.png").arg("chademo" + QString("%1").arg(isError ? "_faild" : ""));
- break;
- case GUNTYPE_GBDC:
- icon_url = QString(":/icons/%1.png").arg("gbdc" + QString("%1").arg(isError ? "_faild" : ""));
- break;
- default:
- break;
- }
- return icon_url;
- }
- QByteArray GeneralInterface::encodeUpdateConfigInfo(const UPDATE_CONFIG &data)
- {
- QByteArray result;
- result.append(0x81);
- result.append(sizeof(data.config_filename));
- result.append(QByteArray(reinterpret_cast<const char*>(&data.config_filename), sizeof(data.config_filename)));
- return result;
- }
- /**
- * @brief GeneralInterface::isError 判断是否有错误
- * @param error_list 错误列表
- * @return 错误返回true,否则返回false
- */
- bool GeneralInterface::isError(const QList<uint32_t> &error_list)
- {
- return std::any_of(error_list.begin(), error_list.end(),
- [](uint32_t value) { return (value > CHARGE_GUN_ERROR_MAX_INDEX); });
- }
- /**
- * @brief GeneralInterface::getMaxElement 获取最大值
- * @param state_list 状态列表
- * @return
- */
- uint8_t GeneralInterface::getMaxElement(const QList<uint32_t> &state_list)
- {
- if (state_list.isEmpty()) {
- return 0; // 或者抛出异常
- }
- auto it = std::max_element(state_list.begin(), state_list.end());
- return *it;
- }
- /**
- * @brief GeneralInterface::addRotationAnimation 添加旋转动画
- * @param label
- */
- void GeneralInterface::addRotationAnimation(QLabel *label)
- {
- // 创建图形场景和代理
- QGraphicsScene *scene = new QGraphicsScene(label->parentWidget());
- QGraphicsProxyWidget *proxy = scene->addWidget(label);
- // 设置旋转中心为标签中心
- proxy->setTransformOriginPoint(proxy->boundingRect().center());
- // 创建旋转动画
- QPropertyAnimation *animation = new QPropertyAnimation(label, "rotation");
- animation->setDuration(2000); // 动画持续时间(毫秒)
- animation->setStartValue(0); // 起始角度
- animation->setEndValue(360); // 结束角度(360度)
- animation->setLoopCount(-1); // 无限循环
- animation->start();
- }
- /**
- * @brief GeneralInterface::getMaxElementWithQMax 获取最大值
- * @param list
- * @return
- */
- uint8_t GeneralInterface::getMaxElementWithQMax(const QList<uint8_t> &list)
- {
- if (list.isEmpty()) {
- return 0;
- }
- int max = list.first();
- for (int num : list) {
- max = qMax(max, num);
- }
- return max;
- }
- /**
- * @brief GeneralInterface::getTips 获取提示信息
- * @param state 状态码
- * @return
- */
- QString GeneralInterface::getTips(const int &state)
- {
- switch (state) {
- case CHARGE_GUN_AVAILABLE: return QCoreApplication::translate("GeneralInterface", "Please Plug in");
- case AUTHORIZATION_QR: return QCoreApplication::translate("GeneralInterface", "Please scan the QR code");
- case AUTHORIZATION_ID_CARD: return QCoreApplication::translate("GeneralInterface", "Please swipe the card");
- case AUTHORIZATION_QR_ID_CARD: return QCoreApplication::translate("GeneralInterface", "Please swipe the card or scan the QR code");
- case WAITING_NO_ID_CARD: return QCoreApplication::translate("GeneralInterface", "Do not swipe card");
- case WAITING_NO_ID_CARD_QR: return QCoreApplication::translate("GeneralInterface", "Do not swipe card; QR code scan works normally");
- case WAITING_STANDBY: return QCoreApplication::translate("GeneralInterface", "waiting");
- case AUTHORIZING_ONLINE: return QCoreApplication::translate("GeneralInterface", "Authorizing online");
- case RETRY: return QCoreApplication::translate("GeneralInterface", "Retry");
- case TIMEOUT: return QCoreApplication::translate("GeneralInterface", "Timeout");
- case RETRY_OR_RETURN_GUN: return QCoreApplication::translate("GeneralInterface", "Please try again or return the connector");
- case SCAN_QR_OR_RETURN_GUN: return QCoreApplication::translate("GeneralInterface", "Scan the QR code or return the connector");
- case FAILED: return QCoreApplication::translate("GeneralInterface", "Failed");
- case CARD_AUTHORIZATION_FAILED: return QCoreApplication::translate("GeneralInterface", "Charging authorization failed");
- case CHANGE_CARD: return QCoreApplication::translate("GeneralInterface", "Please use another card or return the connector");
- case BALANCE_NO_START: return QCoreApplication::translate("GeneralInterface", "Balance:$0x01, insufficient to start charging");
- case TOP_UP_RETRY: return QCoreApplication::translate("GeneralInterface", "Please top up the funds then try again");
- case PREPARE_HANDSHAKING: return QCoreApplication::translate("GeneralInterface", "Preparing Handshaking");
- case HANDSHAKING: return QCoreApplication::translate("GeneralInterface", "Handshaking");
- case CONFIGUING: return QCoreApplication::translate("GeneralInterface", "Configuring");
- case START_CHARGING: return QCoreApplication::translate("GeneralInterface", "Start Charging");
- case STARTUP_FAILED: return QCoreApplication::translate("GeneralInterface", "Startup Failed");
- case UNPLUG_RETRY_OR_CHANGE: return QCoreApplication::translate("GeneralInterface", "Please try unplug the connector and reconnect it to the vehicle or use another connector");
- case STOP_CHARGING: return QCoreApplication::translate("GeneralInterface", "STOP");
- case TIME_REMAINING: return QCoreApplication::translate("GeneralInterface", "mins remaining");
- case RETURN_GUN: return QCoreApplication::translate("GeneralInterface", "Please return the connector");
- case RESTART_CHARGING: return QCoreApplication::translate("GeneralInterface", "Restart");
- case CHARGING_STOP_ABNORMAL: return QCoreApplication::translate("GeneralInterface", "");
- case UNAVAILABLE: return QCoreApplication::translate("GeneralInterface", "Unavailable");
- case CHARGE_GUN_UNAVILABLE: return QCoreApplication::translate("GeneralInterface", "This connector is currently unavailable. Please use another one.");
- case OUT_OF_SERVICE: return QCoreApplication::translate("GeneralInterface", "This charging station is in out-of-service hours and unable to provide charging services.");
- case MAX_POWER_LIMIT: return QCoreApplication::translate("GeneralInterface", "This charging station has reached its maximum power limit and cannot be activated for charging.");
- default: return QCoreApplication::translate("GeneralInterface", "");
- }
- }
- /**
- * @brief GeneralInterface::isCrossTime 判断时间是否交叉
- * @param start 开始时间
- * @param end 结束时间
- * @return 交叉返回 true,否则返回 false
- */
- bool GeneralInterface::isCrossTime(const uint32_t &start, const uint32_t &end)
- {
- return start > end;
- }
- /**
- * @brief GeneralInterface::getAuthResult 获取授权结果
- * @param cardId 卡号
- * @return 卡号存在且状态为无效且过期则返回 0,否则返回 1
- */
- int GeneralInterface::getAuthResult(const QByteArray &cardId)
- {
- auto auth_list = GLOBALS->getValue(Global::Keys::AUTH_LIST).value<AUTH_LIST>();
- auto cfg_key = GLOBALS->getValue(Global::Keys::CFG_KEY).value<CONFIG_KEY_INFO>();
- int result = 1;
- if (cfg_key.CoreProfile.AuthorizationCacheEnabled) { // auth list cache
- foreach (const auto& value, auth_list.authorizationCache) {
- if (cardId.data() == value.idTag &&
- value.status == "Invalid" &&
- isTimeout(value.expiryDate)) {
- result = 0;
- }
- }
- }
- if (cfg_key.LocalAuthListManagementProfile.LocalAuthListEnabled) { // local auth list
- foreach (const auto& value, auth_list.localAuthorizationList) {
- if (cardId.data() == value.idTag &&
- value.status == "Invalid" &&
- isTimeout(value.expiryDate)) {
- result = 0;
- }
- }
- }
- return result;
- }
- /**
- * @brief GeneralInterface::isTimeout 判断时间是否过期
- * @param date 时间字符串
- * @return 过期返回 true,否则返回 false
- */
- bool GeneralInterface::isTimeout(const QString &date)
- {
- // 将字符串转换为 QDateTime
- QDateTime targetTime = QDateTime::fromString(date, Qt::ISODate);
- if (!targetTime.isValid()) {
- return false;
- }
- // 转换为UTC时间以确保比较准确
- targetTime = targetTime.toUTC();
- QDateTime cur_time = QDateTime::currentDateTimeUtc();
- return targetTime < cur_time;
- }
- QString GeneralInterface::calcTime(const uint32_t& startTime, const uint32_t& endTime)
- {
- QDateTime start = QDateTime::fromSecsSinceEpoch(startTime);
- QDateTime end = QDateTime::fromSecsSinceEpoch(endTime);
- return getCurrentDate(start.secsTo(end));
- }
- bool GeneralInterface::isWidgetInLayout(QWidget* widget, QGridLayout* layout)
- {
- if (!widget || !layout) {
- return false;
- }
- // 遍历布局中的所有控件
- for (int i = 0; i < layout->count(); ++i) {
- QLayoutItem* item = layout->itemAt(i);
- if (item && item->widget() == widget) {
- return true;
- }
- }
- return false;
- }
|