用水统计
This commit is contained in:
@@ -12,3 +12,39 @@ export const lookDetails = (roomNo: string) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 水电统计
|
||||||
|
* @param params 统计参数
|
||||||
|
*/
|
||||||
|
export const getStats = (params: any) => {
|
||||||
|
return request({
|
||||||
|
url: '/stuwork/watermonthreport/stats',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 水电趋势分析
|
||||||
|
* @param params 查询参数
|
||||||
|
*/
|
||||||
|
export const getTrend = (params: any) => {
|
||||||
|
return request({
|
||||||
|
url: '/stuwork/watermonthreport/trend',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按楼层统计水电
|
||||||
|
* @param params 查询参数
|
||||||
|
*/
|
||||||
|
export const getFloorStats = (params: any) => {
|
||||||
|
return request({
|
||||||
|
url: '/stuwork/watermonthreport/floorStats',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -69,23 +69,30 @@
|
|||||||
水费明细列表
|
水费明细列表
|
||||||
</span>
|
</span>
|
||||||
<div class="header-actions">
|
<div class="header-actions">
|
||||||
<el-button
|
<el-button
|
||||||
icon="FolderAdd"
|
icon="FolderAdd"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="formDialogRef.openDialog()">
|
@click="formDialogRef.openDialog()">
|
||||||
新增明细
|
新增明细
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
icon="Download"
|
icon="DataAnalysis"
|
||||||
type="success"
|
type="warning"
|
||||||
class="ml10"
|
class="ml10"
|
||||||
|
@click="handleStats">
|
||||||
|
统计分析
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
icon="Download"
|
||||||
|
type="success"
|
||||||
|
class="ml10"
|
||||||
@click="handleExport">
|
@click="handleExport">
|
||||||
导出数据
|
导出数据
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
icon="Setting"
|
icon="Setting"
|
||||||
type="warning"
|
type="info"
|
||||||
class="ml10"
|
class="ml10"
|
||||||
@click="handleInitWaterOrder">
|
@click="handleInitWaterOrder">
|
||||||
批量初始化订单
|
批量初始化订单
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -235,6 +242,9 @@
|
|||||||
<!-- 详情对话框 -->
|
<!-- 详情对话框 -->
|
||||||
<DetailDialog ref="detailDialogRef" />
|
<DetailDialog ref="detailDialogRef" />
|
||||||
|
|
||||||
|
<!-- 统计分析对话框 -->
|
||||||
|
<StatsDialog ref="statsDialogRef" />
|
||||||
|
|
||||||
<!-- 批量初始化对话框-->
|
<!-- 批量初始化对话框-->
|
||||||
<el-dialog v-model="initDialogVisible" title="批量初始化订单" :width="500" :close-on-click-modal="false" draggable>
|
<el-dialog v-model="initDialogVisible" title="批量初始化订单" :width="500" :close-on-click-modal="false" draggable>
|
||||||
<el-form ref="initFormRef" :model="initForm" :rules="initRules" label-width="120px">
|
<el-form ref="initFormRef" :model="initForm" :rules="initRules" label-width="120px">
|
||||||
@@ -259,7 +269,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts" name="WaterDetail">
|
<script setup lang="ts" name="WaterDetail">
|
||||||
import { reactive, ref, onMounted, computed, nextTick } from 'vue'
|
import { reactive, ref, onMounted, computed, nextTick } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||||
import { fetchList, delObjs, initWaterOrder } from "/@/api/stuwork/waterdetail";
|
import { fetchList, delObjs, initWaterOrder } from "/@/api/stuwork/waterdetail";
|
||||||
import { getBuildingList } from "/@/api/stuwork/dormbuilding";
|
import { getBuildingList } from "/@/api/stuwork/dormbuilding";
|
||||||
@@ -267,16 +277,19 @@ import { useMessage, useMessageBox } from "/@/hooks/message";
|
|||||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue'
|
import TableColumnControl from '/@/components/TableColumnControl/index.vue'
|
||||||
import FormDialog from './form.vue';
|
import FormDialog from './form.vue';
|
||||||
import DetailDialog from './detail.vue';
|
import DetailDialog from './detail.vue';
|
||||||
import { List, OfficeBuilding, House, UserFilled, Money, Setting, Menu, Search, Document } from '@element-plus/icons-vue'
|
import StatsDialog from './stats.vue';
|
||||||
|
import { List, OfficeBuilding, House, UserFilled, Money, Setting, Menu, Search, Document, DataAnalysis } from '@element-plus/icons-vue'
|
||||||
import { useTableColumnControl } from '/@/hooks/tableColumn'
|
import { useTableColumnControl } from '/@/hooks/tableColumn'
|
||||||
|
|
||||||
|
|
||||||
// 定义变量
|
// 定义变量
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
const router = useRouter()
|
||||||
const searchFormRef = ref()
|
const searchFormRef = ref()
|
||||||
const columnControlRef = ref<any>()
|
const columnControlRef = ref<any>()
|
||||||
const formDialogRef = ref()
|
const formDialogRef = ref()
|
||||||
const detailDialogRef = ref()
|
const detailDialogRef = ref()
|
||||||
|
const statsDialogRef = ref()
|
||||||
const initFormRef = ref()
|
const initFormRef = ref()
|
||||||
const showSearch = ref(true)
|
const showSearch = ref(true)
|
||||||
const buildingList = ref<any[]>([])
|
const buildingList = ref<any[]>([])
|
||||||
@@ -402,6 +415,11 @@ const handleExport = () => {
|
|||||||
useMessage().warning('功能开发中')
|
useMessage().warning('功能开发中')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 统计分析
|
||||||
|
const handleStats = () => {
|
||||||
|
statsDialogRef.value.openDialog()
|
||||||
|
}
|
||||||
|
|
||||||
// 批量初始化订单
|
// 批量初始化订单
|
||||||
const handleInitWaterOrder = () => {
|
const handleInitWaterOrder = () => {
|
||||||
initDialogVisible.value = true
|
initDialogVisible.value = true
|
||||||
|
|||||||
495
src/views/stuwork/waterdetail/stats.vue
Normal file
495
src/views/stuwork/waterdetail/stats.vue
Normal file
@@ -0,0 +1,495 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
v-model="visible"
|
||||||
|
title="水电统计分析"
|
||||||
|
width="90%"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
draggable
|
||||||
|
destroy-on-close
|
||||||
|
@open="handleOpen"
|
||||||
|
@closed="handleClosed">
|
||||||
|
|
||||||
|
<!-- 查询条件 -->
|
||||||
|
<div class="query-bar">
|
||||||
|
<el-form :inline="true" class="query-form">
|
||||||
|
<el-form-item label="年份">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.year"
|
||||||
|
type="year"
|
||||||
|
placeholder="选择年份"
|
||||||
|
format="YYYY"
|
||||||
|
value-format="YYYY"
|
||||||
|
style="width: 120px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="月份">
|
||||||
|
<el-select v-model="queryParams.month" placeholder="选择月份" clearable style="width: 100px">
|
||||||
|
<el-option v-for="m in 12" :key="m" :label="m + '月'" :value="m" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
|
||||||
|
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 统计卡片 -->
|
||||||
|
<el-row :gutter="16" class="stats-row">
|
||||||
|
<el-col :span="6">
|
||||||
|
<div class="stats-card water">
|
||||||
|
<el-icon class="stats-icon"><Odometer /></el-icon>
|
||||||
|
<div class="stats-info">
|
||||||
|
<div class="stats-label">总用水量</div>
|
||||||
|
<div class="stats-value">{{ statsData.totalWaterUsage || 0 }} <span class="unit">m³</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<div class="stats-card water-cost">
|
||||||
|
<el-icon class="stats-icon"><Money /></el-icon>
|
||||||
|
<div class="stats-info">
|
||||||
|
<div class="stats-label">用水费用</div>
|
||||||
|
<div class="stats-value">¥{{ formatMoney(statsData.totalWaterCost) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<div class="stats-card electricity">
|
||||||
|
<el-icon class="stats-icon"><Odometer /></el-icon>
|
||||||
|
<div class="stats-info">
|
||||||
|
<div class="stats-label">总用电量</div>
|
||||||
|
<div class="stats-value">{{ statsData.totalElectricityUsage || 0 }} <span class="unit">度</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<div class="stats-card electricity-cost">
|
||||||
|
<el-icon class="stats-icon"><Money /></el-icon>
|
||||||
|
<div class="stats-info">
|
||||||
|
<div class="stats-label">用电费用</div>
|
||||||
|
<div class="stats-value">¥{{ formatMoney(statsData.totalElectricityCost) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 图表区域 -->
|
||||||
|
<el-row :gutter="16" class="chart-row">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-card shadow="never" class="chart-card">
|
||||||
|
<template #header>
|
||||||
|
<span class="chart-title">水电用量趋势</span>
|
||||||
|
</template>
|
||||||
|
<div ref="trendChartRef" class="chart-container"></div>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-card shadow="never" class="chart-card">
|
||||||
|
<template #header>
|
||||||
|
<span class="chart-title">楼层用水用电分布</span>
|
||||||
|
</template>
|
||||||
|
<div ref="floorChartRef" class="chart-container"></div>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 楼层统计表格 -->
|
||||||
|
<el-card shadow="never" class="table-card">
|
||||||
|
<template #header>
|
||||||
|
<span class="chart-title">楼层水电统计明细</span>
|
||||||
|
</template>
|
||||||
|
<el-table :data="floorStatsData" v-loading="floorLoading" stripe border size="small" max-height="250">
|
||||||
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||||
|
<el-table-column prop="floorName" label="楼层" align="center" width="80" />
|
||||||
|
<el-table-column prop="waterUsage" label="用水量(m³)" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<span class="water-text">{{ formatNumber(scope.row.waterUsage) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="waterCost" label="用水费用(元)" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<span class="water-text">¥{{ formatMoney(scope.row.waterCost) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="electricityUsage" label="用电量(度)" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<span class="electricity-text">{{ formatNumber(scope.row.electricityUsage) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="electricityCost" label="用电费用(元)" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<span class="electricity-text">¥{{ formatMoney(scope.row.electricityCost) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="visible = false">关闭</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, nextTick } from 'vue'
|
||||||
|
import { getStats, getTrend, getFloorStats } from '/@/api/stuwork/watermonthreport'
|
||||||
|
import { useMessage } from '/@/hooks/message'
|
||||||
|
import { Odometer, Money } from '@element-plus/icons-vue'
|
||||||
|
import * as echarts from 'echarts'
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
|
||||||
|
// 查询参数
|
||||||
|
const queryParams = reactive({
|
||||||
|
year: new Date().getFullYear().toString(),
|
||||||
|
month: new Date().getMonth() + 1
|
||||||
|
})
|
||||||
|
|
||||||
|
// 统计数据
|
||||||
|
const statsData = ref<any>({})
|
||||||
|
const trendData = ref<any[]>([])
|
||||||
|
const floorStatsData = ref<any[]>([])
|
||||||
|
const floorLoading = ref(false)
|
||||||
|
|
||||||
|
// 图表引用
|
||||||
|
const trendChartRef = ref<HTMLElement>()
|
||||||
|
const floorChartRef = ref<HTMLElement>()
|
||||||
|
let trendChart: echarts.ECharts | null = null
|
||||||
|
let floorChart: echarts.ECharts | null = null
|
||||||
|
|
||||||
|
// 打开弹窗
|
||||||
|
const openDialog = () => {
|
||||||
|
visible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化金额
|
||||||
|
const formatMoney = (value: any) => {
|
||||||
|
if (!value) return '0.00'
|
||||||
|
return Number(value).toFixed(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化数字
|
||||||
|
const formatNumber = (value: any) => {
|
||||||
|
if (!value) return '0'
|
||||||
|
return Number(value).toFixed(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 弹窗打开时
|
||||||
|
const handleOpen = () => {
|
||||||
|
resetQuery()
|
||||||
|
nextTick(() => {
|
||||||
|
handleQuery()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 弹窗关闭时
|
||||||
|
const handleClosed = () => {
|
||||||
|
trendChart?.dispose()
|
||||||
|
floorChart?.dispose()
|
||||||
|
trendChart = null
|
||||||
|
floorChart = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置查询参数
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryParams.year = new Date().getFullYear().toString()
|
||||||
|
queryParams.month = new Date().getMonth() + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询统计数据
|
||||||
|
const handleQuery = async () => {
|
||||||
|
await Promise.all([
|
||||||
|
getStatsData(),
|
||||||
|
getTrendData(),
|
||||||
|
getFloorData()
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置查询
|
||||||
|
const handleReset = () => {
|
||||||
|
resetQuery()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取统计数据
|
||||||
|
const getStatsData = async () => {
|
||||||
|
try {
|
||||||
|
const res = await getStats({
|
||||||
|
year: queryParams.year,
|
||||||
|
month: queryParams.month,
|
||||||
|
statsType: 'school'
|
||||||
|
})
|
||||||
|
if (res.data) {
|
||||||
|
statsData.value = res.data
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
useMessage().error(err.msg || '获取统计数据失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取趋势数据
|
||||||
|
const getTrendData = async () => {
|
||||||
|
try {
|
||||||
|
const res = await getTrend({
|
||||||
|
year: queryParams.year
|
||||||
|
})
|
||||||
|
if (res.data && res.data.trendList) {
|
||||||
|
trendData.value = res.data.trendList
|
||||||
|
nextTick(() => renderTrendChart())
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
useMessage().error(err.msg || '获取趋势数据失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取楼层数据
|
||||||
|
const getFloorData = async () => {
|
||||||
|
floorLoading.value = true
|
||||||
|
try {
|
||||||
|
const res = await getFloorStats({
|
||||||
|
year: queryParams.year,
|
||||||
|
month: queryParams.month
|
||||||
|
})
|
||||||
|
if (res.data) {
|
||||||
|
floorStatsData.value = res.data
|
||||||
|
nextTick(() => renderFloorChart())
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
useMessage().error(err.msg || '获取楼层数据失败')
|
||||||
|
} finally {
|
||||||
|
floorLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 渲染趋势图表
|
||||||
|
const renderTrendChart = () => {
|
||||||
|
if (!trendChartRef.value) return
|
||||||
|
|
||||||
|
if (trendChart) {
|
||||||
|
trendChart.dispose()
|
||||||
|
}
|
||||||
|
trendChart = echarts.init(trendChartRef.value)
|
||||||
|
|
||||||
|
const option = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: { type: 'cross' }
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: ['用水量', '用电量'],
|
||||||
|
top: 0
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '3%',
|
||||||
|
right: '4%',
|
||||||
|
bottom: '3%',
|
||||||
|
top: 40,
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: trendData.value.map(d => d.timeLabel)
|
||||||
|
},
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
name: '用水量(m³)',
|
||||||
|
position: 'left'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
name: '用电量(度)',
|
||||||
|
position: 'right'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '用水量',
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
itemStyle: { color: '#409eff' },
|
||||||
|
areaStyle: { color: 'rgba(64, 158, 255, 0.2)' },
|
||||||
|
data: trendData.value.map(d => d.waterUsage)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '用电量',
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
yAxisIndex: 1,
|
||||||
|
itemStyle: { color: '#f56c6c' },
|
||||||
|
areaStyle: { color: 'rgba(245, 108, 108, 0.2)' },
|
||||||
|
data: trendData.value.map(d => d.electricityUsage)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
trendChart.setOption(option)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 渲染楼层图表
|
||||||
|
const renderFloorChart = () => {
|
||||||
|
if (!floorChartRef.value) return
|
||||||
|
|
||||||
|
if (floorChart) {
|
||||||
|
floorChart.dispose()
|
||||||
|
}
|
||||||
|
floorChart = echarts.init(floorChartRef.value)
|
||||||
|
|
||||||
|
const option = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: { type: 'shadow' }
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: ['用水量', '用电量'],
|
||||||
|
top: 0
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '3%',
|
||||||
|
right: '4%',
|
||||||
|
bottom: '3%',
|
||||||
|
top: 40,
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: floorStatsData.value.map(d => d.floorName)
|
||||||
|
},
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
name: '用水量(m³)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
name: '用电量(度)',
|
||||||
|
position: 'right'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '用水量',
|
||||||
|
type: 'bar',
|
||||||
|
itemStyle: { color: '#409eff' },
|
||||||
|
data: floorStatsData.value.map(d => d.waterUsage)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '用电量',
|
||||||
|
type: 'bar',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
itemStyle: { color: '#f56c6c' },
|
||||||
|
data: floorStatsData.value.map(d => d.electricityUsage)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
floorChart.setOption(option)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 暴露方法
|
||||||
|
defineExpose({
|
||||||
|
openDialog
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.query-bar {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
background: #f5f7fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-row {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-card {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: linear-gradient(135deg, #f5f7fa 0%, #e4e7ed 100%);
|
||||||
|
|
||||||
|
.stats-icon {
|
||||||
|
font-size: 36px;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-info {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
.stats-label {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #909399;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-value {
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
.unit {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.water {
|
||||||
|
background: linear-gradient(135deg, #ecf5ff 0%, #d9ecff 100%);
|
||||||
|
.stats-icon { color: #409eff; }
|
||||||
|
.stats-value { color: #409eff; }
|
||||||
|
}
|
||||||
|
|
||||||
|
&.water-cost {
|
||||||
|
background: linear-gradient(135deg, #f0f9eb 0%, #e1f3d8 100%);
|
||||||
|
.stats-icon { color: #67c23a; }
|
||||||
|
.stats-value { color: #67c23a; }
|
||||||
|
}
|
||||||
|
|
||||||
|
&.electricity {
|
||||||
|
background: linear-gradient(135deg, #fdf6ec 0%, #faecd8 100%);
|
||||||
|
.stats-icon { color: #e6a23c; }
|
||||||
|
.stats-value { color: #e6a23c; }
|
||||||
|
}
|
||||||
|
|
||||||
|
&.electricity-cost {
|
||||||
|
background: linear-gradient(135deg, #fef0f0 0%, #fde2e2 100%);
|
||||||
|
.stats-icon { color: #f56c6c; }
|
||||||
|
.stats-value { color: #f56c6c; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-row {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-card {
|
||||||
|
.chart-title {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
height: 280px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-card {
|
||||||
|
.chart-title {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.water-text {
|
||||||
|
color: #409eff;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.electricity-text {
|
||||||
|
color: #f56c6c;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user