风机列表:合并实时数据功能,添加实时曲线
单风机:修改接口参数 设备:量测取消曲线动画
This commit is contained in:
parent
5cbaab5799
commit
23b9da397e
@ -151,7 +151,7 @@ export const getDeviceTypeEnumReq = () => {
|
||||
})
|
||||
}
|
||||
|
||||
export const getRealValueListReq = (data: { deviceId: string, attributes?: string[] }[]) => {
|
||||
export const getRealValueListReq = (data: { deviceId: string, attributes?: (string | number)[] }[]) => {
|
||||
return createAxios<never, RequestReturnType<any>>({
|
||||
url: '/api/data/snapshot',
|
||||
method: 'post',
|
||||
|
@ -584,7 +584,7 @@ const initTrendChart = (type: 'day' | 'month') => {
|
||||
top: 30,
|
||||
right: 10,
|
||||
bottom: 20,
|
||||
left: 25,
|
||||
left: 45,
|
||||
borderColor: '#dadada',
|
||||
},
|
||||
tooltip: {
|
||||
@ -1372,14 +1372,21 @@ const sendManualCommand = (type: 1 | 0) => {
|
||||
}
|
||||
|
||||
const getAlarmList = () => {
|
||||
const start = dayjs().subtract(3, 'day').startOf('day').toDate().getTime()
|
||||
const start = dayjs().startOf('day').toDate().getTime()
|
||||
const end = dayjs().endOf('day').toDate().getTime()
|
||||
|
||||
console.log({
|
||||
startTime: start,
|
||||
endTime: end,
|
||||
deviceCode: [route.query.deviceCode],
|
||||
},'----------------------------------');
|
||||
|
||||
getAlarmListReq({
|
||||
startTime: start,
|
||||
endTime: end,
|
||||
deviceCode: [route.query.name],
|
||||
deviceCode: [route.query.deviceCode],
|
||||
}).then((res) => {
|
||||
console.log(res,'------------------------');
|
||||
|
||||
if (res.rows) {
|
||||
tableData.value = res.rows.map((item: any) => {
|
||||
return {
|
||||
|
@ -39,6 +39,10 @@
|
||||
></el-switch>
|
||||
</div>
|
||||
</div>
|
||||
<div class="headerCenter">
|
||||
<el-button type="primary" :icon="Crop" class="defaultBtn" @click="openMeasure">测点选择</el-button>
|
||||
<el-button style="color: rgb(0, 100, 170)" :icon="Download" class="defaultBtn" @click="downFun">数据导出</el-button>
|
||||
</div>
|
||||
<div class="headerRight">
|
||||
<el-popconfirm title="确认启动么?" @confirm="airBlowerOperate('setTurbineFastStart')">
|
||||
<template #reference>
|
||||
@ -55,11 +59,11 @@
|
||||
<el-button style="color: #0064aa">{{ t('airBlower.reset') }}</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
<el-popconfirm title="确认风机对时么?">
|
||||
<!-- <el-popconfirm title="确认风机对时么?">
|
||||
<template #reference>
|
||||
<el-button style="color: #0064aa">{{ t('airBlower.verify') }}</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</el-popconfirm> -->
|
||||
</div>
|
||||
</el-header>
|
||||
<el-main class="mainPart">
|
||||
@ -119,6 +123,24 @@
|
||||
>电网故障停机</el-tag
|
||||
>
|
||||
</div>
|
||||
<div v-if="item.prop === 'chart'" @click="openLineChart(scope.row)" class="operate">
|
||||
<div class="chartIcon">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="icon"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
>
|
||||
{{ scope.row }}
|
||||
<path
|
||||
d="M896 896H96a32 32 0 0 1-32-32V224a32 32 0 0 1 64 0v608h768a32 32 0 1 1 0 64zM247.008 640a32 32 0 0 1-20.992-56.192l200.992-174.24a32 32 0 0 1 42.272 0.288l172.128 153.44 229.088-246.304a32 32 0 0 1 46.88 43.616l-250.432 269.216a31.936 31.936 0 0 1-44.704 2.08l-174.56-155.52-179.744 155.84a31.872 31.872 0 0 1-20.928 7.776z"
|
||||
fill="#00a4ff"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="item.custom === 'header'" #header="scope">
|
||||
<div>{{ scope.column.label.split(' ')[0] }}</div>
|
||||
@ -159,20 +181,34 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="selectPointVisible" title="选择测点" width="1000">
|
||||
<SelectPoint ref="selectPointDialogRef" :defaultAttr="defaultAttr" :visible="selectPointVisible"></SelectPoint>
|
||||
<template #footer>
|
||||
<div class="selectPointDialogFooter">
|
||||
<el-button type="primary" @click="saveSelectPoint">保存</el-button>
|
||||
<el-button @click="selectPointVisible = false">取消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="realDataLineChartVisible" title="实时曲线" @close="closeLineChart">
|
||||
<RealDataChart :visible="realDataLineChartVisible" :id="clickRowId"></RealDataChart>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SelectTypeObjType, SelectTypeKeyUnionType, TableDataObjType, TableColumnType } from './type'
|
||||
import { onUnmounted, reactive, ref, watch, nextTick } from 'vue'
|
||||
import { onUnmounted, reactive, ref, watch, computed, nextTick } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { getAirBlowerListReq, getBelongLineListReq } from '/@/api/backend/airBlower/request'
|
||||
import { CircleCheck, CircleClose, Loading } from '@element-plus/icons-vue'
|
||||
import { CircleCheck, CircleClose, Loading, Crop, Download } from '@element-plus/icons-vue'
|
||||
import { ElMessage, TableInstance, ElPopconfirm } from 'element-plus'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { getRealTimeState } from './utils'
|
||||
import { getRealTimeState, getCutDecimalsValue } from './utils'
|
||||
import { sendCommandReq } from '/@/api/backend/control/request'
|
||||
import { adminBaseRoutePath } from '/@/router/static/adminBase'
|
||||
|
||||
import { getRealValueListReq } from '/@/api/backend/deviceModel/request'
|
||||
import SelectPoint from '/@/views/backend/equipment/airBlower/selectPoint.vue'
|
||||
import RealDataChart from '/@/views/backend/equipment/airBlower/realDataChart.vue'
|
||||
const router = useRouter()
|
||||
|
||||
const { t } = useI18n()
|
||||
@ -338,17 +374,25 @@ const tableHaderStyle = {
|
||||
color: '#333',
|
||||
}
|
||||
|
||||
const tableColumn: TableColumnType[] = [
|
||||
const defaultColumn: TableColumnType[] = [
|
||||
{
|
||||
label: '风机列表',
|
||||
prop: 'name',
|
||||
align: 'center',
|
||||
custom: 'default',
|
||||
},
|
||||
{
|
||||
label: '实时曲线',
|
||||
prop: 'chart',
|
||||
align: 'center',
|
||||
custom: 'default',
|
||||
width: 55,
|
||||
},
|
||||
{
|
||||
label: '风机型号',
|
||||
prop: 'model',
|
||||
align: 'center',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
label: '风机状态',
|
||||
@ -356,135 +400,196 @@ const tableColumn: TableColumnType[] = [
|
||||
align: 'center',
|
||||
custom: 'default',
|
||||
},
|
||||
{
|
||||
label: '线路',
|
||||
prop: 'belongLine',
|
||||
align: 'center',
|
||||
},
|
||||
]
|
||||
const dynamicColumn: TableColumnType[] = [
|
||||
{
|
||||
label: '风速 (m/s)',
|
||||
prop: 'iwindspeed',
|
||||
align: 'center',
|
||||
custom: 'header',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
label: '有功功率 (MW)',
|
||||
prop: 'igenpower',
|
||||
align: 'center',
|
||||
custom: 'header',
|
||||
},
|
||||
{
|
||||
label: '日发电量 (kWh)',
|
||||
prop: 'ikwhthisday',
|
||||
align: 'center',
|
||||
custom: 'header',
|
||||
},
|
||||
{
|
||||
label: '总发电量 (万kWh)',
|
||||
prop: 'ikwhoverall',
|
||||
align: 'center',
|
||||
custom: 'header',
|
||||
},
|
||||
{
|
||||
label: '机舱角度',
|
||||
prop: 'ivanedirection',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
label: '叶轮转速 (rmp)',
|
||||
prop: 'irotorspeed',
|
||||
label: '风向 (°)',
|
||||
prop: 'iwinddirection',
|
||||
align: 'center',
|
||||
custom: 'header',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
label: '发电机转速 (rmp)',
|
||||
prop: 'igenspeed',
|
||||
align: 'center',
|
||||
custom: 'header',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
label: '机舱温度 (℃)',
|
||||
prop: 'itempnacelle_1sec',
|
||||
label: '有功功率 (KW)',
|
||||
prop: 'igenpower',
|
||||
align: 'center',
|
||||
custom: 'header',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
label: '主油路压力 (kpa)',
|
||||
prop: 'ihydrpress',
|
||||
label: '有功给定 (KW)',
|
||||
prop: 'iactivepowersetpointvalue',
|
||||
align: 'center',
|
||||
custom: 'header',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
label: '变桨角度',
|
||||
prop: 'ipitchangle',
|
||||
label: '无功功率 (KVar)',
|
||||
prop: 'ireactivepower',
|
||||
align: 'center',
|
||||
custom: 'header',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
label: '无功给定 (KVar)',
|
||||
prop: 'ireactivepowersetpointvalue',
|
||||
align: 'center',
|
||||
custom: 'header',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
label: '桨叶1角度 (°)',
|
||||
prop: 'ipitchangle1',
|
||||
align: 'center',
|
||||
custom: 'header',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
label: '桨叶2角度 (°)',
|
||||
prop: 'ipitchangle2',
|
||||
align: 'center',
|
||||
custom: 'header',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
label: '桨叶3角度 (°)',
|
||||
prop: 'ipitchangle3',
|
||||
align: 'center',
|
||||
custom: 'header',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
label: '限电原因',
|
||||
prop: 'powerlimitsource',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
label: '机舱位置 (°)',
|
||||
prop: 'ivanedirection',
|
||||
align: 'center',
|
||||
custom: 'header',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
label: '日发电量 (kWh)',
|
||||
prop: 'ikwhthisday',
|
||||
align: 'center',
|
||||
custom: 'header',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
label: '总发电量 (万kWh)',
|
||||
prop: 'ikwhoverall',
|
||||
align: 'center',
|
||||
custom: 'header',
|
||||
width: 100,
|
||||
},
|
||||
]
|
||||
const tableColumn = ref<TableColumnType[]>([...defaultColumn, ...dynamicColumn])
|
||||
|
||||
const tableRef = ref<TableInstance>()
|
||||
const tableData = ref<TableDataObjType[]>([])
|
||||
const originTableData = ref<TableDataObjType[]>([])
|
||||
|
||||
const createTableReqParams = (airblowerList: { irn: string; name: string }[]) => {
|
||||
const curTableKey = tableColumn.value.map((item) => item.prop)
|
||||
const airBlowerIds: any = []
|
||||
const airBlowerInfo: any = {}
|
||||
const params = airblowerList.map((item: any) => {
|
||||
airBlowerInfo[item.irn] = {
|
||||
name: item.name,
|
||||
model: item.model,
|
||||
belongLine: item.belongLine,
|
||||
modelId: item.modelId,
|
||||
deviceCode: item.deviceCode,
|
||||
}
|
||||
airBlowerIds.push(item.irn)
|
||||
return {
|
||||
deviceId: item.irn,
|
||||
attributes: [...curTableKey, 'iturbineoperationmode', 'iyplevel', 'gridlostdetected', 'ibplevel'],
|
||||
}
|
||||
})
|
||||
return { params, airBlowerInfo, airBlowerIds }
|
||||
}
|
||||
const getTableData = () => {
|
||||
let airBlowerInfoObj: any = {}
|
||||
let airBlowerIdList: any[] = []
|
||||
getAirBlowerListReq()
|
||||
.then((res) => {
|
||||
const data = res.data.map((item: any) => {
|
||||
const state = getRealTimeState(item.attributeMap)
|
||||
const ipitchangle = Math.min(item.attributeMap.ipitchangle1, item.attributeMap.ipitchangle2, item.attributeMap.ipitchangle3)
|
||||
const resVal: any = {}
|
||||
Object.keys(item.attributeMap).forEach((attrKey) => {
|
||||
resVal[attrKey] =
|
||||
item.attributeMap[attrKey] === 0
|
||||
? 0
|
||||
: item.attributeMap[attrKey]
|
||||
? item.attributeMap.iwindspeed % 1 === 0
|
||||
? item.attributeMap.iwindspeed
|
||||
: Math.floor(item.attributeMap[attrKey] * 1000) / 1000
|
||||
: '-'
|
||||
})
|
||||
return {
|
||||
irn: item.irn,
|
||||
name: item.name ?? '-',
|
||||
model: item.model || '-',
|
||||
iotModelId: item.modelId,
|
||||
belongLine: item.belongLine || '-',
|
||||
iwindspeed: '-',
|
||||
igenpower: '-',
|
||||
ikwhthisday: '-',
|
||||
ikwhoverall: '-',
|
||||
ivanedirection: '-',
|
||||
irotorspeed: '-',
|
||||
igenspeed: '-',
|
||||
itempnacelle_1sec: '-',
|
||||
ihydrpress: '-',
|
||||
...resVal,
|
||||
ipitchangle: ipitchangle === 0 ? 0 : ipitchangle ? Math.floor(ipitchangle * 1000) / 1000 : '-',
|
||||
iturbineoperationmode: state,
|
||||
}
|
||||
})
|
||||
|
||||
originTableData.value = data
|
||||
if (airBlowerSelect.belongLine === '全部' && airBlowerSelect.iturbineoperationmode === 987654321) {
|
||||
tableData.value = data
|
||||
if (res.success) {
|
||||
return createTableReqParams(res.data)
|
||||
} else {
|
||||
const irn = tableData.value.map((item) => item.irn)
|
||||
const result: TableDataObjType[] = []
|
||||
data.forEach((item: TableDataObjType) => {
|
||||
if (irn.includes(item.irn)) {
|
||||
result.push(item)
|
||||
}
|
||||
})
|
||||
tableData.value = result
|
||||
}
|
||||
if (selectList.value.length) {
|
||||
const selected = tableData.value.filter((item) => selectList.value.includes(item.irn))
|
||||
selected.forEach((item) => {
|
||||
nextTick(() => {
|
||||
tableRef.value?.toggleRowSelection(item, true)
|
||||
})
|
||||
})
|
||||
throw '获取风机列表失败'
|
||||
}
|
||||
})
|
||||
.catch((err: any) => {
|
||||
.then((data) => {
|
||||
airBlowerInfoObj = data.airBlowerInfo
|
||||
airBlowerIdList = data.airBlowerIds
|
||||
return getRealValueListReq(data!.params)
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
const data = airBlowerIdList.map((id) => {
|
||||
const realData: any = {}
|
||||
Object.keys(res.data[id]).forEach((key) => {
|
||||
realData[key] = getCutDecimalsValue(res.data[id][key])
|
||||
})
|
||||
const state = getRealTimeState(res.data[id])
|
||||
return {
|
||||
irn: id,
|
||||
name: airBlowerInfoObj[id].name,
|
||||
model: airBlowerInfoObj[id].model,
|
||||
iotModelId: airBlowerInfoObj[id].modelId,
|
||||
belongLine: airBlowerInfoObj[id].belongLine,
|
||||
deviceCode: airBlowerInfoObj[id].deviceCode,
|
||||
...realData,
|
||||
iturbineoperationmode: state,
|
||||
}
|
||||
})
|
||||
originTableData.value = data
|
||||
|
||||
if (airBlowerSelect.belongLine === '全部' && airBlowerSelect.iturbineoperationmode === 987654321) {
|
||||
tableData.value = data
|
||||
console.log(tableData.value)
|
||||
} else {
|
||||
const irn = tableData.value.map((item) => item.irn)
|
||||
const result: TableDataObjType[] = []
|
||||
data.forEach((item: TableDataObjType) => {
|
||||
if (irn.includes(item.irn)) {
|
||||
result.push(item)
|
||||
}
|
||||
})
|
||||
tableData.value = result
|
||||
}
|
||||
if (selectList.value.length) {
|
||||
const selected = tableData.value.filter((item) => selectList.value.includes(item.irn))
|
||||
selected.forEach((item) => {
|
||||
nextTick(() => {
|
||||
tableRef.value?.toggleRowSelection(item, true)
|
||||
})
|
||||
})
|
||||
}
|
||||
} else {
|
||||
throw '获取风机列表失败'
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
ElMessage.error(err)
|
||||
})
|
||||
}
|
||||
|
||||
@ -509,7 +614,7 @@ const selectTable = (selected: TableDataObjType[]) => {
|
||||
selectList.value = selected.map((item) => item.irn)
|
||||
}
|
||||
|
||||
const autoUpdate = ref(false)
|
||||
const autoUpdate = ref(true)
|
||||
const autoUpdateInterval = ref<any>(null)
|
||||
watch(autoUpdate, (newVal: boolean) => {
|
||||
if (newVal) {
|
||||
@ -519,7 +624,9 @@ watch(autoUpdate, (newVal: boolean) => {
|
||||
getTableData()
|
||||
}, 2000)
|
||||
} else {
|
||||
ElMessage.warning('关闭自动刷新')
|
||||
if (realDataLineChartVisible.value) {
|
||||
ElMessage.warning('关闭自动刷新')
|
||||
}
|
||||
clearInterval(autoUpdateInterval.value)
|
||||
autoUpdateInterval.value = null
|
||||
}
|
||||
@ -538,13 +645,14 @@ const openWindTurbine = (row: TableDataObjType) => {
|
||||
},
|
||||
})
|
||||
}
|
||||
console.log(row)
|
||||
|
||||
router.push({
|
||||
name: 'windTurbine',
|
||||
query: {
|
||||
irn: row.irn,
|
||||
iotModelId: row.iotModelId,
|
||||
name: row.name,
|
||||
deviceCode: row.deviceCode,
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -565,6 +673,101 @@ const mutiTaskList = ref<
|
||||
}[]
|
||||
>([])
|
||||
|
||||
const selectPointDialogRef = ref()
|
||||
const selectPointVisible = ref(false)
|
||||
const defaultAttr = computed(() => {
|
||||
return dynamicColumn.map((item) => {
|
||||
return {
|
||||
attributeName: item.label.split(' ')[0],
|
||||
unit: item.label.split(' ')[1] ?? '',
|
||||
attributeCode: item.prop as string,
|
||||
}
|
||||
})
|
||||
})
|
||||
const openMeasure = () => {
|
||||
selectPointVisible.value = true
|
||||
}
|
||||
const saveSelectPoint = () => {
|
||||
const list = selectPointDialogRef.value?.getSelectList()
|
||||
if (list) {
|
||||
console.log(list)
|
||||
|
||||
const addCoulmn = list.map((item: any) => {
|
||||
return {
|
||||
label: item.unit ? item.attributeName + item.unit : item.attributeName,
|
||||
prop: item.attributeCode.toLowerCase(),
|
||||
align: 'center',
|
||||
custom: item.unit ? 'header' : undefined,
|
||||
width: 100,
|
||||
}
|
||||
})
|
||||
tableColumn.value = [...defaultColumn, ...addCoulmn]
|
||||
|
||||
getTableData()
|
||||
selectPointVisible.value = false
|
||||
ElMessage.success('选择成功')
|
||||
}
|
||||
}
|
||||
const downFun = () => {
|
||||
const itemsWithoutAge = tableData.value.map((item) => {
|
||||
const { irn, ...rest } = item
|
||||
return rest
|
||||
})
|
||||
if (!tableColumn.value.length || !itemsWithoutAge.length) {
|
||||
return []
|
||||
}
|
||||
const columnSet = new Set(tableColumn.value.map((item) => item.prop))
|
||||
const result: any = []
|
||||
itemsWithoutAge.forEach((item) => {
|
||||
const newItem: any = {}
|
||||
for (const itemKey in item) {
|
||||
if (columnSet.has(itemKey)) {
|
||||
newItem[itemKey] = item[itemKey]
|
||||
}
|
||||
}
|
||||
if (Object.keys(newItem).length > 0) {
|
||||
result.push(newItem)
|
||||
}
|
||||
})
|
||||
let addobj: any = {}
|
||||
tableColumn.value.map((v, i) => {
|
||||
addobj['rowData' + i] = v.label
|
||||
})
|
||||
let tableDatadown = JSON.parse(JSON.stringify(result))
|
||||
tableDatadown.unshift(addobj)
|
||||
console.log(tableDatadown)
|
||||
|
||||
let str = ``
|
||||
for (let i = 0; i < tableDatadown.length; i++) {
|
||||
for (let item in tableDatadown[i]) {
|
||||
if (typeof tableDatadown[i][item] === 'string') {
|
||||
tableDatadown[i][item] = tableDatadown[i][item].replace(/[\n,]/g, (match: any) => (match === '\n' ? ' ' : ','))
|
||||
} else {
|
||||
console.warn(`tableDatadown[${i}][${item}] is not a string`)
|
||||
}
|
||||
str += `${tableDatadown[i][item] + '\t'},`
|
||||
}
|
||||
str += '\n'
|
||||
}
|
||||
let uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(str)
|
||||
let link = document.createElement('a')
|
||||
link.href = uri
|
||||
link.download = '实时数据' + Date.now() + '.csv'
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
}
|
||||
|
||||
const clickRowId = ref('')
|
||||
const realDataLineChartVisible = ref(false)
|
||||
const openLineChart = (row: TableDataObjType) => {
|
||||
clickRowId.value = row.irn
|
||||
realDataLineChartVisible.value = true
|
||||
autoUpdate.value = false
|
||||
}
|
||||
const closeLineChart = () => {
|
||||
autoUpdate.value = true
|
||||
}
|
||||
onUnmounted(() => {
|
||||
autoUpdateInterval.value && clearInterval(autoUpdateInterval.value)
|
||||
autoUpdateInterval.value = null
|
||||
@ -585,10 +788,11 @@ getBlongLineList()
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
// justify-content: space-between;
|
||||
align-items: center;
|
||||
.headerLeft {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
.selectPart {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@ -606,8 +810,18 @@ getBlongLineList()
|
||||
}
|
||||
}
|
||||
}
|
||||
.headerCenter {
|
||||
width: 212px;
|
||||
margin-left: 30px;
|
||||
flex-shrink: 0;
|
||||
.el-button {
|
||||
width: 100px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
.headerRight {
|
||||
width: 436px;
|
||||
margin-left: auto;
|
||||
width: 336px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.el-button {
|
||||
@ -619,7 +833,7 @@ getBlongLineList()
|
||||
.mainPart {
|
||||
width: 100%;
|
||||
height: calc(100% - 60px);
|
||||
.tableClass{
|
||||
.tableClass {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
@ -628,6 +842,18 @@ getBlongLineList()
|
||||
color: #00a4ff;
|
||||
cursor: pointer;
|
||||
}
|
||||
.operate {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.chartIcon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -656,4 +882,12 @@ getBlongLineList()
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.selectPointDialogFooter {
|
||||
text-align: center;
|
||||
.el-button {
|
||||
width: 120px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -0,0 +1,421 @@
|
||||
<template>
|
||||
<div class="realDataChart">
|
||||
<el-row>
|
||||
<el-col :span="8" class="leftPart">
|
||||
<div class="leftHeader">
|
||||
<el-button type="primary" @click="addPoint">添加测点</el-button>
|
||||
</div>
|
||||
<div class="leftMain">
|
||||
<el-scrollbar>
|
||||
<el-checkbox-group v-model="selectList">
|
||||
<el-checkbox
|
||||
v-for="item in realDataList"
|
||||
:key="item.prop"
|
||||
:label="item.name"
|
||||
:value="item.prop"
|
||||
class="checkboxStyle"
|
||||
></el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="16" class="rightPart">
|
||||
<div class="chartPart">
|
||||
<div class="chartRef" ref="chartRef"></div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<el-dialog v-model="selectPointVisible" title="选择测点" width="1000">
|
||||
<SelectPoint ref="selectPointRef" :visible="selectPointVisible" :default-attr="selectPointAttr"></SelectPoint>
|
||||
<template #footer>
|
||||
<div class="selectPointDialogFooter">
|
||||
<el-button type="primary" @click="saveSelectPoint">保存</el-button>
|
||||
<el-button @click="selectPointVisible = false">取消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
import SelectPoint from '/@/views/backend/equipment/airBlower/selectPoint.vue'
|
||||
import { getRealValueListReq } from '/@/api/backend/deviceModel/request'
|
||||
import { dayjs } from 'element-plus'
|
||||
|
||||
const props = withDefaults(defineProps<{ id: string; visible: boolean }>(), {
|
||||
id: '',
|
||||
visible: false,
|
||||
})
|
||||
|
||||
//#region
|
||||
const defaultList = [
|
||||
{
|
||||
prop: 'iturbineoperationmode',
|
||||
name: '运行模式',
|
||||
unit: '',
|
||||
},
|
||||
{
|
||||
prop: 'iwindspeed',
|
||||
name: '风速',
|
||||
unit: '(m/s)',
|
||||
},
|
||||
{
|
||||
prop: 'iwinddirection',
|
||||
name: '风向',
|
||||
unit: '(°)',
|
||||
},
|
||||
{
|
||||
prop: 'igenspeed',
|
||||
name: '发电机转速',
|
||||
unit: '(rpm)',
|
||||
},
|
||||
{
|
||||
prop: 'igenpower',
|
||||
name: '有功功率',
|
||||
unit: '(kW)',
|
||||
},
|
||||
{
|
||||
prop: 'iactivepowersetpointvalue',
|
||||
name: '有功给定',
|
||||
unit: '(kW)',
|
||||
},
|
||||
{
|
||||
prop: 'ireactivepower',
|
||||
name: '无功功率',
|
||||
unit: '(kVar)',
|
||||
},
|
||||
{
|
||||
prop: 'ireactivepowersetpointvalue',
|
||||
name: '无功给定',
|
||||
unit: '(kVar)',
|
||||
},
|
||||
{
|
||||
prop: 'ipitchangle1',
|
||||
name: '桨叶1角度',
|
||||
unit: '(°)',
|
||||
},
|
||||
{
|
||||
prop: 'ipitchangle2',
|
||||
name: '桨叶2角度',
|
||||
unit: '(°)',
|
||||
},
|
||||
{
|
||||
prop: 'ipitchangle3',
|
||||
name: '桨叶3角度',
|
||||
unit: '(°)',
|
||||
},
|
||||
]
|
||||
//#endregion
|
||||
const selectList = ref([])
|
||||
watch(
|
||||
() => selectList.value,
|
||||
() => {
|
||||
if (!timer && selectList.value[0]) {
|
||||
createTimer()
|
||||
}
|
||||
if (selectList.value.length === 0) {
|
||||
clearTimer()
|
||||
chartInstance && chartInstance.clear()
|
||||
}
|
||||
}
|
||||
)
|
||||
const realDataList = ref<any[]>(JSON.parse(JSON.stringify(defaultList)))
|
||||
|
||||
const chartRef = ref()
|
||||
let chartInstance: any = null
|
||||
|
||||
const getRealData = () => {
|
||||
const params = selectList.value.map((item: string) => item.toLowerCase())
|
||||
const time = dayjs().format('YYYY-MM-DD HH:mm:ss')
|
||||
getRealValueListReq([
|
||||
{
|
||||
deviceId: props.id,
|
||||
attributes: params,
|
||||
},
|
||||
]).then((res) => {
|
||||
if (res.code === 200) {
|
||||
createChartData(res.data[props.id], time)
|
||||
}
|
||||
})
|
||||
return []
|
||||
}
|
||||
let realDataXAxis: any = []
|
||||
let realDataSeries: any = []
|
||||
const getRandomDarkColor = () => {
|
||||
let r = Math.floor(Math.random() * 200) // 限制在0到127之间,以生成较深的颜色
|
||||
let g = Math.floor(Math.random() * 200)
|
||||
let b = Math.floor(Math.random() * 200)
|
||||
|
||||
let color = `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`
|
||||
return color
|
||||
}
|
||||
|
||||
const createChartData = (data: { [k: string]: number }, time: string) => {
|
||||
if (realDataXAxis.length > 120) {
|
||||
realDataXAxis.shift()
|
||||
realDataSeries.forEach((item: any) => {
|
||||
item.data.shift()
|
||||
})
|
||||
}
|
||||
const attrCode = Object.keys(data)
|
||||
realDataXAxis.push(time)
|
||||
const lastSeriesId = realDataSeries.map((item: any) => item.id)
|
||||
const color = getRandomDarkColor()
|
||||
let clearState = null
|
||||
lastSeriesId.forEach((item: any) => {
|
||||
if (!attrCode.includes(item)) {
|
||||
const cur = realDataSeries.find((val: any) => val.id === item)
|
||||
delete cur.id
|
||||
clearState = true
|
||||
}
|
||||
})
|
||||
if (clearState) {
|
||||
chartInstance.setOption(
|
||||
{
|
||||
series: realDataSeries,
|
||||
},
|
||||
{
|
||||
replaceMerge: ['series'],
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
const seriesData = attrCode.map((item) => {
|
||||
if (lastSeriesId.includes(item)) {
|
||||
const cur = realDataSeries.find((val: any) => val.id === item)
|
||||
cur.data.push(data[item])
|
||||
return cur
|
||||
} else {
|
||||
const info = realDataList.value.find((val) => val.prop === item)
|
||||
const list = realDataSeries?.[0]?.data ?? []
|
||||
const len = list.length
|
||||
const fillData = new Array(len).fill('')
|
||||
fillData.push(data[item])
|
||||
return {
|
||||
id: item,
|
||||
name: info.name + info.unit,
|
||||
type: 'line',
|
||||
barWidth: 20,
|
||||
itemStyle: {
|
||||
color: color,
|
||||
barBorderRadius: 2,
|
||||
},
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
data: fillData,
|
||||
}
|
||||
}
|
||||
})
|
||||
realDataSeries = seriesData
|
||||
createChart()
|
||||
}
|
||||
const createChart = () => {
|
||||
const chart = chartInstance ?? echarts.init(chartRef.value)
|
||||
let option = null
|
||||
if (chartInstance && realDataXAxis.length > 1) {
|
||||
option = {
|
||||
xAxis: {
|
||||
data: realDataXAxis,
|
||||
},
|
||||
series: realDataSeries,
|
||||
}
|
||||
} else {
|
||||
option = {
|
||||
grid: {
|
||||
top: 50,
|
||||
right: 23,
|
||||
bottom: 50,
|
||||
left: 18,
|
||||
containLabel: true,
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
},
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#dadada',
|
||||
width: 1,
|
||||
type: 'solid',
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
//x轴文字的配置
|
||||
show: true,
|
||||
color: '#4E5969',
|
||||
interval: 'auto',
|
||||
formatter: function (value: any) {
|
||||
return value.slice(11)
|
||||
},
|
||||
//rotate: 45
|
||||
},
|
||||
splitLine: {
|
||||
//分割线配置
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#999999',
|
||||
},
|
||||
},
|
||||
data: realDataXAxis,
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: '',
|
||||
nameTextStyle: {
|
||||
color: '#4E5969',
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#dadada',
|
||||
width: 0,
|
||||
type: 'solid',
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
//x轴文字的配置
|
||||
show: true,
|
||||
color: '#4E5969',
|
||||
},
|
||||
axisTick: { show: false },
|
||||
splitLine: {
|
||||
interval: 50,
|
||||
lineStyle: {
|
||||
type: 'dashed',
|
||||
color: '#dadada',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
],
|
||||
legend: {
|
||||
data: [],
|
||||
textStyle: {
|
||||
color: '#73767a',
|
||||
},
|
||||
},
|
||||
series: realDataSeries,
|
||||
}
|
||||
}
|
||||
chart.setOption(option, { replaceMerge: 'series' })
|
||||
chartInstance = chart
|
||||
}
|
||||
|
||||
const selectPointRef = ref()
|
||||
const selectPointVisible = ref(false)
|
||||
const selectPointAttr = computed(() => {
|
||||
return realDataList.value.map((item) => {
|
||||
return {
|
||||
attributeName: item.name,
|
||||
attributeCode: item.prop,
|
||||
}
|
||||
})
|
||||
})
|
||||
const addPoint = () => {
|
||||
selectPointVisible.value = true
|
||||
}
|
||||
const saveSelectPoint = () => {
|
||||
const data = selectPointRef.value?.getSelectList()
|
||||
if (data) {
|
||||
const selectList = data.map((item: any) => {
|
||||
return {
|
||||
prop: item.attributeCode,
|
||||
name: item.attributeName,
|
||||
unit: item.unit,
|
||||
}
|
||||
})
|
||||
realDataList.value = selectList
|
||||
}
|
||||
}
|
||||
let timer: any = null
|
||||
const createTimer = () => {
|
||||
timer = setInterval(() => {
|
||||
getRealData()
|
||||
}, 1000)
|
||||
}
|
||||
const clearTimer = () => {
|
||||
timer && clearInterval(timer)
|
||||
timer = null
|
||||
realDataSeries = []
|
||||
realDataXAxis = []
|
||||
}
|
||||
onMounted(() => {
|
||||
if (selectList.value.length > 0) {
|
||||
createTimer()
|
||||
}
|
||||
})
|
||||
onUnmounted(() => {
|
||||
clearTimer()
|
||||
chartInstance && chartInstance.dispose()
|
||||
selectList.value = []
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(v) => {
|
||||
if (!v) {
|
||||
clearTimer()
|
||||
chartInstance && chartInstance.clear()
|
||||
selectList.value = []
|
||||
}
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.realDataChart {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.leftPart {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-right: 1px solid #edf2fa;
|
||||
.leftHeader {
|
||||
padding: 10px;
|
||||
}
|
||||
.leftMain {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
.checkboxStyle {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.rightPart {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 452px;
|
||||
.chartPart {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 452px;
|
||||
|
||||
.chartRef {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 452px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,278 @@
|
||||
<template>
|
||||
<div class="selectPoint">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<div class="transferLeft">
|
||||
<div class="transferHeader">
|
||||
<span class="transferTitle">可添加的测点</span>
|
||||
<el-radio-group v-model="radioActiveName" @change="typeChange">
|
||||
<el-radio :value="138">模拟量</el-radio>
|
||||
<el-radio :value="199">计算量</el-radio>
|
||||
<el-radio :value="140">状态量</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<el-main class="mainPart">
|
||||
<el-table
|
||||
class="tablePart"
|
||||
ref="attributeTableRef"
|
||||
:data="attributeTableData"
|
||||
@select="selectTable"
|
||||
@selectAll="selectAllTable"
|
||||
row-key="id"
|
||||
>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="porder" label="序号" width="60" />
|
||||
<el-table-column prop="attributeCode" sortable label="名称" />
|
||||
<el-table-column prop="attributeName" sortable label="描述" />
|
||||
</el-table>
|
||||
<div class="mainFooter" style="display: flex; justify-content: left">
|
||||
<el-pagination
|
||||
v-model:current-page="pageSetting.current"
|
||||
v-model:page-size="pageSetting.pageSize"
|
||||
:total="pageSetting.total"
|
||||
:page-sizes="pageSetting.pageSizes"
|
||||
:pager-count="5"
|
||||
background
|
||||
@change="pageChange"
|
||||
layout="prev,pager,next,sizes"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</el-main>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<div class="transferRight">
|
||||
<div class="transferHeader">
|
||||
<span class="transferTitle"
|
||||
>已选择<span>{{ Statistic }}</span
|
||||
>项</span
|
||||
>
|
||||
<div @click="clearList" style="color: rgb(0, 100, 170); cursor: pointer">清空</div>
|
||||
</div>
|
||||
<el-main class="transferMain">
|
||||
<el-scrollbar>
|
||||
<div class="selectItem" v-for="(item, index) in multipleSelection" :key="item.attributeCode">
|
||||
{{ item.attributeName }}
|
||||
<div>
|
||||
<el-icon v-if="index !== 0" :size="20" @click="moveUp(index)"><Top /></el-icon>
|
||||
<el-icon v-if="index !== Statistic - 1" :size="20" @click="moveDown(index)"><Bottom /></el-icon>
|
||||
<el-icon v-else :size="20"></el-icon>
|
||||
<el-icon :size="20" @click="moveRemove(index, item)"><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</el-main>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, watch, nextTick, onMounted } from 'vue'
|
||||
import { getModelAttributeListReq } from '/@/api/backend/deviceModel/request'
|
||||
import { ElMessage, TableInstance } from 'element-plus'
|
||||
import { Top, Bottom, Close } from '@element-plus/icons-vue'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
defaultAttr: { attributeCode: string; attributeName: string }[]
|
||||
visible: boolean
|
||||
}>(),
|
||||
{
|
||||
defaultAttr: () => [],
|
||||
visible: false,
|
||||
}
|
||||
)
|
||||
|
||||
const radioActiveName = ref<138 | 139 | 140 | 199>(138)
|
||||
const typeChange = () => {
|
||||
getTableData()
|
||||
}
|
||||
|
||||
const attributeTableData = ref<{ attributeName: string; attributeCode: string }[]>([])
|
||||
const selectTable = (section: any) => {
|
||||
const defaultCode = props.defaultAttr.map((item: any) => item.attributeCode)
|
||||
const addSection = section
|
||||
.filter((item: any) => !defaultCode.includes(item.attributeCode.toLowerCase()))
|
||||
.map((item:any) => {
|
||||
return {
|
||||
attributeName: item.attributeName,
|
||||
attributeCode: item.attributeCode.toLowerCase(),
|
||||
unit: item.unit,
|
||||
}
|
||||
})
|
||||
multipleSelection.value = [...props.defaultAttr, ...addSection]
|
||||
}
|
||||
const selectAllTable = (section: any) => {
|
||||
const defaultCode = props.defaultAttr.map((item: any) => item.attributeCode)
|
||||
const addSection = section
|
||||
.filter((item: any) => !defaultCode.includes(item.attributeCode.toLowerCase()))
|
||||
.map((item:any) => {
|
||||
return {
|
||||
attributeName: item.attributeName,
|
||||
attributeCode: item.attributeCode.toLowerCase(),
|
||||
unit: item.unit,
|
||||
}
|
||||
})
|
||||
multipleSelection.value = [...props.defaultAttr, ...addSection]
|
||||
}
|
||||
const pageSetting = reactive({
|
||||
current: 1,
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
pageSizes: [20, 50, 100],
|
||||
})
|
||||
const pageChange = () => {
|
||||
getTableData()
|
||||
}
|
||||
|
||||
const attributeTableRef = ref<TableInstance>()
|
||||
const multipleSelection = ref<{ attributeName: string; attributeCode: string }[]>(props.defaultAttr)
|
||||
const Statistic = computed(() => multipleSelection.value.length)
|
||||
const clearList = () => {
|
||||
multipleSelection.value = []
|
||||
nextTick(() => {
|
||||
attributeTableRef.value?.clearSelection()
|
||||
})
|
||||
}
|
||||
const moveUp = (index: number) => {
|
||||
if (index > 0) {
|
||||
const temp = multipleSelection.value[index]
|
||||
multipleSelection.value[index] = multipleSelection.value[index - 1]
|
||||
multipleSelection.value[index - 1] = temp
|
||||
}
|
||||
}
|
||||
const moveDown = (index: number) => {
|
||||
if (index < Statistic.value - 1) {
|
||||
const temp = multipleSelection.value[index]
|
||||
multipleSelection.value[index] = multipleSelection.value[index + 1]
|
||||
multipleSelection.value[index + 1] = temp
|
||||
}
|
||||
}
|
||||
const moveRemove = (index: number, item: any) => {
|
||||
multipleSelection.value.splice(index, 1)
|
||||
nextTick(() => {
|
||||
const row = attributeTableData.value.find((attr) => attr.attributeCode === item.attributeCode)
|
||||
attributeTableRef.value?.toggleRowSelection(row, false)
|
||||
})
|
||||
}
|
||||
|
||||
const getTableData = () => {
|
||||
getModelAttributeListReq({
|
||||
iotModelId: '',
|
||||
attributeType: radioActiveName.value,
|
||||
pageNum: pageSetting.current,
|
||||
pageSize: pageSetting.pageSize,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
attributeTableData.value = res.rows
|
||||
pageSetting.total = res.total
|
||||
nextTick(() => {
|
||||
initSelect()
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
ElMessage.error(err)
|
||||
})
|
||||
}
|
||||
const initSelect = () => {
|
||||
const defaultCode = props.defaultAttr.map((item: any) => item.attributeCode)
|
||||
|
||||
const row = attributeTableData.value.filter((item) => defaultCode.includes(item.attributeCode.toLowerCase()))
|
||||
if (row.length === 0) return
|
||||
row.forEach((item) => {
|
||||
attributeTableRef.value?.toggleRowSelection(item, true)
|
||||
})
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
() => {
|
||||
if (props.visible) {
|
||||
pageSetting.current = 1
|
||||
pageSetting.pageSize = 20
|
||||
}
|
||||
}
|
||||
)
|
||||
const getSelectList = () => {
|
||||
return multipleSelection.value
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
getSelectList,
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
getTableData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.selectPoint {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.transferHeader {
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 10px;
|
||||
color: #333333;
|
||||
background: #f7f9fc;
|
||||
border-bottom: 1px solid #e1edf6;
|
||||
border-radius: 6px 6px 0 0;
|
||||
}
|
||||
.transferLeft {
|
||||
width: 550px;
|
||||
height: 700px;
|
||||
border: 1px solid #e1edf6;
|
||||
border-radius: 6px;
|
||||
.mainPart {
|
||||
padding: 10px;
|
||||
height: 660px;
|
||||
.tablePart {
|
||||
height: calc(100% - 42px);
|
||||
}
|
||||
.mainFooter {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.transferRight {
|
||||
height: 700px;
|
||||
border: 1px solid #e1edf6;
|
||||
border-radius: 6px;
|
||||
.transferMain {
|
||||
height: 655px;
|
||||
/*padding: 10px;*/
|
||||
padding: 0;
|
||||
::v-deep .el-table__row {
|
||||
height: 40px;
|
||||
padding: 0 20px;
|
||||
background: #eff0f1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.selectItem {
|
||||
height: 40px;
|
||||
padding: 0 20px;
|
||||
background: #eff0f1;
|
||||
border-radius: 4px;
|
||||
margin: 10px;
|
||||
list-style: none;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.el-icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
.mainFooter {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -24,6 +24,8 @@ export type TableDataObjType = {
|
||||
itempnacelle_1sec: string
|
||||
ihydrpress: string
|
||||
ipitchangle: string
|
||||
} & {
|
||||
[key: string]: any
|
||||
}
|
||||
export type TableColumnSortType = {
|
||||
type?: 'default' | 'selection' | 'index' | 'expand'
|
||||
|
@ -390,6 +390,7 @@ const initChart = (data: { values: number[]; times: number[] }) => {
|
||||
const times = data?.times.map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
|
||||
|
||||
const option = {
|
||||
animation: false,
|
||||
grid: {
|
||||
top: 50,
|
||||
right: 23,
|
||||
@ -476,7 +477,7 @@ const initChart = (data: { values: number[]; times: number[] }) => {
|
||||
},
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
data: data?.values ?? [],
|
||||
data: data?.values ?? []
|
||||
},
|
||||
],
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user