# Conflicts:
#	pnpm-lock.yaml
This commit is contained in:
sjl
2025-10-21 16:30:45 +08:00
112 changed files with 18142 additions and 5568 deletions

View File

@@ -1,129 +1,129 @@
<template>
<!-- 异常事件 -->
<TableHeader datePicker ref="refheader" showExport>
<!-- <template v-slot:select>
<el-form-item label="数据来源">
<el-cascader
placeholder="请选择数据来源"
@change="sourceChange"
:options="props.deviceTree"
:show-all-levels="false"
:props="{ checkStrictly: true }"
clearable
></el-cascader>
</el-form-item>
<el-form-item label="级别">
<el-select v-model.trim="tableStore.table.params.level" placeholder="请选择级别" clearable>
<el-option
v-for="item in rankOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
</template> -->
<template #select>
<el-form-item label="设备名称">
<el-input
maxlength="32"
clearable
show-word-limit
v-model.trim="tableStore.table.params.searchValue"
placeholder="请输入设备名称"
/>
</el-form-item>
</template>
</TableHeader>
<!-- <div style="height: 300px;"> -->
<Table ref="tableRef" :isGroup="true" />
<!-- </div> -->
</template>
<script setup lang="ts">
import { ref, onMounted, provide } from 'vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import { mainHeight } from '@/utils/layout'
const props = defineProps(['deviceTree'])
const refheader = ref()
const deviceTree = ref([])
const tabsList = ref([
{
label: '设备告警',
name: 3
},
{
label: '稳态越限告警',
name: 1
},
{
label: '暂态事件',
name: 0
}
])
const rankOptions = ref([
{
value: '1',
label: '1级'
},
{
value: '2',
label: '2级'
},
{
value: '3',
label: '3级'
}
])
const tableStore = new TableStore({
url: '/zl-event-boot/csDevErrEvt/list',
method: 'POST',
exportName: '异常事件',
publicHeight: 65,
column: [
{
title: '序号',
width: 80,
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ title: '设备名称', field: 'ndid', align: 'center' },
{ title: '异常时间', field: 'evtTime', align: 'center', sortable: true },
{ title: '告警代码', field: 'code', align: 'center', sortable: true }
]
})
provide('tableStore', tableStore)
// "target": [],
// "type": "",
// "userId": ""
tableStore.table.params.engineeringid = ''
tableStore.table.params.projectId = ''
tableStore.table.params.deviceId = ''
tableStore.table.params.type = 3
tableStore.table.params.eventIds = []
tableStore.table.params.status = ''
tableStore.table.params.target = []
tableStore.table.params.userId = ''
tableStore.table.params.searchValue = ''
const sourceChange = (e: any) => {
tableStore.table.params.engineeringid = e[0] || ''
tableStore.table.params.projectId = e[1] || ''
tableStore.table.params.deviceId = e[2] || ''
}
onMounted(() => {
tableStore.index()
})
setTimeout(() => {
tableStore.table.height = mainHeight(200).height as any
}, 0)
const addMenu = () => {}
</script>
<style></style>
<template>
<!-- 异常事件 -->
<TableHeader datePicker ref="refheader" showExport>
<!-- <template v-slot:select>
<el-form-item label="数据来源">
<el-cascader
placeholder="请选择数据来源"
@change="sourceChange"
:options="props.deviceTree"
:show-all-levels="false"
:props="{ checkStrictly: true }"
clearable
></el-cascader>
</el-form-item>
<el-form-item label="级别">
<el-select v-model.trim="tableStore.table.params.level" placeholder="请选择级别" clearable>
<el-option
v-for="item in rankOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
</template> -->
<template #select>
<el-form-item label="设备名称">
<el-input
maxlength="32"
clearable
show-word-limit
v-model.trim="tableStore.table.params.searchValue"
placeholder="请输入设备名称"
/>
</el-form-item>
</template>
</TableHeader>
<!-- <div style="height: 300px;"> -->
<Table ref="tableRef" :isGroup="true" />
<!-- </div> -->
</template>
<script setup lang="ts">
import { ref, onMounted, provide } from 'vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import { mainHeight } from '@/utils/layout'
const props = defineProps(['deviceTree'])
const refheader = ref()
const deviceTree = ref([])
const tabsList = ref([
{
label: '设备告警',
name: 3
},
{
label: '稳态越限告警',
name: 1
},
{
label: '暂态事件',
name: 0
}
])
const rankOptions = ref([
{
value: '1',
label: '1级'
},
{
value: '2',
label: '2级'
},
{
value: '3',
label: '3级'
}
])
const tableStore = new TableStore({
url: '/zl-event-boot/csDevErrEvt/list',
method: 'POST',
exportName: '异常事件',
publicHeight: 65,
column: [
{
title: '序号',
width: 80,
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ title: '设备名称', field: 'ndid', align: 'center' },
{ title: '异常时间', field: 'evtTime', align: 'center', sortable: true },
{ title: '告警代码', field: 'code', align: 'center', sortable: true }
]
})
provide('tableStore', tableStore)
// "target": [],
// "type": "",
// "userId": ""
tableStore.table.params.engineeringid = ''
tableStore.table.params.projectId = ''
tableStore.table.params.deviceId = ''
tableStore.table.params.type = 3
tableStore.table.params.eventIds = []
tableStore.table.params.status = ''
tableStore.table.params.target = []
tableStore.table.params.userId = ''
tableStore.table.params.searchValue = ''
const sourceChange = (e: any) => {
tableStore.table.params.engineeringid = e[0] || ''
tableStore.table.params.projectId = e[1] || ''
tableStore.table.params.deviceId = e[2] || ''
}
onMounted(() => {
tableStore.index()
})
setTimeout(() => {
tableStore.table.height = mainHeight(200).height as any
}, 0)
const addMenu = () => {}
</script>
<style></style>

View File

@@ -1,190 +1,190 @@
<template>
<TableHeader datePicker ref="refheader" showExport>
<template v-slot:select>
<el-form-item label="数据来源">
<el-cascader
v-model.trim="tableStore.table.params.cascader"
filterable
placeholder="请选择数据来源"
@change="sourceChange"
:options="deviceTreeOptions"
:show-all-levels="false"
:props="{ checkStrictly: true }"
clearable
></el-cascader>
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备名称" /> -->
</el-form-item>
<el-form-item label="级别">
<el-select v-model.trim="tableStore.table.params.level" placeholder="请选择级别" clearable>
<el-option
v-for="item in rankOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
</template>
</TableHeader>
<!-- <div style="height: 300px;"> -->
<Table ref="tableRef" :isGroup="true" />
<!-- </div> -->
</template>
<script setup lang="ts">
import { ref, onMounted, provide } from 'vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import { mainHeight } from '@/utils/layout'
const props = defineProps(['deviceTree'])
const refheader = ref()
const deviceTree = ref([])
const tabsList = ref([
{
label: '设备告警',
name: 3
},
{
label: '稳态越限告警',
name: 1
},
{
label: '暂态事件',
name: 0
}
])
const rankOptions = ref([
{
value: '1',
label: '1级'
},
{
value: '2',
label: '2级'
},
{
value: '3',
label: '3级'
}
])
const tableStore = new TableStore({
url: '/cs-harmonic-boot/eventUser/queryEventpageWeb',
method: 'POST',
exportName: '设备告警',
publicHeight: 65,
column: [
{
title: '序号',
width: 80,
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ title: '设备名称', field: 'equipmentName', align: 'center' },
{ title: '工程名称', field: 'engineeringName', align: 'center' },
{ title: '项目名称', field: 'projectName', align: 'center' },
{ title: '发生时刻', field: 'startTime', align: 'center', minWidth: 110, sortable: true },
{
title: '模块信息',
field: 'moduleNo',
align: 'center',
formatter: (row: any) => {
return row.cellValue ? row.cellValue : '/'
}
},
{
title: '告警代码',
field: 'code',
align: 'center',
formatter: (row: any) => {
return row.cellValue ? row.cellValue : '/'
},
sortable: true
},
{
title: '事件描述',
field: 'showName'
},
{
title: '级别',
field: 'level',
render: 'tag',
custom: {
1: 'danger',
2: 'warning',
3: 'success'
},
replaceValue: {
1: '1级',
2: '2级',
3: '3级'
}
}
// {
// title: '级别',
// field: 'level',
// formatter: (row: any) => {
// return row.cellValue == 1 ? '1级' : row.cellValue == 2 ? '2级' : row.cellValue == 3 ? '3级' : '/'
// }
// }
],
beforeSearchFun: () => {}
})
provide('tableStore', tableStore)
// "target": [],
// "type": "",
// "userId": ""
tableStore.table.params.cascader = ''
tableStore.table.params.level = ''
tableStore.table.params.engineeringid = ''
tableStore.table.params.projectId = ''
tableStore.table.params.deviceId = ''
tableStore.table.params.type = 3
tableStore.table.params.eventIds = []
tableStore.table.params.status = ''
tableStore.table.params.target = []
tableStore.table.params.userId = ''
tableStore.table.params.deviceTypeId = ''
tableStore.table.params.deviceTypeName = ''
const deviceTreeOptions = ref<any>(props.deviceTree)
deviceTreeOptions.value.map((item: any, index: any) => {
if (item.children.length == 0) {
deviceTreeOptions.value.splice(index, 1)
}
})
const sourceChange = (e: any) => {
tableStore.table.params.deviceTypeId = ''
tableStore.table.params.engineeringid = ''
tableStore.table.params.projectId = ''
tableStore.table.params.deviceId = ''
if (e) {
let name = deviceTreeOptions.value.filter((item: any) => {
return item.id == e[0]
})[0].name
tableStore.table.params.deviceTypeName = name
if (name == '便携式设备') {
tableStore.table.params.deviceTypeId = e[0] || ''
tableStore.table.params.deviceId = e[1] || ''
} else {
tableStore.table.params.deviceTypeId = e[0] || ''
tableStore.table.params.engineeringid = e[1] || ''
tableStore.table.params.projectId = e[2] || ''
}
}
}
onMounted(() => {
tableStore.index()
})
setTimeout(() => {
// tableStore.table.height = mainHeight(200).height as any
}, 0)
const addMenu = () => {}
</script>
<style></style>
<template>
<TableHeader datePicker ref="refheader" showExport>
<template v-slot:select>
<el-form-item label="数据来源">
<el-cascader
v-model.trim="tableStore.table.params.cascader"
filterable
placeholder="请选择数据来源"
@change="sourceChange"
:options="deviceTreeOptions"
:show-all-levels="false"
:props="{ checkStrictly: true }"
clearable
></el-cascader>
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备名称" /> -->
</el-form-item>
<el-form-item label="级别">
<el-select v-model.trim="tableStore.table.params.level" placeholder="请选择级别" clearable>
<el-option
v-for="item in rankOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
</template>
</TableHeader>
<!-- <div style="height: 300px;"> -->
<Table ref="tableRef" :isGroup="true" />
<!-- </div> -->
</template>
<script setup lang="ts">
import { ref, onMounted, provide } from 'vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import { mainHeight } from '@/utils/layout'
const props = defineProps(['deviceTree'])
const refheader = ref()
const deviceTree = ref([])
const tabsList = ref([
{
label: '设备告警',
name: 3
},
{
label: '稳态越限告警',
name: 1
},
{
label: '暂态事件',
name: 0
}
])
const rankOptions = ref([
{
value: '1',
label: '1级'
},
{
value: '2',
label: '2级'
},
{
value: '3',
label: '3级'
}
])
const tableStore = new TableStore({
url: '/cs-harmonic-boot/eventUser/queryEventpageWeb',
method: 'POST',
exportName: '设备告警',
publicHeight: 65,
column: [
{
title: '序号',
width: 80,
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ title: '设备名称', field: 'equipmentName', align: 'center' },
{ title: '工程名称', field: 'engineeringName', align: 'center' },
{ title: '项目名称', field: 'projectName', align: 'center' },
{ title: '发生时刻', field: 'startTime', align: 'center', minWidth: 110, sortable: true },
{
title: '模块信息',
field: 'moduleNo',
align: 'center',
formatter: (row: any) => {
return row.cellValue ? row.cellValue : '/'
}
},
{
title: '告警代码',
field: 'code',
align: 'center',
formatter: (row: any) => {
return row.cellValue ? row.cellValue : '/'
},
sortable: true
},
{
title: '事件描述',
field: 'showName'
},
{
title: '级别',
field: 'level',
render: 'tag',
custom: {
1: 'danger',
2: 'warning',
3: 'success'
},
replaceValue: {
1: '1级',
2: '2级',
3: '3级'
}
}
// {
// title: '级别',
// field: 'level',
// formatter: (row: any) => {
// return row.cellValue == 1 ? '1级' : row.cellValue == 2 ? '2级' : row.cellValue == 3 ? '3级' : '/'
// }
// }
],
beforeSearchFun: () => {}
})
provide('tableStore', tableStore)
// "target": [],
// "type": "",
// "userId": ""
tableStore.table.params.cascader = ''
tableStore.table.params.level = ''
tableStore.table.params.engineeringid = ''
tableStore.table.params.projectId = ''
tableStore.table.params.deviceId = ''
tableStore.table.params.type = 3
tableStore.table.params.eventIds = []
tableStore.table.params.status = ''
tableStore.table.params.target = []
tableStore.table.params.userId = ''
tableStore.table.params.deviceTypeId = ''
tableStore.table.params.deviceTypeName = ''
const deviceTreeOptions = ref<any>(props.deviceTree)
deviceTreeOptions.value.map((item: any, index: any) => {
if (item.children.length == 0) {
deviceTreeOptions.value.splice(index, 1)
}
})
const sourceChange = (e: any) => {
tableStore.table.params.deviceTypeId = ''
tableStore.table.params.engineeringid = ''
tableStore.table.params.projectId = ''
tableStore.table.params.deviceId = ''
if (e) {
let name = deviceTreeOptions.value.filter((item: any) => {
return item.id == e[0]
})[0].name
tableStore.table.params.deviceTypeName = name
if (name == '便携式设备') {
tableStore.table.params.deviceTypeId = e[0] || ''
tableStore.table.params.deviceId = e[1] || ''
} else {
tableStore.table.params.deviceTypeId = e[0] || ''
tableStore.table.params.engineeringid = e[1] || ''
tableStore.table.params.projectId = e[2] || ''
}
}
}
onMounted(() => {
tableStore.index()
})
setTimeout(() => {
// tableStore.table.height = mainHeight(200).height as any
}, 0)
const addMenu = () => {}
</script>
<style></style>

View File

@@ -1,147 +1,147 @@
<template>
<TableHeader datePicker ref="refheader" showExport>
<template v-slot:select>
<el-form-item label="数据来源">
<el-cascader
v-model.trim="tableStore.table.params.cascader"
filterable
placeholder="请选择数据来源"
@change="sourceChange"
:options="deviceTreeOptions"
:show-all-levels="false"
:props="{ checkStrictly: true }"
clearable
></el-cascader>
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备名称" /> -->
</el-form-item>
<!-- <el-form-item label="级别">
<el-select v-model.trim="tableStore.table.params.level" placeholder="请选择级别" clearable>
<el-option
v-for="item in rankOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item> -->
</template>
</TableHeader>
<!-- <div style="height: 300px;"> -->
<Table ref="tableRef" :isGroup="true" />
<!-- </div> -->
</template>
<script setup lang="ts">
import { ref, onMounted, provide } from 'vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import { mainHeight } from '@/utils/layout'
const props = defineProps(['deviceTree'])
const refheader = ref()
const deviceTree = ref([])
const tabsList = ref([
{
label: '设备告警',
name: 3
},
{
label: '稳态越限告警',
name: 1
},
{
label: '暂态事件',
name: 0
}
])
const rankOptions = ref([
{
value: '1',
label: '1级'
},
{
value: '2',
label: '2级'
},
{
value: '3',
label: '3级'
}
])
const tableStore = new TableStore({
url: '/cs-harmonic-boot/eventUser/queryEventpageWeb',
method: 'POST',
exportName: '稳态越限告警',
publicHeight: 65,
column: [
{
title: '序号',
width: 80,
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ title: '设备名称', field: 'equipmentName', align: 'center' },
{ title: '工程名称', field: 'engineeringName', align: 'center' },
{ title: '项目名称', field: 'projectName', align: 'center' },
{ title: '发生时刻', field: 'startTime', align: 'center', sortable: true },
{ title: '事件描述', field: 'showName', align: 'center' }
],
beforeSearchFun: () => {}
})
provide('tableStore', tableStore)
// "target": [],
// "type": "",
// "userId": ""
tableStore.table.params.engineeringid = ''
tableStore.table.params.deviceTypeId = ''
tableStore.table.params.projectId = ''
tableStore.table.params.deviceId = ''
tableStore.table.params.type = 1
tableStore.table.params.eventIds = []
tableStore.table.params.status = ''
tableStore.table.params.target = []
tableStore.table.params.userId = ''
tableStore.table.params.cascader = ''
tableStore.table.params.deviceTypeName = ''
// tableStore.table.params.level=''
const deviceTreeOptions = ref<any>(props.deviceTree)
deviceTreeOptions.value.map((item: any, index: any) => {
if (item.children.length == 0) {
deviceTreeOptions.value.splice(index, 1)
}
})
const sourceChange = (e: any) => {
tableStore.table.params.deviceTypeId = ''
tableStore.table.params.engineeringid = ''
tableStore.table.params.projectId = ''
tableStore.table.params.deviceId = ''
if (e) {
let name = deviceTreeOptions.value.filter((item: any) => {
return item.id == e[0]
})[0].name
tableStore.table.params.deviceTypeName = name
if (name == '便携式设备') {
tableStore.table.params.deviceTypeId = e[0] || ''
tableStore.table.params.deviceId = e[1] || ''
} else {
tableStore.table.params.deviceTypeId = e[0] || ''
tableStore.table.params.engineeringid = e[1] || ''
tableStore.table.params.projectId = e[2] || ''
}
}
}
onMounted(() => {
tableStore.index()
})
setTimeout(() => {
tableStore.table.height = mainHeight(200).height as any
}, 0)
const addMenu = () => {}
</script>
<style></style>
<template>
<TableHeader datePicker ref="refheader" showExport>
<template v-slot:select>
<el-form-item label="数据来源">
<el-cascader
v-model.trim="tableStore.table.params.cascader"
filterable
placeholder="请选择数据来源"
@change="sourceChange"
:options="deviceTreeOptions"
:show-all-levels="false"
:props="{ checkStrictly: true }"
clearable
></el-cascader>
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备名称" /> -->
</el-form-item>
<!-- <el-form-item label="级别">
<el-select v-model.trim="tableStore.table.params.level" placeholder="请选择级别" clearable>
<el-option
v-for="item in rankOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item> -->
</template>
</TableHeader>
<!-- <div style="height: 300px;"> -->
<Table ref="tableRef" :isGroup="true" />
<!-- </div> -->
</template>
<script setup lang="ts">
import { ref, onMounted, provide } from 'vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import { mainHeight } from '@/utils/layout'
const props = defineProps(['deviceTree'])
const refheader = ref()
const deviceTree = ref([])
const tabsList = ref([
{
label: '设备告警',
name: 3
},
{
label: '稳态越限告警',
name: 1
},
{
label: '暂态事件',
name: 0
}
])
const rankOptions = ref([
{
value: '1',
label: '1级'
},
{
value: '2',
label: '2级'
},
{
value: '3',
label: '3级'
}
])
const tableStore = new TableStore({
url: '/cs-harmonic-boot/eventUser/queryEventpageWeb',
method: 'POST',
exportName: '稳态越限告警',
publicHeight: 65,
column: [
{
title: '序号',
width: 80,
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ title: '设备名称', field: 'equipmentName', align: 'center' },
{ title: '工程名称', field: 'engineeringName', align: 'center' },
{ title: '项目名称', field: 'projectName', align: 'center' },
{ title: '发生时刻', field: 'startTime', align: 'center', sortable: true },
{ title: '事件描述', field: 'showName', align: 'center' }
],
beforeSearchFun: () => {}
})
provide('tableStore', tableStore)
// "target": [],
// "type": "",
// "userId": ""
tableStore.table.params.engineeringid = ''
tableStore.table.params.deviceTypeId = ''
tableStore.table.params.projectId = ''
tableStore.table.params.deviceId = ''
tableStore.table.params.type = 1
tableStore.table.params.eventIds = []
tableStore.table.params.status = ''
tableStore.table.params.target = []
tableStore.table.params.userId = ''
tableStore.table.params.cascader = ''
tableStore.table.params.deviceTypeName = ''
// tableStore.table.params.level=''
const deviceTreeOptions = ref<any>(props.deviceTree)
deviceTreeOptions.value.map((item: any, index: any) => {
if (item.children.length == 0) {
deviceTreeOptions.value.splice(index, 1)
}
})
const sourceChange = (e: any) => {
tableStore.table.params.deviceTypeId = ''
tableStore.table.params.engineeringid = ''
tableStore.table.params.projectId = ''
tableStore.table.params.deviceId = ''
if (e) {
let name = deviceTreeOptions.value.filter((item: any) => {
return item.id == e[0]
})[0].name
tableStore.table.params.deviceTypeName = name
if (name == '便携式设备') {
tableStore.table.params.deviceTypeId = e[0] || ''
tableStore.table.params.deviceId = e[1] || ''
} else {
tableStore.table.params.deviceTypeId = e[0] || ''
tableStore.table.params.engineeringid = e[1] || ''
tableStore.table.params.projectId = e[2] || ''
}
}
}
onMounted(() => {
tableStore.index()
})
setTimeout(() => {
tableStore.table.height = mainHeight(200).height as any
}, 0)
const addMenu = () => {}
</script>
<style></style>

View File

@@ -1,365 +1,365 @@
<template>
<div ref="refheader" v-if="!isWaveCharts">
<TableHeader datePicker showExport>
<template v-slot:select>
<el-form-item label="数据来源">
<el-cascader
placeholder="请选择数据来源"
@change="sourceChange"
filterable
v-model.trim="tableStore.table.params.cascader"
:options="deviceTreeOptions"
:show-all-levels="false"
:props="{ checkStrictly: true }"
clearable
></el-cascader>
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备名称" /> -->
</el-form-item>
<!-- <el-form-item label="级别">
<el-select v-model.trim="tableStore.table.params.level" placeholder="请选择级别" clearable>
<el-option v-for="item in rankOptions" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item> -->
</template>
</TableHeader>
<Table></Table>
</div>
<waveFormAnalysis
v-loading="loading"
v-if="isWaveCharts"
ref="waveFormAnalysisRef"
@handleHideCharts="isWaveCharts = false"
:wp="wp"
/>
<!-- <div style="height: 300px;"> -->
<!-- <div style="padding: 10px" v-if="!view" v-loading="loading">
<el-row>
<el-col :span="12">
<div v-if="view2" style="display: flex">
<el-radio-group v-model.trim="value" @change="changeView">
<el-radio-button label="一次值" :value="1" />
<el-radio-button label="二次值" :value="2" />
</el-radio-group>
</div>
</el-col>
<el-col :span="12">
<el-button v-if="view2" @click="backbxlb" class="el-icon-refresh-right" icon="el-icon-Back"
style="float: right">
返回
</el-button>
</el-col>
</el-row>
<el-tabs v-if="view2" v-model.trim="bxactiveName" @tab-click="bxhandleClick">
<el-tab-pane label="瞬时波形" name="ssbx" class="boxbx pt10 pb10"
:style="'height:' + bxecharts + ';overflow-y: scroll;'">
<shushiboxi v-if="bxactiveName == 'ssbx' && showBoxi" :value="value" :boxoList="boxoList" :wp="wp">
</shushiboxi>
</el-tab-pane>
<el-tab-pane label="RMS波形" class="boxbx pt10 pb10" name="rmsbx"
:style="'height:' + bxecharts + ';overflow-y: scroll;'">
<rmsboxi v-if="bxactiveName == 'rmsbx' && showBoxi" :value="value" :boxoList="boxoList" :wp="wp">
</rmsboxi>
</el-tab-pane>
</el-tabs>
</div> -->
</template>
<script setup lang="ts">
import { ref, onMounted, provide, nextTick } from 'vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import shushiboxi from '@/components/echarts/shushiboxi.vue'
import waveFormAnalysis from '@/views/govern/device/control/tabs/components/waveFormAnalysis.vue'
import rmsboxi from '@/components/echarts/rmsboxi.vue'
import { analyseWave } from '@/api/common'
import { mainHeight } from '@/utils/layout'
import { ElMessage } from 'element-plus'
import { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
const props = defineProps(['deviceTree'])
const refheader = ref()
const waveFormAnalysisRef = ref()
const view = ref(true)
const isWaveCharts = ref(false)
const view2 = ref(false)
const showBoxi = ref(true)
const loading = ref(false)
const bxactiveName = ref('ssbx')
const boxoList: any = ref({})
const wp = ref({})
const value = ref(1)
const options = ref([
{
value: 1,
label: '一次值'
},
{
value: 2,
label: '二次值'
}
])
const rankOptions = ref([
{
value: '1',
label: '1级'
},
{
value: '2',
label: '2级'
},
{
value: '3',
label: '3级'
}
])
const tableStore = new TableStore({
url: '/cs-harmonic-boot/eventUser/queryEventpageWeb',
method: 'POST',
publicHeight: 65,
exportName: '暂态事件',
column: [ {
title: '序号',
width: 80,
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ title: '设备名称', field: 'equipmentName', align: 'center' },
{ title: '工程名称', field: 'engineeringName', align: 'center' },
{ title: '项目名称', field: 'projectName', align: 'center' },
{ title: '发生时刻', field: 'startTime', align: 'center', width: '240',sortable: true },
{ title: '监测点名称', field: 'lineName', align: 'center' },
{ title: '事件描述', field: 'showName', align: 'center' },
{ title: '事件发生位置', field: 'evtParamPosition', align: 'center' },
{ title: '相别', field: 'evtParamPhase', align: 'center' },
{ title: '持续时间(s)', field: 'evtParamTm', align: 'center',sortable: true },
{ title: '暂降(聚升)幅值(%)', minWidth: 100, field: 'evtParamVVaDepth', align: 'center',sortable: true },
{
title: '操作',
align: 'center',
width: '180',
render: 'buttons',
buttons: [
{
name: 'edit',
title: '波形分析',
type: 'primary',
icon: 'el-icon-DataLine',
render: 'basicButton',
loading: 'loading1',
disabled: row => {
return !row.wavePath && row.evtParamTm < 20
},
click: async row => {
row.loading1 = true
loading.value = true
isWaveCharts.value = true
await analyseWave(row.id)
.then(res => {
row.loading1 = false
if (res != undefined) {
boxoList.value = row
boxoList.value.featureAmplitude =
row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth - 0 : null
boxoList.value.systemType = 'WX'
wp.value = res.data
}
loading.value = false
})
.catch(() => {
row.loading1 = false
loading.value = false
})
nextTick(() => {
waveFormAnalysisRef.value &&
waveFormAnalysisRef.value.getWpData(wp.value, boxoList.value, true)
// waveFormAnalysisRef.value && waveFormAnalysisRef.value.setHeight(200, 190)
})
// row.loading1 = true
// view.value = false
// view2.value = true
// loading.value = true
// boxoList.value = row
// boxoList.value.systemType = 'WX'
// boxoList.value.persistTime = row.evtParamTm != '-' ? row.evtParamTm - 0 : null
// await analyseWave(row.id)
// .then(res => {
// row.loading1 = false
// if (res != undefined) {
// wp.value = res.data
// }
// loading.value = false
// })
// .catch(() => {
// row.loading1 = false
// loading.value = false
// })
}
},
{
name: 'edit',
title: '波形下载',
type: 'primary',
icon: 'el-icon-Check',
loading: 'loading2',
render: 'basicButton',
disabled: row => {
// && row.evtParamTm < 20
return !row.wavePath
},
click: row => {
getFileZip({ eventId: row.id }).then(res => {
let blob = new Blob([res], { type: 'application/zip' }) // console.log(blob) // var href = window.URL.createObjectURL(blob); //创建下载的链接
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a') // 创建a标签
link.href = url
link.download = row.wavePath.split('/')[2] || '波形文件' // 设置下载的文件名
document.body.appendChild(link)
link.click() //执行下载
document.body.removeChild(link) //释放标签
})
}
},
{
name: 'edit',
text: '暂无波形',
type: 'info',
icon: 'el-icon-DataLine',
render: 'basicButton',
disabled: row => {
return !(!row.wavePath && row.evtParamTm < 20)
}
}
]
}
],
beforeSearchFun: () => {
// if (!tableStore.table.params.deviceId) {
// delete tableStore.table.params.deviceId
// }
},
loadCallback: () => {
tableStore.table.data.forEach((item: any) => {
item.loading = false
item.evtParamTm =
item.evtParamTm.split('s')[0] != '-' ? (item.evtParamTm.split('s')[0] - 0).toFixed(2) : '-'
item.evtParamVVaDepth =
item.evtParamVVaDepth.split('%')[0] != '-' ? (item.evtParamVVaDepth.split('%')[0] - 0).toFixed(2) : '-'
})
}
})
provide('tableStore', tableStore)
// "target": [],
// "type": "",
// "userId": ""
tableStore.table.params.engineeringid = ''
tableStore.table.params.projectId = ''
tableStore.table.params.deviceTypeId = ''
tableStore.table.params.deviceId = ''
tableStore.table.params.type = 0
tableStore.table.params.eventIds = []
tableStore.table.params.status = ''
tableStore.table.params.target = []
tableStore.table.params.userId = ''
tableStore.table.params.cascader = ''
tableStore.table.params.deviceTypeName = ''
// tableStore.table.params.level=''
const deviceTreeOptions: any = ref<any>(props.deviceTree)
deviceTreeOptions.value.map((item: any, index: any) => {
if (item.children.length == 0) {
deviceTreeOptions.value.splice(index, 1)
}
})
const sourceChange = (e: any) => {
tableStore.table.params.deviceTypeId = ''
tableStore.table.params.engineeringid = ''
tableStore.table.params.projectId = ''
tableStore.table.params.deviceId = ''
if (e) {
let name = deviceTreeOptions.value.filter((item: any) => {
return item.id == e[0]
})[0].name
tableStore.table.params.deviceTypeName = name
if (name == '便携式设备') {
tableStore.table.params.deviceTypeId = e[0] || ''
tableStore.table.params.deviceId = e[1] || ''
} else {
tableStore.table.params.deviceTypeId = e[0] || ''
tableStore.table.params.engineeringid = e[1] || ''
tableStore.table.params.projectId = e[2] || ''
}
}
// tableStore.table.params.engineeringid = e[1] || ''
// tableStore.table.params.projectId = e[2] || ''
// const zlIndex = deviceTreeOptions.value.findIndex((item: any) => {
// return item.name == '治理设备'
// })
// const bxsIndex = deviceTreeOptions.value.findIndex((item: any) => {
// return item.name == '便携式设备'
// })
// console.log("🚀 ~ zlIndex ~ zlIndex:", zlIndex,bxsIndex)
// //便携式设备特殊处理
// if (bxsIndex != -1 && deviceTreeOptions.value[bxsIndex].id == e[0] && e.length == 2) {
// tableStore.table.params.deviceId = e[1]
// }
// //治理设备
// if (zlIndex != -1 && deviceTreeOptions.value[zlIndex].id == e[0]) {
// tableStore.table.params.deviceId = e[2] || ''
// }
}
const getboxin = async (row: any) => {
console.log('🚀 ~ getboxin ~ row:', row)
// boxoList.value = row
// await analyseWave(row.id).then(res => {
// if (res != undefined) {
// wp.value = res.data
// view.value = false
// view2.value = true
// }
// })
}
const changeView = () => {
showBoxi.value = false
setTimeout(() => {
showBoxi.value = true
}, 0)
}
const bxhandleClick = (tab: any) => {
if (tab.name == 'ssbx') {
bxactiveName.value = 'ssbx'
} else if (tab.name == 'rmsbx') {
bxactiveName.value = 'rmsbx'
}
// console.log(tab, event);
}
const backbxlb = () => {
view.value = true
view2.value = false
setTimeout(() => {
tableStore.table.height = mainHeight(180).height as any
}, 0)
}
onMounted(() => {
tableStore.index()
})
const bxecharts = mainHeight(175).height as any
setTimeout(() => {
tableStore.table.height = mainHeight(200).height as any
}, 0)
const addMenu = () => {}
</script>
<style scoped lang="scss"></style>
<template>
<div ref="refheader" v-if="!isWaveCharts">
<TableHeader datePicker showExport>
<template v-slot:select>
<el-form-item label="数据来源">
<el-cascader
placeholder="请选择数据来源"
@change="sourceChange"
filterable
v-model.trim="tableStore.table.params.cascader"
:options="deviceTreeOptions"
:show-all-levels="false"
:props="{ checkStrictly: true }"
clearable
></el-cascader>
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备名称" /> -->
</el-form-item>
<!-- <el-form-item label="级别">
<el-select v-model.trim="tableStore.table.params.level" placeholder="请选择级别" clearable>
<el-option v-for="item in rankOptions" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item> -->
</template>
</TableHeader>
<Table></Table>
</div>
<waveFormAnalysis
v-loading="loading"
v-if="isWaveCharts"
ref="waveFormAnalysisRef"
@handleHideCharts="isWaveCharts = false"
:wp="wp"
/>
<!-- <div style="height: 300px;"> -->
<!-- <div style="padding: 10px" v-if="!view" v-loading="loading">
<el-row>
<el-col :span="12">
<div v-if="view2" style="display: flex">
<el-radio-group v-model.trim="value" @change="changeView">
<el-radio-button label="一次值" :value="1" />
<el-radio-button label="二次值" :value="2" />
</el-radio-group>
</div>
</el-col>
<el-col :span="12">
<el-button v-if="view2" @click="backbxlb" class="el-icon-refresh-right" icon="el-icon-Back"
style="float: right">
返回
</el-button>
</el-col>
</el-row>
<el-tabs v-if="view2" v-model.trim="bxactiveName" @tab-click="bxhandleClick">
<el-tab-pane label="瞬时波形" name="ssbx" class="boxbx pt10 pb10"
:style="'height:' + bxecharts + ';overflow-y: scroll;'">
<shushiboxi v-if="bxactiveName == 'ssbx' && showBoxi" :value="value" :boxoList="boxoList" :wp="wp">
</shushiboxi>
</el-tab-pane>
<el-tab-pane label="RMS波形" class="boxbx pt10 pb10" name="rmsbx"
:style="'height:' + bxecharts + ';overflow-y: scroll;'">
<rmsboxi v-if="bxactiveName == 'rmsbx' && showBoxi" :value="value" :boxoList="boxoList" :wp="wp">
</rmsboxi>
</el-tab-pane>
</el-tabs>
</div> -->
</template>
<script setup lang="ts">
import { ref, onMounted, provide, nextTick } from 'vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import shushiboxi from '@/components/echarts/shushiboxi.vue'
import waveFormAnalysis from '@/views/govern/device/control/tabs/components/waveFormAnalysis.vue'
import rmsboxi from '@/components/echarts/rmsboxi.vue'
import { analyseWave } from '@/api/common'
import { mainHeight } from '@/utils/layout'
import { ElMessage } from 'element-plus'
import { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
const props = defineProps(['deviceTree'])
const refheader = ref()
const waveFormAnalysisRef = ref()
const view = ref(true)
const isWaveCharts = ref(false)
const view2 = ref(false)
const showBoxi = ref(true)
const loading = ref(false)
const bxactiveName = ref('ssbx')
const boxoList: any = ref({})
const wp = ref({})
const value = ref(1)
const options = ref([
{
value: 1,
label: '一次值'
},
{
value: 2,
label: '二次值'
}
])
const rankOptions = ref([
{
value: '1',
label: '1级'
},
{
value: '2',
label: '2级'
},
{
value: '3',
label: '3级'
}
])
const tableStore = new TableStore({
url: '/cs-harmonic-boot/eventUser/queryEventpageWeb',
method: 'POST',
publicHeight: 65,
exportName: '暂态事件',
column: [ {
title: '序号',
width: 80,
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ title: '设备名称', field: 'equipmentName', align: 'center' },
{ title: '工程名称', field: 'engineeringName', align: 'center' },
{ title: '项目名称', field: 'projectName', align: 'center' },
{ title: '发生时刻', field: 'startTime', align: 'center', width: '240',sortable: true },
{ title: '监测点名称', field: 'lineName', align: 'center' },
{ title: '事件描述', field: 'showName', align: 'center' },
{ title: '事件发生位置', field: 'evtParamPosition', align: 'center' },
{ title: '相别', field: 'evtParamPhase', align: 'center' },
{ title: '持续时间(s)', field: 'evtParamTm', align: 'center',sortable: true },
{ title: '暂降(聚升)幅值(%)', minWidth: 100, field: 'evtParamVVaDepth', align: 'center',sortable: true },
{
title: '操作',
align: 'center',
width: '180',
render: 'buttons',
buttons: [
{
name: 'edit',
title: '波形分析',
type: 'primary',
icon: 'el-icon-DataLine',
render: 'basicButton',
loading: 'loading1',
disabled: row => {
return !row.wavePath && row.evtParamTm < 20
},
click: async row => {
row.loading1 = true
loading.value = true
isWaveCharts.value = true
await analyseWave(row.id)
.then(res => {
row.loading1 = false
if (res != undefined) {
boxoList.value = row
boxoList.value.featureAmplitude =
row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth - 0 : null
boxoList.value.systemType = 'WX'
wp.value = res.data
}
loading.value = false
})
.catch(() => {
row.loading1 = false
loading.value = false
})
nextTick(() => {
waveFormAnalysisRef.value &&
waveFormAnalysisRef.value.getWpData(wp.value, boxoList.value, true)
// waveFormAnalysisRef.value && waveFormAnalysisRef.value.setHeight(200, 190)
})
// row.loading1 = true
// view.value = false
// view2.value = true
// loading.value = true
// boxoList.value = row
// boxoList.value.systemType = 'WX'
// boxoList.value.persistTime = row.evtParamTm != '-' ? row.evtParamTm - 0 : null
// await analyseWave(row.id)
// .then(res => {
// row.loading1 = false
// if (res != undefined) {
// wp.value = res.data
// }
// loading.value = false
// })
// .catch(() => {
// row.loading1 = false
// loading.value = false
// })
}
},
{
name: 'edit',
title: '波形下载',
type: 'primary',
icon: 'el-icon-Check',
loading: 'loading2',
render: 'basicButton',
disabled: row => {
// && row.evtParamTm < 20
return !row.wavePath
},
click: row => {
getFileZip({ eventId: row.id }).then(res => {
let blob = new Blob([res], { type: 'application/zip' }) // console.log(blob) // var href = window.URL.createObjectURL(blob); //创建下载的链接
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a') // 创建a标签
link.href = url
link.download = row.wavePath.split('/')[2] || '波形文件' // 设置下载的文件名
document.body.appendChild(link)
link.click() //执行下载
document.body.removeChild(link) //释放标签
})
}
},
{
name: 'edit',
text: '暂无波形',
type: 'info',
icon: 'el-icon-DataLine',
render: 'basicButton',
disabled: row => {
return !(!row.wavePath && row.evtParamTm < 20)
}
}
]
}
],
beforeSearchFun: () => {
// if (!tableStore.table.params.deviceId) {
// delete tableStore.table.params.deviceId
// }
},
loadCallback: () => {
tableStore.table.data.forEach((item: any) => {
item.loading = false
item.evtParamTm =
item.evtParamTm.split('s')[0] != '-' ? (item.evtParamTm.split('s')[0] - 0).toFixed(2) : '-'
item.evtParamVVaDepth =
item.evtParamVVaDepth.split('%')[0] != '-' ? (item.evtParamVVaDepth.split('%')[0] - 0).toFixed(2) : '-'
})
}
})
provide('tableStore', tableStore)
// "target": [],
// "type": "",
// "userId": ""
tableStore.table.params.engineeringid = ''
tableStore.table.params.projectId = ''
tableStore.table.params.deviceTypeId = ''
tableStore.table.params.deviceId = ''
tableStore.table.params.type = 0
tableStore.table.params.eventIds = []
tableStore.table.params.status = ''
tableStore.table.params.target = []
tableStore.table.params.userId = ''
tableStore.table.params.cascader = ''
tableStore.table.params.deviceTypeName = ''
// tableStore.table.params.level=''
const deviceTreeOptions: any = ref<any>(props.deviceTree)
deviceTreeOptions.value.map((item: any, index: any) => {
if (item.children.length == 0) {
deviceTreeOptions.value.splice(index, 1)
}
})
const sourceChange = (e: any) => {
tableStore.table.params.deviceTypeId = ''
tableStore.table.params.engineeringid = ''
tableStore.table.params.projectId = ''
tableStore.table.params.deviceId = ''
if (e) {
let name = deviceTreeOptions.value.filter((item: any) => {
return item.id == e[0]
})[0].name
tableStore.table.params.deviceTypeName = name
if (name == '便携式设备') {
tableStore.table.params.deviceTypeId = e[0] || ''
tableStore.table.params.deviceId = e[1] || ''
} else {
tableStore.table.params.deviceTypeId = e[0] || ''
tableStore.table.params.engineeringid = e[1] || ''
tableStore.table.params.projectId = e[2] || ''
}
}
// tableStore.table.params.engineeringid = e[1] || ''
// tableStore.table.params.projectId = e[2] || ''
// const zlIndex = deviceTreeOptions.value.findIndex((item: any) => {
// return item.name == '治理设备'
// })
// const bxsIndex = deviceTreeOptions.value.findIndex((item: any) => {
// return item.name == '便携式设备'
// })
// console.log("🚀 ~ zlIndex ~ zlIndex:", zlIndex,bxsIndex)
// //便携式设备特殊处理
// if (bxsIndex != -1 && deviceTreeOptions.value[bxsIndex].id == e[0] && e.length == 2) {
// tableStore.table.params.deviceId = e[1]
// }
// //治理设备
// if (zlIndex != -1 && deviceTreeOptions.value[zlIndex].id == e[0]) {
// tableStore.table.params.deviceId = e[2] || ''
// }
}
const getboxin = async (row: any) => {
console.log('🚀 ~ getboxin ~ row:', row)
// boxoList.value = row
// await analyseWave(row.id).then(res => {
// if (res != undefined) {
// wp.value = res.data
// view.value = false
// view2.value = true
// }
// })
}
const changeView = () => {
showBoxi.value = false
setTimeout(() => {
showBoxi.value = true
}, 0)
}
const bxhandleClick = (tab: any) => {
if (tab.name == 'ssbx') {
bxactiveName.value = 'ssbx'
} else if (tab.name == 'rmsbx') {
bxactiveName.value = 'rmsbx'
}
// console.log(tab, event);
}
const backbxlb = () => {
view.value = true
view2.value = false
setTimeout(() => {
tableStore.table.height = mainHeight(180).height as any
}, 0)
}
onMounted(() => {
tableStore.index()
})
const bxecharts = mainHeight(175).height as any
setTimeout(() => {
tableStore.table.height = mainHeight(200).height as any
}, 0)
const addMenu = () => {}
</script>
<style scoped lang="scss"></style>

View File

@@ -1,202 +1,202 @@
<template>
<div class="default-main">
<TableHeader datePicker ref="refheader" >
<template v-slot:select>
<el-form-item label="关键字筛选">
<el-input
v-model.trim="tableStore.table.params.name"
placeholder="请输入关键字"
clearable
></el-input>
</el-form-item>
<el-form-item label="流程阶段">
<el-select v-model.trim="tableStore.table.params.process" clearable placeholder="请选择">
<el-option label="功能调试" :value="2"></el-option>
<el-option label="出厂调试" :value="3"></el-option>
<el-option label="正式投运" :value="4"></el-option>
</el-select>
</el-form-item>
</template>
<template v-slot:operation>
<el-button type="primary" icon="el-icon-Download" @click="exportTab">导出</el-button>
</template>
</TableHeader>
<Table ref="tableRef" />
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, provide } from 'vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import { queryByCode, queryByid, queryCsDictTree } from '@/api/system-boot/dictTree'
defineOptions({
name: 'manage/monthly'
})
const refheader = ref()
const devModelOptions: any = ref([])
queryByCode('Device_Type').then(res => {
queryByid(res.data.id).then(res => {
devModelOptions.value = res.data.map((item: any) => {
return {
value: item.id,
label: item.name,
...item
}
})
})
tableStore.index()
})
const tableStore = new TableStore({
url: '/cs-harmonic-boot/statisticsData/halfMonthReport',
method: 'POST',
isWebPaging: true,
exportName: '半月报功能',
column: [
{
title: '序号',
width: 80,
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ title: '工程名称', field: 'engineeringName', minWidth: 150 },
{ title: '项目名称', field: 'projectName', minWidth: 130 },
{ title: '设备名称', field: 'devName', minWidth: 130 },
{ title: '监测点名称', field: 'lineName', minWidth: 130 },
{
title: '投运时间',
field: 'operationalTime',
width: 180,
sortable: true
},
{
title: '数据更新时间',
field: 'latestTime',
width: 180,
sortable: true
// formatter: (row: any) => {
// return row.cellValue || '/'
// }
},
{
title: '设备型号',
field: 'devType',
width: 130,
formatter: row => {
return devModelOptions.value.filter((item: any) => item.value == row.cellValue)[0]?.label
}
},
{ title: 'Mac地址', field: 'mac', width: 140 },
{
title: '流程阶段',
field: 'process',
width: 100,
fixed: 'right',
render: 'tag',
custom: {
2: 'warning',
3: 'warning',
4: 'success'
},
replaceValue: {
2: '功能调试',
3: '出厂调试',
4: '正式投运'
},
minWidth: 80
},
{
title: '运行状态',
field: 'operationalStatus',
render: 'tag',
fixed: 'right',
width: 100,
custom: {
停运: 'danger',
在运: 'success'
},
replaceValue: {
在运: '在运',
停运: '停运'
}
},
{
title: '通讯状态',
field: 'communicationStatus',
width: 100,
fixed: 'right',
render: 'tag',
custom: {
离线: 'danger',
在线: 'success'
},
replaceValue: {
离线: '离线',
在线: '在线'
}
},
{ title: '在线率(%)', fixed: 'right',width: 100, field: 'onlineRate', sortable: true },
{ title: '完整性(%)', fixed: 'right',width: 100, field: 'integrity', sortable: true }
],
beforeSearchFun: () => {},
loadCallback: () => {
let name = tableStore.table.params.name
let data = tableStore.table.copyData.filter(item => {
// 处理latestTime默认值
item.latestTime = item.latestTime || '/'
// 需要检查的字段列表
const fieldsToCheck = ['projectName', 'engineeringName', 'mac', 'devName', 'lineName']
console.log(
'🚀 ~ fieldsToCheck.some(field => item[field]?.includes(name)):',
fieldsToCheck.some(field => item[field]?.includes(name))
)
// 检查任何一个字段包含搜索名称
return fieldsToCheck.some(field => item[field]?.includes(name))
})
tableStore.table.copyData = JSON.parse(JSON.stringify(data))
tableStore.table.total = tableStore.table.copyData.length
if (data.length == 0) {
tableStore.table.data = []
} else {
tableStore.table.data = JSON.parse(
JSON.stringify(
window.XEUtils.chunk(data, tableStore.table.params.pageSize)[tableStore.table.params.pageNum - 1]
)
)
}
}
})
provide('tableStore', tableStore)
tableStore.table.params.process = 4
tableStore.table.params.name = ''
const tableRef = ref()
const exportTab = () => {
tableRef.value.getRef()?.exportData({
filename: '半月报功能', // 文件名字
sheetName: 'Sheet1',
type: 'xlsx', //导出文件类型 xlsx 和 csv
useStyle: true,
data: tableStore.table.copyData, // 数据源 // 过滤那个字段导出
columnFilterMethod: function (column: any) {
return !(
column.column.title === undefined ||
column.column.title === '序号' ||
column.column.title === '操作'
)
}
})
}
onMounted(() => {})
setTimeout(() => {
// tableStore.table.height = mainHeight(200).height as any
}, 0)
const addMenu = () => {}
</script>
<style></style>
<template>
<div class="default-main">
<TableHeader datePicker ref="refheader" >
<template v-slot:select>
<el-form-item label="关键字筛选">
<el-input
v-model.trim="tableStore.table.params.name"
placeholder="请输入关键字"
clearable
></el-input>
</el-form-item>
<el-form-item label="流程阶段">
<el-select v-model.trim="tableStore.table.params.process" clearable placeholder="请选择">
<el-option label="功能调试" :value="2"></el-option>
<el-option label="出厂调试" :value="3"></el-option>
<el-option label="正式投运" :value="4"></el-option>
</el-select>
</el-form-item>
</template>
<template v-slot:operation>
<el-button type="primary" icon="el-icon-Download" @click="exportTab">导出</el-button>
</template>
</TableHeader>
<Table ref="tableRef" />
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, provide } from 'vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import { queryByCode, queryByid, queryCsDictTree } from '@/api/system-boot/dictTree'
defineOptions({
name: 'manage/monthly'
})
const refheader = ref()
const devModelOptions: any = ref([])
queryByCode('Device_Type').then(res => {
queryByid(res.data.id).then(res => {
devModelOptions.value = res.data.map((item: any) => {
return {
value: item.id,
label: item.name,
...item
}
})
})
tableStore.index()
})
const tableStore = new TableStore({
url: '/cs-harmonic-boot/statisticsData/halfMonthReport',
method: 'POST',
isWebPaging: true,
exportName: '半月报功能',
column: [
{
title: '序号',
width: 80,
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ title: '工程名称', field: 'engineeringName', minWidth: 150 },
{ title: '项目名称', field: 'projectName', minWidth: 130 },
{ title: '设备名称', field: 'devName', minWidth: 130 },
{ title: '监测点名称', field: 'lineName', minWidth: 130 },
{
title: '投运时间',
field: 'operationalTime',
width: 180,
sortable: true
},
{
title: '数据更新时间',
field: 'latestTime',
width: 180,
sortable: true
// formatter: (row: any) => {
// return row.cellValue || '/'
// }
},
{
title: '设备型号',
field: 'devType',
width: 130,
formatter: row => {
return devModelOptions.value.filter((item: any) => item.value == row.cellValue)[0]?.label
}
},
{ title: 'Mac地址', field: 'mac', width: 140 },
{
title: '流程阶段',
field: 'process',
width: 100,
fixed: 'right',
render: 'tag',
custom: {
2: 'warning',
3: 'warning',
4: 'success'
},
replaceValue: {
2: '功能调试',
3: '出厂调试',
4: '正式投运'
},
minWidth: 80
},
{
title: '运行状态',
field: 'operationalStatus',
render: 'tag',
fixed: 'right',
width: 100,
custom: {
停运: 'danger',
在运: 'success'
},
replaceValue: {
在运: '在运',
停运: '停运'
}
},
{
title: '通讯状态',
field: 'communicationStatus',
width: 100,
fixed: 'right',
render: 'tag',
custom: {
离线: 'danger',
在线: 'success'
},
replaceValue: {
离线: '离线',
在线: '在线'
}
},
{ title: '在线率(%)', fixed: 'right',width: 100, field: 'onlineRate', sortable: true },
{ title: '完整性(%)', fixed: 'right',width: 100, field: 'integrity', sortable: true }
],
beforeSearchFun: () => {},
loadCallback: () => {
let name = tableStore.table.params.name
let data = tableStore.table.copyData.filter(item => {
// 处理latestTime默认值
item.latestTime = item.latestTime || '/'
// 需要检查的字段列表
const fieldsToCheck = ['projectName', 'engineeringName', 'mac', 'devName', 'lineName']
console.log(
'🚀 ~ fieldsToCheck.some(field => item[field]?.includes(name)):',
fieldsToCheck.some(field => item[field]?.includes(name))
)
// 检查任何一个字段包含搜索名称
return fieldsToCheck.some(field => item[field]?.includes(name))
})
tableStore.table.copyData = JSON.parse(JSON.stringify(data))
tableStore.table.total = tableStore.table.copyData.length
if (data.length == 0) {
tableStore.table.data = []
} else {
tableStore.table.data = JSON.parse(
JSON.stringify(
window.XEUtils.chunk(data, tableStore.table.params.pageSize)[tableStore.table.params.pageNum - 1]
)
)
}
}
})
provide('tableStore', tableStore)
tableStore.table.params.process = 4
tableStore.table.params.name = ''
const tableRef = ref()
const exportTab = () => {
tableRef.value.getRef()?.exportData({
filename: '半月报功能', // 文件名字
sheetName: 'Sheet1',
type: 'xlsx', //导出文件类型 xlsx 和 csv
useStyle: true,
data: tableStore.table.copyData, // 数据源 // 过滤那个字段导出
columnFilterMethod: function (column: any) {
return !(
column.column.title === undefined ||
column.column.title === '序号' ||
column.column.title === '操作'
)
}
})
}
onMounted(() => {})
setTimeout(() => {
// tableStore.table.height = mainHeight(200).height as any
}, 0)
const addMenu = () => {}
</script>
<style></style>

View File

@@ -107,8 +107,8 @@ const editd = (e: any) => {
}
// 设计
const Aclick = (e: any) => {
// window.open(window.location.origin + `/zutai/?id=${e.id}&&name=${e.name}&&preview=false`)
window.open('http://192.168.1.128:4001' + `/zutai/?id=${e.id}&&name=${e.name}&&preview=false`)
// window.open(window.location.origin + `/zutai/?id=${e.id}&&name=${e.name}&&preview=false&&graphicDisplay=zl`)
window.open('http://192.168.1.179:4001' + `/zutai/?id=${e.id}&&name=${e.name}&&preview=false&&graphicDisplay=zl`)
}
// 删除
@@ -143,8 +143,8 @@ const deleted = (e: any) => {
}
const imgData = (e: any) => {
// window.open(window.location.origin + `/zutai/?id=${e.id}&&name=${e.name}&&preview=true#/preview`)
window.open('http://192.168.1.128:4001' + `/zutai/?id=${e.id}&&name=${e.name}&&preview=true#/preview`)
// window.open(window.location.origin + `/zutai/?id=${e.id}&&name=${e.name}&&preview=true&&graphicDisplay=zl#/preview`)
window.open('http://192.168.1.179:4001' + `/zutai/?id=${e.id}&&name=${e.name}&&preview=true&&graphicDisplay=zl#/preview`)
}

View File

@@ -1,105 +1,105 @@
<template>
<div class="default-main">
<div class="mb10" style="display: flex; justify-content: flex-end">
<el-upload
ref="upload"
action=""
:auto-upload="false"
:show-file-list="false"
:limit="1"
:on-change="beforeUpload"
>
<el-button icon="el-icon-Upload" type="primary" class="mr10">导入excel</el-button>
</el-upload>
<el-button @click="downloadExcel" class="" type="primary" icon="el-icon-Download">导出excel</el-button>
<el-button icon="el-icon-ArrowLeftBold" @click="emit('shutDown')">返回</el-button>
</div>
<div style="display: flex">
<div id="luckysheet" :style="{ height: height, flex: 1 }"></div>
</div>
</div>
</template>
<script setup lang="ts">
import { exportExcel } from './export.js'
import { mainHeight } from '@/utils/layout'
import LuckyExcel from 'luckyexcel'
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { viewCustomReportTemplateById } from '@/api/harmonic-boot/luckyexcel'
const emit = defineEmits(['shutDown'])
const height = mainHeight(65).height
const options: any = ref({
container: 'luckysheet',
title: '', // 表 头名
lang: 'zh', // 中文
showtoolbar: false, // 是否显示工具栏
showinfobar: false, // 是否显示顶部信息栏
showsheetbar: true, // 是否显示底部sheet按钮
data: [
{
name: 'Cell',
index: 0,
defaultRowHeight: 27,
defaultColWidth: 105,
chart: [] //图表配置
}
]
})
// 加载luckysheet
const info = () => {
luckysheet.create(options.value)
}
//绑定value
const setValue = (e: any) => {
let data = luckysheet.getRange()
luckysheet.setCellValue(
data[0].row[0],
data[0].column[0],
{
v: e[e.length - 1],
tr: e
}
// checkedNodes[0].data.label
)
}
// 下载表格
const downloadExcel = () => {
exportExcel(luckysheet.getAllSheets(), '报表模板')
}
// 导入
const beforeUpload = (file: any) => {
LuckyExcel.transformExcelToLucky(file.raw, function (exportJson: any) {
if (exportJson.sheets == null || exportJson.sheets.length == 0) {
ElMessage.warning('读取excel文件内容失败,目前只能上传xlsx文件!')
return
}
luckysheet.destroy()
options.value.title = exportJson.info.name
options.value.data = exportJson.sheets
luckysheet.create(options.value)
})
}
const open = async (row: any) => {
await viewCustomReportTemplateById({ id: row.id }).then((Response:any) => {
Response.forEach((item: any) => {
item.celldata.forEach((k: any) => {
item.data[k.r][k.c].v ? (item.data[k.r][k.c] = k.v ) : ''
})
})
options.value.data = Response
})
info()
}
defineExpose({ open })
onMounted(() => {})
</script>
<style lang="scss" scoped>
:deep(.el-tab-pane) {
padding: 10px;
}
</style>
<template>
<div class="default-main">
<div class="mb10" style="display: flex; justify-content: flex-end">
<el-upload
ref="upload"
action=""
:auto-upload="false"
:show-file-list="false"
:limit="1"
:on-change="beforeUpload"
>
<el-button icon="el-icon-Upload" type="primary" class="mr10">导入excel</el-button>
</el-upload>
<el-button @click="downloadExcel" class="" type="primary" icon="el-icon-Download">导出excel</el-button>
<el-button icon="el-icon-Back" @click="emit('shutDown')">返回</el-button>
</div>
<div style="display: flex">
<div id="luckysheet" :style="{ height: height, flex: 1 }"></div>
</div>
</div>
</template>
<script setup lang="ts">
import { exportExcel } from './export.js'
import { mainHeight } from '@/utils/layout'
import LuckyExcel from 'luckyexcel'
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { viewCustomReportTemplateById } from '@/api/harmonic-boot/luckyexcel'
const emit = defineEmits(['shutDown'])
const height = mainHeight(65).height
const options: any = ref({
container: 'luckysheet',
title: '', // 表 头名
lang: 'zh', // 中文
showtoolbar: false, // 是否显示工具栏
showinfobar: false, // 是否显示顶部信息栏
showsheetbar: true, // 是否显示底部sheet按钮
data: [
{
name: 'Cell',
index: 0,
defaultRowHeight: 27,
defaultColWidth: 105,
chart: [] //图表配置
}
]
})
// 加载luckysheet
const info = () => {
luckysheet.create(options.value)
}
//绑定value
const setValue = (e: any) => {
let data = luckysheet.getRange()
luckysheet.setCellValue(
data[0].row[0],
data[0].column[0],
{
v: e[e.length - 1],
tr: e
}
// checkedNodes[0].data.label
)
}
// 下载表格
const downloadExcel = () => {
exportExcel(luckysheet.getAllSheets(), '报表模板')
}
// 导入
const beforeUpload = (file: any) => {
LuckyExcel.transformExcelToLucky(file.raw, function (exportJson: any) {
if (exportJson.sheets == null || exportJson.sheets.length == 0) {
ElMessage.warning('读取excel文件内容失败,目前只能上传xlsx文件!')
return
}
luckysheet.destroy()
options.value.title = exportJson.info.name
options.value.data = exportJson.sheets
luckysheet.create(options.value)
})
}
const open = async (row: any) => {
await viewCustomReportTemplateById({ id: row.id }).then((Response:any) => {
Response.forEach((item: any) => {
item.celldata.forEach((k: any) => {
item.data[k.r][k.c].v ? (item.data[k.r][k.c] = k.v ) : ''
})
})
options.value.data = Response
})
info()
}
defineExpose({ open })
onMounted(() => {})
</script>
<style lang="scss" scoped>
:deep(.el-tab-pane) {
padding: 10px;
}
</style>

View File

@@ -1,159 +1,159 @@
<template>
<div class="default-main">
<div class="mb10" style="display: flex; justify-content: flex-end">
<el-upload ref="upload" action="" :auto-upload="false" :show-file-list="false" :limit="1"
:on-change="beforeUpload">
<el-button icon="el-icon-Upload" type="primary" class="mr10">导入excel</el-button>
</el-upload>
<el-button @click="downloadExcel" class="" type="primary" icon="el-icon-Download">导出excel</el-button>
<el-button type="primary" icon="el-icon-Check" @click="preservation">保存</el-button>
<el-button icon="el-icon-ArrowLeftBold" @click="emit('shutDown')">返回</el-button>
</div>
<div style="display: flex">
<div id="luckysheet" :style="{ height: height, flex: 1 }"></div>
<bind style="width: 500px" class="ml10" @setValue="setValue" />
</div>
<!-- 信息框 -->
<addForm ref="formFer" @submitForm="submitForm" />
</div>
</template>
<script setup lang="ts">
import { exportExcel } from './export.js'
import { mainHeight } from '@/utils/layout'
import LuckyExcel from 'luckyexcel'
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { addTemplate, dateTemplateup, viewCustomReportTemplateById } from '@/api/harmonic-boot/luckyexcel'
import bind from './bind.vue'
import addForm from './form.vue'
const emit = defineEmits(['shutDown'])
const formFer = ref()
const title = ref('')
const list = ref({})
const height = mainHeight(65).height
const options: any = ref({
container: 'luckysheet',
title: '', // 表 头名
lang: 'zh', // 中文
showtoolbar: true, // 是否显示工具栏
showinfobar: false, // 是否显示顶部信息栏
showsheetbar: true, // 是否显示底部sheet按钮
data: [
{
name: 'Cell',
index: 0,
defaultRowHeight: 27,
defaultColWidth: 105,
chart: [] //图表配置
}
]
})
// 加载luckysheet
const info = () => {
luckysheet.create(options.value)
}
//绑定value
const setValue = (e: any) => {
let data = luckysheet.getRange()
luckysheet.setCellValue(
data[0].row[0],
data[0].column[0],
{
v: e[e.length - 1],
tr: e
}
// checkedNodes[0].data.label
)
}
// 下载表格
const downloadExcel = () => {
exportExcel(luckysheet.getAllSheets(), '报表模板')
}
// 导入
const beforeUpload = (file: any) => {
LuckyExcel.transformExcelToLucky(file.raw, function (exportJson: any) {
if (exportJson.sheets == null || exportJson.sheets.length == 0) {
ElMessage.warning('读取excel文件内容失败,目前只能上传xlsx文件!')
return
}
luckysheet.destroy()
options.value.title = exportJson.info.name
exportJson.sheets.forEach((item: any) => {
// item.celldata = []
// item.data = []
item.celldata.forEach((k: any) => {
k.v.ct.s ? (k.v.v = k.v.ct.s[0].v) : ''
k.v.ct.s ? (k.v.m = k.v.ct.s[0].v) : ''
})
})
options.value.data = exportJson.sheets
luckysheet.create(options.value)
})
}
// 保存
const preservation = () => {
formFer.value.open(title.value, list.value)
}
// 新增
const submitForm = (formdata: any, text: string) => {
// let userStr = JSON.stringify(luckysheet.getAllSheets())
let userStr = luckysheet.getAllSheets()
userStr.forEach((item: any) => {
item.data1 = JSON.stringify(item.data)
})
let blob = new Blob([JSON.stringify(userStr)], {
type: 'application/json;charset=UTF-8'
})
let files = new window.File([blob], 'content.json', {
type: 'application/json;charset=UTF-8'
})
let params = new FormData()
params.append('fileContent', files)
params.append('deptId', formdata.deptId)
params.append('valueTitle', formdata.deptId)
params.append('name', formdata.name)
params.append('reportType', formdata.reportType)
params.append('reportForm', formdata.reportForm)
ElMessage.info('正在保存请稍等!')
if (text == '新增报表模板') {
addTemplate(params).then(res => {
ElMessage.success('新增成功!')
formFer.value.shutDown()
emit('shutDown')
}).catch(err => {
ElMessage.error('保存失败!')
formFer.value.shutDown()
})
} else if (text == '编辑报表模板') {
params.append('id', list.value.id)
dateTemplateup(params).then(res => {
ElMessage.success('编辑成功!')
formFer.value.shutDown()
emit('shutDown')
}).catch(err => {
ElMessage.error('保存失败!')
formFer.value.shutDown()
})
}
}
const open = async (text: string, row?: any) => {
title.value = text
if (row) {
list.value = row
await viewCustomReportTemplateById({ id: row.id }).then(Response => {
options.value.data = Response
})
}
info()
}
defineExpose({ open })
onMounted(() => { })
</script>
<style lang="scss" scoped>
:deep(.el-tab-pane) {
padding: 10px;
}
</style>
<template>
<div class="default-main">
<div class="mb10" style="display: flex; justify-content: flex-end">
<el-upload ref="upload" action="" :auto-upload="false" :show-file-list="false" :limit="1"
:on-change="beforeUpload">
<el-button icon="el-icon-Upload" type="primary" class="mr10">导入excel</el-button>
</el-upload>
<el-button @click="downloadExcel" class="" type="primary" icon="el-icon-Download">导出excel</el-button>
<el-button type="primary" icon="el-icon-Check" @click="preservation">保存</el-button>
<el-button icon="el-icon-Back" @click="emit('shutDown')">返回</el-button>
</div>
<div style="display: flex">
<div id="luckysheet" :style="{ height: height, flex: 1 }"></div>
<bind style="width: 500px" class="ml10" @setValue="setValue" />
</div>
<!-- 信息框 -->
<addForm ref="formFer" @submitForm="submitForm" />
</div>
</template>
<script setup lang="ts">
import { exportExcel } from './export.js'
import { mainHeight } from '@/utils/layout'
import LuckyExcel from 'luckyexcel'
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { addTemplate, dateTemplateup, viewCustomReportTemplateById } from '@/api/harmonic-boot/luckyexcel'
import bind from './bind.vue'
import addForm from './form.vue'
const emit = defineEmits(['shutDown'])
const formFer = ref()
const title = ref('')
const list = ref({})
const height = mainHeight(65).height
const options: any = ref({
container: 'luckysheet',
title: '', // 表 头名
lang: 'zh', // 中文
showtoolbar: true, // 是否显示工具栏
showinfobar: false, // 是否显示顶部信息栏
showsheetbar: true, // 是否显示底部sheet按钮
data: [
{
name: 'Cell',
index: 0,
defaultRowHeight: 27,
defaultColWidth: 105,
chart: [] //图表配置
}
]
})
// 加载luckysheet
const info = () => {
luckysheet.create(options.value)
}
//绑定value
const setValue = (e: any) => {
let data = luckysheet.getRange()
luckysheet.setCellValue(
data[0].row[0],
data[0].column[0],
{
v: e[e.length - 1],
tr: e
}
// checkedNodes[0].data.label
)
}
// 下载表格
const downloadExcel = () => {
exportExcel(luckysheet.getAllSheets(), '报表模板')
}
// 导入
const beforeUpload = (file: any) => {
LuckyExcel.transformExcelToLucky(file.raw, function (exportJson: any) {
if (exportJson.sheets == null || exportJson.sheets.length == 0) {
ElMessage.warning('读取excel文件内容失败,目前只能上传xlsx文件!')
return
}
luckysheet.destroy()
options.value.title = exportJson.info.name
exportJson.sheets.forEach((item: any) => {
// item.celldata = []
// item.data = []
item.celldata.forEach((k: any) => {
k.v.ct.s ? (k.v.v = k.v.ct.s[0].v) : ''
k.v.ct.s ? (k.v.m = k.v.ct.s[0].v) : ''
})
})
options.value.data = exportJson.sheets
luckysheet.create(options.value)
})
}
// 保存
const preservation = () => {
formFer.value.open(title.value, list.value)
}
// 新增
const submitForm = (formdata: any, text: string) => {
// let userStr = JSON.stringify(luckysheet.getAllSheets())
let userStr = luckysheet.getAllSheets()
userStr.forEach((item: any) => {
item.data1 = JSON.stringify(item.data)
})
let blob = new Blob([JSON.stringify(userStr)], {
type: 'application/json;charset=UTF-8'
})
let files = new window.File([blob], 'content.json', {
type: 'application/json;charset=UTF-8'
})
let params = new FormData()
params.append('fileContent', files)
params.append('deptId', formdata.deptId)
params.append('valueTitle', formdata.deptId)
params.append('name', formdata.name)
params.append('reportType', formdata.reportType)
params.append('reportForm', formdata.reportForm)
ElMessage.info('正在保存请稍等!')
if (text == '新增报表模板') {
addTemplate(params).then(res => {
ElMessage.success('新增成功!')
formFer.value.shutDown()
emit('shutDown')
}).catch(err => {
ElMessage.error('保存失败!')
formFer.value.shutDown()
})
} else if (text == '编辑报表模板') {
params.append('id', list.value.id)
dateTemplateup(params).then(res => {
ElMessage.success('编辑成功!')
formFer.value.shutDown()
emit('shutDown')
}).catch(err => {
ElMessage.error('保存失败!')
formFer.value.shutDown()
})
}
}
const open = async (text: string, row?: any) => {
title.value = text
if (row) {
list.value = row
await viewCustomReportTemplateById({ id: row.id }).then(Response => {
options.value.data = Response
})
}
info()
}
defineExpose({ open })
onMounted(() => { })
</script>
<style lang="scss" scoped>
:deep(.el-tab-pane) {
padding: 10px;
}
</style>

View File

@@ -1,48 +1,63 @@
<template>
<GridLayout
class="default-main"
v-model:layout="layout"
:row-height="rowHeight"
:is-resizable="false"
:is-draggable="false"
:responsive="false"
:vertical-compact="false"
prevent-collision
:col-num="12"
>
<template #item="{ item }">
<div class="box">
<div class="title">
<div style="display: flex; align-items: center">
<Icon class="HelpFilled" :name="item.icon" />
{{ item.name }}
<div class="default-main">
<TableHeader :showSearch="false">
<template v-slot:select>
<el-form-item label="日期">
<DatePicker ref="datePickerRef" :nextFlag="false" :theCurrentTime="true"></DatePicker>
</el-form-item>
</template>
</TableHeader>
<GridLayout
v-model:layout="layout"
:row-height="rowHeight"
:is-resizable="false"
:is-draggable="false"
:responsive="false"
:vertical-compact="false"
prevent-collision
:col-num="12"
>
<template #item="{ item }">
<div class="box">
<div class="title">
<div style="display: flex; align-items: center">
<Icon class="HelpFilled" :name="item.icon" />
{{ item.name }}
</div>
<!-- <FullScreen class="HelpFilled" style="cursor: pointer" @click="zoom(item)" /> -->
<img :src="flag ? img : img1" style="cursor: pointer; height: 16px" @click="zoom(item)" />
</div>
<div>
<component
:is="item.component"
v-if="item.component"
class="pd10"
:key="key"
:timeValue="datePickerRef.timeValue"
:height="rowHeight * item.h - seRowHeight(item.h) + 'px'"
:width="rowWidth * item.w - 30 + 'px'"
:timeKey="item.timeKey"
/>
<div v-else class="pd10">组件加载失败...</div>
</div>
<!-- <FullScreen class="HelpFilled" style="cursor: pointer" @click="zoom(item)" /> -->
<img :src="flag ? img : img1" style="cursor: pointer; height: 16px" @click="zoom(item)" />
</div>
<div>
<component
:is="item.component"
v-if="item.component"
class="pd10"
:key="key"
:height="rowHeight * item.h - (item.h == 6 ? -20 : item.h == 2 ? 20 : 5) + 'px'"
:width="rowWidth * item.w - 5 + 'px'"
:timeKey="item.timeKey"
/>
<div v-else class="pd10">组件加载失败...</div>
</div>
</div>
</template>
</GridLayout>
</template>
</GridLayout>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, markRaw, onUnmounted, defineAsyncComponent, type Component } from 'vue'
import TableHeader from '@/components/table/header/index.vue'
import { GridLayout } from 'grid-layout-plus'
import DatePicker from '@/components/form/datePicker/index.vue'
import { useDebounceFn } from '@vueuse/core'
import { queryActivatePage } from '@/api/system-boot/csstatisticalset'
import { queryActivatePage, queryByPagePath } from '@/api/system-boot/csstatisticalset'
import { HelpFilled, FullScreen } from '@element-plus/icons-vue'
import { useRouter } from 'vue-router'
const datePickerRef = ref()
const router = useRouter()
// defineOptions({
// name: 'cockpit/homePage'
// })
@@ -60,8 +75,8 @@ interface LayoutItem {
error?: any
}
const key = ref(0)
const img = new URL(`@/assets/imgs/amplify.png`, import.meta.url)
const img1 = new URL(`@/assets/imgs/reduce.png`, import.meta.url)
const img = new URL(`@/assets/img/amplify.png`, import.meta.url)
const img1 = new URL(`@/assets/img/reduce.png`, import.meta.url)
// 响应式数据
const rowHeight = ref(0)
const rowWidth = ref(0)
@@ -94,7 +109,7 @@ const getMainWidth = () => {
// 初始化行高
const initRowHeight = () => {
rowHeight.value = Math.max(0, (getMainHeight() - 20) / 6)
rowHeight.value = Math.max(0, (getMainHeight() - 72) / 6)
rowWidth.value = Math.max(0, getMainWidth() / 12)
}
@@ -111,7 +126,7 @@ const registerComponent = (path: string): Component | string | null => {
try {
// 动态导入组件
const modules = import.meta.glob('@/views/**/*.vue')
const modules = import.meta.glob('@/**/*.vue')
if (!modules[path]) {
console.error(`组件加载失败: ${path}`)
return null
@@ -147,10 +162,21 @@ const zoom = (value: any) => {
flag.value = !flag.value
key.value += 1
}
// 计算组件高度
const seRowHeight = (value: any) => {
if (value == 6) return 0
if (value == 5) return 12
if (value == 4) return 20
if (value == 3) return 30
if (value == 2) return 40
if (value == 1) return 50
return 0
}
// 获取布局数据
const fetchLayoutData = async () => {
try {
const { data } = await queryActivatePage()
const { data } = await queryByPagePath({ pagePath: router.currentRoute.value.name })
const parsedLayout = JSON.parse(data.containerConfig || '[]') as LayoutItem[]
// 处理布局数据
layout.value = parsedLayout.map((item, index) => ({

View File

@@ -0,0 +1,239 @@
<template>
<div class="default-main" :style="{ padding: prop.height ? '0px !important' : '10px' }">
<!-- 实时数据 -->
<!-- 添加加载事件监听 -->
<div class="dataBox" :style="{ height: prop.height || pageHeight.height }">
<div
class="iframe-container"
:style="{
boxShadow: `var(--el-box-shadow-light)`
}"
>
<iframe
:src="iframeSrc"
width="100%"
height="100%"
frameborder="0"
scrolling="no"
id="iframeLeft"
@load="onIframeLoad"
></iframe>
</div>
<el-card class="bottom-container " style="flex: 1;min-height: 165px;">
<div class="buttonBox">
<el-button type="primary" icon="el-icon-Aim">复位</el-button>
</div>
<div class="tableBox">
<Table ref="tableRef" height="100%"></Table>
</div>
</el-card>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, watch, onMounted, onUnmounted, provide } from 'vue'
import Table from '@/components/table/index.vue'
import TableStore from '@/utils/tableStore'
import { mainHeight } from '@/utils/layout'
// import { getActive } from "@/api/manage_wx/index";
// const props = defineProps<{
// project: { id: string; name: string } | null
// }>()
const prop = defineProps({
width: { type: String },
height: { type: String },
timeKey: { type: String },
timeValue: { type: Object }
})
const tableStore: any = new TableStore({
url: '/user-boot/role/selectRoleDetail?id=0',
method: 'POST',
showPage: false,
exportName: '主要监测点列表',
column: [
{
field: 'index',
title: '序号',
width: '80',
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{
title: '时间',
field: 'whetherToGovern',
minWidth: '70'
},
{
title: '监测点名',
field: 'name',
minWidth: '90'
// render: 'customTemplate',
// customTemplate: (row: any) => {
// return `<span style='cursor: pointer;text-decoration: underline;'>${row.name}</span>`
// }
},
{ title: '事件描述', field: 'question', minWidth: '200' }
],
beforeSearchFun: () => {
// tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
// tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
},
loadCallback: () => {
tableStore.table.data = [
{
name: '10kV1#电动机',
type: '电动机',
whetherToGovern: '2025-01-01 15:00:00',
question: '3次谐波电压、5次谐波电流、电压不平衡度超标'
},
{
name: '10kV2#(治理后)',
type: '电焊机',
whetherToGovern: '2025-05-01 16:00:00',
question: '所有指标均合格'
},
{
name: '380V电焊机(治理前)',
type: '电焊机',
whetherToGovern: '2025-06-01 15:00:00',
question: '5次谐波电流、电压不平衡度超标'
},
{
name: '380V水泵机',
type: '电动机',
whetherToGovern: '2025-08-01 15:00:00',
question: '所有指标均合格'
}
]
}
})
const tableRef = ref()
provide('tableRef', tableRef)
const pageHeight = mainHeight(40)
provide('tableStore', tableStore)
const iframeSrc = ref('')
// 监听 props 变化
// watch(
// () => props.project,
// newVal => {
// if (newVal && newVal.id && newVal.name) {
// // window.location.origin
// // iframeSrc.value =
// // "http://192.168.1.179:4001" +
// // `/zutai/?id=${newVal.id}&&name=${encodeURIComponent(
// // newVal.name
// // )}&&preview=true&&display=true&&graphicDisplay=wx#/preview`;
// iframeSrc.value =
// 'http://192.168.1.179:4001' +
// `/zutai/?id=4b4f7f4260198776594f5f9d93a532e8&&name=stt&&preview=true&&display=true#/preview_YPT`
// // console.log("更新 iframeSrc:", iframeSrc.value);
// }
// },
// { immediate: true, deep: true }
// )
onMounted(() => {
iframeSrc.value =
'http://192.168.1.179:4001' +
`/zutai/?id=4b4f7f4260198776594f5f9d93a532e8&&name=stt&&preview=true&&display=true#/preview_YPT`
tableStore.index()
// 监听来自 eventStatistics 组件的消息
window.addEventListener('message', handleMessage)
// getActive({}).then((res: any) => {
// if (res.code == "A0000") {
// // window.location.origin
// iframeSrc.value =
// "http://192.168.1.179:4001" +
// `/zutai/?id=${res.data.id}&&name=${encodeURIComponent(
// res.data.name
// )}&&preview=true&&display=true&&graphicDisplay=wx#/preview`;
// }
// });
})
onUnmounted(() => {
// 清理事件监听器
window.removeEventListener('message', handleMessage)
})
// iframe 加载完成回调 添加加载事件监听
const onIframeLoad = () => {
// console.log("iframe 加载完成");
// 通知 securityDetail.vue 组件 iframe 已加载完成
window.postMessage(
{
type: 'IFRAME_LOADED',
data: { loaded: true }
},
'*'
)
}
// 处理来自 eventStatistics 组件的消息
const handleMessage = (event: MessageEvent) => {
// 验证消息来源(在生产环境中应该验证 origin
// if (event.origin !== 'trusted-origin') return;
const { type, payload } = event.data
if (type === 'SEND_KEYS_TO_IFRAME') {
// 将数据转发给 iframe
sendKeysToIframe(payload)
}
}
// 向 iframe 发送 keyList 数据
const sendKeysToIframe = (keyList: string[]) => {
const iframe = document.getElementById('iframeLeft') as HTMLIFrameElement
if (iframe && iframe.contentWindow) {
iframe.contentWindow.postMessage(
{
type: 'ANALYSIS_KEYS',
payload: keyList
},
'*'
) // 在生产环境中应该指定具体的域名而不是 '*'
}
}
</script>
<style lang="scss" scoped>
.dataBox {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.iframe-container {
flex: 3.5;
}
:deep(.el-card__body) {
display: flex;
padding: 10px;
height: 100%;
.buttonBox {
display: flex;
width: 150px;
align-items: center;
justify-content: center;
}
.tableBox {
flex: 1;
width: 100%;
}
}
</style>

View File

@@ -2,7 +2,7 @@
<div class="pd10">
<el-card>
<el-form ref="formRef" inline :rules="rules" :model="form" label-width="120px" class="form-four">
<el-form-item label="页面名称:" prop="pageName">
<el-form-item label="页面名称" prop="pageName">
<el-input
maxlength="32"
show-word-limit
@@ -11,7 +11,7 @@
></el-input>
</el-form-item>
<el-form-item label="页面排序:" prop="sort">
<el-form-item label="页面排序" prop="sort">
<el-input
maxlength="32"
show-word-limit-number
@@ -19,11 +19,15 @@
:min="0"
:step="1"
step-strictly
style="width: 100%"
/>
</el-form-item>
<el-form-item label="绑定页面">
<el-select v-model="form.pagePath" filterable placeholder="请选择绑定页面" style="width: 100%" clearable>
<el-option v-for="item in pageList" :key="item.path" :label="item.name" :value="item.path" />
</el-select>
</el-form-item>
<el-form-item label="备注:" class="top">
<el-form-item label="备注" class="top">
<el-input
maxlength="300"
show-word-limit
@@ -118,7 +122,7 @@
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted,onBeforeUnmount } from 'vue'
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue'
import { useRouter } from 'vue-router'
import BackComponent from '@/components/icon/back/index.vue'
import { mainHeight } from '@/utils/layout'
@@ -131,11 +135,17 @@ import { Tools, CloseBold } from '@element-plus/icons-vue'
import { addDashboard, updateDashboard, queryById } from '@/api/system-boot/csstatisticalset'
import html2canvas from 'html2canvas'
import { useRoute } from 'vue-router'
// defineOptions({
// name: 'cockpit/popup'
// })
const { go } = useRouter()
const { query } = useRoute()
const router = useRouter()
const height = mainHeight(108)
const indicatorHeight = mainHeight(128)
const rowHeight = ref(0)
const pageList: any = ref([])
const GridHeight = ref(0)
const position = ref<CollapseIconPositionType>('left')
const form: any = reactive({
@@ -144,6 +154,8 @@ const form: any = reactive({
containerConfig: [],
sort: '100',
id: '',
pagePath: '',
pathName: '',
remark: ''
})
const activeNames = ref([])
@@ -168,6 +180,13 @@ const layout: any = ref([
const treeComponents: any = ref([]) //组件树
const treeComponentsCopy: any = ref([]) //组件树
const info = () => {
pageList.value = router
.getRoutes()
.filter(item => item?.meta?.component == '/src/views/pqs/cockpit/homePage/index.vue')
.map(item => {
return { name: item?.meta?.title, path: item?.meta?.path }
})
activeNames.value = []
activeNames1.value = []
componentTree().then(res => {
@@ -185,6 +204,8 @@ const info = () => {
queryById({ id: query.id }).then(res => {
layout.value = JSON.parse(res.data.containerConfig)
form.pageName = res.data.pageName
form.pagePath = res.data.pagePath
form.pathName = res.data.pathName
form.sort = res.data.sort
form.remark = res.data.remark
form.id = res.data.id
@@ -340,6 +361,8 @@ const onSubmit = () => {
}).then(canvas => {
url = canvas.toDataURL('image/png')
})
form.pagePath = form.pagePath || ''
form.pathName = pageList.value.filter((item: any) => item.path == form.pagePath)?.[0]?.name || ''
if (valid) {
if (form.id == '') {

View File

@@ -1,9 +1,19 @@
<template>
<div class="default-main">
<div class=" layoutHeader">
<!-- <div class=" layoutHeader">
<div class="title">{{title}}</div>
<back-component />
</div>
</div> -->
<TableHeader :showSearch="false">
<template v-slot:select>
<el-form-item label="日期">
<DatePicker ref="datePickerRef" :nextFlag="false" :theCurrentTime="true"></DatePicker>
</el-form-item>
</template>
<template v-slot:operation>
<back-component />
</template>
</TableHeader>
<GridLayout
v-model:layout="layout"
:row-height="rowHeight"
@@ -30,8 +40,9 @@
v-if="item.component"
class="pd10"
:key="key"
:height="rowHeight * item.h - (item.h == 6 ? -20 : item.h == 2 ? 20 : 5) + 'px'"
:width="rowWidth * item.w - 5 + 'px'"
:timeValue="datePickerRef.timeValue"
:height="rowHeight * item.h - seRowHeight(item.h) + 'px'"
:width="rowWidth * item.w - 30 + 'px'"
:timeKey="item.timeKey"
/>
<div v-else class="pd10">组件加载失败...</div>
@@ -47,12 +58,14 @@ import { ref, reactive, onMounted, markRaw, onUnmounted, defineAsyncComponent, t
import { GridLayout } from 'grid-layout-plus'
import { useDebounceFn } from '@vueuse/core'
import { useRouter } from 'vue-router'
import TableHeader from '@/components/table/header/index.vue'
import DatePicker from '@/components/form/datePicker/index.vue'
import BackComponent from '@/components/icon/back/index.vue'
import { queryById } from '@/api/system-boot/csstatisticalset'
import { HelpFilled, FullScreen } from '@element-plus/icons-vue'
import { useRoute } from 'vue-router'
// defineOptions({
// name: 'cockpit/homePage'
// name: 'cockpit/view'
// })
const { query } = useRoute()
// 定义类型
@@ -68,14 +81,15 @@ interface LayoutItem {
loading?: boolean
error?: any
}
const datePickerRef = ref()
const title = ref('')
const key = ref(0)
const img = new URL(`@/assets/imgs/amplify.png`, import.meta.url)
const img1 = new URL(`@/assets/imgs/reduce.png`, import.meta.url)
const img = new URL(`@/assets/img/amplify.png`, import.meta.url)
const img1 = new URL(`@/assets/img/reduce.png`, import.meta.url)
// 响应式数据
const rowHeight = ref(0)
const rowWidth = ref(0)
const layout = ref<LayoutItem[]>([
const layout: any = ref<LayoutItem[]>([
// {
// x: 4,
// y: 0,
@@ -121,7 +135,7 @@ const registerComponent = (path: string): Component | string | null => {
try {
// 动态导入组件
const modules = import.meta.glob('@/views/**/*.vue')
const modules = import.meta.glob('@/**/*.vue')
if (!modules[path]) {
console.error(`组件加载失败: ${path}`)
return null
@@ -161,7 +175,7 @@ const zoom = (value: any) => {
const fetchLayoutData = async () => {
try {
const { data } = await queryById({ id: query.id })
title.value = data.pageName+'_预览'
title.value = data.pageName + '_预览'
const parsedLayout = JSON.parse(data.containerConfig || '[]') as LayoutItem[]
// 处理布局数据
layout.value = parsedLayout.map((item, index) => ({
@@ -175,6 +189,16 @@ const fetchLayoutData = async () => {
// 可以添加错误提示逻辑
}
}
// 计算组件高度
const seRowHeight = (value: any) => {
if (value == 6) return 0
if (value == 5) return 12
if (value == 4) return 20
if (value == 3) return 30
if (value == 2) return 40
if (value == 1) return 50
return 0
}
// 窗口大小变化处理 - 使用防抖
const handleResize = useDebounceFn(() => {
@@ -232,8 +256,10 @@ onUnmounted(() => {
:deep(.vgl-item) {
overflow: hidden;
}
.box {
overflow: hidden;
.title {
border-bottom: 1px solid #000;
font-size: 14px;
@@ -246,6 +272,7 @@ onUnmounted(() => {
align-items: center;
justify-content: space-between;
}
.HelpFilled {
height: 16px;
width: 16px;
@@ -253,13 +280,15 @@ onUnmounted(() => {
margin-right: 5px;
}
}
.layoutHeader{
.layoutHeader {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 20px;
font-size: 16px;
.title{
.title {
font-weight: 600;
}
}

View File

@@ -31,8 +31,15 @@
>
{{ item.pageName }}
</span>
<div style="display: flex; align-items: center; font-weight: 550">
<div v-if="item.pathName" :style="{ color: `var(--el-color-primary)` }">
绑定页面{{ item.pathName }}
</div>
<div v-else>暂未绑定</div>
</div>
<div style="display: flex; justify-content: end">
<el-button
<!-- <el-button
class="color"
icon="el-icon-Position"
style="padding: 3px 0"
@@ -41,7 +48,7 @@
@click="activation(item)"
>
激活
</el-button>
</el-button> -->
<el-button
class="color"
icon="el-icon-View"

View File

@@ -1,5 +1,6 @@
<template>
<el-dialog draggable class="cn-operate-dialog" v-model="dialogVisible" width="930px" :title="title" @close="cancel">
<el-dialog draggable class="cn-operate-dialog" v-model="dialogVisible" width="1000px" :title="title"
@close="cancel">
<div style="display: flex">
<el-form :inline="false" :model="form" label-width="auto" :rules="rules" ref="formRef" style="flex: 1">
<el-form-item class="top" label="组件名称" prop="name">
@@ -31,10 +32,10 @@
<el-input v-model="form.sort" placeholder="请输入组件排序"></el-input>
</el-form-item>
</el-form>
<div style="width: 550px; height: 370px; overflow: hidden">
<div style="width: 600px; height: 360px; overflow: hidden">
<div class="ml10" style="font-weight: 600">组件展示</div>
<component :is="registerComponent(form.path)" v-if="registerComponent(form.path)"
class="pd10 GridLayout" :key="form.path" :height="'350px'" :width="'533px'"
class="pd10 GridLayout" :key="form.path" :height="'350px'" :width="'580px'"
:timeKey="form.timeKey" />
<!-- <div class="pd10">组件加载失败...</div> -->
<el-empty v-else description="未查询到组件" style="height: 350px; width: 533px" />
@@ -57,6 +58,7 @@ import TableStore from '@/utils/tableStore' // 若不是列表页面弹框可删
import { getFatherComponent, componentAdd, componentEdit } from '@/api/user-boot/dept'
import IconSelector from '@/components/baInput/components/iconSelector.vue'
import html2canvas from 'html2canvas'
const dictData = useDictData()
const dialogVisible = ref(false)
const title = ref('')
@@ -104,11 +106,12 @@ const submit = () => {
formRef.value.validate(async (valid: boolean) => {
if (valid) {
let url = ''
await html2canvas(document.querySelector('.GridLayout'), {
scale: 2
}).then(canvas => {
url = canvas.toDataURL('image/png')
console.log('🚀 ~ html2canvas ~ url:', url)
})
if (title.value == '新增组件') {
await componentAdd({
@@ -150,7 +153,7 @@ const registerComponent = (path: string): Component | string | null => {
try {
// 动态导入组件
const modules = import.meta.glob('@/views/**/*.vue')
const modules = import.meta.glob('@/**/*.vue')
if (!modules[path]) {
console.error(`组件加载失败: ${path}`)
return null

View File

@@ -5,16 +5,13 @@
<el-button type="primary" @click="add" icon="el-icon-Plus">新增</el-button>
</template>
</TableHeader>
<Table
ref="tableRef"
:tree-config="{ transform: true, parentField: 'uPid', rowField: 'uId' }"
:scroll-y="{ enabled: true }"
/>
<Table ref="tableRef" :tree-config="{ transform: true, parentField: 'uPid', rowField: 'uId' }"
:scroll-y="{ enabled: true }" />
<Add ref="addRef" v-if="addFlag" @onSubmit="tableStore.index()" />
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, provide } from 'vue'
import { ref, onMounted, provide,nextTick } from 'vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import { useDictData } from '@/stores/dictData'
@@ -42,12 +39,13 @@ const tableStore = new TableStore({
width: '80',
render: 'icon'
},
{ field: 'code', title: '组件标识' },
{ field: 'code', title: '组件标识', minWidth: '100', },
{ field: 'path', title: '组件路径' },
{ field: 'image', title: '组件展示', render: 'image' },
{
title: '操作',
render: 'buttons',
width: '150',
buttons: [
{
name: 'edit',
@@ -93,9 +91,9 @@ const tableStore = new TableStore({
loadCallback: () => {
addFlag.value = false
setTimeout(() => {
tableRef.value.getRef().setAllTreeExpand(true)
}, 1000)
tableStore.table.data.forEach((item:any) => {
tableRef.value?.getRef()?.setAllTreeExpand(true)
}, 0)
tableStore.table.data.forEach((item: any) => {
item.state = 0
})
treeData.value = tree2List(tableStore.table.data, Math.random() * 1000)

View File

@@ -1,105 +1,105 @@
<template>
<div class="default-main">
<div class="mb10" style="display: flex; justify-content: flex-end">
<el-upload
ref="upload"
action=""
:auto-upload="false"
:show-file-list="false"
:limit="1"
:on-change="beforeUpload"
>
<el-button icon="el-icon-Upload" type="primary" class="mr10">导入excel</el-button>
</el-upload>
<el-button @click="downloadExcel" class="" type="primary" icon="el-icon-Download">导出excel</el-button>
<el-button icon="el-icon-ArrowLeftBold" @click="emit('shutDown')">返回</el-button>
</div>
<div style="display: flex">
<div id="luckysheet" :style="{ height: height, flex: 1 }"></div>
</div>
</div>
</template>
<script setup lang="ts">
import { exportExcel } from './export.js'
import { mainHeight } from '@/utils/layout'
import LuckyExcel from 'luckyexcel'
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { viewCustomReportTemplateById } from '@/api/harmonic-boot/luckyexcel'
const emit = defineEmits(['shutDown'])
const height = mainHeight(65).height
const options: any = ref({
container: 'luckysheet',
title: '', // 表 头名
lang: 'zh', // 中文
showtoolbar: false, // 是否显示工具栏
showinfobar: false, // 是否显示顶部信息栏
showsheetbar: true, // 是否显示底部sheet按钮
data: [
{
name: 'Cell',
index: 0,
defaultRowHeight: 27,
defaultColWidth: 105,
chart: [] //图表配置
}
]
})
// 加载luckysheet
const info = () => {
luckysheet.create(options.value)
}
//绑定value
const setValue = (e: any) => {
let data = luckysheet.getRange()
luckysheet.setCellValue(
data[0].row[0],
data[0].column[0],
{
v: e[e.length - 1],
tr: e
}
// checkedNodes[0].data.label
)
}
// 下载表格
const downloadExcel = () => {
exportExcel(luckysheet.getAllSheets(), '报表模板')
}
// 导入
const beforeUpload = (file: any) => {
LuckyExcel.transformExcelToLucky(file.raw, function (exportJson: any) {
if (exportJson.sheets == null || exportJson.sheets.length == 0) {
ElMessage.warning('读取excel文件内容失败,目前只能上传xlsx文件!')
return
}
luckysheet.destroy()
options.value.title = exportJson.info.name
options.value.data = exportJson.sheets
luckysheet.create(options.value)
})
}
const open = async (row: any) => {
await viewCustomReportTemplateById({ id: row.id }).then((Response:any) => {
Response.forEach((item: any) => {
item.celldata.forEach((k: any) => {
item.data[k.r][k.c].v ? (item.data[k.r][k.c] = k.v ) : ''
})
})
options.value.data = Response
})
info()
}
defineExpose({ open })
onMounted(() => {})
</script>
<style lang="scss" scoped>
:deep(.el-tab-pane) {
padding: 10px;
}
</style>
<template>
<div class="default-main">
<div class="mb10" style="display: flex; justify-content: flex-end">
<el-upload
ref="upload"
action=""
:auto-upload="false"
:show-file-list="false"
:limit="1"
:on-change="beforeUpload"
>
<el-button icon="el-icon-Upload" type="primary" class="mr10">导入excel</el-button>
</el-upload>
<el-button @click="downloadExcel" class="" type="primary" icon="el-icon-Download">导出excel</el-button>
<el-button icon="el-icon-Back" @click="emit('shutDown')">返回</el-button>
</div>
<div style="display: flex">
<div id="luckysheet" :style="{ height: height, flex: 1 }"></div>
</div>
</div>
</template>
<script setup lang="ts">
import { exportExcel } from './export.js'
import { mainHeight } from '@/utils/layout'
import LuckyExcel from 'luckyexcel'
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { viewCustomReportTemplateById } from '@/api/harmonic-boot/luckyexcel'
const emit = defineEmits(['shutDown'])
const height = mainHeight(65).height
const options: any = ref({
container: 'luckysheet',
title: '', // 表 头名
lang: 'zh', // 中文
showtoolbar: false, // 是否显示工具栏
showinfobar: false, // 是否显示顶部信息栏
showsheetbar: true, // 是否显示底部sheet按钮
data: [
{
name: 'Cell',
index: 0,
defaultRowHeight: 27,
defaultColWidth: 105,
chart: [] //图表配置
}
]
})
// 加载luckysheet
const info = () => {
luckysheet.create(options.value)
}
//绑定value
const setValue = (e: any) => {
let data = luckysheet.getRange()
luckysheet.setCellValue(
data[0].row[0],
data[0].column[0],
{
v: e[e.length - 1],
tr: e
}
// checkedNodes[0].data.label
)
}
// 下载表格
const downloadExcel = () => {
exportExcel(luckysheet.getAllSheets(), '报表模板')
}
// 导入
const beforeUpload = (file: any) => {
LuckyExcel.transformExcelToLucky(file.raw, function (exportJson: any) {
if (exportJson.sheets == null || exportJson.sheets.length == 0) {
ElMessage.warning('读取excel文件内容失败,目前只能上传xlsx文件!')
return
}
luckysheet.destroy()
options.value.title = exportJson.info.name
options.value.data = exportJson.sheets
luckysheet.create(options.value)
})
}
const open = async (row: any) => {
await viewCustomReportTemplateById({ id: row.id }).then((Response:any) => {
Response.forEach((item: any) => {
item.celldata.forEach((k: any) => {
item.data[k.r][k.c].v ? (item.data[k.r][k.c] = k.v ) : ''
})
})
options.value.data = Response
})
info()
}
defineExpose({ open })
onMounted(() => {})
</script>
<style lang="scss" scoped>
:deep(.el-tab-pane) {
padding: 10px;
}
</style>

View File

@@ -1,167 +1,167 @@
<template>
<div class="default-main">
<div class="mb10" style="display: flex; justify-content: flex-end">
<el-upload
ref="upload"
action=""
:auto-upload="false"
:show-file-list="false"
:limit="1"
:on-change="beforeUpload"
>
<el-button icon="el-icon-Upload" type="primary" class="mr10">导入excel</el-button>
</el-upload>
<el-button @click="downloadExcel" class="" type="primary" icon="el-icon-Download">导出excel</el-button>
<el-button type="primary" icon="el-icon-Check" @click="preservation">保存</el-button>
<el-button icon="el-icon-ArrowLeftBold" @click="emit('shutDown')">返回</el-button>
</div>
<div style="display: flex">
<div id="luckysheet" :style="{ height: height, flex: 1 }"></div>
<bind style="width: 500px" class="ml10" @setValue="setValue" />
</div>
<!-- 信息框 -->
<addForm ref="formFer" @submitForm="submitForm" />
</div>
</template>
<script setup lang="ts">
import { exportExcel } from './export.js'
import { mainHeight } from '@/utils/layout'
import LuckyExcel from 'luckyexcel'
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { addTemplate, dateTemplateup, viewCustomReportTemplateById } from '@/api/harmonic-boot/luckyexcel'
import bind from './bind.vue'
import addForm from './form.vue'
const emit = defineEmits(['shutDown'])
const formFer = ref()
const title = ref('')
const list = ref({})
const height = mainHeight(65).height
const options: any = ref({
container: 'luckysheet',
title: '', // 表 头名
lang: 'zh', // 中文
showtoolbar: true, // 是否显示工具栏
showinfobar: false, // 是否显示顶部信息栏
showsheetbar: true, // 是否显示底部sheet按钮
data: [
{
name: 'Cell',
index: 0,
defaultRowHeight: 27,
defaultColWidth: 105,
chart: [] //图表配置
}
]
})
// 加载luckysheet
const info = () => {
luckysheet.create(options.value)
}
//绑定value
const setValue = (e: any) => {
let data = luckysheet.getRange()
luckysheet.setCellValue(
data[0].row[0],
data[0].column[0],
{
v: e[e.length - 1],
tr: e
}
// checkedNodes[0].data.label
)
}
// 下载表格
const downloadExcel = () => {
exportExcel(luckysheet.getAllSheets(), '报表模板')
}
// 导入
const beforeUpload = (file: any) => {
LuckyExcel.transformExcelToLucky(file.raw, function (exportJson: any) {
if (exportJson.sheets == null || exportJson.sheets.length == 0) {
ElMessage.warning('读取excel文件内容失败,目前只能上传xlsx文件!')
return
}
luckysheet.destroy()
options.value.title = exportJson.info.name
// console.log('🚀 ~ exportJson.sheets:', exportJson.sheets)
exportJson.sheets.forEach((item: any) => {
// item.celldata = []
// item.data = []
item.celldata.forEach((k: any) => {
k.v.ct.s ? (k.v.v = k.v.ct.s[0].v) : ''
k.v.ct.s ? (k.v.m = k.v.ct.s[0].v) : ''
})
})
options.value.data = exportJson.sheets
luckysheet.create(options.value)
})
}
// 保存
const preservation = () => {
formFer.value.open(title.value, list.value)
}
// 新增
const submitForm = (formdata: any, text: string) => {
// let userStr = JSON.stringify(luckysheet.getAllSheets())
let userStr = luckysheet.getAllSheets()
// console.log('🚀 ~ submitForm ~ userStr:', userStr)
userStr.forEach((item: any) => {
item.data1 = JSON.stringify(item.data)
})
let blob = new Blob([JSON.stringify(userStr)], {
type: 'application/json;charset=UTF-8'
})
let files = new window.File([blob], 'content.json', {
type: 'application/json;charset=UTF-8'
})
let params = new FormData()
params.append('fileContent', files)
params.append('deptId', formdata.deptId)
params.append('valueTitle', formdata.deptId)
params.append('name', formdata.name)
params.append('reportType', formdata.reportType)
params.append('reportForm', formdata.reportForm)
ElMessage.info('正在保存请稍等!')
if (text == '新增报表模板') {
addTemplate(params).then(res => {
ElMessage.success('新增成功!')
formFer.value.shutDown()
emit('shutDown')
}).catch(err => {
ElMessage.error('保存失败!')
formFer.value.shutDown()
})
} else if (text == '编辑报表模板') {
params.append('id', list.value.id)
dateTemplateup(params).then(res => {
ElMessage.success('编辑成功!')
formFer.value.shutDown()
emit('shutDown')
}).catch(err => {
ElMessage.error('保存失败!')
formFer.value.shutDown()
})
}
}
const open = async (text: string, row?: any) => {
title.value = text
if (row) {
list.value = row
await viewCustomReportTemplateById({ id: row.id }).then(Response => {
options.value.data = Response
})
}
info()
}
defineExpose({ open })
onMounted(() => {})
</script>
<style lang="scss" scoped>
:deep(.el-tab-pane) {
padding: 10px;
}
</style>
<template>
<div class="default-main">
<div class="mb10" style="display: flex; justify-content: flex-end">
<el-upload
ref="upload"
action=""
:auto-upload="false"
:show-file-list="false"
:limit="1"
:on-change="beforeUpload"
>
<el-button icon="el-icon-Upload" type="primary" class="mr10">导入excel</el-button>
</el-upload>
<el-button @click="downloadExcel" class="" type="primary" icon="el-icon-Download">导出excel</el-button>
<el-button type="primary" icon="el-icon-Check" @click="preservation">保存</el-button>
<el-button icon="el-icon-Back" @click="emit('shutDown')">返回</el-button>
</div>
<div style="display: flex">
<div id="luckysheet" :style="{ height: height, flex: 1 }"></div>
<bind style="width: 500px" class="ml10" @setValue="setValue" />
</div>
<!-- 信息框 -->
<addForm ref="formFer" @submitForm="submitForm" />
</div>
</template>
<script setup lang="ts">
import { exportExcel } from './export.js'
import { mainHeight } from '@/utils/layout'
import LuckyExcel from 'luckyexcel'
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { addTemplate, dateTemplateup, viewCustomReportTemplateById } from '@/api/harmonic-boot/luckyexcel'
import bind from './bind.vue'
import addForm from './form.vue'
const emit = defineEmits(['shutDown'])
const formFer = ref()
const title = ref('')
const list = ref({})
const height = mainHeight(65).height
const options: any = ref({
container: 'luckysheet',
title: '', // 表 头名
lang: 'zh', // 中文
showtoolbar: true, // 是否显示工具栏
showinfobar: false, // 是否显示顶部信息栏
showsheetbar: true, // 是否显示底部sheet按钮
data: [
{
name: 'Cell',
index: 0,
defaultRowHeight: 27,
defaultColWidth: 105,
chart: [] //图表配置
}
]
})
// 加载luckysheet
const info = () => {
luckysheet.create(options.value)
}
//绑定value
const setValue = (e: any) => {
let data = luckysheet.getRange()
luckysheet.setCellValue(
data[0].row[0],
data[0].column[0],
{
v: e[e.length - 1],
tr: e
}
// checkedNodes[0].data.label
)
}
// 下载表格
const downloadExcel = () => {
exportExcel(luckysheet.getAllSheets(), '报表模板')
}
// 导入
const beforeUpload = (file: any) => {
LuckyExcel.transformExcelToLucky(file.raw, function (exportJson: any) {
if (exportJson.sheets == null || exportJson.sheets.length == 0) {
ElMessage.warning('读取excel文件内容失败,目前只能上传xlsx文件!')
return
}
luckysheet.destroy()
options.value.title = exportJson.info.name
// console.log('🚀 ~ exportJson.sheets:', exportJson.sheets)
exportJson.sheets.forEach((item: any) => {
// item.celldata = []
// item.data = []
item.celldata.forEach((k: any) => {
k.v.ct.s ? (k.v.v = k.v.ct.s[0].v) : ''
k.v.ct.s ? (k.v.m = k.v.ct.s[0].v) : ''
})
})
options.value.data = exportJson.sheets
luckysheet.create(options.value)
})
}
// 保存
const preservation = () => {
formFer.value.open(title.value, list.value)
}
// 新增
const submitForm = (formdata: any, text: string) => {
// let userStr = JSON.stringify(luckysheet.getAllSheets())
let userStr = luckysheet.getAllSheets()
// console.log('🚀 ~ submitForm ~ userStr:', userStr)
userStr.forEach((item: any) => {
item.data1 = JSON.stringify(item.data)
})
let blob = new Blob([JSON.stringify(userStr)], {
type: 'application/json;charset=UTF-8'
})
let files = new window.File([blob], 'content.json', {
type: 'application/json;charset=UTF-8'
})
let params = new FormData()
params.append('fileContent', files)
params.append('deptId', formdata.deptId)
params.append('valueTitle', formdata.deptId)
params.append('name', formdata.name)
params.append('reportType', formdata.reportType)
params.append('reportForm', formdata.reportForm)
ElMessage.info('正在保存请稍等!')
if (text == '新增报表模板') {
addTemplate(params).then(res => {
ElMessage.success('新增成功!')
formFer.value.shutDown()
emit('shutDown')
}).catch(err => {
ElMessage.error('保存失败!')
formFer.value.shutDown()
})
} else if (text == '编辑报表模板') {
params.append('id', list.value.id)
dateTemplateup(params).then(res => {
ElMessage.success('编辑成功!')
formFer.value.shutDown()
emit('shutDown')
}).catch(err => {
ElMessage.error('保存失败!')
formFer.value.shutDown()
})
}
}
const open = async (text: string, row?: any) => {
title.value = text
if (row) {
list.value = row
await viewCustomReportTemplateById({ id: row.id }).then(Response => {
options.value.data = Response
})
}
info()
}
defineExpose({ open })
onMounted(() => {})
</script>
<style lang="scss" scoped>
:deep(.el-tab-pane) {
padding: 10px;
}
</style>