songguoqiang
11 months ago
6 changed files with 597 additions and 7 deletions
@ -0,0 +1,566 @@ |
|||
<template> |
|||
<div class="contain" v-loading="loading"> |
|||
<div class="title"> |
|||
<div>SPC质量品质数据看板</div> |
|||
</div> |
|||
<div class="height"></div> |
|||
<div class="bod"> |
|||
<div class="time">{{date}}</div> |
|||
<div class="pl-2vw pr-2vw"> |
|||
<el-row :gutter="14" justify="space-between"> |
|||
<el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24"> |
|||
<div class="left"> |
|||
<div class="table"> |
|||
<ul class="table-header"> |
|||
<li class="first"></li> |
|||
<li class="other">数量</li> |
|||
<li class="other">合格数量</li> |
|||
<li class="other">不良数量</li> |
|||
<li class="other">不良率</li> |
|||
</ul> |
|||
<ul class="table-body"> |
|||
<li class="first">外观</li> |
|||
<li class="other blue">{{ tableData.facade.wg_zs }}</li> |
|||
<li class="other green">{{ tableData.facade.wg_ok }}</li> |
|||
<li class="other yellow">{{ tableData.facade.wg_no }}</li> |
|||
<li class="other red">{{ tableData.facade.wg_buhegelv }}</li> |
|||
</ul> |
|||
<ul class="table-body"> |
|||
<li class="first">性能</li> |
|||
<li class="other blue">{{ tableData.performance.xn_zs }}</li> |
|||
<li class="other green">{{ tableData.performance.xn_ok }}</li> |
|||
<li class="other yellow">{{ tableData.performance.xn_no }}</li> |
|||
<li class="other red">{{ tableData.performance.xn_buhegelv }}</li> |
|||
</ul> |
|||
<ul class="table-body"> |
|||
<li class="first">尺寸</li> |
|||
<li class="other blue">{{ tableData.size.cc_zs }}</li> |
|||
<li class="other green">{{ tableData.size.cc_ok }}</li> |
|||
<li class="other yellow">{{ tableData.size.cc_no }}</li> |
|||
<li class="other red">{{ tableData.size.cc_buhegelv }}</li> |
|||
</ul> |
|||
<ul class="table-body"> |
|||
<li class="first">数量合计</li> |
|||
<li class="other blue">{{ tableData.sum.sum_zs }}</li> |
|||
<li class="other green">{{ tableData.sum.sum_ok }}</li> |
|||
<li class="other yellow">{{ tableData.sum.sum_no }}</li> |
|||
<li class="other red">{{ tableData.sum.sum_buhegelv }}</li> |
|||
</ul> |
|||
</div> |
|||
<Echart :options="pieOptionsData" :height="'22vh'" /> |
|||
<div class="line-header"> |
|||
<div class="" |
|||
>零件号:<span>{{ lineData?.item_code }}</span></div |
|||
> |
|||
<div class="" |
|||
>检测类型:<span>{{ lineData?.itemTypeName }}</span></div |
|||
> |
|||
<div class="" v-if="lineData?.itemTypeName == '色差'" |
|||
>点位:<span>{{ lineData?.line_number }}</span></div |
|||
> |
|||
<div class="" |
|||
>检测项:<span>{{ lineData?.contents }}</span></div |
|||
> |
|||
</div> |
|||
<div class="bottom"> |
|||
<div class="line-data"> |
|||
<Echart :options="lineOptionsData" style="height: calc(77vh - 22vh - 240px)" /> |
|||
</div> |
|||
<div class="bottom-r ml-6px mt-20px"> |
|||
<div class="bottom-r-item"> |
|||
<div>CPK(色差)</div> |
|||
<div>{{ lineData?.CPK }}</div> |
|||
<div>CPK</div> |
|||
</div> |
|||
<div class="bottom-r-item mt-6px"> |
|||
<div>PPK(色差)</div> |
|||
<div>{{ lineData?.PPK }}</div> |
|||
<div>PPK</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</el-col> |
|||
<el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24"> |
|||
<div class="right"> |
|||
<div class="samll-title">合格数据</div> |
|||
<div class="mt-10px qualified-list" style="height:calc(50% - 44px);"> |
|||
<dv-scroll-board |
|||
ref="scrollBoard" |
|||
:config="standardData" |
|||
style="width: 100%; height:100%" |
|||
/> |
|||
</div> |
|||
<div class="samll-title mt-10px">不合格数据</div> |
|||
<div class="mt-10px no-qualified-list" style="height:calc(50% - 44px);"> |
|||
<dv-scroll-board |
|||
ref="noStandardDataScrollBoard" |
|||
:config="noStandardData" |
|||
style="width: 100%; height:100%" |
|||
/> |
|||
</div> |
|||
</div> |
|||
</el-col> |
|||
</el-row> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script lang="ts" setup> |
|||
import { set } from 'lodash-es' |
|||
import { EChartsOption } from 'echarts' |
|||
import * as boardAPI from '@/api/board/index' |
|||
import { pieOptions, lineOptions } from '@/views/Home/echarts-data' |
|||
import type { ScrollBoard } from '@kjgl77/datav-vue3/index' |
|||
const pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption |
|||
const lineOptionsData = reactive<EChartsOption>(lineOptions) as EChartsOption |
|||
|
|||
defineOptions({ name: 'Board1' }) |
|||
const { t } = useI18n() |
|||
const tableData = ref({ |
|||
facade: {}, |
|||
size: {}, |
|||
performance: {}, |
|||
sum: {} |
|||
}) |
|||
const loading = ref(true) |
|||
|
|||
// 合格数据的字段 |
|||
const standardDataTotal = ref(0) |
|||
const standardDataTime = ref() |
|||
const standardData = ref({ |
|||
columnWidth: [230, 230, 140, 170, 170, 170, 110], |
|||
header: ['零件号', '零件名称', '检测类型', '检测项', '检测日期', '标准', '实测值'], |
|||
indexHeader: '序号', |
|||
index: false, |
|||
data: [], |
|||
align: ['center','center','center','center','center','center','center'], |
|||
headerBGC: '#e3e8eb', |
|||
oddRowBGC: '#f7f7f7', |
|||
evenRowBGC: '#eeeff1', |
|||
waitTime: 3000, |
|||
headerHeight: 40, |
|||
rowNum: 10 |
|||
}) |
|||
|
|||
const standardDataParams = ref({ |
|||
pageSize: 20, |
|||
pageNo: 1 |
|||
}) |
|||
// 不合格数据字段 |
|||
const noStandardDataTotal = ref(0) |
|||
const noStandardDataTime = ref() |
|||
const noStandardData = ref({ |
|||
columnWidth: [230, 230, 140, 170, 170, 170, 110], |
|||
header: ['零件号', '零件名称', '检测类型', '检测项', '检测日期', '标准', '实测值'], |
|||
indexHeader: '序号', |
|||
index: false, |
|||
data: [], |
|||
align: ['center','center','center','center','center','center','center'], |
|||
headerBGC: '#e3e8eb', |
|||
oddRowBGC: '#f7f7f7', |
|||
evenRowBGC: '#eeeff1', |
|||
waitTime: 3000, |
|||
headerHeight: 40, |
|||
rowNum: 10 |
|||
}) |
|||
const noStandardDataParams = ref({ |
|||
pageSize: 20, |
|||
pageNo: 1 |
|||
}) |
|||
const pieData = ref() |
|||
// 看板获取数量列表以及饼状图 |
|||
const getNumberStatistics = async () => { |
|||
await boardAPI.getNumberStatistics().then((res) => { |
|||
tableData.value.facade = res.list[0] |
|||
tableData.value.size = res.list[1] |
|||
tableData.value.performance = res.list[2] |
|||
tableData.value.sum = res.list[3] |
|||
pieData.value = res.echarts |
|||
}) |
|||
} |
|||
// 饼状图 |
|||
const getpieData = async () => { |
|||
const data = pieData.value |
|||
set(pieOptionsData, 'grid', { left: 20, right: 20, bottom: 20, top: 80, containLabel: true }) |
|||
set(pieOptionsData, 'legend', { |
|||
data: data.map((v) => t(v.name)), |
|||
top: 'center', |
|||
right: 20, |
|||
orient: 'vertical' |
|||
}) |
|||
set(pieOptionsData, 'series', { |
|||
name: '', |
|||
type: 'pie', |
|||
radius: '80%', |
|||
center: ['30%', '50%'], |
|||
label: { |
|||
show: true, |
|||
formatter(param) { |
|||
// correct the percentage |
|||
return param.name + ' (' + param.percent+ '%)'; |
|||
} |
|||
}, |
|||
data: data.map((v) => { |
|||
return { |
|||
name: t(v.name), |
|||
value: v.value |
|||
} |
|||
}) |
|||
}) |
|||
} |
|||
|
|||
// 获取折线图 |
|||
const lineDataTotal = ref(0) |
|||
const lineTime = ref() |
|||
const lineData = ref() |
|||
const getLinePage = async () => { |
|||
await boardAPI.getLinePage().then((res) => { |
|||
if (lineTime.value) { |
|||
clearInterval(lineTime.value) |
|||
} |
|||
lineDataTotal.value = res.length |
|||
if (res?.length > 0) { |
|||
lineData.value = res[0] |
|||
} |
|||
let index = 1 |
|||
lineTime.value = setInterval(() => { |
|||
if (index == res.length) { |
|||
index = 1 |
|||
} |
|||
lineData.value = res[index] |
|||
getLineData() |
|||
index++ |
|||
}, 3000) |
|||
}) |
|||
} |
|||
// 折线图 |
|||
const getLineData = async () => { |
|||
set(lineOptionsData, 'title', { |
|||
text: '', |
|||
left: 0, |
|||
textStyle: { |
|||
fontSize: 14 |
|||
} |
|||
}) |
|||
set(lineOptionsData, 'grid', { |
|||
left: 0, |
|||
right: 0, |
|||
bottom: 0, |
|||
top: 20, |
|||
containLabel: true |
|||
}) |
|||
set(lineOptionsData, 'legend', { |
|||
data: [], |
|||
top: 0, |
|||
right: 20 |
|||
}) |
|||
set(lineOptionsData, 'xAxis', { |
|||
data: lineData.value.xDatasList, |
|||
boundaryGap: false, |
|||
axisTick: { |
|||
show: false |
|||
} |
|||
}) |
|||
set(lineOptionsData, 'series', [ |
|||
{ |
|||
name: '色差', |
|||
data: lineData.value.yDatasList, |
|||
type: 'line', |
|||
areaStyle: {}, |
|||
animationDuration: 1000, |
|||
emphasis: { |
|||
focus: 'series' |
|||
} |
|||
} |
|||
]) |
|||
} |
|||
|
|||
// 获取合格的数据 |
|||
let first = 1 //初始加载列表的时候为1,之后定制器加载的时候显示2 |
|||
const scrollBoard = ref<InstanceType<typeof ScrollBoard>>(null) |
|||
let standardData2 = [] |
|||
const getStandardData = () => { |
|||
boardAPI |
|||
.getStandardData(standardDataParams.value) |
|||
.then((res) => { |
|||
standardDataTotal.value = res.total |
|||
res.list.forEach((item) => { |
|||
let data1 = [] |
|||
data1.push(item.itemCode) |
|||
data1.push(item.itemName) |
|||
data1.push(item.itemTypeName) |
|||
data1.push(item.contents) |
|||
data1.push(item.times) |
|||
data1.push(item.valueRange) |
|||
data1.push(item.detectValue) |
|||
standardData2.push(data1) |
|||
}) |
|||
// 初始进入的时候 |
|||
// standardData.value.index = true |
|||
if (first == 1) { |
|||
standardData.value.data = standardData2 |
|||
first = 2 |
|||
} else { |
|||
if (scrollBoard.value) { |
|||
scrollBoard.value.updateRows(standardData2) |
|||
} |
|||
} |
|||
loading.value = false |
|||
}) |
|||
.catch(() => { |
|||
loading.value = false |
|||
}) |
|||
} |
|||
// 获取不合格的数据 |
|||
let first1 = 1 //初始加载列表的时候为1,之后定制器加载的时候显示2 |
|||
const noStandardDataScrollBoard = ref<InstanceType<typeof ScrollBoard>>(null) |
|||
let noStandardData2 = [] |
|||
const getNoStandardData = () => { |
|||
boardAPI |
|||
.getNoStandardData(noStandardDataParams.value) |
|||
.then((res) => { |
|||
noStandardDataTotal.value = res.total |
|||
res.list.forEach((item) => { |
|||
let data1 = [] |
|||
data1.push(item.itemCode) |
|||
data1.push(item.itemName) |
|||
data1.push(item.itemTypeName) |
|||
data1.push(item.contents) |
|||
data1.push(item.times) |
|||
data1.push(item.valueRange) |
|||
data1.push(item.detectValue) |
|||
noStandardData2.push(data1) |
|||
}) |
|||
// 初始进入的时候 |
|||
// noStandardData.value.index = true |
|||
console.log(first1) |
|||
if (first1 == 1) { |
|||
noStandardData.value.data = noStandardData2 |
|||
first1 = 2 |
|||
} else { |
|||
if (noStandardDataScrollBoard.value) { |
|||
noStandardDataScrollBoard.value.updateRows(noStandardData2) |
|||
} |
|||
} |
|||
console.log(noStandardData.value) |
|||
}) |
|||
.catch(() => {}) |
|||
} |
|||
// 首先定义一个getPreviousDate函数,方便调用 |
|||
function getPreviousDate(numOfDays) { |
|||
var date = new Date() |
|||
date.setDate(date.getDate() - numOfDays) |
|||
var year = date.getFullYear() |
|||
var month = date.getMonth() + 1 |
|||
var day = date.getDate() |
|||
return year + '年' + month + '月' + day+ '日' |
|||
} |
|||
const handleResize= () =>{ |
|||
window.location.reload() |
|||
} |
|||
const date = ref() |
|||
onMounted(async () => { |
|||
date.value = getPreviousDate(7) + ' - ' + getPreviousDate(1) |
|||
await getNumberStatistics() |
|||
getpieData() |
|||
await getLinePage() |
|||
getLineData() |
|||
getStandardData() |
|||
getNoStandardData() |
|||
standardDataTime.value = await setInterval(() => { |
|||
if (standardDataParams.value.pageNo * 10 > standardDataTotal.value) { |
|||
clearInterval(standardDataTime.value) |
|||
} else { |
|||
standardDataParams.value.pageNo++ |
|||
getStandardData() |
|||
} |
|||
}, 15000) |
|||
noStandardDataTime.value = await setInterval(() => { |
|||
if (noStandardDataParams.value.pageNo * 10 > noStandardDataTotal.value) { |
|||
clearInterval(noStandardDataTime.value) |
|||
} else { |
|||
noStandardDataParams.value.pageNo++ |
|||
getNoStandardData() |
|||
} |
|||
}, 15000) |
|||
window.addEventListener('resize', handleResize); |
|||
}) |
|||
|
|||
onUnmounted(() => { |
|||
if (standardDataTime.value) { |
|||
clearInterval(standardDataTime.value) |
|||
} |
|||
if (noStandardDataTime.value) { |
|||
clearInterval(noStandardDataTime.value) |
|||
} |
|||
if (lineTime.value) { |
|||
clearInterval(lineTime.value) |
|||
} |
|||
window.removeEventListener('resize', handleResize); |
|||
}) |
|||
</script> |
|||
<style lang="scss" scoped> |
|||
.contain { |
|||
width: 100%; |
|||
height: 100%; |
|||
background: url(../../assets/imgs/bgimg.png) no-repeat 0 0; |
|||
background-size: 100% 100%; |
|||
} |
|||
.title { |
|||
margin: 0px auto; |
|||
width: 50%; |
|||
text-align: center; |
|||
background: url(../../assets/imgs/title.png) no-repeat 0 0; |
|||
background-size: 100% 100%; |
|||
height: 12vh; |
|||
line-height: 8vh; |
|||
font-size: 2vw; |
|||
color: #596a7c; |
|||
position: absolute; |
|||
left: 50%; |
|||
margin-left: -25%; |
|||
} |
|||
.bod { |
|||
width: 99vw; |
|||
height: 90vh; |
|||
background: url(../../assets/imgs/side.png) no-repeat 0 0; |
|||
background-size: 100% 100%; |
|||
margin: 0 auto; |
|||
} |
|||
.height { |
|||
height: 9vh; |
|||
} |
|||
.time { |
|||
text-align: center; |
|||
color: #3b556e; |
|||
line-height: 8vh; |
|||
font-size: 18px; |
|||
} |
|||
.line-header { |
|||
background: #e3e8eb !important; |
|||
display: flex; |
|||
height: 5vh; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 0px 10px; |
|||
} |
|||
.bottom { |
|||
display: flex; |
|||
flex: 1; |
|||
height: 0px; |
|||
} |
|||
.line-data { |
|||
width: 70%; |
|||
} |
|||
.bottom-r { |
|||
flex: 1; |
|||
height: calc(100% - 38px); |
|||
} |
|||
.bottom-r-item { |
|||
background: #e7ecef; |
|||
height: 50%; |
|||
width: 100%; |
|||
position: relative; |
|||
overflow: hidden; |
|||
display: flex; |
|||
justify-content: center; |
|||
flex-direction: column; |
|||
& > div { |
|||
&:nth-child(1) { |
|||
font-size: 1vw; |
|||
color: #3c73ac; |
|||
padding-top: 10px; |
|||
padding-left: 10px; |
|||
} |
|||
&:nth-child(2) { |
|||
font-size: 1.7vw; |
|||
font-weight: bold; |
|||
padding-left: 10px; |
|||
padding-top: 6px; |
|||
} |
|||
&:nth-child(3) { |
|||
position: absolute; |
|||
font-size: 3vw; |
|||
font-weight: bold; |
|||
color: #dce5ec; |
|||
right: 0px; |
|||
bottom: -1vw; |
|||
} |
|||
} |
|||
} |
|||
.samll-title { |
|||
font-size: 18px; |
|||
position: relative; |
|||
padding-left: 1vw; |
|||
&::after { |
|||
position: absolute; |
|||
content: ''; |
|||
width: 6px; |
|||
height: 20px; |
|||
background: #5bacfe; |
|||
left: 0px; |
|||
top: 50%; |
|||
margin-top: -10px; |
|||
} |
|||
} |
|||
::v-deep(.header-item) { |
|||
color: #6d7079 !important; |
|||
} |
|||
.qualified-list ::v-deep(.row-item) { |
|||
color: #12ad8b !important; |
|||
} |
|||
.no-qualified-list ::v-deep(.row-item) { |
|||
color: #c2020f !important; |
|||
} |
|||
.left { |
|||
display: flex; |
|||
flex-direction: column; |
|||
height: 77vh; |
|||
} |
|||
.right { |
|||
height: 77vh; |
|||
} |
|||
.table { |
|||
ul { |
|||
display: flex; |
|||
padding: 0px; |
|||
margin: 0px; |
|||
&.table-header { |
|||
border-bottom: 1px solid #8f9fae !important; |
|||
border-top: 1px solid #8f9fae !important; |
|||
background: #e3e8eb !important; |
|||
color: #495f76; |
|||
} |
|||
&.table-body { |
|||
border-bottom: 1px solid #8f9fae !important; |
|||
color: #495f76; |
|||
} |
|||
li { |
|||
list-style: none; |
|||
// flex:1; |
|||
padding: 9px 15px; |
|||
text-align: center; |
|||
&.first { |
|||
text-align: right; |
|||
width: 80px; |
|||
} |
|||
&.other { |
|||
flex: 1; |
|||
} |
|||
&.blue { |
|||
color: #3e5567; |
|||
} |
|||
&.green { |
|||
color: #12ae89; |
|||
} |
|||
&.yellow { |
|||
color: #dd962c; |
|||
} |
|||
&.red { |
|||
color: #c2020f; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
Loading…
Reference in new issue