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