| | |
| | | <template> |
| | | <div class="home-main"> |
| | | <div class="home-header-welcome"> |
| | | <div class="welcome-left"> |
| | | <div class="left-avatar" /> |
| | | <div class="left-tips"> |
| | | <div>Hi jack,欢迎使用ZT-LIMS</div> |
| | | <div>今天是2023年07月07日 星期五</div> |
| | | </div> |
| | | <div class="content-main"> |
| | | <div class="echart1"> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="16"> |
| | | <el-card class="box-card" :body-style="{ padding: '0px 10px',height:'17vh' }"> |
| | | <p style="font-size: 10px;margin-left: 10px;">检验总数统计</p> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="6" > |
| | | <img :src="imgSrc" /> |
| | | <div class="card-text"> |
| | | <h3>检验单</h3> |
| | | <p><span>(已检验总数)</span>{{insNum}}</p> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <img :src="imgSrc"/> |
| | | <div class="card-text"> |
| | | <h3>检验单</h3> |
| | | <p><span>(未检验总数)</span>{{insUnNum}}</p> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <img :src="imgSrc"/> |
| | | <div class="card-text"> |
| | | <h3>检验项目</h3> |
| | | <p><span>(已检验总数)</span>{{insproNum}}</p> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <img :src="imgSrc"/> |
| | | <div class="card-text"> |
| | | <h3>检验项目</h3> |
| | | <p><span>(未检验总数)</span>{{insproUnNum}}</p> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-card class="box-card" :body-style="{ padding: '0px',height:'17vh' }"> |
| | | <p style="font-size: 10px;margin-left: 10px;color: #2fcf10;">已检验</p> |
| | | <el-table |
| | | :data="verifiedData" |
| | | :default-sort = "{prop: 'date', order: 'descending'}" |
| | | :cell-style="cell" |
| | | :header-cell-style="{margin:'0',padding:'0',backgroundColor:'#f0f7ff',color:'#0050a7'}"> |
| | | <el-table-column prop="no" label="排名" sortable width="110"></el-table-column> |
| | | <el-table-column prop="result" label="检验结论" width="110"></el-table-column> |
| | | <el-table-column prop="num" label="检验数量" sortable width="110"></el-table-column> |
| | | <el-table-column prop="chact" label="检验占比" sortable width="110"></el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | <div class="welcome-right"> |
| | | <div class="right-centent"> |
| | | <div>即将超期待办</div> |
| | | <div>暂无</div> |
| | | </div> |
| | | <div /> |
| | | <div class="right-centent"> |
| | | <div>已超期待办</div> |
| | | <div>21</div> |
| | | </div> |
| | | <div class="echart2"> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="6"> |
| | | <el-card :body-style="{ padding: '0px',height:'25vh' }"> |
| | | <p>原材料合格率</p> |
| | | <div id="materialPieChart" style="width:100%;height:180px"></div> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-card :body-style="{ padding: '0px',height:'25vh' }"> |
| | | <p>成品合格率</p> |
| | | <div id="finishedPieChart" style="width:100%;height:180px"></div> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-card :body-style="{ padding: '0px',height:'25vh' }"> |
| | | <p style="z-index: 2;position: absolute;font-size: 10px;margin-left: 10px;color: #ff0000;">未检验</p> |
| | | <el-table |
| | | :data="uncheckedData" |
| | | :cell-style="cell" |
| | | :header-cell-style="{margin:'0px',padding:'3px 0px',backgroundColor:'#f0f7ff',color:'#0050a7'}"> |
| | | <el-table-column prop="no" label="序号" width="100"></el-table-column> |
| | | <el-table-column prop="name" label="待检项目" width="120"></el-table-column> |
| | | <el-table-column prop="instrumentname" label="设备" width="120"></el-table-column> |
| | | <el-table-column prop="startTime" label="检验时间" width="120"> |
| | | </el-table-column><el-table-column prop="checkname" label="检验人" width="120"> |
| | | </el-table-column><el-table-column prop="endTime" label="预计结束时间" width="120"></el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | <div class="echart3"> |
| | | <el-card :body-style="{ padding: '0px',height:'40vh' }"> |
| | | <el-radio-group class="button-group" :input="getDataByType(radioType)" v-model="radioType" size="mini"> |
| | | <el-radio-button label="本周"></el-radio-button> |
| | | <el-radio-button label="本月"></el-radio-button> |
| | | <el-radio-button label="本年"></el-radio-button> |
| | | </el-radio-group> |
| | | <div id="barLineChart" style="width:100%;height:300px;"></div> |
| | | </el-card> |
| | | </div> |
| | | </div> |
| | | <div class="content-main" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import * as echarts from 'echarts'; |
| | | import { getVerifiedTop3,getUncheckedTop4,getMatAndFinshQualified, |
| | | getCheckAndProjectNum,getTurno |
| | | } from '@/api/home/index' |
| | | export default { |
| | | name: "home", |
| | | data() { |
| | | return { |
| | | insNum: 0, |
| | | insUnNum: 0, |
| | | insproNum: 0, |
| | | insproUnNum: 0, |
| | | radioType: "本年", |
| | | imgSrc: require("@/assets/404_images/bg.png"), |
| | | verifiedData: new Array(), |
| | | uncheckedData: new Array(), |
| | | } |
| | | }, |
| | | mounted(){ |
| | | this.getcheckProjectNum(); |
| | | this.getVerifiedData(); |
| | | this.getUncheckedData(); |
| | | this.getPieChart(); |
| | | }, |
| | | methods: { |
| | | cell({ row, column, rowIndex, columnIndex }) { |
| | | if(rowIndex===0 && columnIndex===0){ |
| | | return "color: #ff0000;margin:0;padding:2px 0px"; |
| | | } |
| | | if(rowIndex===1 && columnIndex===0){ |
| | | return "color: #f0d357;margin:0;padding:2px 0px"; |
| | | } |
| | | if(rowIndex===2 && columnIndex===0){ |
| | | return "color: #37ff11;margin:0;padding:2px 0px"; |
| | | } |
| | | if(rowIndex>=0 && columnIndex>=0){ |
| | | return {"margin":"0","padding":"2px 0px"}; |
| | | } |
| | | }, |
| | | async getcheckProjectNum(){ |
| | | const {data} = await getCheckAndProjectNum(); |
| | | this.insNum = data.insNum; |
| | | this.insUnNum = data.insUnNum; |
| | | this.insproNum = data.insproNum; |
| | | this.insproUnNum = data.insproUnNum; |
| | | }, |
| | | async getVerifiedData(){ |
| | | const { data } = await getVerifiedTop3(); |
| | | for(let i=0;i<data.length;i++){ |
| | | let val = ""; |
| | | if(data[i].result == 0){ |
| | | val = "不合格"; |
| | | }else if(data[i].result == 1){ |
| | | val = "合格"; |
| | | }else{ |
| | | val = "未检验"; |
| | | } |
| | | this.verifiedData.push ({ |
| | | no: i+1, |
| | | result: val, |
| | | num: data[i].num, |
| | | chact: data[i].chact + '%' |
| | | }) |
| | | } |
| | | }, |
| | | async getUncheckedData(){ |
| | | const {data} = await getUncheckedTop4(); |
| | | for(let i=0;i<data.length;i++){ |
| | | this.uncheckedData.push ({ |
| | | no: i+1, |
| | | name: data[i].name, |
| | | instrumentname: data[i].instrumentname, |
| | | startTime: data[i].startTime, |
| | | checkname: data[i].checkname, |
| | | endTime: data[i].endTime |
| | | }) |
| | | } |
| | | }, |
| | | initPieChart(elementId,data){ |
| | | let chartDom = document.getElementById(elementId); |
| | | let myChart = echarts.init(chartDom); |
| | | window.addEventListener('resize', function() { |
| | | myChart.resize(); |
| | | }); |
| | | let option; |
| | | option = { |
| | | tooltip: { |
| | | trigger: 'item' |
| | | }, |
| | | legend: { |
| | | orient: 'vertical', |
| | | right: 'right', |
| | | top: 'center', |
| | | left: 20 |
| | | }, |
| | | series: [ |
| | | { |
| | | type: 'pie', |
| | | radius: ['40%', '70%'], |
| | | itemStyle: { |
| | | borderRadius: 6, |
| | | borderColor: '#fff', |
| | | borderWidth: 2 |
| | | }, |
| | | tooltip: { |
| | | valueFormatter: function(value){ |
| | | return value + '%'; |
| | | } |
| | | }, |
| | | avoidLabelOverlap: false, |
| | | label: { |
| | | show: false, |
| | | position: 'center', |
| | | formatter: '{c}%' |
| | | }, |
| | | emphasis: { |
| | | label:{ |
| | | fontSize: 25, |
| | | show: true |
| | | } |
| | | }, |
| | | labelLine: { |
| | | show: false |
| | | }, |
| | | data: data |
| | | } |
| | | ] |
| | | }; |
| | | |
| | | option && myChart.setOption(option); |
| | | }, |
| | | async getPieChart(){ |
| | | const {data} = await getMatAndFinshQualified(); |
| | | let material = [ |
| | | { value: data.material, name: '合格',itemStyle: {normal: {color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{offset: 0, color: '#8ea9e0' },{offset: 1, color: '#106de7' }], false)}}}, |
| | | { value: data.unmaterial, name: '不合格',itemStyle: {normal: {color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{offset: 0, color: '#ed9031' },{offset: 1, color: '#feb855' }], false)}} }, |
| | | { value: data.notmaterial, name: '待检验',itemStyle: {normal: {color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{offset: 0, color: '#2ca4a0' },{offset: 1, color: '#3ad1cb' }], false)}} }, |
| | | ] |
| | | let finished = [ |
| | | { value: data.finished, name: '合格',itemStyle: {normal: {color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{offset: 0, color: '#8ea9e0' },{offset: 1, color: '#106de7' }], false)}} }, |
| | | { value: data.unfinished, name: '不合格',itemStyle: {normal: {color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{offset: 0, color: '#ed9031' },{offset: 1, color: '#feb855' }], false)}} }, |
| | | { value: data.notfinished, name: '待检验',itemStyle: {normal: {color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{offset: 0, color: '#2ca4a0' },{offset: 1, color: '#3ad1cb' }], false)}} }, |
| | | ] |
| | | //渲染饼状图 |
| | | this.initPieChart("materialPieChart",material); |
| | | this.initPieChart("finishedPieChart",finished); |
| | | }, |
| | | async getDataByType(label){ |
| | | let xAxis = ['一月', '二月', '三月', '四月', '五月', '六月', '七月','八月','九月','十月','十一月','十二月'] |
| | | let bar1Data = []; |
| | | let bar2Data = []; |
| | | let line1Data = []; |
| | | let line2Data = []; |
| | | switch(label){ |
| | | case "本年": |
| | | const byYear = await getTurno({type:3}); |
| | | bar1Data = byYear.data.series[0].data; |
| | | bar2Data = byYear.data.series[1].data; |
| | | line1Data = byYear.data.series[2].data; |
| | | line2Data = byYear.data.series[3].data; |
| | | break; |
| | | case "本月": |
| | | const byMonth = await getTurno({type:2}); |
| | | bar1Data = byMonth.data.series[0].data; |
| | | bar2Data = byMonth.data.series[1].data; |
| | | line1Data = byMonth.data.series[2].data; |
| | | line2Data = byMonth.data.series[3].data; |
| | | let days = new Array(); |
| | | for(let i=1;i<=byMonth.data.xaxis.length;i++){ |
| | | days.push(i); |
| | | } |
| | | xAxis = days; |
| | | break; |
| | | case "本周": |
| | | const byWeek = await getTurno({type:1}); |
| | | bar1Data = byWeek.data.series[0].data; |
| | | bar2Data = byWeek.data.series[1].data; |
| | | line1Data = byWeek.data.series[2].data; |
| | | line2Data = byWeek.data.series[3].data; |
| | | xAxis = new Array("周一","周二","周三","周四","周五","周六","周日"); |
| | | break |
| | | } |
| | | this.initBarAndLineChart(xAxis,bar1Data,bar2Data,line1Data,line2Data); |
| | | }, |
| | | initBarAndLineChart(xAxis,bar1Data,bar2Data,line1Data,line2Data){ |
| | | let chartDom = document.getElementById('barLineChart'); |
| | | let myChart = echarts.init(chartDom); |
| | | window.addEventListener('resize', function() { |
| | | myChart.resize(); |
| | | }); |
| | | let option; |
| | | option = { |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | axisPointer: { |
| | | type: 'cross', |
| | | crossStyle: { |
| | | color: '#999' |
| | | } |
| | | } |
| | | }, |
| | | legend: {data: ['原材料检验', '成品检验', '原材料合格率','成品合格率']}, |
| | | xAxis: [ |
| | | { |
| | | type: 'category', |
| | | data: xAxis, |
| | | axisPointer: { |
| | | type: 'shadow' |
| | | } |
| | | } |
| | | ], |
| | | yAxis: [ |
| | | { |
| | | type: 'value', |
| | | name: '检验数量', |
| | | min: 0, |
| | | max: 1000, |
| | | interval: 100, |
| | | axisLabel: { |
| | | formatter: '{value}' |
| | | } |
| | | }, |
| | | { |
| | | type: 'value', |
| | | name: '合格率', |
| | | min: 0, |
| | | max: 100, |
| | | interval: 10, |
| | | axisLabel: { |
| | | formatter: '{value} %' |
| | | } |
| | | } |
| | | ], |
| | | series: [ |
| | | { |
| | | name: '原材料检验', |
| | | type: 'bar', |
| | | tooltip: { |
| | | valueFormatter: function (value) { |
| | | return value; |
| | | } |
| | | }, |
| | | itemStyle: { |
| | | normal: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { |
| | | offset: 0, |
| | | color: '#6694ff', |
| | | }, |
| | | { |
| | | offset: 1, |
| | | color: '#096ae4', |
| | | }, |
| | | ]), |
| | | } |
| | | }, |
| | | data: bar1Data |
| | | }, |
| | | { |
| | | name: '成品检验', |
| | | type: 'bar', |
| | | tooltip: { |
| | | valueFormatter: function (value) { |
| | | return value ; |
| | | } |
| | | }, |
| | | itemStyle: { |
| | | normal: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { |
| | | offset: 0, |
| | | color: '#ffc16b', |
| | | }, |
| | | { |
| | | offset: 1, |
| | | color: '#fd8103', |
| | | }, |
| | | ]), |
| | | } |
| | | }, |
| | | data: bar2Data |
| | | }, |
| | | { |
| | | name: '原材料合格率', |
| | | smooth: true, |
| | | type: 'line', |
| | | yAxisIndex: 1, |
| | | tooltip: { |
| | | valueFormatter: function (value) { |
| | | return value + ' %'; |
| | | } |
| | | }, |
| | | itemStyle: {color: "#0166e2"}, |
| | | data: line1Data |
| | | }, |
| | | { |
| | | name: '成品合格率', |
| | | smooth: true, |
| | | type: 'line', |
| | | yAxisIndex: 1, |
| | | tooltip: { |
| | | valueFormatter: function (value) { |
| | | return value + ' %'; |
| | | } |
| | | }, |
| | | itemStyle: {color: "#ed7619"}, |
| | | data: line2Data |
| | | } |
| | | ] |
| | | }; |
| | | option && myChart.setOption(option); |
| | | this.$on('hook:destroyed',()=>{ |
| | | window.removeEventListener("resize", function() { |
| | | myChart.resize(); |
| | | }); |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .home-main{ |
| | | .home-header-welcome{ |
| | | width: 100%; |
| | | background: #fff; |
| | | height: 84px; |
| | | display: flex; |
| | | border-bottom: 1px solid #f0f2f5; |
| | | padding: 8px 24px 12px 24px; |
| | | justify-content: space-between; |
| | | .welcome-left{ |
| | | display: flex; |
| | | align-items: center; |
| | | height: 100%; |
| | | .left-avatar{ |
| | | width: 56px; |
| | | height: 56px; |
| | | margin-right: 24px; |
| | | background: #0077DB; |
| | | border-radius: 50%; |
| | | width:100%; |
| | | height:82vh; |
| | | .content-main{ |
| | | .echart1{ |
| | | .el-table{ |
| | | font-weight: bold; |
| | | width: 100%; |
| | | height:100; |
| | | padding:0px; |
| | | margin-left:10px; |
| | | .el-table__body{ |
| | | .el-table_1_column_1 .cell{ |
| | | color: red; |
| | | } |
| | | } |
| | | |
| | | } |
| | | .box-card img{ |
| | | width:100%; |
| | | height:100px; |
| | | border-radius: 10px; |
| | | } |
| | | .box-card .card-text{ |
| | | position: absolute; |
| | | top:0px; |
| | | h3{ |
| | | margin:20px 20px 0px 20px; |
| | | } |
| | | p{ |
| | | width:100%; |
| | | text-align: right; |
| | | font-size: 50px; |
| | | margin: -20px 10px 0px 5px; |
| | | } |
| | | span{ |
| | | color: gray; |
| | | font-size: 10px; |
| | | margin-right: 80px; |
| | | } |
| | | } |
| | | } |
| | | .echart2 { |
| | | .el-table{ |
| | | font-weight: bold; |
| | | width: 100%; |
| | | height:100; |
| | | padding:0px; |
| | | margin-left:10px; |
| | | padding-top:40px; |
| | | .el-table_2_column_5 div{ |
| | | color: red; |
| | | } |
| | | } |
| | | .left-tips{ |
| | | height: 80%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: space-between; |
| | | >div:nth-child(1){ |
| | | font-size: 20px; |
| | | color: #303133; |
| | | } |
| | | >div:nth-child(2){ |
| | | font-size: 14px; |
| | | color: #606266; |
| | | } |
| | | .el-col{ |
| | | margin: 10px 0; |
| | | } |
| | | p{ |
| | | position: absolute; |
| | | font-size: 10px; |
| | | margin-left: 10px; |
| | | color:black; |
| | | } |
| | | } |
| | | .welcome-right{ |
| | | width: 250px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | .right-centent{ |
| | | height: 80%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: space-between; |
| | | align-items: flex-end; |
| | | >div:nth-child(1){ |
| | | color: #909399; |
| | | font-size: 14px; |
| | | } |
| | | >div:nth-child(2){ |
| | | font-size: 24px; |
| | | color: #c0c4cc; |
| | | } |
| | | } |
| | | >div:nth-child(2){ |
| | | width: 2px; |
| | | height: 70%; |
| | | background: #f0f2f5; |
| | | } |
| | | .echart3 .button-group{ |
| | | margin-top: 10px; |
| | | margin-left: 88%; |
| | | z-index: 10; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | | |
| | | </style> |