diff --git a/hb_client/src/api/srm.js b/hb_client/src/api/srm.js index 7e3a614..ea41540 100644 --- a/hb_client/src/api/srm.js +++ b/hb_client/src/api/srm.js @@ -7,3 +7,11 @@ export function getPlanGantt(data) { params: data }) } +//合格率 +export function getProcessYield(data) { + return request({ + url: '/srm/process/yield/', + method: 'post', + data + }) +} diff --git a/hb_client/src/components/Gantt/components/dashLeftMenu.vue b/hb_client/src/components/Gantt/components/dashLeftMenu.vue new file mode 100644 index 0000000..a4d8be2 --- /dev/null +++ b/hb_client/src/components/Gantt/components/dashLeftMenu.vue @@ -0,0 +1,121 @@ + + + + + diff --git a/hb_client/src/components/Gantt/dashGantt.vue b/hb_client/src/components/Gantt/dashGantt.vue new file mode 100644 index 0000000..e34814b --- /dev/null +++ b/hb_client/src/components/Gantt/dashGantt.vue @@ -0,0 +1,1411 @@ + + + + + diff --git a/hb_client/src/components/faceLogin/faceLogin.vue b/hb_client/src/components/faceLogin/faceLogin.vue index 269d70f..d1aaaf3 100644 --- a/hb_client/src/components/faceLogin/faceLogin.vue +++ b/hb_client/src/components/faceLogin/faceLogin.vue @@ -35,12 +35,56 @@ } }, mounted() { - this.init(); + this.openTheCamera(); }, methods: { + openTheCamera () { + this.$nextTick(function () { + let _this = this; + this.video = document.getElementById('video'); + // 旧版本浏览器可能根本不支持mediaDevices,我们首先设置一个空对象 + if (navigator.mediaDevices === undefined) { + navigator.mediaDevices = {} + } + // 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象 + // 使用getUserMedia,因为它会覆盖现有的属性。 + // 这里,如果缺少getUserMedia属性,就添加它。 + if (navigator.mediaDevices.getUserMedia === undefined) { + navigator.mediaDevices.getUserMedia = function (constraints) { + // 首先获取现存的getUserMedia(如果存在) + let getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia; + // 有些浏览器不支持,会返回错误信息 + // 保持接口一致 + if (!getUserMedia) { + return Promise.reject(new Error('getUserMedia is not implemented in this browser')) + } + // 否则,使用Promise将调用包装到旧的navigator.getUserMedia + return new Promise(function (resolve, reject) { + getUserMedia.call(navigator, constraints, resolve, reject) + }) + } + } + let constraints = { audio: false, video: { width: this.videoWidth, height: this.videoHeight, transform: 'scaleX(-1)' } }; + navigator.mediaDevices.getUserMedia(constraints).then(function (stream) { + // 旧的浏览器可能没有srcObject + if ('srcObject' in _this.video) { + _this.video.srcObject = stream + } else { + // 避免在新的浏览器中使用它,因为它正在被弃用。 + _this.video.src = window.URL.createObjectURL(stream) + } + _this.video.onloadedmetadata = function (e) { + _this.video.play(); + }; + _this.init(); + }).catch(err => { + console.log(err) + }) + }); + }, // 初始化设置 init() { - this.video = document.getElementById('video'); + // this.video = document.getElementById('video'); this.screenshotCanvas = document.getElementById('screenshotCanvas'); let canvas = document.getElementById('canvas'); let context = canvas.getContext('2d'); @@ -64,7 +108,6 @@ event.data.forEach(function (rect) { context.strokeStyle = '#0764B7'; context.strokeRect(rect.x, rect.y, rect.width, rect.height); - // window.plot(rect.x, rect.y, rect.width, rect.height+20); // 避免重复发送请求 if(!_this.uploadLock){ _this.uploadLock = true; @@ -133,7 +176,10 @@ that.uploadLock = false; // this.$message.error('面部识别失败请重新验证'); }); - } + }, + closeCamera () { + this.video.srcObject.getTracks()[0].stop(); + }, } } diff --git a/hb_client/src/components/faceLogin/tracking.vue b/hb_client/src/components/faceLogin/tracking.vue index 67457c6..4ef978b 100644 --- a/hb_client/src/components/faceLogin/tracking.vue +++ b/hb_client/src/components/faceLogin/tracking.vue @@ -24,12 +24,55 @@ } }, mounted() { - this.init(); + this.openTheCamera(); }, methods: { + openTheCamera () { + this.$nextTick(function () { + let _this = this; + this.video = document.getElementById('video'); + // 旧版本浏览器可能根本不支持mediaDevices,我们首先设置一个空对象 + if (navigator.mediaDevices === undefined) { + navigator.mediaDevices = {} + } + // 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象 + // 使用getUserMedia,因为它会覆盖现有的属性。 + // 这里,如果缺少getUserMedia属性,就添加它。 + if (navigator.mediaDevices.getUserMedia === undefined) { + navigator.mediaDevices.getUserMedia = function (constraints) { + // 首先获取现存的getUserMedia(如果存在) + let getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia; + // 有些浏览器不支持,会返回错误信息 + // 保持接口一致 + if (!getUserMedia) { + return Promise.reject(new Error('getUserMedia is not implemented in this browser')) + } + // 否则,使用Promise将调用包装到旧的navigator.getUserMedia + return new Promise(function (resolve, reject) { + getUserMedia.call(navigator, constraints, resolve, reject) + }) + } + } + let constraints = { audio: false, video: { width: this.videoWidth, height: this.videoHeight, transform: 'scaleX(-1)' } }; + navigator.mediaDevices.getUserMedia(constraints).then(function (stream) { + // 旧的浏览器可能没有srcObject + if ('srcObject' in _this.video) { + _this.video.srcObject = stream + } else { + // 避免在新的浏览器中使用它,因为它正在被弃用。 + _this.video.src = window.URL.createObjectURL(stream) + } + _this.video.onloadedmetadata = function (e) { + _this.video.play(); + }; + _this.init(); + }).catch(err => { + console.log(err) + }) + }); + }, // 初始化设置 init() { - this.video = document.getElementById('video'); this.screenshotCanvas = document.getElementById('screenshotCanvas'); let canvas = document.getElementById('canvas'); let context = canvas.getContext('2d'); @@ -46,7 +89,6 @@ let _this = this; //添加事件 tracker.on('track', function (event) { - // 检测出人脸 绘画人脸位置 context.clearRect(0, 0, canvas.width, canvas.height); // 给每个人脸绘制对应的框 @@ -112,7 +154,10 @@ that.uploadLock = false; // this.$message.error('面部识别失败请重新验证'); }); - } + }, + closeCamera () { + this.video.srcObject.getTracks()[0].stop(); + }, } } diff --git a/hb_client/src/views/dashboard/index.vue b/hb_client/src/views/dashboard/index.vue index 8536aa4..7f11fc3 100644 --- a/hb_client/src/views/dashboard/index.vue +++ b/hb_client/src/views/dashboard/index.vue @@ -1,58 +1,121 @@ @@ -252,11 +256,12 @@ import echarts from 'echarts' import { mapGetters } from 'vuex'; import {getPlanGantt} from "@/api/srm"; +import { getProcessYield } from "@/api/srm"; import { getMaterialList } from "@/api/mtm"; -import gantt from "@/components/Gantt/index"; import { getInventoryList } from "@/api/inm"; import { getProductionplanList} from "@/api/pm"; import { getmaterialbatchList } from "@/api/inm"; +import gantt from "@/components/Gantt/dashGantt"; import { getContractList , getOrderList } from "@/api/sam"; export default { @@ -279,7 +284,7 @@ export default { tableIndex:null, chartIndex:null, tableDate:'2021-12', - chartDate:'2021-12', + chartDate:[], proList: [], planList:[], stockList:[], @@ -299,7 +304,10 @@ export default { "6":'辅助工装', }, activeName:'库存警告', - seriesData:[80,95,96, 96, 96, 98, 99,100], + chartData:{ + xAxisData:["冷加工", "热弯", "钢化", "镀膜", "夹层", "包边", "装框"], + seriesData:[80,95,96, 96, 96, 98, 99,100], + }, contractTotalCount:null,//合同总数 contractTotalCurrent:null, orderTotalCount:null,//生产订单总数 @@ -321,9 +329,6 @@ export default { ]) }, methods:{ - openWord(){ - window.open("http://47.95.0.242:2222/media/2021/09/07/004-%E8%AF%B7%E5%81%87%E5%8D%95_LL8uZdx.docx"); - }, getStatisticsData(){ let that = this; let dat = new Date(); @@ -368,13 +373,31 @@ export default { } }); //获取交付产品 + //获取不合格产品 - getMaterialList({page:0,tag:'low_inm'}).then((response) => { + //获取成品率 + let d = new Date(that.currentYear, month, 0); + let days = d.getDate(); + let start = that.currentYear+'-'+that.currentMonth; + let startDate = start + '-01'; + let endDate = start+ '-'+days; + that.chartDate=[start,start]; + getProcessYield({datetime_start:startDate,datetime_end:endDate}).then((response) => { if (response.data) { - that.warningList = response.data; + let list = response.data; + let xAxisData = [],seriesData = []; + list.forEach(item =>{ + xAxisData.push(item.name); + let rate = item.rate*100; + seriesData.push(rate.toFixed(2)) + }); + that.chartData.xAxisData = xAxisData; + that.chartData.seriesData = seriesData; + this.drawChart(); } }); + }, gotoTicketPage(){ let path = this.$route.path; @@ -409,6 +432,7 @@ export default { }, //图标渲染 drawChart() { + let that = this; this.chartColumn = echarts.init(document.getElementById('chartColumn')); this.chartColumn.setOption({ // title: { text: '成品率' }, @@ -444,7 +468,7 @@ export default { splitLine: { show: false, //去掉X轴分割线 }, - data: ["冷加工", "热弯", "钢化", "镀膜", "夹层", "包边", "装框", "成品"] + data: that.chartData.xAxisData, }, yAxis: { axisLine:{ @@ -466,8 +490,8 @@ export default { series: [{ name: '成品率', type: 'bar', - barWidth: 40, - data: this.seriesData, + barWidth: 20, + data: that.chartData.seriesData, label: { show: true, //开启显示 position: 'top', //在上方显示 @@ -479,13 +503,13 @@ export default { }, itemStyle: { normal: { - /*color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: '#adcff3' }, { offset: 1, color: '#409EFF' - }]),*/ + }]), /*color: function(params) { let colorList = [ @@ -507,13 +531,13 @@ export default { } ]); },*/ - color: function(params) { + /*color: function(params) { let colorList = [ '#5fcdc2','#a378e4','#fea94c','#f27197', '#409eff','#5fcdc2','#a378e4','#fea94c' ]; return colorList[params.dataIndex] - }, + },*/ } }, }] @@ -528,7 +552,7 @@ export default { }else if(index==='2'){ this.$router.push({name:'order',params:{page:1,page_size:20}}) }else if(index==='3'){ - this.$router.push({name:'plan',params:{page:1,page_size:20}}) + this.$router.push({name:'management',params:{page:1,page_size:20}}) }else if(index==='4'){ this.$router.push({name:'product',params:{page:1,page_size:20,material__type:1}}) }else if(index==='5'){ @@ -571,18 +595,22 @@ export default { startTime = yea+'-'+mon+'-01'; } if(index==='1'){ - this.tableDate = null; - this.tableIndex = activeIndex; - this.listLoadingPlan = true; - getProductionplanList({page:0,create_time_start:startTime,create_time_end:endTime}).then((response) => { - if (response.data) { - that.planList = response.data; - } - this.listLoadingPlan = false; - }); - }else{ - this.chartDate = null; this.chartIndex = activeIndex; + getProcessYield({datetime_start:startTime,datetime_end:endTime}).then((response) => { + if (response.data) { + let list = response.data; + let xAxisData = [],seriesData = []; + list.forEach(item =>{ + xAxisData.push(item.name); + let rate = item.rate*100; + seriesData.push(rate.toFixed(2)) + }); + that.chartData.xAxisData = xAxisData; + that.chartData.seriesData = seriesData; + this.drawChart(); + } + }); + } //根据时间和类型获取数据 }, @@ -593,33 +621,34 @@ export default { let year = null,month = null,days = null; if(index==='1'){ this.tableIndex = null; - startDate = this.tableDate+'-01'; - year = this.tableDate.split("-")[0]; - month = this.tableDate.split("-")[1]; + startDate = that.chartDate[0]+'-01'; + year =that.chartDate[1].split("-")[0]; + month = that.chartDate[1].split("-")[1]; let d = new Date(year, month, 0); days = d.getDate(); endDate = this.tableDate + '-'+days; - this.listLoadingPlan = true; - getProductionplanList({page:0,create_time_start:startDate,create_time_end:endDate}).then((response) => { + getProcessYield({datetime_start:startDate,datetime_end:endDate}).then((response) => { if (response.data) { - that.planList = response.data; + let list = response.data; + let xAxisData = [],seriesData = []; + list.forEach(item =>{ + xAxisData.push(item.name); + let rate = item.rate*100; + seriesData.push(rate.toFixed(2)) + }); + that.chartData.xAxisData = xAxisData; + that.chartData.seriesData = seriesData; + this.drawChart(); } - this.listLoadingPlan = false; }); - }else{ - this.chartIndex = null; - startDate = this.chartDate+'-01'; - year = this.chartDate.split("-")[0]; - month = this.chartDate.split("-")[1]; - let d = new Date(year, month, 0); - days = d.getDate(); - endDate = this.chartDate + '-'+days; } }, + //库存 handleStockSizeChange(val){ this.stockPageSize = val; this.stockPage = 1; }, + //库存 handleStockCurrentChange(val){ let that = this; this.listLoading = true; @@ -632,6 +661,7 @@ export default { this.listLoading = false; }); }, + //提示 activeNameClick(tab, event) { let that = this; // debugger; @@ -748,11 +778,12 @@ export default { let hei = document.getElementsByClassName('app-main')[0].clientHeight; let heig = document.getElementsByClassName('dashboardTopCard')[0].clientHeight; this.cardTabelHeight = ((hei-heig-130)/2); - document.getElementById('chartColumn').style.height = this.cardTabelHeight+'px'; - this.drawChart(); + document.getElementById('chartColumn').style.height = this.cardTabelHeight-35+'px'; + // this.drawChart(); this.getPlanList(); this.getStockList(); this.getGanttData(); + // this.getYield(); this.getStatisticsData(); }, updated () { @@ -768,70 +799,109 @@ export default { .el-card.is-always-shadow{ height: auto!important; } -.dashboard-container { - margin: 5px 6px; -} -.dashboard-text { - font-size: 30px; - line-height: 46px; -} -.dashboardTopCard{ - margin-bottom: 5px; - border-radius: 10px; - .cards{ - width: 18%; - color: #ffffff; - background: #5fcdc2; - text-align: center; - border-radius: 10px; - padding: 10px; - line-height: 30px; + .dashboard-container { + margin: 5px 6px; + } + .dashboardTopCard,.dashboardMiddle{ + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + margin-bottom: 5px; + background: #ffffff; + box-shadow: 0 2px 12px 0 rgba(0,0,0,.1); + } +/**/ + .cardsWrap{ + display: flex; + width: 20%; + color: #777777; float: left; - margin: 15px 1%; - .cardCurrentText{ - text-align: left; - padding-left: 20px; - } - .cardTotalText{ - font-size: 30px; + font-size: 14px; + } + .svgIconWrap{ + margin-right:20px; + width: 50px; + height: 50px; + border-radius: 15px; + text-align: center; + .svgIcon{ + font-size:24px; + margin-top: 13px } } - .cards:nth-of-type(2){ - background:#5fcdc2;; + .cardsWrap:nth-child(1){ + .svgIconWrap{ + background:#e9f3ff; + .svgIcon{ + color: #409EFF; + } + } } - .cards:nth-child(3){ - background:#a378e4;; + .cardsWrap:nth-child(2){ + .svgIconWrap{ + background:#fff1de; + .svgIcon{ + color: #ffb23f; + } + } } - .cards:nth-of-type(4){ - background:#fea94c;; + + .cardsWrap:nth-child(3){ + .svgIconWrap{ + background:#d9f6d8; + .svgIcon{ + color: #54cb48; + } + } } - .cards:nth-of-type(5){ - background:#f27197;; + .cardsWrap:nth-child(4){ + .svgIconWrap{ + background:#f0e8fd; + .svgIcon{ + color: #a378e4; + } + } } - .cards:nth-of-type(6){ - background:#409eff;; + .cardsWrap:nth-child(5){ + .svgIconWrap{ + background:#f7e5ea; + .svgIcon{ + color: #f27197; + } + } } - .cards:hover{ - box-shadow: 0 0 12px 5px rgba(0,0,0,.1); + .totalCountText{ + height: 20px; + line-height: 20px } -} + .totalCountNum{ + height: 30px; + } + .totalCount{ + font-size: 25px; + font-weight: bold; + color: #626262; + } + /**/ .CardTitleWrap{ display: flex; height: 35px; line-height: 35px; padding-left: 1%; - padding-top: 6px; + box-sizing: border-box; + border-bottom: 1px solid #f5f5f5; + /*padding-top: 6px;*/ .verticalLine{ width: 4px; - height: 20px; - background: orangered; + height: 15px; + background: #409EFF; margin-right: 7px; - margin-top: 6px; + margin-top: 8px; } .dashboardCardTitle{ - height: 35px; - line-height:35px; - font-size: 20px; + height: 34px; + line-height:34px; + font-size: 14px; font-weight: bold; vertical-align: middle; margin-right: 7px; @@ -843,9 +913,7 @@ export default { cursor: pointer; } } - -.dashboardSubRow{ - margin-bottom: 5px; +/*成品率筛选条件*/ .dashboardCardHand{ display: flex; justify-content: space-between; @@ -855,12 +923,13 @@ export default { display: flex; border: 1px solid #DCDFE6; border-radius: 6px; - height: 35px; - line-height:35px; + height: 30px; + line-height:30px; margin-left: 10px; + font-size: 12px; .convenientBtn{ cursor: pointer; - width: 60px; + width: 50px; text-align:center; border-right: 1px solid #DCDFE6; } @@ -880,8 +949,6 @@ export default { } -} - .lists{ padding-right: 40px; .listItem{ @@ -900,4 +967,8 @@ export default { height: 100%!important; } } + #dashboardMiddle .el-range-editor--medium.el-input__inner, + #dashboardMiddle .el-range-editor.el-input__inner{ + height: 30px!important; + } diff --git a/hb_client/src/views/login/index.vue b/hb_client/src/views/login/index.vue index 4f256c6..53da72e 100644 --- a/hb_client/src/views/login/index.vue +++ b/hb_client/src/views/login/index.vue @@ -64,10 +64,10 @@ - +
打卡
- +
@@ -179,9 +179,61 @@ //人脸登录 takePhoto(){ this.limitedPhoto = true; + this.openTheCamera(); + }, + /*打开相机*/ + openTheCamera () { + this.$nextTick(function () { + let _this = this; + this.thisVideo = document.getElementById('videoCamera'); + // 旧版本浏览器可能根本不支持mediaDevices,我们首先设置一个空对象 + if (navigator.mediaDevices === undefined) { + navigator.mediaDevices = {} + } + // 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象 + // 使用getUserMedia,因为它会覆盖现有的属性。 + // 这里,如果缺少getUserMedia属性,就添加它。 + if (navigator.mediaDevices.getUserMedia === undefined) { + navigator.mediaDevices.getUserMedia = function (constraints) { + // 首先获取现存的getUserMedia(如果存在) + let getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia; + // 有些浏览器不支持,会返回错误信息 + // 保持接口一致 + if (!getUserMedia) { + return Promise.reject(new Error('getUserMedia is not implemented in this browser')) + } + // 否则,使用Promise将调用包装到旧的navigator.getUserMedia + return new Promise(function (resolve, reject) { + getUserMedia.call(navigator, constraints, resolve, reject) + }) + } + } + + let constraints = { audio: false, video: { width: this.videoWidth, height: this.videoHeight, transform: 'scaleX(-1)' } }; + navigator.mediaDevices.getUserMedia(constraints).then(function (stream) { + // 旧的浏览器可能没有srcObject + if ('srcObject' in _this.thisVideo) { + _this.thisVideo.srcObject = stream + } else { + // 避免在新的浏览器中使用它,因为它正在被弃用。 + _this.thisVideo.src = window.URL.createObjectURL(stream) + } + _this.thisVideo.onloadedmetadata = function (e) { + _this.thisVideo.play(); + } + }).catch(err => { + console.log(err) + }) + }); + }, + /*关闭相机*/ + closeCamera () { + debugger; + this.$refs.faceTracking.closeCamera(); + // this.thisVideo.srcObject.getTracks()[0].stop(); }, getMsgFormSon(data){ - this.limitedPhoto = data; + // this.limitedPhoto = data; }, }, }; diff --git a/hb_client/src/views/mtm/materialdo.vue b/hb_client/src/views/mtm/materialdo.vue index 19b98e6..b42acd3 100644 --- a/hb_client/src/views/mtm/materialdo.vue +++ b/hb_client/src/views/mtm/materialdo.vue @@ -82,8 +82,8 @@
取消 - - 管理员授权 + 确认 +
diff --git a/hb_client/src/views/workflow/index.vue b/hb_client/src/views/workflow/index.vue index 5a57a88..1694c63 100644 --- a/hb_client/src/views/workflow/index.vue +++ b/hb_client/src/views/workflow/index.vue @@ -102,8 +102,10 @@

创建时间 :{{watchedCreateTime}}

- - +
+ + +
- +