|
|
|
<template>
|
|
|
|
<div class="device-info-wrap">
|
|
|
|
<div class="left-wrap">
|
|
|
|
<EdfsWrap class="chart-box" title="设备概览">
|
|
|
|
<PieChart :data="pieData" />
|
|
|
|
</EdfsWrap>
|
|
|
|
<div class="filter">
|
|
|
|
<LeftFilter @search="onSearch" :categoryTreeData="categoryTreeData" />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<EdfsWrap title="设备信息列表" class="device-info-table">
|
|
|
|
<template #title-right>
|
|
|
|
<!-- <EdfsButton type="primary" inner-text="新增设备" @click="addDevice" /> -->
|
|
|
|
</template>
|
|
|
|
<EdfsTable
|
|
|
|
class="table"
|
|
|
|
v-loading="loading"
|
|
|
|
:data="list"
|
|
|
|
ref="tableRef"
|
|
|
|
:highlight-current-row="true"
|
|
|
|
:page-total="total"
|
|
|
|
:current-page="queryParams.pageNo"
|
|
|
|
:page-size="queryParams.pageSize"
|
|
|
|
row-class-name="row"
|
|
|
|
@pageCurrentChange="handleJump"
|
|
|
|
>
|
|
|
|
<template v-for="(col, idx) in deviceTableCol" :key="idx">
|
|
|
|
<el-table-column
|
|
|
|
v-if="col.prop.endsWith('Time')"
|
|
|
|
:label="col.label"
|
|
|
|
:min-width="col.minWidth"
|
|
|
|
>
|
|
|
|
<template #default="scope">
|
|
|
|
{{ dayjs(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
|
|
|
|
</template>
|
|
|
|
</el-table-column>
|
|
|
|
<el-table-column
|
|
|
|
v-else-if="col.prop === 'status'"
|
|
|
|
:prop="col.prop"
|
|
|
|
:label="col.label"
|
|
|
|
:min-width="col.minWidth"
|
|
|
|
>
|
|
|
|
<template #default="scope">
|
|
|
|
{{ DeviceStatus[scope.row.status] }}
|
|
|
|
</template>
|
|
|
|
</el-table-column>
|
|
|
|
<el-table-column
|
|
|
|
v-else
|
|
|
|
:prop="col.prop"
|
|
|
|
:label="col.label"
|
|
|
|
:min-width="col.minWidth"
|
|
|
|
/>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<el-table-column label="操作" width="210" align="center">
|
|
|
|
<template #default="scope">
|
|
|
|
<EdfsButton
|
|
|
|
link
|
|
|
|
type="primary"
|
|
|
|
inner-text="查看"
|
|
|
|
@click="onView(scope.row)"
|
|
|
|
/><el-divider direction="vertical" />
|
|
|
|
<el-dropdown @command="command => handleCommand(command, scope.row)">
|
|
|
|
<el-button type="primary" link
|
|
|
|
><Icon icon="ep:d-arrow-right" /> 更多</el-button
|
|
|
|
>
|
|
|
|
<template #dropdown>
|
|
|
|
<el-dropdown-menu>
|
|
|
|
<el-dropdown-item command="info">
|
|
|
|
<Icon icon="solar:clapperboard-edit-linear" />编辑基础信息
|
|
|
|
</el-dropdown-item>
|
|
|
|
<el-dropdown-item command="test" v-if="scope.row.status === 1">
|
|
|
|
<Icon icon="solar:document-add-outline" />测试结果录入
|
|
|
|
</el-dropdown-item>
|
|
|
|
<el-dropdown-item command="delivery" v-if="scope.row.status === 2">
|
|
|
|
<Icon icon="solar:inbox-out-outline" />出库
|
|
|
|
</el-dropdown-item>
|
|
|
|
<el-dropdown-item command="printLabel" v-if="scope.row.status >= 1">
|
|
|
|
<Icon icon="solar:printer-outline" />
|
|
|
|
打印标签
|
|
|
|
</el-dropdown-item>
|
|
|
|
<el-dropdown-item command="printReport" v-if="scope.row.status >= 2">
|
|
|
|
<Icon icon="solar:printer-outline" />
|
|
|
|
打印测试报告
|
|
|
|
</el-dropdown-item>
|
|
|
|
|
|
|
|
<el-dropdown-item command="maintain" v-if="scope.row.status >= 3">
|
|
|
|
<Icon icon="solar:minimalistic-magnifer-bug-outline" />设备报修
|
|
|
|
</el-dropdown-item>
|
|
|
|
</el-dropdown-menu>
|
|
|
|
</template>
|
|
|
|
</el-dropdown>
|
|
|
|
</template>
|
|
|
|
</el-table-column>
|
|
|
|
</EdfsTable>
|
|
|
|
</EdfsWrap>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
import dayjs from 'dayjs'
|
|
|
|
import LeftFilter from './components/data-filter.vue'
|
|
|
|
import EdfsWrap from '@/components/dashboard/Edfs-wrap.vue'
|
|
|
|
import EdfsTable from '@/components/dashboard/Edfs-table/index.vue'
|
|
|
|
import EdfsButton from '@/components/dashboard/Edfs-button/index.vue'
|
|
|
|
import { isResError } from '@/hooks/useMessage'
|
|
|
|
import type { TableColumnCtx } from 'element-plus'
|
|
|
|
import { useRouter, useRoute } from 'vue-router'
|
|
|
|
import PieChart from './components/pie-chart.vue'
|
|
|
|
import {
|
|
|
|
getDeviceLabelBase64,
|
|
|
|
getDevicePage,
|
|
|
|
getDeviceSummaryByStatus,
|
|
|
|
getDeviceReportPDF,
|
|
|
|
type IDevice,
|
|
|
|
getDeviceInfo,
|
|
|
|
} from '@/api/module/eam/device'
|
|
|
|
import { ElLoading } from 'element-plus'
|
|
|
|
import { deviceTableCol, DeviceStatus } from './utils'
|
|
|
|
import { getCategoryTree, type ICategoryTree } from '@/api/module/eam/device/category'
|
|
|
|
import jsPDF from 'jspdf'
|
|
|
|
|
|
|
|
defineOptions({
|
|
|
|
name: 'DeviceList',
|
|
|
|
})
|
|
|
|
const route = useRoute()
|
|
|
|
// 将 updateId 转换为 number 类型,如果不存在则为 undefined
|
|
|
|
const updateId = ref<number | undefined>(
|
|
|
|
route.query.updateId !== undefined && route.query.updateId !== null
|
|
|
|
? Number(route.query.updateId)
|
|
|
|
: undefined
|
|
|
|
)
|
|
|
|
|
|
|
|
onActivated(async () => {
|
|
|
|
await nextTick()
|
|
|
|
const index = list.value.findIndex(r => r.id === updateId.value)
|
|
|
|
if (updateId.value && index !== -1) {
|
|
|
|
const res = await getDeviceInfo(updateId.value)
|
|
|
|
if (!isResError(res)) {
|
|
|
|
list.value[index] = res.data
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
const loading = ref(true)
|
|
|
|
const total = ref(0)
|
|
|
|
const list = ref<IDevice[]>([])
|
|
|
|
const queryParams = reactive({
|
|
|
|
pageNo: 1,
|
|
|
|
pageSize: undefined,
|
|
|
|
// serialNo: undefined,
|
|
|
|
// name: undefined,
|
|
|
|
// status: undefined,
|
|
|
|
// categoryId: [],
|
|
|
|
// createTime: [],
|
|
|
|
})
|
|
|
|
const tableRef = ref()
|
|
|
|
const getList = async () => {
|
|
|
|
if (!queryParams.pageSize) {
|
|
|
|
queryParams.pageSize = tableRef.value.getSize()
|
|
|
|
}
|
|
|
|
loading.value = true
|
|
|
|
|
|
|
|
const options = Object.assign({}, queryParams, filter.value)
|
|
|
|
|
|
|
|
const res = await getDevicePage(options)
|
|
|
|
|
|
|
|
if (!isResError(res)) {
|
|
|
|
list.value = res.data.list
|
|
|
|
total.value = res.data.total
|
|
|
|
}
|
|
|
|
|
|
|
|
loading.value = false
|
|
|
|
}
|
|
|
|
|
|
|
|
function handleJump(page: number) {
|
|
|
|
queryParams.pageNo = page
|
|
|
|
getList()
|
|
|
|
}
|
|
|
|
|
|
|
|
const filter = ref<any>({})
|
|
|
|
function onSearch(search: any) {
|
|
|
|
queryParams.pageNo = 1
|
|
|
|
filter.value = search
|
|
|
|
getList()
|
|
|
|
}
|
|
|
|
|
|
|
|
const categoryTreeData = ref<ICategoryTree[]>([])
|
|
|
|
async function loadDeviceTypeTree() {
|
|
|
|
const res = await getCategoryTree()
|
|
|
|
if (!isResError(res)) {
|
|
|
|
categoryTreeData.value = res.data
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
interface SpanMethodProps {
|
|
|
|
row: any
|
|
|
|
column: TableColumnCtx<any>
|
|
|
|
rowIndex: number
|
|
|
|
columnIndex: number
|
|
|
|
}
|
|
|
|
|
|
|
|
const formRef = ref()
|
|
|
|
const openForm = (type: string, id?: number) => {}
|
|
|
|
onMounted(() => {
|
|
|
|
getList()
|
|
|
|
loadDeviceTypeTree()
|
|
|
|
})
|
|
|
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
|
|
|
function editDevice(row: any, type: string) {
|
|
|
|
router.push({
|
|
|
|
path: '/device/deviceOperation',
|
|
|
|
query: { action: 'update', type, id: row.id },
|
|
|
|
})
|
|
|
|
}
|
|
|
|
function addDevice() {
|
|
|
|
router.push({ path: '/device/deviceOperation', query: { action: 'create' } })
|
|
|
|
}
|
|
|
|
function onView(row: any) {
|
|
|
|
router.push({ path: '/device/deviceOperation', query: { action: 'view', id: row.id } })
|
|
|
|
}
|
|
|
|
|
|
|
|
async function onPrint(row: any) {
|
|
|
|
setLoadingPrint()
|
|
|
|
const res = await getDeviceLabelBase64(row.id)
|
|
|
|
closeLoadingPrint()
|
|
|
|
if (isResError(res)) return
|
|
|
|
const pdf = new jsPDF({
|
|
|
|
orientation: 'l',
|
|
|
|
unit: 'mm',
|
|
|
|
format: [60, 40],
|
|
|
|
})
|
|
|
|
|
|
|
|
const imgData = res.data
|
|
|
|
const imgWidth = 60
|
|
|
|
const imgHeight = 40
|
|
|
|
// const isEdge = navigator.userAgent.indexOf('Edg') !== -1
|
|
|
|
// if (isEdge) {
|
|
|
|
// pdf.addImage(imgData, 'PNG', 2, -2, imgWidth, imgHeight)
|
|
|
|
// } else {
|
|
|
|
pdf.addImage(imgData, 'PNG', 2, -2, imgWidth, imgHeight)
|
|
|
|
// }
|
|
|
|
|
|
|
|
pdf.autoPrint()
|
|
|
|
window.open(pdf.output('bloburl'), '_blank')
|
|
|
|
}
|
|
|
|
|
|
|
|
const loadingPrint = ref<any>()
|
|
|
|
function setLoadingPrint() {
|
|
|
|
loadingPrint.value = ElLoading.service({
|
|
|
|
lock: true,
|
|
|
|
text: '打印中请稍等...',
|
|
|
|
spinner: 'el-icon-loading',
|
|
|
|
background: 'rgba(0, 0, 0, 0.7)',
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
function closeLoadingPrint() {
|
|
|
|
loadingPrint.value.close()
|
|
|
|
}
|
|
|
|
|
|
|
|
async function onPrintReport(row: any) {
|
|
|
|
setLoadingPrint()
|
|
|
|
const res = await getDeviceReportPDF(row.id)
|
|
|
|
closeLoadingPrint()
|
|
|
|
if (isResError(res)) return
|
|
|
|
const pdfURL = URL.createObjectURL(res.data)
|
|
|
|
const printWindow = window.open(pdfURL) as any
|
|
|
|
printWindow.onload = () => {
|
|
|
|
printWindow.print()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function handleCommand(command: string, row: any) {
|
|
|
|
if (command === 'printReport') {
|
|
|
|
onPrintReport(row)
|
|
|
|
return
|
|
|
|
} else if (command === 'printLabel') {
|
|
|
|
onPrint(row)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
editDevice(row, command)
|
|
|
|
}
|
|
|
|
|
|
|
|
const pieData = ref<any>([])
|
|
|
|
async function loadPieChartData() {
|
|
|
|
const res = await getDeviceSummaryByStatus()
|
|
|
|
if (isResError(res)) return
|
|
|
|
pieData.value = res.data.map((item: any) => {
|
|
|
|
return {
|
|
|
|
name: item.statusName,
|
|
|
|
value: item.count,
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
onMounted(() => {
|
|
|
|
loadPieChartData()
|
|
|
|
})
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.device-info-wrap {
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
display: flex;
|
|
|
|
column-gap: 12px;
|
|
|
|
box-sizing: border-box;
|
|
|
|
.left-wrap {
|
|
|
|
width: 280px;
|
|
|
|
min-width: 100px;
|
|
|
|
height: 100%;
|
|
|
|
background: var(--warp-bg);
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
.station {
|
|
|
|
position: relative;
|
|
|
|
height: 60px;
|
|
|
|
padding-left: 20px;
|
|
|
|
border-bottom: 1px solid var(--pagination-border-color);
|
|
|
|
:deep(.el-input__inner) {
|
|
|
|
color: #666;
|
|
|
|
}
|
|
|
|
|
|
|
|
:deep(.el-input__wrapper) {
|
|
|
|
padding: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
:deep(.el-input__suffix) {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.chart-box {
|
|
|
|
height: 300px;
|
|
|
|
}
|
|
|
|
.filter {
|
|
|
|
height: calc(100% - 300px);
|
|
|
|
overflow: hidden;
|
|
|
|
}
|
|
|
|
:deep(.edfs-wrap) {
|
|
|
|
box-shadow: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.device-info-table {
|
|
|
|
flex: 1;
|
|
|
|
.table {
|
|
|
|
height: 100%;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|