<template>
|
<div class="app-container">
|
<!-- 搜索表单 -->
|
<el-form ref="queryForm" :model="queryParams" :inline="true" size="small">
|
<el-form-item label="设备编号" prop="deviceCode">
|
<el-input v-model="queryParams.deviceCode" placeholder="请输入设备编号" clearable style="width: 180px" @keyup.enter.native="handleQuery" />
|
</el-form-item>
|
<el-form-item label="设备名称" prop="deviceName">
|
<el-input v-model="queryParams.deviceName" placeholder="请输入设备名称" clearable style="width: 180px" @keyup.enter.native="handleQuery" />
|
</el-form-item>
|
<el-form-item label="使用人" prop="useUser">
|
<el-input v-model="queryParams.useUser" placeholder="请输入使用人" clearable style="width: 150px" @keyup.enter.native="handleQuery" />
|
</el-form-item>
|
<el-form-item label="使用周期" prop="timeRange">
|
<el-date-picker
|
v-model="timeRange"
|
type="daterange"
|
range-separator="-"
|
start-placeholder="开始时间"
|
end-placeholder="结束时间"
|
value-format="yyyy-MM-dd"
|
style="width: 240px"
|
/>
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" icon="el-icon-search" @click="handleQuery">查询</el-button>
|
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
|
<el-button type="success" icon="el-icon-download" @click="handleExport">导出</el-button>
|
</el-form-item>
|
</el-form>
|
|
<!-- 统计卡片 -->
|
<el-row :gutter="20" style="margin-bottom: 20px;">
|
<el-col :span="6">
|
<el-card shadow="hover">
|
<div class="stat-card">
|
<div class="stat-title">设备总数</div>
|
<div class="stat-value">{{ statistics.totalDevices || 0 }}</div>
|
</div>
|
</el-card>
|
</el-col>
|
<el-col :span="6">
|
<el-card shadow="hover">
|
<div class="stat-card">
|
<div class="stat-title">使用次数</div>
|
<div class="stat-value">{{ statistics.useCount || 0 }}</div>
|
</div>
|
</el-card>
|
</el-col>
|
<el-col :span="6">
|
<el-card shadow="hover">
|
<div class="stat-card">
|
<div class="stat-title">使用时长(h)</div>
|
<div class="stat-value">{{ statistics.useHours || 0 }}</div>
|
</div>
|
</el-card>
|
</el-col>
|
<el-col :span="6">
|
<el-card shadow="hover">
|
<div class="stat-card">
|
<div class="stat-title">利用率</div>
|
<div class="stat-value">{{ statistics.utilization || 0 }}%</div>
|
</div>
|
</el-card>
|
</el-col>
|
</el-row>
|
|
<!-- 使用频率图表 -->
|
<el-row :gutter="20" style="margin-bottom: 20px;">
|
<el-col :span="12">
|
<el-card shadow="hover">
|
<div slot="header">设备使用频率TOP10</div>
|
<Echart
|
:xAxis="useFrequencyXAxis"
|
:yAxis="useFrequencyYAxis"
|
:series="useFrequencySeries"
|
:tooltip="{ trigger: 'axis' }"
|
:grid="{ left: '3%', right: '4%', bottom: '3%', containLabel: true }"
|
:chartStyle="{ height: '300px' }"
|
/>
|
</el-card>
|
</el-col>
|
<el-col :span="12">
|
<el-card shadow="hover">
|
<div slot="header">设备使用趋势</div>
|
<Echart
|
:xAxis="useTrendXAxis"
|
:yAxis="useTrendYAxis"
|
:series="useTrendSeries"
|
:tooltip="{ trigger: 'axis' }"
|
:grid="{ left: '3%', right: '4%', bottom: '3%', containLabel: true }"
|
:chartStyle="{ height: '300px' }"
|
/>
|
</el-card>
|
</el-col>
|
</el-row>
|
|
<!-- 数据表格 -->
|
<lims-table
|
:tableData="tableData"
|
:column="tableColumn"
|
:page="page"
|
:tableLoading="tableLoading"
|
@pagination="handlePagination"
|
/>
|
</div>
|
</template>
|
|
<script>
|
import Echart from '@/components/echarts/echarts.vue'
|
import limsTable from '@/components/Table/lims-table.vue'
|
import { pageDeviceRecord, getDeviceStatistics, exportDeviceRecord } from '@/api/report/deviceRecord'
|
|
export default {
|
name: 'DeviceRecord',
|
components: { Echart, limsTable },
|
data() {
|
return {
|
queryParams: {},
|
timeRange: [],
|
tableData: [],
|
tableLoading: false,
|
statistics: {},
|
page: { total: 0, size: 10, current: 1 },
|
tableColumn: [
|
{ label: '设备编号', prop: 'deviceCode', minWidth: '120px' },
|
{ label: '设备名称', prop: 'deviceName', minWidth: '150px' },
|
{ label: '规格型号', prop: 'specModel', minWidth: '120px' },
|
{ label: '使用人', prop: 'useUser', minWidth: '80px' },
|
{ label: '开始时间', prop: 'startTime', minWidth: '160px' },
|
{ label: '结束时间', prop: 'endTime', minWidth: '160px' },
|
{ label: '使用时长(h)', prop: 'useHours', minWidth: '100px' },
|
{ label: '关联样品', prop: 'sampleCode', minWidth: '140px' },
|
{ label: '检测项目', prop: 'testItem', minWidth: '120px' },
|
{ label: '使用状态', prop: 'status', minWidth: '100px', dataType: 'tag', formatData: (val) => val === 1 ? '使用中' : '已结束', formatType: (val) => val === 1 ? 'warning' : 'success' }
|
],
|
// 使用频率图表
|
useFrequencyXAxis: [{ type: 'category', data: [], axisLabel: { rotate: 30 } }],
|
useFrequencyYAxis: [{ type: 'value' }],
|
useFrequencySeries: [{ name: '使用次数', type: 'bar', data: [] }],
|
// 使用趋势图表
|
useTrendXAxis: [{ type: 'category', data: [] }],
|
useTrendYAxis: [{ type: 'value' }],
|
useTrendSeries: [{ name: '使用时长', type: 'line', data: [] }]
|
}
|
},
|
mounted() {
|
this.getList()
|
this.getStatisticsData()
|
},
|
methods: {
|
getList() {
|
this.tableLoading = true
|
const params = { ...this.queryParams }
|
if (this.timeRange && this.timeRange.length === 2) {
|
params.startTime = this.timeRange[0]
|
params.endTime = this.timeRange[1]
|
}
|
pageDeviceRecord({ ...params, ...this.page })
|
.then(res => {
|
this.tableData = res.data.records || []
|
this.page.total = res.data.total || 0
|
})
|
.finally(() => (this.tableLoading = false))
|
},
|
getStatisticsData() {
|
const params = { ...this.queryParams }
|
if (this.timeRange && this.timeRange.length === 2) {
|
params.startTime = this.timeRange[0]
|
params.endTime = this.timeRange[1]
|
}
|
getDeviceStatistics(params).then(res => {
|
this.statistics = res.data.summary || {}
|
// 使用频率图表数据
|
this.useFrequencyXAxis[0].data = (res.data.frequencyData || []).map(item => item.deviceName)
|
this.useFrequencySeries[0].data = (res.data.frequencyData || []).map(item => item.count)
|
// 使用趋势图表数据
|
this.useTrendXAxis[0].data = (res.data.trendData || []).map(item => item.date)
|
this.useTrendSeries[0].data = (res.data.trendData || []).map(item => item.hours)
|
})
|
},
|
handleQuery() {
|
this.page.current = 1
|
this.getList()
|
this.getStatisticsData()
|
},
|
resetQuery() {
|
this.queryParams = {}
|
this.timeRange = []
|
this.handleQuery()
|
},
|
handleExport() {
|
const params = { ...this.queryParams }
|
if (this.timeRange && this.timeRange.length === 2) {
|
params.startTime = this.timeRange[0]
|
params.endTime = this.timeRange[1]
|
}
|
exportDeviceRecord(params).then(res => {
|
this.downloadFile(res, '设备使用记录.xlsx')
|
})
|
},
|
handlePagination({ page, limit }) {
|
this.page.current = page
|
this.page.size = limit
|
this.getList()
|
},
|
downloadFile(data, fileName) {
|
const blob = new Blob([data])
|
const url = window.URL.createObjectURL(blob)
|
const link = document.createElement('a')
|
link.href = url
|
link.download = fileName
|
link.click()
|
window.URL.revokeObjectURL(url)
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
.stat-card {
|
text-align: center;
|
padding: 15px 0;
|
}
|
.stat-title {
|
font-size: 14px;
|
color: #909399;
|
}
|
.stat-value {
|
font-size: 28px;
|
font-weight: bold;
|
color: #303133;
|
margin-top: 10px;
|
}
|
</style>
|