You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
325 lines
8.6 KiB
325 lines
8.6 KiB
<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" v-if="scope.row.status < 2"> |
|
<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 } from 'vue-router' |
|
import PieChart from './components/pie-chart.vue' |
|
import { |
|
getDeviceLabelBase64, |
|
getDevicePage, |
|
getDeviceSummaryByStatus, |
|
getDeviceReportPDF, |
|
type IDevice, |
|
} 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' |
|
|
|
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('l', 'mm', [60, 40]) |
|
|
|
const imgData = res.data |
|
const imgWidth = 60 |
|
const imgHeight = 40 |
|
|
|
pdf.addImage(imgData, 'JPEG', 0, 0, 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 |
|
} |
|
debugger |
|
|
|
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>
|
|
|