<script lang="ts" setup name="DeviceBench"> import { ref } from 'vue' import type { Ref } from 'vue' import type { DateModelType } from 'element-plus' import type { planReturn } from './bench-interface' import Linechart from '@/components/Echart/LineChart.vue' import type { lineDataI } from '@/components/Echart/echart-interface' import { getCustomerExpireData, getHighQualityCustomerList, getSampleAddData, getSampleExpireData } from '@/api/customer/bench' import { getSampleList } from '@/api/customer/sampleList' import type { IOvertimeListQuery } from '@/views/customer/sample/overTime/overtime_list_interface' import { getAdviceList } from '@/api/customer/advice' import type { IAdvice, IAdviceQuery } from '@/views/customer/advice/advice_interface' const reg = /(\d{4})\年(\d{2})月/ // 把2022年3月转为2022-03 // 每个展示块高度 const blockHeight = ref(300) const blockWidth = ref(400) // 到期样品查询条件 const dueSampleListQuery: Ref<IOvertimeListQuery> = ref({ sampleNo: '', // 样品编号 sampleName: '', // 样品名称 sampleModel: '', // 型号 customerNo: '', // 委托方代码 customerName: '', // 委托方名称 startTime: '', // 检定开始时间 endTime: '', // 检定结束时间 overtimeStatus: '1', // 样品超期状态 1已超期、0未超期、空字符串 已超期+未超期 offset: 1, limit: 20, }) // 客户关系查询条件 const customerRelationsListQuery: Ref<IAdviceQuery> = ref({ adviceNo: '', // 投诉编号 customerName: '', // 公司名称 customerNo: '', // 客户编号 startTime: '', // 投诉开始时间 endTime: '', // 投诉结束时间 offset: 1, limit: 20, }) const dueSampleTableLoading = ref(false) // 到期样品表格loading const customerRelationsTableLoading = ref(false) // 客户关系loading const sampleAddLoading = ref(false) // 样品新增趋势loading const customerAddLoading = ref(false) // 客户新增趋势loading const sampleExpireLoading = ref(false) // 样品到期趋势loading const highQualityCustomerLoading = ref(false) // 优质客户名单loading // 到期样品表格数据 const dueSampleTableData = ref() // 到期样品表头 const dueSampleTableHead = [ { text: '样品名称', value: 'sampleName' }, { text: '委托方名称', value: 'customerName', width: '120' }, { text: '上次检定时间', value: 'effectiveDate', width: '180' }, // 指证书出具时间 ] // 优质客户名单表中数据 const highQualityCustomerTableData = ref([]) // 优质客户名单表头 const highQualityCustomerTableHead = [ { text: '客户名称', value: 'customerName' }, { text: '总计检定金额', value: 'totalAmount' }, ] // 客户关系表中数据 const customerRelationsTabledata = ref([]) // 客户关系表头 const customerRelationsTableHead = [ { text: '客户名称', value: 'customerName' }, { text: '投诉/建议类型', value: 'adviceClass' }, { text: '投诉/建议时间', value: 'adviceTime', width: '180' }, ] // 样品新增趋势x轴 const sampleAddXData: Ref<string[]> = ref([]) // 样品新增趋势数据 const sampleAddData: Ref<lineDataI[]> = ref([]) // 样品新增趋势趋势y轴最大值 const sampleAddYDataMax = ref() // 样品到期趋势x轴 const sampleExpireXData: Ref<string[]> = ref([]) // 样品到期趋势数据 const sampleExpireData: Ref<lineDataI[]> = ref([]) // 样品到期趋势y轴最大值 const sampleExpireYDataMax = ref() // 客户新增趋势x轴 const customerAddXData: Ref<string[]> = ref([]) // 客户新增趋势数据 const customerAddData: Ref<lineDataI[]> = ref([]) // 客户新增趋势趋势y轴最大值 const customerAddYDataMax = ref() function calcBlockSize() { // 计算工作台区域高度 - 顶部-面包屑-边距 const bodyHeight = document.body.clientHeight - 60 - 50 - 20 blockHeight.value = bodyHeight > 610 ? (bodyHeight - 10) / 2 : 300 blockWidth.value = (document.body.clientWidth - 180 - 20 - 20) / 3 console.log(blockHeight.value, blockWidth.value - 20) } window.addEventListener('resize', () => { calcBlockSize() }) // 获取样品新增趋势数据 function fetchSampleAddData() { sampleAddLoading.value = true getSampleAddData().then((res) => { sampleAddXData.value = res.data.map((item: planReturn) => item.date.replace(reg, '$1-$2')) const yValue = res.data.map((item: planReturn) => Number(item.count)) sampleAddYDataMax.value = Math.max(yValue) > 10 ? Math.max(yValue) : 10 sampleAddData.value = [{ name: '样品', data: yValue }] sampleAddLoading.value = false }) } // 获取样品到期趋势数据 function fetchSampleExpireData() { sampleExpireLoading.value = true getSampleExpireData().then((res) => { sampleExpireXData.value = res.data.map((item: planReturn) => item.date.replace(reg, '$1-$2')) const yValue = res.data.map((item: planReturn) => Number(item.count)) sampleExpireYDataMax.value = Math.max(yValue) > 10 ? Math.max(yValue) : 10 sampleExpireData.value = [{ name: '样品', data: yValue }] sampleExpireLoading.value = false }) } // 获取优质客户名单 function fetchHighQualityCustomerList() { highQualityCustomerLoading.value = true getHighQualityCustomerList().then((res) => { highQualityCustomerTableData.value = res.data.rows highQualityCustomerLoading.value = false }) } // 获取客户新增趋势数据 function fetchCustomerExpireData() { customerAddLoading.value = true getCustomerExpireData().then((res) => { customerAddXData.value = res.data.map((item: planReturn) => item.date.replace(reg, '$1-$2')) const yValue = res.data.map((item: planReturn) => Number(item.count)) customerAddYDataMax.value = Math.max(yValue) > 10 ? Math.max(yValue) : 10 customerAddData.value = [{ name: '客户', data: yValue }] customerAddLoading.value = false }) } // 获取到期样品表格数据 function fetchDueSampleTableData() { dueSampleTableLoading.value = true getSampleList(dueSampleListQuery.value).then((response) => { dueSampleTableData.value = response.data.rows dueSampleTableLoading.value = false }) } // 获取客户关系表格数据 function fetchcustomerRelationsTableData() { customerRelationsTableLoading.value = true getAdviceList(customerRelationsListQuery.value).then((res) => { customerRelationsTabledata.value = res.data.rows.map((item: IAdvice) => { return { ...item, adviceClass: item.adviceClass === '0' ? '建议' : item.adviceClass === '1' ? '投诉' : '其他', } }) customerRelationsTableLoading.value = false }) } onMounted(() => { calcBlockSize() fetchDueSampleTableData() // 到期样品表格 fetchcustomerRelationsTableData() // 客户关系表格 fetchSampleAddData()// 样品新增趋势 fetchSampleExpireData()// 样品到期趋势 fetchCustomerExpireData()// 客户新增趋势 fetchHighQualityCustomerList()// 优质客户名单 }) </script> <template> <app-container> <div class="customer-bench"> <el-row :gutter="10"> <el-col :span="8"> <bench-col v-loading="dueSampleTableLoading" icon="icon-book" title="到期样品" path-url="/sample/overtime" :style="{ height: blockHeight }" :height="blockHeight" > <el-table :data="dueSampleTableData" :height="blockHeight - 60" style="width: 100%; height: 100%;" stripe header-row-class-name="bench-table-header" row-class-name="bench-table-row" class="bench-table"> <el-table-column v-for="item in dueSampleTableHead" :key="item.value" :prop="item.value" align="center" :label="item.text" :width="item.width" show-overflow-tooltip /> </el-table> </bench-col> </el-col> <el-col :span="8"> <bench-col v-loading="sampleAddLoading" icon="icon-line" title="样品新增趋势" :height="blockHeight" > <line-chart :x-axis-data="sampleAddXData" :width="`${blockWidth - 20}px`" :data="sampleAddData" unit="件" /> </bench-col> </el-col> <el-col :span="8"> <bench-col v-loading="sampleExpireLoading" icon="icon-line" title="样品到期趋势" :height="blockHeight" > <line-chart :x-axis-data="sampleExpireXData" :width="`${blockWidth - 20}px`" :data="sampleExpireData" unit="件" /> </bench-col> </el-col> </el-row> </div> <div class="device-bench" style="margin-top: 10px;"> <el-row :gutter="10"> <el-col :span="8"> <bench-col v-loading="customerRelationsTableLoading" icon="icon-book" title="客户关系" path-url="/customerManage/advice" :style="{ height: blockHeight }" :height="blockHeight" > <el-table :data="customerRelationsTabledata" :height="blockHeight - 60" style="width: 100%; height: 100%;" stripe header-row-class-name="bench-table-header" row-class-name="bench-table-row" class="bench-table"> <el-table-column v-for="item in customerRelationsTableHead" :key="item.value" :prop="item.value" align="center" :label="item.text" :width="item.width" show-overflow-tooltip /> </el-table> </bench-col> </el-col> <el-col :span="8"> <bench-col v-loading="customerAddLoading" icon="icon-line" title="客户新增趋势" :height="blockHeight" > <line-chart :x-axis-data="customerAddXData" :width="`${blockWidth - 20}px`" :data="customerAddData" unit="个" /> </bench-col> </el-col> <el-col :span="8"> <bench-col v-loading="highQualityCustomerLoading" icon="icon-book" title="优质客户名单" :style="{ height: blockHeight }" :height="blockHeight" > <el-table :data="highQualityCustomerTableData" :height="blockHeight - 60" style="width: 100%; height: 100%;" stripe header-row-class-name="bench-table-header" row-class-name="bench-table-row" class="bench-table"> <el-table-column v-for="item in highQualityCustomerTableHead" :key="item.value" :prop="item.value" align="center" :label="item.text" show-overflow-tooltip /> </el-table> </bench-col> </el-col> </el-row> </div> </app-container> </template> <style lang="scss" scoped> .customer-bench { width: 100%; height: 100%; box-sizing: border-box; .the-month-total-Data { width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: space-around; padding: 0 20px; .title { display: flex; justify-content: space-between; font-weight: 500; margin-bottom: 3px; } .content { width: 100%; .item { display: flex; flex-direction: column; flex: 1; margin-right: 10px; padding: 3px 0; justify-content: center; align-items: center; background-image: linear-gradient(to bottom, #e9f5ff, #3d7eff); border-radius: 8px; &:last-child { margin-right: 0; } } } } .my-equipment { height: 100%; display: flex; flex-direction: column; justify-content: space-around; padding: 20px; .item { height: 40%; display: flex; flex-direction: column; justify-content: center; align-items: center; background-image: linear-gradient(to right, #caddff, #3d7eff); border-radius: 16px; } } } </style> <style lang="scss"> .bench-table { .el-table__header-wrapper { border-radius: 8px; } } .bench-table-header { th { font-weight: normal; font-size: 14px; } } .bench-table-row { border-radius: 8px; } </style>