Merge remote-tracking branch 'origin/boardTest' into boardTest

boardTest
suixy 3 months ago
commit 731f6e1007

@ -18,7 +18,7 @@ const service = axios.create({
// axios中请求配置有baseURL选项表示请求URL公共部分 // axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API, baseURL: process.env.VUE_APP_BASE_API,
// 超时 // 超时
timeout: 10000 timeout: 100000
}) })
// request拦截器 // request拦截器
@ -137,6 +137,7 @@ export function download(url, params, filename, config) {
transformRequest: [(params) => { return tansParams(params) }], transformRequest: [(params) => { return tansParams(params) }],
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
responseType: 'blob', responseType: 'blob',
timeout: -1, // 导出操作超时时间无限制
...config ...config
}).then(async (data) => { }).then(async (data) => {
const isBlob = blobValidate(data); const isBlob = blobValidate(data);

@ -180,7 +180,7 @@
plain plain
icon="el-icon-download" icon="el-icon-download"
size="mini" size="mini"
@click="handleExport" @click="openExportDialog"
v-hasPermi="['ems/record:recordIotenvInstant:export']" v-hasPermi="['ems/record:recordIotenvInstant:export']"
>导出</el-button> >导出</el-button>
</el-col> </el-col>
@ -295,6 +295,126 @@
<el-button @click="cancel"> </el-button> <el-button @click="cancel"> </el-button>
</div> </div>
</el-dialog> </el-dialog>
<!-- 导出对话框 -->
<el-dialog title="导出物联网数据" :visible.sync="exportDialogVisible" width="700px" append-to-body>
<el-form ref="exportForm" :model="exportForm" label-width="100px">
<!-- 时间范围选择 -->
<el-form-item label="时间范围" prop="timeRange" required>
<el-date-picker
v-model="exportForm.timeRange"
style="width: 100%"
value-format="yyyy-MM-dd HH:mm:ss"
type="datetimerange"
range-separator="-"
start-placeholder="开始时间"
end-placeholder="结束时间"
></el-date-picker>
</el-form-item>
<!-- 设备选择区域 -->
<el-form-item label="设备选择">
<div style="margin-bottom: 10px;">
<el-button type="primary" size="mini" @click="selectAllDevices"></el-button>
<el-button type="info" size="mini" @click="clearAllDevices"></el-button>
<span style="margin-left: 15px; color: #909399;">
已选择 <span style="color: #409EFF; font-weight: bold;">{{ selectedDevicesCount }}</span> 个设备
</span>
</div>
<!-- 按能源类型分组显示设备 -->
<div class="device-select-container">
<el-checkbox-group v-model="exportForm.selectedDeviceCodes" @change="handleDeviceSelectionChange">
<!-- 温度设备 (type=5) -->
<div v-if="deviceGroups.temperature.length > 0" class="device-group">
<div class="device-group-header">
<span class="device-group-title">温度设备</span>
<el-button type="text" size="mini" @click="selectGroupDevices('temperature')">
{{ isGroupAllSelected('temperature') ? '取消全选' : '全选该类型' }}
</el-button>
</div>
<el-row :gutter="10">
<el-col :span="12" v-for="device in deviceGroups.temperature" :key="device.monitorCode">
<el-checkbox :label="device.monitorCode" :disabled="device.isAmmeter === '0'">
{{ device.monitorName }}
<span v-if="device.isAmmeter === '0'" style="color: #F56C6C; font-size: 12px;">()</span>
</el-checkbox>
</el-col>
</el-row>
</div>
<!-- 温湿度设备 (type=6) -->
<div v-if="deviceGroups.humidity.length > 0" class="device-group">
<div class="device-group-header">
<span class="device-group-title">温湿度设备</span>
<el-button type="text" size="mini" @click="selectGroupDevices('humidity')">
{{ isGroupAllSelected('humidity') ? '取消全选' : '全选该类型' }}
</el-button>
</div>
<el-row :gutter="10">
<el-col :span="12" v-for="device in deviceGroups.humidity" :key="device.monitorCode">
<el-checkbox :label="device.monitorCode" :disabled="device.isAmmeter === '0'">
{{ device.monitorName }}
<span v-if="device.isAmmeter === '0'" style="color: #F56C6C; font-size: 12px;">()</span>
</el-checkbox>
</el-col>
</el-row>
</div>
<!-- 噪声设备 (type=7) -->
<div v-if="deviceGroups.noise.length > 0" class="device-group">
<div class="device-group-header">
<span class="device-group-title">噪声设备</span>
<el-button type="text" size="mini" @click="selectGroupDevices('noise')">
{{ isGroupAllSelected('noise') ? '取消全选' : '全选该类型' }}
</el-button>
</div>
<el-row :gutter="10">
<el-col :span="12" v-for="device in deviceGroups.noise" :key="device.monitorCode">
<el-checkbox :label="device.monitorCode" :disabled="device.isAmmeter === '0'">
{{ device.monitorName }}
<span v-if="device.isAmmeter === '0'" style="color: #F56C6C; font-size: 12px;">()</span>
</el-checkbox>
</el-col>
</el-row>
</div>
<!-- 其他设备 -->
<div v-if="deviceGroups.other.length > 0" class="device-group">
<div class="device-group-header">
<span class="device-group-title">其他设备</span>
<el-button type="text" size="mini" @click="selectGroupDevices('other')">
{{ isGroupAllSelected('other') ? '取消全选' : '全选该类型' }}
</el-button>
</div>
<el-row :gutter="10">
<el-col :span="12" v-for="device in deviceGroups.other" :key="device.monitorCode">
<el-checkbox :label="device.monitorCode" :disabled="device.isAmmeter === '0'">
{{ device.monitorName }}
<span v-if="device.isAmmeter === '0'" style="color: #F56C6C; font-size: 12px;">()</span>
</el-checkbox>
</el-col>
</el-row>
</div>
<!-- 空状态处理当所有设备组都为空时显示 -->
<div v-if="deviceGroups.temperature.length === 0 &&
deviceGroups.humidity.length === 0 &&
deviceGroups.noise.length === 0 &&
deviceGroups.other.length === 0"
class="no-devices-empty">
<i class="el-icon-info"></i>
<span>暂无可用设备请先配置物联网采集设备</span>
</div>
</el-checkbox-group>
</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="confirmExport"></el-button>
<el-button @click="exportDialogVisible = false">取消</el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
@ -368,6 +488,24 @@ export default {
form: {}, form: {},
// //
rules: { rules: {
},
//
exportDialogVisible: false,
exportForm: {
timeRange: [],
selectedDeviceCodes: []
},
//
allDevicesList: [],
//
allDevicesListCache: null,
cacheTimestamp: 0,
//
deviceGroups: {
temperature: [], // (type=5)
humidity: [], // 湿 (type=6)
noise: [], // (type=7)
other: [] // (8,910)
} }
}; };
}, },
@ -375,6 +513,10 @@ export default {
// //
hasSelectedDevice() { hasSelectedDevice() {
return this.queryParams.monitorId || (this.queryParams.monitorIds && this.queryParams.monitorIds.length > 0); return this.queryParams.monitorId || (this.queryParams.monitorIds && this.queryParams.monitorIds.length > 0);
},
//
selectedDevicesCount() {
return this.exportForm.selectedDeviceCodes ? this.exportForm.selectedDeviceCodes.length : 0;
} }
}, },
created() { created() {
@ -607,13 +749,195 @@ export default {
this.$modal.msgSuccess("删除成功"); this.$modal.msgSuccess("删除成功");
}).catch(() => {}); }).catch(() => {});
}, },
/** 导出按钮操作 */
handleExport() { /** ========== 导出相关方法 ========== */
this.download('ems/record/recordIotenvInstant/export', {
...this.queryParams /** 打开导出对话框 */
}, `recordIotenvInstant_${new Date().getTime()}.xlsx`) openExportDialog() {
//
this.exportForm.timeRange = this.daterangeRecordTime ? [...this.daterangeRecordTime] : [];
this.exportForm.selectedDeviceCodes = [];
//
this.loadAllDevicesForExport();
this.exportDialogVisible = true;
}, },
/** 加载所有设备列表(用于导出,使用缓存优化性能) */
loadAllDevicesForExport() {
// 5300000
const now = Date.now();
if (this.allDevicesListCache && (now - this.cacheTimestamp) < 300000) {
// 使
this.allDevicesList = this.allDevicesListCache;
this.groupDevicesByType();
return;
}
// type=10
listBaseMonitorInfo({ monitorTypeList: [5, 6, 7, 8, 9] }).then(response => {
this.allDevicesList = response.data;
this.allDevicesListCache = response.data;
this.cacheTimestamp = now;
this.groupDevicesByType();
});
},
/** 按设备类型分组(不含振动设备,振动在专用页面处理) */
groupDevicesByType() {
//
this.deviceGroups = {
temperature: [], // (type=5)
humidity: [], // 湿 (type=6)
noise: [], // (type=7)
other: [] // (8,910)
};
this.allDevicesList.forEach(device => {
//
if (device.isAmmeter === '0') return;
//
if (device.monitorType === 10) return;
switch (device.monitorType) {
case 5:
this.deviceGroups.temperature.push(device);
break;
case 6:
this.deviceGroups.humidity.push(device);
break;
case 7:
this.deviceGroups.noise.push(device);
break;
default:
this.deviceGroups.other.push(device);
break;
}
});
},
/** 全选设备(不含振动设备) */
selectAllDevices() {
//
const allCodes = this.allDevicesList
.filter(device => device.isAmmeter !== '0' && device.monitorType !== 10)
.map(device => device.monitorCode);
this.exportForm.selectedDeviceCodes = allCodes;
},
/** 清空设备选择 */
clearAllDevices() {
this.exportForm.selectedDeviceCodes = [];
},
/** 处理设备选择变化 */
handleDeviceSelectionChange() {
//
},
/** 判断某个类型的设备是否全部选中 */
isGroupAllSelected(groupName) {
const group = this.deviceGroups[groupName] || [];
//
const validCodes = group
.filter(device => device.isAmmeter !== '0')
.map(device => device.monitorCode);
if (validCodes.length === 0) return false;
//
return validCodes.every(code => this.exportForm.selectedDeviceCodes.includes(code));
},
/** 全选/取消全选某个类型的设备 */
selectGroupDevices(groupName) {
const group = this.deviceGroups[groupName] || [];
//
const validCodes = group
.filter(device => device.isAmmeter !== '0')
.map(device => device.monitorCode);
if (this.isGroupAllSelected(groupName)) {
//
this.exportForm.selectedDeviceCodes = this.exportForm.selectedDeviceCodes
.filter(code => !validCodes.includes(code));
} else {
//
const newCodes = validCodes.filter(code => !this.exportForm.selectedDeviceCodes.includes(code));
this.exportForm.selectedDeviceCodes = [...this.exportForm.selectedDeviceCodes, ...newCodes];
}
},
/** 确认导出 */
confirmExport() {
//
if (!this.exportForm.timeRange || this.exportForm.timeRange.length !== 2) {
this.$modal.msgWarning("请先选择时间范围");
return;
}
//
if (this.exportForm.selectedDeviceCodes.length === 0) {
this.$modal.msgWarning("请至少选择一个设备");
return;
}
//
const selectedMonitorTypes = this.getSelectedMonitorTypes();
//
const exportParams = {
params: {
beginRecordTime: this.exportForm.timeRange[0],
endRecordTime: this.exportForm.timeRange[1],
//
monitorTypes: selectedMonitorTypes.join(',')
},
monitorIds: this.exportForm.selectedDeviceCodes,
monitorId: null // ID使
};
//
const beginDate = this.exportForm.timeRange[0].substring(0, 10).replace(/-/g, '');
const endDate = this.exportForm.timeRange[1].substring(0, 10).replace(/-/g, '');
const deviceCount = this.exportForm.selectedDeviceCodes.length;
//
const typeNames = this.getTypeNamesForFileName(selectedMonitorTypes);
const fileName = `IOT数据_${typeNames}_${beginDate}_${endDate}_${deviceCount}设备.xlsx`;
//
this.download('ems/record/recordIotenvInstant/export', exportParams, fileName);
this.exportDialogVisible = false;
},
/** 获取选中设备的类型集合 */
getSelectedMonitorTypes() {
const selectedCodes = this.exportForm.selectedDeviceCodes;
const types = new Set();
//
this.allDevicesList.forEach(device => {
if (selectedCodes.includes(device.monitorCode) && device.monitorType) {
types.add(device.monitorType);
}
});
return Array.from(types);
},
/** 根据类型生成文件名中的类型描述(不含振动) */
getTypeNamesForFileName(types) {
if (types.length === 0) return '混合';
if (types.length > 2) return '混合';
const typeMap = {
5: '温度',
6: '温湿度',
7: '噪声'
};
return types.map(t => typeMap[t] || '其他').join('_');
},
/** ========== 原有方法 ========== */
getTreeselect() { getTreeselect() {
getMonitorInfoTree({ monitorTypeList: [5,6,7,8,9]}).then(response => { getMonitorInfoTree({ monitorTypeList: [5,6,7,8,9]}).then(response => {
this.monitorInfoOptions = response.data this.monitorInfoOptions = response.data
@ -636,4 +960,66 @@ export default {
.no-device-tip .el-empty { .no-device-tip .el-empty {
padding: 0; padding: 0;
} }
/* 导出对话框样式 */
.device-select-container {
max-height: 400px;
overflow-y: auto;
border: 1px solid #DCDFE6;
border-radius: 4px;
padding: 10px;
}
.device-group {
margin-bottom: 15px;
padding-bottom: 15px;
border-bottom: 1px solid #EBEEF5;
}
.device-group:last-child {
border-bottom: none;
margin-bottom: 0;
padding-bottom: 0;
}
.device-group-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.device-group-title {
font-weight: bold;
color: #1f2d3d; /* 提升对比度,便于识别设备类型标题 */
font-size: 14px;
padding: 2px 6px;
border-left: 3px solid #409EFF;
background: #f5f7fa; /* 浅底突出文字 */
border-radius: 3px;
}
.device-select-container .el-checkbox {
margin-right: 0;
margin-bottom: 8px;
display: block;
}
/* 空状态样式 */
.no-devices-empty {
text-align: center;
padding: 40px 20px;
color: #909399;
font-size: 14px;
}
.no-devices-empty i {
font-size: 24px;
margin-right: 8px;
color: #E6A23C;
}
.device-select-container .el-col {
margin-bottom: 5px;
}
</style> </style>

@ -135,6 +135,14 @@
end-placeholder="结束时间" end-placeholder="结束时间"
></el-date-picker> ></el-date-picker>
</el-form-item> </el-form-item>
<el-form-item label="振动参数">
<el-select v-model="selectedVibrationParam" placeholder="请选择振动参数" style="width: 150px" @change="handleQuery">
<el-option label="振动速度" value="vibrationSpeed"></el-option>
<el-option label="振动位移" value="vibrationDisplacement"></el-option>
<el-option label="振动加速度" value="vibrationAcceleration"></el-option>
<el-option label="振动温度" value="vibrationTemp"></el-option>
</el-select>
</el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button> <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button> <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
@ -193,14 +201,14 @@
<el-table-column label="计量设备" align="center" prop="monitorName" min-width="150"> <el-table-column label="计量设备" align="center" prop="monitorName" min-width="150">
</el-table-column> </el-table-column>
<!-- 振动设备专用列 --> <!-- 振动设备专用列根据选中参数动态显示单列 -->
<el-table-column label="振动速度(mm/s)" align="center" prop="vibrationSpeed" width="120"> <el-table-column v-if="selectedVibrationParam === 'vibrationSpeed'" label="振动速度(mm/s)" align="center" prop="vibrationSpeed" width="150">
</el-table-column> </el-table-column>
<el-table-column label="振动位移(μm)" align="center" prop="vibrationDisplacement" width="120"> <el-table-column v-if="selectedVibrationParam === 'vibrationDisplacement'" label="振动位移(μm)" align="center" prop="vibrationDisplacement" width="150">
</el-table-column> </el-table-column>
<el-table-column label="振动加速度(g)" align="center" prop="vibrationAcceleration" width="120"> <el-table-column v-if="selectedVibrationParam === 'vibrationAcceleration'" label="振动加速度(g)" align="center" prop="vibrationAcceleration" width="150">
</el-table-column> </el-table-column>
<el-table-column label="振动温度(℃)" align="center" prop="vibrationTemp" width="120"> <el-table-column v-if="selectedVibrationParam === 'vibrationTemp'" label="振动温度(℃)" align="center" prop="vibrationTemp" width="150">
</el-table-column> </el-table-column>
<!-- 记录时间列给足够的宽度 --> <!-- 记录时间列给足够的宽度 -->
@ -304,6 +312,8 @@ export default {
name: "RecordIotenvInstant", name: "RecordIotenvInstant",
data() { data() {
return { return {
//
selectedVibrationParam: 'vibrationSpeed',
workUnitName:null, workUnitName:null,
//List //List
@ -484,9 +494,16 @@ export default {
return; return;
} }
// SQL
this.queryParams.vibrationParam = this.selectedVibrationParam;
listRecordIotenvInstant(this.queryParams).then(response => { listRecordIotenvInstant(this.queryParams).then(response => {
this.recordIotenvInstantList = response.rows; // vibrationParam
this.total = response.total; const filteredRows = response.rows.filter(row => {
const value = parseFloat(row[this.selectedVibrationParam]);
return !isNaN(value) && value > 0 && value < 80;
});
this.recordIotenvInstantList = filteredRows;
this.total = response.total; // 使
this.loading = false; this.loading = false;
}); });
}, },
@ -586,9 +603,36 @@ export default {
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
//
if (!this.daterangeRecordTime || this.daterangeRecordTime.length !== 2) {
this.$modal.msgWarning("请先选择记录时间范围再导出");
return;
}
//
if (!this.queryParams.monitorId && (!this.queryParams.monitorIds || this.queryParams.monitorIds.length === 0)) {
this.$modal.msgWarning("请先在左侧树中选择设备再导出");
return;
}
//
this.queryParams.params['beginRecordTime'] = this.daterangeRecordTime[0];
this.queryParams.params['endRecordTime'] = this.daterangeRecordTime[1];
// monitorTypes=10
this.queryParams.params['monitorTypes'] = '10';
//
this.queryParams.params['vibrationParam'] = this.selectedVibrationParam;
//
const paramNameMap = {
vibrationSpeed: '振动速度',
vibrationDisplacement: '振动位移',
vibrationAcceleration: '振动加速度',
vibrationTemp: '振动温度'
};
const paramName = paramNameMap[this.selectedVibrationParam] || '振动数据';
this.download('ems/record/recordIotenvInstant/export', { this.download('ems/record/recordIotenvInstant/export', {
...this.queryParams ...this.queryParams
}, `recordIotenvInstant_${new Date().getTime()}.xlsx`) }, `${paramName}_${this.daterangeRecordTime[0].substring(0,10)}_${this.daterangeRecordTime[1].substring(0,10)}.xlsx`)
}, },
getTreeselect() { getTreeselect() {

@ -59,16 +59,22 @@
></el-input-number> ></el-input-number>
<span style="margin-left: 5px; color: #909399;">分钟/</span> <span style="margin-left: 5px; color: #909399;">分钟/</span>
</el-form-item> </el-form-item>
<el-form-item label="振动参数">
<el-select v-model="selectedVibrationParam" placeholder="请选择振动参数" style="width: 150px" @change="handleQuery">
<el-option label="振动速度" value="vibrationSpeed"></el-option>
<el-option label="振动位移" value="vibrationDisplacement"></el-option>
<el-option label="振动加速度" value="vibrationAcceleration"></el-option>
<el-option label="振动温度" value="vibrationTemp"></el-option>
</el-select>
</el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button> <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button> <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<Chart ref="Chart1" class="chart1"/> <!-- 根据选中参数只显示单个图表 -->
<Chart ref="Chart2" class="chart2"/> <Chart ref="VibrationChart" class="vibration-chart"/>
<Chart ref="Chart3" class="chart3"/>
<Chart ref="Chart4" class="chart4"/>
</el-col> </el-col>
</el-row> </el-row>
@ -96,6 +102,8 @@ export default {
}, },
data() { data() {
return { return {
//
selectedVibrationParam: 'vibrationSpeed',
//List //List
baseMonitorInfoOptions: [], baseMonitorInfoOptions: [],
//List //List
@ -288,213 +296,45 @@ export default {
this.handleQuery() this.handleQuery()
}, },
/** 振动曲线 */ /** 振动曲线:根据选中参数只显示单个图表,过滤无效值保持曲线光滑 */
async getChart() { async getChart() {
if (this.queryParams.monitorId == null) { if (this.queryParams.monitorId == null) {
return return
} }
let query = JSON.parse(JSON.stringify(this.queryParams)) let query = JSON.parse(JSON.stringify(this.queryParams))
// const {data} = await vibrationInstantList(query) // SQL
query.vibrationParam = this.selectedVibrationParam
const {data} = await getRecordIotenvInstantList(query) const {data} = await getRecordIotenvInstantList(query)
let option1 = {
title: {
text: this.selectMonitorName + ' 速度曲线',
x: 'center'
},
grid: {
top: '15%',
bottom: '10%',
left: '10%',
right: '3%'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
label: {
show: true
}
}
},
dataZoom: [{
type: 'slider'
}],
legend: {
right: 0
},
xAxis: {
data: data.map(e => e.recodeTime),
axisLine: {
show: true, //X线
lineStyle: {
color: '#000000'
}
},
axisTick: {
show: true //X
},
axisLabel: {
show: true,
textStyle: {
color: '#000000' //X
}
}
},
yAxis: [
{
type: 'value',
name: '速度(mm/s)',
nameTextStyle: {
color: '#000000'
},
splitLine: {
show: false
},
axisTick: {
show: true
},
axisLine: {
show: true,
lineStyle: {
color: '#000000'
}
},
axisLabel: {
show: true,
textStyle: {
color: '#000000'
}
}
}
],
series: [
{
name: '速度(mm/s)',
connectNulls: true, //
type: 'line',
smooth: true, //线
showAllSymbol: true, //
symbol: 'circle', //
symbolSize: 10, //
// itemStyle: {
// //线
// color: "#058cff",
// },
// lineStyle: {
// color: "#058cff",
// },
// areaStyle: {
// color: "rgba(5,140,255, 0.2)",
// },
data: data.map(e => e.vibrationSpeed)
},
]
}
let option2 = {
title: {
text: this.selectMonitorName + ' 温度曲线',
x: 'center'
},
grid: {
top: '15%',
bottom: '10%',
left: '10%',
right: '3%'
},
dataZoom: [{ //
type: 'slider' const paramConfig = {
}], vibrationSpeed: { name: '速度(mm/s)', title: '速度曲线', field: 'vibrationSpeed' },
tooltip: { vibrationDisplacement: { name: '位移(μm)', title: '位移曲线', field: 'vibrationDisplacement' },
trigger: 'axis', vibrationAcceleration: { name: '加速度(g)', title: '加速度曲线', field: 'vibrationAcceleration' },
axisPointer: { vibrationTemp: { name: '温度(℃)', title: '温度曲线', field: 'vibrationTemp' }
type: 'shadow',
label: {
show: true
}
}
},
legend: {
right: 0
},
xAxis: {
data: data.map(e => e.recodeTime),
axisLine: {
show: true, //X线
lineStyle: {
color: '#000000'
}
},
axisTick: {
show: true //X
},
axisLabel: {
show: true,
textStyle: {
color: '#000000' //X
}
}
},
yAxis: [
{
type: 'value',
name: '温度(℃)',
nameTextStyle: {
color: '#000000'
},
splitLine: {
show: false
},
axisTick: {
show: true
},
axisLine: {
show: true,
lineStyle: {
color: '#000000'
}
},
axisLabel: {
show: true,
textStyle: {
color: '#000000'
}
}
}
],
series: [
{
name: '温度(℃)',
connectNulls: true, //
type: 'line',
smooth: true, //线
showAllSymbol: true, //
symbol: 'circle', //
symbolSize: 10, //
// itemStyle: {
// //线
// color: "#058cff",
// },
// lineStyle: {
// color: "#058cff",
// },
// areaStyle: {
// color: "rgba(5,140,255, 0.2)",
// },
data: data.map(e => e.vibrationTemp)
},
]
} }
let option3 = {
const config = paramConfig[this.selectedVibrationParam]
// 080
const validPoints = data.filter(e => {
const value = parseFloat(e[config.field])
return !isNaN(value) && value > 0 && value < 80
})
//
const timeData = validPoints.map(e => e.recodeTime)
const validData = validPoints.map(e => parseFloat(e[config.field]))
let option = {
title: { title: {
text: this.selectMonitorName + ' 位移曲线', text: this.selectMonitorName + ' ' + config.title,
x: 'center' x: 'center'
}, },
grid: { grid: {
top: '15%', top: '15%',
bottom: '10%', bottom: '15%',
left: '10%', left: '10%',
right: '3%' right: '5%'
}, },
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
@ -512,32 +352,36 @@ export default {
right: 0 right: 0
}, },
xAxis: { xAxis: {
data: data.map(e => e.recodeTime), data: timeData,
axisLine: { axisLine: {
show: true, //X线 show: true,
lineStyle: { lineStyle: {
color: '#000000' color: '#000000'
} }
}, },
axisTick: { axisTick: {
show: true //X show: true
}, },
axisLabel: { axisLabel: {
show: true, show: true,
textStyle: { textStyle: {
color: '#000000' //X color: '#000000'
} }
} }
}, },
yAxis: [ yAxis: [
{ {
type: 'value', type: 'value',
name: '位移(um)', name: config.name,
min: 0,
nameTextStyle: { nameTextStyle: {
color: '#000000' color: '#000000'
}, },
splitLine: { splitLine: {
show: false show: true,
lineStyle: {
type: 'dashed'
}
}, },
axisTick: { axisTick: {
show: true show: true
@ -552,198 +396,36 @@ export default {
show: true, show: true,
textStyle: { textStyle: {
color: '#000000' color: '#000000'
},
formatter: function(value) {
return value.toFixed(2); // 2
} }
} }
} }
], ],
series: [ series: [
{ {
name: '位移(um)', name: config.name,
connectNulls: true, // connectNulls: true, // null线
type: 'line', type: 'line',
smooth: true, //线 smooth: true, // 线
showAllSymbol: true, // showAllSymbol: true,
symbol: 'circle', // symbol: 'circle',
symbolSize: 10, // symbolSize: 8,
// itemStyle: { data: validData
// //线 }
// color: "#058cff",
// },
// lineStyle: {
// color: "#058cff",
// },
// areaStyle: {
// color: "rgba(5,140,255, 0.2)",
// },
data: data.map(e => e.vibrationDisplacement)
},
] ]
} }
let option4 = { this.$refs.VibrationChart.setData(option)
title: {
text: this.selectMonitorName + ' 加速度曲线',
x: 'center'
},
grid: {
top: '15%',
bottom: '10%',
left: '10%',
right: '3%'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
label: {
show: true
}
}
},
dataZoom: [{
type: 'slider'
}],
legend: {
right: 0
},
xAxis: {
data: data.map(e => e.recodeTime),
axisLine: {
show: true, //X线
lineStyle: {
color: '#000000'
}
},
axisTick: {
show: true //X
},
axisLabel: {
show: true,
textStyle: {
color: '#000000' //X
}
}
},
yAxis: [
{
type: 'value',
name: '加速度(g)',
nameTextStyle: {
color: '#000000'
},
splitLine: {
show: false
},
axisTick: {
show: true
},
axisLine: {
show: true,
lineStyle: {
color: '#000000'
}
},
axisLabel: {
show: true,
textStyle: {
color: '#000000'
}
}
}
],
series: [
{
name: '加速度(g)',
connectNulls: true, //
type: 'line',
smooth: true, //线
showAllSymbol: true, //
symbol: 'circle', //
symbolSize: 10, //
// itemStyle: {
// color: "#058cff",
// },
// lineStyle: {
// color: "#058cff",
// },
// areaStyle: {
// color: "rgba(5,140,255, 0.2)",
// },
data: data.map(e => e.vibrationAcceleration)
},
]
}
this.$refs.Chart1.setData(option1)
this.$refs.Chart2.setData(option2)
this.$refs.Chart3.setData(option3)
this.$refs.Chart4.setData(option4)
echarts.connect(this.$refs.Chart1.chart, this.$refs.Chart2.chart, this.$refs.Chart3.chart, this.$refs.Chart4.chart)
this.$refs.Chart1.chart.on('datazoom', (e) => {
option2.dataZoom[0].start = e.start
option2.dataZoom[0].end = e.end
this.$refs.Chart2.setData(option2)
option3.dataZoom[0].start = e.start
option3.dataZoom[0].end = e.end
this.$refs.Chart3.setData(option3)
option4.dataZoom[0].start = e.start
option4.dataZoom[0].end = e.end
this.$refs.Chart4.setData(option4)
})
this.$refs.Chart2.chart.on('datazoom', (e) => {
option1.dataZoom[0].start = e.start
option1.dataZoom[0].end = e.end
this.$refs.Chart1.setData(option1)
option3.dataZoom[0].start = e.start
option3.dataZoom[0].end = e.end
this.$refs.Chart3.setData(option3)
option4.dataZoom[0].start = e.start
option4.dataZoom[0].end = e.end
this.$refs.Chart4.setData(option4)
})
this.$refs.Chart3.chart.on('datazoom', (e) => {
option2.dataZoom[0].start = e.start
option2.dataZoom[0].end = e.end
this.$refs.Chart2.setData(option2)
option1.dataZoom[0].start = e.start
option1.dataZoom[0].end = e.end
this.$refs.Chart1.setData(option1)
option4.dataZoom[0].start = e.start
option4.dataZoom[0].end = e.end
this.$refs.Chart4.setData(option4)
})
this.$refs.Chart4.chart.on('datazoom', (e) => {
option2.dataZoom[0].start = e.start
option2.dataZoom[0].end = e.end
this.$refs.Chart2.setData(option2)
option3.dataZoom[0].start = e.start
option3.dataZoom[0].end = e.end
this.$refs.Chart3.setData(option3)
option1.dataZoom[0].start = e.start
option1.dataZoom[0].end = e.end
this.$refs.Chart4.setData(option1)
})
} }
} }
} }
</script> </script>
<style scoped> <style scoped>
.chart1 { /* 单个振动曲线图表样式 */
width: 50%; .vibration-chart {
height: 40vh; width: 100%;
display: inline-block; height: 70vh;
} display: block;
.chart2 {
width: 50%;
height: 40vh;
display: inline-block;
}
.chart3 {
width: 50%;
height: 40vh;
display: inline-block;
}
.chart4 {
width: 50%;
display: inline-block;
height: 40vh;
} }
</style> </style>

@ -303,6 +303,7 @@ export default {
selectedNodeName: null, // selectedNodeName: null, //
selectedNodeType: null, // selectedNodeType: null, //
selectedNodeCode: null, // Code selectedNodeCode: null, // Code
isParentNode: false, //
deviceTreeProps: { deviceTreeProps: {
children: 'children', children: 'children',
label: 'label' label: 'label'
@ -362,68 +363,54 @@ export default {
this.loading = true this.loading = true
try { try {
console.log('=== 开始加载节点数据 ===') console.log('=== 开始加载节点数据 ===')
console.log('节点ID:', nodeId) console.log('节点ID:', nodeId, '是否为父节点:', this.isParentNode)
// //
const [currentNodeResponse, childNodesResponse] = await Promise.all([ const isParentNode = this.isParentNode
//
getLatestRecords(),
//
getLatestRecordsByParentId(nodeId)
])
let allDeviceData = [] let allDeviceData = []
// if (isParentNode) {
if (currentNodeResponse.code === 200) { //
const currentNodeData = currentNodeResponse.data || [] const childNodesResponse = await getLatestRecordsByParentId(nodeId)
console.log('所有设备数据总数:', currentNodeData.length) if (childNodesResponse.code === 200) {
console.log('当前节点信息 - ID:', this.selectedNodeId, '名称:', this.selectedNodeName, 'Code:', this.selectedNodeCode) const childNodesData = childNodesResponse.data || []
console.log('子节点原始数据数量:', childNodesData.length)
// const childDevices = childNodesData.filter(device => {
// codemonitorId const matches = device.monitorName !== '胶东机场' &&
const currentDevices = currentNodeData.filter(device => { device.monitorId &&
const matchByCode = this.selectedNodeCode && device.monitorId === this.selectedNodeCode device.monitorName
const matchById = device.monitorId === nodeId return matches
const matchByName = device.monitorName === this.selectedNodeName })
const isValid = device.monitorName !== '胶东机场' && console.log('子节点有效设备数量:', childDevices.length)
device.monitorId && allDeviceData = childDevices
device.monitorName }
} else {
//
const currentNodeResponse = await getLatestRecords()
if (currentNodeResponse.code === 200) {
const currentNodeData = currentNodeResponse.data || []
console.log('所有设备数据总数:', currentNodeData.length)
console.log('当前节点信息 - ID:', this.selectedNodeId, '名称:', this.selectedNodeName, 'Code:', this.selectedNodeCode)
const matches = (matchByCode || matchById || matchByName) && isValid //
const currentDevices = currentNodeData.filter(device => {
const matchByCode = this.selectedNodeCode && device.monitorId === this.selectedNodeCode
const matchById = device.monitorId === nodeId
const matchByName = device.monitorName === this.selectedNodeName
const isValid = device.monitorName !== '胶东机场' &&
device.monitorId &&
device.monitorName
if (matches) { return (matchByCode || matchById || matchByName) && isValid
console.log('找到当前节点设备:', device.monitorName, device.monitorId, })
matchByCode ? '(通过Code匹配)' : console.log('当前节点设备数量:', currentDevices.length)
matchById ? '(通过ID匹配)' : '(通过名称匹配)') allDeviceData = currentDevices
} }
return matches
})
console.log('当前节点设备数量:', currentDevices.length)
allDeviceData = [...allDeviceData, ...currentDevices]
} }
// console.log('设备数据总数:', allDeviceData.length)
if (childNodesResponse.code === 200) {
const childNodesData = childNodesResponse.data || []
console.log('子节点原始数据数量:', childNodesData.length)
const childDevices = childNodesData.filter(device => {
const matches = device.monitorName !== '胶东机场' &&
device.monitorId &&
device.monitorName
if (matches) {
console.log('找到子节点设备:', device.monitorName, device.monitorId)
}
return matches
})
console.log('子节点有效设备数量:', childDevices.length)
allDeviceData = [...allDeviceData, ...childDevices]
}
console.log('合并后设备数据总数:', allDeviceData.length)
// monitorId // monitorId
const uniqueDevices = [] const uniqueDevices = []
@ -438,18 +425,6 @@ export default {
this.deviceList = uniqueDevices this.deviceList = uniqueDevices
console.log('最终设备列表数量:', this.deviceList.length) console.log('最终设备列表数量:', this.deviceList.length)
//
const currentNodeDeviceCount = this.deviceList.filter(d => {
return (this.selectedNodeCode && d.monitorId === this.selectedNodeCode) ||
d.monitorId === nodeId ||
d.monitorName === this.selectedNodeName
}).length
const childNodeDeviceCount = this.deviceList.length - currentNodeDeviceCount
console.log('当前节点数据数量:', currentNodeDeviceCount)
console.log('子节点数据数量:', childNodeDeviceCount)
console.log('=== 数据加载完成 ===') console.log('=== 数据加载完成 ===')
} catch (error) { } catch (error) {
@ -491,8 +466,10 @@ export default {
this.selectedNodeName = data.label this.selectedNodeName = data.label
this.selectedNodeType = data.type this.selectedNodeType = data.type
this.selectedNodeCode = data.code // code this.selectedNodeCode = data.code // code
// childrenchildren
this.isParentNode = !!(data.children && data.children.length > 0)
console.log('选中节点ID:', this.selectedNodeId, '节点名称:', this.selectedNodeName, '节点类型:', this.selectedNodeType, '节点Code:', this.selectedNodeCode) console.log('选中节点ID:', this.selectedNodeId, '节点名称:', this.selectedNodeName, '节点类型:', this.selectedNodeType, '节点Code:', this.selectedNodeCode, '是否父节点:', this.isParentNode)
// ID // ID
this.loadDeviceDataByNode(this.selectedNodeId) this.loadDeviceDataByNode(this.selectedNodeId)

Loading…
Cancel
Save