|
@@ -1,356 +1,369 @@
|
|
<template>
|
|
<template>
|
|
- <div class="system-edit-dic-container">
|
|
|
|
- <el-dialog v-model="isShowDialog" :title="data.name + `(${data.key})`" width="850px">
|
|
|
|
- <!-- 添加 tab 切换 -->
|
|
|
|
- <el-tabs v-model="activeTab">
|
|
|
|
- <el-tab-pane label="趋势图" name="trend">
|
|
|
|
- <!-- 这里是 echarts 线图 -->
|
|
|
|
- <div id="lineChart" ref="chartRef" class="chart-container"></div>
|
|
|
|
- </el-tab-pane>
|
|
|
|
- <el-tab-pane label="历史数据" name="history">
|
|
|
|
- <!-- 历史日志数据表格 -->
|
|
|
|
- <div class="history-container">
|
|
|
|
- <div class="date-picker-container">
|
|
|
|
- <el-date-picker v-model="historyDateRange" type="datetimerange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" @change="fetchHistoryData" />
|
|
|
|
- <el-button type="primary" @click="exportData">导出</el-button>
|
|
|
|
- </div>
|
|
|
|
- <el-table :data="historyData" border style="width: 100%" v-loading="historyLoading">
|
|
|
|
- <el-table-column prop="dataTime" label="时间" align="center" />
|
|
|
|
- <el-table-column prop="dataValue" label="属性值" align="center" />
|
|
|
|
- <el-table-column prop="unit" label="数据单位" align="center">
|
|
|
|
- <template #default>{{ data.unit }}</template>
|
|
|
|
- </el-table-column>
|
|
|
|
- </el-table>
|
|
|
|
- <div class="pagination-container">
|
|
|
|
- <el-pagination
|
|
|
|
- v-model:current-page="currentPage"
|
|
|
|
- v-model:page-size="pageSize"
|
|
|
|
- :page-sizes="[10, 20, 50, 100]"
|
|
|
|
- layout="total, sizes, prev, pager, next, jumper"
|
|
|
|
- :total="totalItems"
|
|
|
|
- @size-change="handleSizeChange"
|
|
|
|
- @current-change="handleCurrentChange"
|
|
|
|
- />
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </el-tab-pane>
|
|
|
|
- </el-tabs>
|
|
|
|
- </el-dialog>
|
|
|
|
- </div>
|
|
|
|
|
|
+ <div class="system-edit-dic-container">
|
|
|
|
+ <el-dialog v-model="isShowDialog" :title="data.name + `(${data.key})`" width="850px">
|
|
|
|
+ <!-- 添加 tab 切换 -->
|
|
|
|
+ <el-tabs v-model="activeTab">
|
|
|
|
+ <el-tab-pane label="趋势图" name="trend">
|
|
|
|
+ <!-- 这里是 echarts 线图 -->
|
|
|
|
+ <div id="lineChart" ref="chartRef" class="chart-container"></div>
|
|
|
|
+ </el-tab-pane>
|
|
|
|
+ <el-tab-pane label="历史数据" name="history">
|
|
|
|
+ <!-- 历史日志数据表格 -->
|
|
|
|
+ <div class="history-container">
|
|
|
|
+ <div class="date-picker-container">
|
|
|
|
+ <el-date-picker
|
|
|
|
+ v-model="historyDateRange"
|
|
|
|
+ type="datetimerange"
|
|
|
|
+ range-separator="至"
|
|
|
|
+ start-placeholder="开始日期"
|
|
|
|
+ end-placeholder="结束日期"
|
|
|
|
+ format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
+ value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
+ @change="fetchHistoryData"
|
|
|
|
+ />
|
|
|
|
+ <el-button type="primary" @click="exportData">导出</el-button>
|
|
|
|
+ </div>
|
|
|
|
+ <el-table :data="historyData" border style="width: 100%" v-loading="historyLoading">
|
|
|
|
+ <el-table-column prop="ts" label="时间" align="center" />
|
|
|
|
+ <el-table-column prop="value" label="属性值" align="center" />
|
|
|
|
+ <el-table-column prop="unit" label="数据单位" align="center">
|
|
|
|
+ <template #default>{{ data.unit }}</template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ </el-table>
|
|
|
|
+ <div class="pagination-container">
|
|
|
|
+ <el-pagination
|
|
|
|
+ v-model:current-page="currentPage"
|
|
|
|
+ v-model:page-size="pageSize"
|
|
|
|
+ :page-sizes="[10, 20, 50, 100]"
|
|
|
|
+ layout="total, sizes, prev, pager, next, jumper"
|
|
|
|
+ :total="totalItems"
|
|
|
|
+ @size-change="handleSizeChange"
|
|
|
|
+ @current-change="handleCurrentChange"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </el-tab-pane>
|
|
|
|
+ </el-tabs>
|
|
|
|
+ </el-dialog>
|
|
|
|
+ </div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
<script lang="ts" setup>
|
|
-import { ref, reactive, watch, nextTick } from "vue";
|
|
|
|
-import api from "/@/api/device";
|
|
|
|
-import * as echarts from "echarts";
|
|
|
|
-import dayjs from "dayjs";
|
|
|
|
-import { ElMessage } from "element-plus";
|
|
|
|
|
|
+import { ref, reactive, watch, nextTick } from 'vue'
|
|
|
|
+import api from '/@/api/device'
|
|
|
|
+import * as echarts from 'echarts'
|
|
|
|
+import dayjs from 'dayjs'
|
|
|
|
+import { ElMessage } from 'element-plus'
|
|
|
|
|
|
-const data = ref({ name: "", key: "", unit: "" });
|
|
|
|
-const loading = ref(false);
|
|
|
|
-const isShowDialog = ref(false);
|
|
|
|
-const chartRef = ref<HTMLElement | null>(null);
|
|
|
|
-let chartInstance: echarts.ECharts | null = null;
|
|
|
|
-const lineData = ref([]);
|
|
|
|
|
|
+const data = ref({ name: '', key: '', unit: '' })
|
|
|
|
+const loading = ref(false)
|
|
|
|
+const isShowDialog = ref(false)
|
|
|
|
+const chartRef = ref<HTMLElement | null>(null)
|
|
|
|
+let chartInstance: echarts.ECharts | null = null
|
|
|
|
+const lineData = ref([])
|
|
|
|
|
|
// 新增 Tab 相关状态
|
|
// 新增 Tab 相关状态
|
|
-const activeTab = ref("trend");
|
|
|
|
-const historyData = ref([]);
|
|
|
|
-const historyLoading = ref(false);
|
|
|
|
-const historyDateRange = ref([dayjs().subtract(1, "hour").format("YYYY-MM-DD HH:mm:ss"), dayjs().format("YYYY-MM-DD HH:mm:ss")]);
|
|
|
|
-const currentPage = ref(1);
|
|
|
|
-const pageSize = ref(10);
|
|
|
|
-const totalItems = ref(0);
|
|
|
|
|
|
+const activeTab = ref('trend')
|
|
|
|
+const historyData = ref([])
|
|
|
|
+const historyLoading = ref(false)
|
|
|
|
+const historyDateRange = ref([dayjs().subtract(1, 'hour').format('YYYY-MM-DD HH:mm:ss'), dayjs().format('YYYY-MM-DD HH:mm:ss')])
|
|
|
|
+const currentPage = ref(1)
|
|
|
|
+const pageSize = ref(10)
|
|
|
|
+const totalItems = ref(0)
|
|
|
|
|
|
const params = reactive({
|
|
const params = reactive({
|
|
- productKey: "",
|
|
|
|
- deviceKey: "",
|
|
|
|
- properties: "",
|
|
|
|
- dateRange: [dayjs().subtract(1, "hour").format("YYYY-MM-DD HH:mm:ss"), dayjs().format("YYYY-MM-DD HH:mm:ss")],
|
|
|
|
-});
|
|
|
|
|
|
+ productKey: '',
|
|
|
|
+ deviceKey: '',
|
|
|
|
+ properties: '',
|
|
|
|
+ dateRange: [dayjs().subtract(1, 'hour').format('YYYY-MM-DD HH:mm:ss'), dayjs().format('YYYY-MM-DD HH:mm:ss')],
|
|
|
|
+})
|
|
|
|
|
|
// 初始化图表
|
|
// 初始化图表
|
|
const initChart = () => {
|
|
const initChart = () => {
|
|
- if (chartRef.value) {
|
|
|
|
- // 如果已有实例先销毁
|
|
|
|
- if (chartInstance) {
|
|
|
|
- chartInstance.dispose();
|
|
|
|
- }
|
|
|
|
- // 创建图表实例
|
|
|
|
- chartInstance = echarts.init(chartRef.value);
|
|
|
|
- // 设置加载状态
|
|
|
|
- if (loading.value) {
|
|
|
|
- chartInstance.showLoading();
|
|
|
|
- } else {
|
|
|
|
- chartInstance.hideLoading();
|
|
|
|
- }
|
|
|
|
- // 更新图表
|
|
|
|
- updateChart();
|
|
|
|
- }
|
|
|
|
-};
|
|
|
|
|
|
+ if (chartRef.value) {
|
|
|
|
+ // 如果已有实例先销毁
|
|
|
|
+ if (chartInstance) {
|
|
|
|
+ chartInstance.dispose()
|
|
|
|
+ }
|
|
|
|
+ // 创建图表实例
|
|
|
|
+ chartInstance = echarts.init(chartRef.value)
|
|
|
|
+ // 设置加载状态
|
|
|
|
+ if (loading.value) {
|
|
|
|
+ chartInstance.showLoading()
|
|
|
|
+ } else {
|
|
|
|
+ chartInstance.hideLoading()
|
|
|
|
+ }
|
|
|
|
+ // 更新图表
|
|
|
|
+ updateChart()
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
|
|
// 更新图表数据
|
|
// 更新图表数据
|
|
const updateChart = () => {
|
|
const updateChart = () => {
|
|
- if (!chartInstance) return;
|
|
|
|
|
|
+ if (!chartInstance) return
|
|
|
|
|
|
- // 从 lineData 中提取数据
|
|
|
|
- const xData = lineData.value.map((item: any) => item.ts?.slice(10)).reverse();
|
|
|
|
- const yData = lineData.value.map((item: any) => item.value).reverse();
|
|
|
|
|
|
+ // 从 lineData 中提取数据
|
|
|
|
+ const xData = lineData.value.map((item: any) => item.ts?.slice(10)).reverse()
|
|
|
|
+ const yData = lineData.value.map((item: any) => item.value).reverse()
|
|
|
|
|
|
- // 配置图表选项
|
|
|
|
- const option = {
|
|
|
|
- tooltip: {
|
|
|
|
- trigger: "axis",
|
|
|
|
- formatter: "{b}<br />{a}: {c}",
|
|
|
|
- },
|
|
|
|
- grid: {
|
|
|
|
- top: 15,
|
|
|
|
- left: 40,
|
|
|
|
- right: 30,
|
|
|
|
- bottom: 50, // 增加底部空间,为 dataZoom 留出位置
|
|
|
|
- containLabel: true,
|
|
|
|
- },
|
|
|
|
- dataZoom: [
|
|
|
|
- {
|
|
|
|
- type: "slider", // 滑动条型数据区域缩放组件
|
|
|
|
- show: true,
|
|
|
|
- start: 0,
|
|
|
|
- end: 100,
|
|
|
|
- height: 20,
|
|
|
|
- bottom: 10,
|
|
|
|
- borderColor: "transparent",
|
|
|
|
- backgroundColor: "#f5f5f5",
|
|
|
|
- fillerColor: "rgba(167, 183, 204, 0.4)",
|
|
|
|
- handleIcon: "M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z",
|
|
|
|
- handleSize: "80%",
|
|
|
|
- handleStyle: {
|
|
|
|
- color: "#fff",
|
|
|
|
- shadowBlur: 3,
|
|
|
|
- shadowColor: "rgba(0, 0, 0, 0.6)",
|
|
|
|
- shadowOffsetX: 2,
|
|
|
|
- shadowOffsetY: 2,
|
|
|
|
- },
|
|
|
|
- },
|
|
|
|
- {
|
|
|
|
- type: "inside", // 内置型数据区域缩放组件,允许鼠标滚轮或触摸板缩放
|
|
|
|
- start: 0,
|
|
|
|
- end: 100,
|
|
|
|
- },
|
|
|
|
- ],
|
|
|
|
- xAxis: {
|
|
|
|
- type: "category",
|
|
|
|
- data: xData,
|
|
|
|
- axisLabel: {
|
|
|
|
- rotate: 0,
|
|
|
|
- },
|
|
|
|
- },
|
|
|
|
- yAxis: {
|
|
|
|
- type: "value",
|
|
|
|
- splitLine: {
|
|
|
|
- show: true,
|
|
|
|
- lineStyle: {
|
|
|
|
- color: "rgba(88,88,88,0.5)",
|
|
|
|
- },
|
|
|
|
- },
|
|
|
|
- },
|
|
|
|
- series: [
|
|
|
|
- {
|
|
|
|
- name: "数值",
|
|
|
|
- type: "line",
|
|
|
|
- data: yData,
|
|
|
|
- smooth: true,
|
|
|
|
- lineStyle: {
|
|
|
|
- width: 2,
|
|
|
|
- },
|
|
|
|
- symbolSize: 4,
|
|
|
|
- },
|
|
|
|
- ],
|
|
|
|
- };
|
|
|
|
|
|
+ // 配置图表选项
|
|
|
|
+ const option = {
|
|
|
|
+ tooltip: {
|
|
|
|
+ trigger: 'axis',
|
|
|
|
+ formatter: '{b}<br />{a}: {c}',
|
|
|
|
+ },
|
|
|
|
+ grid: {
|
|
|
|
+ top: 15,
|
|
|
|
+ left: 40,
|
|
|
|
+ right: 30,
|
|
|
|
+ bottom: 50, // 增加底部空间,为 dataZoom 留出位置
|
|
|
|
+ containLabel: true,
|
|
|
|
+ },
|
|
|
|
+ dataZoom: [
|
|
|
|
+ {
|
|
|
|
+ type: 'slider', // 滑动条型数据区域缩放组件
|
|
|
|
+ show: true,
|
|
|
|
+ start: 0,
|
|
|
|
+ end: 100,
|
|
|
|
+ height: 20,
|
|
|
|
+ bottom: 10,
|
|
|
|
+ borderColor: 'transparent',
|
|
|
|
+ backgroundColor: '#f5f5f5',
|
|
|
|
+ fillerColor: 'rgba(167, 183, 204, 0.4)',
|
|
|
|
+ handleIcon:
|
|
|
|
+ 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
|
|
|
|
+ handleSize: '80%',
|
|
|
|
+ handleStyle: {
|
|
|
|
+ color: '#fff',
|
|
|
|
+ shadowBlur: 3,
|
|
|
|
+ shadowColor: 'rgba(0, 0, 0, 0.6)',
|
|
|
|
+ shadowOffsetX: 2,
|
|
|
|
+ shadowOffsetY: 2,
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ type: 'inside', // 内置型数据区域缩放组件,允许鼠标滚轮或触摸板缩放
|
|
|
|
+ start: 0,
|
|
|
|
+ end: 100,
|
|
|
|
+ },
|
|
|
|
+ ],
|
|
|
|
+ xAxis: {
|
|
|
|
+ type: 'category',
|
|
|
|
+ data: xData,
|
|
|
|
+ axisLabel: {
|
|
|
|
+ rotate: 0,
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ yAxis: {
|
|
|
|
+ type: 'value',
|
|
|
|
+ splitLine: {
|
|
|
|
+ show: true,
|
|
|
|
+ lineStyle: {
|
|
|
|
+ color: 'rgba(88,88,88,0.5)',
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ series: [
|
|
|
|
+ {
|
|
|
|
+ name: '数值',
|
|
|
|
+ type: 'line',
|
|
|
|
+ data: yData,
|
|
|
|
+ smooth: true,
|
|
|
|
+ lineStyle: {
|
|
|
|
+ width: 2,
|
|
|
|
+ },
|
|
|
|
+ symbolSize: 4,
|
|
|
|
+ },
|
|
|
|
+ ],
|
|
|
|
+ }
|
|
|
|
|
|
- // 设置图表配置
|
|
|
|
- chartInstance.setOption(option);
|
|
|
|
-};
|
|
|
|
|
|
+ // 设置图表配置
|
|
|
|
+ chartInstance.setOption(option)
|
|
|
|
+}
|
|
|
|
|
|
// 获取历史数据
|
|
// 获取历史数据
|
|
const fetchHistoryData = () => {
|
|
const fetchHistoryData = () => {
|
|
- if (!params.deviceKey || !params.properties) return;
|
|
|
|
|
|
+ if (!params.deviceKey || !params.properties) return
|
|
|
|
|
|
- historyLoading.value = true;
|
|
|
|
|
|
+ historyLoading.value = true
|
|
|
|
|
|
- const historyParams = {
|
|
|
|
- productKey: params.productKey,
|
|
|
|
- deviceKey: params.deviceKey,
|
|
|
|
- properties: params.properties,
|
|
|
|
- dateRange: historyDateRange.value,
|
|
|
|
- page: currentPage.value,
|
|
|
|
- pageSize: pageSize.value,
|
|
|
|
- };
|
|
|
|
|
|
+ const historyParams = {
|
|
|
|
+ productKey: params.productKey,
|
|
|
|
+ deviceKey: params.deviceKey,
|
|
|
|
+ propertyKey: params.properties,
|
|
|
|
+ dateRange: historyDateRange.value,
|
|
|
|
+ pageNum: currentPage.value,
|
|
|
|
+ pageSize: pageSize.value,
|
|
|
|
+ }
|
|
|
|
|
|
- api.analysis
|
|
|
|
- .deviceIndicatorTrend(historyParams)
|
|
|
|
- .then((res: any) => {
|
|
|
|
- historyData.value = res;
|
|
|
|
- totalItems.value = res.length;
|
|
|
|
- })
|
|
|
|
- .catch((error) => {
|
|
|
|
- console.error("获取历史数据失败:", error);
|
|
|
|
- ElMessage.error("获取历史数据失败");
|
|
|
|
- })
|
|
|
|
- .finally(() => {
|
|
|
|
- historyLoading.value = false;
|
|
|
|
- });
|
|
|
|
-};
|
|
|
|
|
|
+ api.instance
|
|
|
|
+ .getLogDetail(historyParams)
|
|
|
|
+ .then((res: any) => {
|
|
|
|
+ historyData.value = res.List
|
|
|
|
+ totalItems.value = res.Total
|
|
|
|
+ })
|
|
|
|
+ .catch(() => {
|
|
|
|
+ historyData.value = []
|
|
|
|
+ totalItems.value = 0
|
|
|
|
+ })
|
|
|
|
+ .finally(() => (historyLoading.value = false))
|
|
|
|
+}
|
|
|
|
|
|
// 处理分页大小变化
|
|
// 处理分页大小变化
|
|
const handleSizeChange = (size: number) => {
|
|
const handleSizeChange = (size: number) => {
|
|
- pageSize.value = size;
|
|
|
|
- fetchHistoryData();
|
|
|
|
-};
|
|
|
|
|
|
+ pageSize.value = size
|
|
|
|
+ fetchHistoryData()
|
|
|
|
+}
|
|
|
|
|
|
// 处理页码变化
|
|
// 处理页码变化
|
|
const handleCurrentChange = (page: number) => {
|
|
const handleCurrentChange = (page: number) => {
|
|
- currentPage.value = page;
|
|
|
|
- fetchHistoryData();
|
|
|
|
-};
|
|
|
|
|
|
+ currentPage.value = page
|
|
|
|
+ fetchHistoryData()
|
|
|
|
+}
|
|
|
|
|
|
// 导出数据
|
|
// 导出数据
|
|
const exportData = () => {
|
|
const exportData = () => {
|
|
- if (historyData.value.length === 0) {
|
|
|
|
- ElMessage.warning("没有数据可导出");
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
|
|
+ const historyParams = {
|
|
|
|
+ productKey: params.productKey,
|
|
|
|
+ deviceKey: params.deviceKey,
|
|
|
|
+ propertyKey: params.properties,
|
|
|
|
+ dateRange: historyDateRange.value,
|
|
|
|
+ pageNum: currentPage.value,
|
|
|
|
+ pageSize: pageSize.value,
|
|
|
|
+ }
|
|
|
|
|
|
- // 创建CSV内容
|
|
|
|
- let csvContent = "时间,属性值";
|
|
|
|
- if (data.value.unit) {
|
|
|
|
- csvContent += ",数据单位";
|
|
|
|
- }
|
|
|
|
- csvContent += "\n";
|
|
|
|
|
|
+ api.instance.getLogDetail(historyParams).then((res: any) => {
|
|
|
|
+ // 创建CSV内容
|
|
|
|
+ let csvContent = '时间,属性值'
|
|
|
|
+ if (data.value.unit) {
|
|
|
|
+ csvContent += ',数据单位'
|
|
|
|
+ }
|
|
|
|
+ csvContent += '\n'
|
|
|
|
|
|
- historyData.value.forEach((item: any) => {
|
|
|
|
- csvContent += `${item.ts},${item.value}`;
|
|
|
|
- if (data.value.unit) {
|
|
|
|
- csvContent += `,${data.value.unit}`;
|
|
|
|
- }
|
|
|
|
- csvContent += "\n";
|
|
|
|
- });
|
|
|
|
|
|
+ res.List.forEach((item: any) => {
|
|
|
|
+ csvContent += `${item.ts},${item.value}`
|
|
|
|
+ if (data.value.unit) {
|
|
|
|
+ csvContent += `,${data.value.unit}`
|
|
|
|
+ }
|
|
|
|
+ csvContent += '\n'
|
|
|
|
+ })
|
|
|
|
|
|
- // 创建Blob对象
|
|
|
|
- const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
|
|
|
|
- const url = URL.createObjectURL(blob);
|
|
|
|
|
|
+ // 创建Blob对象
|
|
|
|
+ const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })
|
|
|
|
+ const url = URL.createObjectURL(blob)
|
|
|
|
|
|
- // 创建下载链接
|
|
|
|
- const link = document.createElement("a");
|
|
|
|
- link.setAttribute("href", url);
|
|
|
|
- link.setAttribute("download", `${data.value.name}_历史数据_${dayjs().format("YYYYMMDD_HHmmss")}.csv`);
|
|
|
|
- link.style.visibility = "hidden";
|
|
|
|
- document.body.appendChild(link);
|
|
|
|
- link.click();
|
|
|
|
- document.body.removeChild(link);
|
|
|
|
-};
|
|
|
|
|
|
+ // 创建下载链接
|
|
|
|
+ const link = document.createElement('a')
|
|
|
|
+ link.setAttribute('href', url)
|
|
|
|
+ link.setAttribute('download', `${data.value.name}_历史数据_${dayjs().format('YYYYMMDD_HHmmss')}.csv`)
|
|
|
|
+ link.style.visibility = 'hidden'
|
|
|
|
+ document.body.appendChild(link)
|
|
|
|
+ link.click()
|
|
|
|
+ document.body.removeChild(link)
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
// 监听数据变化,更新图表
|
|
// 监听数据变化,更新图表
|
|
watch(
|
|
watch(
|
|
- () => lineData.value,
|
|
|
|
- () => {
|
|
|
|
- nextTick(() => {
|
|
|
|
- updateChart();
|
|
|
|
- });
|
|
|
|
- },
|
|
|
|
- { deep: true }
|
|
|
|
-);
|
|
|
|
|
|
+ () => lineData.value,
|
|
|
|
+ () => {
|
|
|
|
+ nextTick(() => {
|
|
|
|
+ updateChart()
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ { deep: true }
|
|
|
|
+)
|
|
|
|
|
|
// 监听 loading 状态变化
|
|
// 监听 loading 状态变化
|
|
watch(
|
|
watch(
|
|
- () => loading.value,
|
|
|
|
- (newVal) => {
|
|
|
|
- if (chartInstance) {
|
|
|
|
- if (newVal) {
|
|
|
|
- chartInstance.showLoading();
|
|
|
|
- } else {
|
|
|
|
- chartInstance.hideLoading();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-);
|
|
|
|
|
|
+ () => loading.value,
|
|
|
|
+ (newVal) => {
|
|
|
|
+ if (chartInstance) {
|
|
|
|
+ if (newVal) {
|
|
|
|
+ chartInstance.showLoading()
|
|
|
|
+ } else {
|
|
|
|
+ chartInstance.hideLoading()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+)
|
|
|
|
|
|
// 监听弹窗显示状态
|
|
// 监听弹窗显示状态
|
|
watch(
|
|
watch(
|
|
- () => isShowDialog.value,
|
|
|
|
- (val) => {
|
|
|
|
- if (val) {
|
|
|
|
- nextTick(() => {
|
|
|
|
- initChart();
|
|
|
|
- // 重置分页
|
|
|
|
- currentPage.value = 1;
|
|
|
|
- // 如果是历史日志标签页,加载历史数据
|
|
|
|
- if (activeTab.value === "history") {
|
|
|
|
- fetchHistoryData();
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-);
|
|
|
|
|
|
+ () => isShowDialog.value,
|
|
|
|
+ (val) => {
|
|
|
|
+ if (val) {
|
|
|
|
+ nextTick(() => {
|
|
|
|
+ initChart()
|
|
|
|
+ // 重置分页
|
|
|
|
+ currentPage.value = 1
|
|
|
|
+ // 如果是历史日志标签页,加载历史数据
|
|
|
|
+ if (activeTab.value === 'history') {
|
|
|
|
+ fetchHistoryData()
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+)
|
|
|
|
|
|
// 监听标签页切换
|
|
// 监听标签页切换
|
|
watch(
|
|
watch(
|
|
- () => activeTab.value,
|
|
|
|
- (val) => {
|
|
|
|
- if (val === "history" && isShowDialog.value) {
|
|
|
|
- fetchHistoryData();
|
|
|
|
- } else if (val === "trend" && isShowDialog.value) {
|
|
|
|
- nextTick(() => {
|
|
|
|
- initChart();
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-);
|
|
|
|
|
|
+ () => activeTab.value,
|
|
|
|
+ (val) => {
|
|
|
|
+ if (val === 'history' && isShowDialog.value) {
|
|
|
|
+ fetchHistoryData()
|
|
|
|
+ } else if (val === 'trend' && isShowDialog.value) {
|
|
|
|
+ nextTick(() => {
|
|
|
|
+ initChart()
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+)
|
|
|
|
|
|
// 打开弹窗
|
|
// 打开弹窗
|
|
const openDialog = (row: any, deviceKey: string, productKey: string) => {
|
|
const openDialog = (row: any, deviceKey: string, productKey: string) => {
|
|
- params.productKey = productKey;
|
|
|
|
- params.deviceKey = deviceKey;
|
|
|
|
- params.properties = row.key;
|
|
|
|
|
|
+ params.productKey = productKey
|
|
|
|
+ params.deviceKey = deviceKey
|
|
|
|
+ params.properties = row.key
|
|
|
|
|
|
- // 重置日期范围
|
|
|
|
- historyDateRange.value = [dayjs().subtract(1, "hour").format("YYYY-MM-DD HH:mm:ss"), dayjs().format("YYYY-MM-DD HH:mm:ss")];
|
|
|
|
- console.log(row);
|
|
|
|
- data.value = row;
|
|
|
|
- isShowDialog.value = true;
|
|
|
|
- loading.value = true;
|
|
|
|
- api.instance
|
|
|
|
- .getLogDetail({
|
|
|
|
- deviceKey: deviceKey,
|
|
|
|
- propertyKey: row.key,
|
|
|
|
- pageSize: 100,
|
|
|
|
- })
|
|
|
|
- .then((res: any) => {
|
|
|
|
- lineData.value = res.List;
|
|
|
|
- })
|
|
|
|
- .finally(() => (loading.value = false));
|
|
|
|
-};
|
|
|
|
|
|
+ // 重置日期范围
|
|
|
|
+ historyDateRange.value = [dayjs().subtract(1, 'hour').format('YYYY-MM-DD HH:mm:ss'), dayjs().format('YYYY-MM-DD HH:mm:ss')]
|
|
|
|
+ data.value = row
|
|
|
|
+ isShowDialog.value = true
|
|
|
|
+ loading.value = true
|
|
|
|
+ api.instance
|
|
|
|
+ .getLogDetail({
|
|
|
|
+ deviceKey: deviceKey,
|
|
|
|
+ propertyKey: row.key,
|
|
|
|
+ pageSize: 100,
|
|
|
|
+ })
|
|
|
|
+ .then((res: any) => {
|
|
|
|
+ lineData.value = res.List
|
|
|
|
+ })
|
|
|
|
+ .finally(() => (loading.value = false))
|
|
|
|
+}
|
|
|
|
|
|
-defineExpose({ openDialog });
|
|
|
|
|
|
+defineExpose({ openDialog })
|
|
</script>
|
|
</script>
|
|
<style scoped>
|
|
<style scoped>
|
|
.chart-container {
|
|
.chart-container {
|
|
- width: 100%;
|
|
|
|
- height: 400px;
|
|
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 400px;
|
|
}
|
|
}
|
|
|
|
|
|
.history-container {
|
|
.history-container {
|
|
- width: 100%;
|
|
|
|
|
|
+ width: 100%;
|
|
}
|
|
}
|
|
|
|
|
|
.date-picker-container {
|
|
.date-picker-container {
|
|
- display: flex;
|
|
|
|
- justify-content: space-between;
|
|
|
|
- margin-bottom: 15px;
|
|
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ margin-bottom: 15px;
|
|
}
|
|
}
|
|
|
|
|
|
.pagination-container {
|
|
.pagination-container {
|
|
- margin-top: 15px;
|
|
|
|
- display: flex;
|
|
|
|
- justify-content: flex-end;
|
|
|
|
|
|
+ margin-top: 15px;
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: flex-end;
|
|
}
|
|
}
|
|
</style>
|
|
</style>
|