279 lines
7.8 KiB
C++
279 lines
7.8 KiB
C++
#include "qsubscriptionmanager.h"
|
|
#include <QDebug>
|
|
#include <QFile>
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
#include <QJsonArray>
|
|
#include <QDir>
|
|
|
|
QSubscriptionManager* QSubscriptionManager::instance()
|
|
{
|
|
static QSubscriptionManager* instance = nullptr;
|
|
static QMutex mutex;
|
|
|
|
if (!instance) {
|
|
QMutexLocker locker(&mutex);
|
|
if (!instance) {
|
|
instance = new QSubscriptionManager();
|
|
}
|
|
}
|
|
return instance;
|
|
}
|
|
|
|
QSubscriptionManager::QSubscriptionManager(QObject *parent) : QObject(parent)
|
|
{
|
|
m_configPath = getDefaultConfigPath();
|
|
// 自动加载配置
|
|
loadFromFile();
|
|
}
|
|
|
|
QSubscriptionManager::~QSubscriptionManager()
|
|
{
|
|
// 自动保存配置
|
|
saveToFile();
|
|
}
|
|
|
|
bool QSubscriptionManager::addSubscription(const QString& stockCode, double threshold)
|
|
{
|
|
if (stockCode.isEmpty() || threshold <= 0) {
|
|
qWarning() << "QSubscriptionManager: Invalid subscription parameters";
|
|
return false;
|
|
}
|
|
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
SubscriptionConfig config(stockCode, threshold);
|
|
m_subscriptions[stockCode] = config;
|
|
|
|
emit subscriptionAdded(stockCode, threshold);
|
|
emit subscriptionsChanged();
|
|
|
|
qDebug() << "QSubscriptionManager: Added subscription for" << stockCode << "with threshold" << threshold;
|
|
return true;
|
|
}
|
|
|
|
bool QSubscriptionManager::removeSubscription(const QString& stockCode)
|
|
{
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
if (m_subscriptions.contains(stockCode)) {
|
|
m_subscriptions.remove(stockCode);
|
|
|
|
emit subscriptionRemoved(stockCode);
|
|
emit subscriptionsChanged();
|
|
|
|
qDebug() << "QSubscriptionManager: Removed subscription for" << stockCode;
|
|
return true;
|
|
}
|
|
|
|
qWarning() << "QSubscriptionManager: Subscription not found for" << stockCode;
|
|
return false;
|
|
}
|
|
|
|
bool QSubscriptionManager::updateThreshold(const QString& stockCode, double threshold)
|
|
{
|
|
if (threshold <= 0) {
|
|
qWarning() << "QSubscriptionManager: Invalid threshold value";
|
|
return false;
|
|
}
|
|
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
if (m_subscriptions.contains(stockCode)) {
|
|
m_subscriptions[stockCode].threshold = threshold;
|
|
m_subscriptions[stockCode].lastUpdated = QDateTime::currentDateTime();
|
|
|
|
emit thresholdUpdated(stockCode, threshold);
|
|
emit subscriptionsChanged();
|
|
|
|
qDebug() << "QSubscriptionManager: Updated threshold for" << stockCode << "to" << threshold;
|
|
return true;
|
|
}
|
|
|
|
qWarning() << "QSubscriptionManager: Subscription not found for" << stockCode;
|
|
return false;
|
|
}
|
|
|
|
bool QSubscriptionManager::enableSubscription(const QString& stockCode, bool enabled)
|
|
{
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
if (m_subscriptions.contains(stockCode)) {
|
|
if (m_subscriptions[stockCode].enabled != enabled) {
|
|
m_subscriptions[stockCode].enabled = enabled;
|
|
m_subscriptions[stockCode].lastUpdated = QDateTime::currentDateTime();
|
|
|
|
emit subscriptionEnabledChanged(stockCode, enabled);
|
|
emit subscriptionsChanged();
|
|
|
|
qDebug() << "QSubscriptionManager:" << (enabled ? "Enabled" : "Disabled") << "subscription for" << stockCode;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
qWarning() << "QSubscriptionManager: Subscription not found for" << stockCode;
|
|
return false;
|
|
}
|
|
|
|
QList<SubscriptionConfig> QSubscriptionManager::getAllSubscriptions() const
|
|
{
|
|
QMutexLocker locker(&m_mutex);
|
|
return m_subscriptions.values();
|
|
}
|
|
|
|
double QSubscriptionManager::getThreshold(const QString& stockCode) const
|
|
{
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
if (m_subscriptions.contains(stockCode)) {
|
|
return m_subscriptions[stockCode].threshold;
|
|
}
|
|
|
|
return 0.0;
|
|
}
|
|
|
|
bool QSubscriptionManager::isSubscribed(const QString& stockCode) const
|
|
{
|
|
QMutexLocker locker(&m_mutex);
|
|
return m_subscriptions.contains(stockCode);
|
|
}
|
|
|
|
bool QSubscriptionManager::isEnabled(const QString& stockCode) const
|
|
{
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
if (m_subscriptions.contains(stockCode)) {
|
|
return m_subscriptions[stockCode].enabled;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void QSubscriptionManager::addSubscriptions(const QList<SubscriptionConfig>& subscriptions)
|
|
{
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
for (const SubscriptionConfig& config : subscriptions) {
|
|
m_subscriptions[config.stockCode] = config;
|
|
}
|
|
|
|
emit subscriptionsChanged();
|
|
}
|
|
|
|
void QSubscriptionManager::removeSubscriptions(const QList<QString>& stockCodes)
|
|
{
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
for (const QString& code : stockCodes) {
|
|
m_subscriptions.remove(code);
|
|
}
|
|
|
|
emit subscriptionsChanged();
|
|
}
|
|
|
|
void QSubscriptionManager::loadFromFile(const QString& filePath)
|
|
{
|
|
QString path = filePath.isEmpty() ? m_configPath : filePath;
|
|
|
|
QFile file(path);
|
|
if (!file.open(QIODevice::ReadOnly)) {
|
|
qDebug() << "QSubscriptionManager: No existing config file found, using defaults";
|
|
return;
|
|
}
|
|
|
|
QByteArray data = file.readAll();
|
|
file.close();
|
|
|
|
QJsonDocument doc = QJsonDocument::fromJson(data);
|
|
if (doc.isNull() || !doc.isObject()) {
|
|
qWarning() << "QSubscriptionManager: Failed to parse config file";
|
|
return;
|
|
}
|
|
|
|
QJsonObject root = doc.object();
|
|
QJsonArray subscriptionsArray = root["subscriptions"].toArray();
|
|
|
|
QMutexLocker locker(&m_mutex);
|
|
m_subscriptions.clear();
|
|
|
|
for (const QJsonValue& value : subscriptionsArray) {
|
|
QJsonObject obj = value.toObject();
|
|
SubscriptionConfig config;
|
|
config.stockCode = obj["stockCode"].toString();
|
|
config.threshold = obj["threshold"].toDouble();
|
|
config.enabled = obj["enabled"].toBool(true);
|
|
config.lastUpdated = QDateTime::fromString(obj["lastUpdated"].toString(), Qt::ISODate);
|
|
|
|
if (!config.stockCode.isEmpty() && config.threshold > 0) {
|
|
m_subscriptions[config.stockCode] = config;
|
|
}
|
|
}
|
|
|
|
qDebug() << "QSubscriptionManager: Loaded" << m_subscriptions.size() << "subscriptions from" << path;
|
|
}
|
|
|
|
void QSubscriptionManager::saveToFile(const QString& filePath)
|
|
{
|
|
QString path = filePath.isEmpty() ? m_configPath : filePath;
|
|
|
|
// 确保目录存在
|
|
QDir dir = QFileInfo(path).absoluteDir();
|
|
if (!dir.exists()) {
|
|
dir.mkpath(".");
|
|
}
|
|
|
|
QFile file(path);
|
|
if (!file.open(QIODevice::WriteOnly)) {
|
|
qWarning() << "QSubscriptionManager: Failed to open config file for writing:" << path;
|
|
return;
|
|
}
|
|
|
|
QJsonObject root;
|
|
QJsonArray subscriptionsArray;
|
|
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
for (const SubscriptionConfig& config : m_subscriptions) {
|
|
QJsonObject obj;
|
|
obj["stockCode"] = config.stockCode;
|
|
obj["threshold"] = config.threshold;
|
|
obj["enabled"] = config.enabled;
|
|
obj["lastUpdated"] = config.lastUpdated.toString(Qt::ISODate);
|
|
subscriptionsArray.append(obj);
|
|
}
|
|
|
|
root["subscriptions"] = subscriptionsArray;
|
|
root["version"] = "1.0";
|
|
root["lastSaved"] = QDateTime::currentDateTime().toString(Qt::ISODate);
|
|
|
|
QJsonDocument doc(root);
|
|
file.write(doc.toJson());
|
|
file.close();
|
|
|
|
qDebug() << "QSubscriptionManager: Saved" << m_subscriptions.size() << "subscriptions to" << path;
|
|
}
|
|
|
|
int QSubscriptionManager::getSubscriptionCount() const
|
|
{
|
|
QMutexLocker locker(&m_mutex);
|
|
return m_subscriptions.size();
|
|
}
|
|
|
|
int QSubscriptionManager::getEnabledSubscriptionCount() const
|
|
{
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
int count = 0;
|
|
for (const SubscriptionConfig& config : m_subscriptions) {
|
|
if (config.enabled) {
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
QString QSubscriptionManager::getDefaultConfigPath() const
|
|
{
|
|
return QDir::currentPath() + "/config/subscriptions.json";
|
|
}
|