历史数据:新增页面

实时数据:添加本地测点缓存
This commit is contained in:
高云鹏 2025-01-13 17:45:55 +08:00
parent 1baa3f77c2
commit 14e00ae08f
4 changed files with 1048 additions and 4 deletions

View File

@ -0,0 +1,57 @@
import createAxios from '/@/utils/axios'
export const getTemplateListReq = (data: { category: '历史数据' & string; pageNum: number; pageSize: number }) => {
return createAxios<
never,
Promise<{
code: number
msg: string
data: {
total: number
rows: { id: string; category: '历史数据' & string; template: string }[]
code: number
msg: string
}
success: boolean
}>
>({
url: '/api/page/report/template/getList',
method: 'post',
data,
})
}
export const addTemplateListReq = (data: { category: '历史数据' & string; template: string }) => {
return createAxios<
never,
Promise<{
code: number
msg: string
data: {
id: string
category: '历史数据' & string
template: string
}[]
success: boolean
}>
>({
url: '/api/page/report/template/add',
method: 'post',
data,
})
}
export const delTemplateListReq = (data: { id: string }) => {
return createAxios<
never,
Promise<{
code: number
msg: string
success: boolean
}>
>({
url: '/api/page/report/template/del',
method: 'post',
data,
})
}

View File

@ -237,6 +237,7 @@ 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'
import { permission } from '/@/utils/directive'
import { table } from 'console'
const vPermission = permission()
const router = useRouter()
@ -423,7 +424,7 @@ const defaultColumn: TableColumnType[] = [
width: 100,
},
]
const dynamicColumn: TableColumnType[] = [
let dynamicColumn: TableColumnType[] = [
{
label: '风速 (m/s)',
prop: 'iwindspeed',
@ -523,6 +524,17 @@ const dynamicColumn: TableColumnType[] = [
},
]
const tableColumn = ref<TableColumnType[]>([...defaultColumn, ...dynamicColumn])
const getSaveColumn = () => {
const saveColumn = localStorage.getItem('airBlowerTableColumnList')
console.log(saveColumn,'saveColumn');
if (saveColumn) {
tableColumn.value = JSON.parse(saveColumn)
console.log(tableColumn.value,'tableColumn.value');
dynamicColumn = tableColumn.value.slice(4)
}
}
getSaveColumn()
const tableRef = ref<TableInstance>()
const tableData = ref<TableDataObjType[]>([])
@ -611,7 +623,7 @@ const getTableData = () => {
}
})
.catch((err) => {
ElMessage.error(err)
// ElMessage.error(err)
})
}
@ -702,9 +714,10 @@ const selectPointDialogRef = ref()
const selectPointVisible = ref(false)
const defaultAttr = computed(() => {
return dynamicColumn.map((item) => {
tableColumn.value.length
return {
attributeName: item.label.split(' ')[0],
unit: item.label.split(' ')[1] ?? '',
unit:item.label.split(' ')[1] ?? '',
attributeCode: item.prop as string,
}
})
@ -728,7 +741,7 @@ const saveSelectPoint = () => {
}
})
tableColumn.value = [...defaultColumn, ...addCoulmn]
localStorage.setItem('airBlowerTableColumnList', JSON.stringify(tableColumn.value))
getTableData()
selectPointVisible.value = false
ElMessage.success('选择成功')

View File

@ -0,0 +1,964 @@
<template>
<div class="historyData">
<el-container class="container">
<el-header class="header">
<div class="timePart">
<span class="label">时间</span>
<div class="timeSelect">
<el-date-picker
v-model="searchData.time"
:type="searchData.interval == '1d' ? 'daterange' : 'datetimerange'"
:value-format="searchData.interval == '1d' ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'"
:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]"
:teleported="false"
:shortcuts="shortcuts"
/>
</div>
</div>
<div class="intervalPart">
<span class="label">间隔</span>
<el-select v-model="searchData.interval" placeholder="请选择间隔">
<el-option v-for="v in intervalOptions" :key="v.value" :label="v.label" :value="v.value"></el-option>
</el-select>
</div>
<div class="templatePart">
<span class="label">模板</span>
<el-select v-model="searchData.template" placeholder="请选择模板" clearable>
<el-option v-for="v in templateOptions" :key="v.id" :label="v.name" :value="v.id" @click="changeTemplate">
<template #default>
<div class="templateOption">
<span>{{ v.name }}</span>
<el-icon :size="18" style="color: red" @click="delTemplate(v.id)">
<Delete />
</el-icon>
</div>
</template>
</el-option>
</el-select>
</div>
<el-button type="primary" :icon="Crop" class="pointSelect" @click="openMeasure">测点选择</el-button>
<div class="opeareBtn">
<el-button type="primary" :loading="searchLoading" @click="getData">查询</el-button>
<el-button style="color: #0064aa" @click="exportExcel">导出</el-button>
<el-button class="button" :icon="Notebook" type="primary" @click="addTemplate" plain>保存为模板</el-button>
</div>
</el-header>
<el-main class="main">
<el-table v-loading="searchLoading" :data="tableData" height="100%">
<el-table-column v-for="item in tableColumn" :key="item.prop" :prop="item.prop" :label="item.label"></el-table-column>
</el-table>
</el-main>
<el-footer class="footer">
<el-pagination
v-model:current-page="pageSetting.current"
v-model:page-size="pageSetting.pageSize"
:total="pageSetting.total"
:page-sizes="pageSetting.pageSizes"
background
:pager-count="7"
layout="prev, pager, next, jumper,sizes,total"
@change="getcurrentPage"
></el-pagination>
</el-footer>
</el-container>
<el-dialog v-model="pointDialogVisible" title="测点选择" width="1200">
<el-row :gutter="10" class="pointDialogRow">
<el-col :span="4" class="pointDialogCol">
<div class="pointDialogColTitle">风机列表</div>
<div class="pointDialogColContent">
<el-scrollbar>
<el-checkbox-group v-model="selectWindBlower">
<el-checkbox
v-for="v in windBlowerOptions"
:key="v.value"
:label="v.label"
:value="v.value"
size="large"
class="windBlowerCheckbox"
></el-checkbox>
</el-checkbox-group>
</el-scrollbar>
</div>
</el-col>
<el-col :span="15" class="pointDialogCol">
<div class="pointDialogColTitle">
<span class="title">测点列表</span>
<div class="pointDialogColTitleInput">
<el-input v-model="pointDialogSearchData.inputValue" clearable @keyup.enter="pointDialogSearch"></el-input>
<el-button type="primary" @click="pointDialogSearch">查询</el-button>
</div>
<div class="pointDialogColTitleRightPart">
<el-radio-group v-model="pointDialogSearchData.type" @change="pointDialogRaidoChange">
<el-radio :value="138" label="模拟量"></el-radio>
<el-radio :value="199" label="计算量"></el-radio>
</el-radio-group>
</div>
</div>
<div class="pointDialogColContent">
<el-table ref="pointDialogTableRef" class="pointTable" :data="pointDialogTableData">
<!-- @select="pointDialogTableSelect"
@select-all="pointDialogTableSelectAll" -->
<!-- <el-table-column type="selection" width="55"></el-table-column> -->
<el-table-column label="属性名称" prop="attributeName"></el-table-column>
<el-table-column label="属性编码" prop="attributeCode"></el-table-column>
<el-table-column label="瞬时值" prop="interpolation" width="70">
<template #default="scope">
<div class="showValueType">
<el-checkbox @change="autoSelectRow(scope, 'interpolation')" v-model="scope.row.interpolation"></el-checkbox>
</div>
</template>
</el-table-column>
<el-table-column label="平均值" prop="average" width="70">
<template #default="scope">
<div class="showValueType">
<el-checkbox @change="autoSelectRow(scope, 'average')" v-model="scope.row.average"></el-checkbox>
</div>
</template>
</el-table-column>
<el-table-column label="最大值" prop="max" width="70">
<template #default="scope">
<div class="showValueType">
<el-checkbox @change="autoSelectRow(scope, 'max')" v-model="scope.row.max"></el-checkbox>
</div>
</template>
</el-table-column>
<el-table-column label="最小值" prop="min" width="70">
<template #default="scope">
<div class="showValueType">
<el-checkbox @change="autoSelectRow(scope, 'min')" v-model="scope.row.min"></el-checkbox>
</div>
</template>
</el-table-column>
</el-table>
<div class="footer">
<el-pagination
v-model:current-page="pointDialogPageSetting.current"
v-model:page-size="pointDialogPageSetting.pageSize"
:total="pointDialogPageSetting.total"
:page-sizes="pointDialogPageSetting.pageSizes"
background
:pager-count="4"
layout="prev, pager, next, jumper,sizes,total"
@change="getcurrentPageForPointDialog"
></el-pagination>
</div>
</div>
</el-col>
<el-col :span="5" class="pointDialogCol">
<div class="pointDialogColTitle">
<span>已选择测点列表</span>
<el-button @click="clearmultipleSelection">清空</el-button>
</div>
<div class="pointDialogSelectedList">
<el-scrollbar>
<div class="selectItem" v-for="(item, index) in multipleSelection" :key="item.prop">
<span>{{ item.label }}</span>
<div class="moveIcon">
<el-icon v-if="index !== 0" :size="18" @click="moveUp(index)"><Top /></el-icon>
<el-icon v-if="index !== multipleSelection.length - 1" :size="18" @click="moveDown(index)"><Bottom /></el-icon>
<el-icon v-else :size="18"></el-icon>
<el-icon :size="18" @click="moveRemove(index, item)"><Close /></el-icon>
</div>
</div>
</el-scrollbar>
</div>
</el-col>
</el-row>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitPointDialog"> 确认 </el-button>
<el-button @click="pointDialogVisible = false">取消</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { Crop, Notebook, Delete, Top, Bottom, Close } from '@element-plus/icons-vue'
import { dayjs, ElMessageBox, ElMessage, TableInstance } from 'element-plus'
import { getAirBlowerListReq } from '/@/api/backend/airBlower/request'
import { getModelAttributeListReq, getRealValueRangeReq } from '/@/api/backend/deviceModel/request'
import { getTemplateListReq, addTemplateListReq, delTemplateListReq } from '/@/api/backend/historyData/request'
import { windowReq } from '/@/api/backend/statAnalysis/request'
import { selectData } from '/@/views/backend/historyData/type'
const shortcuts = [
{
text: '今天',
value: () => {
const start = dayjs().startOf('day').format('YYYY-MM-DD HH:mm:ss')
const end = dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss')
return [start, end]
},
},
{
text: '昨天',
value: () => {
const start = dayjs().subtract(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss')
const end = dayjs().subtract(1, 'day').endOf('day').format('YYYY-MM-DD HH:mm:ss')
return [start, end]
},
},
{
text: '前3天',
value: () => {
const start = dayjs().subtract(3, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss')
const end = dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss')
return [start, end]
},
},
{
text: '本周',
value: () => {
const start = dayjs().startOf('week').format('YYYY-MM-DD HH:mm:ss')
const end = dayjs().endOf('week').format('YYYY-MM-DD HH:mm:ss')
return [start, end]
},
},
{
text: '本月',
value: () => {
const start = dayjs().startOf('month').format('YYYY-MM-DD HH:mm:ss')
const end = dayjs().endOf('month').format('YYYY-MM-DD HH:mm:ss')
return [start, end]
},
},
]
const intervalOptions = [
{ label: '一分钟', value: '1m' },
{ label: '五分钟', value: '5m' },
{ label: '十分钟', value: '10m' },
{ label: '十五分钟', value: '15m' },
{ label: '一小时', value: '1h' },
{ label: '一天', value: '1d' },
{ label: '原始', value: 'NONE' },
]
const templateOptions = ref<
{
name: string
time: string[]
id: string
interval: string
column: { label: string; prop: string }[]
windBlowerList: string[]
}[]
>([])
const changeTemplate = () => {
const templateData = templateOptions.value.find((item) => item.id === searchData.template)
if (templateData) {
searchData.interval = templateData?.interval ?? searchData.interval
searchData.time = templateData?.time ?? searchData.time
tableColumn.value = templateData?.column ? [...oririnTableColumn, ...templateData.column] : tableColumn.value
// selectWindBlower.value = templateData?.windBlowerList ?? selectWindBlower.value
submitParams.windBlowerList = templateData?.windBlowerList ?? selectWindBlower.value
submitParams.column = templateData?.column ?? multipleSelection.value
}
}
const delTemplate = (id: string) => {
ElMessageBox.confirm('确定删除该模板吗?', '删除模板', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
delTemplateListReq({ id }).then((res) => {
if (res.code === 200) {
ElMessage.success('删除成功')
if (searchData.template === id) {
searchData.template = ''
}
getTemplateList()
}
})
})
}
const openMeasure = () => {
selectWindBlower.value = JSON.parse(JSON.stringify(submitParams.windBlowerList))
multipleSelection.value = JSON.parse(JSON.stringify(submitParams.column))
pointDialogTableData.value.forEach((item) => {
item.interpolation = false
item.average = false
item.max = false
item.min = false
})
multipleSelection.value.forEach((item) => {
const attrList = item.prop.split('--')
const type = attrList[1] as 'interpolation' | 'average' | 'max' | 'min'
const rowIndex = pointDialogTableData.value.findIndex((r) => r.attributeCode === attrList[0])!
pointDialogTableData.value[rowIndex][type] = true
})
pointDialogVisible.value = true
}
const searchLoading = ref(false)
const getData = () => {
searchLoading.value = true
getRealValueRange()
}
const getRealValueRange = () => {
const startTime = dayjs(searchData.time[0]).valueOf()
const endTime = dayjs(searchData.time[1]).valueOf()
const interval = searchData.interval
const interpolationAttr: string[] = []
const averageAttr: string[] = []
const maxAttr: string[] = []
const minAttr: string[] = []
const deviceNameData: any = {}
submitParams.windBlowerList.forEach((item: string) => {
deviceNameData[item] = windBlowerOptions.value.find((item1) => item1.value === item)?.label
})
for (let item of submitParams.column) {
const attributeCode = item.prop.split('--')
if (attributeCode[1] === 'interpolation') {
interpolationAttr.push(attributeCode[0])
}
if (attributeCode[1] === 'average') {
averageAttr.push(attributeCode[0])
}
if (attributeCode[1] === 'max') {
maxAttr.push(attributeCode[0])
}
if (attributeCode[1] === 'min') {
minAttr.push(attributeCode[0])
}
}
const reqList: any[] = [null, null, null, null]
if (interpolationAttr.length) {
const devices = submitParams.windBlowerList.map((item: string) => {
return {
deviceId: item,
attributes: interpolationAttr,
}
})
reqList[0] = getRealValueRangeReq({
devices,
interval,
startTime,
endTime,
})
}
if (averageAttr.length) {
const devices = submitParams.windBlowerList.map((item: string) => {
return {
deviceId: item,
attributes: averageAttr,
}
})
reqList[1] = windowReq({
devices,
interval,
startTime,
endTime,
calFunction: 'average',
})
}
if (maxAttr.length) {
const devices = submitParams.windBlowerList.map((item: string) => {
return {
deviceId: item,
attributes: maxAttr,
}
})
reqList[2] = windowReq({
devices,
interval,
startTime,
endTime,
calFunction: 'max',
})
}
if (minAttr.length) {
const devices = submitParams.windBlowerList.map((item: string) => {
return {
deviceId: item,
attributes: minAttr,
}
})
reqList[3] = windowReq({
devices,
interval,
startTime,
endTime,
calFunction: 'min',
})
}
const reqPromise = Promise.all(reqList)
reqPromise.then((res) => {
const [interpolationRes, averageRes, maxRes, minRes] = res
const tableDataList: any = []
if (interpolationRes && interpolationRes.code === 200) {
submitParams.windBlowerList.forEach((deviceId) => {
const device = interpolationRes.data[deviceId]
interpolationAttr.forEach((attr) => {
device[attr].times.forEach((t: number, index: number) => {
const attrNameKey = attr + '--interpolation'
tableDataList.push({
name: deviceNameData[deviceId],
time: dayjs(t).format('YYYY-MM-DD HH:mm:ss'),
[attrNameKey]: device[attr].values[index],
})
})
})
})
}
if (averageRes && averageRes.code === 200) {
submitParams.windBlowerList.forEach((deviceId) => {
const device = averageRes.data[deviceId]
averageAttr.forEach((attr) => {
device[attr].times.forEach((t: number, index: number) => {
const attrNameKey = attr + '--average'
const tableDataIndex = tableDataList.findIndex(
(data: any) => data.name == deviceNameData[deviceId] && data.time == dayjs(t).format('YYYY-MM-DD HH:mm:ss')
)
tableDataList[tableDataIndex][attrNameKey] = device[attr].values[index]
})
})
})
}
if (maxRes && maxRes.code === 200) {
submitParams.windBlowerList.forEach((deviceId) => {
const device = maxRes.data[deviceId]
maxAttr.forEach((attr) => {
device[attr].times.forEach((t: number, index: number) => {
const attrNameKey = attr + '--max'
const tableDataIndex = tableDataList.findIndex(
(data: any) => data.name == deviceNameData[deviceId] && data.time == dayjs(t).format('YYYY-MM-DD HH:mm:ss')
)
tableDataList[tableDataIndex][attrNameKey] = device[attr].values[index]
})
})
})
}
if (minRes && minRes.code === 200) {
submitParams.windBlowerList.forEach((deviceId) => {
const device = minRes.data[deviceId]
minAttr.forEach((attr) => {
device[attr].times.forEach((t: number, index: number) => {
const attrNameKey = attr + '--min'
const tableDataIndex = tableDataList.findIndex(
(data: any) => data.name == deviceNameData[deviceId] && data.time == dayjs(t).format('YYYY-MM-DD HH:mm:ss')
)
tableDataList[tableDataIndex][attrNameKey] = device[attr].values[index]
})
})
})
}
allTableData = tableDataList
pageSetting.total = tableDataList.length
pageSetting.current = 1
triggerTableRefresh.value = !triggerTableRefresh.value
searchLoading.value = false
})
}
const exportData = () => {}
const addTemplate = () => {
ElMessageBox.prompt('请输入模板名称', '添加模板', {
confirmButtonText: '确定',
cancelButtonText: '取消',
})
.then(({ value }) => {
const template = {
name: value,
time: searchData.time,
interval: searchData.interval,
column: submitParams.column,
windBlowerList: submitParams.windBlowerList,
}
addTemplateListReq({
category: '历史数据',
template: JSON.stringify(template),
})
.then((res) => {
ElMessage.success('添加成功')
getTemplateList()
})
.catch(() => {
ElMessage.error('添加失败')
})
})
.catch(() => {})
}
const searchData = reactive({
time: shortcuts[0].value(),
interval: '5m',
template: '',
})
const getTemplateList = () => {
getTemplateListReq({
category: '历史数据',
pageNum: 1,
pageSize: 100,
}).then((res) => {
if (res.code === 200) {
const templateData = res.data.rows.map((item) => {
const templateData = JSON.parse(item.template)
return {
id: item.id,
name: templateData.name,
time: templateData.time,
interval: templateData.interval,
column: templateData.column,
windBlowerList: templateData.windBlowerList,
}
})
templateOptions.value = templateData
}
})
}
getTemplateList()
const oririnTableColumn = [
{
label: '风机名称',
prop: 'name',
},
{
label: '时间',
prop: 'time',
},
]
const tableColumn = ref(oririnTableColumn)
let allTableData: any = []
const triggerTableRefresh = ref(false)
const tableData = computed(() => {
triggerTableRefresh.value
return allTableData.slice((pageSetting.current - 1) * pageSetting.pageSize, pageSetting.current * pageSetting.pageSize)
})
const pageSetting = reactive({
current: 1,
pageSize: 20,
total: 0,
pageSizes: [20, 50, 100],
})
const getcurrentPage = () => {}
const pointDialogVisible = ref(false)
const selectWindBlower = ref<string[]>([])
const windBlowerOptions = ref<{ label: string; value: string }[]>([])
const getAirBlowerList = () => {
return getAirBlowerListReq().then((res) => {
if (res.success) {
const data = res.data.map((item) => {
return {
label: item.name,
value: item.irn,
}
})
pointDialogSearchData.modelId = res.data?.[0].modelId ?? ''
windBlowerOptions.value = data
}
})
}
getAirBlowerList().then(() => {
getModelAttributeList()
})
const pointDialogSearchData = reactive<{
inputValue: string
type: 138 | 199
modelId: string
}>({
inputValue: '',
type: 138,
modelId: '',
})
const pointDialogSearch = () => {
getModelAttributeList()
}
const pointDialogRaidoChange = () => {
if (!pointDialogVisible.value) return
getModelAttributeList()
}
const pointDialogTableRef = ref<TableInstance>()
const pointDialogTableData = ref<selectData[]>([])
const selectRowList = ref<selectData[]>([])
const autoSelectRow = (scope: any, type: 'interpolation' | 'average' | 'max' | 'min') => {
const state = scope.row[type]
if (state) {
const exist = selectRowList.value.find((item) => item.id === scope.row.id)
if (!exist) {
selectRowList.value.push(scope.row)
} else {
exist[type] = state
}
getAddColumn()
} else {
const index = multipleSelection.value.findIndex((item) => {
const attrList = item.prop.split('--')
return attrList[0] === scope.row.attributeCode && attrList[1] === type
})
if (index > -1) {
multipleSelection.value.splice(index, 1)
}
if (!scope.row.interpolation && !scope.row.average && !scope.row.max && !scope.row.min) {
const index = selectRowList.value.findIndex((item) => item.id === scope.row.id)
if (index > -1) {
selectRowList.value.splice(index, 1)
}
}
}
}
const pointDialogPageSetting = reactive({
current: 1,
pageSize: 20,
total: 0,
pageSizes: [20, 50, 100],
})
const getModelAttributeList = () => {
const reqParams = {
iotModelId: pointDialogSearchData.modelId,
attributeName: pointDialogSearchData.inputValue,
attributeType: pointDialogSearchData.type,
pageNum: pointDialogPageSetting.current,
pageSize: pointDialogPageSetting.pageSize,
}
return getModelAttributeListReq(reqParams).then((res) => {
if (res.code == 200) {
const data = res.rows.map((item) => {
const compareData = {
interpolation: false,
average: false,
max: false,
min: false,
}
if (pointDialogVisible.value) {
const selectedInfo = selectRowList.value.find((select) => select.id == item.id)
if (selectedInfo) {
compareData.interpolation = selectedInfo.interpolation
compareData.average = selectedInfo.average
compareData.max = selectedInfo.max
compareData.min = selectedInfo.min
}
}
return {
id: item.id!,
attributeName: item.attributeName,
attributeCode: item.attributeCode,
...compareData,
}
})
pointDialogTableData.value = data
pointDialogPageSetting.total = res.total
}
})
}
const getcurrentPageForPointDialog = () => {
if (!pointDialogVisible.value) return
getModelAttributeList()
}
const getAddColumn = () => {
const dynamicColumn: { label: string; prop: string }[] = []
for (let item of selectRowList.value) {
if (item.interpolation) {
dynamicColumn.push({
label: item.attributeName,
prop: item.attributeCode + '--interpolation',
})
}
if (item.average) {
dynamicColumn.push({
label: item.attributeName + '-平均值',
prop: item.attributeCode + '--average',
})
}
if (item.max) {
dynamicColumn.push({
label: item.attributeName + '-最大值',
prop: item.attributeCode + '--max',
})
}
if (item.min) {
dynamicColumn.push({
label: item.attributeName + '-最小值',
prop: item.attributeCode + '--min',
})
}
}
multipleSelection.value = dynamicColumn
}
const submitParams: {
column: { label: string; prop: string }[]
windBlowerList: string[]
} = {
column: [],
windBlowerList: [],
}
const multipleSelection = ref<{ label: string; prop: string }[]>([])
const moveUp = (index: number) => {
const temp = multipleSelection.value[index]
multipleSelection.value[index] = multipleSelection.value[index - 1]
multipleSelection.value[index - 1] = temp
}
const moveDown = (index: number) => {
const temp = multipleSelection.value[index]
multipleSelection.value[index] = multipleSelection.value[index + 1]
multipleSelection.value[index + 1] = temp
}
const moveRemove = (index: number, item: { label: string; prop: string }) => {
multipleSelection.value.splice(index, 1)
const realProp = item.prop.split('--')
const type = realProp[1] as 'interpolation' | 'average' | 'max' | 'min'
const selectRowIndex = selectRowList.value.findIndex((row) => row.attributeCode === realProp[0])!
selectRowList.value[selectRowIndex][type] = false
if (
!selectRowList.value[selectRowIndex].interpolation &&
!selectRowList.value[selectRowIndex].average &&
!selectRowList.value[selectRowIndex].max &&
!selectRowList.value[selectRowIndex].min
) {
selectRowList.value.splice(selectRowIndex, 1)
}
const rowIndex = pointDialogTableData.value.findIndex((row) => row.attributeCode === realProp[0])!
if (rowIndex > -1) {
pointDialogTableData.value[rowIndex][type] = false
}
}
const clearmultipleSelection = () => {
multipleSelection.value = []
pointDialogTableRef.value?.clearSelection()
selectRowList.value.forEach((item) => {
const row = pointDialogTableData.value.find((row) => row.id === item.id)
if (row) {
row.interpolation = false
row.average = false
row.max = false
row.min = false
}
})
selectRowList.value = []
}
const submitPointDialog = () => {
if (!selectWindBlower.value.length) {
ElMessage.error('请选择风机')
return
}
if (!selectRowList.value.length) {
ElMessage.error('请选择测点')
return
}
submitParams.windBlowerList = JSON.parse(JSON.stringify(selectWindBlower.value))
submitParams.column = JSON.parse(JSON.stringify(multipleSelection.value))
tableColumn.value = [...oririnTableColumn, ...submitParams.column]
pointDialogVisible.value = false
}
const exportExcel = () => {
const title = tableColumn.value.map((item: any) => item.label).join('\t,') + '\n'
const titleKeyArr = tableColumn.value.map((item: any) => item.prop)
let str = ''
allTableData.forEach((item: any) => {
titleKeyArr.forEach((prop: any) => {
const val = typeof item[prop] === 'string' ? item[prop] : item[prop] ? String(item[prop]) : ''
str += val + '\t' + ','
})
str += '\n'
})
str = title + str
let uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(str)
let link = document.createElement('a')
link.href = uri
link.download = '历史数据' + searchData.time[0] + '-' + searchData.time[1] + '.csv'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
</script>
<style scoped lang="scss">
.historyData {
width: 100%;
height: 100%;
.container {
width: 100%;
height: 100%;
.header {
height: 60px;
display: flex;
align-items: center;
.timePart {
display: flex;
justify-content: space-between;
width: 450px;
height: 100%;
display: flex;
align-items: center;
.label {
margin: 0 10px;
}
.timeSelect {
width: 400px;
}
}
.intervalPart {
display: flex;
align-items: center;
width: 250px;
height: 100%;
.label {
margin: 0 10px;
}
.el-select {
width: 200px;
}
:deep(.el-select__wrapper) {
width: 200px;
height: 40px;
}
}
.templatePart {
display: flex;
align-items: center;
width: 250px;
height: 100%;
.label {
margin: 0 10px;
}
.el-select {
width: 200px;
height: 40px;
}
:deep(.el-select__wrapper) {
width: 200px;
height: 40px;
}
.templateOption {
display: flex;
align-items: center;
justify-content: space-between;
}
}
.pointSelect {
margin: 0 10px;
width: 100px;
height: 40px;
}
.opeareBtn {
margin-left: auto;
display: flex;
align-items: center;
width: 350px;
height: 100%;
.el-button {
margin: 0 10px;
width: 100px;
height: 40px;
}
}
}
.main {
height: calc(100% - 100px);
}
.footer {
display: flex;
justify-content: right;
align-items: center;
height: 40px;
}
}
.pointDialogRow {
width: 100%;
.pointDialogCol {
width: 100%;
height: 600px;
.pointDialogColTitle {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
width: 100%;
height: 40px;
background-color: #f7f9fc;
border-radius: 6px 6px 0 0;
border: 1px solid #e4e7ed;
border-bottom: none;
.title {
margin: 0 10px;
}
.pointDialogColTitleInput {
.el-input {
width: 200px;
}
.el-button {
margin-left: 10px;
}
}
.pointDialogColTitleRightPart {
margin-left: auto;
width: 170px;
}
}
.pointDialogColContent {
width: 100%;
height: 560px;
padding: 0 10px;
border: 1px solid #e4e7ed;
border-top: none;
border-radius: 0 0 6px 6px;
.windBlowerCheckbox {
margin: 0;
width: 100%;
}
.pointTable {
width: 100%;
height: 520px;
}
.footer {
display: flex;
justify-content: right;
height: 40px;
}
}
.pointDialogSelectedList {
width: 100%;
height: 560px;
border: 1px solid #e4e7ed;
border-top: none;
border-radius: 0 0 6px 6px;
.selectItem {
margin: 5px;
padding-left: 10px;
display: flex;
justify-content: space-between;
align-items: center;
min-height: 40px;
border-radius: 4px;
background-color: #eff0f1;
.moveIcon {
display: flex;
justify-content: right;
align-items: center;
width: 60px;
.el-icon {
cursor: pointer;
}
}
}
}
}
}
}
</style>

View File

@ -0,0 +1,10 @@
export type selectData =
{
id: string
attributeName: string
attributeCode: string
interpolation: boolean
average: boolean
max: boolean
min: boolean
}