#include "Dao.h"
#include "common/Utils.h"
#include "common/Snowflake.h"
#include "common/JsonN.h"
#include "app/Application.h"
#include "app/AppData.h"
#include "common/Crypto.h"

std::string DAO::sqlPageLimit(int index, int size)
{
    int startIndex = index * size;
    if (startIndex < 0) { startIndex = 0; }
    return " LIMIT " + std::to_string(startIndex) + "," + std::to_string(size);
}

Errcode DAO::count(DaoEntity& dao, std::string tableName, std::string condition, int& count)
{
    std::string sql = "SELECT COUNT(*) count FROM " + tableName;
    if (!condition.empty()) { sql += " WHERE " + condition; };
    sql += ";";

    std::vector<Fields> result;
    int ret = dao.exec(sql, result);
    if (ret == 0)
    {
        count = (result.size() > 0) ? result[0].get<int>("count") : 0;
    }
    return Errcode(ret);
}

Errcode DAO::exec(std::shared_ptr<DaoEntity> dao, std::string sql)
{
    if (!dao) { dao = DaoEntity::create(""); }
    if (!dao->isConnected())
    {
        return Errcode::ERR_DB_CONN;
    }
    auto ret = dao->exec(sql);
    return Errcode(ret);
}

Errcode DAO::exec(std::shared_ptr<DaoEntity> dao, std::string sql, vector<Fields>& result)
{
    if (!dao) { dao = DaoEntity::create(""); }
    if (!dao->isConnected())
    {
        return Errcode::ERR_DB_CONN;
    }
    auto ret = dao->exec(sql, result);
    return Errcode(ret);
}
Errcode DAO::query(std::shared_ptr<DaoEntity> dao, std::string tableName, std::vector<std::string> keys, std::string condition)
{
    std::string sql;
    return DAO::exec(dao, sql);
}
Errcode DAO::queryPagination(std::shared_ptr<DaoEntity> dao, std::string tableName, std::vector<std::string> keys, std::string condition)
{
    std::string sql;
    return DAO::exec(dao, sql);
}
Errcode DAO::insert(std::shared_ptr<DaoEntity> dao, std::string tableName, Fields params)
{
    return DAO::exec(dao, params.toSqlInsert(tableName));
}
Errcode DAO::update(std::shared_ptr<DaoEntity> dao, std::string tableName, Fields params, std::string primaryKey)
{
    std::string primaryVal = params.remove(primaryKey);
    if (primaryVal.empty())
    {
        spdlog::error("DAO update [{}] failed,{} is NULL.", tableName, primaryKey);
        return Errcode::ERR_PARAM;
    }
    if (params.size() == 0)
    {
        spdlog::error("DAO update [{}] failed, params size=0.", tableName);
        return Errcode::ERR_PARAM_NUL;
    }
    std::string condition = "WHERE " + primaryKey + "='" + primaryVal + "'";
    string sql = params.toSqlUpdate(tableName, condition);
    return DAO::exec(dao, sql);
}
Errcode DAO::remove(std::shared_ptr<DaoEntity> dao, std::string tableName, std::string primaryKey, std::string val)
{
    std::string sql = "DELETE from `" + tableName + "` WHERE " + primaryKey + "='" + val + "';";
    return DAO::exec(dao, sql);
}
static Errcode QueryCount(DaoEntity& dao, std::string sqlFrom, int& count)
{
    std::vector<Fields> result;
    int ret = dao.exec("SELECT COUNT(*) count " + sqlFrom, result);
    if (ret == 0)
    {
        count = (result.size() > 0) ? result[0].get<int>("count") : 0;
    }
    return Errcode(ret);
}


static Errcode QueryPagination(std::string sqlFields, std::string sqlFrom, PageInfo& page, vector<Fields>& result, std::string orderby="")
{
    DaoEntity dao("");
    if (!dao.isConnected())
    {
        return Errcode::ERR_DB_CONN;
    }
    int count {0};
    Errcode err = QueryCount(dao, sqlFrom, count);
    if (err != Errcode::OK)
    {
        return err;
    }
    
    if (page.index < 1) page.index = 1;
    if (page.size <= 0) page.size = 10;
    page.total = count;
    std::string sql = "SELECT " + sqlFields + " " + sqlFrom + orderby + DAO::sqlPageLimit(page.index -1, page.size);
    int ret = dao.exec(sql, result);
    return Errcode(ret);
}

// 新增用户信息
Errcode DAO::insertUser(Fields& params)
{
    std::string account = params.value(DMUser::ACCOUNT);
    if (account.empty())
    {
        return Errcode::ERR_PARAM;
    }

    // step1: 查询检查登录名是否已经存在
    std::vector<Fields> result;
    auto dao = DaoEntity::create(DMUser::TABLENAME);
    int ret = dao->exec("SELECT * from user WHERE account='" + account + "';", result);
    if (ret != 0)
    {
        return Errcode(ret);
    }
    if (result.size() > 0)
    {
        return Errcode::ERR_DB_DUPLICATE;
    }

    std::string createTime = Utils::timeStr();
    params.set(DMUser::USER_ID, Snowflake::instance().getIdStr());
    params.set(DMUser::CREATETIME, createTime);
    params.set(DMUser::PASSWD, "123456");
    std::string userRoleId = params.remove(DMRole::ROLE_ID);
    ret = dao->insertFields(params);
    if (ret != 0)
    {
        return Errcode(ret);
    }

    
    if (!userRoleId.empty())
    {
        Fields paramsUserRole;
        paramsUserRole.set(DMUser::USER_ID, params.value(DMUser::USER_ID));
        paramsUserRole.set(DMRole::ROLE_ID, userRoleId);
        paramsUserRole.set(DMUser::UPDATETIME, createTime);
        dao->setTableName(DMUserRole::TABLENAME);
        ret = dao->duplicateUpdate(paramsUserRole, {DMUser::USER_ID});
    }
    return Errcode::OK;
}

Errcode DAO::login(std::shared_ptr<DaoEntity> dao, std::string account, std::string passwd, Fields& fields)
{
    if (!dao) { dao = std::make_shared<DaoEntity>(""); }
    if (!dao->isConnected())
    {
        return Errcode::ERR_DB_CONN;
    }
    std::string t = Utils::timeStr();

    std::string sql = "SELECT u.*, ur.role_id FROM `user` u"
        " LEFT JOIN user_role ur ON u.user_id = ur.user_id WHERE u.account='" + account + "';";
    std::vector<Fields> result;
    int ret = dao->exec(sql, result);
    if (ret != 0)
    { 
        return Errcode(ret);
    }
    if (result.size() <=0)
    {
        return Errcode::ERR_LOGIN_USER_NOTEXIST;
    }
    fields = result[0];
    std::string userId = fields.value("user_id");
    int loginCount = fields.get<int>("login_count");

    // 判断密码

    if (passwd != Crypto::sm3(fields.remove("passwd")))
    {
        return Errcode::ERR_LOGIN_PASSWD;
    }

    // 数据库更新用户登录信息
    //sql = "UPDATE user SET login_time='" + t + "', login_count='" + std::to_string(loginCount + 1) + "' WHERE user_id = '" +  userId + "'; ";
    //ret = dao->exec(sql);
    //if (ret != 0)
    //{
    //    XLOGE() << "更新用户登录信息失败：sql=" << sql;
    //}

    //DAO1::writeSystemLog(dao, 2, userId, account, "用户登录成功");
    return Errcode::OK;
}

Errcode DAO::queryRolePermission(std::shared_ptr<DaoEntity> dao, int roleId, vector<Fields>& result)
{
    std::string sql = R"(SELECT rp.role_id, p.permission_id, p.parent_id, p.route, p.name, rp.is_view, rp.is_add, rp.is_edit, rp.is_del 
        FROM role_permission rp
        LEFT JOIN permission p ON p.permission_id = rp.permission_id
        WHERE rp.is_open='1' AND rp.role_id =')" + std::to_string(roleId) + "';";
    return DAO::exec(dao, sql, result);
}

Errcode DAO::queryRolePermission(std::shared_ptr<DaoEntity> dao, vector<Fields>& result)
{
    // 查询 role 的 permission
    std::string sql = R"(SELECT rp.role_id, r.name role_name, rp.permission_id, p.parent_id, p.route,  p.name, rp.is_view, rp.is_add, rp.is_edit, rp.is_del FROM role_permission rp
        LEFT JOIN `role` r ON r.role_id = rp.role_id
        LEFT JOIN permission p ON p.permission_id = rp.permission_id
        WHERE rp.is_open='1';)";
    return DAO::exec(dao, sql, result);
}

// 分页查询用户信息列表
Errcode DAO::queryUserList(PageInfo& pageInfo, vector<Fields>& result)
{
    std::string sqlFields = "u.user_id, u.account, u.name, u.phone, u.age, u.email, u.gender, u.is_open, u.create_time, u.update_time, r.role_id , r.name role_name";
    std::string sqlCondition = "FROM USER u LEFT JOIN user_role ur ON ur.user_id = u.user_id LEFT JOIN ROLE r ON r.role_id =ur.role_id";

    return QueryPagination(sqlFields, sqlCondition, pageInfo, result);
}

Errcode DAO::updateUserById(Fields& params)
{
    auto dao = DaoEntity::create(DMUser::TABLENAME);

    std::string createTime = Utils::timeStr();
    std::string userId = params.remove(DMUser::USER_ID);
    std::string roleId = params.remove(DMRole::ROLE_ID);

    if (params.size() > 0)
    {
        int ret = dao->updateFields(params, "WHERE " + DMUser::USER_ID + "='" + userId + "'");
        if (ret != 0)
        {
            return Errcode(ret);
        }
    }
    if (!roleId.empty())
    {
        dao->setTableName(DMUserRole::TABLENAME);
        Fields paramsUserRole;
        paramsUserRole.set(DMUserRole::USER_ID, userId);
        paramsUserRole.set(DMUserRole::ROLE_ID, roleId);
        paramsUserRole.set(DMUserRole::UPDATETIME, createTime);
        int ret = dao->duplicateUpdate(paramsUserRole, {DMUserRole::ROLE_ID});
        if (ret != 0)
        {
            return Errcode(ret);
        }
    }
    return Errcode::OK;
}

Errcode DAO::deleteUserById(std::string userId)
{
    std::string sql = "DELETE from user WHERE user_id='" + userId + "';";
    return DAO::exec(NULL, sql);
}

Errcode DAO::queryPermissionList(PageInfo& pageInfo, vector<Fields>& result)
{
    std::string sqlFrom = "FROM permission WHERE permission.parent_id IS NULL OR permission.parent_id=''";
    return QueryPagination("*", sqlFrom, pageInfo, result);
}

Errcode DAO::insertPermission(Fields& params)
{
    return DAO::exec(NULL, params.toSqlInsert(DMPermission::TABLENAME));
}

Errcode DAO::updatePermissionById(Fields& params)
{
    std::string primaryKey = DMPermission::PERMISSION_ID;
    std::string primaryVal = params.remove(primaryKey);
    if (primaryVal.empty())
    {
        return Errcode::ERR_DB_SQL;
    }
    std::string condition = "WHERE " + primaryKey + "='" + primaryVal + "'";
    string sql = params.toSqlUpdate(DMPermission::TABLENAME, condition);
    return DAO::exec(NULL, sql);
}

Errcode DAO::deletePermissionById(std::string permissionId)
{
    std::string sql = "DELETE from permission WHERE permission_id='" + permissionId + "';";
    return DAO::exec(NULL, sql);
}

Errcode DAO::queryRoleList(std::shared_ptr<DaoEntity> dao, vector<Fields>& result)
{
    std::string sql = "SELECT * FROM " + DMRole::TABLENAME + ";";
    return DAO::exec(dao, sql, result);
}

Errcode DAO::queryRoleList(PageInfo& pageInfo, vector<Fields>& result)
{
    std::string sqlFields = "";
    std::string sqlCondition = "FROM " + DMRole::TABLENAME;
    return QueryPagination("*", sqlCondition, pageInfo, result);
}

Errcode DAO::updateRolePermission(std::shared_ptr<DaoEntity> dao, std::string roleId, vector<Fields>& vecFields)
{
    if (!dao) dao = DaoEntity::create("");
    dao->setTableName(DMRolePermission::TABLENAME);
    std::string sqlDel = "DELETE from " + DMRolePermission::TABLENAME + " WHERE role_id='" + roleId + "';";
    int ret = dao->exec(sqlDel);
    if (ret != 0 ){ return Errcode(ret); };
    ret = dao->insertFields(vecFields);
    if (ret != 0) { return Errcode(ret); };
    return Errcode::OK;
}

// 新增角色
Errcode DAO::insertRole(Fields& params) 
{
    std::string permission = params.remove("permission");
    std::string name = params.value("name");
    auto dao = DaoEntity::create(DMRole::TABLENAME);
    auto err = DAO::insert(dao, DMRole::TABLENAME, params);
    
    if (err == Errcode::OK && !permission.empty())
    {
        njson jsonarray;
        if (JSON::parse(permission, jsonarray))
        {
            // 查询获取 roleId
            std::vector<Fields> res;
            std::string sql = "SELECT * FROM " + DMRole::TABLENAME + " WHERE name='" + name + "';";
            err = DAO::exec(dao, sql, res);
            if (err == Errcode::OK && res.size() > 0)
            {
                std::string roleId = res[0].value("role_id");
                std::vector<Fields> vecFields;
                for (auto& item: jsonarray)
                {
                    Fields fields;
                    fields.set("role_id", roleId);
                    fields.set("permission_id", item["permission_id"].get<std::string>());
                    fields.set("is_open", item["is_open"].get<std::string>());
                    fields.set("is_view", item["is_view"].get<std::string>());
                    fields.set("is_add", item["is_add"].get<std::string>());
                    fields.set("is_edit", item["is_edit"].get<std::string>());
                    fields.set("is_del", item["is_del"].get<std::string>());
                    vecFields.push_back(fields);
                }
                err = DAO::updateRolePermission(dao, roleId, vecFields);
            }
        }
    }
    return err;
}

// 更新角色
Errcode DAO::updateRoleById(std::shared_ptr<DaoEntity> dao, Fields& params)
{
    if (!dao) dao = DaoEntity::create("");
    dao->setTableName(DMRole::TABLENAME);

    auto roleId = params.value(DMRole::ROLE_ID);
    if (roleId.empty())
    {
        return Errcode::ERR_DB_SQL;
    }
    auto permission = params.remove("permission");
    
    auto err = DAO::update(dao, DMRole::TABLENAME, params, DMRole::ROLE_ID);
    //if (err == Errcode::OK && !permission.empty())
    //{
    //    err = DAO::updateRolePermission(dao, roleId, permission);
    //}
    return err;
}

// 删除角色
Errcode DAO::deleteRoleById(std::string userId)
{
    return DAO::remove(NULL, DMRole::TABLENAME, DMRole::ROLE_ID, userId);
}

Errcode DAO::insertStation(Fields& params)
{
    auto dao = DaoEntity::create(DMStation::TABLENAME);
    params.remove(DMStation::STATION_ID);
    params.check(DMStation::LATITUDE, "", "NULL");
    params.check(DMStation::LONGITUDE, "", "NULL");

    std::string sql = params.toSqlInsert(DMStation::TABLENAME);
    return DAO::insert(NULL, DMStation::TABLENAME, params);
}

// 查询场站信息列表
Errcode DAO::queryStationList(std::shared_ptr<DaoEntity> dao, vector<Fields>& result)
{
    std::string sql = "SELECT * FROM " + DMStation::TABLENAME;
    return DAO::exec(dao, sql, result);
}

// 分页查询场站信息列表
Errcode DAO::queryStationList(PageInfo& pageInfo, vector<Fields>& result)
{
    std::string sqlFrom = "FROM " + DMStation::TABLENAME;
    return QueryPagination("*", sqlFrom, pageInfo, result);
}

Errcode DAO::updateStationById(Fields& params)
{
    std::string primaryKey = DMStation::STATION_ID;
    return DAO::update(NULL, DMStation::TABLENAME, params, primaryKey);
}

// 查询设备信息列表
Errcode DAO::queryDeviceList(std::shared_ptr<DaoEntity> dao, vector<Fields>& result, bool sort/* = false*/)
{
    std::string sql = "SELECT d.*, ddt.category FROM device d LEFT JOIN def_device_type ddt ON d.`type`=ddt.device_type_id";
    if (sort) sql += " ORDER BY station_id, sort_no";
    sql += ";";
    return DAO::exec(dao, sql, result);
}

// 分页查询设备信息列表
Errcode DAO::queryDeviceList(PageInfo& pageInfo, vector<Fields>& result)
{
    std::string sqlFrom = "FROM device d LEFT JOIN station s ON d.station_id =s.station_id";
    return QueryPagination("d.*, s.name station_name", sqlFrom, pageInfo, result);
}
Errcode DAO::queryDeviceListByStation(PageInfo& pageInfo, string stationId, vector<Fields>& result)
{
    std::string sqlFrom = "FROM device d LEFT JOIN station s ON d.station_id =s.station_id WHERE d.station_id='" + stationId + "' ORDER BY d.station_id, d.sort_no";
    return QueryPagination("d.*, s.name station_name", sqlFrom, pageInfo, result);
}

// 查询设备类型定义
Errcode DAO::queryDeviceTypeDef(std::shared_ptr<DaoEntity> dao, vector<Fields>& result)
{
    std::string sql = "SELECT * FROM " + DMDefDeviceType::TABLENAME + ";";
    return DAO::exec(dao, sql, result);
}

Errcode DAO::insertDevice(Fields& params)
{
    return DAO::exec(NULL, params.toSqlInsert(DMDevice::TABLENAME));
}

Errcode DAO::updateDeviceById(Fields& params)
{
    return DAO::update(NULL, DMDevice::TABLENAME, params, DMDevice::DEVICE_ID);
}

// 策略管理
Errcode DAO::queryPolicyList(PageInfo& pageInfo, vector<Fields>& result)
{
    std::string sqlFrom = "FROM " + DMPolicy::TABLENAME;
    return QueryPagination("*", sqlFrom, pageInfo, result);
}

Errcode DAO::queryPolicyList(std::shared_ptr<DaoEntity> dao, vector<Fields>& result)
{
    std::string sql = "SELECT * FROM " + DMPolicy::TABLENAME;
    return DAO::exec(dao, sql, result);
}
Errcode DAO::insertPolicy(Fields& params)
{
    return DAO::insert(NULL, DMPolicy::TABLENAME, params);
}
Errcode DAO::updatePolicyById(Fields& params)
{
    return DAO::update(NULL, DMPolicy::TABLENAME, params, DMPolicy::POLICY_ID);
}
Errcode DAO::deletePolicyById(std::string policyId)
{
    return DAO::remove(NULL, DMPolicy::TABLENAME, DMPolicy::POLICY_ID, policyId);
}

// 系统日志管理
Errcode DAO::querySystemLogList(PageInfo& pageInfo, vector<Fields>& result)
{
    std::string sqlFrom = "FROM " + DMLogSystem::TABLENAME;
    return QueryPagination("*", sqlFrom, pageInfo, result, " order by create_time desc ");
}
Errcode DAO::insertSystemLog(Fields& params)
{
    params.set(DMLogAlert::LOG_ID, Snowflake::instance().getIdStr());
    return DAO::insert(NULL, DMLogSystem::TABLENAME, params);
}
Errcode DAO::updateSystemLogById(Fields& params)
{
    return DAO::update(NULL, DMLogSystem::TABLENAME, params, DMLogSystem::LOG_ID);
}

Errcode DAO::insertSystemLogSys(std::string content, int status)
{
    Fields fields;
    fields.set("type", 1);
    fields.set("content", content);
    fields.set("status", status);
    return DAO::insertSystemLog(fields);
}
Errcode DAO::insertSystemLogUser(std::string token, std::string content, int status)
{
    User user = Application::data().getUser(token);
    Fields fields;
    fields.set("type", 2);
    fields.set("content", content);
    fields.set("status", status);
    fields.set("user_id", user.userId);
    fields.set("user_account", user.account);
    return DAO::insertSystemLog(fields);
}
Errcode DAO::insertSystemLogDevice(int stationId, int deviceId, std::string content, int status)
{
    Fields fields;
    fields.set("station_id", stationId);
    fields.set("device_id", deviceId);
    fields.set("type", 3);
    fields.set("content", content);
    fields.set("status", status);
    return DAO::insertSystemLog(fields);
}

Errcode DAO::queryAlertLogList(PageInfo& pageInfo, vector<Fields>& result)
{
    std::string sqlFrom = "from log_alert la left join device d on d.device_id =la.device_id left join station s on s.station_id = d.station_id";
    return QueryPagination("d.station_id, s.name station_name, d.name device_name, la.*", sqlFrom, pageInfo, result, " order by create_time desc ");
}
Errcode DAO::insertAlertLog(Fields& params)
{
    params.set(DMLogAlert::LOG_ID, Snowflake::instance().getIdStr());
    return DAO::insert(NULL, DMLogAlert::TABLENAME, params);
}
Errcode DAO::updateAlertLogById(Fields& params)
{
    return DAO::update(NULL, DMLogAlert::TABLENAME, params, DMLogAlert::LOG_ID);
}


Errcode DAO::queryStatDataList(std::shared_ptr<DaoEntity> dao, std::string startDate, std::string endDate, vector<Fields>& result)
{
    std::string sql = "SELECT * FROM " + DMStatStation::TABLENAME + " WHERE dt BETWEEN '" + startDate + "' AND '" + endDate + "';";
    return DAO::exec(dao, sql, result);
}

Errcode DAO::queryStatStationGroup(std::shared_ptr<DaoEntity> dao, string stationId, string category, string startDate, string endDate, vector<Fields>& result)
{
    std::string sqlCondition;
    if (!startDate.empty() && endDate.empty())
    {
        sqlCondition += "dt BETWEEN '" + startDate + "' AND '" + endDate + "'";
    }
    if (!stationId.empty())
    {
        if (!sqlCondition.empty()) sqlCondition += " AND ";
        sqlCondition += "station_id='" + stationId + "'";
    }
    if (!category.empty() && category != "0")
    {
        //if (!sqlCondition.empty()) sqlCondition += " AND ";
        //sqlCondition += "category='" + category  + "'";;
    }
    if (!sqlCondition.empty()) { sqlCondition = " WHERE " + sqlCondition; }

    std::string sql = R"(SELECT dt,
	    SUM(storage_elect_in) storage_elect_in,
	    SUM(storage_elect_out) storage_elect_out,
        SUM(storage_num_in) storage_num_in,
        SUM(storage_num_out) storage_num_out,
	    SUM(storage_num_err) storage_num_err,
	    SUM(solar_elect_gen) solar_elect_gen,
	    SUM(solar_elect_grid) solar_elect_grid,
	    SUM(solar_num_err) solar_num_err,
	    AVG(storage_usage) storage_usage,
	    SUM(charge_elect) charge_elect,
	    SUM(charge_num) charge_num,
	    SUM(charge_num_err) charge_num_err,
        AVG(charge_usage) charge_usage,
	    SUM(income_elect) income_elect,
	    SUM(income_charge) income_charge
	    FROM stat_day)" +  sqlCondition + " GROUP by dt;";
    return DAO::exec(dao, sql, result);
}

Errcode DAO::queryStatStationList(PageInfo& pageInfo, Fields& params, vector<Fields>& result)
{
    std::string stationId = params.value("station_id");
    std::string category = params.value("category");
    std::string startDate = params.value("start_date");
    std::string endDate = params.value("end_date");

    std::string sqlCondition;
    if (!startDate.empty() && !endDate.empty())
    {
        sqlCondition += "dt BETWEEN '" + startDate + "' AND '" + endDate + "'";
    }
    if (!stationId.empty())
    {
        if (!sqlCondition.empty()) sqlCondition += " AND ";
        sqlCondition += "ss.station_id='" + stationId + "'";
    }
    if (!category.empty() && category != "0")
    {
        //if (!sqlCondition.empty()) sqlCondition += " AND ";
        //sqlCondition += "ss.category='" + category  + "'";;
    }
    if (!sqlCondition.empty()) { sqlCondition = " WHERE " + sqlCondition; }

    std::string sqlFields = "ss.* ";
    std::string sqlFrom = R"(FROM stat_day ss )" + sqlCondition;
    return QueryPagination(sqlFields, sqlFrom, pageInfo, result);
}

Errcode DAO::queryWorkModeDef(std::shared_ptr<DaoEntity> dao, vector<Fields>& result)
{
    std::string sql = "SELECT * FROM " + DMDefWorkMode::TABLENAME + ";";
    return DAO::exec(dao, sql, result);
}

Errcode DAO::queryPolicyTypeDef(std::shared_ptr<DaoEntity> dao, vector<Fields>& result)
{
    std::string sql = "SELECT * FROM " + DMDefPolicyType::TABLENAME + ";";
    return DAO::exec(dao, sql, result);
}

Errcode DAO::insertStatDay(std::shared_ptr<DaoEntity> dao, Fields& fields)
{
    // 根据主键（dt、station_id、category），写入或更新数据
    if (!dao) { dao = DaoEntity::create("stat_day"); }
    else { dao->setTableName("stat_day"); }
    std::vector<std::string> vecKeys = {
        "storage_elect_in",
        "storage_elect_out",
        "storage_num_in",
        "storage_num_out",
        "storage_num_err",
        "storage_t_in",
        "storage_t_out",
        "storage_usage",
        "solar_elect_gen",
        "solar_elect_grid",
        "solar_num_err",
        "solar_t",
        "solar_usage",
        "charge_elect",
        "charge_num",
        "charge_num_err",
        "charge_t",
        "charge_usage",
        "income_elect",
        "income_charge",
        "usage_rate"
    };
    int ret = dao->duplicateUpdate(fields, vecKeys);
    return Errcode(ret);
}

Errcode DAO::insertRuntimeData(std::shared_ptr<DaoEntity> dao, Fields& fields)
{
    if (!dao) { dao = DaoEntity::create("history_day"); }
    int ret = dao->duplicateUpdate(fields, {"value"});
    return Errcode(ret);
}


Errcode DAO::queryRuntimeData(std::shared_ptr<DaoEntity> dao, std::string dt, int stationId, int deviceId, vector<Fields>& result)
{
    if (!dao) { dao = DaoEntity::create("history_day"); }
    std::string sql = "SELECT * FROM history_day WHERE dt='" + dt + "' AND station_id='" + std::to_string(stationId) +
        "' AND device_id='" + std::to_string(deviceId) + "';";
    int ret = dao->exec(sql, result);
    return Errcode(ret);
}

Errcode DAO::queryRuntimeDataHistory(std::shared_ptr<DaoEntity> dao, std::string dt, vector<Fields>& result)
{
    if (!dao) { dao = DaoEntity::create(""); }
    std::string sql = "SELECT * FROM history_day WHERE dt='" + dt + "';";
    int ret = dao->exec(sql, result);
    return Errcode(ret);
}

Errcode DAO::queryPredictHistory(std::shared_ptr<DaoEntity> dao, std::string dt, vector<Fields>& result)
{
    if (!dao) { dao = DaoEntity::create(""); }
    std::string sql = "SELECT * FROM predict_day WHERE dt='" + dt + "';";
    int ret = dao->exec(sql, result);
    return Errcode(ret);
}