mirror of
https://gitee.com/js-yhsec/energy_storage.git
synced 2026-05-27 18:59:26 +08:00
根据甲方意见修改:删除光伏等无数据的展示模块、储能充放电/收益按月+季度+周+年展示、修改首页展示内容
This commit is contained in:
@@ -492,10 +492,11 @@ Errcode DAO::deletePolicyById(std::string policyId)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 系统日志管理
|
// 系统日志管理
|
||||||
Errcode DAO::querySystemLogList(PageInfo& pageInfo, vector<Fields>& result)
|
Errcode DAO::querySystemLogList(const std::string& stationId, PageInfo& pageInfo, vector<Fields>& result)
|
||||||
{
|
{
|
||||||
std::string sqlFrom = "FROM " + DMLogSystem::TABLENAME;
|
std::string sqlFrom = "FROM " + DMLogSystem::TABLENAME;
|
||||||
return QueryPagination("*", sqlFrom, pageInfo, result, " order by create_time desc ");
|
if (!stationId.empty()) sqlFrom += (" WHERE station_id='" + stationId + "'");
|
||||||
|
return QueryPagination("*", sqlFrom, pageInfo, result, " ORDER BY create_time desc ");
|
||||||
}
|
}
|
||||||
Errcode DAO::insertSystemLog(Fields& params)
|
Errcode DAO::insertSystemLog(Fields& params)
|
||||||
{
|
{
|
||||||
@@ -537,10 +538,11 @@ Errcode DAO::insertSystemLogDevice(int stationId, int deviceId, std::string cont
|
|||||||
return DAO::insertSystemLog(fields);
|
return DAO::insertSystemLog(fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
Errcode DAO::queryAlertLogList(PageInfo& pageInfo, vector<Fields>& result)
|
Errcode DAO::queryAlertLogList(const std::string& stationId, 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";
|
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 ");
|
if (!stationId.empty()) sqlFrom += (" WHERE s.station_id='" + stationId + "'");
|
||||||
|
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)
|
Errcode DAO::insertAlertLog(Fields& params)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ public:
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// === 系统日志管理 ===
|
// === 系统日志管理 ===
|
||||||
// 分页查询系统日志列表
|
// 分页查询系统日志列表
|
||||||
static Errcode querySystemLogList(PageInfo& pageInfo, vector<Fields>& result);
|
static Errcode querySystemLogList(const std::string& stationId, PageInfo& pageInfo, vector<Fields>& result);
|
||||||
static Errcode insertSystemLog(Fields& params);
|
static Errcode insertSystemLog(Fields& params);
|
||||||
static Errcode updateSystemLogById(Fields& params);
|
static Errcode updateSystemLogById(Fields& params);
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ public:
|
|||||||
static Errcode insertSystemLogUser(std::string token, std::string content, int status);
|
static Errcode insertSystemLogUser(std::string token, std::string content, int status);
|
||||||
static Errcode insertSystemLogDevice(int stationId, int deviceId, std::string content, int status);
|
static Errcode insertSystemLogDevice(int stationId, int deviceId, std::string content, int status);
|
||||||
|
|
||||||
static Errcode queryAlertLogList(PageInfo& pageInfo, vector<Fields>& result);
|
static Errcode queryAlertLogList(const std::string& stationId, PageInfo& pageInfo, vector<Fields>& result);
|
||||||
static Errcode insertAlertLog(Fields& params);
|
static Errcode insertAlertLog(Fields& params);
|
||||||
static Errcode updateAlertLogById(Fields& params);
|
static Errcode updateAlertLogById(Fields& params);
|
||||||
|
|
||||||
|
|||||||
@@ -188,6 +188,8 @@ static std::map<std::string, HandlerOptions> g_mapHttpHandlerGet =
|
|||||||
{"/queryStatDetailList", HandlerOptions(&HttpEntity::queryStatDetailList, {})},
|
{"/queryStatDetailList", HandlerOptions(&HttpEntity::queryStatDetailList, {})},
|
||||||
{"/queryStatCharts", HandlerOptions(&HttpEntity::queryStatCharts, {})},
|
{"/queryStatCharts", HandlerOptions(&HttpEntity::queryStatCharts, {})},
|
||||||
{"/exportStatReport", HandlerOptions(&HttpEntity::exportStatReport, {})},
|
{"/exportStatReport", HandlerOptions(&HttpEntity::exportStatReport, {})},
|
||||||
|
{"/queryStatStationMode", HandlerOptions(&HttpEntity::queryStatStationMode, {})},
|
||||||
|
|
||||||
|
|
||||||
{"/queryEnvironment", HandlerOptions(&HttpEntity::queryEnvironment, { "station_id"})},
|
{"/queryEnvironment", HandlerOptions(&HttpEntity::queryEnvironment, { "station_id"})},
|
||||||
|
|
||||||
@@ -1225,12 +1227,16 @@ Errcode HttpEntity::queryPolicyByType(const httplib::Request& req, njson& json,
|
|||||||
|
|
||||||
Errcode HttpEntity::querySystemLogList(const httplib::Request& req, njson& json, std::string& errmsg)
|
Errcode HttpEntity::querySystemLogList(const httplib::Request& req, njson& json, std::string& errmsg)
|
||||||
{
|
{
|
||||||
|
Fields params;
|
||||||
|
GetRequestParams(req, {"station_id"}, params);
|
||||||
|
|
||||||
PageInfo pageinfo;
|
PageInfo pageinfo;
|
||||||
pageinfo.index = Utils::toInt(req.get_param_value("page"));
|
pageinfo.index = Utils::toInt(req.get_param_value("page"));
|
||||||
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
|
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
|
||||||
|
|
||||||
|
std::string stationId = params.value("station_id");
|
||||||
std::vector<Fields> result;
|
std::vector<Fields> result;
|
||||||
auto err = DAO::querySystemLogList(pageinfo, result);
|
auto err = DAO::querySystemLogList(stationId, pageinfo, result);
|
||||||
HttpHelper::setPagination(pageinfo, result, json);
|
HttpHelper::setPagination(pageinfo, result, json);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -1245,12 +1251,16 @@ Errcode HttpEntity::updateSystemLog(const httplib::Request& req, njson& json, st
|
|||||||
|
|
||||||
Errcode HttpEntity::queryAlertLogList(const httplib::Request& req, njson& json, std::string& errmsg)
|
Errcode HttpEntity::queryAlertLogList(const httplib::Request& req, njson& json, std::string& errmsg)
|
||||||
{
|
{
|
||||||
|
Fields params;
|
||||||
|
GetRequestParams(req, {"station_id"}, params);
|
||||||
|
|
||||||
PageInfo pageinfo;
|
PageInfo pageinfo;
|
||||||
pageinfo.index = Utils::toInt(req.get_param_value("page"));
|
pageinfo.index = Utils::toInt(req.get_param_value("page"));
|
||||||
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
|
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
|
||||||
|
|
||||||
|
std::string stationId = params.value("station_id");
|
||||||
std::vector<Fields> result;
|
std::vector<Fields> result;
|
||||||
auto err = DAO::queryAlertLogList(pageinfo, result);
|
auto err = DAO::queryAlertLogList(stationId, pageinfo, result);
|
||||||
HttpHelper::setPagination(pageinfo, result, json);
|
HttpHelper::setPagination(pageinfo, result, json);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -1571,12 +1581,10 @@ Errcode HttpEntity::queryStatDayList(const httplib::Request& req, njson& json, s
|
|||||||
|
|
||||||
int64_t t0 = Utils::time(startDate + " 00:00:00");
|
int64_t t0 = Utils::time(startDate + " 00:00:00");
|
||||||
int64_t t1 = Utils::time(endDate + " 00:00:00");
|
int64_t t1 = Utils::time(endDate + " 00:00:00");
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
njson jsondata = njson::array();
|
njson jsondata = njson::array();
|
||||||
for (int64_t t = t0; t<=t1; t += 86400)
|
for (int64_t t = t0; t<=t1; t += 86400)
|
||||||
{
|
{
|
||||||
i++;
|
|
||||||
njson jsonrow;
|
njson jsonrow;
|
||||||
std::string dt = Utils::dateStr(t);
|
std::string dt = Utils::dateStr(t);
|
||||||
Fields* fields = NULL;
|
Fields* fields = NULL;
|
||||||
@@ -1709,6 +1717,115 @@ Errcode HttpEntity::queryStatCharts(const httplib::Request& req, njson& json, st
|
|||||||
return Errcode::OK;
|
return Errcode::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Errcode HttpEntity::queryStatStationMode(const httplib::Request& req, njson& json, std::string& errmsg)
|
||||||
|
{
|
||||||
|
Fields params;
|
||||||
|
GetRequestParams(req, {"station_id", "start_date", "end_date", "mode"}, params);
|
||||||
|
|
||||||
|
std::string stationId = params.value("station_id");
|
||||||
|
std::string startDate = params.value("start_date");
|
||||||
|
std::string endDate = params.value("end_date");
|
||||||
|
std::string mode = params.value("mode");
|
||||||
|
|
||||||
|
std::string sqlC = std::format(" WHERE dt>='{}' AND dt<='{}'", startDate, endDate);
|
||||||
|
if (!stationId.empty()) sqlC += std::format(" AND station_id='{}'", stationId);
|
||||||
|
|
||||||
|
std::string sql = " SUM(E_in) E_in, SUM(E_out) E_out, SUM(fee_in) fee_in, SUM(fee_out) fee_out, SUM(income) income FROM stat_total_day";
|
||||||
|
std::string sqlGroupBy;
|
||||||
|
if (mode == "year") {
|
||||||
|
sql = "SELECT YEAR(dt) AS year, " + sql + sqlC + " GROUP BY YEAR(dt);";
|
||||||
|
} else if (mode == "quarter") {
|
||||||
|
sql = "SELECT YEAR(dt) AS year, QUARTER(dt) quarter, " + sql + sqlC+ " GROUP BY YEAR(dt), QUARTER(dt);";
|
||||||
|
} else if (mode == "month") {
|
||||||
|
sql = "SELECT YEAR(dt) AS year, MONTH(dt) month, " + sql + sqlC + "GROUP BY YEAR(dt), MONTH(dt);";
|
||||||
|
} else if (mode == "week") {
|
||||||
|
sql = "SELECT YEAR(dt) AS year, WEEK(dt) week, " + sql + sqlC + " GROUP BY YEAR(dt), WEEK(dt);";
|
||||||
|
} else {
|
||||||
|
mode = "date";
|
||||||
|
sql = "SELECT dt, E_in, E_out, fee_in, fee_out, income FROM stat_total_day " + sqlC + " LIMIT 1000;";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Fields> result;
|
||||||
|
Errcode err = DAO::exec(NULL, sql, result);
|
||||||
|
|
||||||
|
njson jsondata = njson::array();
|
||||||
|
if (mode == "date")
|
||||||
|
{
|
||||||
|
std::map<std::string, Fields*> mapTemp;
|
||||||
|
for (auto& item: result)
|
||||||
|
{
|
||||||
|
auto& dt = item.value("dt");
|
||||||
|
mapTemp[dt] = &item;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t t0 = Utils::time(startDate + " 00:00:00");
|
||||||
|
int64_t t1 = Utils::time(endDate + " 00:00:00");
|
||||||
|
|
||||||
|
for (int64_t t = t0; t<=t1; t += 86400)
|
||||||
|
{
|
||||||
|
njson jsonrow;
|
||||||
|
std::string dt = Utils::dateStr(t);
|
||||||
|
Fields* item = NULL;
|
||||||
|
auto iter = mapTemp.find(dt);
|
||||||
|
if (iter != mapTemp.end()) { item = iter->second; }
|
||||||
|
|
||||||
|
jsonrow["dt"] = dt;
|
||||||
|
jsonrow["E_in"] = item ? item->value("E_in") : "0";
|
||||||
|
jsonrow["E_out"] = item ? item->value("E_out") : "0";
|
||||||
|
jsonrow["fee_in"] = item ? item->value("fee_in") : "0";
|
||||||
|
jsonrow["fee_out"] = item ? item->value("fee_out") : "0";
|
||||||
|
jsonrow["income"] = item ? item->value("income") : "0";
|
||||||
|
int rate = 0;
|
||||||
|
if (item) {
|
||||||
|
int E_in = item->get<int>("E_in");
|
||||||
|
int E_out = item->get<int>("E_out");
|
||||||
|
if (E_in != 0) {
|
||||||
|
rate = (float(E_out)/float(E_in)) * 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jsonrow["E_rate"] = rate;
|
||||||
|
jsondata.push_back(jsonrow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto& item: result)
|
||||||
|
{
|
||||||
|
njson jsonrow;
|
||||||
|
if (mode == "year") {
|
||||||
|
jsonrow["dt"] = item.value("year") + "年";
|
||||||
|
}
|
||||||
|
else if (mode == "quarter") {
|
||||||
|
jsonrow["dt"] = item.value("year") + "年" + item.value("quarter") + "季度";
|
||||||
|
}
|
||||||
|
else if (mode == "month") {
|
||||||
|
jsonrow["dt"] = item.value("year") + "年" + item.value("month") + "月";
|
||||||
|
}
|
||||||
|
else if (mode == "week") {
|
||||||
|
jsonrow["dt"] = item.value("year") + "年" + item.value("week") + "周";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
jsonrow["dt"] = item.value("dt");
|
||||||
|
}
|
||||||
|
jsonrow["E_in"] = item.value("E_in");
|
||||||
|
jsonrow["E_out"] = item.value("E_out");
|
||||||
|
int rate = 0;
|
||||||
|
int E_in = item.get<int>("E_in");
|
||||||
|
int E_out = item.get<int>("E_out");
|
||||||
|
if (E_in != 0) {
|
||||||
|
rate = (float(E_out)/float(E_in)) * 100;
|
||||||
|
}
|
||||||
|
jsonrow["E_rate"] = rate;
|
||||||
|
jsonrow["fee_in"] = item.value("fee_in");
|
||||||
|
jsonrow["fee_out"] = item.value("fee_out");
|
||||||
|
jsonrow["income"] = item.value("income");
|
||||||
|
jsondata.push_back(jsonrow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
json["data"] = jsondata;
|
||||||
|
return Errcode::OK;
|
||||||
|
}
|
||||||
|
|
||||||
Errcode HttpEntity::exportStatReport(const httplib::Request& req, njson& json, std::string& errmsg)
|
Errcode HttpEntity::exportStatReport(const httplib::Request& req, njson& json, std::string& errmsg)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -118,6 +118,9 @@ public:
|
|||||||
// 场站按类某一天的历史曲线数据
|
// 场站按类某一天的历史曲线数据
|
||||||
Errcode queryStatCharts(const httplib::Request& req, njson& json, std::string& errmsg);
|
Errcode queryStatCharts(const httplib::Request& req, njson& json, std::string& errmsg);
|
||||||
|
|
||||||
|
// 场站按周、月、季度、年统计: 充电量、放电量、 使用率=放电量/充电量、充电费、放电费、收益=放电费-充电费
|
||||||
|
Errcode queryStatStationMode(const httplib::Request& req, njson& json, std::string& errmsg);
|
||||||
|
|
||||||
Errcode exportStatReport(const httplib::Request& req, njson& json, std::string& errmsg);
|
Errcode exportStatReport(const httplib::Request& req, njson& json, std::string& errmsg);
|
||||||
|
|
||||||
Errcode queryEnvironment(const httplib::Request& req, njson& json, std::string& errmsg);
|
Errcode queryEnvironment(const httplib::Request& req, njson& json, std::string& errmsg);
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ export default {
|
|||||||
// areaStyle: {
|
// areaStyle: {
|
||||||
// global: false,
|
// global: false,
|
||||||
// color: {
|
// color: {
|
||||||
// type: 'linear', x: 0, y: 0, x2: 0, y2: 1,
|
// type: 'linear', x: 0, y: 0, x2: 0, y2: 1,
|
||||||
// colorStops: [
|
// colorStops: [
|
||||||
// { offset: 0, color: JSON.parse(JSON.stringify(item)).colorStart }, // 顶部颜色
|
// { offset: 0, color: JSON.parse(JSON.stringify(item)).colorStart }, // 顶部颜色
|
||||||
// { offset: 1, color: JSON.parse(JSON.stringify(item)).colorEnd } // 底部颜色
|
// { offset: 1, color: JSON.parse(JSON.stringify(item)).colorEnd } // 底部颜色
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ export default {
|
|||||||
{ title: '场站信息', class: '', componentId: markRaw( PrefabCabin), infoKey: 'prefab' },
|
{ title: '场站信息', class: '', componentId: markRaw( PrefabCabin), infoKey: 'prefab' },
|
||||||
{ title: '储能运行信息', class: 'operation-status', componentId: markRaw(OperationalInfo), infoKey: 'storage' },
|
{ title: '储能运行信息', class: 'operation-status', componentId: markRaw(OperationalInfo), infoKey: 'storage' },
|
||||||
{ title: '充电运行信息', class: 'operation-status', componentId: markRaw(OperationalInfo), infoKey: 'charge' },
|
{ title: '充电运行信息', class: 'operation-status', componentId: markRaw(OperationalInfo), infoKey: 'charge' },
|
||||||
{ title: '光伏运行信息', class: 'operation-status', componentId: markRaw(OperationalInfo), infoKey: 'pv' },
|
// { title: '光伏运行信息', class: 'operation-status', componentId: markRaw(OperationalInfo), infoKey: 'pv' },
|
||||||
{ title: '电网侧运行信息', class: 'operation-status', componentId: markRaw(OperationalInfo), infoKey: 'grid' },
|
{ title: '电网侧运行信息', class: 'operation-status', componentId: markRaw(OperationalInfo), infoKey: 'grid' },
|
||||||
{ title: '环境信息', class: 'envInfo', componentId:markRaw( EnvInfo), infoKey: 'envTotal' }
|
{ title: '环境信息', class: 'envInfo', componentId:markRaw( EnvInfo), infoKey: 'envTotal' }
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -64,14 +64,15 @@ export default {
|
|||||||
],
|
],
|
||||||
myItemsStats: [
|
myItemsStats: [
|
||||||
{ key: 'storage_device_num', value: '', label: '储能设备数量', d: '个' },
|
{ key: 'storage_device_num', value: '', label: '储能设备数量', d: '个' },
|
||||||
{ key: 'solar_device_num', value: '', label: '光伏设备数量', d: '个' },
|
// { key: 'solar_device_num', value: '', label: '光伏设备数量', d: '个' },
|
||||||
{ key: 'charge_device_num', value: '', label: '充电设备数量', d: '个' },
|
|
||||||
{ key: 'solar_elect_grid', value: '', label: '上网总电量', d: 'kWh' },
|
|
||||||
{ key: 'storage_elect_in', value: '', label: '储能充电总电量', d: 'kWh' },
|
{ key: 'storage_elect_in', value: '', label: '储能充电总电量', d: 'kWh' },
|
||||||
{ key: 'solar_elect_gen', value: '', label: '光伏发电总电量', d: 'kWh' },
|
|
||||||
{ key: 'charge_elect', value: '', label: '充电桩充电总电量', d: 'kWh' },
|
|
||||||
{ key: 'income_elect', value: '', label: '收益总金额', d: '元' },
|
|
||||||
{ key: 'storage_elect_out', value: '', label: '储能放电总电量', d: 'kWh' },
|
{ key: 'storage_elect_out', value: '', label: '储能放电总电量', d: 'kWh' },
|
||||||
|
// { key: 'solar_elect_gen', value: '', label: '光伏发电总电量', d: 'kWh' },
|
||||||
|
{ key: 'charge_device_num', value: '', label: '充电设备数量', d: '个' },
|
||||||
|
{ key: 'charge_elect', value: '', label: '充电桩充电总电量', d: 'kWh' },
|
||||||
|
// { key: 'solar_elect_grid', value: '', label: '上网总电量', d: 'kWh' },
|
||||||
|
{ key: 'income_elect', value: '', label: '收益总金额', d: '元' },
|
||||||
],
|
],
|
||||||
list: [
|
list: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -136,8 +136,8 @@ export default {
|
|||||||
smooth: true,
|
smooth: true,
|
||||||
type: 'line',
|
type: 'line',
|
||||||
barWidth: 10,
|
barWidth: 10,
|
||||||
itemStyle: { borderRadius: 10, color: item.lineColor },
|
itemStyle: {borderRadius: 10, color: item.lineColor},
|
||||||
emphasis: { focus: 'series' },
|
emphasis: {focus: 'series'},
|
||||||
global: false,
|
global: false,
|
||||||
showSymbol: false,
|
showSymbol: false,
|
||||||
data: []
|
data: []
|
||||||
|
|||||||
@@ -123,8 +123,8 @@ export default {
|
|||||||
smooth: true,
|
smooth: true,
|
||||||
type: 'line',
|
type: 'line',
|
||||||
barWidth: 10,
|
barWidth: 10,
|
||||||
itemStyle: { borderRadius: 10, color: item.lineColor },
|
itemStyle: {borderRadius: 10, color: item.lineColor},
|
||||||
emphasis: { focus: 'series' },
|
emphasis: {focus: 'series'},
|
||||||
global: false,
|
global: false,
|
||||||
showSymbol: false,
|
showSymbol: false,
|
||||||
data: []
|
data: []
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mychart">
|
<div class="mychartbox">
|
||||||
<!-- <div class="text_Cur">
|
<!-- <div class="text_Cur">
|
||||||
<div v-for="item in curList" :key="item.key">
|
<div v-for="item in curList" :key="item.key">
|
||||||
<div>{{ item.name }}</div>
|
<div>{{ item.name }}</div>
|
||||||
@@ -19,7 +19,7 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
propKey: { type: String, default: '' },
|
propKey: { type: String, default: '' },
|
||||||
propData: { type: Array, default: () => [] },
|
propData: { type: Array, default: () => [] },
|
||||||
propOption: { type: Object, default: { series: [] } }
|
propOption: { type: Object, default: ()=> ({ series: [] }) }
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -162,11 +162,13 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.mychart {
|
.mychartbox {
|
||||||
height: calc(100% - 35px);
|
height: calc(100% - 35px);
|
||||||
background-color: #80808010;
|
// background-color: #80808010;
|
||||||
|
background-color: rgba(33, 105, 195, 0.12);
|
||||||
|
|
||||||
.mychart {
|
.mychart {
|
||||||
|
margin-left: 5px;
|
||||||
height: calc(100% - 5px);
|
height: calc(100% - 5px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
178
web/src/components/Home/MyChartLine.vue
Normal file
178
web/src/components/Home/MyChartLine.vue
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
<template>
|
||||||
|
<div class="mychartbox">
|
||||||
|
<!-- <div class="text_Cur">
|
||||||
|
<div v-for="item in curList" :key="item.key">
|
||||||
|
<div>{{ item.name }}</div>
|
||||||
|
<span class="mark">{{ item.value ? item.value : 0 }}</span>
|
||||||
|
<span class="d">{{ item.d }}</span>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
<div :id="myChartId" class="mychart"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { processData } from '@/utils/dealWithData'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: '',
|
||||||
|
props: {
|
||||||
|
propKey: { type: String, default: '' },
|
||||||
|
propData: { type: Array, default: () => [] },
|
||||||
|
propOption: { type: Object, default: ()=> ({ series: [] }) }
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
myChartId: 'mychart' + Math.floor(Math.random() * 9999),
|
||||||
|
myEchart: null,
|
||||||
|
xData: [], // EChart的 x 轴 option
|
||||||
|
yData: [], // EChart的 y 轴 option
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
propData: {
|
||||||
|
handler(newVal, oldVal) {
|
||||||
|
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.drawLineChart()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true, // 初始化时更新
|
||||||
|
deep: true // 确保深度比较
|
||||||
|
},
|
||||||
|
propOption: {
|
||||||
|
handler(newVal, oldVal) {
|
||||||
|
},
|
||||||
|
immediate: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() { },
|
||||||
|
beforeUnmount() {
|
||||||
|
window.removeEventListener('resize', this.handleResize)
|
||||||
|
if (this.myEchart) {
|
||||||
|
this.myEchart.dispose()
|
||||||
|
this.myEchart = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
handleResize() {
|
||||||
|
if (this.myEchart) {
|
||||||
|
this.myEchart.resize()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getChartData() {
|
||||||
|
const keyList = this.propOption.series.map((item) => item.key)
|
||||||
|
const result = processData(this.propData, keyList)
|
||||||
|
this.xData = result.dates
|
||||||
|
this.yData = result.values
|
||||||
|
|
||||||
|
if (this.xData.length == 0) {
|
||||||
|
const today = new Date();
|
||||||
|
for (let i = 6; i >= 0; i--) {
|
||||||
|
const date = new Date(today); // 每次创建新日期实例(避免修改原日期)
|
||||||
|
date.setDate(today.getDate() - i); // 往前推 i 天
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份 0-11,需 +1
|
||||||
|
const day = String(date.getDate()).padStart(2, '0');
|
||||||
|
this.xData.push(`${month}-${day}`);
|
||||||
|
|
||||||
|
for (let j = 0; j < keyList.length; j++) {
|
||||||
|
if (j == 0) this.yData.push([])
|
||||||
|
else this.yData[j].push(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
drawLineChart(activeKey) {
|
||||||
|
|
||||||
|
this.getChartData(activeKey)
|
||||||
|
if (this.myEchart) {
|
||||||
|
this.myEchart.dispose()
|
||||||
|
}
|
||||||
|
const chartDom = document.getElementById(this.myChartId)
|
||||||
|
if (!chartDom) return;
|
||||||
|
let myEchart = this.$echarts.init(chartDom)
|
||||||
|
this.myEchart = myEchart
|
||||||
|
let option = {
|
||||||
|
animation: false,
|
||||||
|
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
|
||||||
|
legend: { top: 10, textStyle: { color: '#fff' } },
|
||||||
|
grid: { left: '3%', right: '4%', bottom: '1%', top: '32%' },
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: this.xData,
|
||||||
|
axisLine: { lineStyle: { type: 'dashed', color: '#435463' } },
|
||||||
|
axisLabel: { color: '#fff' }
|
||||||
|
},
|
||||||
|
yAxis: [],
|
||||||
|
series: []
|
||||||
|
}
|
||||||
|
|
||||||
|
const yAxisItem = {
|
||||||
|
name: '',
|
||||||
|
type: 'value',
|
||||||
|
// min: 0,
|
||||||
|
// max: 2,
|
||||||
|
//interval: 1, // 强制步长
|
||||||
|
splitNumber: 2, // 分段数
|
||||||
|
nameTextStyle: { color: '#fff' },
|
||||||
|
splitLine: { lineStyle: { type: 'dashed', color: '#435463' } },
|
||||||
|
axisLabel: { color: '#fff', fontSize: 12 },
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.propOption.yAxis) {
|
||||||
|
this.propOption.yAxis.forEach((item, index) => {
|
||||||
|
const maxVal = Math.max(...this.yData[index]);
|
||||||
|
if (maxVal && maxVal > 0) {
|
||||||
|
// yAxisItem.min = undefined
|
||||||
|
// yAxisItem.max = maxVal
|
||||||
|
}
|
||||||
|
yAxisItem.name = item
|
||||||
|
option.yAxis.push(yAxisItem)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.propOption.series) {
|
||||||
|
this.propOption.series.forEach((item, index) => {
|
||||||
|
option.series.push({
|
||||||
|
name: item.name,
|
||||||
|
type: item.type ? item.type : 'bar',
|
||||||
|
color: item.color,
|
||||||
|
data: this.yData[index],
|
||||||
|
barWidth: '20%',
|
||||||
|
// 关键:强制显示超出坐标轴范围的点
|
||||||
|
symbolKeep: true
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option.yAxis.length == 0) { option.yAxis.push(yAxisItem) }
|
||||||
|
option && myEchart.setOption(option)
|
||||||
|
this.setupResizeListener()
|
||||||
|
|
||||||
|
},
|
||||||
|
setupResizeListener() {
|
||||||
|
window.removeEventListener('resize', this.handleResize);
|
||||||
|
window.addEventListener('resize', this.handleResize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mychartbox {
|
||||||
|
height: calc(100% - 35px);
|
||||||
|
// background-color: #80808010;
|
||||||
|
// background-color: rgba(33, 105, 195, 0.12);
|
||||||
|
background-color: rgba(33, 105, 195, 0.12);
|
||||||
|
|
||||||
|
.mychart {
|
||||||
|
margin-left: 5px;
|
||||||
|
height: calc(100% - 5px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
<div class="total-station">
|
<div class="total-station">
|
||||||
<div class="content-my">
|
<div class="content-my">
|
||||||
<div v-for="item in myItems" :key="item.key" :class="`item ${item.class}`" >
|
<div v-for="item in myItems" :key="item.key" :class="`item ${item.class}`" >
|
||||||
<span style="color:#d0d0d0; margin: 0 0 0 0">{{ item.label }}</span>
|
<span style="height: 50%; color:#d0d0d0; margin: 0 0 0 0; font-size:14px; font-weight: 600; display: flex; align-items: center;">{{ item.label }}</span>
|
||||||
<div style="margin-left: 20%;">
|
<div style="height: 50%; margin-left: 20%;">
|
||||||
<span :style="{ 'color': item.color, 'font-size':'16px', 'font-weight':600}">{{ item.value ? item.value : (item.d ? 0 : '--') }}</span>
|
<span :style="{ 'color': item.color, 'font-size':'16px', 'font-weight':600}">{{ item.value ? item.value : (item.d ? 0 : '--') }}</span>
|
||||||
<span style="font-size:16px; margin-left: 8px;">{{ item.d }}</span>
|
<span style="font-size:16px; margin-left: 8px;">{{ item.d }}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -53,18 +53,10 @@ export default {
|
|||||||
return {
|
return {
|
||||||
myItems: [
|
myItems: [
|
||||||
{ color:'#a0f0a0', key: 'runDays', value: 0, label:'场站运行天数', d:'天'},
|
{ color:'#a0f0a0', key: 'runDays', value: 0, label:'场站运行天数', d:'天'},
|
||||||
// { color:'#a0f0a0', key: 'storage_device_num', value: 0, label:'储能设备数量', d:'个'},
|
|
||||||
// { color:'#a0f0a0', key: 'charge_device_num', value: 0, label:'充电设备数量', d:'个'},
|
|
||||||
// { color:'#a0f0a0', key: 'solar_device_num', value: 0, label:'光伏设备数量', d:'个'},
|
|
||||||
// { color:'#a0f0a0', key: 'solar_elect_grid', value: 0, label:'上网总电量', d:'kWh'},
|
|
||||||
{ color:'#a0f0a0', key: 'storage_elect_in', value: 0, label:'累计储能总电量', d:'kWh'},
|
{ color:'#a0f0a0', key: 'storage_elect_in', value: 0, label:'累计储能总电量', d:'kWh'},
|
||||||
// { color:'#a0f0a0', key: 'charge_elect_out', value: 0, label:'充电桩充电总电量', d:'kWh'},
|
|
||||||
// { color:'#a0f0a0', key: 'solar_elect_gen', value: 0, label:'光伏发电总电量', d:'kWh'},
|
|
||||||
{ color:'#a0f0a0', key: 'income_elect', value: 0, label:'累计收益总金额', d:'元'},
|
{ color:'#a0f0a0', key: 'income_elect', value: 0, label:'累计收益总金额', d:'元'},
|
||||||
// { color:'#a0f0a0', key: 'storage_elect_out', value: 0, label:'储能放电总电量', d:'kWh'},
|
|
||||||
{ color:'#a0f0a0', key: 'storage_status', value: '空闲', label:'储能状态'},
|
{ color:'#a0f0a0', key: 'storage_status', value: '空闲', label:'储能状态'},
|
||||||
{ color:'#a0f0a0', key: 'charge_status', value: '空闲', label:'充电状态'},
|
{ color:'#a0f0a0', key: 'charge_status', value: '空闲', label:'充电状态'},
|
||||||
{ color:'#a0f0a0', key: 'pv_status', value: '离线', label:'光伏状态'},
|
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="onLine">
|
<div class="onLine">
|
||||||
<div class="content-my">
|
<div class="content-my">
|
||||||
<div v-for="item in myItems" :key="item.key" :class="`item ${item.class}`" >
|
<div v-for="item in myItems" :key="item.key" :class="`item ${item.class}`" >
|
||||||
<span style="height: 50%; color:#d0d0d0; margin:0 0 0 0">{{ item.label }}</span>
|
<span style="height: 50%; color:#d0d0d0; margin:0 0 0 0; font-size:14px; font-weight: 600; display: flex; align-items: center;">{{ item.label }}</span>
|
||||||
<div style="height: 50%; margin-left: 20%;">
|
<div style="height: 50%; margin-left: 20%;">
|
||||||
<span style="color:#a0f0a0; font-size:16px; font-weight:600;">{{ item.value ? item.value : 0 }}</span>
|
<span style="color:#a0f0a0; font-size:16px; font-weight:600;">{{ item.value ? item.value : 0 }}</span>
|
||||||
<span style="font-size:16px; margin-left: 8px;">{{ item.d }}</span>
|
<span style="font-size:16px; margin-left: 8px;">{{ item.d }}</span>
|
||||||
@@ -55,11 +55,11 @@ export default {
|
|||||||
{ key: 'runDays', value: 0, label:'系统运行天数', d:'天'},
|
{ key: 'runDays', value: 0, label:'系统运行天数', d:'天'},
|
||||||
{ key: 'storage_device_num', value: 0, label:'储能设备数量', d:'个'},
|
{ key: 'storage_device_num', value: 0, label:'储能设备数量', d:'个'},
|
||||||
{ key: 'charge_device_num', value: 0, label:'充电设备数量', d:'个'},
|
{ key: 'charge_device_num', value: 0, label:'充电设备数量', d:'个'},
|
||||||
{ key: 'solar_device_num', value: 0, label:'光伏设备数量', d:'个'},
|
// { key: 'solar_device_num', value: 0, label:'光伏设备数量', d:'个'},
|
||||||
{ key: 'solar_elect_grid', value: 0, label:'上网总电量', d:'kWh'},
|
{ key: 'solar_elect_grid', value: 0, label:'上网总电量', d:'kWh'},
|
||||||
{ key: 'storage_elect_in', value: 0, label:'储能充电总电量', d:'kWh'},
|
{ key: 'storage_elect_in', value: 0, label:'储能充电总电量', d:'kWh'},
|
||||||
{ key: 'charge_elect_out', value: 0, label:'充电桩充电总电量', d:'kWh'},
|
{ key: 'charge_elect_out', value: 0, label:'充电桩充电总电量', d:'kWh'},
|
||||||
{ key: 'solar_elect_gen', value: 0, label:'光伏发电总电量', d:'kWh'},
|
// { key: 'solar_elect_gen', value: 0, label:'光伏发电总电量', d:'kWh'},
|
||||||
{ key: 'income_elect', value: 0, label:'累计收益总金额', d:'元'},
|
{ key: 'income_elect', value: 0, label:'累计收益总金额', d:'元'},
|
||||||
{ key: 'storage_elect_out', value: 0, label:'储能放电总电量', d:'kWh'},
|
{ key: 'storage_elect_out', value: 0, label:'储能放电总电量', d:'kWh'},
|
||||||
],
|
],
|
||||||
@@ -182,7 +182,7 @@ export default {
|
|||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
.item {
|
.item {
|
||||||
width: calc(25% - 6px);
|
width: calc(33% - 6px);
|
||||||
margin-left: 3px;
|
margin-left: 3px;
|
||||||
margin-right: 3px;
|
margin-right: 3px;
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
|
|||||||
@@ -35,8 +35,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- 日期选择框 date-->
|
<!-- 日期选择框 date-->
|
||||||
<div class="date-picker" v-if="item.type == 'datePick1'">
|
<div class="date-picker" v-if="item.type == 'datePick1'">
|
||||||
|
<a-range-picker :locale="locale"
|
||||||
<a-range-picker v-model:value="formData[item.key]" value-format="YYYY-MM-DD" @change="$emit('onSearch', formData)" />
|
v-model:value="formData[item.key]"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
:picker="datePicker"
|
||||||
|
@openChange="handleOpenChange"
|
||||||
|
@change="handleChange(item.key)" />
|
||||||
</div>
|
</div>
|
||||||
<!-- 输入框 -->
|
<!-- 输入框 -->
|
||||||
<div class="input" v-if="item.type == 'input'">
|
<div class="input" v-if="item.type == 'input'">
|
||||||
@@ -91,10 +95,21 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import {ref} from 'vue'
|
||||||
|
import zhCN from 'ant-design-vue/es/locale/zh_CN'
|
||||||
|
import locale from 'ant-design-vue/es/date-picker/locale/zh_CN'
|
||||||
|
import 'dayjs/locale/zh-cn'
|
||||||
|
|
||||||
|
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import 'dayjs/locale/zh-cn'
|
||||||
|
dayjs.locale('zh-cn')
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SearchBox',
|
name: 'SearchBox',
|
||||||
components: {},
|
components: {},
|
||||||
props: {
|
props: {
|
||||||
|
datePicker: { type: String, default: ()=> { return "date" }},
|
||||||
titleOption: {
|
titleOption: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {
|
default: () => {
|
||||||
@@ -143,6 +158,24 @@ export default {
|
|||||||
},
|
},
|
||||||
immediate: true,
|
immediate: true,
|
||||||
deep: true
|
deep: true
|
||||||
|
},
|
||||||
|
datePicker: {
|
||||||
|
handler(newVal) {
|
||||||
|
// 临时:处理 statisticalAnalysis.vue 中设置日期选择模式时,时间区间的默认值修正
|
||||||
|
// key = 'time' 只在 statisticalAnalysis.vue 中设置生效
|
||||||
|
const key = 'time';
|
||||||
|
if (!this.formData[key]) {
|
||||||
|
// 今天的日期
|
||||||
|
const date = new Date();
|
||||||
|
const dtNow = date.toISOString().split('T')[0];
|
||||||
|
// 7天前
|
||||||
|
date.setDate(date.getDate() - 7);
|
||||||
|
const dtStart = date.toISOString().split('T')[0];
|
||||||
|
this.formData[key] = [dtStart, dtNow]
|
||||||
|
}
|
||||||
|
this.handleChange(key)
|
||||||
|
},
|
||||||
|
immediate: true,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -169,14 +202,62 @@ export default {
|
|||||||
},
|
},
|
||||||
handelClick(type) {
|
handelClick(type) {
|
||||||
this.$emit('operateForm', type)
|
this.$emit('operateForm', type)
|
||||||
}
|
},
|
||||||
|
|
||||||
// handleChange() {
|
handleChange(key) {
|
||||||
// this.$emit("onSearch", this.formData);
|
if (this.formData[key] && this.formData[key][0]) {
|
||||||
// },
|
if (this.datePicker == "week") {
|
||||||
|
this.formData[key][0] = dayjs(this.formData[key][0]).startOf('week').format('YYYY-MM-DD')
|
||||||
|
} else if (this.datePicker == "month") {
|
||||||
|
this.formData[key][0] = dayjs(this.formData[key][0]).startOf('month').format('YYYY-MM-DD')
|
||||||
|
} else if (this.datePicker == "quarter") {
|
||||||
|
this.formData[key][0] = dayjs(this.formData[key][0]).startOf('quarter').format('YYYY-MM-DD')
|
||||||
|
} else if (this.datePicker == "year") {
|
||||||
|
this.formData[key][0] = dayjs(this.formData[key][0]).startOf('year').format('YYYY-MM-DD')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.formData[key] && this.formData[key][1]) {
|
||||||
|
if (this.datePicker == "week") {
|
||||||
|
this.formData[key][1] = dayjs(this.formData[key][1]).endOf('week').format('YYYY-MM-DD')
|
||||||
|
} else if (this.datePicker == "month") {
|
||||||
|
this.formData[key][1] = dayjs(this.formData[key][1]).endOf('month').format('YYYY-MM-DD')
|
||||||
|
} else if (this.datePicker == "quarter") {
|
||||||
|
this.formData[key][1] = dayjs(this.formData[key][1]).endOf('quarter').format('YYYY-MM-DD')
|
||||||
|
} else if (this.datePicker == "year") {
|
||||||
|
this.formData[key][1] = dayjs(this.formData[key][1]).endOf('year').format('YYYY-MM-DD')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.$emit("onSearch", this.formData);
|
||||||
|
},
|
||||||
// pressEnter() {
|
// pressEnter() {
|
||||||
// this.$emit("onSearch", this.formData);
|
// this.$emit("onSearch", this.formData);
|
||||||
// },
|
// },
|
||||||
|
|
||||||
|
handleOpenChange() {
|
||||||
|
if (open) {
|
||||||
|
// 延迟执行以确保 DOM 已渲染
|
||||||
|
setTimeout(() => {
|
||||||
|
const cells = document.querySelectorAll('.ant-picker-cell');
|
||||||
|
|
||||||
|
cells.forEach((cell) => {
|
||||||
|
const title = cell.getAttribute('title');
|
||||||
|
const innerDiv = cell.querySelector('.ant-picker-cell-inner');
|
||||||
|
|
||||||
|
if (title && innerDiv) {
|
||||||
|
// if (title.includes('Q1')) {
|
||||||
|
// innerDiv.textContent = '第一季度';
|
||||||
|
// } else if (title.includes('Q2')) {
|
||||||
|
// innerDiv.textContent = '第二季度';
|
||||||
|
// } else if (title.includes('Q3')) {
|
||||||
|
// innerDiv.textContent = '第三季度';
|
||||||
|
// } else if (title.includes('Q4')) {
|
||||||
|
// innerDiv.textContent = '第四季度';
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -191,6 +272,7 @@ input:-internal-autofill-selected {
|
|||||||
:deep(.anticon) {
|
:deep(.anticon) {
|
||||||
color: var(--theme-text-default) !important;
|
color: var(--theme-text-default) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search {
|
.search {
|
||||||
// height:70px;
|
// height:70px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@@ -259,7 +341,11 @@ input:-internal-autofill-selected {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
width: 80px;
|
// width: 65px;
|
||||||
|
flex: 1; /* 占满剩余空间 */
|
||||||
|
text-align: right; /* 文字右对齐 */
|
||||||
|
white-space: nowrap; /* 防止换行 */
|
||||||
|
margin-right: 10px; /* 右侧间隔10px */
|
||||||
color: var(--theme-text-default);
|
color: var(--theme-text-default);
|
||||||
}
|
}
|
||||||
.top-right,
|
.top-right,
|
||||||
@@ -338,4 +424,44 @@ input:-internal-autofill-selected {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// :deep(.ant-picker-cell-inner) {
|
||||||
|
// width: 75px !important;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /* 深度穿透修改季度/月份/日期面板里面的宽度 */
|
||||||
|
// :deep(.ant-picker-dropdown .ant-picker-cell-inner) {
|
||||||
|
// width: 100px !important; /* 你想要的宽度 */
|
||||||
|
// }
|
||||||
|
/* 方法1:匹配任意hash类名 */
|
||||||
|
// :deep(.ant-picker-dropdown .ant-picker-quarter-panel .ant-picker-cell-inner) {
|
||||||
|
// width: 100px !important;
|
||||||
|
// min-width: 100px !important;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /* 方法2:如果上面不生效,提高特异性 */
|
||||||
|
// :deep(.ant-picker-dropdown div.ant-picker-quarter-panel .ant-picker-cell-inner) {
|
||||||
|
// width: 100px !important;
|
||||||
|
// min-width: 100px !important;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /* 方法3:双重类名提高权重 */
|
||||||
|
// :deep(.ant-picker-dropdown .ant-picker-quarter-panel .ant-picker-cell.ant-picker-cell-inner) {
|
||||||
|
// width: 100px !important;
|
||||||
|
// min-width: 100px !important;
|
||||||
|
// }
|
||||||
|
// /* 放到全局样式文件(如 global.css 或 App.vue 中不加 scoped) */
|
||||||
|
// .ant-picker-dropdown .ant-picker-quarter-panel .ant-picker-cell-inner {
|
||||||
|
// width: 100px !important;
|
||||||
|
// min-width: 100px !important;
|
||||||
|
// }
|
||||||
|
|
||||||
|
/* 或者使用 :global 逃逸 scoped */
|
||||||
|
:global(.ant-picker-dropdown .ant-picker-quarter-panel .ant-picker-cell-inner) {
|
||||||
|
width: 50px !important;
|
||||||
|
min-width: 50px !important;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -152,10 +152,10 @@ export default {
|
|||||||
key: 'fire40',
|
key: 'fire40',
|
||||||
name: '消防信息'
|
name: '消防信息'
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
key: 'airc',
|
// key: 'airc',
|
||||||
name: '空调信息'
|
// name: '空调信息'
|
||||||
},
|
// },
|
||||||
],
|
],
|
||||||
tableDatas: {},
|
tableDatas: {},
|
||||||
|
|
||||||
@@ -270,7 +270,7 @@ export default {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
.env-item {
|
.env-item {
|
||||||
width: 24%;
|
width: 30%;
|
||||||
|
|
||||||
.tab {
|
.tab {
|
||||||
&>span {
|
&>span {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export const policyTypes = [
|
|||||||
|
|
||||||
{
|
{
|
||||||
value: '5',
|
value: '5',
|
||||||
label: '自定时段'
|
label: '运营支撑'
|
||||||
}
|
}
|
||||||
// {
|
// {
|
||||||
// value: '2',
|
// value: '2',
|
||||||
|
|||||||
@@ -154,16 +154,16 @@ export default {
|
|||||||
// { v: '数量', key: 'num' }
|
// { v: '数量', key: 'num' }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
name: '光伏设备',
|
// name: '光伏设备',
|
||||||
power: 60,
|
// power: 60,
|
||||||
num: 62,
|
// num: 62,
|
||||||
systemType: 3,
|
// systemType: 3,
|
||||||
titles: [
|
// titles: [
|
||||||
//{ v: '总功率', key: 'power', sufix: 'kW' },
|
// //{ v: '总功率', key: 'power', sufix: 'kW' },
|
||||||
// { v: '数量', key: 'num' }
|
// // { v: '数量', key: 'num' }
|
||||||
]
|
// ]
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
name: '辅助设备',
|
name: '辅助设备',
|
||||||
power: 60,
|
power: 60,
|
||||||
|
|||||||
@@ -12,9 +12,21 @@
|
|||||||
<span>{{ item.name }}</span>
|
<span>{{ item.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div v-if="activeKey == 4">
|
||||||
|
<a-radio-group v-model:value="datePickerMode" class="my-radio-group" @change="onStatTypeChanged">
|
||||||
|
<a-radio-button style="width: 60px;" value="date">天</a-radio-button>
|
||||||
|
<a-radio-button style="width: 60px;" value="week">周</a-radio-button>
|
||||||
|
<a-radio-button style="width: 60px;" value="month">月</a-radio-button>
|
||||||
|
<a-radio-button style="width: 60px;" value="quarter">季度</a-radio-button>
|
||||||
|
<a-radio-button style="width: 60px;" value="year">年</a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
</div>
|
||||||
|
|
||||||
<searchBox
|
<searchBox
|
||||||
class="searchBox"
|
class="searchBox"
|
||||||
ref="searchBox"
|
ref="searchBox"
|
||||||
|
:date-picker="datePickerMode"
|
||||||
:btn-option-list="btnOptionList"
|
:btn-option-list="btnOptionList"
|
||||||
:search-options="searchOptions"
|
:search-options="searchOptions"
|
||||||
:title-option="{ title: '', info: '' }"
|
:title-option="{ title: '', info: '' }"
|
||||||
@@ -59,9 +71,22 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="activeKey == 4" class="content-table-4" >
|
<div v-if="activeKey == 4" class="content-table-4" >
|
||||||
|
<div style="display: flex; height: 30%; margin-bottom: 10px; ">
|
||||||
|
<MyChartLine style="width: calc(33% - 5px); height: 100%; margin-bottom: 10px;"
|
||||||
|
propKey="chart1" :prop-option="chartPropOption1" :prop-data="chartData">
|
||||||
|
</MyChartLine>
|
||||||
|
<MyChartLine style="width:calc(33% - 5px); height: 100%; margin-left: 10px;"
|
||||||
|
propKey="chart2" :prop-option="chartPropOption2" :prop-data="chartData">
|
||||||
|
</MyChartLine>
|
||||||
|
<MyChartLine style="width:calc(33% - 5px); height: 100%; margin-left: 10px;"
|
||||||
|
propKey="chart3" :prop-option="chartPropOption3" :prop-data="chartData">
|
||||||
|
</MyChartLine>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<ComTable
|
<ComTable
|
||||||
:tableH="tableH"
|
:tableH="tableH"
|
||||||
:columns="columns"
|
:columns="tableColumns"
|
||||||
:table-data="tableData"
|
:table-data="tableData"
|
||||||
:table-option="{ page: false, select: false}">
|
:table-option="{ page: false, select: false}">
|
||||||
<template #action="record">
|
<template #action="record">
|
||||||
@@ -77,12 +102,47 @@ import energyEchart from '@/components/statisticalAnalysis/energyEchart.vue'
|
|||||||
import searchBox from '@/components/SearchBox.vue'
|
import searchBox from '@/components/SearchBox.vue'
|
||||||
import { postReq, getReq } from '@/request/api'
|
import { postReq, getReq } from '@/request/api'
|
||||||
import {downloadByUrl} from '@/utils/download'
|
import {downloadByUrl} from '@/utils/download'
|
||||||
|
import MyChartLine from '@/components/Home/MyChartLine.vue'
|
||||||
|
|
||||||
|
import { ref, computed } from 'vue'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'StatisicalAnView',
|
name: 'StatisicalAnView',
|
||||||
components: { energyEchart, searchBox },
|
components: { energyEchart, searchBox },
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
chartInfo: { title: '系统运行统计', infoKey: 'total' },
|
||||||
|
chartPropOption1: {
|
||||||
|
yAxis: ['电量(kWh)'],
|
||||||
|
series: [
|
||||||
|
{ name: '充电电量', key: 'E_in', color: '#2a82e4' },
|
||||||
|
{ name: '放电电量', key: 'E_out', color: '#5aabf2' },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
chartData: [
|
||||||
|
],
|
||||||
|
chartPropOption2: {
|
||||||
|
yAxis: ['充放使用率(%)'],
|
||||||
|
series: [
|
||||||
|
{ name: '使用率', key: 'E_rate', color: '#2a82e4', type: "line" },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
chartPropOption3: {
|
||||||
|
yAxis: ['费用(元)'],
|
||||||
|
series: [
|
||||||
|
{ name: '充电费', key: 'fee_in', color: '#2a82e4', type: "bar" },
|
||||||
|
{ name: '放电费', key: 'fee_out', color: '#5aabf2', type: "bar" },
|
||||||
|
{ name: '收益', key: 'income', color: '#0cdaf5', type: "bar" },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
datePickerMode: "date",
|
||||||
|
formDatetime: {
|
||||||
|
start: '',
|
||||||
|
end: ''
|
||||||
|
},
|
||||||
|
|
||||||
btnOptionList: [],
|
btnOptionList: [],
|
||||||
loading: {
|
loading: {
|
||||||
chart: false,
|
chart: false,
|
||||||
@@ -99,7 +159,7 @@ export default {
|
|||||||
key: 'time'
|
key: 'time'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '场站切换',
|
label: '场站选择',
|
||||||
type: 'slot',
|
type: 'slot',
|
||||||
value: [],
|
value: [],
|
||||||
key: 'station',
|
key: 'station',
|
||||||
@@ -455,23 +515,10 @@ export default {
|
|||||||
activeKey: 1,
|
activeKey: 1,
|
||||||
interval: null,
|
interval: null,
|
||||||
tabList: [
|
tabList: [
|
||||||
{
|
{ key: 1, name: '储能设备' },
|
||||||
key: 1,
|
{ key: 2, name: '充电设备' },
|
||||||
name: '储能设备'
|
// { key: 3, name: '光伏设备' },
|
||||||
},
|
{ key: 4, name: '运行效益' }
|
||||||
|
|
||||||
{
|
|
||||||
key: 2,
|
|
||||||
name: '充电设备'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 3,
|
|
||||||
name: '光伏设备'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 4,
|
|
||||||
name: '策略运行效益'
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
tableList: {
|
tableList: {
|
||||||
1: {
|
1: {
|
||||||
@@ -657,15 +704,22 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
columns: [
|
//每个站显示使用率=放电量/充电量、收益=放电费-充电费,按周、月、季度、年;
|
||||||
|
tableColumns: [
|
||||||
{ title: '日期', dataIndex: 'dt', key: 'dt' },
|
{ title: '日期', dataIndex: 'dt', key: 'dt' },
|
||||||
{ title: '时段', dataIndex: 'period', key: 'period', ellipsis: true}, // fixed: 'left', // filterable: true
|
|
||||||
{ title: '储能充电电量(kWh)', dataIndex: 'E_in', key: 'E_in'},
|
{ title: '储能充电电量(kWh)', dataIndex: 'E_in', key: 'E_in'},
|
||||||
{ title: '储能放电电量(kWh)', dataIndex: 'E_out', key: 'E_out'},
|
{ title: '储能放电电量(kWh)', dataIndex: 'E_out', key: 'E_out'},
|
||||||
{ title: '电网价格(元/kWh)', dataIndex: 'grid_price', key: 'gridPrice' },
|
{ title: '充放使用率(%)', dataIndex: 'E_rate', key: 'E_rate'},
|
||||||
{ title: '充电价格(元/kWh)', dataIndex: 'charge_price', key: 'chargePrice' },
|
{ title: '储能充电费(元)', dataIndex: 'fee_in', key: 'fee_in'},
|
||||||
|
{ title: '储能放电费(元)', dataIndex: 'fee_out', key: 'fee_out'},
|
||||||
{ title: '收益(元)', dataIndex: 'income', key: 'income'},
|
{ title: '收益(元)', dataIndex: 'income', key: 'income'},
|
||||||
{ title: '操作', dataIndex: 'operate', key: 'operate', scopedSlots: { customRender: 'action' } }
|
// { title: '时段', dataIndex: 'period', key: 'period', ellipsis: true}, // fixed: 'left', // filterable: true
|
||||||
|
// { title: '储能充电电量(kWh)', dataIndex: 'E_in', key: 'E_in' },
|
||||||
|
// { title: '储能放电电量(kWh)', dataIndex: 'E_out', key: 'E_out' },
|
||||||
|
// { title: '电网价格(元/kWh)', dataIndex: 'grid_price', key: 'gridPrice' },
|
||||||
|
// { title: '充电价格(元/kWh)', dataIndex: 'charge_price', key: 'chargePrice' },
|
||||||
|
// { title: '收益(元)', dataIndex: 'income', key: 'income' },
|
||||||
|
// { title: '操作', dataIndex: 'operate', key: 'operate', scopedSlots: { customRender: 'action' } }
|
||||||
],
|
],
|
||||||
|
|
||||||
tableData: [
|
tableData: [
|
||||||
@@ -676,17 +730,21 @@ export default {
|
|||||||
// {period: "总计", gridPrice: "0.8", chargePrice: "0.6", income: "0.2", elect: "35", incomeTotal: "100"}
|
// {period: "总计", gridPrice: "0.8", chargePrice: "0.6", income: "0.2", elect: "35", incomeTotal: "100"}
|
||||||
|
|
||||||
],
|
],
|
||||||
tableH: 500
|
tableH: 500,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
activeKey: {
|
activeKey: {
|
||||||
handler(newVal) {
|
handler(newVal) {
|
||||||
if (!newVal) return
|
if (!newVal) return
|
||||||
|
|
||||||
|
console.log("activeKey=", this.activeKey)
|
||||||
// 清除之前的数据
|
// 清除之前的数据
|
||||||
this.resetDataForInactiveKey()
|
this.resetDataForInactiveKey()
|
||||||
|
|
||||||
if (newVal !== 4) {
|
if (newVal !== 4) {
|
||||||
|
this.datePickerMode = "date"
|
||||||
|
|
||||||
// 并行加载新数据
|
// 并行加载新数据
|
||||||
Promise.all([
|
Promise.all([
|
||||||
this.getStationList(),
|
this.getStationList(),
|
||||||
@@ -699,6 +757,9 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
console.log("4")
|
||||||
|
this.datePickerMode = "date"
|
||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
const elementTable = document.getElementsByClassName('content-table-4')[0]
|
const elementTable = document.getElementsByClassName('content-table-4')[0]
|
||||||
if ( elementTable) {
|
if ( elementTable) {
|
||||||
@@ -709,6 +770,16 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// immediate: true // 添加立即执行
|
// immediate: true // 添加立即执行
|
||||||
|
},
|
||||||
|
datePickerMode: {
|
||||||
|
handler(newVal) {
|
||||||
|
if (!newVal) return
|
||||||
|
if (this.activeKey == 4) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.getEGridPeriod()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -717,13 +788,14 @@ export default {
|
|||||||
console.log('mounted')
|
console.log('mounted')
|
||||||
// 优先加载第一个页面(activeKey=1)所需的数据
|
// 优先加载第一个页面(activeKey=1)所需的数据
|
||||||
// this.btnOptionList = this.$getBtns(['导出'])
|
// this.btnOptionList = this.$getBtns(['导出'])
|
||||||
|
|
||||||
|
// searchBox 的 onSearch 在初始化的时候也会触发查询
|
||||||
Promise.all([
|
Promise.all([
|
||||||
this.getStationList()
|
this.getStationList()
|
||||||
|
|
||||||
]).then(()=>{
|
]).then(()=>{
|
||||||
this.getEchartsListForActiveKey(),
|
// this.getEchartsListForActiveKey(),
|
||||||
this.getTableListForActiveKey()
|
// this.getTableListForActiveKey()
|
||||||
this.getStatCharts()
|
// this.getStatCharts()
|
||||||
this.startRealtimeRefresh()
|
this.startRealtimeRefresh()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -740,6 +812,11 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onStatTypeChanged(e){
|
||||||
|
const newValue = e.target.value;
|
||||||
|
this.datePickerMode = newValue
|
||||||
|
},
|
||||||
|
|
||||||
operateForm(type, record = {}) {
|
operateForm(type, record = {}) {
|
||||||
if (type == 'output') {
|
if (type == 'output') {
|
||||||
this.loading.chart=true
|
this.loading.chart=true
|
||||||
@@ -867,7 +944,6 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async getStationList() {
|
async getStationList() {
|
||||||
console.log('getsStationList')
|
|
||||||
const params = {
|
const params = {
|
||||||
page_size: 1000,
|
page_size: 1000,
|
||||||
page: 1
|
page: 1
|
||||||
@@ -901,17 +977,20 @@ export default {
|
|||||||
this.getTableListForActiveKey()
|
this.getTableListForActiveKey()
|
||||||
},
|
},
|
||||||
onSearch(data) {
|
onSearch(data) {
|
||||||
|
// search组件日期变化
|
||||||
this.paramsDate.start_date = data.time ? data.time[0] : ''
|
this.paramsDate.start_date = data.time ? data.time[0] : ''
|
||||||
this.paramsDate.end_date = data.time ? data.time[1] : ''
|
this.paramsDate.end_date = data.time ? data.time[1] : ''
|
||||||
|
|
||||||
if (this.activeKey !== 4) {
|
if (this.activeKey !== 4) {
|
||||||
this.tableList[this.activeKey].pageOption.page = 1
|
this.tableList[this.activeKey].pageOption.page = 1
|
||||||
this.getStationList(), this.getStatCharts(),this.getEchartsListForActiveKey(), this.getTableListForActiveKey()
|
//this.getStationList(),
|
||||||
|
this.getStatCharts(),this.getEchartsListForActiveKey(), this.getTableListForActiveKey()
|
||||||
} else {
|
} else {
|
||||||
this.getEGridPeriod()
|
this.getEGridPeriod()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
changeStation() {
|
changeStation() {
|
||||||
|
// search组件场站变化
|
||||||
if (this.activeKey != 4) {
|
if (this.activeKey != 4) {
|
||||||
this.getStatCharts()
|
this.getStatCharts()
|
||||||
this.getEchartsListForActiveKey()
|
this.getEchartsListForActiveKey()
|
||||||
@@ -946,32 +1025,47 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async getEGridPeriod() {
|
async getEGridPeriod() {
|
||||||
|
console.log("getEGridPeriod")
|
||||||
const query = {
|
const query = {
|
||||||
dt_start:this.paramsDate.start_date,
|
start_date:this.paramsDate.start_date,
|
||||||
dt_end: this.paramsDate.end_date,
|
end_date: this.paramsDate.end_date,
|
||||||
station_id: this.stationId,
|
station_id: this.stationId,
|
||||||
|
mode: this.datePickerMode
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!query.dt_end) {
|
if (!query.end_date) {
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
const year = today.getFullYear();
|
const year = today.getFullYear();
|
||||||
const month = String(today.getMonth() + 1).padStart(2, '0'); // 处理月份:先+1(因为getMonth返回0-11),再补零到2位
|
const month = String(today.getMonth() + 1).padStart(2, '0'); // 处理月份:先+1(因为getMonth返回0-11),再补零到2位
|
||||||
const day = String(today.getDate()).padStart(2, '0'); // 处理日期:直接补零到2位
|
const day = String(today.getDate()).padStart(2, '0'); // 处理日期:直接补零到2位
|
||||||
query.dt_end = `${year}-${month}-${day}`; // 拼接成指定格式
|
query.end_date = `${year}-${month}-${day}`; // 拼接成指定格式
|
||||||
}
|
}
|
||||||
if (!query.dt_start) {
|
if (!query.start_date) {
|
||||||
query.dt_start = query.dt_end;
|
query.start_date = query.end_date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// const res = await getReq('/queryEGridPeriod', query)
|
||||||
|
// if (res.errcode === 0) {
|
||||||
|
// this.tableData = res.data
|
||||||
|
// } else {
|
||||||
|
// throw res
|
||||||
|
// }
|
||||||
|
// } catch (error) {
|
||||||
|
// this.tableData = []
|
||||||
|
// }
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await getReq('/queryEGridPeriod', query)
|
const res = await getReq('/queryStatStationMode', query)
|
||||||
if (res.errcode === 0) {
|
if (res.errcode === 0) {
|
||||||
this.tableData = res.data
|
this.tableData = res.data
|
||||||
|
this.chartData = res.data
|
||||||
} else {
|
} else {
|
||||||
throw res
|
throw res
|
||||||
}
|
}
|
||||||
}catch (error) {
|
}catch (error) {
|
||||||
this.tableData = []
|
this.tableData = []
|
||||||
|
this.chartData = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1015,7 +1109,7 @@ export default {
|
|||||||
.content-table-4 {
|
.content-table-4 {
|
||||||
// overflow: scroll;
|
// overflow: scroll;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc(100% - 52px);
|
height: calc(70% - 52px);
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
//overflow: hidden;
|
//overflow: hidden;
|
||||||
|
|
||||||
@@ -1024,6 +1118,43 @@ export default {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 选中后的背景色 + 文字色 */
|
||||||
|
.my-radio-group {
|
||||||
|
/* 修改默认状态的字体和背景色 */
|
||||||
|
:deep(.ant-radio-button-wrapper) {
|
||||||
|
/* 字体设置 */
|
||||||
|
// font-size: 14px; /* 字体大小 */
|
||||||
|
// font-weight: 500; /* 字体粗细 */
|
||||||
|
// font-family: 'Microsoft YaHei', 'PingFang SC', sans-serif; /* 字体类型 */
|
||||||
|
color: white; /* 字体颜色 */
|
||||||
|
|
||||||
|
/* 背景色 */
|
||||||
|
background-color: #08365c; /* 背景色 - 浅灰/白色调 */
|
||||||
|
border-color: #12fbff; /* 边框颜色 */
|
||||||
|
|
||||||
|
/* 去掉右侧分割线颜色 */
|
||||||
|
&::before {
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 选中状态的背景色 */
|
||||||
|
:deep(.ant-radio-button-wrapper-checked) {
|
||||||
|
background-color: #1890ff; /* 自定义颜色 */
|
||||||
|
border-color: #12fbff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /* 鼠标 hover 效果(可选) */
|
||||||
|
// :deep(.ant-radio-button-wrapper:not(.ant-radio-button-checked):hover) {
|
||||||
|
// border-color: #1890ff;
|
||||||
|
// color:red;
|
||||||
|
// // color: #1890ff;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.main_content {
|
.main_content {
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
height: calc(100% - 40px);
|
height: calc(100% - 40px);
|
||||||
|
|||||||
@@ -32,7 +32,8 @@
|
|||||||
<span class="linear-text">{{ item.title }}</span>
|
<span class="linear-text">{{ item.title }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<component :is="item.componentId" :prop-key="item.infoKey" :prop-option="compInfo[item.infoKey]"
|
<component
|
||||||
|
:is="item.componentId" :prop-key="item.infoKey" :prop-option="compInfo[item.infoKey]"
|
||||||
:prop-data="compDataStation[item.infoKey]">
|
:prop-data="compDataStation[item.infoKey]">
|
||||||
</component>
|
</component>
|
||||||
</div>
|
</div>
|
||||||
@@ -50,6 +51,7 @@ import Pv from '@/components/Home/Pv.vue'
|
|||||||
import Alarm from '@/components/Home/Alarm.vue'
|
import Alarm from '@/components/Home/Alarm.vue'
|
||||||
import Map from '@/components/Home/Map.vue'
|
import Map from '@/components/Home/Map.vue'
|
||||||
import MyChartBar from '@/components/Home/MyChartBar.vue'
|
import MyChartBar from '@/components/Home/MyChartBar.vue'
|
||||||
|
import MyChartLine from '@/components/Home/MyChartLine.vue'
|
||||||
import { getReq, postReq } from '@/request/api'
|
import { getReq, postReq } from '@/request/api'
|
||||||
import { getRunDays, getDateDaysAgo } from '@/utils/dealWithData'
|
import { getRunDays, getDateDaysAgo } from '@/utils/dealWithData'
|
||||||
import { markRaw } from 'vue'
|
import { markRaw } from 'vue'
|
||||||
@@ -80,82 +82,46 @@ export default {
|
|||||||
energy: {
|
energy: {
|
||||||
yAxis: ['电量(kWh)'],
|
yAxis: ['电量(kWh)'],
|
||||||
series: [
|
series: [
|
||||||
{ name: '日充电电量', key: 'storage_elect_in', color: '#22E4FF' },
|
{ name: '日充电电量', key: 'E_in', color: '#0E68E4' },
|
||||||
{ name: '日放电电量', key: 'storage_elect_out', color: '#0E68E4' },
|
{ name: '日放电电量', key: 'E_out', color: '#69b0e7' },
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
pv: {
|
rate: {
|
||||||
yAxis: ['电量(kWh)'],
|
yAxis: ['百分比(%)'],
|
||||||
series: [
|
series: [
|
||||||
{ name: '日发电电量', key: 'solar_elect_gen', color: '#22E4FF' },
|
{ name: '充放电使用率', key: 'E_rate', color: '#0E68E4', type: "line"},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
charge: {
|
income: {
|
||||||
yAxis: ['电量(kWh)'],
|
yAxis: ['金额(元)'],
|
||||||
series: [
|
series: [
|
||||||
{ name: '日充电电量', key: 'charge_elect', color: '#22E4FF' },
|
{ name: '充电费', key: 'fee_in', color: '#0E68E4' },
|
||||||
]
|
{ name: '放电费', key: 'fee_out', color: '#69b0e7' },
|
||||||
},
|
{ name: '收益', key: 'income', color: '#22E4FF' },
|
||||||
stateGrid: {
|
|
||||||
yAxis: ['电量(kWh)'],
|
|
||||||
series: [
|
|
||||||
{ name: '日上网电量', key: 'solar_elect_grid', color: '#22E4FF' },
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
listLeft: [
|
listLeft: [
|
||||||
{ title: '系统运行统计', class: 'online-status', componentId: markRaw(onLine), infoKey: 'total' },
|
{ title: '系统运行统计', class: 'online-status', componentId: markRaw(onLine), infoKey: 'total' },
|
||||||
{ title: '储能设备', class: 'energy-status', componentId: markRaw(MyChartBar), infoKey: 'energy' },
|
{ title: '储能充放电量', class: 'energy-status', componentId: markRaw(MyChartBar), infoKey: 'energy' },
|
||||||
{ title: '充电设备', class: 'charge-analysis', componentId: markRaw(MyChartBar), infoKey: 'charge' },
|
{ title: '储能充放使用率', class: 'charge-analysis', componentId: markRaw(MyChartLine), infoKey: 'rate' },
|
||||||
{ title: '光伏设备', class: 'work-order', componentId: markRaw(MyChartBar), infoKey: 'pv' },
|
{ title: '储能收益', class: 'work-order', componentId: markRaw(MyChartBar), infoKey: 'income' }
|
||||||
{ title: '电网侧', class: 'work-order', componentId: markRaw(MyChartBar), infoKey: 'stateGrid' },
|
|
||||||
],
|
],
|
||||||
listRight: [
|
listRight: [
|
||||||
{ title: '场站运行统计', class: 'online-status', componentId: markRaw(TotalStation), infoKey: 'totalStation' },
|
{ title: '场站运行统计', class: 'online-status', componentId: markRaw(TotalStation), infoKey: 'totalStation' },
|
||||||
{ title: '储能设备', class: 'energy-status', componentId: markRaw(MyChartBar), infoKey: 'energy' },
|
{ title: '储能充放电量', class: 'energy-status', componentId: markRaw(MyChartBar), infoKey: 'energy' },
|
||||||
{ title: '充电设备', class: 'charge-analysis', componentId: markRaw(MyChartBar), infoKey: 'charge' },
|
{ title: '储能充放使用率', class: 'charge-analysis', componentId: markRaw(MyChartLine), infoKey: 'rate' },
|
||||||
{ title: '光伏设备', class: 'work-order', componentId: markRaw(MyChartBar), infoKey: 'pv' },
|
{ title: '储能收益', class: 'work-order', componentId: markRaw(MyChartBar), infoKey: 'income' }
|
||||||
{ title: '电网侧', class: 'work-order', componentId: markRaw(MyChartBar), infoKey: 'stateGrid' },
|
|
||||||
],
|
],
|
||||||
stationList: [],
|
stationList: [],
|
||||||
selectStationId: '',
|
selectStationId: '',
|
||||||
list: [
|
list: [
|
||||||
{
|
{ title: '系统运行统计', class: 'online-status', componentId: markRaw(onLine), infoKey: 'onLineTotal' },
|
||||||
title: '系统运行统计',
|
{ title: '运行分析', class: 'stats-cards', componentId: markRaw(Operational), infoKey: 'operationTotal' },
|
||||||
class: 'online-status',
|
{ title: '储能设备', class: 'energy-status', componentId: markRaw(Energy), infoKey: 'energy' },
|
||||||
componentId: markRaw(onLine),
|
{ title: '充电设备', class: 'charge-analysis', componentId: markRaw(Charge), infoKey: 'charge' },
|
||||||
infoKey: 'onLineTotal'
|
{ title: '光伏设备', class: 'work-order', componentId: markRaw(Pv), infoKey: 'pv' },
|
||||||
},
|
{ title: '告警信息', class: 'alarm-stats', componentId: markRaw(Alarm), infoKey: 'alarm' }
|
||||||
{
|
|
||||||
title: '运行分析',
|
|
||||||
class: 'stats-cards',
|
|
||||||
componentId: markRaw(Operational),
|
|
||||||
infoKey: 'operationTotal'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '储能设备',
|
|
||||||
class: 'energy-status',
|
|
||||||
componentId: markRaw(Energy),
|
|
||||||
infoKey: 'energy'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '充电设备',
|
|
||||||
class: 'charge-analysis',
|
|
||||||
componentId: markRaw(Charge),
|
|
||||||
infoKey: 'charge'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '光伏设备',
|
|
||||||
class: 'work-order',
|
|
||||||
componentId: markRaw(Pv),
|
|
||||||
infoKey: 'pv'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '告警信息',
|
|
||||||
class: 'alarm-stats',
|
|
||||||
componentId: markRaw(Alarm),
|
|
||||||
infoKey: 'alarm'
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
|
|
||||||
sysName: '',
|
sysName: '',
|
||||||
@@ -291,19 +257,17 @@ export default {
|
|||||||
query.station_id = curStationId
|
query.station_id = curStationId
|
||||||
}
|
}
|
||||||
//const arr = { 1: 'energy', 2: 'charge', 3: 'pv' }
|
//const arr = { 1: 'energy', 2: 'charge', 3: 'pv' }
|
||||||
const res = await getReq('/queryStatDayList', query)
|
const res = await getReq('/queryStatStationMode', query) // queryStatDayList
|
||||||
if (res.errcode === 0) {
|
if (res.errcode === 0) {
|
||||||
if (curStationId) {
|
if (curStationId) {
|
||||||
this.compDataStation.energy
|
this.compDataStation.energy
|
||||||
= this.compDataStation.charge
|
= this.compDataStation.rate
|
||||||
= this.compDataStation.pv
|
= this.compDataStation.income
|
||||||
= this.compDataStation.stateGrid
|
|
||||||
= res.data
|
= res.data
|
||||||
} else {
|
} else {
|
||||||
this.compData.energy
|
this.compData.energy
|
||||||
= this.compData.pv
|
= this.compData.rate
|
||||||
= this.compData.stateGrid
|
= this.compData.income
|
||||||
= this.compData.charge
|
|
||||||
= res.data
|
= res.data
|
||||||
}
|
}
|
||||||
// this.list.forEach((item) => {
|
// this.list.forEach((item) => {
|
||||||
@@ -391,7 +355,7 @@ export default {
|
|||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
background-clip: text;
|
background-clip: text;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 400;
|
font-weight: 800;
|
||||||
margin-left: 6px;
|
margin-left: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="alarmLog">
|
<div class="alarmLog">
|
||||||
<!-- <searchBox :btn-option-list="btnOptionList" @operateForm="operateForm"></searchBox> -->
|
<!-- <searchBox :btn-option-list="btnOptionList" @operateForm="operateForm"></searchBox> -->
|
||||||
|
<searchBox class="searchBox" ref="searchBox" :search-options="searchOptions" :title-option="{ title: '', info: '' }">
|
||||||
|
<template #stationSelect="">
|
||||||
|
<a-select style="width: 200px" :dropdown-match-select-width="false" v-model:value="stationId" allow-clear @change="changeStation">
|
||||||
|
<a-select-option :value="option.value" v-for="option in stationList" :key="option.value">
|
||||||
|
{{ option.label }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</template>
|
||||||
|
</searchBox>
|
||||||
|
|
||||||
<div class="content-table">
|
<div class="content-table">
|
||||||
<ComTable
|
<ComTable
|
||||||
@@ -44,12 +53,11 @@ import { getReq, postReq } from '@/request/api.js'
|
|||||||
import EditCom from '@/components/EditCom.vue'
|
import EditCom from '@/components/EditCom.vue'
|
||||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
|
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
|
||||||
import { createVNode } from 'vue'
|
import { createVNode } from 'vue'
|
||||||
|
import searchBox from '@/components/SearchBox.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: '',
|
name: '',
|
||||||
components: {
|
components: { EditCom, searchBox },
|
||||||
EditCom
|
|
||||||
},
|
|
||||||
props: {},
|
props: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -61,6 +69,11 @@ export default {
|
|||||||
page: 1
|
page: 1
|
||||||
},
|
},
|
||||||
btnOptionList: [],
|
btnOptionList: [],
|
||||||
|
searchOptions: [
|
||||||
|
{label: '场站选择', type: 'slot', value: [], key: 'station', slotName: 'stationSelect'}
|
||||||
|
],
|
||||||
|
stationId: undefined,
|
||||||
|
stationList: [],
|
||||||
paramsDate: {},
|
paramsDate: {},
|
||||||
tableData: []
|
tableData: []
|
||||||
}
|
}
|
||||||
@@ -80,16 +93,42 @@ export default {
|
|||||||
mounted() {
|
mounted() {
|
||||||
this.operateList = this.$getBtns(['查看'])
|
this.operateList = this.$getBtns(['查看'])
|
||||||
// this.btnOptionList = this.$getBtns(['新增'])
|
// this.btnOptionList = this.$getBtns(['新增'])
|
||||||
|
Promise.all([
|
||||||
|
this.getStationList()
|
||||||
|
]).then(()=>{
|
||||||
this.getList()
|
this.getList()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
// 下拉场站选择
|
||||||
|
changeStation() {
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
// 查询获取场站列表,查询日志列表时,stationId可以默认为空,查询全部
|
||||||
|
async getStationList() {
|
||||||
|
const params = { page_size: 1000, page: 1 }
|
||||||
|
try {
|
||||||
|
const res = await getReq('/queryStationList', params)
|
||||||
|
if (res.errcode === 0) {
|
||||||
|
this.stationList = res.data.map((item) => {
|
||||||
|
return { value: item.station_id, label: item.name }
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const err = { tip: res.errmsg }
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
//统一处理报错提示
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
async getList() {
|
async getList() {
|
||||||
this.$refs.comTable.loading = true
|
this.$refs.comTable.loading = true
|
||||||
|
|
||||||
const { page, pageSize } = this.pageOption
|
const { page, pageSize } = this.pageOption
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
|
station_id: this.stationId,
|
||||||
...this.paramsDate,
|
...this.paramsDate,
|
||||||
page_size: pageSize,
|
page_size: pageSize,
|
||||||
page
|
page
|
||||||
@@ -196,7 +235,7 @@ export default {
|
|||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
|
||||||
.content-table {
|
.content-table {
|
||||||
height: 100%;
|
height: calc(100% - 75px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,7 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="syslog">
|
<div class="syslog">
|
||||||
<!-- <searchBox :btn-option-list="btnOptionList" @operateForm="operateForm"></searchBox> -->
|
<!-- <searchBox :btn-option-list="btnOptionList" @operateForm="operateForm"></searchBox> -->
|
||||||
|
<searchBox class="searchBox" ref="searchBox" :search-options="searchOptions" :title-option="{ title: '', info: '' }">
|
||||||
|
<template #stationSelect="">
|
||||||
|
<a-select style="width: 200px" :dropdown-match-select-width="false" v-model:value="stationId" allow-clear @change="changeStation">
|
||||||
|
<a-select-option :value="option.value" v-for="option in stationList" :key="option.value">
|
||||||
|
{{ option.label }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</template>
|
||||||
|
</searchBox>
|
||||||
<div class="content-table">
|
<div class="content-table">
|
||||||
<ComTable
|
<ComTable
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
@@ -59,6 +67,11 @@ export default {
|
|||||||
page: 1
|
page: 1
|
||||||
},
|
},
|
||||||
btnOptionList: [],
|
btnOptionList: [],
|
||||||
|
searchOptions: [
|
||||||
|
{label: '场站选择', type: 'slot', value: [], key: 'station', slotName: 'stationSelect'}
|
||||||
|
],
|
||||||
|
stationId: undefined,
|
||||||
|
stationList: [],
|
||||||
paramsDate: {},
|
paramsDate: {},
|
||||||
tableData: []
|
tableData: []
|
||||||
}
|
}
|
||||||
@@ -78,16 +91,43 @@ export default {
|
|||||||
mounted() {
|
mounted() {
|
||||||
this.operateList = this.$getBtns(['查看'])
|
this.operateList = this.$getBtns(['查看'])
|
||||||
// this.btnOptionList = this.$getBtns(['新增'])
|
// this.btnOptionList = this.$getBtns(['新增'])
|
||||||
|
// 先获查询取场站列表,然后查询日志列表
|
||||||
|
Promise.all([
|
||||||
|
this.getStationList()
|
||||||
|
]).then(()=>{
|
||||||
this.getList()
|
this.getList()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
// 下拉场站选择
|
||||||
|
changeStation() {
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
// 查询获取场站列表,查询日志列表时,stationId可以默认为空,查询全部
|
||||||
|
async getStationList() {
|
||||||
|
const params = { page_size: 1000, page: 1 }
|
||||||
|
try {
|
||||||
|
const res = await getReq('/queryStationList', params)
|
||||||
|
if (res.errcode === 0) {
|
||||||
|
this.stationList = res.data.map((item) => {
|
||||||
|
return { value: item.station_id, label: item.name }
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const err = { tip: res.errmsg }
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
//统一处理报错提示
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
async getList() {
|
async getList() {
|
||||||
this.$refs.comTable.loading = true
|
this.$refs.comTable.loading = true
|
||||||
|
|
||||||
const { page, pageSize } = this.pageOption
|
const { page, pageSize } = this.pageOption
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
|
station_id: this.stationId ? this.stationId : "",
|
||||||
...this.paramsDate,
|
...this.paramsDate,
|
||||||
page_size: pageSize,
|
page_size: pageSize,
|
||||||
page
|
page
|
||||||
@@ -179,7 +219,7 @@ export default {
|
|||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
|
||||||
.content-table {
|
.content-table {
|
||||||
height: 100%;
|
height: calc(100% - 75px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user