|
@@ -1,17 +1,9 @@
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
import dayjs from 'dayjs'
|
|
import dayjs from 'dayjs'
|
|
|
-import { IotRdDailyReportApi } from '@/api/pms/iotrddailyreport'
|
|
|
|
|
-import { useDebounceFn } from '@vueuse/core'
|
|
|
|
|
-import CountTo from '@/components/count-to1.vue'
|
|
|
|
|
-import * as echarts from 'echarts'
|
|
|
|
|
-
|
|
|
|
|
-import { Motion, AnimatePresence } from 'motion-v'
|
|
|
|
|
-
|
|
|
|
|
import { rangeShortcuts } from '@/utils/formatTime'
|
|
import { rangeShortcuts } from '@/utils/formatTime'
|
|
|
-
|
|
|
|
|
import { useUserStore } from '@/store/modules/user'
|
|
import { useUserStore } from '@/store/modules/user'
|
|
|
-import download from '@/utils/download'
|
|
|
|
|
-import { useTableComponents } from '@/components/ZmTable/useTableComponents'
|
|
|
|
|
|
|
+import DailyStatistics from './components/DailyStatistics.vue'
|
|
|
|
|
+import NonProductionEfficiency from './components/NonProductionEfficiency.vue'
|
|
|
|
|
|
|
|
const deptId = useUserStore().getUser.deptId
|
|
const deptId = useUserStore().getUser.deptId
|
|
|
|
|
|
|
@@ -26,441 +18,42 @@ interface Query {
|
|
|
|
|
|
|
|
const id = deptId
|
|
const id = deptId
|
|
|
|
|
|
|
|
-const query = ref<Query>({
|
|
|
|
|
|
|
+const createDefaultQuery = (): Query => ({
|
|
|
pageNo: 1,
|
|
pageNo: 1,
|
|
|
pageSize: 10,
|
|
pageSize: 10,
|
|
|
deptId: deptId,
|
|
deptId: deptId,
|
|
|
|
|
+ contractName: '',
|
|
|
|
|
+ taskName: '',
|
|
|
createTime: [
|
|
createTime: [
|
|
|
...rangeShortcuts[1].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
|
|
...rangeShortcuts[1].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
|
|
|
]
|
|
]
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
-const totalWorkKeys: [string, string | undefined, string, string, number][] = [
|
|
|
|
|
- [
|
|
|
|
|
- 'cumulativeBridgePlug',
|
|
|
|
|
- undefined,
|
|
|
|
|
- '桥塞',
|
|
|
|
|
- 'i-material-symbols:check-circle-outline-rounded text-emerald',
|
|
|
|
|
- 0
|
|
|
|
|
- ],
|
|
|
|
|
- [
|
|
|
|
|
- 'cumulativeRunCount',
|
|
|
|
|
- undefined,
|
|
|
|
|
- '趟数',
|
|
|
|
|
- 'i-material-symbols:check-circle-outline-rounded text-emerald',
|
|
|
|
|
- 0
|
|
|
|
|
- ],
|
|
|
|
|
- [
|
|
|
|
|
- 'cumulativeWorkingWell',
|
|
|
|
|
- undefined,
|
|
|
|
|
- '井数',
|
|
|
|
|
- 'i-material-symbols:check-circle-outline-rounded text-emerald',
|
|
|
|
|
- 0
|
|
|
|
|
- ],
|
|
|
|
|
- [
|
|
|
|
|
- 'cumulativeWorkingLayers',
|
|
|
|
|
- undefined,
|
|
|
|
|
- '段数',
|
|
|
|
|
- 'i-material-symbols:check-circle-outline-rounded text-emerald',
|
|
|
|
|
- 0
|
|
|
|
|
- ],
|
|
|
|
|
- [
|
|
|
|
|
- 'cumulativeHourCount',
|
|
|
|
|
- undefined,
|
|
|
|
|
- '小时(H)',
|
|
|
|
|
- 'i-material-symbols:nest-clock-farsight-analog-outline-rounded text-emerald',
|
|
|
|
|
- 2
|
|
|
|
|
- ],
|
|
|
|
|
- [
|
|
|
|
|
- 'cumulativeWaterVolume',
|
|
|
|
|
- '方',
|
|
|
|
|
- '水方量',
|
|
|
|
|
- 'i-material-symbols:water-drop-outline-rounded text-sky',
|
|
|
|
|
- 2
|
|
|
|
|
- ],
|
|
|
|
|
- ['taici', undefined, '台次', 'i-material-symbols:check-circle-outline-rounded text-emerald', 0],
|
|
|
|
|
- [
|
|
|
|
|
- 'utilizationRate',
|
|
|
|
|
- '%',
|
|
|
|
|
- '设备利用率',
|
|
|
|
|
- 'i-material-symbols:check-circle-outline-rounded text-emerald',
|
|
|
|
|
- 0
|
|
|
|
|
- ],
|
|
|
|
|
- [
|
|
|
|
|
- 'cumulativeFuels',
|
|
|
|
|
- '万升',
|
|
|
|
|
- '累计油耗',
|
|
|
|
|
- 'i-material-symbols:directions-car-outline-rounded text-sky',
|
|
|
|
|
- 2
|
|
|
|
|
- ]
|
|
|
|
|
-]
|
|
|
|
|
-
|
|
|
|
|
-const totalWork = ref({
|
|
|
|
|
- cumulativeFuels: 0,
|
|
|
|
|
- taici: 0,
|
|
|
|
|
- cumulativeBridgePlug: 0,
|
|
|
|
|
- cumulativeRunCount: 0,
|
|
|
|
|
- cumulativeWorkingWell: 0,
|
|
|
|
|
- cumulativeWorkingLayers: 0,
|
|
|
|
|
- cumulativeHourCount: 0,
|
|
|
|
|
- cumulativeWaterVolume: 0,
|
|
|
|
|
- utilizationRate: 0
|
|
|
|
|
-})
|
|
|
|
|
-
|
|
|
|
|
-const totalLoading = ref(false)
|
|
|
|
|
-
|
|
|
|
|
-const getTotal = useDebounceFn(async () => {
|
|
|
|
|
- totalLoading.value = true
|
|
|
|
|
-
|
|
|
|
|
- const { pageNo, pageSize, ...other } = query.value
|
|
|
|
|
-
|
|
|
|
|
- try {
|
|
|
|
|
- const res2 = await IotRdDailyReportApi.totalWorkload(other)
|
|
|
|
|
-
|
|
|
|
|
- totalWork.value = {
|
|
|
|
|
- ...totalWork.value,
|
|
|
|
|
- taici: res2.taici || 0,
|
|
|
|
|
- cumulativeBridgePlug: res2.cumulativeBridgePlug || 0,
|
|
|
|
|
- cumulativeRunCount: res2.cumulativeRunCount || 0,
|
|
|
|
|
- cumulativeWorkingWell: res2.cumulativeWorkingWell || 0,
|
|
|
|
|
- cumulativeWorkingLayers: res2.cumulativeWorkingLayers || 0,
|
|
|
|
|
- cumulativeHourCount: res2.cumulativeHourCount || 0,
|
|
|
|
|
- cumulativeWaterVolume: res2.cumulativeWaterVolume || 0,
|
|
|
|
|
- ...res2,
|
|
|
|
|
- cumulativeFuels: (res2.cumulativeFuels || 0) / 10000,
|
|
|
|
|
- utilizationRate: Number(((res2.utilizationRate || 0) * 100).toFixed(2))
|
|
|
|
|
- }
|
|
|
|
|
- } finally {
|
|
|
|
|
- totalLoading.value = false
|
|
|
|
|
- }
|
|
|
|
|
-}, 500)
|
|
|
|
|
-
|
|
|
|
|
-interface List {
|
|
|
|
|
- id: number | null
|
|
|
|
|
- name: string | null
|
|
|
|
|
- type: '1' | '2' | '3'
|
|
|
|
|
- cumulativeBridgePlug: number | null
|
|
|
|
|
- cumulativeRunCount: number | null
|
|
|
|
|
- cumulativeWorkingWell: number | null
|
|
|
|
|
- cumulativeHourCount: number | null
|
|
|
|
|
- totalDailyFuel: number | null
|
|
|
|
|
- cumulativeWaterVolume: number | null
|
|
|
|
|
- cumulativeWorkingLayers: number | null
|
|
|
|
|
- cumulativePumpTrips: number | null
|
|
|
|
|
- cumulativeMixSand: number | null
|
|
|
|
|
- utilizationRate: number | null
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-const list = ref<List[]>([])
|
|
|
|
|
-
|
|
|
|
|
-const type = ref('2')
|
|
|
|
|
-
|
|
|
|
|
-const listLoading = ref(false)
|
|
|
|
|
-
|
|
|
|
|
-const getList = useDebounceFn(async () => {
|
|
|
|
|
- listLoading.value = true
|
|
|
|
|
- try {
|
|
|
|
|
- const res = await IotRdDailyReportApi.getIotRdDailyReportSummary(query.value)
|
|
|
|
|
-
|
|
|
|
|
- const { list: reslist } = res
|
|
|
|
|
-
|
|
|
|
|
- type.value = reslist[0]?.type || '2'
|
|
|
|
|
-
|
|
|
|
|
- list.value = reslist.map(
|
|
|
|
|
- ({ id, projectDeptId, projectDeptName, teamId, teamName, sort, taskId, type, ...other }) => {
|
|
|
|
|
- return {
|
|
|
|
|
- id: type === '2' ? projectDeptId : teamId,
|
|
|
|
|
- name: type === '2' ? projectDeptName : teamName,
|
|
|
|
|
- ...other,
|
|
|
|
|
- cumulativeBridgePlug: other.cumulativeBridgePlug || 0,
|
|
|
|
|
- cumulativeRunCount: other.cumulativeRunCount || 0,
|
|
|
|
|
- cumulativeWorkingWell: other.cumulativeWorkingWell || 0,
|
|
|
|
|
- cumulativeHourCount: other.cumulativeHourCount || 0,
|
|
|
|
|
- totalDailyFuel: other.totalDailyFuel || 0,
|
|
|
|
|
- cumulativeWaterVolume: other.cumulativeWaterVolume || 0,
|
|
|
|
|
- cumulativeWorkingLayers: other.cumulativeWorkingLayers || 0,
|
|
|
|
|
- cumulativePumpTrips: other.cumulativePumpTrips || 0,
|
|
|
|
|
- cumulativeMixSand: other.cumulativeMixSand || 0,
|
|
|
|
|
- utilizationRate: other.utilizationRate || 0
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
- } finally {
|
|
|
|
|
- listLoading.value = false
|
|
|
|
|
- }
|
|
|
|
|
-}, 500)
|
|
|
|
|
-
|
|
|
|
|
-const tab = ref<'表格' | '看板'>('表格')
|
|
|
|
|
-
|
|
|
|
|
-const currentTab = ref<'表格' | '看板'>('表格')
|
|
|
|
|
-
|
|
|
|
|
|
|
+const query = ref<Query>(createDefaultQuery())
|
|
|
|
|
+const activeTab = ref<'日报统计' | '非生产时效'>('日报统计')
|
|
|
const deptName = ref('四川瑞都')
|
|
const deptName = ref('四川瑞都')
|
|
|
-
|
|
|
|
|
-const direction = ref<'left' | 'right'>('right')
|
|
|
|
|
-
|
|
|
|
|
-const handleSelectTab = (val: '表格' | '看板') => {
|
|
|
|
|
- tab.value = val
|
|
|
|
|
- direction.value = val === '看板' ? 'right' : 'left'
|
|
|
|
|
- nextTick(() => {
|
|
|
|
|
- currentTab.value = val
|
|
|
|
|
- setTimeout(() => {
|
|
|
|
|
- render()
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-const chartRef = ref<HTMLDivElement | null>(null)
|
|
|
|
|
-let chart: echarts.ECharts | null = null
|
|
|
|
|
-
|
|
|
|
|
-const xAxisData = ref<string[]>([])
|
|
|
|
|
-
|
|
|
|
|
-const legend = ref<string[][]>([
|
|
|
|
|
- ['个数', 'cumulativeBridgePlug'],
|
|
|
|
|
- ['井数', 'cumulativeWorkingWell'],
|
|
|
|
|
- ['小时 (H)', 'cumulativeHourCount'],
|
|
|
|
|
- ['油耗 (万升)', 'cumulativeFuels'],
|
|
|
|
|
- ['水方量 (方)', 'cumulativeWaterVolume'],
|
|
|
|
|
- ['台次(泵车)', 'cumulativePumpTrips'],
|
|
|
|
|
- ['段数', 'cumulativeWorkingLayers'],
|
|
|
|
|
- ['台次(仪表/混砂)', 'cumulativeMixSand'],
|
|
|
|
|
- ['设备利用率 (%)', 'utilizationRate']
|
|
|
|
|
-])
|
|
|
|
|
-
|
|
|
|
|
-const chartData = ref<Record<string, number[]>>({
|
|
|
|
|
- cumulativeFuelConsumption: [],
|
|
|
|
|
- cumulativeGasInjection: [],
|
|
|
|
|
- cumulativePowerConsumption: [],
|
|
|
|
|
- cumulativeWaterInjection: [],
|
|
|
|
|
- transitTime: [],
|
|
|
|
|
- utilizationRate: []
|
|
|
|
|
-})
|
|
|
|
|
-
|
|
|
|
|
-let chartLoading = ref(false)
|
|
|
|
|
-
|
|
|
|
|
-const getChart = useDebounceFn(async () => {
|
|
|
|
|
- chartLoading.value = true
|
|
|
|
|
-
|
|
|
|
|
- try {
|
|
|
|
|
- const res = await IotRdDailyReportApi.getIotRdDailyReportSummaryPolyline(query.value)
|
|
|
|
|
-
|
|
|
|
|
- chartData.value = {
|
|
|
|
|
- cumulativeBridgePlug: res.map((item) => item.cumulativeBridgePlug || 0),
|
|
|
|
|
- cumulativeWorkingWell: res.map((item) => item.cumulativeWorkingWell || 0),
|
|
|
|
|
- cumulativeHourCount: res.map((item) => item.cumulativeHourCount || 0),
|
|
|
|
|
- cumulativeFuels: res.map((item) => (item.cumulativeFuels || 0) / 10000),
|
|
|
|
|
- cumulativeWaterVolume: res.map((item) => item.cumulativeWaterVolume || 0),
|
|
|
|
|
- cumulativeWorkingLayers: res.map((item) => item.cumulativeWorkingLayers || 0),
|
|
|
|
|
- cumulativePumpTrips: res.map((item) => item.cumulativePumpTrips || 0),
|
|
|
|
|
- cumulativeMixSand: res.map((item) => item.cumulativeMixSand || 0),
|
|
|
|
|
- utilizationRate: res.map((item) => Number(((item.utilizationRate || 0) * 100).toFixed(2)))
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- xAxisData.value = res.map((item) => item.reportDate || '')
|
|
|
|
|
- } finally {
|
|
|
|
|
- chartLoading.value = false
|
|
|
|
|
- }
|
|
|
|
|
-}, 500)
|
|
|
|
|
-
|
|
|
|
|
-const resizer = () => {
|
|
|
|
|
- chart?.resize()
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-onUnmounted(() => {
|
|
|
|
|
- window.removeEventListener('resize', resizer)
|
|
|
|
|
-})
|
|
|
|
|
-
|
|
|
|
|
-const render = () => {
|
|
|
|
|
- if (!chartRef.value) return
|
|
|
|
|
-
|
|
|
|
|
- chart = echarts.init(chartRef.value, undefined, { renderer: 'canvas' })
|
|
|
|
|
-
|
|
|
|
|
- window.addEventListener('resize', resizer)
|
|
|
|
|
-
|
|
|
|
|
- const values: number[] = []
|
|
|
|
|
-
|
|
|
|
|
- for (const [_name, key] of legend.value) {
|
|
|
|
|
- values.push(...(chartData.value[key] || []))
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- const maxVal = values.length === 0 ? 10000 : Math.max(...values)
|
|
|
|
|
- const minVal = values.length === 0 ? 0 : Math.min(...values) > 0 ? 0 : Math.min(...values)
|
|
|
|
|
-
|
|
|
|
|
- const maxDigits = (Math.floor(maxVal) + '').length
|
|
|
|
|
- const minDigits = minVal === 0 ? 0 : (Math.floor(Math.abs(minVal)) + '').length
|
|
|
|
|
- const interval = Math.max(maxDigits, minDigits)
|
|
|
|
|
-
|
|
|
|
|
- const maxInterval = interval
|
|
|
|
|
- const minInterval = minDigits
|
|
|
|
|
-
|
|
|
|
|
- const intervalArr = [0]
|
|
|
|
|
- for (let i = 1; i <= interval; i++) {
|
|
|
|
|
- intervalArr.push(Math.pow(10, i))
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- chart.setOption({
|
|
|
|
|
- tooltip: {
|
|
|
|
|
- trigger: 'axis',
|
|
|
|
|
- axisPointer: {
|
|
|
|
|
- type: 'line'
|
|
|
|
|
- },
|
|
|
|
|
- formatter: (params) => {
|
|
|
|
|
- let d = `${params[0].axisValueLabel}<br>`
|
|
|
|
|
- let item = params.map((el) => {
|
|
|
|
|
- return `<div class="flex items-center justify-between mt-1 gap-1">
|
|
|
|
|
- <span>${el.marker} ${el.seriesName}</span>
|
|
|
|
|
- <span>${chartData.value[legend.value[el.componentIndex][1]][el.dataIndex].toFixed(2)} ${el.seriesName.split(' ')[1] ?? ''}</span>
|
|
|
|
|
- </div>`
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- return d + item.join('')
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- legend: {
|
|
|
|
|
- data: legend.value.map(([name]) => name),
|
|
|
|
|
- show: true
|
|
|
|
|
- },
|
|
|
|
|
- xAxis: {
|
|
|
|
|
- type: 'category',
|
|
|
|
|
- data: xAxisData.value
|
|
|
|
|
- },
|
|
|
|
|
- yAxis: {
|
|
|
|
|
- type: 'value',
|
|
|
|
|
- min: -minInterval,
|
|
|
|
|
- max: maxInterval,
|
|
|
|
|
- interval: 1,
|
|
|
|
|
- axisLabel: {
|
|
|
|
|
- formatter: (v) => {
|
|
|
|
|
- const num = v === 0 ? 0 : v > 0 ? Math.pow(10, v) : -Math.pow(10, -v)
|
|
|
|
|
-
|
|
|
|
|
- return num.toLocaleString()
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- series: legend.value.map(([name, key]) => ({
|
|
|
|
|
- name,
|
|
|
|
|
- type: 'line',
|
|
|
|
|
- smooth: true,
|
|
|
|
|
- showSymbol: true,
|
|
|
|
|
- data: chartData.value[key].map((value) => {
|
|
|
|
|
- if (value === 0) return 0
|
|
|
|
|
-
|
|
|
|
|
- const isPositive = value > 0
|
|
|
|
|
- const absItem = Math.abs(value)
|
|
|
|
|
-
|
|
|
|
|
- const min_value = Math.max(...intervalArr.filter((v) => v <= absItem))
|
|
|
|
|
- const min_index = intervalArr.findIndex((v) => v === min_value)
|
|
|
|
|
-
|
|
|
|
|
- const new_value =
|
|
|
|
|
- (absItem - min_value) / (intervalArr[min_index + 1] - intervalArr[min_index]) + min_index
|
|
|
|
|
-
|
|
|
|
|
- return isPositive ? new_value : -new_value
|
|
|
|
|
- })
|
|
|
|
|
- }))
|
|
|
|
|
- })
|
|
|
|
|
-}
|
|
|
|
|
|
|
+const refreshKey = ref(0)
|
|
|
|
|
|
|
|
const handleDeptNodeClick = (node: any) => {
|
|
const handleDeptNodeClick = (node: any) => {
|
|
|
deptName.value = node.name
|
|
deptName.value = node.name
|
|
|
handleQuery()
|
|
handleQuery()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const handleQuery = (setPage = true) => {
|
|
|
|
|
- if (setPage) {
|
|
|
|
|
- query.value.pageNo = 1
|
|
|
|
|
- }
|
|
|
|
|
- getChart().then(() => {
|
|
|
|
|
- render()
|
|
|
|
|
- })
|
|
|
|
|
- getList()
|
|
|
|
|
- getTotal()
|
|
|
|
|
|
|
+const handleQuery = () => {
|
|
|
|
|
+ query.value.pageNo = 1
|
|
|
|
|
+ refreshKey.value += 1
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const resetQuery = () => {
|
|
const resetQuery = () => {
|
|
|
- query.value = {
|
|
|
|
|
- pageNo: 1,
|
|
|
|
|
- pageSize: 10,
|
|
|
|
|
- deptId: deptId,
|
|
|
|
|
- contractName: '',
|
|
|
|
|
- taskName: '',
|
|
|
|
|
- createTime: [
|
|
|
|
|
- ...rangeShortcuts[1].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
|
|
|
|
|
- ]
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ query.value = createDefaultQuery()
|
|
|
|
|
+ deptName.value = '四川瑞都'
|
|
|
handleQuery()
|
|
handleQuery()
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-watch(
|
|
|
|
|
- () => query.value.createTime,
|
|
|
|
|
- () => {
|
|
|
|
|
- handleQuery(false)
|
|
|
|
|
- }
|
|
|
|
|
-)
|
|
|
|
|
-
|
|
|
|
|
-watch([() => query.value.contractName, () => query.value.taskName], () => {
|
|
|
|
|
- handleQuery(false)
|
|
|
|
|
-})
|
|
|
|
|
-
|
|
|
|
|
-onMounted(() => {
|
|
|
|
|
- handleQuery()
|
|
|
|
|
-})
|
|
|
|
|
-
|
|
|
|
|
-const exportChart = () => {
|
|
|
|
|
- if (!chart) return
|
|
|
|
|
- let img = new Image()
|
|
|
|
|
- img.src = chart.getDataURL({
|
|
|
|
|
- type: 'png',
|
|
|
|
|
- pixelRatio: 1,
|
|
|
|
|
- backgroundColor: '#fff'
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- img.onload = function () {
|
|
|
|
|
- let canvas = document.createElement('canvas')
|
|
|
|
|
- canvas.width = img.width
|
|
|
|
|
- canvas.height = img.height
|
|
|
|
|
- let ctx = canvas.getContext('2d')
|
|
|
|
|
- ctx?.drawImage(img, 0, 0)
|
|
|
|
|
- let dataURL = canvas.toDataURL('image/png')
|
|
|
|
|
-
|
|
|
|
|
- let a = document.createElement('a')
|
|
|
|
|
-
|
|
|
|
|
- let event = new MouseEvent('click')
|
|
|
|
|
-
|
|
|
|
|
- a.href = dataURL
|
|
|
|
|
- a.download = `瑞恒日报统计数据.png`
|
|
|
|
|
- a.dispatchEvent(event)
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-const exportData = async () => {
|
|
|
|
|
- const res = await IotRdDailyReportApi.exportRdDailyReportStatistics(query.value)
|
|
|
|
|
- download.excel(res, '瑞都日报统计数据.xlsx')
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-const exportAll = async () => {
|
|
|
|
|
- if (tab.value === '看板') exportChart()
|
|
|
|
|
- else exportData()
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-const router = useRouter()
|
|
|
|
|
-
|
|
|
|
|
-const tolist = (id: number) => {
|
|
|
|
|
- const { pageNo, pageSize, ...rest } = query.value
|
|
|
|
|
-
|
|
|
|
|
- router.push({
|
|
|
|
|
- path: '/iotdayilyreport/IotRdDailyReport',
|
|
|
|
|
- query: {
|
|
|
|
|
- ...rest,
|
|
|
|
|
- deptId: id
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-const { ZmTable, ZmTableColumn } = useTableComponents()
|
|
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
<template>
|
|
|
<div
|
|
<div
|
|
|
- class="grid grid-cols-[auto_1fr] grid-rows-[62px_128px_1fr] gap-4 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
|
|
|
|
|
|
|
+ class="grid grid-cols-[auto_1fr] grid-rows-[62px_48px_1fr] gap-4 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
|
|
|
>
|
|
>
|
|
|
<DeptTreeSelect
|
|
<DeptTreeSelect
|
|
|
:deptId="id"
|
|
:deptId="id"
|
|
@@ -468,9 +61,6 @@ const { ZmTable, ZmTableColumn } = useTableComponents()
|
|
|
v-model="query.deptId"
|
|
v-model="query.deptId"
|
|
|
@node-click="handleDeptNodeClick"
|
|
@node-click="handleDeptNodeClick"
|
|
|
/>
|
|
/>
|
|
|
- <!-- <div class="p-4 bg-white dark:bg-[#1d1e1f] shadow rounded-lg row-span-3">
|
|
|
|
|
-
|
|
|
|
|
- </div> -->
|
|
|
|
|
<el-form
|
|
<el-form
|
|
|
size="default"
|
|
size="default"
|
|
|
class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-8 gap-8 flex items-center justify-between"
|
|
class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-8 gap-8 flex items-center justify-between"
|
|
@@ -514,116 +104,36 @@ const { ZmTable, ZmTableColumn } = useTableComponents()
|
|
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-form>
|
|
</el-form>
|
|
|
- <div class="grid grid-cols-9 gap-8">
|
|
|
|
|
- <div
|
|
|
|
|
- v-for="info in totalWorkKeys"
|
|
|
|
|
- :key="info[0]"
|
|
|
|
|
- class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow p-1 flex flex-col items-center justify-center gap-1"
|
|
|
|
|
- >
|
|
|
|
|
- <div class="size-7.5" :class="info[3]"></div>
|
|
|
|
|
- <count-to
|
|
|
|
|
- class="text-2xl font-medium"
|
|
|
|
|
- :start-val="0"
|
|
|
|
|
- :end-val="totalWork[info[0]]"
|
|
|
|
|
- :decimals="info[4]"
|
|
|
|
|
- >
|
|
|
|
|
- <span class="text-xs leading-8 text-[var(--el-text-color-regular)]">暂无数据</span>
|
|
|
|
|
- </count-to>
|
|
|
|
|
- <div class="text-sm font-medium text-[var(--el-text-color-regular)] whitespace-nowrap">
|
|
|
|
|
- {{ info[1] ? info[2] + '(' + info[1] + ')' : info[2] }}
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
|
|
|
- <div class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow flex flex-col p-4 gap-2">
|
|
|
|
|
- <div class="flex h-12 items-center justify-between">
|
|
|
|
|
- <el-button-group>
|
|
|
|
|
- <el-button
|
|
|
|
|
- size="default"
|
|
|
|
|
- :type="tab === '表格' ? 'primary' : 'default'"
|
|
|
|
|
- @click="handleSelectTab('表格')"
|
|
|
|
|
- >表格
|
|
|
|
|
- </el-button>
|
|
|
|
|
- <el-button
|
|
|
|
|
- size="default"
|
|
|
|
|
- :type="tab === '看板' ? 'primary' : 'default'"
|
|
|
|
|
- @click="handleSelectTab('看板')"
|
|
|
|
|
- >看板
|
|
|
|
|
- </el-button>
|
|
|
|
|
- </el-button-group>
|
|
|
|
|
- <h3 class="text-xl font-medium">{{ `${deptName}-${tab}` }}</h3>
|
|
|
|
|
- <el-button size="default" type="primary" @click="exportAll">导出</el-button>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="flex-1 relative">
|
|
|
|
|
- <el-auto-resizer class="absolute">
|
|
|
|
|
- <template #default="{ height }">
|
|
|
|
|
- <Motion
|
|
|
|
|
- as="div"
|
|
|
|
|
- :style="{ position: 'relative', overflow: 'hidden' }"
|
|
|
|
|
- :animate="{ height: `${height}px`, width: `100%` }"
|
|
|
|
|
- :transition="{ type: 'spring', stiffness: 200, damping: 25, duration: 0.3 }"
|
|
|
|
|
- >
|
|
|
|
|
- <AnimatePresence :initial="false" mode="sync">
|
|
|
|
|
- <Motion
|
|
|
|
|
- :key="currentTab"
|
|
|
|
|
- as="div"
|
|
|
|
|
- :initial="{ x: direction === 'left' ? '-100%' : '100%', opacity: 0 }"
|
|
|
|
|
- :animate="{ x: '0%', opacity: 1 }"
|
|
|
|
|
- :exit="{ x: direction === 'left' ? '50%' : '-50%', opacity: 0 }"
|
|
|
|
|
- :transition="{ type: 'tween', stiffness: 300, damping: 30, duration: 0.3 }"
|
|
|
|
|
- :style="{ position: 'absolute', left: 0, right: 0, top: 0 }"
|
|
|
|
|
- >
|
|
|
|
|
- <div :style="{ width: `100%`, height: `${height}px` }">
|
|
|
|
|
- <zm-table
|
|
|
|
|
- v-if="currentTab === '表格'"
|
|
|
|
|
- :loading="listLoading"
|
|
|
|
|
- :data="list"
|
|
|
|
|
- :height="height"
|
|
|
|
|
- show-border
|
|
|
|
|
- >
|
|
|
|
|
- <zm-table-column label="部门" prop="name">
|
|
|
|
|
- <template #default="{ row }">
|
|
|
|
|
- <el-button text type="primary" @click.prevent="tolist(row.id)">{{
|
|
|
|
|
- row.name
|
|
|
|
|
- }}</el-button>
|
|
|
|
|
- </template>
|
|
|
|
|
- </zm-table-column>
|
|
|
|
|
- <zm-table-column label="油耗(万升)" prop="totalDailyFuel" />
|
|
|
|
|
- <zm-table-column label="桥塞" prop="cumulativeBridgePlug" />
|
|
|
|
|
- <zm-table-column label="趟数" prop="cumulativeRunCount" />
|
|
|
|
|
- <zm-table-column label="井数" prop="cumulativeWorkingWell" />
|
|
|
|
|
- <zm-table-column label="段数" prop="cumulativeWorkingLayers" />
|
|
|
|
|
- <zm-table-column label="小时(H)" prop="cumulativeHourCount" />
|
|
|
|
|
- <zm-table-column label="水方量(方)" prop="cumulativeWaterVolume" />
|
|
|
|
|
- <zm-table-column label="台次">
|
|
|
|
|
- <zm-table-column label="泵车" prop="cumulativePumpTrips" />
|
|
|
|
|
- <zm-table-column label="仪表/混砂" prop="cumulativeMixSand" />
|
|
|
|
|
- </zm-table-column>
|
|
|
|
|
- <zm-table-column
|
|
|
|
|
- label="设备利用率"
|
|
|
|
|
- prop="utilizationRate"
|
|
|
|
|
- cover-formatter
|
|
|
|
|
- :real-value="
|
|
|
|
|
- (row: List) => (Number(row.utilizationRate ?? 0) * 100).toFixed(2) + '%'
|
|
|
|
|
- "
|
|
|
|
|
- />
|
|
|
|
|
- </zm-table>
|
|
|
|
|
- <div
|
|
|
|
|
- ref="chartRef"
|
|
|
|
|
- v-loading="chartLoading"
|
|
|
|
|
- :key="dayjs().valueOf()"
|
|
|
|
|
- v-else
|
|
|
|
|
- :style="{ width: `100%`, height: `${height}px` }"
|
|
|
|
|
- >
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- </Motion>
|
|
|
|
|
- </AnimatePresence>
|
|
|
|
|
- </Motion>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-auto-resizer>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <el-button-group class="justify-self-start self-center">
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ size="default"
|
|
|
|
|
+ :type="activeTab === '日报统计' ? 'primary' : 'default'"
|
|
|
|
|
+ @click="activeTab = '日报统计'"
|
|
|
|
|
+ >
|
|
|
|
|
+ 日报统计
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ size="default"
|
|
|
|
|
+ :type="activeTab === '非生产时效' ? 'primary' : 'default'"
|
|
|
|
|
+ @click="activeTab = '非生产时效'"
|
|
|
|
|
+ >
|
|
|
|
|
+ 非生产时效
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </el-button-group>
|
|
|
|
|
+
|
|
|
|
|
+ <DailyStatistics
|
|
|
|
|
+ v-if="activeTab === '日报统计'"
|
|
|
|
|
+ :query="query"
|
|
|
|
|
+ :dept-name="deptName"
|
|
|
|
|
+ :refresh-key="refreshKey"
|
|
|
|
|
+ />
|
|
|
|
|
+ <NonProductionEfficiency
|
|
|
|
|
+ v-else
|
|
|
|
|
+ :query="query"
|
|
|
|
|
+ :dept-name="deptName"
|
|
|
|
|
+ :refresh-key="refreshKey"
|
|
|
|
|
+ />
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|